diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e24705..2f2b875 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,119 +2,21 @@ name: CI on: push: - + branches: + - master + - 3.next-cake5 pull_request: branches: - '*' +permissions: + contents: read + jobs: testsuite: - runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - php-version: ['8.1'] - db-type: [sqlite, mysql, pgsql] - prefer-lowest: [''] - - steps: - - name: Setup MySQL latest - if: matrix.db-type == 'mysql' - run: docker run --rm --name=mysqld -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=cakephp -p 3306:3306 -d mysql --default-authentication-plugin=mysql_native_password --disable-log-bin - - - name: Setup PostgreSQL latest - if: matrix.db-type == 'pgsql' - run: docker run --rm --name=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=cakephp -p 5432:5432 -d postgres - - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, intl, apcu, sqlite, pdo_sqlite, pdo_${{ matrix.db-type }}, ${{ matrix.db-type }} - ini-values: apc.enable_cli = 1 - coverage: pcov - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Get date part for cache key - id: key-date - run: echo "::set-output name=date::$(date +'%Y-%m')" - - - name: Cache composer dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }} - - - name: composer install - run: | - if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then - composer update --prefer-lowest --prefer-stable - else - composer update - fi - - - name: Setup problem matchers for PHPUnit - if: matrix.php-version == '7.4' && matrix.db-type == 'mysql' - run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - - name: Run PHPUnit - run: | - if [[ ${{ matrix.db-type }} == 'sqlite' ]]; then export DB_URL='sqlite:///:memory:'; fi - if [[ ${{ matrix.db-type }} == 'mysql' ]]; then export DB_URL='mysql://root:root@127.0.0.1/cakephp?encoding=utf8'; fi - if [[ ${{ matrix.db-type }} == 'pgsql' ]]; then export DB_URL='postgres://postgres:postgres@127.0.0.1/postgres'; fi - if [[ ${{ matrix.php-version }} == '7.4' ]]; then - export CODECOVERAGE=1 && vendor/bin/phpunit --verbose --coverage-clover=coverage.xml - else - vendor/bin/phpunit - fi - - - name: Submit code coverage - if: matrix.php-version == '7.4' - uses: codecov/codecov-action@v1 + uses: cakephp/.github/.github/workflows/testsuite-with-db.yml@5.x + secrets: inherit cs-stan: - name: Coding Standard & Static Analysis - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - extensions: mbstring, intl, apcu - coverage: none - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Get date part for cache key - id: key-date - run: echo "::set-output name=date::$(date +'%Y-%m')" - - - name: Cache composer dependencies - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }} - - - name: composer install - run: composer stan-setup - - - name: Run PHP CodeSniffer - run: composer cs-check - - # - name: Run psalm - # if: success() || failure() - # run: vendor/bin/psalm.phar --output-format=github - - # - name: Run phpstan - # if: success() || failure() - # run: composer stan + uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x + secrets: inherit diff --git a/.gitignore b/.gitignore index 92d9288..fd0c450 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /auth.json /.ddev /.idea +/.phpunit.result.cache diff --git a/.phive/phars.xml b/.phive/phars.xml new file mode 100644 index 0000000..9aa6dfe --- /dev/null +++ b/.phive/phars.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.semver b/.semver index 1bbf1c0..9f57831 100644 --- a/.semver +++ b/.semver @@ -1,6 +1,6 @@ --- -:major: 2 +:major: 3 :minor: 0 -:patch: 4 +:patch: 0 :special: '' :metadata: '' diff --git a/README.md b/README.md index 8ac371d..d4f0d30 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,14 @@ Enumeration list for [CakePHP 5](http://cakephp.org). Versions and branches --------------------- -| CakePHP | CakeDC Enum Plugin | Tag | Notes | -|:-----------|:--------------------------------------------------------|:----------|:---------| -| ^5.0.0-dev | [3.next](https://github.com/cakedc/enum/tree/3next) | 3.0.0-dev | unstable | -| ^4.0 | [2.next](https://github.com/cakedc/enum/tree/2.next) | 2.0.4 | stable | -| ^3.7 | [master](https://github.com/cakedc/enum/tree/master) | 1.5.0 | stable | -| ^3.7 | [develop](https://github.com/cakedc/enum/tree/develop) | - | unstable | -| ^3.6 | [master](https://github.com/cakedc/enum/tree/1.4.0) | 1.4.0 | stable | -| 3.1 - 3.5 | | 1.3.0 | stable | +| CakePHP | CakeDC Enum Plugin | Tag | Notes | +|:----------|:-------------------------------------------------------|:------|:---------| +| ^5.0.0 | [3.next](https://github.com/cakedc/enum/tree/3next) | 3.0.0 | unstable | +| ^4.0 | [2.next](https://github.com/cakedc/enum/tree/2.next) | 2.0.4 | stable | +| ^3.7 | [master](https://github.com/cakedc/enum/tree/master) | 1.5.0 | stable | +| ^3.7 | [develop](https://github.com/cakedc/enum/tree/develop) | - | unstable | +| ^3.6 | [master](https://github.com/cakedc/enum/tree/1.4.0) | 1.4.0 | stable | +| 3.1 - 3.5 | | 1.3.0 | stable | Install @@ -27,7 +27,7 @@ Install Using [Composer](http://getcomposer.org): ``` -composer require cakedc/enum:3.0.0-dev +composer require cakedc/enum ``` You then need to load the plugin. You can use the shell command: diff --git a/VERSION b/VERSION index 2468aa9..4a36342 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0-dev +3.0.0 diff --git a/composer.json b/composer.json index 98e3ff9..36a9059 100644 --- a/composer.json +++ b/composer.json @@ -15,14 +15,16 @@ }, "require": { "php": ">=8.1", - "cakephp/cakephp": "5.x-dev" + "cakephp/cakephp": "^5.0.0" }, "require-dev": { - "phpunit/phpunit": "^10.0", + "phpunit/phpunit": "^10.1.0", "cakephp/cakephp-codesniffer": "^5.0", - "cakephp/bake": "3.x-dev", - "cakephp/migrations": "4.x-dev", - "aura/intl": "^3.0" + "cakephp/bake": "^3.0.0", + "cakephp/migrations": "^4.0.0", + "aura/intl": "^3.0", + "vimeo/psalm": "^5.15", + "phpstan/phpstan": "^1.10" }, "autoload": { "psr-4": { @@ -34,8 +36,6 @@ "CakeDC\\Enum\\Test\\": "tests" } }, - "prefer-stable": true, - "minimum-stability": "dev", "scripts": { "analyse": [ "@stan", diff --git a/config/Migrations/001_create_enum_lookups.php b/config/Migrations/001_create_enum_lookups.php index 49b4713..7ef9086 100644 --- a/config/Migrations/001_create_enum_lookups.php +++ b/config/Migrations/001_create_enum_lookups.php @@ -1,4 +1,16 @@ + + + + + diff --git a/phpstan.neon b/phpstan.neon index 6aa4eed..36e2ad0 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,6 @@ parameters: - level: 4 - autoload_files: - - tests/bootstrap.php + level: 6 + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + paths: + - src diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 6fd21aa..cc5decb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,19 +1,22 @@ - - - - - - - - - - ./tests/TestCase - - - - - - - + + + + + + + + + + tests/TestCase/ + + + + + + + + src/ + + diff --git a/psalm.xml b/psalm.xml index f737bed..1f2cff2 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,126 +1,17 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/EnumPlugin.php b/src/EnumPlugin.php index a999581..fc5ca60 100644 --- a/src/EnumPlugin.php +++ b/src/EnumPlugin.php @@ -20,7 +20,7 @@ class EnumPlugin extends BasePlugin /** * Plugin name. * - * @var string + * @var string|null */ protected ?string $name = 'Enum'; } diff --git a/src/Model/Behavior/EnumBehavior.php b/src/Model/Behavior/EnumBehavior.php index 8ad0587..b09e472 100644 --- a/src/Model/Behavior/EnumBehavior.php +++ b/src/Model/Behavior/EnumBehavior.php @@ -27,6 +27,7 @@ use CakeDC\Enum\Model\Behavior\Strategy\ConstStrategy; use CakeDC\Enum\Model\Behavior\Strategy\LookupStrategy; use CakeDC\Enum\Model\Behavior\Strategy\StrategyInterface; +use function Cake\I18n\__d; class EnumBehavior extends Behavior { @@ -63,7 +64,7 @@ class EnumBehavior extends Behavior * ]; * ``` * - * @var array + * @var array */ protected array $_defaultConfig = [ 'defaultStrategy' => 'lookup', @@ -135,7 +136,10 @@ public function strategy(string $alias, mixed $strategy): StrategyInterface throw new MissingEnumStrategyException([$class]); } - return $this->strategies[$alias] = new $class($alias, $this->_table); + /** @var \CakeDC\Enum\Model\Behavior\Strategy\StrategyInterface $strategy */ + $strategy = new $class($alias, $this->_table); + + return $this->strategies[$alias] = $strategy; } /** @@ -219,7 +223,7 @@ protected function enumList(string $alias, array $config): array if ($this->getConfig('nested')) { array_walk( $return, - function (&$item, $val): void { + function (mixed &$item, mixed $val): void { $item = ['value' => $val, 'text' => $item]; } ); @@ -240,13 +244,11 @@ protected function translate(array $list): array { $domain = $this->getConfig('translationDomain'); - return array_map(function ($value) use ($domain) { - return __d($domain, $value); - }, $list); + return array_map(fn ($value) => __d($domain, $value), $list); } /** - * @param \Cake\Event\Event $event Event. + * @param \Cake\Event\EventInterface $event Event. * @param \Cake\ORM\RulesChecker $rules Rules checker. * @return \Cake\ORM\RulesChecker */ @@ -299,7 +301,7 @@ public function __call(string $method, array $args): bool /** * @param \Cake\Event\EventInterface $event The beforeFind event that was fired. - * @param \Cake\ORM\SelectQuery $query Query + * @param \Cake\ORM\Query\SelectQuery $query Query * @param \ArrayObject $options The options for the query * @return void */ diff --git a/src/Model/Behavior/Strategy/AbstractStrategy.php b/src/Model/Behavior/Strategy/AbstractStrategy.php index 3dae0f6..d5e6f3f 100644 --- a/src/Model/Behavior/Strategy/AbstractStrategy.php +++ b/src/Model/Behavior/Strategy/AbstractStrategy.php @@ -16,6 +16,7 @@ use Cake\Core\InstanceConfigTrait; use Cake\ORM\Table; use Cake\Utility\Inflector; +use function Cake\I18n\__d; abstract class AbstractStrategy implements StrategyInterface { diff --git a/src/Model/Behavior/Strategy/ConstStrategy.php b/src/Model/Behavior/Strategy/ConstStrategy.php index c00376a..785dfe7 100644 --- a/src/Model/Behavior/Strategy/ConstStrategy.php +++ b/src/Model/Behavior/Strategy/ConstStrategy.php @@ -15,6 +15,7 @@ use ArrayObject; use Cake\Collection\CollectionInterface; +use Cake\Datasource\EntityInterface; use Cake\Event\EventInterface; use Cake\ORM\Entity; use Cake\ORM\Query\SelectQuery; @@ -29,7 +30,7 @@ class ConstStrategy extends AbstractStrategy /** * Constants list * - * @var array + * @var array|null */ protected ?array $constants = null; @@ -64,9 +65,7 @@ public function enum(array $config = []): array } } - $values = array_map(function ($v) use ($constants) { - return $constants[$v]; - }, $keys); + $values = array_map(fn ($v): mixed => $constants[$v], $keys); return array_combine($keys, $values); } @@ -91,7 +90,7 @@ protected function getConstants(): array $constants = []; foreach ($classConstants as $key => $value) { - if (str_starts_with($key, (string)$prefix)) { + if (str_starts_with($key, $prefix)) { $listKey = substr($key, $length); if ($lowercase) { $listKey = strtolower($listKey); @@ -105,7 +104,7 @@ protected function getConstants(): array /** * @param \Cake\Event\EventInterface $event The beforeFind event that was fired. - * @param \Cake\ORM\Query $query Query + * @param \Cake\ORM\Query\SelectQuery $query Query * @param \ArrayObject $options The options for the query * @return void */ @@ -124,12 +123,8 @@ public function beforeFind(EventInterface $event, SelectQuery $query, ArrayObjec $query->clearContain()->contain($contain); - $query->formatResults(function (CollectionInterface $results) { - return $results->map(function ($row) { - if (is_string($row) || !$row) { - return $row; - } - + $query->formatResults(fn (CollectionInterface $results) => $results + ->map(function (EntityInterface $row): EntityInterface { $constant = Hash::get($row, $this->getConfig('field')); $field = Inflector::singularize(Inflector::underscore($this->alias)); @@ -139,17 +134,10 @@ public function beforeFind(EventInterface $event, SelectQuery $query, ArrayObjec 'value' => $constant, ], ['markClean' => true, 'markNew' => false]); - if (is_array($row)) { - $row[$field] = $value->toArray(); - - return $row; - } - $row->set($field, $value); $row->setDirty($field, false); return $row; - }); - }); + })); } } diff --git a/src/Model/Behavior/Strategy/LookupStrategy.php b/src/Model/Behavior/Strategy/LookupStrategy.php index fe43093..8bca6fa 100644 --- a/src/Model/Behavior/Strategy/LookupStrategy.php +++ b/src/Model/Behavior/Strategy/LookupStrategy.php @@ -14,25 +14,13 @@ namespace CakeDC\Enum\Model\Behavior\Strategy; use Cake\ORM\Locator\LocatorAwareTrait; -use Cake\ORM\Table; use Cake\Utility\Inflector; class LookupStrategy extends AbstractStrategy { use LocatorAwareTrait; - /** - * {@inheritDoc} - * - * @param string $alias Strategy's alias. - * @param \Cake\ORM\Table $table Table object. - */ - public function __construct(string $alias, Table $table) - { - parent::__construct($alias, $table); - $this->modelClass = 'CakeDC/Enum.Lookups'; - // $this->modelFactory('Table', [$this->getTableLocator(), 'get']); - } + protected string $modelClass = 'CakeDC/Enum.Lookups'; /** * {@inheritDoc} diff --git a/tests/Fixture/ArticlesFixture.php b/tests/Fixture/ArticlesFixture.php index 6140f70..075eb8c 100644 --- a/tests/Fixture/ArticlesFixture.php +++ b/tests/Fixture/ArticlesFixture.php @@ -19,16 +19,6 @@ class ArticlesFixture extends TestFixture { public string $table = 'enum_articles'; - public array $fields = [ - 'id' => ['type' => 'integer'], - 'title' => ['type' => 'string'], - 'body' => ['type' => 'text'], - 'priority' => ['type' => 'string'], - 'status' => ['type' => 'string'], - 'article_category' => ['type' => 'integer'], - '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]], - ]; - public array $records = [ [ 'title' => 'Dummy article', diff --git a/tests/Fixture/LookupsFixture.php b/tests/Fixture/LookupsFixture.php index 75cdabb..41b5611 100644 --- a/tests/Fixture/LookupsFixture.php +++ b/tests/Fixture/LookupsFixture.php @@ -19,14 +19,6 @@ class LookupsFixture extends TestFixture { public string $table = 'enum_lookups'; - public array $fields = [ - 'id' => ['type' => 'integer'], - 'label' => ['type' => 'string'], - 'prefix' => ['type' => 'string'], - 'name' => ['type' => 'string'], - '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]], - ]; - public array $records = [ [ 'label' => 'Urgent', diff --git a/tests/TestCase/Model/Behavior/EnumBehaviorTest.php b/tests/TestCase/Model/Behavior/EnumBehaviorTest.php index e9e3743..3f4bb0d 100644 --- a/tests/TestCase/Model/Behavior/EnumBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/EnumBehaviorTest.php @@ -17,7 +17,6 @@ use Cake\ORM\Association\BelongsTo; use Cake\ORM\Entity; use Cake\ORM\Table; -use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; use CakeDC\Enum\Model\Behavior\Strategy\AbstractStrategy; @@ -88,7 +87,7 @@ public function setUp(): void 'Open Source Software', ]); - $this->Articles = TableRegistry::getTableLocator()->get('CakeDC/Enum.Articles', [ + $this->Articles = $this->getTableLocator()->get('CakeDC/Enum.Articles', [ 'className' => ArticlesTable::class, 'table' => 'enum_articles', ]); @@ -97,7 +96,7 @@ public function setUp(): void public function tearDown(): void { parent::tearDown(); - TableRegistry::getTableLocator()->clear(); + $this->getTableLocator()->clear(); } public static function provideBasicConfiguration(): array @@ -189,8 +188,8 @@ public static function provideBasicConfiguration(): array */ public function testBasicConfiguration(array $config, array $expected) { - TableRegistry::getTableLocator()->clear(); - $Articles = TableRegistry::getTableLocator()->get('CakeDC/Enum.Articles', ['table' => 'enum_articles']); + $this->getTableLocator()->clear(); + $Articles = $this->getTableLocator()->get('CakeDC/Enum.Articles', ['table' => 'enum_articles']); $Articles->addBehavior('CakeDC/Enum.Enum', $config); $result = $Articles->behaviors()->Enum->getConfig(); $this->assertEquals($expected, $result); @@ -424,8 +423,8 @@ public static function provideThirdPartyStrategy(): array */ public function testThirdPartyStrategy(array $config, array $expected) { - TableRegistry::getTableLocator()->clear(); - $Articles = TableRegistry::getTableLocator()->get('CakeDC/Enum.Articles', ['table' => 'enum_articles']); + $this->getTableLocator()->clear(); + $Articles = $this->getTableLocator()->get('CakeDC/Enum.Articles', ['table' => 'enum_articles']); $Articles->addBehavior('CakeDC/Enum.Enum', $config); $result = $Articles->enum('article_category'); $this->assertEquals($expected, $result);