From 2160b3e27fc846620e703aec8d7b879e15a47d5d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 1 Dec 2025 20:31:17 +0000 Subject: [PATCH 1/8] Update plugin to CakePHP 4 compatibility - Update composer.json dependencies to CakePHP ^4.0 - Update PHP requirement to >=7.4 (required for CakePHP 4) - Update PHPUnit to ^8.5|^9.3 for compatibility - Update phpstan and php-cs-fixer versions - Add void return types to initialize() methods (CakePHP 4 requirement) - Add void return types to setUp() and tearDown() test methods (PHPUnit 8+ requirement) - Update TableRegistry::get() to TableRegistry::getTableLocator()->get() (CakePHP 4 pattern) - Update README to reflect CakePHP 4.x compatibility --- README.md | 2 +- composer.json | 12 ++++++------ src/Model/Behavior/FetchableBehavior.php | 2 +- .../Model/Behavior/FetchableBehaviorTest.php | 6 +++--- .../TestApp/Model/Table/StatusPropertiesTable.php | 2 +- tests/test_app/TestApp/Model/Table/StatusesTable.php | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9e90969..09bd57c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Total Downloads](https://img.shields.io/packagist/dt/riesenia/cakephp-fetchable.svg?style=flat-square)](https://packagist.org/packages/riesenia/cakephp-fetchable) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) -This plugin is for CakePHP 3.x and contains behavior that handles fetching entities +This plugin is for CakePHP 4.x and contains behavior that handles fetching entities from cache / memory storage. Relevant for tables that contain moderate number of rows and are used commonly in many parts of application. diff --git a/composer.json b/composer.json index 448d757..c545597 100644 --- a/composer.json +++ b/composer.json @@ -11,14 +11,14 @@ } ], "require": { - "php": ">=7.1", - "cakephp/orm": "^3.5" + "php": ">=7.4", + "cakephp/orm": "^4.0" }, "require-dev": { - "cakephp/cakephp": "^3.5", - "friendsofphp/php-cs-fixer": "~2.0", - "phpstan/phpstan": "~0.11", - "phpunit/phpunit": "^5.7.14|^6.0", + "cakephp/cakephp": "^4.0", + "friendsofphp/php-cs-fixer": "~3.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^8.5|^9.3", "rshop/php-cs-fixer-config": "~2.0" }, "autoload": { diff --git a/src/Model/Behavior/FetchableBehavior.php b/src/Model/Behavior/FetchableBehavior.php index 754424b..2e37cf9 100644 --- a/src/Model/Behavior/FetchableBehavior.php +++ b/src/Model/Behavior/FetchableBehavior.php @@ -31,7 +31,7 @@ class FetchableBehavior extends Behavior /** * {@inheritdoc} */ - public function initialize(array $config) + public function initialize(array $config): void { // key is set automatically if (!isset($config['key'])) { diff --git a/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php b/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php index dada140..ffaaeb8 100644 --- a/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php @@ -89,11 +89,11 @@ public function testI18nFetch() /** * setUp method. */ - public function setUp() + public function setUp(): void { parent::setUp(); - $this->Statuses = TableRegistry::get('Statuses', [ + $this->Statuses = TableRegistry::getTableLocator()->get('Statuses', [ 'className' => 'TestApp\Model\Table\StatusesTable' ]); } @@ -101,7 +101,7 @@ public function setUp() /** * tearDown method. */ - public function tearDown() + public function tearDown(): void { unset($this->Statuses); diff --git a/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php b/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php index 0e0f41c..0966c9b 100644 --- a/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php +++ b/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php @@ -14,7 +14,7 @@ class StatusPropertiesTable extends Table { - public function initialize(array $config) + public function initialize(array $config): void { parent::initialize($config); diff --git a/tests/test_app/TestApp/Model/Table/StatusesTable.php b/tests/test_app/TestApp/Model/Table/StatusesTable.php index 30329c4..bc5126c 100644 --- a/tests/test_app/TestApp/Model/Table/StatusesTable.php +++ b/tests/test_app/TestApp/Model/Table/StatusesTable.php @@ -15,7 +15,7 @@ class StatusesTable extends Table { - public function initialize(array $config) + public function initialize(array $config): void { parent::initialize($config); From e989cd6c1a30d3960284ef0ee4d86a0140e05d3e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 1 Dec 2025 20:36:09 +0000 Subject: [PATCH 2/8] Add GitHub Actions CI workflow and update test configuration - Add GitHub Actions workflow for automated testing - Test on PHP 7.4, 8.0, 8.1, 8.2, 8.3 - Test with lowest and highest dependencies - Run PHPStan static analysis - Run PHP CS Fixer code style checks - Update phpunit.xml for PHPUnit 8/9 compatibility - Replace deprecated listeners with extensions - Replace whitelist with coverage/include - Remove deprecated syntaxCheck attribute - Fix test suite name - Add phpstan.neon configuration for static analysis - Add .php-cs-fixer.dist.php for PHP-CS-Fixer 3.0 compatibility --- .github/workflows/ci.yml | 93 ++++++++++++++++++++++++++++++++++++++++ .php-cs-fixer.dist.php | 47 ++++++++++++++++++++ phpstan.neon | 8 ++++ phpunit.xml | 25 ++++------- 4 files changed, 157 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .php-cs-fixer.dist.php create mode 100644 phpstan.neon diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..abac825 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-version: ['7.4', '8.0', '8.1', '8.2', '8.3'] + dependencies: ['highest'] + include: + - php-version: '7.4' + dependencies: 'lowest' + + name: PHP ${{ matrix.php-version }} - ${{ matrix.dependencies }} + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, intl, pdo_sqlite + coverage: none + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies (highest) + if: matrix.dependencies == 'highest' + run: composer update --prefer-dist --no-interaction --no-progress + + - name: Install dependencies (lowest) + if: matrix.dependencies == 'lowest' + run: composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction --no-progress + + - name: Run test suite + run: vendor/bin/phpunit + + code-quality: + runs-on: ubuntu-latest + name: Code Quality + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: mbstring, intl + coverage: none + tools: cs2pr + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer update --prefer-dist --no-interaction --no-progress + + - name: Run PHPStan + run: vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr + continue-on-error: true + + - name: Run PHP CS Fixer + run: vendor/bin/php-cs-fixer fix --dry-run --diff --verbose + continue-on-error: true diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..016078f --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,47 @@ +in(__DIR__) + ->exclude('vendor') + ->notPath('tests/tmp'); + +$config = new PhpCsFixer\Config(); +$config + ->setRiskyAllowed(true) + ->setRules([ + '@PSR12' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => true, + 'blank_line_after_opening_tag' => true, + 'cast_spaces' => ['space' => 'none'], + 'concat_space' => ['spacing' => 'one'], + 'declare_strict_types' => true, + 'header_comment' => [ + 'header' => $header, + 'comment_type' => 'PHPDoc', + 'location' => 'after_open', + 'separate' => 'both', + ], + 'native_function_invocation' => [ + 'include' => ['@all'], + 'scope' => 'namespaced', + ], + 'no_unused_imports' => true, + 'ordered_imports' => true, + 'phpdoc_align' => ['align' => 'left'], + 'phpdoc_no_empty_return' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'whitespace_after_comma_in_array' => true, + ]) + ->setFinder($finder); + +return $config; diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..9196e82 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,8 @@ +parameters: + level: 6 + paths: + - src + bootstrapFiles: + - tests/bootstrap.php + ignoreErrors: + - '#Access to an undefined property Cake\\ORM\\Table::\$[a-zA-Z0-9_]+\.#' diff --git a/phpunit.xml b/phpunit.xml index 49364f7..76907f7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -3,7 +3,6 @@ colors="true" processIsolation="false" stopOnFailure="false" - syntaxCheck="false" bootstrap="./tests/bootstrap.php" > @@ -13,26 +12,20 @@ - + ./tests/TestCase - - - - - - - + + + - - + + ./src/ - - + + - \ No newline at end of file + From ada4e89a7ac72d62f6d0c904347ad4fcf58f906c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 1 Dec 2025 20:44:47 +0000 Subject: [PATCH 3/8] Fix test database configuration for CakePHP 4 - Set default database value to ':memory:' for SQLite when env var not set - Use proper null coalescing for database connection parameters - Add quoteIdentifiers and cacheMetadata to connection config - Update .gitignore to exclude PHPUnit and PHP-CS-Fixer cache files This fixes the "database key needs to be a non-empty string" error when running tests in CakePHP 4. --- .gitignore | 2 ++ tests/bootstrap.php | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c6cf386..f30e48b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,7 @@ composer.phar composer.lock .php_cs.cache +.php-cs-fixer.cache +.phpunit.result.cache .DS_Store Thumbs.db \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 46c2e93..446d12e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -85,12 +85,13 @@ ConnectionManager::setConfig('test', [ 'className' => 'Cake\Database\Connection', - 'driver' => \getenv('db_class'), - 'dsn' => \getenv('db_dsn'), - 'database' => \getenv('db_database'), - 'username' => \getenv('db_login'), - 'password' => \getenv('db_password'), - 'timezone' => 'UTC' + 'driver' => \getenv('db_class') ?: 'Cake\Database\Driver\Sqlite', + 'database' => \getenv('db_database') ?: ':memory:', + 'username' => \getenv('db_login') ?: null, + 'password' => \getenv('db_password') ?: null, + 'timezone' => 'UTC', + 'quoteIdentifiers' => false, + 'cacheMetadata' => true, ]); Log::setConfig([ 'debug' => [ From 1fcd1b1eb317f2f566e0c5e88b2894d3e12ab75b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 1 Dec 2025 20:51:15 +0000 Subject: [PATCH 4/8] Update fixtures to CakePHP 4 format - Replace deprecated $fields and $records properties - Implement init() method for record initialization - Implement _buildSchema() method using TableSchema API - Use addColumn(), addConstraint(), and addIndex() methods - This fixes the "Cannot describe table. It has 0 columns" error The new format is compatible with CakePHP 4.x test fixtures and provides better type safety and clarity. --- tests/Fixture/I18nFixture.php | 114 +++++++++++++--------- tests/Fixture/StatusPropertiesFixture.php | 57 +++++++---- tests/Fixture/StatusesFixture.php | 48 +++++---- 3 files changed, 134 insertions(+), 85 deletions(-) diff --git a/tests/Fixture/I18nFixture.php b/tests/Fixture/I18nFixture.php index 9a589ff..0a3d2cd 100644 --- a/tests/Fixture/I18nFixture.php +++ b/tests/Fixture/I18nFixture.php @@ -23,53 +23,71 @@ class I18nFixture extends TestFixture * @var string */ public $table = 'i18n'; - /** - * Fields. - * - * @var array - */ - // @codingStandardsIgnoreStart - public $fields = [ - 'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null], - 'locale' => ['type' => 'string', 'length' => 6, 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null], - 'model' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null], - 'foreign_key' => ['type' => 'integer', 'length' => 10, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null], - 'field' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null], - 'content' => ['type' => 'text', 'length' => null, 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'comment' => '', 'precision' => null], - '_indexes' => [ - 'model' => ['type' => 'index', 'columns' => ['model', 'foreign_key', 'field'], 'length' => []], - ], - '_constraints' => [ - 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []], - 'locale' => ['type' => 'unique', 'columns' => ['locale', 'model', 'foreign_key', 'field'], 'length' => []], - ], - '_options' => [ - 'engine' => 'InnoDB', - 'collation' => 'utf8_general_ci' - ], - ]; - /** - * Records. - * - * @var array - */ - public $records = [ - [ - 'id' => 1, - 'locale' => 'sk_SK', - 'model' => 'Statuses', - 'foreign_key' => 1, - 'field' => 'name', - 'content' => 'First status - sk' - ], - [ - 'id' => 2, - 'locale' => 'sk_SK', - 'model' => 'StatusProperties', - 'foreign_key' => 1, - 'field' => 'name', - 'content' => 'Property 1 - sk' - ], - ]; + public function init(): void + { + $this->records = [ + [ + 'id' => 1, + 'locale' => 'sk_SK', + 'model' => 'Statuses', + 'foreign_key' => 1, + 'field' => 'name', + 'content' => 'First status - sk' + ], + [ + 'id' => 2, + 'locale' => 'sk_SK', + 'model' => 'StatusProperties', + 'foreign_key' => 1, + 'field' => 'name', + 'content' => 'Property 1 - sk' + ], + ]; + parent::init(); + } + + protected function _buildSchema($schema) + { + return $schema->addColumn('id', [ + 'type' => 'integer', + 'null' => false, + 'autoIncrement' => true, + ]) + ->addColumn('locale', [ + 'type' => 'string', + 'length' => 6, + 'null' => false, + ]) + ->addColumn('model', [ + 'type' => 'string', + 'length' => 255, + 'null' => false, + ]) + ->addColumn('foreign_key', [ + 'type' => 'integer', + 'null' => false, + ]) + ->addColumn('field', [ + 'type' => 'string', + 'length' => 255, + 'null' => false, + ]) + ->addColumn('content', [ + 'type' => 'text', + 'null' => true, + ]) + ->addConstraint('primary', [ + 'type' => 'primary', + 'columns' => ['id'] + ]) + ->addConstraint('locale', [ + 'type' => 'unique', + 'columns' => ['locale', 'model', 'foreign_key', 'field'] + ]) + ->addIndex('model', [ + 'type' => 'index', + 'columns' => ['model', 'foreign_key', 'field'] + ]); + } } diff --git a/tests/Fixture/StatusPropertiesFixture.php b/tests/Fixture/StatusPropertiesFixture.php index 7381f8e..c0bb657 100644 --- a/tests/Fixture/StatusPropertiesFixture.php +++ b/tests/Fixture/StatusPropertiesFixture.php @@ -14,24 +14,41 @@ class StatusPropertiesFixture extends TestFixture { - public $fields = [ - 'id' => ['type' => 'integer'], - 'status_id' => ['type' => 'integer', 'default' => null, 'null' => true], - 'name' => ['type' => 'string', 'default' => null, 'null' => true], - '_constraints' => [ - 'primary' => ['type' => 'primary', 'columns' => ['id']] - ] - ]; - public $records = [ - [ - 'id' => 1, - 'status_id' => 1, - 'name' => 'First property' - ], - [ - 'id' => 2, - 'status_id' => 1, - 'name' => 'Second property' - ] - ]; + public function init(): void + { + $this->records = [ + [ + 'id' => 1, + 'status_id' => 1, + 'name' => 'First property' + ], + [ + 'id' => 2, + 'status_id' => 1, + 'name' => 'Second property' + ] + ]; + parent::init(); + } + + protected function _buildSchema($schema) + { + return $schema->addColumn('id', [ + 'type' => 'integer', + 'null' => false, + ]) + ->addColumn('status_id', [ + 'type' => 'integer', + 'null' => true, + ]) + ->addColumn('name', [ + 'type' => 'string', + 'length' => 255, + 'null' => true, + ]) + ->addConstraint('primary', [ + 'type' => 'primary', + 'columns' => ['id'] + ]); + } } diff --git a/tests/Fixture/StatusesFixture.php b/tests/Fixture/StatusesFixture.php index eef5408..219214f 100644 --- a/tests/Fixture/StatusesFixture.php +++ b/tests/Fixture/StatusesFixture.php @@ -14,21 +14,35 @@ class StatusesFixture extends TestFixture { - public $fields = [ - 'id' => ['type' => 'integer'], - 'name' => ['type' => 'string', 'default' => null, 'null' => true], - '_constraints' => [ - 'primary' => ['type' => 'primary', 'columns' => ['id']] - ] - ]; - public $records = [ - [ - 'id' => 1, - 'name' => 'First status' - ], - [ - 'id' => 2, - 'name' => 'Second status' - ] - ]; + public function init(): void + { + $this->records = [ + [ + 'id' => 1, + 'name' => 'First status' + ], + [ + 'id' => 2, + 'name' => 'Second status' + ] + ]; + parent::init(); + } + + protected function _buildSchema($schema) + { + return $schema->addColumn('id', [ + 'type' => 'integer', + 'null' => false, + ]) + ->addColumn('name', [ + 'type' => 'string', + 'length' => 255, + 'null' => true, + ]) + ->addConstraint('primary', [ + 'type' => 'primary', + 'columns' => ['id'] + ]); + } } From fb4dc18d23c5d07e7b705c9182017b6d092681a4 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 1 Dec 2025 20:58:23 +0000 Subject: [PATCH 5/8] Fix fixture schema method for CakePHP 4 - Use getTableSchema() method instead of _buildSchema() - Use $records property instead of init() method - Create and return TableSchema object directly - Remove parent::init() call that was causing table lookup errors This fixes "Cannot describe schema for table. The table does not exist" error. --- tests/Fixture/I18nFixture.php | 47 +++++++++++------------ tests/Fixture/StatusPropertiesFixture.php | 35 ++++++++--------- tests/Fixture/StatusesFixture.php | 31 ++++++++------- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/tests/Fixture/I18nFixture.php b/tests/Fixture/I18nFixture.php index 0a3d2cd..a05ee9e 100644 --- a/tests/Fixture/I18nFixture.php +++ b/tests/Fixture/I18nFixture.php @@ -24,32 +24,29 @@ class I18nFixture extends TestFixture */ public $table = 'i18n'; - public function init(): void - { - $this->records = [ - [ - 'id' => 1, - 'locale' => 'sk_SK', - 'model' => 'Statuses', - 'foreign_key' => 1, - 'field' => 'name', - 'content' => 'First status - sk' - ], - [ - 'id' => 2, - 'locale' => 'sk_SK', - 'model' => 'StatusProperties', - 'foreign_key' => 1, - 'field' => 'name', - 'content' => 'Property 1 - sk' - ], - ]; - parent::init(); - } + public $records = [ + [ + 'id' => 1, + 'locale' => 'sk_SK', + 'model' => 'Statuses', + 'foreign_key' => 1, + 'field' => 'name', + 'content' => 'First status - sk' + ], + [ + 'id' => 2, + 'locale' => 'sk_SK', + 'model' => 'StatusProperties', + 'foreign_key' => 1, + 'field' => 'name', + 'content' => 'Property 1 - sk' + ], + ]; - protected function _buildSchema($schema) + public function getTableSchema() { - return $schema->addColumn('id', [ + $schema = new \Cake\Database\Schema\TableSchema('i18n'); + $schema->addColumn('id', [ 'type' => 'integer', 'null' => false, 'autoIncrement' => true, @@ -89,5 +86,7 @@ protected function _buildSchema($schema) 'type' => 'index', 'columns' => ['model', 'foreign_key', 'field'] ]); + + return $schema; } } diff --git a/tests/Fixture/StatusPropertiesFixture.php b/tests/Fixture/StatusPropertiesFixture.php index c0bb657..6459e2d 100644 --- a/tests/Fixture/StatusPropertiesFixture.php +++ b/tests/Fixture/StatusPropertiesFixture.php @@ -14,26 +14,23 @@ class StatusPropertiesFixture extends TestFixture { - public function init(): void - { - $this->records = [ - [ - 'id' => 1, - 'status_id' => 1, - 'name' => 'First property' - ], - [ - 'id' => 2, - 'status_id' => 1, - 'name' => 'Second property' - ] - ]; - parent::init(); - } + public $records = [ + [ + 'id' => 1, + 'status_id' => 1, + 'name' => 'First property' + ], + [ + 'id' => 2, + 'status_id' => 1, + 'name' => 'Second property' + ] + ]; - protected function _buildSchema($schema) + public function getTableSchema() { - return $schema->addColumn('id', [ + $schema = new \Cake\Database\Schema\TableSchema('status_properties'); + $schema->addColumn('id', [ 'type' => 'integer', 'null' => false, ]) @@ -50,5 +47,7 @@ protected function _buildSchema($schema) 'type' => 'primary', 'columns' => ['id'] ]); + + return $schema; } } diff --git a/tests/Fixture/StatusesFixture.php b/tests/Fixture/StatusesFixture.php index 219214f..0d1f823 100644 --- a/tests/Fixture/StatusesFixture.php +++ b/tests/Fixture/StatusesFixture.php @@ -14,24 +14,21 @@ class StatusesFixture extends TestFixture { - public function init(): void - { - $this->records = [ - [ - 'id' => 1, - 'name' => 'First status' - ], - [ - 'id' => 2, - 'name' => 'Second status' - ] - ]; - parent::init(); - } + public $records = [ + [ + 'id' => 1, + 'name' => 'First status' + ], + [ + 'id' => 2, + 'name' => 'Second status' + ] + ]; - protected function _buildSchema($schema) + public function getTableSchema() { - return $schema->addColumn('id', [ + $schema = new \Cake\Database\Schema\TableSchema('statuses'); + $schema->addColumn('id', [ 'type' => 'integer', 'null' => false, ]) @@ -44,5 +41,7 @@ protected function _buildSchema($schema) 'type' => 'primary', 'columns' => ['id'] ]); + + return $schema; } } From d68644bb4ecf5c00810ee2a8ebf5a299906db592 Mon Sep 17 00:00:00 2001 From: Tomas Saghy Date: Tue, 2 Dec 2025 15:38:19 +0100 Subject: [PATCH 6/8] upd --- .php-cs-fixer.dist.php | 44 ++-------- composer.json | 4 +- src/Model/Behavior/FetchableBehavior.php | 12 +-- tests/Fixture/I18nFixture.php | 80 ++++--------------- tests/Fixture/StatusPropertiesFixture.php | 44 +++------- tests/Fixture/StatusesFixture.php | 37 +++------ .../Model/Behavior/FetchableBehaviorTest.php | 27 ++++++- tests/bootstrap.php | 7 +- .../Model/Table/StatusPropertiesTable.php | 1 - .../TestApp/Model/Table/StatusesTable.php | 1 - 10 files changed, 74 insertions(+), 183 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 016078f..8d8e761 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,44 +4,12 @@ Licensed under the MIT License (c) RIESENIA.com'; -$finder = PhpCsFixer\Finder::create() - ->in(__DIR__) - ->exclude('vendor') - ->notPath('tests/tmp'); +$config = new Rshop\CS\Config\Rshop($header); -$config = new PhpCsFixer\Config(); -$config - ->setRiskyAllowed(true) - ->setRules([ - '@PSR12' => true, - 'array_syntax' => ['syntax' => 'short'], - 'binary_operator_spaces' => true, - 'blank_line_after_opening_tag' => true, - 'cast_spaces' => ['space' => 'none'], - 'concat_space' => ['spacing' => 'one'], - 'declare_strict_types' => true, - 'header_comment' => [ - 'header' => $header, - 'comment_type' => 'PHPDoc', - 'location' => 'after_open', - 'separate' => 'both', - ], - 'native_function_invocation' => [ - 'include' => ['@all'], - 'scope' => 'namespaced', - ], - 'no_unused_imports' => true, - 'ordered_imports' => true, - 'phpdoc_align' => ['align' => 'left'], - 'phpdoc_no_empty_return' => true, - 'phpdoc_order' => true, - 'phpdoc_scalar' => true, - 'phpdoc_trim' => true, - 'return_type_declaration' => ['space_before' => 'none'], - 'single_quote' => true, - 'trailing_comma_in_multiline' => ['elements' => ['arrays']], - 'whitespace_after_comma_in_array' => true, - ]) - ->setFinder($finder); +$config->setStrict() + ->setRule('general_phpdoc_annotation_remove', ['annotations' => ['author']]) + ->getFinder() + ->in(__DIR__) + ->exclude('vendor'); return $config; diff --git a/composer.json b/composer.json index c545597..0401d2f 100644 --- a/composer.json +++ b/composer.json @@ -16,10 +16,10 @@ }, "require-dev": { "cakephp/cakephp": "^4.0", - "friendsofphp/php-cs-fixer": "~3.0", + "friendsofphp/php-cs-fixer": "^3.0", "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^8.5|^9.3", - "rshop/php-cs-fixer-config": "~2.0" + "rshop/php-cs-fixer-config": "^3.0" }, "autoload": { "psr-4": { diff --git a/src/Model/Behavior/FetchableBehavior.php b/src/Model/Behavior/FetchableBehavior.php index 2e37cf9..f24f389 100644 --- a/src/Model/Behavior/FetchableBehavior.php +++ b/src/Model/Behavior/FetchableBehavior.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace Fetchable\Model\Behavior; @@ -28,9 +27,6 @@ class FetchableBehavior extends Behavior /** @var array */ private $_cache; - /** - * {@inheritdoc} - */ public function initialize(array $config): void { // key is set automatically @@ -43,8 +39,6 @@ public function initialize(array $config): void /** * Fetch data. - * - * @return array */ public function fetch(): array { @@ -58,7 +52,7 @@ public function fetch(): array return $this->_cache[$key]; } - if (($data = Cache::read($key, $this->getConfig('cache'))) === false) { + if (!($data = Cache::read($key, $this->getConfig('cache')))) { $data = []; $find = $this->_table->find($this->getConfig('finder')); @@ -83,8 +77,6 @@ public function fetch(): array * Fetch entity. * * @param int|string $id - * - * @return EntityInterface */ public function fetchEntity($id): EntityInterface { @@ -100,8 +92,6 @@ public function fetchEntity($id): EntityInterface /** * Get primary key value for entity. * - * @param EntityInterface $entity - * * @return int|string */ protected function _getPrimaryValue(EntityInterface $entity) diff --git a/tests/Fixture/I18nFixture.php b/tests/Fixture/I18nFixture.php index a05ee9e..49212e1 100644 --- a/tests/Fixture/I18nFixture.php +++ b/tests/Fixture/I18nFixture.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace Fetchable\Test\Fixture; @@ -24,69 +23,24 @@ class I18nFixture extends TestFixture */ public $table = 'i18n'; - public $records = [ - [ - 'id' => 1, - 'locale' => 'sk_SK', - 'model' => 'Statuses', - 'foreign_key' => 1, - 'field' => 'name', - 'content' => 'First status - sk' - ], - [ - 'id' => 2, - 'locale' => 'sk_SK', - 'model' => 'StatusProperties', - 'foreign_key' => 1, - 'field' => 'name', - 'content' => 'Property 1 - sk' + public $fields = [ + 'id' => ['type' => 'integer', 'null' => false, 'autoIncrement' => true], + 'locale' => ['type' => 'string', 'length' => 6, 'null' => false], + 'model' => ['type' => 'string', 'length' => 255, 'null' => false], + 'foreign_key' => ['type' => 'integer', 'null' => false], + 'field' => ['type' => 'string', 'length' => 255, 'null' => false], + 'content' => ['type' => 'text', 'null' => true], + '_indexes' => [ + 'model' => ['type' => 'index', 'columns' => ['model', 'foreign_key', 'field']] ], + '_constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']], + 'locale' => ['type' => 'unique', 'columns' => ['locale', 'model', 'foreign_key', 'field']] + ] ]; - public function getTableSchema() - { - $schema = new \Cake\Database\Schema\TableSchema('i18n'); - $schema->addColumn('id', [ - 'type' => 'integer', - 'null' => false, - 'autoIncrement' => true, - ]) - ->addColumn('locale', [ - 'type' => 'string', - 'length' => 6, - 'null' => false, - ]) - ->addColumn('model', [ - 'type' => 'string', - 'length' => 255, - 'null' => false, - ]) - ->addColumn('foreign_key', [ - 'type' => 'integer', - 'null' => false, - ]) - ->addColumn('field', [ - 'type' => 'string', - 'length' => 255, - 'null' => false, - ]) - ->addColumn('content', [ - 'type' => 'text', - 'null' => true, - ]) - ->addConstraint('primary', [ - 'type' => 'primary', - 'columns' => ['id'] - ]) - ->addConstraint('locale', [ - 'type' => 'unique', - 'columns' => ['locale', 'model', 'foreign_key', 'field'] - ]) - ->addIndex('model', [ - 'type' => 'index', - 'columns' => ['model', 'foreign_key', 'field'] - ]); - - return $schema; - } + public $records = [ + ['id' => 1, 'locale' => 'sk_SK', 'model' => 'Statuses', 'foreign_key' => 1, 'field' => 'name', 'content' => 'First status - sk'], + ['id' => 2, 'locale' => 'sk_SK', 'model' => 'StatusProperties', 'foreign_key' => 1, 'field' => 'name', 'content' => 'Property 1 - sk'] + ]; } diff --git a/tests/Fixture/StatusPropertiesFixture.php b/tests/Fixture/StatusPropertiesFixture.php index 6459e2d..23b801b 100644 --- a/tests/Fixture/StatusPropertiesFixture.php +++ b/tests/Fixture/StatusPropertiesFixture.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace Fetchable\Test\Fixture; @@ -14,40 +13,17 @@ class StatusPropertiesFixture extends TestFixture { - public $records = [ - [ - 'id' => 1, - 'status_id' => 1, - 'name' => 'First property' - ], - [ - 'id' => 2, - 'status_id' => 1, - 'name' => 'Second property' + public $fields = [ + 'id' => ['type' => 'integer'], + 'status_id' => ['type' => 'integer', 'null' => true], + 'name' => ['type' => 'string', 'length' => 255, 'null' => true], + '_constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']] ] ]; - public function getTableSchema() - { - $schema = new \Cake\Database\Schema\TableSchema('status_properties'); - $schema->addColumn('id', [ - 'type' => 'integer', - 'null' => false, - ]) - ->addColumn('status_id', [ - 'type' => 'integer', - 'null' => true, - ]) - ->addColumn('name', [ - 'type' => 'string', - 'length' => 255, - 'null' => true, - ]) - ->addConstraint('primary', [ - 'type' => 'primary', - 'columns' => ['id'] - ]); - - return $schema; - } + public $records = [ + ['id' => 1, 'status_id' => 1, 'name' => 'First property'], + ['id' => 2, 'status_id' => 1, 'name' => 'Second property'] + ]; } diff --git a/tests/Fixture/StatusesFixture.php b/tests/Fixture/StatusesFixture.php index 0d1f823..cf2cf06 100644 --- a/tests/Fixture/StatusesFixture.php +++ b/tests/Fixture/StatusesFixture.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace Fetchable\Test\Fixture; @@ -14,34 +13,16 @@ class StatusesFixture extends TestFixture { - public $records = [ - [ - 'id' => 1, - 'name' => 'First status' - ], - [ - 'id' => 2, - 'name' => 'Second status' + public $fields = [ + 'id' => ['type' => 'integer'], + 'name' => ['type' => 'string', 'length' => 255, 'null' => true], + '_constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']] ] ]; - public function getTableSchema() - { - $schema = new \Cake\Database\Schema\TableSchema('statuses'); - $schema->addColumn('id', [ - 'type' => 'integer', - 'null' => false, - ]) - ->addColumn('name', [ - 'type' => 'string', - 'length' => 255, - 'null' => true, - ]) - ->addConstraint('primary', [ - 'type' => 'primary', - 'columns' => ['id'] - ]); - - return $schema; - } + public $records = [ + ['id' => 1, 'name' => 'First status'], + ['id' => 2, 'name' => 'Second status'] + ]; } diff --git a/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php b/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php index ffaaeb8..25efc27 100644 --- a/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/FetchableBehaviorTest.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace Fetchable\Test\TestCase\Model\Behavior; @@ -31,6 +30,11 @@ class FetchableBehaviorTest extends TestCase 'plugin.Fetchable.I18n' ]; + /** + * @var \TestApp\Model\Table\StatusesTable + */ + protected $Statuses; + /** * Test fetch. */ @@ -86,6 +90,27 @@ public function testI18nFetch() $this->assertEquals('Property 1 - sk', $statuses[1]['status_properties'][0]['name']); } + /** + * setUpBeforeClass method - Create fixture tables. + */ + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + + $connection = \Cake\Datasource\ConnectionManager::get('test'); + + // Create fixture tables + $fixtures = [ + new \Fetchable\Test\Fixture\StatusesFixture(), + new \Fetchable\Test\Fixture\StatusPropertiesFixture(), + new \Fetchable\Test\Fixture\I18nFixture() + ]; + + foreach ($fixtures as $fixture) { + $fixture->create($connection); + } + } + /** * setUp method. */ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 446d12e..5deaa43 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); use Cake\Cache\Cache; @@ -91,17 +90,17 @@ 'password' => \getenv('db_password') ?: null, 'timezone' => 'UTC', 'quoteIdentifiers' => false, - 'cacheMetadata' => true, + 'cacheMetadata' => false ]); Log::setConfig([ 'debug' => [ 'engine' => 'Cake\Log\Engine\FileLog', 'levels' => ['notice', 'info', 'debug'], - 'file' => 'debug', + 'file' => 'debug' ], 'error' => [ 'engine' => 'Cake\Log\Engine\FileLog', 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], - 'file' => 'error', + 'file' => 'error' ] ]); diff --git a/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php b/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php index 0966c9b..44b3195 100644 --- a/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php +++ b/tests/test_app/TestApp/Model/Table/StatusPropertiesTable.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace TestApp\Model\Table; diff --git a/tests/test_app/TestApp/Model/Table/StatusesTable.php b/tests/test_app/TestApp/Model/Table/StatusesTable.php index bc5126c..1caef61 100644 --- a/tests/test_app/TestApp/Model/Table/StatusesTable.php +++ b/tests/test_app/TestApp/Model/Table/StatusesTable.php @@ -5,7 +5,6 @@ * Licensed under the MIT License * (c) RIESENIA.com */ - declare(strict_types=1); namespace TestApp\Model\Table; From 394b455621d157eb9c8178e28505e5b989cf8f54 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 2 Dec 2025 14:44:19 +0000 Subject: [PATCH 7/8] Remove PHP 7.4 from test matrix - Update minimum PHP version to 8.0 in composer.json - Remove PHP 7.4 from GitHub Actions test matrix - Test lowest dependencies on PHP 8.0 instead PHP 7.4 reached end of life in November 2022. --- .github/workflows/ci.yml | 4 ++-- composer.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abac825..591f930 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,10 +12,10 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['7.4', '8.0', '8.1', '8.2', '8.3'] + php-version: ['8.0', '8.1', '8.2', '8.3'] dependencies: ['highest'] include: - - php-version: '7.4' + - php-version: '8.0' dependencies: 'lowest' name: PHP ${{ matrix.php-version }} - ${{ matrix.dependencies }} diff --git a/composer.json b/composer.json index 0401d2f..abf909f 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": ">=7.4", + "php": ">=8.0", "cakephp/orm": "^4.0" }, "require-dev": { From 0a954eb32ad41bd93f0fe3846266a67afa88adfe Mon Sep 17 00:00:00 2001 From: Tomas Saghy Date: Tue, 2 Dec 2025 15:55:53 +0100 Subject: [PATCH 8/8] remove lowest --- .github/workflows/ci.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 591f930..49d2492 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,12 +13,8 @@ jobs: fail-fast: false matrix: php-version: ['8.0', '8.1', '8.2', '8.3'] - dependencies: ['highest'] - include: - - php-version: '8.0' - dependencies: 'lowest' - name: PHP ${{ matrix.php-version }} - ${{ matrix.dependencies }} + name: PHP ${{ matrix.php-version }} steps: - uses: actions/checkout@v3 @@ -44,14 +40,9 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - - name: Install dependencies (highest) - if: matrix.dependencies == 'highest' + - name: Install dependencies run: composer update --prefer-dist --no-interaction --no-progress - - name: Install dependencies (lowest) - if: matrix.dependencies == 'lowest' - run: composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction --no-progress - - name: Run test suite run: vendor/bin/phpunit