diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b705137 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +# Do not export those files in the Composer archive (lighter dependency) +/.craftplugin export-ignore +/.gitattributes export-ignore +/.github/ export-ignore +/.gitignore export-ignore +/.scrutinizer.yml export-ignore +/codeception.yml export-ignore +/composer.lock export-ignore +/buildchain/ export-ignore +/resources/ export-ignore +/src/web/assets/src/ +/tests/ export-ignore + +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.github/workflows/code-analysis.yaml b/.github/workflows/code-analysis.yaml new file mode 100644 index 0000000..d4bf3fa --- /dev/null +++ b/.github/workflows/code-analysis.yaml @@ -0,0 +1,40 @@ +name: Code Analysis + +on: + pull_request: null + push: + branches: + - develop + workflow_dispatch: +permissions: + contents: read +jobs: + code_analysis: + strategy: + fail-fast: false + matrix: + actions: + - name: 'PHPStan' + run: composer phpstan + - name: 'Coding Standards' + run: composer fix-cs + name: ${{ matrix.actions.name }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: /tmp/composer-cache + key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} + - name: Setup PHP + id: setup-php + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + extensions: 'ctype,curl,dom,iconv,imagick,intl,json,mbstring,openssl,pcre,pdo,reflection,spl,zip' + ini-values: post_max_size=256M, max_execution_time=180, memory_limit=512M + tools: composer:v2 + - name: Install Composer dependencies + run: composer install --no-interaction --no-ansi --no-progress + - run: ${{ matrix.actions.run }} diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..8e33492 --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,21 @@ +name: Create Release +run-name: Create release for ${{ github.event.client_payload.version }} + +on: + repository_dispatch: + types: + - craftcms/new-release + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: ncipollo/release-action@v1 + with: + body: ${{ github.event.client_payload.notes }} + makeLatest: ${{ github.event.client_payload.latest }} + name: ${{ github.event.client_payload.version }} + prerelease: ${{ github.event.client_payload.prerelease }} + tag: ${{ github.event.client_payload.tag }} diff --git a/CHANGELOG.md b/CHANGELOG.md index e24ac67..6a85760 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. +## 1.12.1 - 2024.04.15 +### Added +* Stable release for Craft CMS 5 +* Add `phpstan` and `ecs` code linting +* Add `code-analysis.yaml` GitHub action +* Add `create-release.yml` for automated released + +### Changed +* PHPstan code cleanup +* ECS code cleanup + ## 1.12.0 - 2024.01.25 ### Added * Added support for Craft CMS 5 diff --git a/LICENSE.md b/LICENSE.md index 48dee26..fce0799 100755 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2021 nystudio107 -Copyright (c) 2021 PutYourLightsOn +Copyright (c) nystudio107 +Copyright (c) PutYourLightsOn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/composer.json b/composer.json index 71597fe..74a9667 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "nystudio107/craft-autocomplete", "description": "Provides Twig template IDE autocomplete of Craft CMS & plugin variables", "type": "yii2-extension", - "version": "1.12.0", + "version": "1.12.1", "keywords": [ "craft", "cms", @@ -30,7 +30,17 @@ } ], "require": { - "craftcms/cms": "^3.0.0 || ^4.0.0 || ^5.0.0-alpha.1" + "craftcms/cms": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "require-dev": { + "craftcms/ecs": "dev-main", + "craftcms/phpstan": "dev-main", + "craftcms/rector": "dev-main" + }, + "scripts": { + "phpstan": "phpstan --ansi --memory-limit=1G", + "check-cs": "ecs check --ansi", + "fix-cs": "ecs check --fix --ansi" }, "config": { "allow-plugins": { diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..85860c2 --- /dev/null +++ b/ecs.php @@ -0,0 +1,13 @@ +paths([ + __DIR__ . '/src', + __FILE__, + ]); + $ecsConfig->parallel(); + $ecsConfig->sets([SetList::CRAFT_CMS_4]); +}; diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..9ad1308 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +includes: + - %currentWorkingDirectory%/vendor/craftcms/phpstan/phpstan.neon + +parameters: + level: 5 + paths: + - src diff --git a/src/Autocomplete.php b/src/Autocomplete.php index 826496e..e43bdeb 100755 --- a/src/Autocomplete.php +++ b/src/Autocomplete.php @@ -1,13 +1,13 @@ self::DEFAULT_AUTOCOMPLETE_GENERATORS + 'types' => self::DEFAULT_AUTOCOMPLETE_GENERATORS, ]); $this->trigger(self::EVENT_REGISTER_AUTOCOMPLETE_GENERATORS, $event); $this->allAutocompleteGenerators = $event->types; diff --git a/src/base/Generator.php b/src/base/Generator.php index f94ee31..e048a0c 100644 --- a/src/base/Generator.php +++ b/src/base/Generator.php @@ -1,13 +1,13 @@ elements->getAllElementTypes(); @@ -157,7 +157,7 @@ private static function elementRouteVariables(): array * * @return array */ - private static function globalVariables(): array + protected static function globalVariables(): array { $globalVariables = []; // See if the GlobalsExtension class is available (Craft CMS 3.7.8 or later) and use it @@ -182,7 +182,7 @@ private static function globalVariables(): array * * @return array */ - private static function overrideValues(): array + protected static function overrideValues(): array { return [ // Swap in our variable in place of the `craft` variable diff --git a/src/generators/AutocompleteVariableGenerator.php b/src/generators/AutocompleteVariableGenerator.php index d9fe639..7435afa 100644 --- a/src/generators/AutocompleteVariableGenerator.php +++ b/src/generators/AutocompleteVariableGenerator.php @@ -1,13 +1,13 @@ getProperties(ReflectionProperty::IS_PUBLIC) as $reflectProp) { - if ($reflectProp) { - // Property name - $reflectPropName = $reflectProp->getName(); - // Ensure the property exists only for this class and not any parent class - if (property_exists(get_parent_class($behavior), $reflectPropName)) { - continue; - } - // Do it this way because getType() reflection method is >= PHP 7.4 - $reflectPropType = gettype($behavior->$reflectPropName); - switch ($reflectPropType) { - case 'object': - $properties[$reflectPropName] = get_class($behavior->$reflectPropName); - break; - default: - $properties[$reflectPropName] = $reflectPropType; - break; - } + // Property name + $reflectPropName = $reflectProp->getName(); + // Ensure the property exists only for this class and not any parent class + if (property_exists(get_parent_class($behavior), $reflectPropName)) { + continue; + } + // Do it this way because getType() reflection method is >= PHP 7.4 + $reflectPropType = gettype($behavior->$reflectPropName); + switch ($reflectPropType) { + case 'object': + $properties[$reflectPropName] = get_class($behavior->$reflectPropName); + break; + default: + $properties[$reflectPropName] = $reflectPropType; + break; } } // Methods foreach ($reflect->getMethods(ReflectionMethod::IS_PUBLIC) as $reflectMethod) { - if ($reflectMethod) { - // Method name - $reflectMethodName = $reflectMethod->getName(); - // Ensure the method exists only for this class and not any parent class - if (method_exists(get_parent_class($behavior), $reflectMethodName)) { - continue; - } - // Method return type - $methodReturn = ''; - $reflectMethodReturnType = $reflectMethod->getReturnType(); - if ($reflectMethodReturnType) { - $methodReturn = ': ' . $reflectMethodReturnType->getName(); - } - // Method parameters - $methodParams = []; - foreach ($reflectMethod->getParameters() as $methodParam) { - $paramType = ''; - $methodParamType = $methodParam->getType(); - if ($methodParamType) { - $paramType = $methodParamType . ' '; - } - $methodParams[] = $paramType . '$' . $methodParam->getName(); + // Method name + $reflectMethodName = $reflectMethod->getName(); + // Ensure the method exists only for this class and not any parent class + if (method_exists(get_parent_class($behavior), $reflectMethodName)) { + continue; + } + // Method return type + $methodReturn = ''; + $reflectMethodReturnType = $reflectMethod->getReturnType(); + if ($reflectMethodReturnType instanceof ReflectionNamedType) { + $methodReturn = ': ' . $reflectMethodReturnType->getName(); + } + // Method parameters + $methodParams = []; + foreach ($reflectMethod->getParameters() as $methodParam) { + $paramType = ''; + $methodParamType = $methodParam->getType(); + if ($methodParamType) { + $paramType = $methodParamType . ' '; } - $methods[$reflectMethodName] = '(' . implode(', ', $methodParams) . ')' . $methodReturn; + $methodParams[] = $paramType . '$' . $methodParam->getName(); } + $methods[$reflectMethodName] = '(' . implode(', ', $methodParams) . ')' . $methodReturn; } } catch (\ReflectionException $e) { }