From 6f32e3f4506bd3d2bd53759d0f0c48ba42c63b5c Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 27 Jun 2022 19:52:44 +0530 Subject: [PATCH 01/38] Update for Cake 5 --- .github/workflows/ci.yml | 34 ++++++++-------- composer.json | 15 +++---- phpstan-baseline.neon | 15 +++++-- phpunit.xml.dist | 33 ++++++---------- psalm-baseline.xml | 16 ++++++++ psalm.xml | 1 + src/Action/DashboardAction.php | 6 +-- src/Breadcrumb/ActiveBreadcrumb.php | 2 +- src/Breadcrumb/Breadcrumb.php | 24 ++++++------ src/CrudViewPlugin.php | 39 +++++++++++++++++++ src/Dashboard/Dashboard.php | 2 +- src/Dashboard/Module/ActionLinkItem.php | 10 ++--- src/Dashboard/Module/LinkItem.php | 30 +++++++------- src/Listener/Traits/FormTypeTrait.php | 4 +- .../Traits/SidebarNavigationTrait.php | 4 +- src/Listener/ViewListener.php | 16 ++++---- src/Listener/ViewSearchListener.php | 2 +- src/Menu/MenuDropdown.php | 4 +- src/Menu/MenuItem.php | 16 ++++---- src/Plugin.php | 19 --------- src/View/Cell/DashboardTableCell.php | 4 +- src/View/Cell/TablesListCell.php | 7 ++-- src/View/CrudView.php | 4 +- src/View/Helper/CrudViewHelper.php | 30 +++++++------- src/View/Widget/DateTimeWidget.php | 3 +- tests/TestCase/Dashboard/DashboardTest.php | 3 +- .../Dashboard/Module/LinkItemTest.php | 7 ++-- .../View/Helper/CrudViewHelperTest.php | 19 +++------ .../View/Widget/DateTimeWidgetTest.php | 4 +- tests/bootstrap.php | 8 +--- 30 files changed, 207 insertions(+), 174 deletions(-) create mode 100644 psalm-baseline.xml create mode 100644 src/CrudViewPlugin.php delete mode 100644 src/Plugin.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db57c4b8..3a550007 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,18 +4,18 @@ on: [push, pull_request] jobs: testsuite: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: prefer-lowest: [''] - php-version: ['7.4', '8.0', '8.1'] + php-version: ['8.1', '8.2'] include: - - php-version: '7.2' + - php-version: '8.1' prefer-lowest: 'prefer-lowest' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -28,47 +28,49 @@ jobs: run: | if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then composer update --prefer-lowest --prefer-stable + elif ${{ matrix.php-version == '8.2' }}; then + composer update --ignore-platform-req=php else - composer install + composer update fi - name: Run PHPUnit run: | - if [[ ${{ matrix.php-version }} == '7.4' ]]; then + if [[ ${{ matrix.php-version }} == '8.1' ]]; then vendor/bin/phpunit --coverage-clover=coverage.xml else vendor/bin/phpunit fi - name: Code Coverage Report - if: matrix.php-version == '7.4' - uses: codecov/codecov-action@v2 + if: matrix.php-version == '8.1' + uses: codecov/codecov-action@v3 cs-stan: name: Coding Standard & Static Analysis - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.1' extensions: mbstring, intl coverage: none - tools: vimeo/psalm:4.22, phpstan:1.4 + tools: vimeo/psalm:4.23, phpstan:1.7, cs2pr - name: Composer Install - run: composer require --dev cakephp/cakephp-codesniffer:^4.1 + run: composer require --dev cakephp/cakephp-codesniffer:5.x-dev - name: Run phpcs - run: vendor/bin/phpcs --report=checkstyle --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/ + run: vendor/bin/phpcs --report=checkstyle --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/ | cs2pr - name: Run psalm - if: success() || failure() + if: always() run: psalm --output-format=github - name: Run phpstan - if: success() || failure() + if: always() run: phpstan analyse --error-format=github diff --git a/composer.json b/composer.json index aa162fcd..0a9d7926 100644 --- a/composer.json +++ b/composer.json @@ -29,14 +29,13 @@ } ], "require": { - "cakephp/cakephp": "^4.0", - "friendsofcake/crud": "^6.0", - "friendsofcake/bootstrap-ui": "^3.0" + "cakephp/cakephp": "5.x-dev", + "friendsofcake/crud": "dev-cake-5", + "friendsofcake/bootstrap-ui": "dev-cake-5" }, "require-dev": { - "friendsofcake/cakephp-test-utilities": "^2.0", - "markstory/asset_compress": "^4.0", - "phpunit/phpunit": "~8.5.0 || ^9.3" + "friendsofcake/cakephp-test-utilities": "dev-cake-5.x", + "phpunit/phpunit": "^9.5.19" }, "autoload": { "psr-4": { @@ -54,5 +53,7 @@ "wiki": "http://cakephp.nu/cakephp-crud/", "irc": "irc://irc.freenode.org/friendsofcake" }, - "prefer-stable": true + "config": { + "sort-packages": true + } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index c4333366..b028a228 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -40,13 +40,23 @@ parameters: count: 1 path: src/Listener/ViewSearchListener.php + - + message: "#^Call to method css\\(\\) on an unknown class AssetCompress\\\\View\\\\Helper\\\\AssetCompressHelper\\.$#" + count: 1 + path: src/View/CrudView.php + + - + message: "#^Call to method script\\(\\) on an unknown class AssetCompress\\\\View\\\\Helper\\\\AssetCompressHelper\\.$#" + count: 2 + path: src/View/CrudView.php + - message: "#^Binary operation \"\\+\" between string and array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true', data\\-alt\\-input\\-class\\?\\: string, class\\: array\\{'input\\-group', 'flatpickr'\\}\\} results in an error\\.$#" count: 1 path: src/View/Widget/DateTimeWidget.php - - message: "#^Binary operation \"\\+\\=\" between array\\\\|string and array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true'\\} results in an error\\.$#" + message: "#^Binary operation \"\\+\\=\" between array\\\\|string\\|null and array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true'\\} results in an error\\.$#" count: 1 path: src/View/Widget/DateTimeWidget.php @@ -71,7 +81,6 @@ parameters: path: src/View/Widget/DateTimeWidget.php - - message: "#^Parameter \\#1 \\$options of method Cake\\\\View\\\\StringTemplate\\:\\:formatAttributes\\(\\) expects array\\\\|null, array\\\\|string given\\.$#" + message: "#^Parameter \\#1 \\$options of method Cake\\\\View\\\\StringTemplate\\:\\:formatAttributes\\(\\) expects array\\\\|null, array\\\\|string\\|null given\\.$#" count: 1 path: src/View/Widget/DateTimeWidget.php - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 279d1795..10712c99 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,32 +5,23 @@ stopOnFailure="false" bootstrap="./tests/bootstrap.php" > - - - - - ./tests/TestCase - - - - - - - - - + + + - - - ./src/ - - + + + src/ + + + + + + diff --git a/psalm-baseline.xml b/psalm-baseline.xml new file mode 100644 index 00000000..2ee45abd --- /dev/null +++ b/psalm-baseline.xml @@ -0,0 +1,16 @@ + + + + + $this->AssetCompress + $this->AssetCompress + $this->AssetCompress + + + + + $data['name'] + $data['templateVars'] + + + diff --git a/psalm.xml b/psalm.xml index fa13ae4a..c423ba40 100644 --- a/psalm.xml +++ b/psalm.xml @@ -5,6 +5,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + errorBaseline="psalm-baseline.xml" > diff --git a/src/Action/DashboardAction.php b/src/Action/DashboardAction.php index fd8b12b1..b8e89fdc 100644 --- a/src/Action/DashboardAction.php +++ b/src/Action/DashboardAction.php @@ -11,7 +11,7 @@ class DashboardAction extends BaseAction { use ViewTrait; - protected $_defaultConfig = [ + protected array $_defaultConfig = [ 'enabled' => true, 'view' => null, ]; @@ -19,9 +19,9 @@ class DashboardAction extends BaseAction /** * HTTP GET handler * - * @return void|\Cake\Http\Response + * @return void */ - protected function _get() + protected function _get(): void { $pageTitle = $this->getConfig('scaffold.page_title', __d('CrudView', 'Dashboard')); $this->setConfig('scaffold.page_title', $pageTitle); diff --git a/src/Breadcrumb/ActiveBreadcrumb.php b/src/Breadcrumb/ActiveBreadcrumb.php index fc15cd47..069c925f 100644 --- a/src/Breadcrumb/ActiveBreadcrumb.php +++ b/src/Breadcrumb/ActiveBreadcrumb.php @@ -11,7 +11,7 @@ class ActiveBreadcrumb extends Breadcrumb * @inheritDoc * @psalm-suppress MissingParamType */ - public function __construct($title, $url = null, array $options = []) + public function __construct(string|array $title, string|array|null $url = null, array $options = []) { if (!isset($options['class'])) { $options['class'] = ''; diff --git a/src/Breadcrumb/Breadcrumb.php b/src/Breadcrumb/Breadcrumb.php index 200bc21a..23269192 100644 --- a/src/Breadcrumb/Breadcrumb.php +++ b/src/Breadcrumb/Breadcrumb.php @@ -10,35 +10,35 @@ class Breadcrumb * If the specified $url is a link, then this will * also be wrapped by `` tags. * - * @var string|array + * @var array|string **/ - protected $title; + protected string|array $title; /** * Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * - * @var string|array|null + * @var array|string|null */ - protected $url = null; + protected string|array|null $url = null; /** * Array of options and HTML attributes. * * @var array **/ - protected $options = []; + protected array $options = []; /** * Contains a breadcrumb entry * - * @param string|array $title If provided as a string, it represents the title of the crumb. + * @param array|string $title If provided as a string, it represents the title of the crumb. * Alternatively, if you want to add multiple crumbs at once, you can provide an array, with each values being a * single crumb. Arrays are expected to be of this form: * - *title* The title of the crumb * - *link* The link of the crumb. If not provided, no link will be made * - *options* Options of the crumb. See description of params option of this method. - * @param string|array|null $url URL of the crumb. Either a string, an array of route params to pass to + * @param array|string|null $url URL of the crumb. Either a string, an array of route params to pass to * Url::build() or null / empty if the crumb does not have a link. * @param array $options Array of options. These options will be used as attributes HTML attribute the crumb will * be rendered in (a
  • tag by default). It accepts two special keys: @@ -46,7 +46,7 @@ class Breadcrumb * the link) * - *templateVars*: Specific template vars in case you override the templates provided. */ - public function __construct($title, $url = null, array $options = []) + public function __construct(string|array $title, string|array|null $url = null, array $options = []) { $this->title = $title; $this->url = $url; @@ -56,9 +56,9 @@ public function __construct($title, $url = null, array $options = []) /** * Returns the menu item title * - * @return string|array + * @return array|string */ - public function getTitle() + public function getTitle(): string|array { return $this->title; } @@ -66,9 +66,9 @@ public function getTitle() /** * Returns the menu item ur * - * @return string|array|null + * @return array|string|null */ - public function getUrl() + public function getUrl(): string|array|null { return $this->url; } diff --git a/src/CrudViewPlugin.php b/src/CrudViewPlugin.php new file mode 100644 index 00000000..cc0e3cba --- /dev/null +++ b/src/CrudViewPlugin.php @@ -0,0 +1,39 @@ + 12, diff --git a/src/Dashboard/Module/ActionLinkItem.php b/src/Dashboard/Module/ActionLinkItem.php index 2948f585..8bb8b512 100644 --- a/src/Dashboard/Module/ActionLinkItem.php +++ b/src/Dashboard/Module/ActionLinkItem.php @@ -12,19 +12,19 @@ class ActionLinkItem extends LinkItem * * @var array **/ - protected $actions = []; + protected array $actions = []; /** * Constructor * - * @param string|array $title The content to be wrapped by `` tags. + * @param array|string $title The content to be wrapped by `` tags. * Can be an array if $url is null. If $url is null, $title will be used as both the URL and title. - * @param string|array|null $url Cake-relative URL or array of URL parameters, or + * @param array|string|null $url Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * @param array $options Array of options and HTML attributes. * @param array $actions Array of ActionItems */ - public function __construct($title, $url, $options = [], array $actions = []) + public function __construct(string|array $title, string|array|null $url, array $options = [], array $actions = []) { parent::__construct($title, $url, $options); $this->set('actions', $actions); @@ -36,7 +36,7 @@ public function __construct($title, $url, $options = [], array $actions = []) * @param array $actions Array of options and HTML attributes. * @return array */ - protected function _setActions($actions) + protected function _setActions(array $actions): array { return (new Collection($actions))->map(function ($value) { $options = (array)$value->get('options') + ['class' => ['btn btn-secondary']]; diff --git a/src/Dashboard/Module/LinkItem.php b/src/Dashboard/Module/LinkItem.php index eec60d11..767846aa 100644 --- a/src/Dashboard/Module/LinkItem.php +++ b/src/Dashboard/Module/LinkItem.php @@ -15,33 +15,33 @@ class LinkItem * * @var string **/ - protected $title; + protected string $title; /** * Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * - * @var string|array|null + * @var array|string|null */ - protected $url = null; + protected string|array|null $url = null; /** * Array of options and HTML attributes. * * @var array **/ - protected $options = []; + protected array $options = []; /** * Constructor * - * @param string|array $title The content to be wrapped by `` tags. + * @param array|string $title The content to be wrapped by `` tags. * Can be an array if $url is null. If $url is null, $title will be used as both the URL and title. - * @param string|array|null $url Cake-relative URL or array of URL parameters, or + * @param array|string|null $url Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * @param array $options Array of options and HTML attributes. */ - public function __construct($title, $url, array $options = []) + public function __construct(string|array $title, string|array|null $url, array $options = []) { $this->set('title', $title); $this->set('url', $url); @@ -51,10 +51,10 @@ public function __construct($title, $url, array $options = []) /** * title property setter * - * @param string|array|null $title A title for the link - * @return string|array + * @param array|string|null $title A title for the link + * @return array|string */ - protected function _setTitle($title) + protected function _setTitle(string|array|null $title): string|array { if (empty($title)) { throw new InvalidArgumentException('Missing title for LinkItem action'); @@ -66,11 +66,11 @@ protected function _setTitle($title) /** * url property setter * - * @param string|array|null $url Cake-relative URL or array of URL parameters, or + * @param array|string|null $url Cake-relative URL or array of URL parameters, or * external URL (starts with http://) - * @return string|array + * @return array|string */ - protected function _setUrl($url) + protected function _setUrl(string|array|null $url): string|array { if ($url === null || empty($url)) { throw new InvalidArgumentException('Invalid url specified for LinkItem'); @@ -83,9 +83,9 @@ protected function _setUrl($url) * options property setter * * @param array $options Array of options and HTML attributes. - * @return string|array + * @return array|string */ - protected function _setOptions($options) + protected function _setOptions(array $options): string|array { if (empty($options)) { $options = []; diff --git a/src/Listener/Traits/FormTypeTrait.php b/src/Listener/Traits/FormTypeTrait.php index 5c56b083..842d31a8 100644 --- a/src/Listener/Traits/FormTypeTrait.php +++ b/src/Listener/Traits/FormTypeTrait.php @@ -156,9 +156,9 @@ protected function _getDefaultExtraLeftButtons(): array /** * Get form url. * - * @return mixed + * @return array|string|null */ - protected function _getFormUrl() + protected function _getFormUrl(): array|string|null { $action = $this->_action(); diff --git a/src/Listener/Traits/SidebarNavigationTrait.php b/src/Listener/Traits/SidebarNavigationTrait.php index 37340418..5eb32cec 100644 --- a/src/Listener/Traits/SidebarNavigationTrait.php +++ b/src/Listener/Traits/SidebarNavigationTrait.php @@ -24,9 +24,9 @@ public function beforeRenderSidebarNavigation(): void /** * Returns the sidebar navigation to show on scaffolded view * - * @return string|null|false + * @return string|false|null */ - protected function _getSidebarNavigation() + protected function _getSidebarNavigation(): string|false|null { $action = $this->_action(); diff --git a/src/Listener/ViewListener.php b/src/Listener/ViewListener.php index 7f3c0397..7a7ca249 100644 --- a/src/Listener/ViewListener.php +++ b/src/Listener/ViewListener.php @@ -4,7 +4,7 @@ namespace CrudView\Listener; use Cake\Collection\Collection; -use Cake\Database\Exception; +use Cake\Database\Exception\DatabaseException; use Cake\Event\EventInterface; use Cake\Utility\Hash; use Cake\Utility\Inflector; @@ -30,7 +30,7 @@ class ViewListener extends BaseListener * * @var array|null */ - protected $associations = null; + protected ?array $associations = null; /** * [beforeFind description] @@ -199,7 +199,7 @@ protected function _getBreadcrumbs(): array * The user can choose to suppress specific relations using the blacklist * functionality. * - * @param string[] $associationTypes List of association types. + * @param array $associationTypes List of association types. * @return array */ protected function _getRelatedModels(array $associationTypes = []): array @@ -284,7 +284,7 @@ protected function _getPageVariables(): array 'displayField' => $table->getDisplayField(), 'primaryKey' => $table->getPrimaryKey(), ]; - } catch (Exception $e) { + } catch (DatabaseException) { // May be empty if there is no table object for the action } @@ -317,7 +317,7 @@ protected function _scaffoldFields(array $associations = []): array $scope = $action->getConfig('scope'); if ($scope === 'entity' && !empty($associations['manyToMany'])) { - foreach ($associations['manyToMany'] as $alias => $options) { + foreach ($associations['manyToMany'] as $options) { $cols[sprintf('%s._ids', $options['entities'])] = [ 'multiple' => true, ]; @@ -595,7 +595,7 @@ protected function _associations(array $whitelist = []): array * * @return array|string */ - protected function _primaryKeyValue() + protected function _primaryKeyValue(): array|string { $fields = (array)$this->_table()->getPrimaryKey(); $values = []; @@ -617,7 +617,7 @@ protected function _primaryKeyValue() * * @return string|int|null */ - protected function _displayFieldValue() + protected function _displayFieldValue(): string|int|null { /** @psalm-suppress PossiblyInvalidArgument */ return $this->_deriveFieldFromContext($this->_table()->getDisplayField()); @@ -630,7 +630,7 @@ protected function _displayFieldValue() * @param string $field Name of field. * @return mixed */ - protected function _deriveFieldFromContext(string $field) + protected function _deriveFieldFromContext(string $field): mixed { $controller = $this->_controller(); $modelClass = $this->_table()->getAlias(); diff --git a/src/Listener/ViewSearchListener.php b/src/Listener/ViewSearchListener.php index b53270ce..13ce81a4 100644 --- a/src/Listener/ViewSearchListener.php +++ b/src/Listener/ViewSearchListener.php @@ -25,7 +25,7 @@ class ViewSearchListener extends BaseListener * * @var array */ - protected $_defaultConfig = [ + protected array $_defaultConfig = [ 'enabled' => null, 'autocomplete' => true, 'select2' => true, diff --git a/src/Menu/MenuDropdown.php b/src/Menu/MenuDropdown.php index 00d16895..4a190794 100644 --- a/src/Menu/MenuDropdown.php +++ b/src/Menu/MenuDropdown.php @@ -10,14 +10,14 @@ class MenuDropdown * * @var string **/ - protected $title; + protected string $title; /** * Array of MenuDivider|MenuItem entries * * @var array **/ - protected $entries = []; + protected array $entries = []; /** * Contains an HTML link. diff --git a/src/Menu/MenuItem.php b/src/Menu/MenuItem.php index 0746a141..f640a506 100644 --- a/src/Menu/MenuItem.php +++ b/src/Menu/MenuItem.php @@ -10,32 +10,32 @@ class MenuItem * * @var string **/ - protected $title; + protected string $title; /** * Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * - * @var string|array|null + * @var array|string|null */ - protected $url = null; + protected string|array|null $url = null; /** * Array of options and HTML attributes. * * @var array **/ - protected $options = []; + protected array $options = []; /** * Contains an HTML link. * * @param string $title The content to be wrapped by `` tags. - * @param string|array|null $url Cake-relative URL or array of URL parameters, or + * @param array|string|null $url Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * @param array $options Array of options and HTML attributes. */ - public function __construct(string $title, $url = null, array $options = []) + public function __construct(string $title, string|array|null $url = null, array $options = []) { $this->title = $title; $this->url = $url; @@ -55,9 +55,9 @@ public function getTitle(): string /** * Returns the menu item ur * - * @return string|array|null + * @return array|string|null */ - public function getUrl() + public function getUrl(): string|array|null { return $this->url; } diff --git a/src/Plugin.php b/src/Plugin.php deleted file mode 100644 index 679fa93c..00000000 --- a/src/Plugin.php +++ /dev/null @@ -1,19 +0,0 @@ -getSchemaCollection(); $tables = $schema->listTables(); @@ -48,6 +49,6 @@ public function display(?array $tables = null, ?array $blacklist = null) $normal[$table] = $config; } - return $this->set('tables', $normal); + $this->set('tables', $normal); } } diff --git a/src/View/CrudView.php b/src/View/CrudView.php index f6198dbc..1705060a 100644 --- a/src/View/CrudView.php +++ b/src/View/CrudView.php @@ -24,7 +24,7 @@ class CrudView extends View implements EventListenerInterface * * @var string */ - protected $layout = 'CrudView.default'; + protected string $layout = 'CrudView.default'; /** * Initialization hook method. @@ -63,7 +63,7 @@ public function implementedEvents(): array * * @return void */ - public function beforeLayout() + public function beforeLayout(): void { $this->_loadAssets(); } diff --git a/src/View/Helper/CrudViewHelper.php b/src/View/Helper/CrudViewHelper.php index 62e01423..e27d1547 100644 --- a/src/View/Helper/CrudViewHelper.php +++ b/src/View/Helper/CrudViewHelper.php @@ -23,21 +23,21 @@ class CrudViewHelper extends Helper * * @var array */ - protected $helpers = ['Form', 'Html', 'Time']; + protected array $helpers = ['Form', 'Html', 'Time']; /** * Context * * @var \Cake\Datasource\EntityInterface */ - protected $_context; + protected EntityInterface $_context; /** * Default config. * * @var array */ - protected $_defaultConfig = [ + protected array $_defaultConfig = [ 'fieldFormatters' => null, ]; @@ -68,9 +68,9 @@ public function getContext(): EntityInterface * @param string $field The field to process. * @param \Cake\Datasource\EntityInterface $data The entity data. * @param array $options Processing options. - * @return string|null|array|bool|int + * @return array|string|int|bool|null */ - public function process(string $field, EntityInterface $data, array $options = []) + public function process(string $field, EntityInterface $data, array $options = []): string|array|bool|int|null { $this->setContext($data); @@ -106,7 +106,7 @@ public function process(string $field, EntityInterface $data, array $options = [ * @param string $field The field to extract, if null, the field from the entity context is used. * @return mixed */ - public function fieldValue(?EntityInterface $data, string $field) + public function fieldValue(?EntityInterface $data, string $field): mixed { if (empty($data)) { $data = $this->getContext(); @@ -121,9 +121,9 @@ public function fieldValue(?EntityInterface $data, string $field) * @param string $field Name of field. * @param mixed $value The value that the field should have within related data. * @param array $options Options array. - * @return array|bool|null|int|string + * @return array|string|int|bool|null */ - public function introspect(string $field, $value, array $options = []) + public function introspect(string $field, mixed $value, array $options = []): array|bool|int|string|null { $output = $this->relation($field); if ($output) { @@ -185,7 +185,7 @@ public function columnType(string $field): ?string * @param array $options Options array * @return string */ - public function formatBoolean(string $field, $value, array $options): string + public function formatBoolean(string $field, mixed $value, array $options): string { return (bool)$value ? $this->Html->badge(__d('crud', 'Yes'), ['class' => empty($options['inverted']) ? 'success' : 'danger']) : @@ -200,7 +200,7 @@ public function formatBoolean(string $field, $value, array $options): string * @param array $options Options array. * @return string */ - public function formatDate(string $field, $value, array $options): string + public function formatDate(string $field, mixed $value, array $options): string { if ($value === null) { return $this->Html->badge(__d('crud', 'N/A'), ['class' => 'info']); @@ -225,7 +225,7 @@ public function formatDate(string $field, $value, array $options): string * @param array $options Options array. * @return string */ - public function formatTime(string $field, $value, array $options): string + public function formatTime(string $field, mixed $value, array $options): string { $format = $options['format'] ?? 'KK:mm:ss a'; /** @var string $value */ @@ -244,7 +244,7 @@ public function formatTime(string $field, $value, array $options): string * @param mixed $value Value of field. * @return string */ - public function formatString(string $field, $value): string + public function formatString(string $field, mixed $value): string { return h(Text::truncate((string)$value, 200)); } @@ -256,7 +256,7 @@ public function formatString(string $field, $value): string * @param array $options Options array. * @return string */ - public function formatDisplayField($value, array $options): string + public function formatDisplayField(string $value, array $options): string { return $this->createViewLink($value, ['escape' => false]); } @@ -267,7 +267,7 @@ public function formatDisplayField($value, array $options): string * @param string $field Name of field. * @return mixed Array of data to output, false if no match found */ - public function relation(string $field) + public function relation(string $field): mixed { $associations = $this->associations(); if (empty($associations['manyToOne'])) { @@ -421,7 +421,7 @@ public function associations(): array * @param string $key View variable to get. * @return mixed */ - public function getViewVar(string $key) + public function getViewVar(string $key): mixed { return $this->_View->get($key); } diff --git a/src/View/Widget/DateTimeWidget.php b/src/View/Widget/DateTimeWidget.php index db8958bc..151892e8 100644 --- a/src/View/Widget/DateTimeWidget.php +++ b/src/View/Widget/DateTimeWidget.php @@ -3,10 +3,11 @@ namespace CrudView\View\Widget; +use BootstrapUI\View\Widget\DateTimeWidget as BUIDateTimeWidget; use Cake\Core\Configure; use Cake\View\Form\ContextInterface; -class DateTimeWidget extends \BootstrapUI\View\Widget\DateTimeWidget +class DateTimeWidget extends BUIDateTimeWidget { // phpcs:disable /** diff --git a/tests/TestCase/Dashboard/DashboardTest.php b/tests/TestCase/Dashboard/DashboardTest.php index 576e600d..b885b60d 100644 --- a/tests/TestCase/Dashboard/DashboardTest.php +++ b/tests/TestCase/Dashboard/DashboardTest.php @@ -8,6 +8,7 @@ use Cake\TestSuite\TestCase; use CrudView\Dashboard\Dashboard; use CrudView\View\Cell\DashboardTableCell; +use InvalidArgumentException; /** * DashboardTest class @@ -33,7 +34,7 @@ public function testConstruct() public function testInvalidConstruct() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Valid columns value must be one of [1, 2, 3, 4, 6, 12]'); new Dashboard(null, 0); diff --git a/tests/TestCase/Dashboard/Module/LinkItemTest.php b/tests/TestCase/Dashboard/Module/LinkItemTest.php index 2cdeaebd..8ee4995f 100644 --- a/tests/TestCase/Dashboard/Module/LinkItemTest.php +++ b/tests/TestCase/Dashboard/Module/LinkItemTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use CrudView\Dashboard\Module\LinkItem; +use InvalidArgumentException; /** * LinkItemTest class @@ -27,7 +28,7 @@ public function testConstruct() public function testInvalidTitle() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Missing title for LinkItem action'); new LinkItem('', null); @@ -35,7 +36,7 @@ public function testInvalidTitle() public function testInvalidNullUrl() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid url specified for LinkItem'); new LinkItem('Title', null); @@ -43,7 +44,7 @@ public function testInvalidNullUrl() public function testInvalidEmptyUrl() { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid url specified for LinkItem'); new LinkItem('Title', ''); diff --git a/tests/TestCase/View/Helper/CrudViewHelperTest.php b/tests/TestCase/View/Helper/CrudViewHelperTest.php index 76c7a5ff..36fac1f1 100644 --- a/tests/TestCase/View/Helper/CrudViewHelperTest.php +++ b/tests/TestCase/View/Helper/CrudViewHelperTest.php @@ -3,7 +3,7 @@ namespace CrudView\Test\TestCase\View\Helper; -use Cake\I18n\FrozenTime; +use Cake\I18n\DateTime; use Cake\ORM\Entity; use Cake\TestSuite\TestCase; use Cake\View\View; @@ -14,19 +14,12 @@ */ class CrudViewHelperTest extends TestCase { - /** - * Helper to be tested - * - * @var \Crud\View\Helper\CrudViewHelper - */ - public $CrudView; + protected CrudViewHelper $CrudView; /** - * Mocked view - * * @var \Cake\View\View&\PHPUnit_Framework_MockObject_MockObject */ - public $View; + protected $View; /** * setUp method @@ -64,7 +57,7 @@ public function testIntrospect() ->with('created') ->will($this->returnValue('datetime')); - $value = new FrozenTime(); + $value = new DateTime(); $result = $this->CrudView->introspect('created', $value); $this->assertEquals('just now', $result); @@ -75,10 +68,10 @@ public function testIntrospect() $this->assertEquals($this->CrudView->Time->format($value, 'KK:mm:ss a'), $result); $result = $this->CrudView->introspect('created', 'invalid'); - $this->assertEquals('N/A', $result); + $this->assertEquals('N/A', $result); $result = $this->CrudView->introspect('created', null); - $this->assertEquals('N/A', $result); + $this->assertEquals('N/A', $result); $this->CrudView->setConfig('fieldFormatters', [ 'datetime' => function () { diff --git a/tests/TestCase/View/Widget/DateTimeWidgetTest.php b/tests/TestCase/View/Widget/DateTimeWidgetTest.php index 7cd1c097..55c440c6 100644 --- a/tests/TestCase/View/Widget/DateTimeWidgetTest.php +++ b/tests/TestCase/View/Widget/DateTimeWidgetTest.php @@ -4,7 +4,7 @@ namespace CrudView\Test\TestCase\View\Widget; use Cake\Core\Configure; -use Cake\I18n\FrozenDate; +use Cake\I18n\Date; use Cake\TestSuite\TestCase; use Cake\View\Form\ContextInterface; use Cake\View\StringTemplate; @@ -83,7 +83,7 @@ public function renderProvider() [ 'id' => 'the-id3', 'name' => 'the-name3', - 'val' => new FrozenDate('2000-01-01'), + 'val' => new Date('2000-01-01'), 'type' => 'date', 'required' => false, ], diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6ec33c3e..3709ec0d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,8 +1,8 @@ add(new \CrudView\Plugin()); - -Configure::write('Error.ignoredDeprecationPaths', [ - 'src/TestSuite/Fixture/FixtureInjector.php', -]); +Plugin::getCollection()->add(new CrudViewPlugin()); From 83ecacf93c817cc04c0900de7818903e2d66606c Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 31 Dec 2022 12:56:43 +0530 Subject: [PATCH 02/38] Updates for Cake 5 --- .github/workflows/ci.yml | 49 ++----------------- composer.json | 6 ++- phpstan-baseline.neon | 27 +--------- psalm-baseline.xml | 20 +++++--- src/Listener/ViewListener.php | 4 ++ src/View/Helper/CrudViewHelper.php | 11 +---- .../View/Helper/CrudViewHelperTest.php | 2 +- 7 files changed, 29 insertions(+), 90 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52d7b97a..3a9f666f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,51 +4,12 @@ on: [push, pull_request] jobs: testsuite: - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - prefer-lowest: [''] - php-version: ['8.1', '8.2'] - include: - - php-version: '8.1' - prefer-lowest: 'prefer-lowest' - - steps: - - uses: actions/checkout@v3 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, intl, pdo_${{ matrix.db-type }} - coverage: pcov - - - name: Composer install - run: | - if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then - composer update --prefer-lowest --prefer-stable - elif ${{ matrix.php-version == '8.2' }}; then - composer update --ignore-platform-req=php - else - composer update - fi - - - name: Run PHPUnit - run: | - if [[ ${{ matrix.php-version }} == '8.1' ]]; then - vendor/bin/phpunit --coverage-clover=coverage.xml - else - vendor/bin/phpunit - fi - - - name: Code Coverage Report - if: matrix.php-version == '8.1' - uses: codecov/codecov-action@v3 + uses: cakephp/.github/.github/workflows/testsuite-without-db.yml@5.x + secrets: inherit cs-stan: name: Coding Standard & Static Analysis - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 @@ -59,10 +20,10 @@ jobs: php-version: '8.1' extensions: mbstring, intl coverage: none - tools: vimeo/psalm:4, phpstan:1.9, cs2pr + tools: vimeo/psalm:5, phpstan:1.9, cs2pr - name: Composer Install - run: composer require --dev cakephp/cakephp-codesniffer:5.x-dev + run: composer require --dev cakephp/cakephp-codesniffer:^5.0 - name: Run phpcs run: vendor/bin/phpcs --report=checkstyle --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/ | cs2pr diff --git a/composer.json b/composer.json index 6a8ca257..4f9bed6d 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,7 @@ }, "require-dev": { "friendsofcake/cakephp-test-utilities": "dev-cake-5.x", + "markstory/asset_compress": "5.x-dev", "phpunit/phpunit": "^9.5.19" }, "autoload": { @@ -53,11 +54,12 @@ "wiki": "http://cakephp.nu/cakephp-crud/", "irc": "irc://irc.freenode.org/friendsofcake" }, - "prefer-stable": true, "config": { "sort-packages": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f58831e8..5b56306e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -26,32 +26,7 @@ parameters: path: src/Listener/ViewSearchListener.php - - message: "#^Call to method css\\(\\) on an unknown class AssetCompress\\\\View\\\\Helper\\\\AssetCompressHelper\\.$#" - count: 1 - path: src/View/CrudView.php - - - - message: "#^Call to method script\\(\\) on an unknown class AssetCompress\\\\View\\\\Helper\\\\AssetCompressHelper\\.$#" - count: 2 - path: src/View/CrudView.php - - - - message: "#^Binary operation \"\\+\" between string and array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true', data\\-alt\\-input\\-class\\?\\: string, class\\: array\\{'input\\-group', 'flatpickr'\\}\\} results in an error\\.$#" - count: 1 - path: src/View/Widget/DateTimeWidget.php - - - - message: "#^Binary operation \"\\+\\=\" between array\\\\|string\\|null and array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true'\\} results in an error\\.$#" - count: 1 - path: src/View/Widget/DateTimeWidget.php - - - - message: "#^Offset 'data\\-wrap' does not exist on array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true'\\}\\.$#" - count: 1 - path: src/View/Widget/DateTimeWidget.php - - - - message: "#^Offset 'iconClass' on array\\{data\\-enable\\-seconds\\?\\: 'true', data\\-date\\-format\\: string, data\\-alt\\-format\\?\\: mixed, data\\-alt\\-input\\?\\: 'true', data\\-no\\-calendar\\?\\: 'true', data\\-enable\\-time\\?\\: 'true'\\} in isset\\(\\) does not exist\\.$#" + message: "#^Binary operation \"\\+\" between string and non\\-empty\\-array results in an error\\.$#" count: 1 path: src/View/Widget/DateTimeWidget.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2ee45abd..2e98c4d3 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,16 +1,22 @@ - - - - $this->AssetCompress - $this->AssetCompress - $this->AssetCompress - + + + + $event->getSubject()->element + + + + + $input['type'] + $data['name'] $data['templateVars'] + + $data['type'] + diff --git a/src/Listener/ViewListener.php b/src/Listener/ViewListener.php index 6bfb4755..e2add620 100644 --- a/src/Listener/ViewListener.php +++ b/src/Listener/ViewListener.php @@ -37,6 +37,7 @@ class ViewListener extends BaseListener * * @param \Cake\Event\EventInterface $event Event. * @return void + * @psalm-param \Cake\Event\EventInterface<\Crud\Event\Subject> $event */ public function beforeFind(EventInterface $event): void { @@ -57,6 +58,7 @@ public function beforeFind(EventInterface $event): void * * @param \Cake\Event\EventInterface $event Event. * @return void + * @psalm-param \Cake\Event\EventInterface<\Crud\Event\Subject> $event */ public function beforePaginate(EventInterface $event): void { @@ -77,6 +79,7 @@ public function beforePaginate(EventInterface $event): void * * @param \Cake\Event\EventInterface $event Event. * @return void + * @psalm-param \Cake\Event\EventInterface<\Crud\Event\Subject> $event */ public function beforeRender(EventInterface $event): void { @@ -125,6 +128,7 @@ public function beforeRender(EventInterface $event): void * * @param \Cake\Event\EventInterface $event Event. * @return void + * @psalm-param \Cake\Event\EventInterface<\Crud\Event\Subject> $event */ public function setFlash(EventInterface $event): void { diff --git a/src/View/Helper/CrudViewHelper.php b/src/View/Helper/CrudViewHelper.php index e27d1547..f6a9bd5a 100644 --- a/src/View/Helper/CrudViewHelper.php +++ b/src/View/Helper/CrudViewHelper.php @@ -9,7 +9,6 @@ use Cake\Utility\Text; use Cake\View\Helper; use Cake\View\Helper\FormHelper; -use DateTimeInterface; /** * @property \BootstrapUI\View\Helper\FormHelper $Form @@ -206,15 +205,7 @@ public function formatDate(string $field, mixed $value, array $options): string return $this->Html->badge(__d('crud', 'N/A'), ['class' => 'info']); } - if ( - is_int($value) - || is_string($value) - || $value instanceof DateTimeInterface - ) { - return $this->Time->timeAgoInWords($value, $options); - } - - return $this->Html->badge(__d('crud', 'N/A'), ['class' => 'info']); + return $this->Time->timeAgoInWords($value, $options); } /** diff --git a/tests/TestCase/View/Helper/CrudViewHelperTest.php b/tests/TestCase/View/Helper/CrudViewHelperTest.php index 36fac1f1..7e3b6222 100644 --- a/tests/TestCase/View/Helper/CrudViewHelperTest.php +++ b/tests/TestCase/View/Helper/CrudViewHelperTest.php @@ -17,7 +17,7 @@ class CrudViewHelperTest extends TestCase protected CrudViewHelper $CrudView; /** - * @var \Cake\View\View&\PHPUnit_Framework_MockObject_MockObject + * @var \Cake\View\View&\PHPUnit\Framework\MockObject\MockObject */ protected $View; From 44e0c53ea4eb659252dd9d755cc816ec8cdf9f65 Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 17 Jul 2023 18:09:38 +0530 Subject: [PATCH 03/38] Updates for phpunit 10 --- .github/workflows/ci.yml | 2 +- .gitignore | 1 + composer.json | 2 +- phpunit.xml.dist | 22 ++++++------------- src/Action/DashboardAction.php | 1 + src/Dashboard/Dashboard.php | 1 + src/Listener/Traits/FormTypeTrait.php | 1 + src/Listener/ViewListener.php | 1 + src/View/Helper/CrudViewHelper.php | 1 + tests/TestCase/Dashboard/DashboardTest.php | 1 + .../View/Widget/DateTimeWidgetTest.php | 2 +- 11 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a9f666f..5301470b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: php-version: '8.1' extensions: mbstring, intl coverage: none - tools: vimeo/psalm:5, phpstan:1.9, cs2pr + tools: vimeo/psalm:5, phpstan:1.10, cs2pr - name: Composer Install run: composer require --dev cakephp/cakephp-codesniffer:^5.0 diff --git a/.gitignore b/.gitignore index 5209c916..ad935574 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ vendor/ composer.lock tmp .phpunit.result.cache +.phpunit.cache diff --git a/composer.json b/composer.json index 4f9bed6d..786e3c73 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "require-dev": { "friendsofcake/cakephp-test-utilities": "dev-cake-5.x", "markstory/asset_compress": "5.x-dev", - "phpunit/phpunit": "^9.5.19" + "phpunit/phpunit": "^10.1" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 10712c99..f6a7ea06 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,27 +1,19 @@ - + ./tests/TestCase - - + - - - - src/ - - - + + + src/ + + diff --git a/src/Action/DashboardAction.php b/src/Action/DashboardAction.php index b8e89fdc..9001fe8f 100644 --- a/src/Action/DashboardAction.php +++ b/src/Action/DashboardAction.php @@ -6,6 +6,7 @@ use Crud\Action\BaseAction; use Crud\Traits\ViewTrait; use CrudView\Dashboard\Dashboard; +use function Cake\I18n\__d; class DashboardAction extends BaseAction { diff --git a/src/Dashboard/Dashboard.php b/src/Dashboard/Dashboard.php index 9afd4872..68c10dcf 100644 --- a/src/Dashboard/Dashboard.php +++ b/src/Dashboard/Dashboard.php @@ -6,6 +6,7 @@ use Cake\Datasource\EntityTrait; use Cake\View\Cell; use InvalidArgumentException; +use function Cake\I18n\__d; class Dashboard { diff --git a/src/Listener/Traits/FormTypeTrait.php b/src/Listener/Traits/FormTypeTrait.php index d2e84a73..e00d40a0 100644 --- a/src/Listener/Traits/FormTypeTrait.php +++ b/src/Listener/Traits/FormTypeTrait.php @@ -6,6 +6,7 @@ use Cake\Controller\Controller; use Crud\Action\BaseAction; use Crud\Action\EditAction; +use function Cake\I18n\__d; trait FormTypeTrait { diff --git a/src/Listener/ViewListener.php b/src/Listener/ViewListener.php index e2add620..60de2716 100644 --- a/src/Listener/ViewListener.php +++ b/src/Listener/ViewListener.php @@ -15,6 +15,7 @@ use CrudView\Listener\Traits\SiteTitleTrait; use CrudView\Listener\Traits\UtilityNavigationTrait; use CrudView\Traits\CrudViewConfigTrait; +use function Cake\I18n\__d; class ViewListener extends BaseListener { diff --git a/src/View/Helper/CrudViewHelper.php b/src/View/Helper/CrudViewHelper.php index f6a9bd5a..6595e1d7 100644 --- a/src/View/Helper/CrudViewHelper.php +++ b/src/View/Helper/CrudViewHelper.php @@ -9,6 +9,7 @@ use Cake\Utility\Text; use Cake\View\Helper; use Cake\View\Helper\FormHelper; +use function Cake\I18n\__d; /** * @property \BootstrapUI\View\Helper\FormHelper $Form diff --git a/tests/TestCase/Dashboard/DashboardTest.php b/tests/TestCase/Dashboard/DashboardTest.php index b885b60d..06dd42a1 100644 --- a/tests/TestCase/Dashboard/DashboardTest.php +++ b/tests/TestCase/Dashboard/DashboardTest.php @@ -9,6 +9,7 @@ use CrudView\Dashboard\Dashboard; use CrudView\View\Cell\DashboardTableCell; use InvalidArgumentException; +use function Cake\I18n\__d; /** * DashboardTest class diff --git a/tests/TestCase/View/Widget/DateTimeWidgetTest.php b/tests/TestCase/View/Widget/DateTimeWidgetTest.php index 55c440c6..8abd06d4 100644 --- a/tests/TestCase/View/Widget/DateTimeWidgetTest.php +++ b/tests/TestCase/View/Widget/DateTimeWidgetTest.php @@ -55,7 +55,7 @@ public function testRenderSimple($compareFileName, $data) * * @return array */ - public function renderProvider() + public static function renderProvider() { return [ [ From d98efdee3e6a7f07b80506c1e1b24b8b1583112d Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 17 Jul 2023 18:20:38 +0530 Subject: [PATCH 04/38] Fix errors reported by static analysis --- phpstan.neon | 2 -- psalm-baseline.xml | 5 ----- psalm.xml | 3 +++ src/Listener/Traits/IndexTypeTrait.php | 4 ++-- src/Listener/ViewListener.php | 23 ++++++++++++++--------- src/Listener/ViewSearchListener.php | 9 ++++++--- src/View/Helper/CrudViewHelper.php | 1 + 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 3b09bdc5..ec34e635 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,5 +9,3 @@ parameters: - src universalObjectCratesClasses: - Crud\Event\Subject - bootstrapFiles: - - vendor/cakephp/cakephp/src/Database/Exception/DatabaseException.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2e98c4d3..53d6cf0d 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,10 +1,5 @@ - - - $event->getSubject()->element - - $input['type'] diff --git a/psalm.xml b/psalm.xml index c423ba40..e3b7c384 100644 --- a/psalm.xml +++ b/psalm.xml @@ -6,6 +6,9 @@ xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" errorBaseline="psalm-baseline.xml" + usePhpDocMethodsWithoutMagicCall="true" + findUnusedBaselineEntry="true" + findUnusedCode="false" > diff --git a/src/Listener/Traits/IndexTypeTrait.php b/src/Listener/Traits/IndexTypeTrait.php index d19dee76..d2d4f6f8 100644 --- a/src/Listener/Traits/IndexTypeTrait.php +++ b/src/Listener/Traits/IndexTypeTrait.php @@ -84,7 +84,7 @@ protected function _getIndexTitleField(): string $field = $action->getConfig('scaffold.index_title_field'); if ($field === null) { - $field = $this->_table()->getDisplayField(); + $field = $this->_model()->getDisplayField(); } return $field; @@ -154,5 +154,5 @@ abstract protected function _action(?string $name = null): BaseAction; /** * @inheritDoc */ - abstract protected function _table(); + abstract protected function _model(); } diff --git a/src/Listener/ViewListener.php b/src/Listener/ViewListener.php index 60de2716..33e4a204 100644 --- a/src/Listener/ViewListener.php +++ b/src/Listener/ViewListener.php @@ -15,8 +15,12 @@ use CrudView\Listener\Traits\SiteTitleTrait; use CrudView\Listener\Traits\UtilityNavigationTrait; use CrudView\Traits\CrudViewConfigTrait; +use function Cake\Core\pluginSplit; use function Cake\I18n\__d; +/** + * @method \Cake\ORM\Table _model() + */ class ViewListener extends BaseListener { use CrudViewConfigTrait; @@ -134,6 +138,7 @@ public function beforeRender(EventInterface $event): void public function setFlash(EventInterface $event): void { unset($event->getSubject()->params['class']); + /** @psalm-suppress UndefinedPropertyAssignment */ $event->getSubject()->element = ltrim($event->getSubject()->type); } @@ -173,7 +178,7 @@ protected function _getPageTitle(): string $displayFieldValue = $this->_displayFieldValue(); if ( $displayFieldValue === null - || $this->_table()->getDisplayField() === $this->_table()->getPrimaryKey() + || $this->_model()->getDisplayField() === $this->_model()->getPrimaryKey() ) { /** @psalm-var string $primaryKeyValue */ return sprintf('%s %s #%s', $actionName, $controllerName, $primaryKeyValue); @@ -218,12 +223,12 @@ protected function _getRelatedModels(array $associationTypes = []): array if (empty($models)) { $associations = []; if (empty($associationTypes)) { - $associations = $this->_table()->associations(); + $associations = $this->_model()->associations(); } else { foreach ($associationTypes as $assocType) { $associations = array_merge( $associations, - $this->_table()->associations()->getByType($assocType) + $this->_model()->associations()->getByType($assocType) ); } } @@ -268,7 +273,7 @@ protected function _blacklist(): array */ protected function _getPageVariables(): array { - $table = $this->_table(); + $table = $this->_model(); $modelClass = $table->getAlias(); $controller = $this->_controller(); $scope = $this->_action()->getConfig('scope'); @@ -317,7 +322,7 @@ protected function _scaffoldFields(array $associations = []): array } if (empty($scaffoldFields) || $action->getConfig('scaffold.autoFields')) { - $cols = $this->_table()->getSchema()->columns(); + $cols = $this->_model()->getSchema()->columns(); $cols = Hash::normalize($cols); $scope = $action->getConfig('scope'); @@ -554,7 +559,7 @@ protected function _normalizeActions(array $actions): array */ protected function _associations(array $whitelist = []): array { - $table = $this->_table(); + $table = $this->_model(); $associationConfiguration = []; @@ -605,7 +610,7 @@ protected function _associations(array $whitelist = []): array */ protected function _primaryKeyValue(): array|string { - $fields = (array)$this->_table()->getPrimaryKey(); + $fields = (array)$this->_model()->getPrimaryKey(); $values = []; foreach ($fields as $field) { $values[] = $this->_deriveFieldFromContext($field); @@ -628,7 +633,7 @@ protected function _primaryKeyValue(): array|string protected function _displayFieldValue(): string|int|null { /** @psalm-suppress PossiblyInvalidArgument */ - return $this->_deriveFieldFromContext($this->_table()->getDisplayField()); + return $this->_deriveFieldFromContext($this->_model()->getDisplayField()); } /** @@ -641,7 +646,7 @@ protected function _displayFieldValue(): string|int|null protected function _deriveFieldFromContext(string $field): mixed { $controller = $this->_controller(); - $modelClass = $this->_table()->getAlias(); + $modelClass = $this->_model()->getAlias(); $entity = $this->_entity(); $request = $this->_request(); $value = $entity->get($field); diff --git a/src/Listener/ViewSearchListener.php b/src/Listener/ViewSearchListener.php index 13ce81a4..c29b3292 100644 --- a/src/Listener/ViewSearchListener.php +++ b/src/Listener/ViewSearchListener.php @@ -8,6 +8,9 @@ use Cake\Utility\Hash; use Crud\Listener\BaseListener; +/** + * @method \Cake\ORM\Table _model() + */ class ViewSearchListener extends BaseListener { /** @@ -56,7 +59,7 @@ public function implementedEvents(): array */ public function afterPaginate(EventInterface $event): void { - if (!$this->_table()->behaviors()->has('Search')) { + if (!$this->_model()->behaviors()->has('Search')) { return; } @@ -82,13 +85,13 @@ public function fields(): array $fields = $this->getConfig('fields') ?: []; $config = $this->getConfig(); - $schema = $this->_table()->getSchema(); + $schema = $this->_model()->getSchema(); $request = $this->_request(); if ($fields) { $fields = Hash::normalize($fields); } else { - $filters = $this->_table()->searchManager()->getFilters($config['collection']); + $filters = $this->_model()->searchManager()->getFilters($config['collection']); foreach ($filters as $filter) { $opts = $filter->getConfig('form'); diff --git a/src/View/Helper/CrudViewHelper.php b/src/View/Helper/CrudViewHelper.php index 6595e1d7..261302c1 100644 --- a/src/View/Helper/CrudViewHelper.php +++ b/src/View/Helper/CrudViewHelper.php @@ -9,6 +9,7 @@ use Cake\Utility\Text; use Cake\View\Helper; use Cake\View\Helper\FormHelper; +use function Cake\Core\h; use function Cake\I18n\__d; /** From a49ba32affba3ae41c3521ad72dd3b97c8dfb787 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 3 Oct 2023 18:57:49 +0530 Subject: [PATCH 05/38] Update to stable releases --- composer.json | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 786e3c73..bea8551a 100644 --- a/composer.json +++ b/composer.json @@ -29,13 +29,13 @@ } ], "require": { - "cakephp/cakephp": "5.x-dev", - "friendsofcake/crud": "dev-cake-5", - "friendsofcake/bootstrap-ui": "dev-cake-5" + "cakephp/cakephp": "^5.0", + "friendsofcake/crud": "^7.0", + "friendsofcake/bootstrap-ui": "^5.0" }, "require-dev": { - "friendsofcake/cakephp-test-utilities": "dev-cake-5.x", - "markstory/asset_compress": "5.x-dev", + "friendsofcake/cakephp-test-utilities": "^3.0", + "markstory/asset_compress": "^5.0", "phpunit/phpunit": "^10.1" }, "autoload": { @@ -59,7 +59,5 @@ "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } - }, - "minimum-stability": "dev", - "prefer-stable": true + } } From 84be527d39a83b0162d9f8dbfb83f01eb8cfb491 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 4 Oct 2023 22:55:55 +0530 Subject: [PATCH 06/38] Fix type --- src/Listener/ViewListener.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Listener/ViewListener.php b/src/Listener/ViewListener.php index 33e4a204..e7dce5c6 100644 --- a/src/Listener/ViewListener.php +++ b/src/Listener/ViewListener.php @@ -606,9 +606,9 @@ protected function _associations(array $whitelist = []): array * * If no value can be found, NULL is returned * - * @return array|string + * @return array|string|int|null */ - protected function _primaryKeyValue(): array|string + protected function _primaryKeyValue(): array|string|int|null { $fields = (array)$this->_model()->getPrimaryKey(); $values = []; From 8e707395fa03055d8e13d6d09348bfaa7aa78888 Mon Sep 17 00:00:00 2001 From: ADmad Date: Fri, 6 Oct 2023 13:57:47 +0530 Subject: [PATCH 07/38] Fix search inline form display --- src/Listener/ViewSearchListener.php | 34 ++++++++++++++++++++++++----- templates/element/search.php | 12 +++++----- webroot/css/local.css | 22 +++++++++++-------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/Listener/ViewSearchListener.php b/src/Listener/ViewSearchListener.php index c29b3292..2a098923 100644 --- a/src/Listener/ViewSearchListener.php +++ b/src/Listener/ViewSearchListener.php @@ -6,7 +6,9 @@ use Cake\Event\EventInterface; use Cake\Routing\Router; use Cake\Utility\Hash; +use Cake\Utility\Inflector; use Crud\Listener\BaseListener; +use function Cake\I18n\__d; /** * @method \Cake\ORM\Table _model() @@ -82,14 +84,14 @@ public function afterPaginate(EventInterface $event): void */ public function fields(): array { - $fields = $this->getConfig('fields') ?: []; + $fields = Hash::normalize($this->getConfig('fields'), default: []) ?: []; $config = $this->getConfig(); $schema = $this->_model()->getSchema(); $request = $this->_request(); if ($fields) { - $fields = Hash::normalize($fields); + $fields = Hash::normalize($fields, default: []); } else { $filters = $this->_model()->searchManager()->getFilters($config['collection']); @@ -109,21 +111,21 @@ public function fields(): array 'type' => 'text', ]; - if (substr($field, -3) === '_id' && $field !== '_id') { + if (str_ends_with($field, '_id') && $field !== '_id') { $input['type'] = 'select'; } - $input = (array)$opts + $input; + $input = $opts + $input; $input['value'] = $request->getQuery($field); if (empty($input['options']) && $schema->getColumnType($field) === 'boolean') { - $input['options'] = ['No', 'Yes']; + $input['options'] = [__d('crud', 'No'), __d('crud', 'Yes')]; $input['type'] = 'select'; } if (!empty($input['options'])) { - $input['empty'] = true; + $input['empty'] ??= $this->getPlaceholder($field); if (empty($input['class']) && !$config['select2']) { $input['class'] = 'no-select2'; } @@ -156,6 +158,13 @@ public function fields(): array ]; } + if ($input['type'] === 'text') { + $input['placeholder'] ??= $this->getPlaceholder($field); + } + if ($input['type'] === 'select') { + $input['empty'] ??= $this->getPlaceholder($field); + } + $urlArgs = []; $fieldKeys = $input['fields'] ?? ['id' => $field, 'value' => $field]; @@ -174,4 +183,17 @@ public function fields(): array return $fields; } + + protected function getPlaceholder(string $field): string + { + if (str_contains($field, '.')) { + [, $field] = explode('.', $field); + } + + if (str_ends_with($field, '_id') && $field !== '_id') { + $field = substr($field, 0, -3); + } + + return Inflector::humanize($field); + } } diff --git a/templates/element/search.php b/templates/element/search.php index 990e513d..0c16d1fb 100644 --- a/templates/element/search.php +++ b/templates/element/search.php @@ -7,19 +7,19 @@
    'form-inline', 'id' => 'searchFilter']; + $searchOptions += ['align' => 'inline', 'id' => 'searchFilter']; echo $this->Form->create(null, $searchOptions); echo $this->Form->hidden('_search'); ?> Form->controls($searchInputs, ['fieldset' => false]); ?> -
    - Form->button(__d('crud', 'Filter results'), ['type' => 'submit', 'class' => 'btn btn-primary']); ?> - Search->isSearch()) : ?> + Form->button(__d('crud', 'Filter results'), ['type' => 'submit', 'class' => 'btn btn-primary']); ?> + Search->isSearch()) : ?> +
    Search->resetLink(__d('crud', 'Reset'), ['class' => 'btn btn-primary']) ?> - -
    +
    + Form->end(); ?>
    diff --git a/webroot/css/local.css b/webroot/css/local.css index 94b1ad82..aad75f97 100644 --- a/webroot/css/local.css +++ b/webroot/css/local.css @@ -43,21 +43,25 @@ h2 .actions { margin-left: 15px; } -.search-filters .form-inline .form-group label, -.search-filters .form-inline .btn { - margin-right: .25rem !important; + +.search-filters .form-inline .col-auto { + margin-bottom: var(--bs-gutter-y) !important; } -.search-filters .form-inline .form-group { - margin-right: .5rem !important; +.search-filters .form-inline .form-control input { + min-width: 90px !important; } -.search-filters .form-inline .form-group { - margin-bottom: 1rem !important; +.search-filters .form-inline option { + color: var(--bs-body-color); + font-style: normal; } -.search-filters .form-inline .form-control input { - min-width: 90px !important; +.search-filters .form-inline select:invalid, +.search-filters .form-inline select:has(option[value=""]:checked), +.search-filters .form-inline option[value=""] { + font-style: italic; + color: #777; } .search-filters .form-inline select.autocomplete { From 31b08cab0feace2470a973268c8695d44642fb53 Mon Sep 17 00:00:00 2001 From: ADmad Date: Fri, 6 Oct 2023 19:47:00 +0530 Subject: [PATCH 08/38] Fix bootstrap 5's data attributes --- templates/element/action-groups.php | 2 +- templates/element/form/tabs.php | 2 +- templates/element/menu/dropdown.php | 2 +- templates/layout/default.php | 46 ++++++++++++++--------------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/templates/element/action-groups.php b/templates/element/action-groups.php index 6ac81752..443208a8 100644 --- a/templates/element/action-groups.php +++ b/templates/element/action-groups.php @@ -16,7 +16,7 @@ $group) : ?>
    -
  • > - +
  • diff --git a/templates/element/menu/dropdown.php b/templates/element/menu/dropdown.php index b406a1d8..1458ab01 100644 --- a/templates/element/menu/dropdown.php +++ b/templates/element/menu/dropdown.php @@ -1,5 +1,5 @@