diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2736420..254b38be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,9 @@ name: CI -on: [push, pull_request] +on: + schedule: + - cron: '0 0 * * *' + push: + pull_request: jobs: tests: name: Tests @@ -7,31 +11,21 @@ jobs: strategy: matrix: os: [ubuntu-latest] - php: ['8.0', '8.1'] - doctrine: ['2.11'] + php: ['8.0', '8.1', '8.2', '8.3'] + doctrine: ['2.14'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} + ini-values: error_reporting=E_ALL tools: phpunit, git coverage: xdebug - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache composer dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - # Use composer.json for key, if composer.lock is not committed. - # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - name: Install dependencies for doctrine/orm ${{ matrix.doctrine }} run: composer require --no-progress --no-scripts --no-plugins -v -W doctrine/orm "~${{ matrix.doctrine }}.0" - name: PHPUnit run: vendor/bin/phpunit --coverage-clover=coverage.xml --coverage-text - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v3 with: file: ./coverage.xml diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 00000000..92e9b92d --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,36 @@ +name: "Static Analysis" + +on: + pull_request: + push: + +jobs: + static-analysis-phpstan: + name: "Static Analysis with PHPStan" + runs-on: "ubuntu-22.04" + + strategy: + matrix: + php-version: + - "8.0" + - "8.1" + - "8.2" + + steps: + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + extensions: "pdo_sqlite" + + - name: "Install dependencies with Composer" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "${{ matrix.dependencies }}" + + - name: "Run a static analysis with phpstan/phpstan" + run: "vendor/bin/phpstan analyse -c phpstan.neon.dist" diff --git a/.gitignore b/.gitignore index 46624afd..8fb8a241 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,11 @@ composer.phar composer.lock .DS_Store .php_cs.cache +.php-cs-fixer.cache +.phpunit.result.cache /tests/Stubs/storage/framework/views/* !/tests/Stubs/storage/framework/views/.gitkeep /tests/Stubs/storage/doctrine.generated.php .idea -laravel-doctrine-orm.iml \ No newline at end of file +laravel-doctrine-orm.iml diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 00000000..74355def --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,30 @@ +in(__DIR__) + ->exclude('vendor') +; + +$config = new PhpCsFixer\Config(); + +return $config->setRules([ + '@PSR2' => true, + 'blank_line_after_opening_tag' => true, + 'no_leading_namespace_whitespace' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_blank_lines_after_phpdoc' => true, + 'concat_space' => ['spacing' => 'one'], + 'ordered_imports' => true, + 'blank_line_before_statement' => true, + 'no_extra_blank_lines' => true, + 'no_unused_imports' => true, + 'no_whitespace_in_blank_line' => true, + 'phpdoc_order' => true, + 'phpdoc_align' => ['tags' => ['param', 'return', 'throws', 'type', 'var']], + 'phpdoc_scalar' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => ['operators' => ['==' => 'align', '=' => 'align', '=>' => 'align']], +]) + ->setFinder($finder) + ; diff --git a/.php_cs b/.php_cs deleted file mode 100644 index c2489d19..00000000 --- a/.php_cs +++ /dev/null @@ -1,45 +0,0 @@ -exclude('vendor') - ->in(__DIR__); - -return Symfony\CS\Config\Config::create() - ->setUsingCache(true) - ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) - ->fixers(array( - 'psr4', - 'encoding', - 'short_tag', - 'blankline_after_open_tag', - 'namespace_no_leading_whitespace', - 'no_blank_lines_after_class_opening', - 'single_array_no_trailing_comma', - 'no_empty_lines_after_phpdocs', - 'concat_with_spaces', - 'eof_ending', - 'ordered_use', - 'extra_empty_lines', - 'single_line_after_imports', - 'trailing_spaces', - 'remove_lines_between_uses', - 'return', - 'indentation', - 'linefeed', - 'braces', - 'visibility', - 'unused_use', - 'whitespacy_lines', - 'php_closing_tag', - 'phpdoc_order', - 'phpdoc_params', - 'phpdoc_trim', - 'phpdoc_scalar', - 'short_array_syntax', - 'align_double_arrow', - 'align_equals', - 'lowercase_constants', - 'lowercase_keywords', - 'multiple_use', - 'line_after_namespace', - ))->finder($finder); diff --git a/README.md b/README.md index 44c1e0fd..d5f4f210 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![GitHub release](https://img.shields.io/github/release/laravel-doctrine/orm.svg?style=flat-square)](https://packagist.org/packages/laravel-doctrine/orm) [![Github actions](https://github.com/laravel-doctrine/orm/workflows/CI/badge.svg?branch=1.8)](https://github.com/laravel-doctrine/orm/actions?query=workflow%3ACI+branch%3A1.7) -[![StyleCI](https://styleci.io/repos/39036008/shield)](https://styleci.io/repos/39036008) [![Scrutinizer](https://img.shields.io/scrutinizer/g/laravel-doctrine/orm.svg?style=flat-square)](https://github.com/laravel-doctrine/orm) [![Packagist](https://img.shields.io/packagist/dm/laravel-doctrine/orm.svg?style=flat-square)](https://packagist.org/packages/laravel-doctrine/orm) [![Packagist](https://img.shields.io/packagist/dt/laravel-doctrine/orm.svg?style=flat-square)](https://packagist.org/packages/laravel-doctrine/orm) @@ -50,6 +49,7 @@ Version | Supported Laravel Versions ~1.6 | 7.x ~1.7 | 8.x ~1.8 | 9.x +~2.0 | 10.x Because of the auto package discovery feature Laravel has, the ServiceProvider and Facades are automatically registered. diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 00000000..415ea515 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,72 @@ +# Upgrade to 2.0 + +## DBAL 3 + +The most significant change in version 2.0 is using doctrine/dbal 3. You should [review their upgrade guide](https://github.com/doctrine/dbal/blob/bd54f5043eaff656b314037bf285d8b7f1c311b8/UPGRADE.md) in addition to this one. + +## Lumen supported dropped +We recommend using eloquent instead. + +## Minimum Doctrine/ORM version to 2.14 + +This release supports a minimum doctrine/orm version of 2.14 due to a number of deprecations and new features that we are taking advantage of. + + +## Proxy namespace required +You must now set a namespace for your proxies. Use the configuration option `proxies.namespace`. the previous default value was `DoctrineProxies`. + +## Command signature changed + +All doctrine commands are now extended from `doctrine` itself. Some of the command options have been changed or removed, and some have been added. + +### Removed: FluentExporter, GenerateEntitiesCommand, GenerateRepositoriesCommand, ConvertMappingCommand, MappingImportCommand, ConvertConfigCommand + +Doctrine is moving away from code generation and we are following suit, as well as reducing our maintenance burden. + +## Removed MasterSlaveConnection + +The old MasterSlaveConnection has been supported for backwards compatibility, but has now been removed. You can migrate to the new PrimaryReadReplicaConnection instead. + +## Removed JSON type +If you were still including this line in your custom_types config, it should be removed: + +``` +'json' => LaravelDoctrine\ORM\Types\Json::class +``` + +## Removed 'simple' Annotations +The `simple` configuration option for simple annotation reader has been removed as support for this +is removed in Doctrine. + + +## Short namespaces + +Short namespaces such as `Entities:User` are no longer supported by Doctrine and have been removed. + +## Driver Options Rename + +If you have been setting "driverOptions" on your MySQL database config, you should rename it to "options" to align with Laravel's naming scheme. + +## Metadata driver `config` removed +Used deprecated YamlDriver and was not supported by doctrine. + +## UrlRoutable::getRouteKeyName renamed to getRouteKeyNameStatic +This method was renamed to not conflict with the UrlRoutable trait of Laravel. + +## Logging configuration changed +DBAL deprecated the SQLLogger functionality in favor of the new middleware functionality. +Logging moved to the new middlewares section. +```php + 'middlewares' => [ + \Doctrine\DBAL\Logging\Middleware::class + ], +``` + +### Classes and interface in `LaravelDoctrine\ORM\Loggers` removed +Use new "middleware" logic, see above. + +### Clockwork logger removed +Out of scope for this package. + +### Laravel debugbar logger removed +Laravel debugbar does not support the new Middleware to Doctrine. Open for PR to re-add this functionality. diff --git a/composer.json b/composer.json index 32fb4360..3ea5b304 100644 --- a/composer.json +++ b/composer.json @@ -17,31 +17,34 @@ ], "require": { "php": "^8.0", - "doctrine/annotations": "^1.13", - "doctrine/cache": "^1", - "doctrine/dbal": "^2.13.3", - "doctrine/orm": "^2.11", - "doctrine/persistence": "^1.3.5|^2.0", - "illuminate/auth": "^9.0", - "illuminate/console": "^9.0", - "illuminate/container": "^9.0", - "illuminate/contracts": "^9.0", - "illuminate/pagination": "^9.0", - "illuminate/routing": "^9.0", - "illuminate/support": "^9.0", - "illuminate/validation": "^9.0", - "illuminate/view": "^9.0", + "doctrine/annotations": "^2", + "doctrine/dbal": "^3.2", + "doctrine/orm": "^2.14", + "doctrine/persistence": "^3", + "illuminate/auth": "^9.0|^10.0", + "illuminate/console": "^9.0|^10.0", + "illuminate/container": "^9.0|^10.0", + "illuminate/contracts": "^9.0|^10.0", + "illuminate/pagination": "^9.0|^10.0", + "illuminate/routing": "^9.0|^10.0", + "illuminate/support": "^9.0|^10.0", + "illuminate/validation": "^9.0|^10.0", + "illuminate/view": "^9.0|^10.0", + "symfony/cache": "^6.0", "symfony/serializer": "^5.0|^6.0", "symfony/yaml": "^5.0|^6.0" }, + "conflict": { + "laravel/lumen": "*" + }, "require-dev": { "phpunit/phpunit": "^9.3", "mockery/mockery": "^1.3.1", - "barryvdh/laravel-debugbar": "~3.0", - "itsgoingd/clockwork": "^5.0", - "illuminate/log": "^9.0", - "illuminate/notifications": "^9.0", - "illuminate/queue": "^9.0", + "illuminate/log": "^9.0|^10.0", + "illuminate/notifications": "^9.0|^10.0", + "illuminate/queue": "^9.0|^10.0", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.1", "fakerphp/faker": "^1.20" }, "autoload": { diff --git a/config/doctrine.php b/config/doctrine.php index b0947fe0..f24275a7 100644 --- a/config/doctrine.php +++ b/config/doctrine.php @@ -12,7 +12,7 @@ | paths setting to the appropriate path and replace App namespace | by your own namespace. | - | Available meta drivers: fluent|annotations|yaml|simplified_yaml|xml|simplified_xml|config|static_php|php + | Available meta drivers: attributes|fluent|xml|simplified_xml|static_php|php | | Available connections: mysql|oracle|pgsql|sqlite|sqlsrv | (Connections can be configured in the database config) @@ -29,16 +29,18 @@ 'dev' => env('APP_DEBUG', false), 'meta' => env('DOCTRINE_METADATA', 'annotations'), 'connection' => env('DB_CONNECTION', 'mysql'), - 'namespaces' => [], 'paths' => [ base_path('app/Entities') ], + 'repository' => Doctrine\ORM\EntityRepository::class, + 'proxies' => [ - 'namespace' => false, + 'namespace' => 'DoctrineProxies', 'path' => storage_path('proxies'), 'auto_generate' => env('DOCTRINE_PROXY_AUTOGENERATE', false) ], + /* |-------------------------------------------------------------------------- | Doctrine events @@ -52,7 +54,9 @@ 'listeners' => [], 'subscribers' => [] ], + 'filters' => [], + /* |-------------------------------------------------------------------------- | Doctrine mapping types @@ -77,6 +81,14 @@ */ 'mapping_types' => [ //'enum' => 'string' + ], + + /** + * References: + * https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/architecture.html#middlewares + */ + 'middlewares' => [ + // Doctrine\DBAL\Logging\Middleware::class ] ] ], @@ -141,26 +153,13 @@ ], /* |-------------------------------------------------------------------------- - | Enable query logging with laravel file logging, - | debugbar, clockwork or an own implementation. - | Setting it to false, will disable logging - | - | Available: - | - LaravelDoctrine\ORM\Loggers\LaravelDebugbarLogger - | - LaravelDoctrine\ORM\Loggers\ClockworkLogger - | - LaravelDoctrine\ORM\Loggers\FileLogger - |-------------------------------------------------------------------------- - */ - 'logger' => env('DOCTRINE_LOGGER', false), - /* - |-------------------------------------------------------------------------- | Cache |-------------------------------------------------------------------------- | | Configure meta-data, query and result caching here. | Optionally you can enable second level caching. | - | Available: apc|array|file|illuminate|memcached|php_file|redis|void + | Available: apc|array|file|illuminate|memcached|php_file|redis | */ 'cache' => [ diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 00000000..2cbbb96c --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,1569 @@ +parameters: + ignoreErrors: + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\DoctrineUserProvider\\:\\:retrieveByCredentials\\(\\) has parameter \\$credentials with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Auth/DoctrineUserProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\DoctrineUserProvider\\:\\:validateCredentials\\(\\) has parameter \\$credentials with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Auth/DoctrineUserProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\Passwords\\\\DoctrineTokenRepository\\:\\:__construct\\(\\) has parameter \\$throttle with no type specified\\.$#" + count: 1 + path: src/Auth/Passwords/DoctrineTokenRepository.php + + - + message: "#^Cannot access offset 'config' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 1 + path: src/Auth/Passwords/PasswordBrokerManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\Passwords\\\\PasswordBrokerManager\\:\\:createTokenRepository\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Auth/Passwords/PasswordBrokerManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\Passwords\\\\PasswordResetServiceProvider\\:\\:provides\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Auth/Passwords/PasswordResetServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\Passwords\\\\PasswordResetTable\\:\\:columns\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Auth/Passwords/PasswordResetTable.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Auth\\\\Passwords\\\\PasswordResetTable\\:\\:indices\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Auth/Passwords/PasswordResetTable.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\BootChain\\:\\:add\\(\\) has no return type specified\\.$#" + count: 1 + path: src/BootChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\BootChain\\:\\:boot\\(\\) has no return type specified\\.$#" + count: 1 + path: src/BootChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\BootChain\\:\\:flush\\(\\) has no return type specified\\.$#" + count: 1 + path: src/BootChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Cache\\\\ArrayCacheProvider\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Cache/ArrayCacheProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Cache\\\\FileCacheProvider\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Cache/FileCacheProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Cache\\\\IlluminateCacheProvider\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Cache/IlluminateCacheProvider.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Configuration\\\\Cache\\\\IlluminateCacheProvider\\:\\:\\$store \\(string\\) on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Configuration/Cache/IlluminateCacheProvider.php + + - + message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#" + count: 1 + path: src/Configuration/Cache/IlluminateCacheProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Cache\\\\PhpFileCacheProvider\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Cache/PhpFileCacheProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\MysqlConnection\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/MysqlConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\MysqlConnection\\:\\:resolve\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/MysqlConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\OracleConnection\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/OracleConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\OracleConnection\\:\\:resolve\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/OracleConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PgsqlConnection\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PgsqlConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PgsqlConnection\\:\\:resolve\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PgsqlConnection.php + + - + message: "#^Cannot access offset 'driver' on array\\|LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\Connection\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:__construct\\(\\) has parameter \\$resolvedBaseSettings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getConnectionData\\(\\) has parameter \\$connection with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getConnectionData\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getFilteredConfig\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getReadReplicasConfig\\(\\) has parameter \\$replicas with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getReadReplicasConfig\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getReplicasConfiguration\\(\\) has parameter \\$replicaConfig with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:getReplicasConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:replaceKeyIfExists\\(\\) has parameter \\$array with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:replaceKeyIfExists\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Parameter \\#1 \\$array of function array_diff_key expects array, array\\|LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\Connection given\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:\\$primaryReadReplicaConfigIgnored type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\PrimaryReadReplicaConnection\\:\\:\\$resolvedBaseSettings type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/PrimaryReadReplicaConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\SqliteConnection\\:\\:isMemory\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/SqliteConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\SqliteConnection\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/SqliteConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\SqliteConnection\\:\\:resolve\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/SqliteConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\SqlsrvConnection\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/SqlsrvConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Connections\\\\SqlsrvConnection\\:\\:resolve\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Connections/SqlsrvConnection.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\CustomTypeManager\\:\\:addCustomTypes\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Configuration/CustomTypeManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\CustomTypeManager\\:\\:addCustomTypes\\(\\) has parameter \\$typeMap with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/CustomTypeManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\CustomTypeManager\\:\\:addType\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Configuration/CustomTypeManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\CustomTypeManager\\:\\:addType\\(\\) has parameter \\$class with no type specified\\.$#" + count: 1 + path: src/Configuration/CustomTypeManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\CustomTypeManager\\:\\:addType\\(\\) has parameter \\$name with no type specified\\.$#" + count: 1 + path: src/Configuration/CustomTypeManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\CustomTypeManager\\:\\:getType\\(\\) has parameter \\$type with no type specified\\.$#" + count: 1 + path: src/Configuration/CustomTypeManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Driver\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Driver.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\LaravelNamingStrategy\\:\\:classToFieldName\\(\\) has parameter \\$className with no type specified\\.$#" + count: 1 + path: src/Configuration/LaravelNamingStrategy.php + + - + message: "#^Parameter \\#3 \\$className \\(null\\) of method LaravelDoctrine\\\\ORM\\\\Configuration\\\\LaravelNamingStrategy\\:\\:embeddedFieldToColumnName\\(\\) should be compatible with parameter \\$className \\(class\\-string\\) of method Doctrine\\\\ORM\\\\Mapping\\\\NamingStrategy\\:\\:embeddedFieldToColumnName\\(\\)$#" + count: 1 + path: src/Configuration/LaravelNamingStrategy.php + + - + message: "#^Parameter \\#4 \\$embeddedClassName \\(null\\) of method LaravelDoctrine\\\\ORM\\\\Configuration\\\\LaravelNamingStrategy\\:\\:embeddedFieldToColumnName\\(\\) should be compatible with parameter \\$embeddedClassName \\(class\\-string\\) of method Doctrine\\\\ORM\\\\Mapping\\\\NamingStrategy\\:\\:embeddedFieldToColumnName\\(\\)$#" + count: 1 + path: src/Configuration/LaravelNamingStrategy.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:__call\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:callCustomCreator\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:createDriver\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:driver\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:getDrivers\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Parameter \\#1 \\$callback of function call_user_func_array expects callable\\(\\)\\: mixed, array\\{mixed, string\\} given\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:\\$customCreators type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Configuration\\\\Manager\\:\\:\\$drivers type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/Manager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Annotations\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Annotations.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Attributes\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Attributes.php + + - + message: "#^Call to method setFluentFactory\\(\\) on an unknown class LaravelDoctrine\\\\Fluent\\\\FluentDriver\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Class LaravelDoctrine\\\\Fluent\\\\Extensions\\\\ExtensibleClassMetadataFactory not found\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Instantiated class LaravelDoctrine\\\\Fluent\\\\Builders\\\\Builder not found\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Instantiated class LaravelDoctrine\\\\Fluent\\\\FluentDriver not found\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Fluent\\:\\:getNamingStrategy\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Fluent\\:\\:getQuoteStrategy\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Fluent\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Fluent.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\MetaDataManager\\:\\:getClassSuffix\\(\\) should return string but returns null\\.$#" + count: 1 + path: src/Configuration/MetaData/MetaDataManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Php\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Php.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\SimplifiedXml\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/SimplifiedXml.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\SimplifiedYaml\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/SimplifiedYaml.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\StaticPhp\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/StaticPhp.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Xml\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Xml.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Configuration\\\\MetaData\\\\Yaml\\:\\:resolve\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Configuration/MetaData/Yaml.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Console\\\\Command\\:\\:message\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Console/Command.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Console\\\\Command\\:\\:message\\(\\) has parameter \\$message with no type specified\\.$#" + count: 1 + path: src/Console/Command.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ManagerRegistry\\:\\:addConnection\\(\\)\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ManagerRegistry\\:\\:addManager\\(\\)\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getConnection\\(\\)\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Function base_path not found\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Console\\\\DumpDatabaseCommand\\:\\:createSchema\\(\\) has parameter \\$em with no type specified\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Console\\\\DumpDatabaseCommand\\:\\:dropSchema\\(\\) has parameter \\$em with no type specified\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Console\\\\DumpDatabaseCommand\\:\\:handle\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Parameter \\#1 \\$connection of method LaravelDoctrine\\\\ORM\\\\Console\\\\DumpDatabaseCommand\\:\\:connect\\(\\) expects string, array\\|bool\\|string\\|null given\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Parameter \\#1 \\$em of method LaravelDoctrine\\\\ORM\\\\Console\\\\DumpDatabaseCommand\\:\\:dump\\(\\) expects string, array\\|bool\\|string\\|null given\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Parameter \\#2 \\$em of method LaravelDoctrine\\\\ORM\\\\Console\\\\DumpDatabaseCommand\\:\\:connect\\(\\) expects string, array\\|bool\\|string\\|null given\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Part \\$binary \\(array\\|bool\\|string\\) of encapsed string cannot be cast to string\\.$#" + count: 1 + path: src/Console/DumpDatabaseCommand.php + + - + message: "#^Class LaravelDoctrine\\\\ORM\\\\Console\\\\EnsureProductionSettingsCommand extends deprecated class Doctrine\\\\ORM\\\\Tools\\\\Console\\\\Command\\\\EnsureProductionSettingsCommand\\.$#" + count: 1 + path: src/Console/EnsureProductionSettingsCommand.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineExtender\\:\\:extend\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineExtender.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\MappingDriver\\:\\:addMappings\\(\\)\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\MappingDriver\\:\\:addPaths\\(\\)\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getConfiguration\\(\\)\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:addMappings\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:addMappings\\(\\) has parameter \\$mappings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:addPaths\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:addPaths\\(\\) has parameter \\$paths with no value type specified in iterable type array\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:callExtendOn\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:extend\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:extendAll\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineManager\\:\\:onResolve\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Ternary operator condition is always true\\.$#" + count: 1 + path: src/DoctrineManager.php + + - + message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Foundation\\\\Application\\:\\:configure\\(\\)\\.$#" + count: 3 + path: src/DoctrineServiceProvider.php + + - + message: "#^Call to static method create\\(\\) on an unknown class Faker\\\\Factory\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Cannot access offset 'config' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 2 + path: src/DoctrineServiceProvider.php + + - + message: "#^Cannot access offset 'db' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Cannot access offset 'events' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 2 + path: src/DoctrineServiceProvider.php + + - + message: "#^Cannot access offset 'registry' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Class Doctrine\\\\Common\\\\Persistence\\\\ManagerRegistry not found\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Expression \"\\$this\\-\\>app\\['db'\\]\" on a separate line does not do anything\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Fetching class constant class of deprecated class LaravelDoctrine\\\\ORM\\\\Console\\\\EnsureProductionSettingsCommand\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:boot\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:bootExtensionManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:ensureValidatorIsUsable\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:extendAuthManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:extendNotificationChannel\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:mergeConfig\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerClassMetaDataFactory\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerConsoleCommands\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerCustomTypes\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerEntityManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerExtensions\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerManagerRegistry\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:registerPresenceVerifierProvider\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:setupCache\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:setupConnection\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:setupConnection\\(\\) should return array but return statement is missing\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\DoctrineServiceProvider\\:\\:setupMetaData\\(\\) has no return type specified\\.$#" + count: 1 + path: src/DoctrineServiceProvider.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\MappingDriver\\:\\:addPaths\\(\\)\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Dead catch \\- ReflectionException is never thrown in the try block\\.$#" + count: 2 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:configureProxies\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:configureProxies\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:create\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:createEventManager\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:decorateManager\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:getConnectionDriver\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:getConnectionDriver\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:hasValidPrimaryReadReplicaConfig\\(\\) has parameter \\$driverConfig with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:isPrimaryReadReplicaConfigured\\(\\) has parameter \\$driverConfig with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerFilters\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerFilters\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerListener\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerListeners\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerListeners\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerMappingTypes\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerMappingTypes\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerPaths\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerPaths\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerSubscribers\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:registerSubscribers\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setCacheSettings\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setCustomFunctions\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setCustomHydrationModes\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setCustomMappingDriverChain\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setCustomMappingDriverChain\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setMetadataDriver\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setMetadataDriver\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setNamingStrategy\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setNamingStrategy\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setQuoteStrategy\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setQuoteStrategy\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setRepositoryFactory\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setRepositoryFactory\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\EntityManagerFactory\\:\\:setSecondLevelCaching\\(\\) has no return type specified\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Parameter \\#1 \\$cmfName of method Doctrine\\\\ORM\\\\Configuration\\:\\:setClassMetadataFactoryName\\(\\) expects class\\-string, string given\\.$#" + count: 1 + path: src/EntityManagerFactory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\Extension\\:\\:addSubscribers\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/Extension.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\Extension\\:\\:getFilters\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/Extension.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\MappingDriver\\:\\:getReader\\(\\)\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:boot\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:bootExtension\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:bootExtension\\(\\) has parameter \\$connection with no type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:getBootedExtensions\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:getExtensions\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:markAsBooted\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:markAsBooted\\(\\) has parameter \\$connection with no type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:notBootedYet\\(\\) has parameter \\$connection with no type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:register\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Extensions\\\\ExtensionManager\\:\\:\\$bootedExtensions type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/ExtensionManager.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\MappingDriverChain\\:\\:__construct\\(\\) has parameter \\$namespace with no type specified\\.$#" + count: 1 + path: src/Extensions/MappingDriverChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\MappingDriverChain\\:\\:addMappings\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/MappingDriverChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\MappingDriverChain\\:\\:addMappings\\(\\) has parameter \\$mappings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/MappingDriverChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\MappingDriverChain\\:\\:addPaths\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/MappingDriverChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\MappingDriverChain\\:\\:addPaths\\(\\) has parameter \\$paths with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/MappingDriverChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\MappingDriverChain\\:\\:getReader\\(\\) should return Doctrine\\\\Common\\\\Annotations\\\\Reader\\|null but return statement is missing\\.$#" + count: 1 + path: src/Extensions/MappingDriverChain.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\TablePrefix\\\\TablePrefixExtension\\:\\:addSubscribers\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/TablePrefix/TablePrefixExtension.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\TablePrefix\\\\TablePrefixExtension\\:\\:getFilters\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/TablePrefix/TablePrefixExtension.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\TablePrefix\\\\TablePrefixListener\\:\\:getSubscribedEvents\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Extensions/TablePrefix/TablePrefixListener.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Extensions\\\\TablePrefix\\\\TablePrefixListener\\:\\:loadClassMetadata\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Extensions/TablePrefix/TablePrefixListener.php + + - + message: "#^Offset 'joinTable' does not exist on array\\{cache\\?\\: array, cascade\\: array\\, declared\\?\\: class\\-string, fetch\\: mixed, fieldName\\: string, id\\?\\: bool, inherited\\?\\: class\\-string, indexBy\\?\\: string, \\.\\.\\.\\}\\.$#" + count: 1 + path: src/Extensions/TablePrefix/TablePrefixListener.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getConfiguration\\(\\)\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getConnection\\(\\)\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Container\\\\Container\\:\\:forgetInstance\\(\\)\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: """ + #^Call to method fromNamespaceAlias\\(\\) of deprecated class Doctrine\\\\ORM\\\\Exception\\\\UnknownEntityNamespace\\: + No replacement planned\\.$# + """ + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Cannot call method getName\\(\\) on ReflectionClass\\|false\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:addConnection\\(\\) has no return type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:addConnection\\(\\) has parameter \\$connection with no type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:addConnection\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:addManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:addManager\\(\\) has parameter \\$manager with no type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:addManager\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:closeManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getConnectionBindingName\\(\\) has parameter \\$connection with no type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getConnectionNames\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getConnections\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getManager\\(\\) should return Doctrine\\\\Persistence\\\\ObjectManager but returns object\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getManagerBindingName\\(\\) has parameter \\$manager with no type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getManagerForClass\\(\\) should return Doctrine\\\\Persistence\\\\ObjectManager\\|null but return statement is missing\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getManagerNames\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:getRepository\\(\\) return type with generic interface Doctrine\\\\Persistence\\\\ObjectRepository does not specify its types\\: T$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:purgeManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:setDefaultConnection\\(\\) has no return type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:setDefaultManager\\(\\) has no return type specified\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Parameter \\#1 \\$className of method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadataFactory\\\\>\\:\\:isTransient\\(\\) expects class\\-string, string given\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Parameter \\#1 \\$className of method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getRepository\\(\\) expects class\\-string\\, string given\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:\\$connections type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:\\$connectionsMap type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:\\$managers type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\IlluminateRegistry\\:\\:\\$managersMap type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Unable to resolve the template type T in call to method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getRepository\\(\\)$#" + count: 1 + path: src/IlluminateRegistry.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Middleware\\\\SubstituteBindings\\:\\:substituteImplicitBindings\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Middleware/SubstituteBindings.php + + - + message: "#^Parameter \\#1 \\$route of method Illuminate\\\\Contracts\\\\Routing\\\\Registrar\\:\\:substituteBindings\\(\\) expects Illuminate\\\\Routing\\\\Route, object\\|string\\|null given\\.$#" + count: 1 + path: src/Middleware/SubstituteBindings.php + + - + message: "#^Parameter \\#1 \\$route of method LaravelDoctrine\\\\ORM\\\\Middleware\\\\SubstituteBindings\\:\\:substituteImplicitBindings\\(\\) expects Illuminate\\\\Routing\\\\Route, object\\|string\\|null given\\.$#" + count: 1 + path: src/Middleware/SubstituteBindings.php + + - + message: "#^Cannot call method routeNotificationFor\\(\\) on class\\-string\\|object\\.$#" + count: 1 + path: src/Notifications/DoctrineChannel.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Notifications\\\\DoctrineChannel\\:\\:send\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Notifications/DoctrineChannel.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Notifications\\\\Notification\\:\\:\\$id has no type specified\\.$#" + count: 1 + path: src/Notifications/Notification.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\AbstractQuery\\:\\:setFirstResult\\(\\)\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Call to an undefined method Doctrine\\\\ORM\\\\AbstractQuery\\:\\:setMaxResults\\(\\)\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:__construct\\(\\) has parameter \\$queryParams with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:convertToLaravelPaginator\\(\\) has parameter \\$doctrinePaginator with generic class Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\Paginator but does not specify its types\\: T$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:fromParams\\(\\) has parameter \\$queryParams with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:fromRequest\\(\\) has parameter \\$queryParams with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:getDoctrinePaginator\\(\\) return type with generic class Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\Paginator does not specify its types\\: T$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:getQueryParams\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:make\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:queryParams\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Parameter \\#1 \\$query of class Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\Paginator constructor expects Doctrine\\\\ORM\\\\Query\\|Doctrine\\\\ORM\\\\QueryBuilder, Doctrine\\\\ORM\\\\AbstractQuery given\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Pagination\\\\PaginatorAdapter\\:\\:\\$queryParams type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 2 + path: src/Pagination/PaginatorAdapter.php + + - + message: "#^Cannot access offset 'config' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 2 + path: src/Queue/FailedJobsServiceProvider.php + + - + message: "#^Cannot access offset 'events' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 1 + path: src/Queue/FailedJobsServiceProvider.php + + - + message: "#^Cannot access offset 'registry' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" + count: 1 + path: src/Queue/FailedJobsServiceProvider.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Serializers\\\\ArraySerializer\\:\\:serialize\\(\\) has parameter \\$entity with no type specified\\.$#" + count: 1 + path: src/Serializers/ArraySerializer.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Serializers\\\\ArraySerializer\\:\\:serialize\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Serializers/ArraySerializer.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Serializers\\\\ArraySerializer\\:\\:serialize\\(\\) should return array but returns array\\|ArrayObject\\|bool\\|float\\|int\\|string\\|null\\.$#" + count: 1 + path: src/Serializers/ArraySerializer.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Serializers\\\\JsonSerializer\\:\\:serialize\\(\\) has parameter \\$entity with no type specified\\.$#" + count: 1 + path: src/Serializers/JsonSerializer.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\ConfigRepository\\:\\:__construct\\(\\) has parameter \\$items with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/ConfigRepository.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\ConfigRepository\\:\\:all\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/ConfigRepository.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\ConfigRepository\\:\\:get\\(\\) has parameter \\$key with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/ConfigRepository.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\ConfigRepository\\:\\:set\\(\\) has parameter \\$key with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/ConfigRepository.php + + - + message: "#^Parameter \\#2 \\$key of static method Illuminate\\\\Support\\\\Arr\\:\\:get\\(\\) expects int\\|string\\|null, array\\|string given\\.$#" + count: 1 + path: src/Testing/ConfigRepository.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\ConfigRepository\\:\\:\\$items type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/ConfigRepository.php + + - + message: "#^Class LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory implements generic interface ArrayAccess but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:create\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:createAs\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:make\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:makeAs\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:raw\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:raw\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:rawOf\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:rawOf\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:state\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:\\$afterCreating type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:\\$afterMaking type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:\\$definitions type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:\\$states \\(array\\\\) on left side of \\?\\? is not nullable\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\Factory\\:\\:\\$states type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 1 + path: src/Testing/Factory.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:__construct\\(\\) has parameter \\$afterCreating with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:__construct\\(\\) has parameter \\$afterMaking with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:__construct\\(\\) has parameter \\$definitions with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:applyStates\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:applyStates\\(\\) has parameter \\$definition with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:applyStates\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callAfter\\(\\) has parameter \\$afterCallbacks with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callAfter\\(\\) has parameter \\$models with generic class Illuminate\\\\Support\\\\Collection but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callAfterCallbacks\\(\\) has parameter \\$afterCallbacks with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callAfterCreating\\(\\) has parameter \\$models with generic class Illuminate\\\\Support\\\\Collection but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callAfterMaking\\(\\) has parameter \\$models with generic class Illuminate\\\\Support\\\\Collection but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callClosureAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:callClosureAttributes\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:construct\\(\\) has parameter \\$afterCreating with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:construct\\(\\) has parameter \\$afterMaking with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:construct\\(\\) has parameter \\$definitions with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:construct\\(\\) has parameter \\$states with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:create\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:getStates\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:make\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:makeInstance\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:stateAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:stateAttributes\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^PHPDoc tag @var for variable \\$metadata contains generic class Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata but does not specify its types\\: T$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:\\$activeStates type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:\\$afterCreating type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:\\$afterMaking type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:\\$definitions type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Property LaravelDoctrine\\\\ORM\\\\Testing\\\\FactoryBuilder\\:\\:\\$states type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 1 + path: src/Testing/FactoryBuilder.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\SimpleHydrator\\:\\:hydrate\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Testing/SimpleHydrator.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\SimpleHydrator\\:\\:hydrate\\(\\) has parameter \\$class with no type specified\\.$#" + count: 1 + path: src/Testing/SimpleHydrator.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\SimpleHydrator\\:\\:hydrateReflection\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Testing/SimpleHydrator.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Testing\\\\SimpleHydrator\\:\\:hydrateReflection\\(\\) has parameter \\$reflection with generic class ReflectionClass but does not specify its types\\: T$#" + count: 1 + path: src/Testing/SimpleHydrator.php + + - + message: "#^Unsafe call to private method LaravelDoctrine\\\\ORM\\\\Testing\\\\SimpleHydrator\\:\\:hydrateReflection\\(\\) through static\\:\\:\\.$#" + count: 1 + path: src/Testing/SimpleHydrator.php + + - + message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQueryBuilder\\(\\)\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Call to function is_null\\(\\) with string will always evaluate to false\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Validation\\\\DoctrinePresenceVerifier\\:\\:getCount\\(\\) has parameter \\$extra with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Validation\\\\DoctrinePresenceVerifier\\:\\:getMultiCount\\(\\) has parameter \\$extra with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Validation\\\\DoctrinePresenceVerifier\\:\\:getMultiCount\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Validation\\\\DoctrinePresenceVerifier\\:\\:queryExtraConditions\\(\\) has no return type specified\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Method LaravelDoctrine\\\\ORM\\\\Validation\\\\DoctrinePresenceVerifier\\:\\:queryExtraConditions\\(\\) has parameter \\$extra with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Validation/DoctrinePresenceVerifier.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 00000000..afb8b75e --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,16 @@ +parameters: + level: 7 + paths: + - src + + ignoreErrors: + - + message: '~^Function config_path not found.$~' + - + message: '~^Function database_path not found.$~' + - + message: '~^Function app not found.$~' + +includes: + - phpstan-baseline.neon + - vendor/phpstan/phpstan-deprecation-rules/rules.neon diff --git a/phpunit.xml b/phpunit.xml index c2b2fa93..493fd4a7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -8,15 +8,17 @@ convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" > + + + src/ + + ./tests/ - - - src/ - - diff --git a/src/AbstractTable.php b/src/AbstractTable.php index bf185a2e..76de44cf 100644 --- a/src/AbstractTable.php +++ b/src/AbstractTable.php @@ -7,17 +7,18 @@ use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; +/** @interal */ abstract class AbstractTable { /** * @var string */ - protected $table; + protected string $table; /** * @param string $table */ - public function __construct($table) + public function __construct(string $table) { $this->table = $table; } @@ -25,7 +26,7 @@ public function __construct($table) /** * @return Table */ - public function build() + public function build(): Table { return new Table( $this->table, @@ -40,7 +41,7 @@ public function build() * @param bool $autoincrement * @return Column */ - protected function column($name, $type, $autoincrement = false) + protected function column($name, string $type, bool $autoincrement = false): Column { $column = new Column($name, Type::getType($type)); $column->setAutoincrement($autoincrement); @@ -50,12 +51,12 @@ protected function column($name, $type, $autoincrement = false) /** * @param string $name - * @param array $columns + * @param string[] $columns * @param bool $unique * @param bool $primary * @return Index */ - protected function index($name, array $columns, $unique = false, $primary = false) + protected function index(string $name, array $columns, bool $unique = false, bool $primary = false): Index { return new Index($name, $columns, $unique, $primary); } diff --git a/src/Auth/Authenticatable.php b/src/Auth/Authenticatable.php index 8b8b2083..0a66be95 100644 --- a/src/Auth/Authenticatable.php +++ b/src/Auth/Authenticatable.php @@ -9,11 +9,13 @@ trait Authenticatable /** * @ORM\Column(type="string") */ + #[ORM\Column(type: 'string')] protected $password; /** * @ORM\Column(name="remember_token", type="string", nullable=true) */ + #[ORM\Column(name: 'remember_token', type: 'string', nullable: true)] protected $rememberToken; /** diff --git a/src/Auth/DoctrineUserProvider.php b/src/Auth/DoctrineUserProvider.php index b3c2e0b4..bc995796 100644 --- a/src/Auth/DoctrineUserProvider.php +++ b/src/Auth/DoctrineUserProvider.php @@ -23,16 +23,16 @@ class DoctrineUserProvider implements UserProvider protected $em; /** - * @var string + * @var class-string */ protected $entity; /** * @param Hasher $hasher * @param EntityManagerInterface $em - * @param string $entity + * @param class-string $entity */ - public function __construct(Hasher $hasher, EntityManagerInterface $em, $entity) + public function __construct(Hasher $hasher, EntityManagerInterface $em, string $entity) { $this->hasher = $hasher; $this->entity = $entity; @@ -79,7 +79,7 @@ public function updateRememberToken(Authenticatable $user, $token) { $user->setRememberToken($token); $this->em->persist($user); - $this->em->flush($user); + $this->em->flush(); } /** @@ -116,7 +116,7 @@ public function validateCredentials(Authenticatable $user, array $credentials) /** * Returns repository for the entity. - * @return EntityRepository + * @return EntityRepository */ protected function getRepository() { diff --git a/src/Auth/Passwords/DoctrineTokenRepository.php b/src/Auth/Passwords/DoctrineTokenRepository.php index bde11035..d51194d3 100644 --- a/src/Auth/Passwords/DoctrineTokenRepository.php +++ b/src/Auth/Passwords/DoctrineTokenRepository.php @@ -108,7 +108,7 @@ public function create(CanResetPassword $user) 'token' => $this->hasher->make($token), 'date' => new Carbon('now') ]) - ->execute(); + ->executeStatement(); return $token; } @@ -125,7 +125,7 @@ protected function deleteExisting(CanResetPassword $user) ->delete($this->table) ->where('email = :email') ->setParameter('email', $user->getEmailForPasswordReset()) - ->execute(); + ->executeStatement(); } /** @@ -145,7 +145,7 @@ public function exists(CanResetPassword $user, $token) ->where('email = :email') ->setParameter('email', $email) ->setMaxResults(1) - ->execute()->fetch(); + ->executeQuery()->fetchAssociative(); return $record && !$this->tokenExpired($record['created_at']) @@ -178,7 +178,7 @@ public function recentlyCreatedToken(CanResetPassword $user) ->from($this->table) ->where('email = :email') ->setParameter('email', $user->getEmailForPasswordReset()) - ->execute()->fetch(); + ->executeQuery()->fetchAssociative(); return $record && $this->tokenRecentlyCreated($record['created_at']); } @@ -224,7 +224,7 @@ public function deleteExpired() ->delete($this->table) ->where('created_at < :expiredAt') ->setParameter('expiredAt', $expiredAt) - ->execute(); + ->executeStatement(); } /** @@ -243,7 +243,7 @@ public function createNewToken() */ protected function getTable() { - $schema = $this->connection->getSchemaManager(); + $schema = $this->connection->createSchemaManager(); if (!$schema->tablesExist($this->table)) { $schema->createTable($this->getTableDefinition()); @@ -262,7 +262,7 @@ public function getConnection() } /** - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception * @return Table */ protected function getTableDefinition() diff --git a/src/Configuration/Cache/ArrayCacheProvider.php b/src/Configuration/Cache/ArrayCacheProvider.php index 7c9506ba..875460a6 100644 --- a/src/Configuration/Cache/ArrayCacheProvider.php +++ b/src/Configuration/Cache/ArrayCacheProvider.php @@ -2,18 +2,14 @@ namespace LaravelDoctrine\ORM\Configuration\Cache; -use Doctrine\Common\Cache\ArrayCache; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; use LaravelDoctrine\ORM\Configuration\Driver; class ArrayCacheProvider implements Driver { - /** - * @param array $settings - * - * @return ArrayCache - */ - public function resolve(array $settings = []) + public function resolve(array $settings = []): CacheItemPoolInterface { - return new ArrayCache(); + return new ArrayAdapter; } } diff --git a/src/Configuration/Cache/FileCacheProvider.php b/src/Configuration/Cache/FileCacheProvider.php index 89708b55..c00bb077 100644 --- a/src/Configuration/Cache/FileCacheProvider.php +++ b/src/Configuration/Cache/FileCacheProvider.php @@ -4,7 +4,11 @@ use Doctrine\Common\Cache\FilesystemCache; use Illuminate\Contracts\Config\Repository; +use Illuminate\Contracts\Foundation\Application; use LaravelDoctrine\ORM\Configuration\Driver; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; + use function storage_path; class FileCacheProvider implements Driver @@ -22,17 +26,15 @@ public function __construct(Repository $config) $this->config = $config; } - /** - * @param array $settings - * - * @return FilesystemCache - */ - public function resolve(array $settings = []) - { - $path = $settings['path'] ?? $this->config->get('cache.stores.file.path', storage_path('framework/cache')); + public function resolve(array $settings = []): CacheItemPoolInterface + { + $path = $settings['path'] ?? $this->config->get('cache.stores.file.path', storage_path('framework/cache')); + $namespace = $settings['namespace'] ?? $this->config->get('doctrine.cache.namespace', 'doctrine-cache'); - return new FilesystemCache( - $path + return new FilesystemAdapter( + $namespace, + 0, + $path ); } } diff --git a/src/Configuration/Cache/IlluminateCacheAdapter.php b/src/Configuration/Cache/IlluminateCacheAdapter.php deleted file mode 100644 index b193769a..00000000 --- a/src/Configuration/Cache/IlluminateCacheAdapter.php +++ /dev/null @@ -1,97 +0,0 @@ -cache = $cache; - } - - /** - * Fetches an entry from the cache. - * - * @param string $id The id of the cache entry to fetch. - * - * @return string|bool The cached data or FALSE, if no cache entry exists for the given id. - */ - protected function doFetch($id) - { - return $this->cache->get($id) ?? false; - } - - /** - * Tests if an entry exists in the cache. - * - * @param string $id The cache id of the entry to check for. - * - * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. - */ - protected function doContains($id) - { - return (bool) $this->cache->has($id); - } - - /** - * Puts data into the cache. - * - * @param string $id The cache id. - * @param string $data The cache entry/data. - * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this - * cache entry (0 => infinite lifeTime). - * - * @return bool - */ - protected function doSave($id, $data, $lifeTime = false) - { - if (!$lifeTime) { - return $this->cache->forever($id, $data); - } - - return $this->cache->put($id, $data, $lifeTime); - } - - /** - * {@inheritdoc} - */ - protected function doDelete($id) - { - return $this->cache->forget($id); - } - - /** - * {@inheritdoc} - */ - protected function doFlush() - { - return $this->cache->flush(); - } - - /** - * {@inheritdoc} - */ - protected function doGetStats() - { - $stats = $this->cache->connection()->info(); - - return [ - Cache::STATS_HITS => isset($stats['keyspace_hits']) ? $stats['keyspace_hits'] : $stats['Stats']['keyspace_hits'], - Cache::STATS_MISSES => isset($stats['keyspace_misses']) ? $stats['keyspace_misses'] : $stats['Stats']['keyspace_misses'], - Cache::STATS_UPTIME => isset($stats['uptime_in_seconds']) ? $stats['uptime_in_seconds'] : $stats['Server']['uptime_in_seconds'], - Cache::STATS_MEMORY_USAGE => isset($stats['used_memory']) ? $stats['used_memory'] : $stats['Memory']['used_memory'] - ]; - } -} diff --git a/src/Configuration/Cache/IlluminateCacheProvider.php b/src/Configuration/Cache/IlluminateCacheProvider.php index 2bf739a1..6aafcd55 100644 --- a/src/Configuration/Cache/IlluminateCacheProvider.php +++ b/src/Configuration/Cache/IlluminateCacheProvider.php @@ -3,9 +3,12 @@ namespace LaravelDoctrine\ORM\Configuration\Cache; use const E_USER_DEPRECATED; + use Illuminate\Contracts\Cache\Factory; use InvalidArgumentException; use LaravelDoctrine\ORM\Configuration\Driver; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\Psr16Adapter; class IlluminateCacheProvider implements Driver { @@ -18,7 +21,7 @@ class IlluminateCacheProvider implements Driver * @var string */ protected $store; - + /** * @param Factory $cache */ @@ -27,12 +30,7 @@ public function __construct(Factory $cache) $this->cache = $cache; } - /** - * @param array $settings - * - * @return IlluminateCacheAdapter - */ - public function resolve(array $settings = []) + public function resolve(array $settings = []): CacheItemPoolInterface { $store = $this->store ?? $settings['store'] ?? null; @@ -44,8 +42,11 @@ public function resolve(array $settings = []) trigger_error('Using driver "' . $this->store . '" with a custom store is deprecated. Please use the "illuminate" driver.', E_USER_DEPRECATED); } - return new IlluminateCacheAdapter( - $this->cache->store($store) - ); + return new Psr16Adapter($this->cache->store($store), $settings['namespace'] ?? ''); + } + + public function getStore(): string + { + return $this->store; } } diff --git a/src/Configuration/Cache/PhpFileCacheProvider.php b/src/Configuration/Cache/PhpFileCacheProvider.php index 800ce70e..bd621f41 100644 --- a/src/Configuration/Cache/PhpFileCacheProvider.php +++ b/src/Configuration/Cache/PhpFileCacheProvider.php @@ -2,10 +2,11 @@ namespace LaravelDoctrine\ORM\Configuration\Cache; -use Doctrine\Common\Cache\PhpFileCache; use Illuminate\Contracts\Config\Repository; +use Illuminate\Contracts\Foundation\Application; use LaravelDoctrine\ORM\Configuration\Driver; -use function storage_path; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\PhpFilesAdapter; class PhpFileCacheProvider implements Driver { @@ -22,17 +23,15 @@ public function __construct(Repository $config) $this->config = $config; } - /** - * @param array $settings - * - * @return PhpFileCache - */ - public function resolve(array $settings = []) + public function resolve(array $settings = []): CacheItemPoolInterface { - $path = $settings['path'] ?? $this->config->get('cache.stores.file.path', storage_path('framework/cache')); + $path = $settings['path'] ?? $this->config->get('cache.stores.file.path', storage_path('framework/cache')); + $namespace = $settings['namespace'] ?? $this->config->get('doctrine.cache.namespace', 'doctrine-cache'); - return new PhpFileCache( - $path + return new PhpFilesAdapter( + $namespace, + 0, + $path, ); } } diff --git a/src/Configuration/Cache/VoidCacheProvider.php b/src/Configuration/Cache/VoidCacheProvider.php deleted file mode 100644 index 4e52da70..00000000 --- a/src/Configuration/Cache/VoidCacheProvider.php +++ /dev/null @@ -1,19 +0,0 @@ -resolvedBaseSettings = $resolvedBaseSettings; - } - - /** - * {@inheritdoc} - */ - public function resolve(array $settings = []) - { - $driver = $this->resolvedBaseSettings['driver']; - - $resolvedSettings = [ - 'wrapperClass' => $settings['wrapperClass'] ?? MasterSlaveDoctrineWrapper::class, - 'driver' => $driver, - 'master' => $this->getConnectionData(isset($settings['write']) ? $settings['write'] : [], $driver), - 'slaves' => $this->getSlavesConfig($settings['read'], $driver), - ]; - - if (!empty($settings['serverVersion'])) { - $resolvedSettings['serverVersion'] = $settings['serverVersion']; - } - - if (!empty($settings['defaultTableOptions'])) { - $resolvedSettings['defaultTableOptions'] = $settings['defaultTableOptions']; - } - - return $resolvedSettings; - } - - /** - * Returns config for slave connections. - * - * @param array $slaves - * @param string $driver - * - * @return array - */ - public function getSlavesConfig(array $slaves, $driver) - { - $handledSlaves = []; - foreach ($slaves as $slave) { - $handledSlaves[] = $this->getConnectionData($slave, $driver); - } - - return $handledSlaves; - } - - /** - * Returns single connection (slave or master) config. - * - * @param array $connection - * @param string $driver - * - * @return array - */ - private function getConnectionData(array $connection, $driver) - { - $connection = $this->replaceKeyIfExists($connection, 'database', $driver === 'pdo_sqlite' ? 'path' : 'dbname'); - $connection = $this->replaceKeyIfExists($connection, 'username', 'user'); - - return array_merge($this->getFilteredConfig(), $connection); - } - - /** - * Returns filtered configuration to use in slaves/masters. - * - * @return array - */ - private function getFilteredConfig() - { - return array_diff_key($this->resolvedBaseSettings, array_flip($this->masterSlaveConfigIgnored)); - } - - /** - * Replaces key in array if it exists. - * - * @param array $array - * @param string $oldKey - * @param string $newKey - * - * @return array - */ - private function replaceKeyIfExists(array $array, $oldKey, $newKey) - { - if (!isset($array[$oldKey])) { - return $array; - } - - $array[$newKey] = $array[$oldKey]; - unset($array[$oldKey]); - - return $array; - } -} diff --git a/src/Configuration/Connections/MysqlConnection.php b/src/Configuration/Connections/MysqlConnection.php index 7f8465a0..24c6df43 100644 --- a/src/Configuration/Connections/MysqlConnection.php +++ b/src/Configuration/Connections/MysqlConnection.php @@ -24,9 +24,9 @@ public function resolve(array $settings = []) 'unix_socket' => Arr::get($settings, 'unix_socket'), 'prefix' => Arr::get($settings, 'prefix'), 'defaultTableOptions' => Arr::get($settings, 'defaultTableOptions', []), - 'driverOptions' => Arr::get($settings, 'driverOptions', []), 'serverVersion' => Arr::get($settings, 'serverVersion'), - 'wrapperClass' => Arr::get($settings, 'wrapperClass') + 'wrapperClass' => Arr::get($settings, 'wrapperClass'), + 'driverOptions' => Arr::get($settings, 'options', []), ]; } } diff --git a/src/Configuration/Connections/PgsqlConnection.php b/src/Configuration/Connections/PgsqlConnection.php index 8768b006..20016e57 100644 --- a/src/Configuration/Connections/PgsqlConnection.php +++ b/src/Configuration/Connections/PgsqlConnection.php @@ -25,7 +25,8 @@ public function resolve(array $settings = []) 'prefix' => Arr::get($settings, 'prefix'), 'defaultTableOptions' => Arr::get($settings, 'defaultTableOptions', []), 'serverVersion' => Arr::get($settings, 'serverVersion'), - 'wrapperClass' => Arr::get($settings, 'wrapperClass') + 'wrapperClass' => Arr::get($settings, 'wrapperClass'), + 'driverOptions' => Arr::get($settings, 'options', []), ]; } } diff --git a/src/Configuration/Connections/SqliteConnection.php b/src/Configuration/Connections/SqliteConnection.php index 63491286..8e345829 100644 --- a/src/Configuration/Connections/SqliteConnection.php +++ b/src/Configuration/Connections/SqliteConnection.php @@ -22,6 +22,7 @@ public function resolve(array $settings = []) 'memory' => $this->isMemory($settings), 'path' => Arr::get($settings, 'database'), 'defaultTableOptions' => Arr::get($settings, 'defaultTableOptions', []), + 'driverOptions' => Arr::get($settings, 'options', []), 'wrapperClass' => Arr::get($settings, 'wrapperClass') ]; } @@ -33,6 +34,6 @@ public function resolve(array $settings = []) */ protected function isMemory(array $settings = []) { - return Str::startsWith(Arr::get($settings, 'database'), ':memory'); + return Str::startsWith(Arr::get($settings, 'database', ''), ':memory'); } } diff --git a/src/Configuration/Connections/SqlsrvConnection.php b/src/Configuration/Connections/SqlsrvConnection.php index e1dc9a40..d453b367 100644 --- a/src/Configuration/Connections/SqlsrvConnection.php +++ b/src/Configuration/Connections/SqlsrvConnection.php @@ -24,7 +24,15 @@ public function resolve(array $settings = []) 'charset' => Arr::get($settings, 'charset'), 'defaultTableOptions' => Arr::get($settings, 'defaultTableOptions', []), 'serverVersion' => Arr::get($settings, 'serverVersion'), - 'wrapperClass' => Arr::get($settings, 'wrapperClass') + 'wrapperClass' => Arr::get($settings, 'wrapperClass'), + 'driverOptions' => array_merge(Arr::get($settings, 'options', []), + isset($settings['encrypt']) + ? ['encrypt' => Arr::get($settings, 'encrypt')] + : [], + isset($settings['trust_server_certificate']) + ? ['trustServerCertificate' => Arr::get($settings, 'trust_server_certificate')] + : [], + ), ]; } } diff --git a/src/Configuration/CustomTypeManager.php b/src/Configuration/CustomTypeManager.php index 8bc24a90..ba15b6f6 100644 --- a/src/Configuration/CustomTypeManager.php +++ b/src/Configuration/CustomTypeManager.php @@ -10,7 +10,7 @@ class CustomTypeManager * @param $name * @param $class * - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception */ public function addType($name, $class) { @@ -34,7 +34,7 @@ public function addCustomTypes(array $typeMap) /** * @param $type * - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception * @return Type */ public function getType($type) diff --git a/src/Configuration/MetaData/Annotations.php b/src/Configuration/MetaData/Annotations.php index 530bc071..052ec04a 100644 --- a/src/Configuration/MetaData/Annotations.php +++ b/src/Configuration/MetaData/Annotations.php @@ -2,9 +2,12 @@ namespace LaravelDoctrine\ORM\Configuration\MetaData; -use Doctrine\ORM\Configuration; +use Doctrine\ORM\ORMSetup; use Illuminate\Support\Arr; +/** + * @deprecated + */ class Annotations extends MetaData { /** @@ -14,9 +17,8 @@ class Annotations extends MetaData */ public function resolve(array $settings = []) { - return (new Configuration())->newDefaultAnnotationDriver( - Arr::get($settings, 'paths', []), - Arr::get($settings, 'simple', false) + return ORMSetup::createDefaultAnnotationDriver( + Arr::get($settings, 'paths', []) ); } } diff --git a/src/Configuration/MetaData/Config.php b/src/Configuration/MetaData/Config.php deleted file mode 100644 index c7e451fc..00000000 --- a/src/Configuration/MetaData/Config.php +++ /dev/null @@ -1,35 +0,0 @@ -config = $config; - } - - /** - * @param array $settings - * - * @return \Doctrine\Persistence\Mapping\Driver\MappingDriver - */ - public function resolve(array $settings = []) - { - return new ConfigDriver( - $this->config->get(Arr::get($settings, 'mapping_file'), []) - ); - } -} diff --git a/src/Configuration/MetaData/Config/ConfigDriver.php b/src/Configuration/MetaData/Config/ConfigDriver.php deleted file mode 100644 index c36ed5c7..00000000 --- a/src/Configuration/MetaData/Config/ConfigDriver.php +++ /dev/null @@ -1,59 +0,0 @@ -mappings = $mappings; - } - - /** - * Gets the names of all mapped classes known to this driver. - * @return array The names of all mapped classes known to this driver. - */ - public function getAllClassNames() - { - return array_keys($this->mappings); - } - - /** - * Returns whether the class with the specified name should have its metadata loaded. - * This is only the case if it is either mapped as an Entity or a MappedSuperclass. - * - * @param string $className - * - * @return bool - */ - public function isTransient($className) - { - return !array_key_exists($className, $this->mappings); - } - - /** - * Gets the element of schema meta data for the class from the mapping file. - * This will lazily load the mapping file if it is not loaded yet. - * - * @param string $className - * - * @throws MappingException - * @return array The element of schema meta data. - */ - public function getElement($className) - { - return Arr::get($this->mappings, $className); - } -} diff --git a/src/Configuration/MetaData/SimplifiedYaml.php b/src/Configuration/MetaData/SimplifiedYaml.php index e0acc2f5..e841ee09 100644 --- a/src/Configuration/MetaData/SimplifiedYaml.php +++ b/src/Configuration/MetaData/SimplifiedYaml.php @@ -5,6 +5,9 @@ use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver; use Illuminate\Support\Arr; +/** + * @deprecated + */ class SimplifiedYaml extends MetaData { /** diff --git a/src/Configuration/MetaData/Yaml.php b/src/Configuration/MetaData/Yaml.php index 5e0296c6..a3d8ca9e 100644 --- a/src/Configuration/MetaData/Yaml.php +++ b/src/Configuration/MetaData/Yaml.php @@ -5,6 +5,9 @@ use Doctrine\ORM\Mapping\Driver\YamlDriver; use Illuminate\Support\Arr; +/** + * @deprecated + */ class Yaml extends MetaData { /** diff --git a/src/Console/ClearMetadataCacheCommand.php b/src/Console/ClearMetadataCacheCommand.php index 399192ec..94d17157 100644 --- a/src/Console/ClearMetadataCacheCommand.php +++ b/src/Console/ClearMetadataCacheCommand.php @@ -2,64 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\Common\Cache\ApcCache; -use Doctrine\Common\Cache\XcacheCache; -use Doctrine\Persistence\ManagerRegistry; -use InvalidArgumentException; -use LogicException; +use Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand; -class ClearMetadataCacheCommand extends Command +class ClearMetadataCacheCommand extends MetadataCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:clear:metadata:cache - {--flush : If defined, cache entries will be flushed instead of deleted/invalidated.} - {--em= : Clear cache for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Clear all metadata cache of the various cache drivers.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - $cache = $em->getConfiguration()->getMetadataCacheImpl(); - - if (!$cache) { - throw new InvalidArgumentException('No Result cache driver is configured on given EntityManager.'); - } - - if ($cache instanceof ApcCache) { - throw new LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); - } - - if ($cache instanceof XcacheCache) { - throw new LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); - } - - $this->message('Clearing result cache entries for ' . $name . ' entity manager'); - - $result = $cache->deleteAll(); - $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; + parent::__construct($entityManagerProvider); + } - if ($this->option('flush')) { - $result = $cache->flushAll(); - $message = ($result) ? 'Successfully flushed cache entries.' : $message; - } + protected function configure(): void + { + parent::configure(); - $this->info($message); - } + $this->setName('doctrine:clear:metadata:cache'); } } diff --git a/src/Console/ClearQueryCacheCommand.php b/src/Console/ClearQueryCacheCommand.php index 7225699c..87715995 100644 --- a/src/Console/ClearQueryCacheCommand.php +++ b/src/Console/ClearQueryCacheCommand.php @@ -2,64 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\Common\Cache\ApcCache; -use Doctrine\Common\Cache\XcacheCache; -use Doctrine\Persistence\ManagerRegistry; -use InvalidArgumentException; -use LogicException; +use Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand; -class ClearQueryCacheCommand extends Command +class ClearQueryCacheCommand extends QueryCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:clear:query:cache - {--flush : If defined, cache entries will be flushed instead of deleted/invalidated.} - {--em= : Clear cache for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Clear all query cache of the various cache drivers.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - $cache = $em->getConfiguration()->getQueryCacheImpl(); - - if (!$cache) { - throw new InvalidArgumentException('No Result cache driver is configured on given EntityManager.'); - } - - if ($cache instanceof ApcCache) { - throw new LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); - } - - if ($cache instanceof XcacheCache) { - throw new LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); - } - - $this->message('Clearing result cache entries for ' . $name . ' entity manager'); - - $result = $cache->deleteAll(); - $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; + parent::__construct($entityManagerProvider); + } - if ($this->option('flush')) { - $result = $cache->flushAll(); - $message = ($result) ? 'Successfully flushed cache entries.' : $message; - } + protected function configure(): void + { + parent::configure(); - $this->info($message); - } + $this->setName('doctrine:clear:query:cache'); } } diff --git a/src/Console/ClearResultCacheCommand.php b/src/Console/ClearResultCacheCommand.php index 896b21ed..fb5bb73e 100644 --- a/src/Console/ClearResultCacheCommand.php +++ b/src/Console/ClearResultCacheCommand.php @@ -2,64 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\Common\Cache\ApcCache; -use Doctrine\Common\Cache\XcacheCache; -use Doctrine\Persistence\ManagerRegistry; -use InvalidArgumentException; -use LogicException; +use Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand; -class ClearResultCacheCommand extends Command +class ClearResultCacheCommand extends ResultCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:clear:result:cache - {--flush : If defined, cache entries will be flushed instead of deleted/invalidated.} - {--em= : Clear cache for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Clear all result cache of the various cache drivers.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - $cache = $em->getConfiguration()->getResultCacheImpl(); - - if (!$cache) { - throw new InvalidArgumentException('No Result cache driver is configured on given EntityManager.'); - } - - if ($cache instanceof ApcCache) { - throw new LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); - } - - if ($cache instanceof XcacheCache) { - throw new LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI."); - } - - $this->message('Clearing result cache entries for ' . $name . ' entity manager'); - - $result = $cache->deleteAll(); - $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; + parent::__construct($entityManagerProvider); + } - if ($this->option('flush')) { - $result = $cache->flushAll(); - $message = ($result) ? 'Successfully flushed cache entries.' : $message; - } + protected function configure(): void + { + parent::configure(); - $this->info($message); - } + $this->setName('doctrine:clear:result:cache'); } } diff --git a/src/Console/ConvertConfigCommand.php b/src/Console/ConvertConfigCommand.php deleted file mode 100644 index 08733f10..00000000 --- a/src/Console/ConvertConfigCommand.php +++ /dev/null @@ -1,152 +0,0 @@ -setName('doctrine:config:convert') - ->setAliases(['doctrine:config:convert']) - ->setDescription('Convert the configuration file for another laravel-doctrine implementation into a valid configuration for LaravelDoctrine\ORM') - ->setDefinition([ - new InputArgument( - 'author', - InputArgument::REQUIRED, - 'The name of the author of the repository being migrated from. Options are "atrauzzi" and "mitchellvanw"' - ), - new InputOption( - 'dest-path', - null, - InputOption::VALUE_OPTIONAL, - 'Where the generated configuration should be placed', - 'config' - ), - new InputOption( - 'source-file', - null, - InputOption::VALUE_OPTIONAL, - 'Where the source configuration file is located.', - 'config/doctrine.php' - ) - ]); - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int|null|void - */ - public function execute(InputInterface $input, OutputInterface $output) - { - if (($destPath = $input->getOption('dest-path')) === null) { - $destPath = 'config'; - } - - if (($author = $input->getArgument('author')) === null) { - throw new InvalidArgumentException('Missing author option'); - } - - if (($sourceFilePath = $input->getOption('source-file')) === null) { - $sourceFilePath = 'config/doctrine.php'; - } - - $destPath = realpath($destPath); - - if (!is_dir($destPath)) { - mkdir($destPath, 0777, true); - } - - if (!is_writable($destPath)) { - throw new InvalidArgumentException( - sprintf( - "Configuration destination directory '%s' does not have write permissions.", - $destPath - ) - ); - } - - $destFilePath = $destPath . '/doctrine.generated.php'; - - $originalSourceFilePath = $sourceFilePath; - $sourceFilePath = realPath($sourceFilePath); - - if (!file_exists($sourceFilePath)) { - throw new InvalidArgumentException( - sprintf( - "Source file at path '%s' does not exist.", - $originalSourceFilePath - ) - ); - } - - $sourceArrayConfig = include $sourceFilePath; - - $viewFactory = $this->createViewFactory(); - - $className = __NAMESPACE__ . '\ConfigMigrations\\' . ucfirst($author) . 'Migrator'; - - if (!class_exists($className)) { - throw new InvalidArgumentException('Author provided was not a valid choice.'); - } else { - $configMigrator = new $className($viewFactory); - $convertedConfigString = $configMigrator->convertConfiguration($sourceArrayConfig); - } - - file_put_contents($destFilePath, 'writeln('Conversion successful. File generated at ' . $destFilePath); - } - - /** - * @return \Illuminate\View\Factory - */ - protected function createViewFactory() - { - $FileViewFinder = new FileViewFinder( - new Filesystem, - [realpath(__DIR__ . '/ConfigMigrations/templates')] - ); - - $dispatcher = new Dispatcher(new Container); - - $compiler = new BladeCompiler(new Filesystem(), storage_path() . '/framework/views'); - $bladeEngine = new CompilerEngine($compiler); - $engineResolver = new EngineResolver(); - $engineResolver->register('blade', function () use (&$bladeEngine) { - return $bladeEngine; - }); - - $viewFactory = new \Illuminate\View\Factory($engineResolver, $FileViewFinder, $dispatcher); - - return $viewFactory; - } -} diff --git a/src/Console/ConvertMappingCommand.php b/src/Console/ConvertMappingCommand.php deleted file mode 100644 index f59443d7..00000000 --- a/src/Console/ConvertMappingCommand.php +++ /dev/null @@ -1,141 +0,0 @@ -option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - - if ($this->option('from-database') === true) { - $databaseDriver = new DatabaseDriver( - $em->getConnection()->getSchemaManager() - ); - - $em->getConfiguration()->setMetadataDriverImpl( - $databaseDriver - ); - - if (($namespace = $this->option('namespace')) !== null) { - $databaseDriver->setNamespace($namespace); - } - } - - $cmf = new DisconnectedClassMetadataFactory(); - $cmf->setEntityManager($em); - $metadata = $cmf->getAllMetadata(); - $metadata = MetadataFilter::filter($metadata, $this->option('filter')); - - // Process destination directory - if (!is_dir($destPath = $this->argument('dest-path'))) { - mkdir($destPath, 0775, true); - } - $destPath = realpath($destPath); - - if (!file_exists($destPath)) { - throw new \InvalidArgumentException( - sprintf( - "Mapping destination directory '%s' does not exist.", - $this->argument('dest-path') - ) - ); - } - - if (!is_writable($destPath)) { - throw new \InvalidArgumentException( - sprintf( - "Mapping destination directory '%s' does not have write permissions.", - $destPath - ) - ); - } - - $toType = strtolower($this->argument('to-type')); - - $exporter = $this->getExporter($toType, $destPath); - $exporter->setOverwriteExistingFiles($this->option('force')); - - if ($toType == 'annotation') { - $entityGenerator = new EntityGenerator(); - $exporter->setEntityGenerator($entityGenerator); - - $entityGenerator->setNumSpaces($this->option('num-spaces')); - - if (($extend = $this->option('extend')) !== null) { - $entityGenerator->setClassToExtend($extend); - } - } - - if (count($metadata)) { - foreach ($metadata as $class) { - $this->info(sprintf('Processing entity "%s"', $class->name)); - } - - $exporter->setMetadata($metadata); - $exporter->export(); - - $this->info(PHP_EOL . sprintf( - 'Exporting "%s" mapping information to "%s"', - $toType, - $destPath - )); - } else { - $this->info('No Metadata Classes to process.'); - } - } - } - - /** - * @param string $toType - * @param string $destPath - * - * @return \Doctrine\ORM\Tools\Export\Driver\AbstractExporter - */ - protected function getExporter($toType, $destPath) - { - $cme = new ClassMetadataExporter(); - - $cme->registerExportDriver('fluent', FluentExporter::class); - - return $cme->getExporter($toType, $destPath); - } -} diff --git a/src/Console/EnsureProductionSettingsCommand.php b/src/Console/EnsureProductionSettingsCommand.php index 000f21b0..a73e25c1 100644 --- a/src/Console/EnsureProductionSettingsCommand.php +++ b/src/Console/EnsureProductionSettingsCommand.php @@ -5,48 +5,20 @@ use Doctrine\Persistence\ManagerRegistry; use Exception; -class EnsureProductionSettingsCommand extends Command +/** + * @deprecated + */ +class EnsureProductionSettingsCommand extends \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:ensure:production - {--with-db : Flag to also inspect database connection existence.} - {--em= : Ensure production settings for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Verify that Doctrine is properly configured for a production environment.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - - try { - $em->getConfiguration()->ensureProductionSettings(); - - if ($this->option('with-db')) { - $em->getConnection()->connect(); - } - } catch (Exception $e) { - $this->error('Error for ' . $name . ' entity manager'); - $this->error($e->getMessage()); + parent::__construct($entityManagerProvider); + } - return 1; - } + protected function configure(): void + { + parent::configure(); - $this->comment('Environment for ' . $name . ' entity manager is correctly configured for production.'); - } + $this->setName('doctrine:ensure:production'); } } diff --git a/src/Console/EntityManagerProvider.php b/src/Console/EntityManagerProvider.php new file mode 100644 index 00000000..64f59df5 --- /dev/null +++ b/src/Console/EntityManagerProvider.php @@ -0,0 +1,31 @@ +managerRegistry->getManager(); + + assert($entityManager instanceof EntityManagerInterface); + + return $entityManager; + } + + public function getManager(string $name): EntityManagerInterface + { + $entityManager = $this->managerRegistry->getManager($name); + + assert($entityManager instanceof EntityManagerInterface); + + return $entityManager; + } +} diff --git a/src/Console/Exporters/FluentExporter.php b/src/Console/Exporters/FluentExporter.php deleted file mode 100644 index 697c6896..00000000 --- a/src/Console/Exporters/FluentExporter.php +++ /dev/null @@ -1,465 +0,0 @@ -getImports($metadata) as $import) { - $lines[] = $import; - } - - $lines[] = null; - $lines[] = 'class ' . $this->getClassNameShort($metadata) . 'Mapping extends ' . $this->getExtendShort($metadata) . ' {'; - $lines[] = null; - - foreach ($this->exportMapFor($metadata) as $line) { - $lines[] = $line; - } - - $lines[] = null; - - foreach ($this->exportMap($metadata) as $line) { - $lines[] = $line; - } - - $lines[] = '}'; - - return implode("\n", $lines); - } - - /** - * @param mixed $var - * - * @return string - */ - protected function _varExport($var) - { - $export = var_export($var, true); - $export = str_replace("\n", PHP_EOL . str_repeat(' ', 8), $export); - $export = str_replace(' ', ' ', $export); - $export = str_replace('array (', 'array(', $export); - $export = str_replace('array( ', 'array(', $export); - $export = str_replace(',)', ')', $export); - $export = str_replace(', )', ')', $export); - $export = str_replace(' ', ' ', $export); - - return $export; - } - - /** - * @param ClassMetadataInfo $metadata - * @return string - */ - protected function getClassName(ClassMetadataInfo $metadata) - { - return ltrim(str_replace($metadata->namespace, '', $metadata->name), '\\'); - } - - /** - * @param ClassMetadataInfo $metadata - * - * @return string - */ - private function getExtend(ClassMetadataInfo $metadata) - { - if ($metadata->isMappedSuperclass) { - return 'LaravelDoctrine\Fluent\MappedSuperClassMapping'; - } elseif ($metadata->isEmbeddedClass) { - return 'LaravelDoctrine\Fluent\EmbeddableMapping'; - } else { - return 'LaravelDoctrine\Fluent\EntityMapping'; - } - } - - /** - * @param ClassMetadataInfo $metadata - * @return mixed - */ - private function getExtendShort(ClassMetadataInfo $metadata) - { - return $this->classBaseName($this->getExtend($metadata)); - } - - /** - * @param string $className - * @return string - */ - private function classBaseName($className) - { - if (strpos($className, '\\') === false) { - return $className; - } - - return substr($className, strrpos($className, '\\') + 1); - } - - /** - * @param ClassMetadataInfo $metadata - * @return array - */ - private function getImports(ClassMetadataInfo $metadata) - { - $extend = $this->getExtend($metadata); - - $imports = [ - 'LaravelDoctrine\Fluent\Fluent', - 'Doctrine\ORM\Mapping\ClassMetadataInfo', - $extend, - $metadata->name - ]; - - // Sort alphabetically - asort($imports); - - return array_map(function ($import) { - return 'use ' . $import . ';'; - }, $imports); - } - - /** - * @param ClassMetadataInfo $metadata - * @return array - */ - protected function exportMapFor(ClassMetadataInfo $metadata) - { - $lines = [ - '/**', - ' *', - ' * Returns the fully qualified name of the class that this mapper maps.', - ' *', - ' * @return string', - ' */', - 'public function mapFor()', - '{', - self::TAB . 'return ' . $this->getClassNameShort($metadata) . '::class;', - '}', - ]; - - return array_map(function ($line) { - return self::TAB . $line; - }, $lines); - } - - /** - * @param ClassMetadataInfo $metadata - * @return array - */ - private function exportMap(ClassMetadataInfo $metadata) - { - $lines = [ - '/**', - ' *', - ' * Load the object\'s metadata through the Metadata Builder object.', - ' *', - ' * @param Fluent $builder', - ' */', - 'public function map(Fluent $builder)', - '{', - ]; - - foreach ($this->exportMapMethodContent($metadata) as $line) { - $lines[] = $line; - } - - $lines[] = '}'; - - return array_map(function ($line) { - return self::TAB . $line; - }, $lines); - } - - /** - * @param ClassMetadataInfo $metadata - * @return array - */ - private function exportMapMethodContent(ClassMetadataInfo $metadata) - { - if ($metadata->customRepositoryClassName) { - $lines[] = "\$builder->entity()->setRepositoryClass('" . $metadata->customRepositoryClassName . ")';"; - } - - if ($metadata->table) { - $lines[] = '$builder->table(\'' . $metadata->table['name'] . '\');'; - } - - if ($metadata->inheritanceType && $this->_getInheritanceTypeString($metadata->inheritanceType) !== 'NONE') { - $dColumn = ''; - if ($metadata->discriminatorColumn) { - $dColumn = '->column(\'' . $metadata->discriminatorColumn['name'] . '\', \'' . $metadata->discriminatorColumn['type'] . '\', \'' . $metadata->discriminatorColumn['length'] . '\')'; - } - - $dMap = ''; - if ($metadata->discriminatorMap) { - $dMap = '->map(' . $this->_varExport($metadata->discriminatorMap) . ')'; - } - - $lines[] = '$builder->inheritance(ClassMetadataInfo::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ')' . $dColumn . $dMap . ';'; - } - - if ($metadata->lifecycleCallbacks) { - foreach ($metadata->lifecycleCallbacks as $event => $callbacks) { - foreach ($callbacks as $callback) { - $lines[] = "\$builder->events()->$event('$callback');"; - } - } - } - - $lines[] = null; - - foreach ($metadata->fieldMappings as $fieldMapping) { - $lines[] = $this->convertField($metadata, $fieldMapping); - } - - $lines[] = null; - - foreach ($metadata->associationMappings as $associationMapping) { - $lines[] = $this->exportAssociations($associationMapping); - } - - return array_map(function ($line) { - return self::TAB . $line; - }, $lines); - } - - /** - * @param ClassMetadataInfo $metadata - * @param $fieldMapping - * @return array - */ - private function convertField(ClassMetadataInfo $metadata, $fieldMapping) - { - $type = $fieldMapping['type']; - $name = $fieldMapping['fieldName']; - - $column = ''; - if (isset($fieldMapping['columnName']) && $fieldMapping['columnName'] != $name) { - $column = $fieldMapping['columnName']; - $column = "->name('$column')"; - } - - $length = ''; - if (isset($fieldMapping['length']) && !is_null($fieldMapping['length'])) { - $length = $fieldMapping['length']; - $length = "->length($length)"; - } - - $nullable = ''; - if (isset($fieldMapping['nullable']) && $fieldMapping['nullable'] === true) { - $nullable = "->nullable()"; - } - - $unique = ''; - if (isset($fieldMapping['unique']) && $fieldMapping['unique'] === true) { - $unique = "->unique()"; - } - - $primary = ''; - if (isset($fieldMapping['id']) && $fieldMapping['id'] === true) { - $primary = "->primary()"; - } - - $scale = ''; - if (isset($fieldMapping['scale']) && $fieldMapping['scale'] != 0) { - $scale = $fieldMapping['scale']; - $scale = "->scale($scale)"; - } - - $precision = ''; - if (isset($fieldMapping['precision']) && $fieldMapping['precision'] != 0) { - $precision = $fieldMapping['precision']; - $precision = "->precision($precision)"; - } - - $generatedValue = ''; - if (isset($fieldMapping['id']) && $fieldMapping['id'] === true && !$metadata->isIdentifierComposite && $generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) { - $type = 'increments'; - $primary = false; - - if ($generatorType != 'AUTO' && $generatorType != 'IDENTITY') { - $generatorType = strtolower($generatorType); - $generatedValue = '->generatedValue()->' . $generatorType . '()'; - } - } - - if ($type == 'smallint') { - $type = 'smallInteger'; - } - - return "\$builder->$type('$name')$column$length$nullable$unique$primary$scale$precision$generatedValue;"; - } - - /** - * @param array $associationMapping - * @return array - */ - private function exportAssociations(array $associationMapping) - { - $cascade = ['remove', 'persist', 'refresh', 'merge', 'detach']; - foreach ($cascade as $key => $value) { - if (!$associationMapping['isCascade' . ucfirst($value)]) { - unset($cascade[$key]); - } - } - - if (count($cascade) === 5) { - $cascade = ['all']; - } - - $fieldName = $associationMapping['fieldName']; - $targetEntity = $associationMapping['targetEntity']; - $fetch = isset($associationMapping['fetch']) ? $associationMapping['fetch'] : ''; - - $mappedBy = ''; - $inversedBy = ''; - $joinColumns = []; - $joinTable = ''; - $orphanRemoval = ''; - $orderBy = ''; - - if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) { - $method = 'oneToOne'; - $mappedBy = $associationMapping['mappedBy']; - $inversedBy = $associationMapping['inversedBy']; - $joinColumns = $associationMapping['joinColumns']; - $orphanRemoval = $associationMapping['orphanRemoval']; - } elseif ($associationMapping['type'] & ClassMetadataInfo::MANY_TO_ONE) { - $method = 'manyToOne'; - $mappedBy = $associationMapping['mappedBy']; - $inversedBy = $associationMapping['inversedBy']; - $joinColumns = $associationMapping['joinColumns']; - $orphanRemoval = $associationMapping['orphanRemoval']; - } elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) { - $method = 'oneToMany'; - $potentialAssociationMappingIndexes = [ - 'mappedBy', - 'orphanRemoval', - 'orderBy', - ]; - foreach ($potentialAssociationMappingIndexes as $index) { - if (isset($associationMapping[$index])) { - $oneToManyMappingArray[$index] = $associationMapping[$index]; - } - } - - if (isset($oneToManyMappingArray['mappedBy'])) { - $mappedBy = $oneToManyMappingArray['mappedBy']; - } - if (isset($oneToManyMappingArray['orphanRemoval'])) { - $orphanRemoval = $oneToManyMappingArray['orphanRemoval']; - } - if (isset($oneToManyMappingArray['orderBy'])) { - $orderBy = $oneToManyMappingArray['orderBy']; - } - } elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) { - $method = 'manyToMany'; - $potentialAssociationMappingIndexes = [ - 'mappedBy', - 'joinTable', - 'orderBy', - ]; - foreach ($potentialAssociationMappingIndexes as $index) { - if (isset($associationMapping[$index])) { - $manyToManyMappingArray[$index] = $associationMapping[$index]; - } - } - - if (isset($manyToManyMappingArray['mappedBy'])) { - $mappedBy = $manyToManyMappingArray['mappedBy']; - } - if (isset($manyToManyMappingArray['joinTable'])) { - $joinTable = $manyToManyMappingArray['joinTable']; - } - if (isset($manyToManyMappingArray['orderBy'])) { - $orderBy = $manyToManyMappingArray['orderBy']; - } - } - - if ($mappedBy != '') { - $mappedBy = "->mappedBy('$mappedBy')"; - } - - if ($inversedBy != '') { - $inversedBy = "->inversedBy('$inversedBy')"; - } - - if ($fetch != '') { - switch ($fetch) { - - case ClassMetadataInfo::FETCH_LAZY: - $fetch = ''; // Lazy is default anyway - break; - - case ClassMetadataInfo::FETCH_EAGER: - $fetch = "->fetchEager()"; - break; - - case ClassMetadataInfo::FETCH_EXTRA_LAZY: - $fetch = "->fetchExtraLazy()"; - break; - } - } - - $joinColumn = ''; - if ($joinColumns) { - foreach ($joinColumns as $c) { - $columnName = $c['name']; - $referencedColumnName = $c['referencedColumnName']; - $nullable = !isset($c['nullable']) || $c['nullable'] == true ? 'true' : 'false'; - $unique = !isset($c['unique']) || $c['nullable'] == false ? 'false' : 'true'; - $onDelete = isset($c['onDelete']) ? '\'' . $c['onDelete'] . '\'' : 'null'; - $columnDefinition = isset($c['columnDefinition']) ? '\'' . $c['columnDefinition'] . '\'' : 'null'; - - $joinColumn .= "->addJoinColumn('$fieldName', '$columnName', '$referencedColumnName', $nullable, $unique, $onDelete, $columnDefinition)"; - } - } - - if ($orphanRemoval != '' && $orphanRemoval == true) { - $orphanRemoval = "->orphanRemoval()"; - } - - $cascadeChain = ''; - if (count($cascade) > 0) { - foreach ($cascade as $option) { - $cascadeChain .= '->cascade' . ucfirst($option) . '()'; - } - } - - $joinTableChain = ''; - if ($joinTable != '') { - if (isset($joinTable['name'])) { - $joinTableChain .= '->joinTable(\'' . $joinTable['name'] . '\')'; - } - } - - return "\$builder->$method('$targetEntity', '$fieldName')$mappedBy$inversedBy$cascadeChain$fetch$joinColumn$orphanRemoval$orderBy$joinTableChain;"; - } - - private function getClassNameShort(ClassMetadataInfo $metadata) - { - return $this->classBaseName($metadata->name); - } -} diff --git a/src/Console/GenerateEntitiesCommand.php b/src/Console/GenerateEntitiesCommand.php deleted file mode 100644 index 1aa19ca8..00000000 --- a/src/Console/GenerateEntitiesCommand.php +++ /dev/null @@ -1,102 +0,0 @@ -option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - - $this->comment(''); - $this->message('Generating getter and setter for ' . $name . ' entity manager...', 'blue'); - - $cmf = new DisconnectedClassMetadataFactory(); - $cmf->setEntityManager($em); - $metadatas = $cmf->getAllMetadata(); - $metadatas = MetadataFilter::filter($metadatas, $this->option('filter')); - - $destPath = base_path($this->argument('dest-path') ?:'app/Entities'); - - if (!is_dir($destPath)) { - mkdir($destPath, 0777, true); - } - - $destPath = realpath($destPath); - - if (!file_exists($destPath)) { - throw new \InvalidArgumentException( - sprintf( - "Proxies destination directory ' < info>%s ' does not exist.", - $em->getConfiguration()->getProxyDir() - ) - ); - } - - if (count($metadatas)) { - - // Create EntityGenerator - $entityGenerator = new EntityGenerator(); - - $entityGenerator->setGenerateAnnotations($this->option('generate-annotations')); - $entityGenerator->setGenerateStubMethods($this->option('generate-methods')); - $entityGenerator->setRegenerateEntityIfExists($this->option('regenerate-entities')); - $entityGenerator->setUpdateEntityIfExists($this->option('update-entities')); - $entityGenerator->setNumSpaces((int) $this->option('num-spaces')); - $entityGenerator->setBackupExisting(!$this->option('no-backup')); - - if (($extend = $this->option('extend')) !== null) { - $entityGenerator->setClassToExtend($extend); - } - - foreach ($metadatas as $metadata) { - $this->comment( - sprintf('Processing entity "%s"', $metadata->name) - ); - } - - // Generating Entities - $entityGenerator->generate($metadatas, $destPath); - - // Outputting information message - $this->comment(PHP_EOL . sprintf('Entity classes generated to "%s"', $destPath)); - } - } - } -} diff --git a/src/Console/GenerateProxiesCommand.php b/src/Console/GenerateProxiesCommand.php index f0653006..ea23ea4c 100644 --- a/src/Console/GenerateProxiesCommand.php +++ b/src/Console/GenerateProxiesCommand.php @@ -6,85 +6,17 @@ use Doctrine\Persistence\ManagerRegistry; use InvalidArgumentException; -class GenerateProxiesCommand extends Command +class GenerateProxiesCommand extends \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:generate:proxies - {dest-path? : The path to generate your proxy classes. If none is provided, it will attempt to grab from configuration.} - {-- filter=* : A string pattern used to match entities that should be processed.} - {--em= : Generate proxies for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Generates proxy classes for entity classes.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - - $this->comment(''); - $this->message('Generating proxies for ' . $name . ' entity manager...', 'blue'); - - $metadatas = $em->getMetadataFactory()->getAllMetadata(); - $metadatas = MetadataFilter::filter($metadatas, $this->option('filter')); - - // Process destination directory - if (($destPath = $this->argument('dest-path')) === null) { - $destPath = $em->getConfiguration()->getProxyDir(); - } - - if (!is_dir($destPath)) { - mkdir($destPath, 0777, true); - } - - $destPath = realpath($destPath); - - if (!file_exists($destPath)) { - throw new InvalidArgumentException( - sprintf( - "Proxies destination directory '%s' does not exist.", - $em->getConfiguration()->getProxyDir() - ) - ); - } - - if (!is_writable($destPath)) { - throw new InvalidArgumentException( - sprintf( - "Proxies destination directory '%s' does not have write permissions.", - $destPath - ) - ); - } - - if (count($metadatas)) { - foreach ($metadatas as $metadata) { - $this->comment( - sprintf('Processing entity "%s"', $metadata->name) - ); - } + parent::__construct($entityManagerProvider); + } - // Generating Proxies - $em->getProxyFactory()->generateProxyClasses($metadatas, $destPath); + protected function configure(): void + { + parent::configure(); - // Outputting information message - $this->comment(sprintf('Proxy classes generated to "%s"', $destPath)); - } else { - $this->error('No Metadata Classes to process.'); - } - } + $this->setName('doctrine:generate:proxies'); } } diff --git a/src/Console/GenerateRepositoriesCommand.php b/src/Console/GenerateRepositoriesCommand.php deleted file mode 100644 index f4e963f6..00000000 --- a/src/Console/GenerateRepositoriesCommand.php +++ /dev/null @@ -1,107 +0,0 @@ -option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - /** @var EntityManagerInterface $em */ - $em = $registry->getManager($name); - - $this->comment(''); - $this->message('Generating repositories for ' . $name . ' entity manager...', 'blue'); - - $metadatas = $em->getMetadataFactory()->getAllMetadata(); - $metadatas = MetadataFilter::filter($metadatas, $this->option('filter')); - - $repositoryName = $em->getConfiguration()->getDefaultRepositoryClassName(); - - $destPath = base_path($this->argument('dest-path') ?:'app/Repositories'); - - if (!is_dir($destPath)) { - mkdir($destPath, 0777, true); - } - - $destPath = realpath($destPath); - - if (!file_exists($destPath)) { - throw new InvalidArgumentException( - sprintf( - "Repositories destination directory '%s' does not exist.", - $em->getConfiguration()->getProxyDir() - ) - ); - } - - if (!is_writable($destPath)) { - throw new InvalidArgumentException( - sprintf( - "Repositories destination directory '%s' does not have write permissions.", - $destPath - ) - ); - } - - if (empty($metadatas)) { - $this->error('No Metadata Classes to process.'); - - return; - } - - $numRepositories = 0; - $generator = new EntityRepositoryGenerator(); - - $generator->setDefaultRepositoryName($repositoryName); - - foreach ($metadatas as $metadata) { - if ($metadata->customRepositoryClassName) { - $this->comment( - sprintf('Processing repository "%s"', $metadata->customRepositoryClassName) - ); - - $generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath); - - ++$numRepositories; - } - } - - if ($numRepositories === 0) { - $this->error('No Repository classes were found to be processed.'); - - return; - } - - $this->comment(sprintf('Repository classes generated to "%s"', $destPath)); - } - } -} diff --git a/src/Console/InfoCommand.php b/src/Console/InfoCommand.php index 69f38060..929058a0 100644 --- a/src/Console/InfoCommand.php +++ b/src/Console/InfoCommand.php @@ -6,63 +6,17 @@ use Doctrine\Persistence\ManagerRegistry; use Exception; -class InfoCommand extends Command +class InfoCommand extends \Doctrine\ORM\Tools\Console\Command\InfoCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:info - {--em= : Info for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Show basic information about all mapped entities.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - * - * @throws Exception - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - $exit = 0; - - foreach ($names as $name) { - $em = $registry->getManager($name); - - $entityClassNames = $em->getConfiguration() - ->getMetadataDriverImpl() - ->getAllClassNames(); - - if (!$entityClassNames) { - throw new Exception( - 'You do not have any mapped Doctrine ORM entities according to the current configuration. ' . - 'If you have entities or mapping files you should check your mapping configuration for errors.' - ); - } - - $this->message(sprintf("Found %d mapped entities for {$name} entity manager:", count($entityClassNames))); - - foreach ($entityClassNames as $entityClassName) { - try { - $em->getClassMetadata($entityClassName); - $this->comment(sprintf("[OK] %s", $entityClassName)); - } catch (MappingException $e) { - $this->comment("[FAIL] " . $entityClassName); - $this->comment(sprintf("%s", $e->getMessage())); - $this->comment(''); + parent::__construct($entityManagerProvider); + } - $exit = 1; - } - } - } + protected function configure(): void + { + parent::configure(); - return $exit; + $this->setName('doctrine:info'); } } diff --git a/src/Console/MappingImportCommand.php b/src/Console/MappingImportCommand.php deleted file mode 100644 index f82a9efe..00000000 --- a/src/Console/MappingImportCommand.php +++ /dev/null @@ -1,134 +0,0 @@ -option('em'); - $em = $registry->getManager($emName); - - $destPath = base_path($this->argument('dest-path') ? $this->argument('dest-path') : 'app/Mappings'); - - $simplified = false; - $type = $this->argument('mapping-type'); - - if (Str::startsWith($type, 'simplified')) { - $simplified = true; - - if (Str::contains($type, 'xml')) { - $type = 'xml'; - } elseif (Str::contains($type, 'yaml')) { - $type = 'yaml'; - } - } - - $cme = new ClassMetadataExporter(); - $exporter = $cme->getExporter($type); - - $exporter->setOverwriteExistingFiles($this->option('force')); - - if ('annotation' === $type) { - $entityGenerator = $this->getEntityGenerator(); - $exporter->setEntityGenerator($entityGenerator); - } - - $databaseDriver = new DatabaseDriver($em->getConnection()->getSchemaManager()); - - // set namespace that will be used to generate metadata files - $namespace = $this->option('namespace'); - if ($namespace) { - $databaseDriver->setNamespace($namespace); - } - - $em->getConfiguration()->setMetadataDriverImpl($databaseDriver); - - $cmf = new DisconnectedClassMetadataFactory(); - $cmf->setEntityManager($em); - - $metadata = $cmf->getAllMetadata(); - $metadata = MetadataFilter::filter($metadata, $this->option('filter')); - - if ($metadata) { - $this->info(sprintf('Importing mapping information from "%s" entity manager', $emName)); - - foreach ($metadata as $class) { - $className = $class->name; - if ('annotation' === $type) { - $path = $destPath . '/' . str_replace('\\', '.', $className) . '.php'; - } elseif ($simplified) { - $element = explode('\\', $className); - $path = $destPath . '/' . end($element) . '.orm.' . $type; - } else { - $path = $destPath . '/' . str_replace('\\', '.', $className) . '.dcm.' . $type; - } - $this->info(sprintf(' > writing %s', $path)); - $code = $exporter->exportClassMetadata($class); - if (!is_dir($dir = dirname($path))) { - mkdir($dir, 0775, true); - } - file_put_contents($path, $code); - chmod($path, 0664); - } - - return 0; - } else { - $this->error('Database does not have any mapping information.'); - $this->error(''); - - return 1; - } - } - - /** - * get a doctrine entity generator - * - * @return EntityGenerator - */ - protected function getEntityGenerator() - { - $entityGenerator = new EntityGenerator(); - - $entityGenerator->setGenerateAnnotations(false); - $entityGenerator->setGenerateStubMethods(true); - $entityGenerator->setRegenerateEntityIfExists(false); - $entityGenerator->setUpdateEntityIfExists(true); - $entityGenerator->setNumSpaces(4); - $entityGenerator->setAnnotationPrefix('ORM\\'); - - return $entityGenerator; - } -} diff --git a/src/Console/SchemaCreateCommand.php b/src/Console/SchemaCreateCommand.php index 3d580ae5..2f6df32a 100644 --- a/src/Console/SchemaCreateCommand.php +++ b/src/Console/SchemaCreateCommand.php @@ -2,52 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\ORM\Tools\SchemaTool; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand; -class SchemaCreateCommand extends Command +class SchemaCreateCommand extends CreateCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:schema:create - {--sql : Dumps the generated SQL statements to the screen (does not execute them)} - {--em= : Create schema for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - if (!$this->option('sql')) { - $this->error('ATTENTION: This operation should not be executed in a production environment.'); - } - - foreach ($names as $name) { - $em = $registry->getManager($name); - $tool = new SchemaTool($em); - - $this->message('Creating database schema for ' . $name . ' entity manager...', 'blue'); + parent::__construct($entityManagerProvider); + } - if ($this->option('sql')) { - $sql = $tool->getCreateSchemaSql($em->getMetadataFactory()->getAllMetadata()); - $this->comment(' ' . implode('; ' . PHP_EOL, $sql)); - } else { - $tool->createSchema($em->getMetadataFactory()->getAllMetadata()); - } - } + protected function configure(): void + { + parent::configure(); - $this->info('Database schema created successfully!'); + $this->setName('doctrine:schema:create'); } } diff --git a/src/Console/SchemaDropCommand.php b/src/Console/SchemaDropCommand.php index 28ab3f61..b45b9bb2 100644 --- a/src/Console/SchemaDropCommand.php +++ b/src/Console/SchemaDropCommand.php @@ -2,99 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\ORM\Tools\SchemaTool; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand; -class SchemaDropCommand extends Command +class SchemaDropCommand extends DropCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:schema:drop - {--sql : Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.} - {--force : Don\'t ask for the deletion of the database, but force the operation to run.} - {--full : Instead of using the Class Metadata to detect the database table schema, drop ALL assets that the database contains. } - {--em= : Drop schema for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $this->error('ATTENTION: This operation should not be executed in a production environment.'); - - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - $exit = 0; - - foreach ($names as $name) { - $em = $registry->getManager($name); - $tool = new SchemaTool($em); - - $this->info(''); - $this->message('Checking scheme for ' . $name . ' entity manager...'); - - if ($this->option('sql')) { - if ($this->option('full')) { - $sql = $tool->getDropDatabaseSQL(); - } else { - $sql = $tool->getDropSchemaSQL($em->getMetadataFactory()->getAllMetadata()); - } - $this->comment(' ' . implode('; ' . PHP_EOL, $sql)); - } else { - if ($this->option('force')) { - $this->message('Dropping database schema...'); - - if ($this->option('full')) { - $tool->dropDatabase(); - } else { - $tool->dropSchema($em->getMetadataFactory()->getAllMetadata()); - } - - $this->info('Database schema dropped successfully!'); - - return 0; - } - - if ($this->option('full')) { - $sql = $tool->getDropDatabaseSQL(); - } else { - $sql = $tool->getDropSchemaSQL($em->getMetadataFactory()->getAllMetadata()); - } - - if (count($sql)) { - $pluralization = (1 === count($sql)) ? 'query' : 'queries'; - $this->message(sprintf( - 'The Schema-Tool would execute "%s" %s to update the database.', - count($sql), - $pluralization - )); - $this->message('Please run the operation by passing one - or both - of the following options:'); - - $this->comment(sprintf( - ' php artisan %s --force to execute the command', - $this->getName() - )); - $this->comment(sprintf( - ' php artisan %s --sql to dump the SQL statements to the screen', - $this->getName() - )); + parent::__construct($entityManagerProvider); + } - $exit = 1; - } else { - $this->error('Nothing to drop. The database is empty!'); - } - } - } + protected function configure(): void + { + parent::configure(); - return $exit; + $this->setName('doctrine:schema:drop'); } } diff --git a/src/Console/SchemaUpdateCommand.php b/src/Console/SchemaUpdateCommand.php index 479700d0..cbb6e470 100644 --- a/src/Console/SchemaUpdateCommand.php +++ b/src/Console/SchemaUpdateCommand.php @@ -2,102 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\ORM\Tools\SchemaTool; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand; -class SchemaUpdateCommand extends Command +class SchemaUpdateCommand extends UpdateCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:schema:update - {--clean : If defined, all assets of the database which are not relevant to the current metadata will be dropped.} - {--sql : Dumps the generated SQL statements to the screen (does not execute them)} - {--force : Causes the generated SQL statements to be physically executed against your database} - {--em= : Update schema for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - if (!$this->option('sql') && (!$this->laravel->environment('local') && !$this->option('force'))) { - $this->error('ATTENTION: This operation should not be executed in a production environment.'); - $this->error('Use the incremental update to detect changes during development and use'); - $this->error('the SQL DDL provided to manually update your database in production.'); - } - - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - - foreach ($names as $name) { - $em = $registry->getManager($name); - $tool = new SchemaTool($em); - - $this->comment(''); - $this->message( - 'Checking if database connected to ' . $name . ' entity manager needs updating...', - 'blue' - ); - - // Check if there are updates available - $sql = $tool->getUpdateSchemaSql( - $em->getMetadataFactory()->getAllMetadata(), - !$this->option('clean') - ); - - if (0 === count($sql)) { - return $this->error('Nothing to update - your database is already in sync with the current entity metadata.'); - } - - if ($this->option('sql')) { - $this->comment(' ' . implode('; ' . PHP_EOL, $sql)); - } else { - if ($this->laravel->environment('local') || $this->option('force')) { - $this->message('Updating database schema...', 'blue'); - $tool->updateSchema( - $em->getMetadataFactory()->getAllMetadata(), - !$this->option('clean') - ); - - $pluralization = (1 === count($sql)) ? 'query was' : 'queries were'; - $this->info(sprintf( - 'Database schema updated successfully! "%s" %s executed', - count($sql), - $pluralization - )); - } else { - $this->message(sprintf( - 'The Schema-Tool would execute "%s" queries to update the database.', - count($sql) - )); - } - } - } - - if (!$this->option('sql') && (!$this->laravel->environment('local') && !$this->option('force'))) { - $this->info(''); - $this->message('Please run the operation by passing one - or both - of the following options:'); - $this->comment(sprintf( - ' php artisan %s --force to execute the command', - $this->getName() - )); - $this->comment(sprintf( - ' php artisan %s --sql to dump the SQL statements to the screen', - $this->getName() - )); + parent::__construct($entityManagerProvider); + } - return 1; - } + protected function configure(): void + { + parent::configure(); - return 0; + $this->setName('doctrine:schema:update'); } } diff --git a/src/Console/SchemaValidateCommand.php b/src/Console/SchemaValidateCommand.php index 56adf0f7..ce64f4fe 100644 --- a/src/Console/SchemaValidateCommand.php +++ b/src/Console/SchemaValidateCommand.php @@ -2,71 +2,19 @@ namespace LaravelDoctrine\ORM\Console; -use Doctrine\ORM\Tools\SchemaValidator; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand; -class SchemaValidateCommand extends Command +class SchemaValidateCommand extends ValidateSchemaCommand { - /** - * The name and signature of the console command. - * @var string - */ - protected $signature = 'doctrine:schema:validate - {--skip-mapping : Skip the mapping validation check} - {--skip-sync : Skip checking if the mapping is in sync with the database} - {--em= : Validate schema for a specific entity manager }'; - - /** - * The console command description. - * @var string - */ - protected $description = 'Validate the mapping files.'; - - /** - * Execute the console command. - * - * @param ManagerRegistry $registry - */ - public function handle(ManagerRegistry $registry) + public function __construct(EntityManagerProvider $entityManagerProvider) { - $names = $this->option('em') ? [$this->option('em')] : $registry->getManagerNames(); - $exit = 0; - - foreach ($names as $name) { - $em = $registry->getManager($name); - $validator = new SchemaValidator($em); - - $this->comment(''); - $this->message('Validating for ' . $name . ' entity manager...'); - - if ($this->option('skip-mapping')) { - $this->comment('Mapping] Skipped mapping check.'); - } elseif ($errors = $validator->validateMapping()) { - foreach ($errors as $className => $errorMessages) { - $this->error("[Mapping] FAIL - The entity-class '" . $className . "' mapping is invalid:"); - $this->comment(''); - - foreach ($errorMessages as $errorMessage) { - $this->message('* ' . $errorMessage, 'red'); - } - } - - $exit += 1; - } else { - $this->info('[Mapping] OK - The mapping files are correct.'); - } - - if ($this->option('skip-sync')) { - $this->comment('Database] SKIPPED - The database was not checked for synchronicity.'); - } elseif (!$validator->schemaInSyncWithMetadata()) { - $this->error('[Database] FAIL - The database schema is not in sync with the current mapping file.'); + parent::__construct($entityManagerProvider); + } - $exit += 2; - } else { - $this->info('[Database] OK - The database schema is in sync with the mapping files.'); - } - } + protected function configure(): void + { + parent::configure(); - return $exit; + $this->setName('doctrine:schema:validate'); } } diff --git a/src/Contracts/UrlRoutable.php b/src/Contracts/UrlRoutable.php index 2f8c1eb9..dd053157 100644 --- a/src/Contracts/UrlRoutable.php +++ b/src/Contracts/UrlRoutable.php @@ -4,5 +4,5 @@ interface UrlRoutable { - public static function getRouteKeyName(): string; + public static function getRouteKeyNameStatic(): string; } diff --git a/src/DoctrineManager.php b/src/DoctrineManager.php index 6e8e0b87..10974f08 100644 --- a/src/DoctrineManager.php +++ b/src/DoctrineManager.php @@ -70,6 +70,7 @@ public function extendAll($callback) */ private function callExtendOn($connection, $callback, ManagerRegistry $registry) { + /** @var \Doctrine\ORM\EntityManagerInterface $manager */ $manager = $registry->getManager($connection); if (!is_callable($callback)) { @@ -91,17 +92,6 @@ private function callExtendOn($connection, $callback, ManagerRegistry $registry) ]); } - /** - * @param $namespace - * @param string|null $connection - */ - public function addNamespace($namespace, $connection = null) - { - $this->onResolve(function (ManagerRegistry $registry) use ($connection, $namespace) { - $this->getMetaDataDriver($connection, $registry)->addNamespace($namespace); - }); - } - /** * @param array $paths * @param string|null $connection @@ -125,7 +115,7 @@ public function addMappings(array $mappings = [], $connection = null) } /** - * @param null $connection + * @param string|null $connection * * @param ManagerRegistry $registry * @return MappingDriver diff --git a/src/DoctrineServiceProvider.php b/src/DoctrineServiceProvider.php index d66cc269..af8878e2 100644 --- a/src/DoctrineServiceProvider.php +++ b/src/DoctrineServiceProvider.php @@ -24,12 +24,9 @@ use LaravelDoctrine\ORM\Console\ClearQueryCacheCommand; use LaravelDoctrine\ORM\Console\ClearResultCacheCommand; use LaravelDoctrine\ORM\Console\ConvertConfigCommand; -use LaravelDoctrine\ORM\Console\ConvertMappingCommand; use LaravelDoctrine\ORM\Console\DumpDatabaseCommand; use LaravelDoctrine\ORM\Console\EnsureProductionSettingsCommand; -use LaravelDoctrine\ORM\Console\GenerateEntitiesCommand; use LaravelDoctrine\ORM\Console\GenerateProxiesCommand; -use LaravelDoctrine\ORM\Console\GenerateRepositoriesCommand; use LaravelDoctrine\ORM\Console\InfoCommand; use LaravelDoctrine\ORM\Console\MappingImportCommand; use LaravelDoctrine\ORM\Console\SchemaCreateCommand; @@ -371,11 +368,6 @@ protected function registerConsoleCommands() ClearQueryCacheCommand::class, EnsureProductionSettingsCommand::class, GenerateProxiesCommand::class, - ConvertConfigCommand::class, - MappingImportCommand::class, - GenerateEntitiesCommand::class, - GenerateRepositoriesCommand::class, - ConvertMappingCommand::class, DumpDatabaseCommand::class ]); } diff --git a/src/EntityManagerFactory.php b/src/EntityManagerFactory.php index 3b2c8f35..377b2b23 100644 --- a/src/EntityManagerFactory.php +++ b/src/EntityManagerFactory.php @@ -2,28 +2,30 @@ namespace LaravelDoctrine\ORM; -use Doctrine\Common\Cache\Cache; use Doctrine\Common\EventManager; -use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection as DocrinePrimaryReadReplicaConnection; +use Doctrine\DBAL\Driver\Middleware; +use Doctrine\DBAL\DriverManager; +use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory; use Doctrine\ORM\Cache\DefaultCacheFactory; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; -use Doctrine\ORM\Tools\Setup; use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Container\Container; use Illuminate\Support\Arr; use InvalidArgumentException; use LaravelDoctrine\ORM\Configuration\Cache\CacheManager; use LaravelDoctrine\ORM\Configuration\Connections\ConnectionManager; -use LaravelDoctrine\ORM\Configuration\Connections\MasterSlaveConnection; use LaravelDoctrine\ORM\Configuration\Connections\PrimaryReadReplicaConnection; use LaravelDoctrine\ORM\Configuration\LaravelNamingStrategy; use LaravelDoctrine\ORM\Configuration\MetaData\MetaData; use LaravelDoctrine\ORM\Configuration\MetaData\MetaDataManager; use LaravelDoctrine\ORM\Extensions\MappingDriverChain; use LaravelDoctrine\ORM\Resolvers\EntityListenerResolver; +use LaravelDoctrine\ORM\ORMSetupResolver; +use LogicException; +use Psr\Cache\CacheItemPoolInterface; use ReflectionException; class EntityManagerFactory @@ -54,7 +56,7 @@ class EntityManagerFactory protected $container; /** - * @var Setup + * @var ORMSetupResolver */ private $setup; @@ -65,7 +67,7 @@ class EntityManagerFactory /** * @param Container $container - * @param Setup $setup + * @param ORMSetupResolver $setup * @param MetaDataManager $meta * @param ConnectionManager $connection * @param CacheManager $cache @@ -74,7 +76,7 @@ class EntityManagerFactory */ public function __construct( Container $container, - Setup $setup, + ORMSetupResolver $setup, MetaDataManager $meta, ConnectionManager $connection, CacheManager $cache, @@ -102,29 +104,34 @@ public function create(array $settings = []) $configuration = $this->setup->createConfiguration( Arr::get($settings, 'dev', false), Arr::get($settings, 'proxies.path'), - $this->cache->driver($defaultDriver) ); + $configuration->setSchemaManagerFactory(new DefaultSchemaManagerFactory); + $this->setMetadataDriver($settings, $configuration); + $this->setMiddlewares($settings, $configuration); $eventManager = $this->createEventManager($settings); $driver = $this->getConnectionDriver($settings); - $connection = $this->connection->driver( + $connection_configuration = $this->connection->driver( $driver['driver'], $driver ); - if ($this->isMasterSlaveConfigured($driver)) { - $this->hasValidMasterSlaveConfig($driver); - if (class_exists(DocrinePrimaryReadReplicaConnection::class)) { - $connection = (new PrimaryReadReplicaConnection($this->config, $connection))->resolve($driver); - } else { - $connection = (new MasterSlaveConnection($this->config, $connection))->resolve($driver); + if ($this->isPrimaryReadReplicaConfigured($driver)) { + if($this->hasValidPrimaryReadReplicaConfig($driver)) { + $connection_configuration = (new PrimaryReadReplicaConnection($this->config, $connection_configuration))->resolve($driver); } } + $connection = DriverManager::getConnection( + $connection_configuration, + $configuration, + $eventManager, + ); + $this->setNamingStrategy($settings, $configuration); $this->setQuoteStrategy($settings, $configuration); $this->setCustomFunctions($configuration); @@ -141,7 +148,7 @@ public function create(array $settings = []) $configuration->setEntityListenerResolver($this->resolver); - $manager = EntityManager::create( + $manager = new EntityManager( $connection, $configuration, $eventManager @@ -149,7 +156,6 @@ public function create(array $settings = []) $manager = $this->decorateManager($settings, $manager); - $this->setLogger($manager, $configuration); $this->registerListeners($settings, $manager); $this->registerSubscribers($settings, $manager); $this->registerFilters($settings, $configuration, $manager); @@ -178,6 +184,28 @@ private function setMetadataDriver(array $settings, Configuration $configuration } } + /** + * @param array{middlewares?: class-string[]} $settings + * @param Configuration $configuration + * @return void + */ + private function setMiddlewares(array $settings, Configuration $configuration): void + { + $middlewares = []; + + foreach($settings['middlewares'] ?? [] as $middlewareClass) { + $middleware = $this->container->make($middlewareClass); + + if (!($middleware instanceof Middleware)) { + throw new LogicException($middlewareClass . 'does not implement ' . Middleware::class); + } + + $middlewares[] = $middleware; + } + + $configuration->setMiddlewares($middlewares); + } + /** * @param array $settings * @param EntityManagerInterface $manager @@ -299,19 +327,6 @@ protected function configureProxies(array $settings, Configuration $configuratio } } - /** - * @param EntityManagerInterface $em - * @param Configuration $configuration - */ - protected function setLogger(EntityManagerInterface $em, Configuration $configuration) - { - if ($this->config->get('doctrine.logger', false)) { - $this->container->make( - $this->config->get('doctrine.logger', false) - )->register($em, $configuration); - } - } - /** * @param array $settings * @param Configuration $configuration @@ -366,31 +381,27 @@ protected function setCustomHydrationModes(Configuration $configuration) */ protected function setCacheSettings(Configuration $configuration) { - $configuration->setQueryCacheImpl($this->applyNamedCacheConfiguration('query')); - $configuration->setResultCacheImpl($this->applyNamedCacheConfiguration('result')); - $configuration->setMetadataCacheImpl($this->applyNamedCacheConfiguration('metadata')); + $configuration->setQueryCache($this->applyNamedCacheConfiguration('query')); + $configuration->setResultCache($this->applyNamedCacheConfiguration('result')); + $configuration->setMetadataCache($this->applyNamedCacheConfiguration('metadata')); $this->setSecondLevelCaching($configuration); } - /** - * @param string $cacheName - * @return Cache - */ - private function applyNamedCacheConfiguration($cacheName) + private function applyNamedCacheConfiguration(string $cacheName): CacheItemPoolInterface { $defaultDriver = $this->config->get('doctrine.cache.default', 'array'); $defaultNamespace = $this->config->get('doctrine.cache.namespace'); $settings = $this->config->get('doctrine.cache.' . $cacheName, []); + if (!isset($settings['namespace'])) { + $settings['namespace'] = $defaultNamespace; + } + $driver = $settings['driver'] ?? $defaultDriver; $cache = $this->cache->driver($driver, $settings); - if ($namespace = $this->config->get('doctrine.cache.' . $cacheName . '.namespace', $defaultNamespace)) { - $cache->setNamespace($namespace); - } - return $cache; } @@ -423,15 +434,6 @@ protected function setCustomMappingDriverChain(array $settings, Configuration $c 'LaravelDoctrine' ); - foreach (Arr::get($settings, 'namespaces', []) as $alias => $namespace) { - // Add an alias for the namespace using the key - if (is_string($alias)) { - $configuration->addEntityNamespace($alias, $namespace); - } - - $chain->addNamespace($namespace); - } - $configuration->setMetadataDriverImpl( $chain ); @@ -477,12 +479,12 @@ protected function getConnectionDriver(array $settings = []) * @param $settings * @param EntityManagerInterface $manager * - * @throws \Doctrine\DBAL\DBALException If Database Type or Doctrine Type is not found. + * @throws \Doctrine\DBAL\Exception If Database Type or Doctrine Type is not found. */ protected function registerMappingTypes(array $settings, EntityManagerInterface $manager) { foreach (Arr::get($settings, 'mapping_types', []) as $dbType => $doctrineType) { - // Throw DBALException if Doctrine Type is not found. + // Throw \Doctrine\DBAL\Exception if Doctrine Type is not found. $manager->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping($dbType, $doctrineType); } } @@ -511,7 +513,7 @@ private function createEventManager(array $settings = []) * * @return bool */ - private function isMasterSlaveConfigured(array $driverConfig) + private function isPrimaryReadReplicaConfigured(array $driverConfig) { // Setting read is mandatory for master/slave configuration. Setting write is optional. // But if write was set and read wasn't, it means configuration is incorrect and we must inform the user. @@ -522,8 +524,9 @@ private function isMasterSlaveConfigured(array $driverConfig) * Check if slave configuration is valid. * * @param array $driverConfig + * @return bool */ - private function hasValidMasterSlaveConfig(array $driverConfig) + private function hasValidPrimaryReadReplicaConfig(array $driverConfig) { if (!isset($driverConfig['read'])) { throw new \InvalidArgumentException("Parameter 'read' must be set for read/write config."); @@ -538,5 +541,7 @@ private function hasValidMasterSlaveConfig(array $driverConfig) if (($key = array_search(0, array_map('count', $slaves))) !== false) { throw new \InvalidArgumentException("Parameter 'read' config no. {$key} is empty."); } + + return true; } } diff --git a/src/Extensions/ExtensionManager.php b/src/Extensions/ExtensionManager.php index 25f7d79a..9e8ccd28 100644 --- a/src/Extensions/ExtensionManager.php +++ b/src/Extensions/ExtensionManager.php @@ -40,6 +40,7 @@ public function __construct(Container $container) */ public function boot(ManagerRegistry $registry) { + /** @var \Doctrine\ORM\EntityManagerInterface $em */ foreach ($registry->getManagers() as $connection => $em) { foreach ($this->extensions as $extension) { $extension = $this->container->make($extension); diff --git a/src/Extensions/MappingDriverChain.php b/src/Extensions/MappingDriverChain.php index 31847852..69dccd3d 100644 --- a/src/Extensions/MappingDriverChain.php +++ b/src/Extensions/MappingDriverChain.php @@ -21,14 +21,6 @@ public function __construct(MappingDriver $driver, $namespace) $this->setDefaultDriver($driver); } - /** - * @param $namespace - */ - public function addNamespace($namespace) - { - $this->addDriver($this->getDefaultDriver(), $namespace); - } - /** * @param array $paths */ @@ -39,10 +31,12 @@ public function addPaths(array $paths = []) if (method_exists($driver, 'addPaths')) { $driver->addPaths($paths); } elseif ($driver instanceof FileDriver) { - if ($driver->getLocator() instanceof DefaultFileLocator) { - $driver->getLocator()->addPaths($paths); - } elseif ($driver->getLocator() instanceof SymfonyFileLocator) { - $driver->getLocator()->addNamespacePrefixes($paths); + $locator = $driver->getLocator(); + + if ($locator instanceof DefaultFileLocator) { + $locator->addPaths($paths); + } elseif ($locator instanceof SymfonyFileLocator) { + $locator->addNamespacePrefixes($paths); } } } diff --git a/src/Facades/EntityManager.php b/src/Facades/EntityManager.php index e2970ef7..6aaf2808 100644 --- a/src/Facades/EntityManager.php +++ b/src/Facades/EntityManager.php @@ -13,7 +13,7 @@ * @method static void detach(object $object) * @method static void refresh(object $object) * @method static void flush() - * @method static \Doctrine\Persistence\ObjectRepository getRepository(string $className) + * @method static \Doctrine\ORM\EntityRepository getRepository(string $className) * @method static \Doctrine\Persistence\Mapping\ClassMetadata getClassMetadata(string $className) * @method static \Doctrine\Persistence\Mapping\ClassMetadataFactory getMetadataFactory() * @method static void initializeObject(object $obj) diff --git a/src/IlluminateRegistry.php b/src/IlluminateRegistry.php index 7f8ecb66..3ab111bb 100644 --- a/src/IlluminateRegistry.php +++ b/src/IlluminateRegistry.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Container\Container; use InvalidArgumentException; use ReflectionClass; +use Doctrine\ORM\Exception\UnknownEntityNamespace; final class IlluminateRegistry implements ManagerRegistry { @@ -328,7 +329,7 @@ public function getAliasNamespace($alias) } } - throw ORMException::unknownEntityNamespace($alias); + throw UnknownEntityNamespace::fromNamespaceAlias($alias); } /** diff --git a/src/Loggers/Clockwork/DoctrineDataSource.php b/src/Loggers/Clockwork/DoctrineDataSource.php deleted file mode 100644 index 148a9500..00000000 --- a/src/Loggers/Clockwork/DoctrineDataSource.php +++ /dev/null @@ -1,71 +0,0 @@ -logger = $logger; - $this->connection = $connection; - $this->formatter = new FormatQueryKeywords(new ReplaceQueryParams); - } - - /** - * Adds ran database queries to the request - * - * @param Request $request - * - * @return Request - */ - public function resolve(Request $request) - { - $request->databaseQueries = array_merge($request->databaseQueries, $this->getDatabaseQueries()); - - return $request; - } - - /** - * Returns an array of runnable queries and their durations from the internal array - */ - protected function getDatabaseQueries() - { - $queries = []; - foreach ($this->logger->queries as $query) { - $queries[] = [ - 'query' => $this->formatter->format($this->connection->getDatabasePlatform(), $query['sql'], $query['params']), - 'duration' => $query['executionMS'] * 1000, - 'connection' => $this->connection->getDriver()->getName() - ]; - } - - return $queries; - } -} diff --git a/src/Loggers/ClockworkLogger.php b/src/Loggers/ClockworkLogger.php deleted file mode 100644 index b18bb9b5..00000000 --- a/src/Loggers/ClockworkLogger.php +++ /dev/null @@ -1,41 +0,0 @@ -clockwork = $clockwork; - } - - /** - * @param EntityManagerInterface $em - * @param Configuration $configuration - */ - public function register(EntityManagerInterface $em, Configuration $configuration) - { - $debugStack = new DebugStack; - $configuration->setSQLLogger($debugStack); - $this->clockwork->addDataSource( - new DoctrineDataSource( - $debugStack, - $em->getConnection() - ) - ); - } -} diff --git a/src/Loggers/Debugbar/DoctrineCollector.php b/src/Loggers/Debugbar/DoctrineCollector.php deleted file mode 100644 index 2c2a4045..00000000 --- a/src/Loggers/Debugbar/DoctrineCollector.php +++ /dev/null @@ -1,41 +0,0 @@ -debugStack; - } - - /** - * @return array - */ - public function getWidgets() - { - return [ - "doctrine" => [ - "icon" => "arrow-right", - "widget" => "PhpDebugBar.Widgets.SQLQueriesWidget", - "map" => "doctrine", - "default" => "[]" - ], - "doctrine:badge" => [ - "map" => "doctrine.nb_statements", - "default" => 0 - ] - ]; - } -} diff --git a/src/Loggers/EchoLogger.php b/src/Loggers/EchoLogger.php deleted file mode 100644 index 3dcbdb74..00000000 --- a/src/Loggers/EchoLogger.php +++ /dev/null @@ -1,19 +0,0 @@ -setSQLLogger(new EchoSQLLogger()); - } -} diff --git a/src/Loggers/File/DoctrineFileLogger.php b/src/Loggers/File/DoctrineFileLogger.php deleted file mode 100644 index 8b110614..00000000 --- a/src/Loggers/File/DoctrineFileLogger.php +++ /dev/null @@ -1,88 +0,0 @@ -logger = $logger; - $this->formatter = new FormatQueryKeywords(new ReplaceQueryParams); - $this->connection = $connection; - } - - /** - * Logs a SQL statement somewhere. - * - * @param string $sql The SQL to be executed. - * @param array|null $params The SQL parameters. - * @param array|null $types The SQL parameter types. - * - * @return void - */ - public function startQuery($sql, array $params = null, array $types = null) - { - $this->start = microtime(true); - $this->query = $this->formatter->format($this->connection->getDatabasePlatform(), $sql, $params, $types); - } - - /** - * Marks the last started query as stopped. This can be used for timing of queries. - * @return void - */ - public function stopQuery() - { - $this->logger->debug($this->getQuery(), [$this->getExecutionTime()]); - } - - /** - * @return string - */ - public function getQuery() - { - return $this->query; - } - - /** - * @return mixed - */ - protected function getExecutionTime() - { - return microtime(true) - $this->start; - } -} diff --git a/src/Loggers/FileLogger.php b/src/Loggers/FileLogger.php deleted file mode 100644 index 48eeceed..00000000 --- a/src/Loggers/FileLogger.php +++ /dev/null @@ -1,34 +0,0 @@ -logger = $logger; - } - - /** - * @param EntityManagerInterface $em - * @param Configuration $configuration - */ - public function register(EntityManagerInterface $em, Configuration $configuration) - { - $logger = new DoctrineFileLogger($this->logger, $em->getConnection()); - $configuration->setSQLLogger($logger); - } -} diff --git a/src/Loggers/Formatters/FormatQueryKeywords.php b/src/Loggers/Formatters/FormatQueryKeywords.php deleted file mode 100644 index aac9d56f..00000000 --- a/src/Loggers/Formatters/FormatQueryKeywords.php +++ /dev/null @@ -1,64 +0,0 @@ -formatter = $formatter; - } - - /** - * @param AbstractPlatform - * @param string $sql - * @param array|null $params - * @param array|null $types - * - * @return string - */ - public function format($platform, $sql, array $params = null, array $types = null) - { - $sql = $this->formatter->format($platform, $sql, $params, $types); - - return preg_replace_callback('/\b' . implode('\b|\b', $this->keywords) . '\b/i', function ($match) { - return strtoupper($match[0]); - }, $sql); - } -} diff --git a/src/Loggers/Formatters/QueryFormatter.php b/src/Loggers/Formatters/QueryFormatter.php deleted file mode 100644 index 8c0a70b7..00000000 --- a/src/Loggers/Formatters/QueryFormatter.php +++ /dev/null @@ -1,18 +0,0 @@ - $param) { - $type = $types[$key] ?? null; - $param = $this->convertParam($platform, $param, $type); - $sql = preg_replace('/\?/', "$param", $sql, 1); - } - } - - return $sql; - } - - /** - * @param mixed $param - * - * @throws Exception - * @return string - */ - protected function convertParam($platform, $param, $type = null) - { - if ($type === null) { - $type = ''; - } - - if (is_object($param)) { - if (!method_exists($param, '__toString')) { - if ($param instanceof DateTimeInterface) { - $param = $param->format('Y-m-d H:i:s'); - } elseif (Type::hasType($type)) { - $type = Type::getType($type); - $param = $type->convertToDatabaseValue($param, $platform); - } else { - throw new Exception('Given query param is an instance of ' . get_class($param) . ' and could not be converted to a string'); - } - } - } elseif (is_array($param)) { - if ($this->isNestedArray($param)) { - $param = json_encode($param, JSON_UNESCAPED_UNICODE); - } else { - $param = implode( - ', ', - array_map( - function ($part) { - return '"' . (string) $part . '"'; - }, - $param - ) - ); - - return '(' . $param . ')'; - } - } else { - $param = e($param); - } - - return '"' . (string) $param . '"'; - } - - /** - * @param array $array - * @return bool - */ - private function isNestedArray(array $array) - { - foreach ($array as $key => $value) { - if (is_array($value)) { - return true; - } - } - - return false; - } -} diff --git a/src/Loggers/LaravelDebugbarLogger.php b/src/Loggers/LaravelDebugbarLogger.php deleted file mode 100644 index d6655ed8..00000000 --- a/src/Loggers/LaravelDebugbarLogger.php +++ /dev/null @@ -1,44 +0,0 @@ -debugbar = $debugbar; - } - - /** - * @param EntityManagerInterface $em - * @param Configuration $configuration - */ - public function register(EntityManagerInterface $em, Configuration $configuration) - { - if ($this->debugbar->hasCollector('doctrine')) { - $debugStack = $this->debugbar->getCollector('doctrine')->getDebugStack(); - } else { - $debugStack = new DebugStack; - - $this->debugbar->addCollector( - new DoctrineCollector($debugStack) - ); - } - - $configuration->setSQLLogger($debugStack); - } -} diff --git a/src/Loggers/Logger.php b/src/Loggers/Logger.php deleted file mode 100644 index 994c4ad4..00000000 --- a/src/Loggers/Logger.php +++ /dev/null @@ -1,15 +0,0 @@ -name]; $class = $this->getClassName($parameter); - if ($repository = $this->registry->getRepository($class)) { - $reflectionClass = new \ReflectionClass($class); + if ($class) { + $repository = $this->registry->getRepository($class); - if ($reflectionClass->implementsInterface(UrlRoutable::class)) { - $name = call_user_func([$class, 'getRouteKeyName']); + if (is_a($class, UrlRoutable::class, true)) { + $name = call_user_func([$class, 'getRouteKeyNameStatic']); $entity = $repository->findOneBy([ $name => $id @@ -105,14 +107,16 @@ private function signatureParameters(Route $route) })->toArray(); } + /** + * @return class-string + */ private function getClassName(ReflectionParameter $parameter): ?string { - $class = null; - if (($type = $parameter->getType()) && $type instanceof \ReflectionNamedType && !$type->isBuiltin()) { $class = $type->getName(); + return class_exists($class) ? $class : null; } - return $class; + return null; } } diff --git a/src/Notifications/Notification.php b/src/Notifications/Notification.php index 97d6617e..fd266558 100644 --- a/src/Notifications/Notification.php +++ b/src/Notifications/Notification.php @@ -7,6 +7,7 @@ /** * @ORM\MappedSuperclass */ +#[ORM\MappedSuperclass] class Notification { /** @@ -14,6 +15,9 @@ class Notification * @ORM\GeneratedValue * @ORM\Column(type="integer") */ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column(type: 'integer')] protected $id; /** @@ -26,6 +30,7 @@ class Notification * @ORM\Column(type="string") * @var string */ + #[ORM\Column(type: 'string')] protected $level = 'info'; /** @@ -33,6 +38,7 @@ class Notification * @ORM\Column(type="string") * @var string */ + #[ORM\Column(type: 'string')] protected $message; /** @@ -40,6 +46,7 @@ class Notification * @ORM\Column(type="string") * @var string */ + #[ORM\Column(type: 'string')] protected $actionText; /** @@ -47,6 +54,7 @@ class Notification * @ORM\Column(type="string") * @var string */ + #[ORM\Column(type: 'string')] protected $actionUrl; /** diff --git a/src/ORMSetupResolver.php b/src/ORMSetupResolver.php new file mode 100644 index 00000000..2631c06a --- /dev/null +++ b/src/ORMSetupResolver.php @@ -0,0 +1,21 @@ +setProxyDir($proxyDir); + $config->setAutoGenerateProxyClasses($isDevMode); + + return $config; + } +} diff --git a/src/Queue/FailedJobsServiceProvider.php b/src/Queue/FailedJobsServiceProvider.php index 9f8963e2..c622a322 100644 --- a/src/Queue/FailedJobsServiceProvider.php +++ b/src/Queue/FailedJobsServiceProvider.php @@ -18,7 +18,7 @@ public function register() $schema = $this->app['registry'] ->getConnection($connection) - ->getSchemaManager(); + ->createSchemaManager(); if (!$schema->tablesExist($tableName)) { $schema->createTable( diff --git a/src/Serializers/ArraySerializer.php b/src/Serializers/ArraySerializer.php index 65cc93a2..35a235d8 100644 --- a/src/Serializers/ArraySerializer.php +++ b/src/Serializers/ArraySerializer.php @@ -3,9 +3,20 @@ namespace LaravelDoctrine\ORM\Serializers; use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer; +use Symfony\Component\Serializer\Serializer; class ArraySerializer { + /** + * @var Serializer + */ + protected $serializer; + + public function __construct() + { + $this->serializer = new Serializer([$this->getNormalizer()]); + } + /** * @param $entity * @@ -13,7 +24,7 @@ class ArraySerializer */ public function serialize($entity) { - return $this->getNormalizer()->normalize($entity, 'array'); + return $this->serializer->normalize($entity, 'array'); } /** diff --git a/src/Serializers/Arrayable.php b/src/Serializers/Arrayable.php index 4200cd7c..70fd4218 100644 --- a/src/Serializers/Arrayable.php +++ b/src/Serializers/Arrayable.php @@ -5,7 +5,7 @@ trait Arrayable { /** - * @return string + * @return array */ public function toArray() { diff --git a/src/Testing/Factory.php b/src/Testing/Factory.php index 6cf659e7..80df33b8 100644 --- a/src/Testing/Factory.php +++ b/src/Testing/Factory.php @@ -311,7 +311,7 @@ public function load($path) * * @return bool */ - public function offsetExists($offset) + public function offsetExists(mixed $offset): bool { return isset($this->definitions[$offset]); } @@ -323,7 +323,7 @@ public function offsetExists($offset) * * @return mixed */ - public function offsetGet($offset) + public function offsetGet(mixed $offset): mixed { return $this->make($offset); } @@ -336,7 +336,7 @@ public function offsetGet($offset) * * @return void */ - public function offsetSet($offset, $value) + public function offsetSet(mixed $offset, mixed $value): void { $this->define($offset, $value); } @@ -348,7 +348,7 @@ public function offsetSet($offset, $value) * * @return void */ - public function offsetUnset($offset) + public function offsetUnset(mixed $offset): void { unset($this->definitions[$offset]); } diff --git a/src/Testing/FactoryBuilder.php b/src/Testing/FactoryBuilder.php index b8f19fa0..74186422 100644 --- a/src/Testing/FactoryBuilder.php +++ b/src/Testing/FactoryBuilder.php @@ -21,7 +21,7 @@ class FactoryBuilder /** * The model being built. * - * @var string + * @var class-string */ protected $class; @@ -65,11 +65,25 @@ class FactoryBuilder */ protected $activeStates = []; + /** + * The registered after making callbacks. + * + * @var array + */ + public $afterMaking = []; + + /** + * The registered after creating callbacks. + * + * @var array + */ + public $afterCreating = []; + /** * Create an new builder instance. * * @param ManagerRegistry $registry - * @param string $class + * @param class-string $class * @param string $name * @param array $definitions * @param \Faker\Generator $faker diff --git a/src/Types/Json.php b/src/Types/Json.php deleted file mode 100644 index 3133db41..00000000 --- a/src/Types/Json.php +++ /dev/null @@ -1,56 +0,0 @@ -getJsonTypeDeclarationSQL($fieldDeclaration); - } - - return $platform->getClobTypeDeclarationSQL($fieldDeclaration); - } - - /** - * When database value is null, we return null instead of empty array like our parent does. - * {@inheritdoc} - */ - public function convertToPHPValue($value, AbstractPlatform $platform) - { - if ($value === null || $value === '') { - return null; - } - - return parent::convertToPHPValue($value, $platform); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'json'; - } -} diff --git a/src/Utilities/ArrayUtil.php b/src/Utilities/ArrayUtil.php deleted file mode 100644 index cf651691..00000000 --- a/src/Utilities/ArrayUtil.php +++ /dev/null @@ -1,14 +0,0 @@ -select($collection); + $builder = $this->selectCount($collection); $builder->where("e.{$column} = :" . $this->prepareParam($column)); if (!is_null($excludeId) && $excludeId != 'NULL') { @@ -60,7 +60,7 @@ public function getCount($collection, $column, $value, $excludeId = null, $idCol $query->setParameter($this->prepareParam($idColumn), $excludeId); } - return $query->getSingleScalarResult(); + return (int) $query->getSingleScalarResult(); } /** @@ -75,25 +75,25 @@ public function getCount($collection, $column, $value, $excludeId = null, $idCol */ public function getMultiCount($collection, $column, array $values, array $extra = []) { - $builder = $this->select($collection); + $builder = $this->selectCount($collection); $builder->where($builder->expr()->in("e.{$column}", $values)); $this->queryExtraConditions($extra, $builder); - return $builder->getQuery()->getSingleScalarResult(); + return (int) $builder->getQuery()->getSingleScalarResult(); } /** - * @param string $collection + * @param string $entity * * @return \Doctrine\ORM\QueryBuilder */ - protected function select($collection) + protected function selectCount($entity) { - $em = $this->getEntityManager($collection); + $em = $this->getEntityManager($entity); $builder = $em->createQueryBuilder(); - $builder->select('count(e)')->from($collection, 'e'); + $builder->select('count(e)')->from($entity, 'e'); return $builder; } @@ -122,7 +122,7 @@ protected function queryExtraConditions(array $extra, QueryBuilder $builder) /** * @param string $entity * - * @return \Doctrine\Persistence\ObjectManager|null + * @return \Doctrine\Persistence\ObjectManager */ protected function getEntityManager($entity) { diff --git a/tests/Auth/DoctrineUserProviderTest.php b/tests/Auth/DoctrineUserProviderTest.php index 829a27b5..a0efaaaf 100644 --- a/tests/Auth/DoctrineUserProviderTest.php +++ b/tests/Auth/DoctrineUserProviderTest.php @@ -102,7 +102,7 @@ public function test_can_update_remember_token() $user = new AuthenticableMock; $this->em->shouldReceive('persist')->once()->with($user); - $this->em->shouldReceive('flush')->once()->with($user); + $this->em->shouldReceive('flush')->once()->withNoArgs(); $this->provider->updateRememberToken($user, 'newToken'); diff --git a/tests/Auth/Passwords/DoctrineTokenRepositoryTest.php b/tests/Auth/Passwords/DoctrineTokenRepositoryTest.php index b719ae19..999b28f7 100644 --- a/tests/Auth/Passwords/DoctrineTokenRepositoryTest.php +++ b/tests/Auth/Passwords/DoctrineTokenRepositoryTest.php @@ -50,7 +50,7 @@ protected function setUp(): void $this->builder = m::mock(QueryBuilder::class); $this->schema = m::mock(AbstractSchemaManager::class); - $this->connection->shouldReceive('getSchemaManager') + $this->connection->shouldReceive('createSchemaManager') ->andReturn($this->schema); $this->schema->shouldReceive('tablesExist') @@ -91,7 +91,7 @@ public function test_can_create_a_token() ->with('email', 'user@mockery.mock') ->andReturnSelf(); - $this->builder->shouldReceive('execute') + $this->builder->shouldReceive('executeStatement') ->twice() ->andReturn(true); @@ -150,11 +150,13 @@ public function test_can_check_if_exists() ->with('email', 'user@mockery.mock') ->andReturnSelf(); - $this->builder->shouldReceive('execute') + $result = m::mock(\Doctrine\DBAL\Result::class); + + $this->builder->shouldReceive('executeQuery') ->once() - ->andReturnSelf(); + ->andReturn($result); - $this->builder->shouldReceive('fetch') + $result->shouldReceive('fetchAssociative') ->once() ->andReturn([ 'email' => 'user@mockery.mock', @@ -191,17 +193,19 @@ public function test_can_check_if_recently_created_token() ->with('email', 'user@mockery.mock') ->andReturnSelf(); - $this->builder->shouldReceive('execute') - ->once() - ->andReturnSelf(); + $result = m::mock(\Doctrine\DBAL\Result::class); - $this->builder->shouldReceive('fetch') - ->once() - ->andReturn([ - 'email' => 'user@mockery.mock', - 'token' => 'token', - 'created_at' => Carbon::now() - ]); + $this->builder->shouldReceive('executeQuery') + ->once() + ->andReturn($result); + + $result->shouldReceive('fetchAssociative') + ->once() + ->andReturn([ + 'email' => 'user@mockery.mock', + 'token' => 'token', + 'created_at' => Carbon::now() + ]); $this->assertTrue($this->repository->recentlyCreatedToken(new UserMock)); } @@ -227,7 +231,8 @@ public function test_can_delete() ->with('email', 'user@mockery.mock') ->andReturnSelf(); - $this->builder->shouldReceive('execute') + + $this->builder->shouldReceive('executeStatement') ->once() ->andReturn(true); @@ -256,7 +261,7 @@ public function test_can_delete_expired() ->once() ->andReturnSelf(); - $this->builder->shouldReceive('execute') + $this->builder->shouldReceive('executeStatement') ->once(); $this->repository->deleteExpired(); diff --git a/tests/Configuration/Cache/AbstractCacheTest.php b/tests/Configuration/Cache/AbstractCacheTest.php deleted file mode 100644 index 655423a3..00000000 --- a/tests/Configuration/Cache/AbstractCacheTest.php +++ /dev/null @@ -1,123 +0,0 @@ -getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('get') - ->with('[1][cacheKey]') - ->once()->andReturn('fetched'); - - $this->assertEquals('fetched', $this->getCache()->fetch(1)); - } - - public function test_can_fetch_multiple() - { - $this->getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('get') - ->with('[1][cacheKey]') - ->once()->andReturn('fetched1'); - - $this->getStore()->shouldReceive('get') - ->with('[2][cacheKey]') - ->once()->andReturn('fetched2'); - - $result = $this->getCache()->fetchMultiple([1, 2]); - - $this->assertContains('fetched1', $result); - $this->assertContains('fetched2', $result); - } - - public function test_can_test_if_cache_contains() - { - $this->getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('get') - ->with('[1][cacheKey]') - ->once()->andReturn('fetched'); - - $this->assertTrue($this->getCache()->contains(1)); - } - - public function test_can_save() - { - $this->getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('put') - ->with('[1][cacheKey]', 'data', 60) - ->once()->andReturn(true); - - $this->assertTrue($this->getCache()->save(1, 'data', 60)); - } - - public function test_can_delete() - { - $this->getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('forget') - ->with('[1][cacheKey]') - ->once()->andReturn(true); - - $this->assertTrue($this->getCache()->delete(1)); - } - - public function test_can_delete_all() - { - $this->getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('put') - ->with("DoctrineNamespaceCacheKey[]", 1, false) - ->once()->andReturn(true); - - $this->assertTrue($this->getCache()->deleteAll()); - } - - public function test_can_flush_all() - { - $this->getStore()->shouldReceive('flush') - ->once()->andReturn(true); - - $this->assertTrue($this->getCache()->flushAll()); - } - - public function test_can_namespace_cache() - { - $this->getCache()->setNamespace('namespace'); - $this->assertEquals('namespace', $this->getCache()->getNamespace()); - - $this->getStore()->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[namespace]') - ->once()->andReturn('cacheKey'); - - $this->getStore()->shouldReceive('get') - ->with('namespace[1][cacheKey]') - ->once()->andReturn('fetched'); - - $this->assertEquals('fetched', $this->getCache()->fetch(1)); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Configuration/Cache/ApcCacheProviderTest.php b/tests/Configuration/Cache/ApcCacheProviderTest.php index e84535a4..3ae8ef7b 100644 --- a/tests/Configuration/Cache/ApcCacheProviderTest.php +++ b/tests/Configuration/Cache/ApcCacheProviderTest.php @@ -3,8 +3,8 @@ use Illuminate\Contracts\Cache\Factory; use Illuminate\Contracts\Cache\Repository; use LaravelDoctrine\ORM\Configuration\Cache\ApcCacheProvider; -use LaravelDoctrine\ORM\Configuration\Cache\IlluminateCacheAdapter; use Mockery as m; +use Psr\Cache\CacheItemPoolInterface; class ApcCacheProviderTest extends AbstractCacheProviderTest { @@ -23,6 +23,6 @@ public function getProvider() public function getExpectedInstance() { - return IlluminateCacheAdapter::class; + return CacheItemPoolInterface::class; } } diff --git a/tests/Configuration/Cache/ArrayCacheProviderTest.php b/tests/Configuration/Cache/ArrayCacheProviderTest.php index 14dcc712..af0cc6a6 100644 --- a/tests/Configuration/Cache/ArrayCacheProviderTest.php +++ b/tests/Configuration/Cache/ArrayCacheProviderTest.php @@ -1,7 +1,7 @@ app->shouldReceive('resolve')->andReturn(new ArrayCacheProvider()); $this->assertInstanceOf(ArrayCacheProvider::class, $this->manager->driver()); - $this->assertInstanceOf(ArrayCache::class, $this->manager->driver()->resolve()); + $this->assertInstanceOf(ArrayAdapter::class, $this->manager->driver()->resolve()); } public function test_driver_can_return_a_given_driver() { $config = m::mock(Repository::class); + $app = m::mock(Application::class); $this->app->shouldReceive('resolve')->andReturn(new FileCacheProvider( - $config + $config, + $app, )); $this->assertInstanceOf(FileCacheProvider::class, $this->manager->driver()); diff --git a/tests/Configuration/Cache/FileCacheProviderTest.php b/tests/Configuration/Cache/FileCacheProviderTest.php index bff84632..4e780c8d 100644 --- a/tests/Configuration/Cache/FileCacheProviderTest.php +++ b/tests/Configuration/Cache/FileCacheProviderTest.php @@ -1,34 +1,41 @@ shouldReceive('get') - ->with('cache.stores.file.path', storage_path('framework/cache')) - ->once() - ->andReturn('/tmp'); + ->with('cache.stores.file.path', __DIR__ . DIRECTORY_SEPARATOR . '../../Stubs/storage/framework/cache') + ->once() + ->andReturn('/tmp'); + + $config->shouldReceive('get') + ->with('doctrine.cache.namespace', 'doctrine-cache') + ->once() + ->andReturn('doctrine-cache'); return new FileCacheProvider( - $config + $config, ); } public function getExpectedInstance() { - return FilesystemCache::class; + return FilesystemAdapter::class; } } -function storage_path($path = null) -{ - $storage = __DIR__ . DIRECTORY_SEPARATOR . '../../Stubs/storage'; +if(!function_exists('storage_path')) { + function storage_path($path = null) + { + $storage = __DIR__ . DIRECTORY_SEPARATOR . '../../Stubs/storage'; - return is_null($path) ? $storage : $storage . DIRECTORY_SEPARATOR . $path; + return is_null($path) ? $storage : $storage . DIRECTORY_SEPARATOR . $path; + } } diff --git a/tests/Configuration/Cache/IlluminateCacheAdapterTest.php b/tests/Configuration/Cache/IlluminateCacheAdapterTest.php deleted file mode 100644 index f3edd7d0..00000000 --- a/tests/Configuration/Cache/IlluminateCacheAdapterTest.php +++ /dev/null @@ -1,141 +0,0 @@ -repository = m::mock(Repository::class); - $this->cache = new IlluminateCacheAdapter( - $this->repository - ); - } - - public function test_can_fetch() - { - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('get') - ->with('[1][1]') - ->once()->andReturn('fetched'); - - $this->assertEquals('fetched', $this->cache->fetch(1)); - } - - public function test_can_fetch_multiple() - { - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('get') - ->with('[1][1]') - ->once()->andReturn('fetched1'); - - $this->repository->shouldReceive('get') - ->with('[2][1]') - ->once()->andReturn('fetched2'); - - $result = $this->cache->fetchMultiple([1, 2]); - - $this->assertContains('fetched1', $result); - $this->assertContains('fetched2', $result); - } - - public function test_can_test_if_cache_contains() - { - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('has') - ->with('[1][1]') - ->once()->andReturn(true); - - $this->assertTrue($this->cache->contains(1)); - } - - public function test_can_save() - { - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('put') - ->with('[1][1]', 'data', 60) - ->once()->andReturn(true); - - $this->assertTrue($this->cache->save(1, 'data', 60)); - } - - public function test_can_delete() - { - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('forget') - ->with('[1][1]') - ->once()->andReturn(true); - - $this->assertTrue($this->cache->delete(1)); - } - - public function test_can_delete_all() - { - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('forever') - ->with('DoctrineNamespaceCacheKey[]', 2) - ->once()->andReturn(true); - - $this->assertTrue($this->cache->deleteAll()); - } - - public function test_can_flush_all() - { - $this->repository->shouldReceive('flush') - ->once()->andReturn(true); - - $this->assertTrue($this->cache->flushAll()); - } - - public function test_can_namespace_cache() - { - $this->cache->setNamespace('namespace'); - $this->assertEquals('namespace', $this->cache->getNamespace()); - - $this->repository->shouldReceive('get') - ->with('DoctrineNamespaceCacheKey[namespace]') - ->once()->andReturn(1); - - $this->repository->shouldReceive('get') - ->with('namespace[1][1]') - ->once()->andReturn('fetched'); - - $this->assertEquals('fetched', $this->cache->fetch(1)); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Configuration/Cache/IlluminateCacheProviderTest.php b/tests/Configuration/Cache/IlluminateCacheProviderTest.php new file mode 100644 index 00000000..5b9faff7 --- /dev/null +++ b/tests/Configuration/Cache/IlluminateCacheProviderTest.php @@ -0,0 +1,64 @@ +repository = m::mock(Repository::class); + $manager = m::mock(Factory::class); + $manager->shouldReceive('store') + ->once() + ->andReturn($this->repository); + + $this->driver = new IlluminateCacheProvider($manager); + } + + public function test_driver_returns_provided_namespace(): void + { + $this->repository->shouldReceive('getMultiple') + ->withSomeOfArgs(['namespace_item']) + ->once(); + + $cache = $this->driver->resolve(['store' => 'redis', 'namespace' => 'namespace']); + $cache->getItem('item'); + + $this->assertTrue(true); + } + + public function test_driver_has_no_namespace_by_default(): void + { + $this->repository->shouldReceive('getMultiple') + ->withSomeOfArgs(['item']) + ->once(); + + $cache = $this->driver->resolve(['store' => 'redis']); + $cache->getItem('item'); + + $this->assertTrue(true); + } + + public function tearDown(): void + { + m::close(); + } +} diff --git a/tests/Configuration/Cache/MemcachedCacheProviderTest.php b/tests/Configuration/Cache/MemcachedCacheProviderTest.php index e8ab527f..65aefa17 100644 --- a/tests/Configuration/Cache/MemcachedCacheProviderTest.php +++ b/tests/Configuration/Cache/MemcachedCacheProviderTest.php @@ -2,9 +2,9 @@ use Illuminate\Contracts\Cache\Factory; use Illuminate\Contracts\Cache\Repository; -use LaravelDoctrine\ORM\Configuration\Cache\IlluminateCacheAdapter; use LaravelDoctrine\ORM\Configuration\Cache\MemcachedCacheProvider; use Mockery as m; +use Psr\Cache\CacheItemPoolInterface; class MemcachedCacheProviderTest extends AbstractCacheProviderTest { @@ -23,6 +23,6 @@ public function getProvider() public function getExpectedInstance() { - return IlluminateCacheAdapter::class; + return CacheItemPoolInterface::class; } } diff --git a/tests/Configuration/Cache/PhpFileCacheProviderTest.php b/tests/Configuration/Cache/PhpFileCacheProviderTest.php index ca3b2904..78f48f03 100644 --- a/tests/Configuration/Cache/PhpFileCacheProviderTest.php +++ b/tests/Configuration/Cache/PhpFileCacheProviderTest.php @@ -1,27 +1,41 @@ shouldReceive('get') - ->with('cache.stores.file.path', __DIR__ . DIRECTORY_SEPARATOR . '../../Stubs/storage/framework/cache') + ->with('cache.stores.file.path', __DIR__ . DIRECTORY_SEPARATOR . '../../Stubs/storage/framework/cache') ->once() ->andReturn('/tmp'); + $config->shouldReceive('get') + ->with('doctrine.cache.namespace', 'doctrine-cache') + ->once() + ->andReturn('doctrine-cache'); + return new PhpFileCacheProvider( - $config + $config, ); } public function getExpectedInstance() { - return PhpFileCache::class; + return PhpFilesAdapter::class; + } +} + +if(!function_exists('storage_path')) { + function storage_path($path = null) + { + $storage = __DIR__ . DIRECTORY_SEPARATOR . '../../Stubs/storage'; + + return is_null($path) ? $storage : $storage . DIRECTORY_SEPARATOR . $path; } } diff --git a/tests/Configuration/Cache/RedisCacheProviderTest.php b/tests/Configuration/Cache/RedisCacheProviderTest.php index 02f9f528..1bf82637 100644 --- a/tests/Configuration/Cache/RedisCacheProviderTest.php +++ b/tests/Configuration/Cache/RedisCacheProviderTest.php @@ -2,9 +2,9 @@ use Illuminate\Contracts\Cache\Factory; use Illuminate\Contracts\Cache\Repository; -use LaravelDoctrine\ORM\Configuration\Cache\IlluminateCacheAdapter; use LaravelDoctrine\ORM\Configuration\Cache\RedisCacheProvider; use Mockery as m; +use Psr\Cache\CacheItemPoolInterface; class RedisCacheProviderTest extends AbstractCacheProviderTest { @@ -23,6 +23,6 @@ public function getProvider() public function getExpectedInstance() { - return IlluminateCacheAdapter::class; + return CacheItemPoolInterface::class; } } diff --git a/tests/Configuration/Cache/VoidCacheProviderTest.php b/tests/Configuration/Cache/VoidCacheProviderTest.php deleted file mode 100644 index e730e2f9..00000000 --- a/tests/Configuration/Cache/VoidCacheProviderTest.php +++ /dev/null @@ -1,17 +0,0 @@ -getResolvedMysqlConfig(), $this->getInputConfig(), $this->getExpectedConfig()]; - - // Case #1. Configuration is only set in the read/write nodes. - $out[] = [['driver' => 'pdo_mysql'], $this->getNodesInputConfig(), $this->getNodesExpectedConfig()]; - - // Case #2. Simple valid configuration with oracle base settings. - $out[] = [$this->getResolvedOracleConfig(), $this->getInputConfig(), $this->getOracleExpectedConfig()]; - - // Case #3. Simple valid configuration with pgqsql base settings. - $out[] = [$this->getResolvedPgqsqlConfig(), $this->getInputConfig(), $this->getPgsqlExpectedConfig()]; - - // Case #4. Simple valid configuration with sqlite base settings. - $out[] = [$this->getResolvedSqliteConfig(), $this->getSqliteInputConfig(), $this->getSqliteExpectedConfig()]; - - return $out; - } - - /** - * Check if master slave connection manages configuration well. - * - * @param array $resolvedBaseSettings - * @param array $settings - * @param $expectedOutput - * - * @dataProvider getMasterSlaveConnectionData - */ - public function testMasterSlaveConnection(array $resolvedBaseSettings, array $settings, array $expectedOutput) - { - $this->assertEquals( - $expectedOutput, - (new MasterSlaveConnection(m::mock(Repository::class), $resolvedBaseSettings))->resolve($settings) - ); - } - - /** - * Returns dummy input configuration for testing. - * - * @return array - */ - private function getInputConfig() - { - return [ - 'driver' => 'mysql', - 'host' => 'localhost', - 'port' => '3306', - 'database' => 'test', - 'username' => 'homestead', - 'password' => 'secret', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', - 'strict' => false, - 'engine' => null, - 'write' => [ - 'port' => 3307, - 'user' => 'homestead1', - 'password' => 'secret1', - ], - 'read' => [ - [ - 'port' => 3308, - 'database' => 'test2', - ], - [ - 'host' => 'localhost2', - 'port' => 3309 - ], - ], - 'serverVersion' => '5.8', - 'defaultTableOptions' => [ - 'charset' => 'utf8mb4', - 'collate' => 'utf8mb4_unicode_ci', - ] - ]; - } - - /** - * Returns dummy expected result configuration for testing. - * - * @return array - */ - private function getExpectedConfig() - { - return [ - 'wrapperClass' => MasterSlaveDoctrineWrapper::class, - 'driver' => 'pdo_mysql', - 'serverVersion' => '5.8', - 'slaves' => [ - [ - 'host' => 'localhost', - 'user' => 'homestead', - 'password' => 'secret', - 'dbname' => 'test2', - 'port' => '3308', - 'charset' => 'charset', - 'unix_socket' => 'unix_socket', - 'prefix' => 'prefix' - ], - [ - 'host' => 'localhost2', - 'user' => 'homestead', - 'password' => 'secret', - 'dbname' => 'test', - 'port' => '3309', - 'charset' => 'charset', - 'unix_socket' => 'unix_socket', - 'prefix' => 'prefix' - ] - ], - 'master' => [ - 'host' => 'localhost', - 'user' => 'homestead1', - 'password' => 'secret1', - 'dbname' => 'test', - 'port' => '3307', - 'charset' => 'charset', - 'unix_socket' => 'unix_socket', - 'prefix' => 'prefix' - ], - 'defaultTableOptions' => [ - 'charset' => 'utf8mb4', - 'collate' => 'utf8mb4_unicode_ci', - ], - ]; - } - - /** - * Returns dummy input configuration where configuration is only set in read and write nodes. - * - * @return array - */ - private function getNodesInputConfig() - { - return [ - 'write' => [ - 'port' => 3307, - 'password' => 'secret1', - 'host' => 'localhost', - 'database' => 'test', - 'username' => 'homestead' - ], - 'read' => [ - [ - 'port' => 3308, - 'database' => 'test2', - 'host' => 'localhost', - 'username' => 'homestead', - 'password' => 'secret' - ], - [ - 'host' => 'localhost2', - 'port' => 3309, - 'database' => 'test', - 'username' => 'homestead', - 'password' => 'secret' - ], - ], - ]; - } - - /** - * Returns dummy expected output configuration where configuration is only set in read and write nodes. - * - * @return array - */ - private function getNodesExpectedConfig() - { - return [ - 'wrapperClass' => MasterSlaveDoctrineWrapper::class, - 'driver' => 'pdo_mysql', - 'slaves' => [ - [ - 'host' => 'localhost', - 'user' => 'homestead', - 'password' => 'secret', - 'dbname' => 'test2', - 'port' => '3308', - ], - [ - 'host' => 'localhost2', - 'user' => 'homestead', - 'password' => 'secret', - 'dbname' => 'test', - 'port' => '3309', - ] - ], - 'master' => [ - 'host' => 'localhost', - 'user' => 'homestead', - 'password' => 'secret1', - 'dbname' => 'test', - 'port' => '3307', - ], - ]; - } - - /** - * Returns dummy expected result configuration for testing oracle connections. - * - * @return array - */ - private function getOracleExpectedConfig() - { - $expectedConfigOracle = $this->getNodesExpectedConfig(); - $expectedConfigOracle['driver'] = 'oci8'; - $expectedConfigOracle['master']['user'] = 'homestead1'; - $expectedConfigOracle['serverVersion'] = '5.8'; - - $expectedConfigOracle['defaultTableOptions'] = [ - 'charset' => 'utf8mb4', - 'collate' => 'utf8mb4_unicode_ci', - ]; - - return $expectedConfigOracle; - } - - /** - * Returns dummy expected result configuration for testing pgsql connections. - * - * @return array - */ - private function getPgsqlExpectedConfig() - { - $expectedConfigPgsql = $this->getNodesExpectedConfig(); - $expectedConfigPgsql['driver'] = 'pgsql'; - $expectedConfigPgsql['master']['user'] = 'homestead1'; - $expectedConfigPgsql['master']['sslmode'] = 'sslmode'; - $expectedConfigPgsql['slaves'][0]['sslmode'] = 'sslmode'; - $expectedConfigPgsql['slaves'][1]['sslmode'] = 'sslmode'; - $expectedConfigPgsql['serverVersion'] = '5.8'; - - $expectedConfigPgsql['defaultTableOptions'] = [ - 'charset' => 'utf8mb4', - 'collate' => 'utf8mb4_unicode_ci', - ]; - - return $expectedConfigPgsql; - } - - /** - * Returns dummy expected result configuration for testing Sqlite connections. - * - * @return array - */ - private function getSqliteExpectedConfig() - { - return [ - 'wrapperClass' => MasterSlaveDoctrineWrapper::class, - 'driver' => 'pdo_sqlite', - 'slaves' => [ - [ - 'user' => 'homestead', - 'password' => 'secret', - 'port' => 3308, - 'path' => ':memory', - 'memory' => true, - ], - [ - 'host' => 'localhost2', - 'user' => 'homestead', - 'password' => 'secret', - 'port' => 3309, - 'path' => ':memory', - 'memory' => true, - ] - ], - 'master' => [ - 'user' => 'homestead1', - 'password' => 'secret1', - 'port' => 3307, - 'memory' => true, - 'path' => ':memory', - ], - 'serverVersion' => '5.8', - 'defaultTableOptions' => [ - 'charset' => 'utf8mb4', - 'collate' => 'utf8mb4_unicode_ci', - ] - ]; - } - - /** - * Returns dummy input configuration for testing Sqlite connections. - * - * @return array - */ - private function getSqliteInputConfig() - { - $inputConfigSqlite = $this->getInputConfig(); - unset($inputConfigSqlite['read'][0]['database']); - unset($inputConfigSqlite['read'][1]['database']); - unset($inputConfigSqlite['write']['database']); - - return $inputConfigSqlite; - } - - /** - * Returns already resolved mysql configuration. - * - * @return array - */ - private function getResolvedMysqlConfig() - { - return [ - 'driver' => 'pdo_mysql', - 'host' => 'localhost', - 'dbname' => 'test', - 'user' => 'homestead', - 'password' => 'secret', - 'charset' => 'charset', - 'port' => 'port', - 'unix_socket' => 'unix_socket', - 'prefix' => 'prefix' - ]; - } - - /** - * Returns already resolved oci configuration. - * - * @return array - */ - private function getResolvedOracleConfig() - { - return [ - 'driver' => 'oci8', - 'host' => 'localhost', - 'dbname' => 'test', - 'user' => 'homestead', - 'password' => 'secret', - 'port' => 'port', - ]; - } - - /** - * Returns already resolved sqlite configuration. - * - * @return array - */ - private function getResolvedSqliteConfig() - { - return [ - 'driver' => 'pdo_sqlite', - 'path' => ':memory', - 'user' => 'homestead', - 'password' => 'secret', - 'memory' => true - ]; - } - - /** - * Returns already resolved pgsql configuration. - * - * @return array - */ - private function getResolvedPgqsqlConfig() - { - return [ - 'driver' => 'pgsql', - 'host' => 'localhost', - 'dbname' => 'test', - 'user' => 'homestead', - 'password' => 'secret', - 'port' => 'port', - 'sslmode' => 'sslmode', - ]; - } -} diff --git a/tests/Configuration/Connections/PgsqlConnectionTest.php b/tests/Configuration/Connections/PgsqlConnectionTest.php index fcad5571..047b2f04 100644 --- a/tests/Configuration/Connections/PgsqlConnectionTest.php +++ b/tests/Configuration/Connections/PgsqlConnectionTest.php @@ -38,6 +38,7 @@ public function test_can_resolve() 'prefix' => 'prefix', 'sslmode' => 'sslmode', 'defaultTableOptions' => [], + 'driverOptions' => [], ]); $this->assertEquals('pdo_pgsql', $resolved['driver']); @@ -50,6 +51,7 @@ public function test_can_resolve() $this->assertEquals('sslmode', $resolved['sslmode']); $this->assertEquals('prefix', $resolved['prefix']); $this->assertCount(0, $resolved['defaultTableOptions']); + $this->assertCount(0, $resolved['driverOptions']); } protected function tearDown(): void diff --git a/tests/Configuration/Connections/SqliteConnectionTest.php b/tests/Configuration/Connections/SqliteConnectionTest.php index ebbf2dc9..eb62c044 100644 --- a/tests/Configuration/Connections/SqliteConnectionTest.php +++ b/tests/Configuration/Connections/SqliteConnectionTest.php @@ -34,6 +34,7 @@ public function test_can_resolve() 'password' => 'password', 'prefix' => 'prefix', 'defaultTableOptions' => [], + 'driverOptions' => [], ]); $this->assertEquals('pdo_sqlite', $resolved['driver']); @@ -43,6 +44,7 @@ public function test_can_resolve() $this->assertFalse($resolved['memory']); $this->assertEquals('path', $resolved['path']); $this->assertCount(0, $resolved['defaultTableOptions']); + $this->assertCount(0, $resolved['driverOptions']); } public function test_can_resolve_with_in_memory_database() diff --git a/tests/Configuration/Connections/SqlsrvConnectionTest.php b/tests/Configuration/Connections/SqlsrvConnectionTest.php index 9cecc498..16eb9f8c 100644 --- a/tests/Configuration/Connections/SqlsrvConnectionTest.php +++ b/tests/Configuration/Connections/SqlsrvConnectionTest.php @@ -37,6 +37,7 @@ public function test_can_resolve() 'prefix' => 'prefix', 'charset' => 'charset', 'defaultTableOptions' => [], + 'driverOptions' => [], ]); $this->assertEquals('pdo_sqlsrv', $resolved['driver']); @@ -48,6 +49,7 @@ public function test_can_resolve() $this->assertEquals('prefix', $resolved['prefix']); $this->assertEquals('charset', $resolved['charset']); $this->assertCount(0, $resolved['defaultTableOptions']); + $this->assertCount(0, $resolved['driverOptions']); } protected function tearDown(): void diff --git a/tests/Configuration/CustomTypeManagerTest.php b/tests/Configuration/CustomTypeManagerTest.php index 913614c9..572f3479 100644 --- a/tests/Configuration/CustomTypeManagerTest.php +++ b/tests/Configuration/CustomTypeManagerTest.php @@ -1,6 +1,6 @@ ['entities'], 'dev' => true, 'proxies' => ['path' => 'path'], - 'simple' => false ]); $this->assertInstanceOf(MappingDriver::class, $resolved); diff --git a/tests/Configuration/MetaData/Config/ConfigTest.php b/tests/Configuration/MetaData/Config/ConfigTest.php deleted file mode 100644 index 9f47dae4..00000000 --- a/tests/Configuration/MetaData/Config/ConfigTest.php +++ /dev/null @@ -1,44 +0,0 @@ -config = m::mock(Repository::class); - $this->config->shouldReceive('get')->with('mappings', [])->once()->andReturn([ - 'App\User' => [] - ]); - - $this->meta = new Config($this->config); - } - - public function test_can_resolve() - { - $resolved = $this->meta->resolve([ - 'paths' => ['entities'], - 'dev' => true, - 'proxies' => ['path' => 'path'], - 'mapping_file' => 'mappings' - ]); - - $this->assertInstanceOf(MappingDriver::class, $resolved); - } -} diff --git a/tests/Configuration/MetaData/ConfigDriverTest.php b/tests/Configuration/MetaData/ConfigDriverTest.php deleted file mode 100644 index 70174bba..00000000 --- a/tests/Configuration/MetaData/ConfigDriverTest.php +++ /dev/null @@ -1,56 +0,0 @@ -driver = new ConfigDriver( - [ - 'App\User' => [ - 'type' => 'entity', - 'table' => 'users', - 'id' => [ - 'id' => [ - 'type' => 'integer', - 'strategy' => 'identity' - ], - ], - 'fields' => [ - 'name' => [ - 'type' => 'string' - ] - ] - ], - 'App\Article' => [ - 'type' => 'entity' - ] - ] - ); - } - - public function test_can_get_all_class_names() - { - $this->assertContains('App\User', $this->driver->getAllClassNames()); - $this->assertContains('App\Article', $this->driver->getAllClassNames()); - } - - public function test_can_check_if_is_transient() - { - $this->assertFalse($this->driver->isTransient('App\User')); - $this->assertTrue($this->driver->isTransient('App\NonExisting')); - } - - public function test_can_element() - { - $this->assertContains('entity', $this->driver->getElement('App\Article')); - $this->assertNull($this->driver->getElement('App\NonExisting')); - } -} diff --git a/tests/Console/Exporters/FluentExporterTest.php b/tests/Console/Exporters/FluentExporterTest.php deleted file mode 100644 index 73cd33d5..00000000 --- a/tests/Console/Exporters/FluentExporterTest.php +++ /dev/null @@ -1,57 +0,0 @@ -mapField([ - 'fieldName' => 'id', - 'type' => 'integer', - 'id' => true - ]); - - $expected = <<integer('id')->primary(); - } -} -PHP; - $exporter = new FluentExporter(); - $this->assertEquals(str_replace(["\r", "\n", ' '], '', $expected), str_replace(["\r", "\n", ' '], '', $exporter->exportClassMetadata($metadata))); - } -} diff --git a/tests/DoctrineManagerTest.php b/tests/DoctrineManagerTest.php index b86b5dc7..70a855d6 100644 --- a/tests/DoctrineManagerTest.php +++ b/tests/DoctrineManagerTest.php @@ -152,32 +152,6 @@ public function test_can_extend_all_connections() BootChain::boot($this->registry); } - public function test_can_add_a_new_namespace_to_default_connection() - { - $this->registry->shouldReceive('getManager') - ->once() - ->with('default') - ->andReturn($this->em); - - $configuration = m::mock(Configuration::class); - - $mappingDriver = m::mock(MappingDriverChain::class); - $mappingDriver->shouldReceive('addNamespace')->once()->with('NewNamespace'); - - $configuration->shouldReceive('getMetadataDriverImpl') - ->once() - ->andReturn($mappingDriver); - - $this->em->shouldReceive('getConfiguration') - ->once()->andReturn($configuration); - - $this->manager->addNamespace('NewNamespace', 'default'); - - BootChain::boot($this->registry); - - $this->assertTrue(true); - } - public function test_can_add_paths_to_default_connection() { $this->registry->shouldReceive('getManager') diff --git a/tests/EntityManagerFactoryTest.php b/tests/EntityManagerFactoryTest.php index 5c60b039..a3f2b868 100644 --- a/tests/EntityManagerFactoryTest.php +++ b/tests/EntityManagerFactoryTest.php @@ -1,10 +1,10 @@ mockResolver(); $this->mockConfig(); - $this->setup = m::mock(Setup::class); + $this->setup = m::mock(ORMSetupResolver::class); $this->setup->shouldReceive('createConfiguration')->once()->andReturn($this->configuration); $this->factory = new EntityManagerFactory( @@ -149,18 +149,6 @@ public function test_debugbar_logger_can_be_enabled() $this->disableCustomFunctions(); $this->enableLaravelNamingStrategy(); - $this->config->shouldReceive('get') - ->with('doctrine.logger', false) - ->twice()->andReturn('LoggerMock'); - - $logger = m::mock(Logger::class); - - $this->container->shouldReceive('make') - ->with('LoggerMock')->once() - ->andReturn($logger); - - $logger->shouldReceive('register')->once(); - $manager = $this->factory->create($this->settings); $this->assertEntityManager($manager); @@ -239,10 +227,12 @@ public function test_custom_cache_namespace_can_be_set() ->andReturn('namespace'); foreach ($this->caches as $cache) { - $this->config->shouldReceive('get') - ->with('doctrine.cache.' . $cache . '.namespace', 'namespace') + $this->config->shouldNotReceive('get') + ->with('doctrine.cache.' . $cache, []) ->once() - ->andReturn('namespace'); + ->andReturn([ + 'namespace' => $cache, + ])->byDefault(); } $cache = m::mock(Cache::class); @@ -315,8 +305,8 @@ public function test_can_set_listeners() $manager = $this->factory->create($this->settings); $this->assertEntityManager($manager); - $this->assertCount(1, $manager->getEventManager()->getListeners()); - $this->assertTrue(array_key_exists('name', $manager->getEventManager()->getListeners())); + $this->assertCount(1, $manager->getEventManager()->getAllListeners()); + $this->assertTrue(array_key_exists('name', $manager->getEventManager()->getAllListeners())); } public function test_can_set_multiple_listeners() @@ -346,8 +336,8 @@ public function test_can_set_multiple_listeners() $manager = $this->factory->create($this->settings); $this->assertEntityManager($manager); - $this->assertCount(1, $manager->getEventManager()->getListeners()); - $this->assertTrue(array_key_exists('name', $manager->getEventManager()->getListeners())); + $this->assertCount(1, $manager->getEventManager()->getAllListeners()); + $this->assertTrue(array_key_exists('name', $manager->getEventManager()->getAllListeners())); $this->assertCount(2, $manager->getEventManager()->getListeners('name')); } @@ -380,7 +370,7 @@ public function test_can_set_subscribers() $this->container->shouldReceive('make') ->with(SubscriberStub::class) ->once() - ->andReturn(new SubscriberStub); + ->andReturn(new SubscriberStub()); $this->disableDebugbar(); $this->disableSecondLevelCaching(); @@ -395,8 +385,8 @@ public function test_can_set_subscribers() $manager = $this->factory->create($this->settings); $this->assertEntityManager($manager); - $this->assertCount(1, $manager->getEventManager()->getListeners()); - $this->assertTrue(array_key_exists('onFlush', $manager->getEventManager()->getListeners())); + $this->assertCount(1, $manager->getEventManager()->getAllListeners()); + $this->assertTrue(array_key_exists('onFlush', $manager->getEventManager()->getAllListeners())); } public function test_setting_non_existent_subscriber_throws_exception() @@ -556,7 +546,7 @@ public function test_illuminate_cache_provider_custom_store() $factory = new EntityManagerFactory( $container, - new Setup(), + new ORMSetupResolver(), new MetaDataManager($container), new ConnectionManager($container), new CacheManager($container), @@ -566,7 +556,7 @@ public function test_illuminate_cache_provider_custom_store() $manager = $factory->create($config->get('doctrine')); - $this->assertInstanceOf(IlluminateCacheAdapter::class, $manager->getConfiguration()->getMetadataCacheImpl()); + $this->assertInstanceOf(CacheItemPoolInterface::class, $manager->getConfiguration()->getMetadataCache()); } public function test_illuminate_cache_provider_redis() @@ -614,7 +604,7 @@ public function test_illuminate_cache_provider_redis() $factory = new EntityManagerFactory( $container, - new Setup(), + new ORMSetupResolver(), new MetaDataManager($container), new ConnectionManager($container), new CacheManager($container), @@ -624,7 +614,7 @@ public function test_illuminate_cache_provider_redis() $manager = $factory->create($config->get('doctrine')); - $this->assertInstanceOf(IlluminateCacheAdapter::class, $manager->getConfiguration()->getMetadataCacheImpl()); + $this->assertInstanceOf(CacheItemPoolInterface::class, $manager->getConfiguration()->getMetadataCache()); } public function test_illuminate_cache_provider_invalid_store() @@ -672,7 +662,7 @@ public function test_illuminate_cache_provider_invalid_store() $factory = new EntityManagerFactory( $container, - new Setup(), + new ORMSetupResolver(), new MetaDataManager($container), new ConnectionManager($container), new CacheManager($container), @@ -732,7 +722,7 @@ public function test_php_file_cache_custom_path() $factory = new EntityManagerFactory( $container, - new Setup(), + new ORMSetupResolver(), new MetaDataManager($container), new ConnectionManager($container), new CacheManager($container), @@ -742,8 +732,14 @@ public function test_php_file_cache_custom_path() $manager = $factory->create($config->get('doctrine')); - $this->assertInstanceOf(\Doctrine\Common\Cache\PhpFileCache::class, $manager->getConfiguration()->getMetadataCacheImpl()); - $this->assertStringEndsWith('myCustomPath', $manager->getConfiguration()->getMetadataCacheImpl()->getDirectory()); + $metadata_cache = $manager->getConfiguration()->getMetadataCache(); + $this->assertInstanceOf(\Symfony\Component\Cache\Adapter\PhpFilesAdapter::class, $metadata_cache); + + $reflection_cache = new ReflectionObject($metadata_cache); + $directory_property = $reflection_cache->getProperty('directory'); + $directory_property->setAccessible(true); + + $this->assertStringContainsString('myCustomPath', $directory_property->getValue($metadata_cache)); } public function test_wrapper_connection() @@ -777,7 +773,7 @@ public function test_wrapper_connection() $factory = new EntityManagerFactory( $container, - new Setup(), + new ORMSetupResolver(), new MetaDataManager($container), new ConnectionManager($container), new CacheManager($container), @@ -823,7 +819,7 @@ public function test_custom_event_manager() $factory = new EntityManagerFactory( $container, - new Setup(), + new ORMSetupResolver(), new MetaDataManager($container), new ConnectionManager($container), new CacheManager($container), @@ -899,8 +895,8 @@ protected function mockCache() $this->cache = m::mock(CacheManager::class); $this->cache->shouldReceive('driver') - ->times(count($this->caches) + 1) // one for each cache driver + one default - ->andReturn(new ArrayCache()); + ->times(count($this->caches)) // one for each cache driver + ->andReturn(new ArrayAdapter()); } protected function mockConnection() @@ -936,14 +932,11 @@ protected function mockApp() protected function mockResolver() { - $this->listenerResolver = m::mock(LaravelDoctrineEntityListenerResolver::class); + $this->listenerResolver = m::mock(EntityListenerResolver::class); } protected function disableDebugbar() { - $this->config->shouldReceive('get') - ->with('doctrine.logger', false) - ->once()->andReturn(false); } protected function disableSecondLevelCaching() @@ -963,13 +956,6 @@ protected function disableCustomCacheNamespace() ->with('doctrine.cache.namespace') ->atLeast()->once() ->andReturn(null); - - foreach ($this->caches as $cache) { - $this->config->shouldReceive('get') - ->with('doctrine.cache.' . $cache . '.namespace', null) - ->atLeast()->once() - ->andReturn(null); - } } protected function disableCustomFunctions() @@ -989,6 +975,8 @@ protected function mockORMConfiguration() $this->configuration->shouldReceive('setMetadataDriverImpl') ->atLeast()->once(); + $this->configuration->shouldReceive('setMiddlewares') + ->atLeast()->once(); $this->configuration->shouldReceive('getAutoCommit') ->atLeast()->once() @@ -998,14 +986,12 @@ protected function mockORMConfiguration() ->atLeast()->once() ->andReturn('Doctrine\ORM\Mapping\ClassMetadataFactory'); - $this->configuration->shouldReceive('setMetadataCacheImpl')->once(); - $this->configuration->shouldReceive('setQueryCacheImpl')->once(); - $this->configuration->shouldReceive('setResultCacheImpl')->once(); + $this->configuration->shouldReceive('setMetadataCache')->once(); + $this->configuration->shouldReceive('setQueryCache')->once(); + $this->configuration->shouldReceive('setResultCache')->once(); - $this->configuration->shouldReceive('getMetadataCache')->zeroOrMoreTimes(); - - $cache = m::mock(Cache::class); - $this->configuration->shouldReceive('getMetadataCacheImpl') + $cache = m::mock(CacheItemPoolInterface::class); + $this->configuration->shouldReceive('getMetadataCache') ->atLeast()->once() ->andReturn($cache); @@ -1014,14 +1000,14 @@ protected function mockORMConfiguration() ->atLeast()->once() ->andReturn($repoFactory); - $entityListenerResolver = m::mock(LaravelDoctrineEntityListenerResolver::class); + $entityListenerResolver = m::mock(EntityListenerResolver::class); $this->configuration->shouldReceive('getEntityListenerResolver') ->atLeast()->once() ->andReturn($entityListenerResolver); $this->configuration->shouldReceive('setEntityListenerResolver') ->atLeast()->once() - ->with(m::type(LaravelDoctrineEntityListenerResolver::class)); + ->with(m::type(EntityListenerResolver::class)); $this->configuration->shouldReceive('getProxyDir') ->atLeast()->once() @@ -1050,6 +1036,14 @@ protected function mockORMConfiguration() $this->configuration->shouldReceive('setDefaultRepositoryClassName') ->once() ->with('Repo'); + + $this->configuration->shouldReceive('getMiddlewares')->once()->andReturn([]); + + $this->configuration->shouldReceive('isLazyGhostObjectEnabled')->once()->andReturnFalse(); + + $schema_manager_factory = new DefaultSchemaManagerFactory(); + $this->configuration->shouldReceive('setSchemaManagerFactory')->once(); + $this->configuration->shouldReceive('getSchemaManagerFactory')->once()->andReturn($schema_manager_factory); } protected function enableLaravelNamingStrategy() @@ -1064,11 +1058,11 @@ protected function enableLaravelNamingStrategy() } /** - * Data provider for testMasterSlaveConnection. + * Data provider for testPrimaryReadReplicaConnection. * * @return array */ - public function getTestMasterSlaveConnectionData() + public function getTestPrimaryReadReplicaConnectionData() { $out = []; @@ -1135,9 +1129,9 @@ public function getTestMasterSlaveConnectionData() * @param string $expectedException * @param string $msg * - * @dataProvider getTestMasterSlaveConnectionData + * @dataProvider getTestPrimaryReadReplicaConnectionData */ - public function testMasterSlaveConnection( + public function testPrimaryReadReplicaConnection( array $inputConfig, $expectedException = '', $msg = '' @@ -1148,12 +1142,7 @@ public function testMasterSlaveConnection( $this->mockResolver(); $this->mockConfig($inputConfig, empty($expectedException)); - $this->cache = m::mock(CacheManager::class); - $this->cache->shouldReceive('driver') - ->times(empty($expectedException) ? 4 : 1) - ->andReturn(new ArrayCache()); - - $this->setup = m::mock(Setup::class); + $this->setup = m::mock(ORMSetupResolver::class); $this->setup->shouldReceive('createConfiguration')->once()->andReturn($this->configuration); $this->connection = m::mock(ConnectionManager::class); @@ -1184,60 +1173,9 @@ public function testMasterSlaveConnection( } $this->settings['connection'] = 'mysql'; - $factory->create($this->settings); - - $this->assertTrue(true); - } - - /** - * doctrine/dbal 2.11 has MasterSlaveConnection class deprecated in favour of PrimaryReadReplicaConnection - */ - public function testPrimaryReadReplicaConnectionIsUsedWhenAvailable() - { - if (!class_exists(DoctrinePrimaryReadReplicaConnection::class)) { - $this->markTestSkipped('Skipped for doctrine/dbal < 2.11'); - } - - m::resetContainer(); - - $this->mockApp(); - $this->mockResolver(); - $this->mockConfig($this->getDummyBaseInputConfig()); - - $this->cache = m::mock(CacheManager::class); - $this->cache->shouldReceive('driver') - ->times(4) - ->andReturn(new ArrayCache()); - - $this->setup = m::mock(Setup::class); - $this->setup->shouldReceive('createConfiguration')->once()->andReturn($this->configuration); - - $this->connection = m::mock(ConnectionManager::class); - $this->connection->shouldReceive('driver') - ->once() - ->with('mysql', $this->getDummyBaseInputConfig()) - ->andReturn(['driver' => 'pdo_mysql']); - - $factory = new EntityManagerFactory( - $this->container, - $this->setup, - $this->meta, - $this->connection, - $this->cache, - $this->config, - $this->listenerResolver - ); - - $this->disableDebugbar(); - $this->disableCustomCacheNamespace(); - $this->disableSecondLevelCaching(); - $this->disableCustomFunctions(); - $this->enableLaravelNamingStrategy(); - - $this->settings['connection'] = 'mysql'; - $entityManager = $factory->create($this->settings); + $em = $factory->create($this->settings); - $this->assertInstanceOf(DoctrinePrimaryReadReplicaConnection::class, $entityManager->getConnection()); + $this->assertInstanceOf(PrimaryReadReplicaConnection::class, $em->getConnection()); } protected function tearDown(): void diff --git a/tests/Extensions/ExtensionManagerTest.php b/tests/Extensions/ExtensionManagerTest.php index 0bf01767..168b26d0 100644 --- a/tests/Extensions/ExtensionManagerTest.php +++ b/tests/Extensions/ExtensionManagerTest.php @@ -17,7 +17,7 @@ class ExtensionManagerTest extends TestCase { /** - * @var Mock + * @var ManagerRegistry|Mock */ protected $registry; @@ -52,7 +52,7 @@ class ExtensionManagerTest extends TestCase protected $reader; /** - * @var Mock + * @var Container|Mock */ protected $container; diff --git a/tests/Extensions/MappingDriverChainTest.php b/tests/Extensions/MappingDriverChainTest.php index 8f96f96f..61d23f30 100644 --- a/tests/Extensions/MappingDriverChainTest.php +++ b/tests/Extensions/MappingDriverChainTest.php @@ -33,19 +33,6 @@ public function test_get_default_driver() $this->assertEquals($this->driver, $this->chain->getDefaultDriver()); } - public function test_can_add_namespace() - { - $this->chain->addNamespace('NewNamespace'); - $this->chain->addNamespace('NewNamespace2'); - $this->chain->addNamespace('NewNamespace3'); - - $this->assertArrayHasKey('Namespace', $this->chain->getDrivers()); - $this->assertArrayHasKey('NewNamespace', $this->chain->getDrivers()); - $this->assertArrayHasKey('NewNamespace2', $this->chain->getDrivers()); - $this->assertArrayHasKey('NewNamespace3', $this->chain->getDrivers()); - $this->assertArrayNotHasKey('NonExisting', $this->chain->getDrivers()); - } - public function test_can_add_paths() { $this->driver->shouldReceive('addPaths')->with(['paths'])->once(); diff --git a/tests/IlluminateRegistryTest.php b/tests/IlluminateRegistryTest.php index cce0e63e..c80e27c3 100644 --- a/tests/IlluminateRegistryTest.php +++ b/tests/IlluminateRegistryTest.php @@ -347,7 +347,7 @@ public function test_cannot_reset_non_existing_managers() public function test_get_alias_namespace_from_unknown_namespace() { $this->expectException(ORMException::class); - $this->expectExceptionMessage('Unknown Entity namespace alias \'Alias\''); + $this->expectExceptionMessage('Unknown Entity namespace alias "Alias"'); $this->registry->getAliasNamespace('Alias'); } diff --git a/tests/Loggers/Clockwork/DoctrineDataSourceTest.php b/tests/Loggers/Clockwork/DoctrineDataSourceTest.php deleted file mode 100644 index 9d5b6f66..00000000 --- a/tests/Loggers/Clockwork/DoctrineDataSourceTest.php +++ /dev/null @@ -1,66 +0,0 @@ -logger = new DebugStack; - $this->logger->queries = [ - [ - 'sql' => 'SELECT * FROM table WHERE condition = ?', - 'params' => ['value'], - 'executionMS' => 0.001 - ] - ]; - - $this->connection = m::mock(\Doctrine\DBAL\Connection::class); - $this->driver = m::mock(\Doctrine\DBAL\Driver::class); - - $this->driver->shouldReceive('getName')->once()->andReturn('mysql'); - - $this->connection->shouldReceive('getDriver')->once()->andReturn($this->driver); - $this->connection->shouldReceive('getDatabasePlatform')->once()->andReturn('mysql'); - - $this->source = new DoctrineDataSource($this->logger, $this->connection); - } - - public function test_transforms_debugstack_query_log_to_clockwork_compatible_array() - { - $request = $this->source->resolve(new Request); - - $this->assertEquals([ - [ - 'query' => 'SELECT * FROM table WHERE condition = "value"', - 'duration' => 1, - 'connection' => 'mysql' - ] - ], $request->databaseQueries); - } -} diff --git a/tests/Loggers/ClockworkLoggerTest.php b/tests/Loggers/ClockworkLoggerTest.php deleted file mode 100644 index fec224c6..00000000 --- a/tests/Loggers/ClockworkLoggerTest.php +++ /dev/null @@ -1,42 +0,0 @@ -shouldReceive('getConnection')->andReturn($connection); - $connection->shouldReceive('getDriver')->andReturn($driver); - $driver->shouldReceive('getName')->andReturn('mysql'); - - $configuration->shouldReceive('setSQLLogger') - ->once(); - - $clockwork->shouldReceive('addDataSource')->once(); - - $logger = new ClockworkLogger($clockwork); - - $logger->register($em, $configuration); - - $this->assertTrue(true); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Loggers/EchoLoggerTest.php b/tests/Loggers/EchoLoggerTest.php deleted file mode 100644 index 7429815a..00000000 --- a/tests/Loggers/EchoLoggerTest.php +++ /dev/null @@ -1,30 +0,0 @@ -shouldReceive('setSQLLogger') - ->once(); - - $logger = new EchoLogger(); - - $logger->register($em, $configuration); - - $this->assertTrue(true); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Loggers/File/DoctrineFileLoggerTest.php b/tests/Loggers/File/DoctrineFileLoggerTest.php deleted file mode 100644 index a0f36aaa..00000000 --- a/tests/Loggers/File/DoctrineFileLoggerTest.php +++ /dev/null @@ -1,52 +0,0 @@ -writer = m::mock(Log::class); - $this->connection = m::mock(Connection::class); - $this->logger = new DoctrineFileLogger( - $this->writer, - $this->connection - ); - } - - public function test_transforms_debugstack_query_log_to_clockwork_compatible_array() - { - $this->writer->shouldReceive('debug')->once(); - $this->connection->shouldReceive('getDatabasePlatform')->once(); - - $this->logger->startQuery('SELECT * FROM table WHERE condition = ?', ['value']); - $this->logger->stopQuery(); - - $this->assertEquals('SELECT * FROM table WHERE condition = "value"', $this->logger->getQuery()); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Loggers/FileLoggerTest.php b/tests/Loggers/FileLoggerTest.php deleted file mode 100644 index f5394e90..00000000 --- a/tests/Loggers/FileLoggerTest.php +++ /dev/null @@ -1,36 +0,0 @@ -shouldReceive('setSQLLogger') - ->once(); - - $em->shouldReceive('getConnection') - ->once()->andReturn(m::mock(Connection::class)); - - $logger = new FileLogger($writer); - - $logger->register($em, $configuration); - - $this->assertTrue(true); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Loggers/Formatters/FormatQueryKeywordsTest.php b/tests/Loggers/Formatters/FormatQueryKeywordsTest.php deleted file mode 100644 index cf1ecda8..00000000 --- a/tests/Loggers/Formatters/FormatQueryKeywordsTest.php +++ /dev/null @@ -1,86 +0,0 @@ -mock = m::mock(QueryFormatter::class); - - $this->platform = m::mock(AbstractPlatform::class); - - $this->formatter = new FormatQueryKeywords($this->mock); - } - - public function test_formats_select_queries() - { - $sql = "select * from table where condition is not null having count(id) > 10 limit 10 offset 10 group by parent order by position desc"; - $params = []; - $types = []; - - $this->decorate($this->platform, $sql, $params, $types); - - $this->assertEquals('SELECT * FROM table WHERE condition IS NOT NULL HAVING COUNT(id) > 10 LIMIT 10 OFFSET 10 GROUP BY parent ORDER BY position DESC', $this->formatter->format($this->platform, $sql, $params, $types)); - } - - public function test_formats_insert_queries() - { - $sql = "insert into table (column1, column2, column3) values (value1, value2, value3)"; - $params = []; - $types = []; - - $this->decorate($this->platform, $sql, $params, $types); - - $this->assertEquals('INSERT INTO table (column1, column2, column3) VALUES (value1, value2, value3)', $this->formatter->format($this->platform, $sql, $params, $types)); - } - - public function test_formats_update_queries() - { - $sql = "update table set column1=value, column2=value2 where some_column=some_value"; - $params = []; - $types = []; - - $this->decorate($this->platform, $sql, $params, $types); - - $this->assertEquals('UPDATE table SET column1=value, column2=value2 WHERE some_column=some_value', $this->formatter->format($this->platform, $sql, $params, $types)); - } - - public function test_formats_delete_queries() - { - $sql = "update table set column1=value, column2=value2 where some_column=some_value"; - $params = []; - $types = []; - - $this->decorate($this->platform, $sql, $params, $types); - - $this->assertEquals('UPDATE table SET column1=value, column2=value2 WHERE some_column=some_value', $this->formatter->format($this->platform, $sql, $params, $types)); - } - - protected function tearDown(): void - { - m::close(); - } - - protected function decorate($platform, $sql, $params, $types) - { - $this->mock->shouldReceive('format')->once()->with($platform, $sql, $params, $types)->andReturn($sql); - } -} diff --git a/tests/Loggers/Formatters/ReplaceQueryParamsTest.php b/tests/Loggers/Formatters/ReplaceQueryParamsTest.php deleted file mode 100644 index d75ae934..00000000 --- a/tests/Loggers/Formatters/ReplaceQueryParamsTest.php +++ /dev/null @@ -1,182 +0,0 @@ -platform = m::mock(AbstractPlatform::class); - $this->formatter = new ReplaceQueryParams; - } - - public function test_can_replace_string_param() - { - $sql = 'SELECT * FROM table WHERE column = ?'; - $params = ['value']; - - $this->assertEquals( - 'SELECT * FROM table WHERE column = "value"', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_can_replace_multiple_string_params() - { - $sql = 'SELECT * FROM table WHERE column = ? AND column2 = ?'; - $params = ['value', 'value2']; - - $this->assertEquals( - 'SELECT * FROM table WHERE column = "value" AND column2 = "value2"', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_cannot_replace_object_params_without__toString() - { - $this->expectException(Exception::class); - $this->expectExceptionMessage('Given query param is an instance of ObjectClass and could not be converted to a string'); - - $sql = 'SELECT * FROM table WHERE column = ?'; - $params = [new ObjectClass]; - - $this->formatter->format($this->platform, $sql, $params); - } - - public function test_can_replace_object_params_with__toString() - { - $sql = 'SELECT * FROM table WHERE column = ?'; - $params = [new StringClass]; - - $this->assertEquals( - 'SELECT * FROM table WHERE column = "string"', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_can_replace_datetime_objects() - { - $date = new DateTime('now'); - $sql = 'SELECT * FROM table WHERE column = ?'; - $params = [$date]; - - $this->assertEquals( - 'SELECT * FROM table WHERE column = "' . $date->format('Y-m-d H:i:s') . '"', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_can_replace_datetime_immutable_objects() - { - $date = new DateTimeImmutable('now'); - $sql = 'SELECT * FROM table WHERE column = ?'; - $params = [$date]; - - $this->assertEquals( - 'SELECT * FROM table WHERE column = "' . $date->format('Y-m-d H:i:s') . '"', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_can_replace_array_param() - { - $sql = 'SELECT * FROM table WHERE column IN ?'; - $params = [['value1', 'value2']]; - - $this->assertEquals( - 'SELECT * FROM table WHERE column IN ("value1", "value2")', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_can_replace_nested_array_param() - { - $sql = 'SELECT * FROM table WHERE column = ?'; - $params = [['key1' => 'value1', 'key2' => ['key21' => 'value22']]]; - - $this->assertEquals( - 'SELECT * FROM table WHERE column = "' . json_encode(reset($params), JSON_UNESCAPED_UNICODE) . '"', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_can_replace_nested_array_param2() - { - $sql = 'INSERT INTO foo (column1) VALUES (?)'; - $params = [ - 1 => [ - 'id' => 20, - 'foo' => 'bar', - 'nested' => [] - ] - ]; - - $this->assertEquals( - 'INSERT INTO foo (column1) VALUES ("{"id":20,"foo":"bar","nested":[]}")', - $this->formatter->format($this->platform, $sql, $params) - ); - } - - public function test_replace_object_params_without__toString_but_type() - { - $sql = 'UPDATE table foo SET column = ?'; - $params = [new ObjectClass()]; - $types = ['object_type']; - - if (!Type::hasType('object_type')) { - Type::addType('object_type', ObjectType::class); - } - - $this->assertEquals( - 'UPDATE table foo SET column = "{"status":false}"', - $this->formatter->format($this->platform, $sql, $params, $types) - ); - } - - protected function tearDown(): void - { - m::close(); - } -} - -class ObjectClass -{ - public $status = false; -} - -class StringClass -{ - public function __toString() - { - return 'string'; - } -} - -class ObjectType extends JsonArrayType -{ - public function convertToDatabaseValue($value, AbstractPlatform $platform) - { - return json_encode(get_object_vars($value)); - } - - public function getName() - { - return 'object_type'; - } -} diff --git a/tests/Loggers/LaravelDebugbarLoggerTest.php b/tests/Loggers/LaravelDebugbarLoggerTest.php deleted file mode 100644 index 789eee8c..00000000 --- a/tests/Loggers/LaravelDebugbarLoggerTest.php +++ /dev/null @@ -1,35 +0,0 @@ -shouldReceive('setSQLLogger') - ->once(); - - $debugbar->shouldReceive('hasCollector')->with('doctrine')->once()->andReturn(false); - $debugbar->shouldReceive('addCollector')->once(); - - $logger = new LaravelDebugbarLogger($debugbar); - - $logger->register($em, $configuration); - - $this->assertTrue(true); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Middleware/SubstituteBindingsTest.php b/tests/Middleware/SubstituteBindingsTest.php index b0b7e95c..ba1ebd2a 100644 --- a/tests/Middleware/SubstituteBindingsTest.php +++ b/tests/Middleware/SubstituteBindingsTest.php @@ -6,6 +6,8 @@ use Illuminate\Contracts\Routing\Registrar; use Illuminate\Events\Dispatcher; use Illuminate\Http\Request; +use Illuminate\Routing\CallableDispatcher; +use Illuminate\Routing\Contracts\CallableDispatcher as CallableDispatcherContract; use Illuminate\Routing\Router; use LaravelDoctrine\ORM\Middleware\SubstituteBindings; use Mockery as m; @@ -39,6 +41,7 @@ public function setUp(): void protected function getRouter() { $container = new Container; + $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app)); $router = new Router(new Dispatcher, $container); $container->singleton(Registrar::class, function () use ($router) { @@ -62,9 +65,7 @@ public function test_entity_binding() $router = $this->getRouter(); $router->get('foo/{entity}', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (BindableEntity $entity) { - return $entity->getName(); - }, + 'uses' => 'EntityController@returnEntityName', ]); $this->mockRegistry(); @@ -84,9 +85,7 @@ public function test_entity_binding_expect_entity_not_found_exception() $router->get('foo/{entity}', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (BindableEntity $entity) { - return $entity->getName(); - }, + 'uses' => 'EntityController@returnEntityName', ]); $this->mockRegistry(); @@ -100,9 +99,7 @@ public function test_entity_binding_get_null_entity() $router = $this->getRouter(); $router->get('foo/{entity}', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (BindableEntity $entity = null) { - return $entity; - }, + 'uses' => 'EntityController@returnEntity', ]); $this->mockRegistry(); @@ -116,18 +113,14 @@ public function test_binding_value() $router = $this->getRouter(); $router->get('foo/{value}', [ 'middleware' => SubstituteBindings::class, - 'uses' => function ($value) { - return $value; - }, + 'uses' => 'EntityController@returnValue', ]); $this->assertEquals(123456, $router->dispatch(Request::create('foo/123456', 'GET'))->getContent()); $router->get('doc/trine', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (Request $request) { - return $request instanceof Request ? 'request' : 'something else'; - }, + 'uses' => 'EntityController@checkRequest', ]); $this->assertEquals('request', $router->dispatch(Request::create('doc/trine', 'GET'))->getContent()); @@ -172,9 +165,7 @@ public function test_for_typed_value_binding() $router = $this->getRouter(); $router->get('foo/{value}', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (string $value) { - return $value; - }, + 'uses' => 'EntityController@returnValue', ]); $this->assertEquals('test', $router->dispatch(Request::create('foo/test', 'GET'))->getContent()); @@ -182,18 +173,14 @@ public function test_for_typed_value_binding() $router = $this->getRouter(); $router->get('bar/{value}', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (int $value) { - return $value; - }, + 'uses' => 'EntityController@returnValue', ]); $this->assertEquals(123456, $router->dispatch(Request::create('bar/123456', 'GET'))->getContent()); $router->get('doc/trine', [ 'middleware' => SubstituteBindings::class, - 'uses' => function (Request $request) { - return $request instanceof Request ? 'request' : 'something else'; - }, + 'uses' => 'EntityController@checkRequest', ]); $this->assertEquals('request', $router->dispatch(Request::create('doc/trine', 'GET'))->getContent()); @@ -238,7 +225,7 @@ public function getName() return strtolower($this->name); } - public static function getRouteKeyName(): string + public static function getRouteKeyNameStatic(): string { return 'name'; } @@ -255,4 +242,21 @@ public function interfacer(BindableEntityWithInterface $entity) { return $entity->getId(); } + + public function returnValue(string $value) + { + return $value; + } + + public function returnEntity(BindableEntity $entity = null) { + return $entity; + } + + public function returnEntityName(BindableEntity $entity) { + return $entity->getName(); + } + + public function checkRequest(Request $request) { + return $request instanceof Request ? 'request' : 'something else'; + } } diff --git a/tests/Pagination/PaginatorAdapterTest.php b/tests/Pagination/PaginatorAdapterTest.php index c3476574..040da1a0 100644 --- a/tests/Pagination/PaginatorAdapterTest.php +++ b/tests/Pagination/PaginatorAdapterTest.php @@ -2,7 +2,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Internal\Hydration\AbstractHydrator; @@ -91,14 +91,14 @@ private function mockEntityManager() 'id' => [ 'fieldName' => 'id', 'columnName' => 'id', - 'type' => Type::INTEGER, + 'type' => Types::INTEGER, 'id' => true, 'options' => ['unsigned' => true], ], 'name' => [ 'fieldName' => 'name', 'columnName' => 'name', - 'type' => Type::STRING, + 'type' => Types::STRING, ], ]; @@ -117,10 +117,10 @@ private function mockEntityManager() $metadata->shouldReceive('isInheritanceTypeSingleTable')->andReturn(false); $metadata->shouldReceive('isInheritanceTypeJoined')->andReturn(false); $metadata->shouldReceive('getTableName')->andReturn('fooes'); - $metadata->shouldReceive('getTypeOfField')->andReturn(Type::INTEGER); + $metadata->shouldReceive('getTypeOfField')->andReturn(Types::INTEGER); $connection->shouldReceive('getDatabasePlatform')->andReturn($platform); - $connection->shouldReceive('executeQuery')->andReturn([]); + $connection->shouldReceive('executeQuery')->andReturn($this->createMock(\Doctrine\DBAL\Result::class)); $connection->shouldReceive('getParams')->andReturn([]); $platform->shouldReceive('appendLockHint')->andReturnUsing(function ($a) { diff --git a/tests/Serializers/ArraySerializerTest.php b/tests/Serializers/ArraySerializerTest.php index 4df93306..55431b6f 100644 --- a/tests/Serializers/ArraySerializerTest.php +++ b/tests/Serializers/ArraySerializerTest.php @@ -22,7 +22,8 @@ public function test_can_serialize_to_array() $this->assertEquals([ 'id' => 'IDVALUE', - 'name' => 'NAMEVALUE' + 'name' => 'NAMEVALUE', + 'list' => ['item1', 'item2'] ], $array); } } @@ -35,6 +36,8 @@ class ArrayableEntity protected $name = 'NAMEVALUE'; + protected $list = ['item1', 'item2']; + public function getId() { return $this->id; @@ -44,4 +47,9 @@ public function getName() { return $this->name; } + + public function getList() + { + return $this->list; + } } diff --git a/tests/Testing/FactoryBuilderTest.php b/tests/Testing/FactoryBuilderTest.php index d6230b9f..abc3b02a 100644 --- a/tests/Testing/FactoryBuilderTest.php +++ b/tests/Testing/FactoryBuilderTest.php @@ -93,7 +93,7 @@ protected function getEntityManager() 'database' => ':memory:', ]; - $config = Setup::createAnnotationMetadataConfiguration([__DIR__], true); + $config = Setup::createAttributeMetadataConfiguration([__DIR__], true); return EntityManager::create($conn, $config); } @@ -263,27 +263,29 @@ public function test_it_handles_after_making_with_state_callback() } } -/** - * @Entity - */ +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\JoinTable; +use Doctrine\ORM\Mapping\JoinColumn; +use Doctrine\ORM\Mapping\ManyToMany; +use Doctrine\ORM\Mapping\InverseJoinColumn; + +#[Entity] class EntityStub { - /** - * @Id @GeneratedValue @Column(type="integer") - */ + #[Id] + #[GeneratedValue] + #[Column(type: "integer")] public $id; - /** - * @Column(type="string") - */ + #[Column(type: "string")] public $name; - /** - * @ManyToMany(targetEntity="EntityStub") - * @JoinTable(name="stub_stubs", - * joinColumns={@JoinColumn(name="owner_id", referencedColumnName="id")}, - * inverseJoinColumns={@JoinColumn(name="owned_id", referencedColumnName="id")} - * ) - */ + #[ManyToMany(targetEntity: "EntityStub")] + #[JoinTable(name: "stub_stubs")] + #[JoinColumn(name: "owner_id", referencedColumnName: "id")] + #[InverseJoinColumn(name: "owned_id", referencedColumnName: "id")] public $others; } diff --git a/tests/Testing/FactoryTest.php b/tests/Testing/FactoryTest.php index aaeec4d2..3b01cbfd 100644 --- a/tests/Testing/FactoryTest.php +++ b/tests/Testing/FactoryTest.php @@ -19,7 +19,7 @@ public function test_it_passes_along_the_class_configured_states() $builder = $factory->of('SomeClass'); - $this->assertObjectHasAttribute('states', $builder); + $this->assertTrue(property_exists($builder, 'states')); $this->assertArrayHasKey('SomeClass', $builder->getStates()); $this->assertArrayHasKey('withState', $builder->getStates()['SomeClass']); } @@ -37,7 +37,7 @@ public function test_it_passes_along_after_creating_callback() $builder = $factory->of('SomeClass'); - $this->assertObjectHasAttribute('afterCreating', $builder); + $this->assertTrue(property_exists($builder, 'afterCreating')); $this->assertArrayHasKey('SomeClass', $builder->afterCreating); $this->assertArrayHasKey('default', $builder->afterCreating['SomeClass']); } @@ -54,7 +54,7 @@ public function test_it_passes_along_after_making_callback() }); $builder = $factory->of('SomeClass'); - $this->assertObjectHasAttribute('afterMaking', $builder); + $this->assertTrue(property_exists($builder, 'afterMaking')); $this->assertArrayHasKey('SomeClass', $builder->afterMaking); $this->assertArrayHasKey('default', $builder->afterMaking['SomeClass']); } @@ -71,7 +71,7 @@ public function test_it_passes_along_after_creating_state_callback() }); $builder = $factory->of('SomeClass'); - $this->assertObjectHasAttribute('afterCreating', $builder); + $this->assertTrue(property_exists($builder, 'afterCreating')); $this->assertArrayHasKey('SomeClass', $builder->afterCreating); $this->assertArrayHasKey('withState', $builder->afterCreating['SomeClass']); } @@ -89,7 +89,7 @@ public function test_it_passes_along_after_making_state_callback() $builder = $factory->of('SomeClass'); - $this->assertObjectHasAttribute('afterMaking', $builder); + $this->assertTrue(property_exists($builder, 'afterMaking')); $this->assertArrayHasKey('SomeClass', $builder->afterMaking); $this->assertArrayHasKey('withState', $builder->afterMaking['SomeClass']); } diff --git a/tests/Types/JsonTypeTest.php b/tests/Types/JsonTypeTest.php deleted file mode 100644 index 137b1062..00000000 --- a/tests/Types/JsonTypeTest.php +++ /dev/null @@ -1,51 +0,0 @@ -platform = m::mock(AbstractPlatform::class); - - if (!Type::hasType('json')) { - Type::addType('json', Json::class); - } - $this->type = Type::getType('json'); - } - - public function test_it_returns_null_when_database_value_is_null() - { - $this->assertNull($this->type->convertToPHPValue(null, $this->platform)); - } - - public function test_it_returns_null_when_database_value_is_empty() - { - $this->assertNull($this->type->convertToPHPValue('', $this->platform)); - } - - public function test_it_returns_array_when_database_value_is_json() - { - $this->assertEquals(['value'], $this->type->convertToPHPValue(json_encode(['value']), $this->platform)); - } - - protected function tearDown(): void - { - m::close(); - } -} diff --git a/tests/Utilities/ArrayUtilTest.php b/tests/Utilities/ArrayUtilTest.php deleted file mode 100644 index 02959aec..00000000 --- a/tests/Utilities/ArrayUtilTest.php +++ /dev/null @@ -1,34 +0,0 @@ - 'value' - ]; - - $this->assertEquals('value', ArrayUtil::get($values['key'])); - } - - public function test_returns_default_value_when_not_exists() - { - $values = [ - 'key' => 'value' - ]; - - $this->assertNull(ArrayUtil::get($values['key2'])); - } - - public function test_can_pass_custom_default_value() - { - $values = [ - 'key' => 'value' - ]; - - $this->assertEquals('default', ArrayUtil::get($values['key2'], 'default')); - } -}