diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..adb2b52c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/.phpcs-cache +/clover.xml +/composer.lock +/coveralls-upload.json +/docs/html/ +/mkdocs.site.yml +/phpcs.log +/phpcs.xml +/phpunit.xml +/test/fix/ +/vendor/ +/zf-mkdoc-theme.tgz +/zf-mkdoc-theme/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..bd9d5fec --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +sudo: false +language: php + +php: +- 7.1 +- 7.2 +- nightly + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - composer self-update + +install: travis_retry composer update --prefer-dist + +script: + - vendor/bin/phpcs + - vendor/bin/phpcs $(find test/fixable/* | sort) --report=summary --report-file=phpcs.log; diff test/expected-report.txt phpcs.log + +stages: + - Validate against schema + - Validate fixes + - Test + +jobs: + allow_failures: + - php: nightly + + include: + - stage: Validate against schema + addons: + apt: + packages: + - libxml2-utils + script: xmllint --noout --schema vendor/squizlabs/php_codesniffer/phpcs.xsd src/ZendCodingStandard/ruleset.xml + + - stage: Validate fixes + before_script: + - cp -R test/fixable/ test/fix/ + script: vendor/bin/phpcbf test/fix; diff test/fix test/fixed + +notifications: + email: false diff --git a/CHANGELOG.md b/CHANGELOG.md index f7fd6df6..2508c7df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,141 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. +## 2.0.0 - TBD + +### Added + +- [#5](https://github.com/zendframework/zend-coding-standard/pull/5) adds + online documentation: https://docs.zendframework.com/zend-coding-standard/ +- [#5](https://github.com/zendframework/zend-coding-standard/pull/5) adds + PSR-12 rules. + + *NOTE:* PSR-12 is not finalized. e.g. The `!` operator and `:` placement for + return values are still under discussion. We will change these rules, and, + when PSR-12 is finalized, adapt them. +- [#5](https://github.com/zendframework/zend-coding-standard/pull/5) extends + PSR-12 with ZendFramework specific rules: + + *NOTE:* Most of these rules should look familiar as they are already being + used in components rewritten for PHP 7.1. + + - There should be one space on either side of an equals sign used to assign + a value to a variable. In case of a block of related assignments, more + space may be inserted before the equal sign to promote readability. + - Short array syntax must be used to define arrays. + - All values in multiline arrays must be indented with 4 spaces. + - All array values must be followed by a comma, including the last value. + - Whitespace is not allowed around the opening bracket or before the + closing bracket when referencing an array. + - The `global` keyword may not be used. + - The `PHP_SAPI` constant must be used instead of the `php_sapi_name()` + function. + - PHP function calls must be in lowercase. + - PHP functions which are an alias may not be used. + - Deprecated functions should not be used. + - Comments may be omitted and should not be used for typehinted arguments. + - Comments may not start with `#`. + - Comments may not be empty. + - The words _private_, _protected_, _static_, _constructor_, _deconstructor_, + _Created by_, _getter_ and _setter_, may not be used in comments. + - The annotations `@api`, `@author`, `@category`, `@created`, `@package`, + `@subpackage` and `@version` may not be used in comments. Git commits + provide accurate information. + - The asterisks in a doc comment should align, and there should be one space + between the asterisk and tag. + - Comment tags `@param`, `@throws` and `@return` should not be aligned or + contain multiple spaces between the tag, type and description. + - If a function throws any exceptions, they should be documented in `@throws` + tags. + - The `@var` tag may be used in inline comments to document the _Type_ of + properties. + - Single-line comments with a `@var` tag should be written as one-liners. + - Shorthand scalar typehint variants must be used in docblocks. + - Each PHP file should have a page level docblock with `@see`, `@copyright` + and `@license`. The copyright date should only be adjusted if the file has + changed. + - Each PHP file should have a strict type declaration at the top after the + page level docblock. + - Import statements should be alphabetically sorted. + - Import statements should not be grouped. + - Each import statement should be on its own line. + - Absolute class name references, functions and constants should be imported. + - Unused import statements are not allowed. + - Classes and function within the same namespace should not be imported. + - Imports should not have an alias with the same name. + - A class should not have unused private constants, (or write-only) + properties and methods. + - Class name resolution via `::class` should be used instead of + `__CLASS__`, `get_class()`, `get_class($this)`, `get_called_class()` and + `get_parent_class()`. + - Methods may not have the final declaration in classes declared as final. + - The colon used with return type declarations MUST be surrounded with 1 + space. + - Nullable and optional arguments, which are marked as `= null`, must have + the `?` symbol present. + - Control Structures must have at least one statement inside of the body. + - Catch blocks may be empty. + - Catch blocks must be reachable. + - Catch blocks must use `Throwable` instead of `Exception`. + - The not (`!`) operator must be followed by exactly one space. + - The `&&` and `||` operators must be used instead of `AND` and `OR`. + - The null coalescing operator `??` should be used when possible. + - Assignment operators (eg `+=`, `.=`) should be used when possible. + - Unused variables should not be passed to closures via `use`. + - The code may not contain unreachable code. + - The backtick operator may not be used for execution of shell commands. + - Class and Interface names should be unique in a project and must have a + unique fully qualified name. + - Methods that only call the parent method should not be defined. + - Files that contain PHP code should only have PHP code and should not have + any _"inline HTML"_. + - There must be exactly one space after a type cast. + - Constructors should be named `__construct`, not after the class. + - The opening PHP tag should be the first item in the file. + - Strings should not be concatenated together unless used in multiline for + readability. + - Loose `==` and `!=` comparison operators should not be used. Use `===` + and `!==` instead. + - Language constructs must be used without parentheses where possible. + - Short list syntax `[...]` should be used instead of `list(...)`. + - Short form of type keywords must be used. i.e. `bool` instead of + `boolean`, `int` instead of `integer`, etc. The `binary` and `unset` cast + operators are not allowed. + - Parentheses should not be used if they can be omitted. + - Semicolons `;` should not be used if they can be omitted. + - Variables should be returned directly instead of assigned to a variable + which is not used. + - The `self` keyword should be used instead of the current class name, and + should not have spaces around `::`. + - Static methods should not use `$this`. + - Double quote strings may only be used if they contain variables. + - Strings should not be enclosed in parentheses when being echoed. + - Type casts should not have whitespace inside the parentheses. + - The opening brace for functions should be on a new line with no blank + lines surrounding it. + - The PHP constructs `echo`, `print`, `return`, `include`, `include_once`, + `require`, `require_once`, and `new`, should have one space after them. + - The object operator `->` should not have any spaces around it. + - Semicolons should not have spaces before them. + - The code should not contain superfluous whitespaces. e.g. multiple empty + lines, trailing spaces, etc. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + ## 1.0.0 - 2016-11-09 Initial public release. Incorporates rules for: diff --git a/LICENSE.md b/LICENSE.md index badc26ea..67ba2104 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2016, Zend Technologies USA, Inc. +Copyright (c) 2016-2018, Zend Technologies USA, Inc. All rights reserved. diff --git a/README.md b/README.md index 2a7e94a8..5922b094 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,28 @@ -Zend Framework Coding Standard -============================== +# zend-coding-standard -Repository with all coding standard ruleset for Zend Framework repositories. +[![Build Status](https://secure.travis-ci.org/zendframework/zend-coding-standard.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-coding-standard) +The coding standard ruleset for Zend Framework components. -Installation ------------- +This specification extends and expands [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md), +the extended coding style guide and requires adherence to [PSR-1](https://www.php-fig.org/psr/psr-1), +the basic coding standard. These are minimal specifications and don't address all factors, including things like: + +- whitespace around operators +- alignment of array keys and operators +- alignment of object operations +- how to format multi-line conditionals +- what and what not to import, and how +- etc. + +Contributors have different coding styles and so do the maintainers. During code reviews there are regularly +discussions about spaces and alignments, where and when was said that a function needs to be imported. And +that's where this coding standard comes in: To have internal consistency in a component and between components. + +> Note: PSR-12 is not finalized. e.g. The `!` operator and `:` placement for return values are still under discussion. +We will change these rules, and, when PSR-12 is finalized, adapt them. + +## Installation 1. Install the module via composer by running: @@ -22,26 +39,36 @@ Installation } ``` -3. Create file `phpcs.xml` on base path of your repository with content: +3. Create file `phpcs.xml` on base path of your repository with this content: ```xml - - - + + + + + + + + + + + config src test + + + ``` You can add or exclude some locations in that file. For a reference please see: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml - -Usage ------ +## Usage * To run checks only: @@ -50,7 +77,62 @@ Usage ``` * To automatically fix many CS issues: - + ```bash $ composer cs-fix ``` + +## Ignoring parts of a File + +> Note: Before PHP_CodeSniffer version 3.2.0, `// @codingStandardsIgnoreStart` and `// @codingStandardsIgnoreEnd` were +> used. These are deprecated and will be removed in PHP_CodeSniffer version 4.0. + +Disable parts of a file: +```php +$xmlPackage = new XMLPackage; +// phpcs:disable +$xmlPackage['error_code'] = get_default_error_code_value(); +$xmlPackage->send(); +// phpcs:enable +``` + +Disable a specific rule: +```php +// phpcs:disable Generic.Commenting.Todo.Found +$xmlPackage = new XMLPackage; +$xmlPackage['error_code'] = get_default_error_code_value(); +// TODO: Add an error message here. +$xmlPackage->send(); +// phpcs:enable +``` + +## Development + +> **New rules or Sniffs may not be introduced in minor or bugfix releases and should always be based on the develop +branch and queued for the next major release, unless considered a bugfix for existing rules.** + +If you want to test changes against ZendFramework components or your own projects, install your forked +zend-coding-standard globally with composer: +```bash +$ composer global config repositories.zend-coding-standard vcs git@github.com:/zend-coding-standard.git +$ composer global require --dev zendframework/zend-coding-standard:dev- + +# For this to work, add this to your path: ~/.composer/vendor/bin +# Using `-s` prints the rules that triggered the errors so they can be reviewed easily. `-p` is for progress display. +$ phpcs -sp --standard=ZendCodingStandard src test +``` +Make sure you remove the global installation after testing from your global composer.json file!!! + +Documentation can be previewed locally by installing [MkDocs](https://www.mkdocs.org/#installation) and run +`mkdocs serve`. This will start a server where you can read the docs. + +## Reference + +Rules can be added, excluded or tweaked locally, depending on your preferences. More information on how to do this can +be found here: + +- [Coding Standard Tutorial](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial) +- [Configuration Options](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options) +- [Selectively Applying Rules](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-Ruleset#selectively-applying-rules) +- [Customisable Sniff Properties](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Customisable-Sniff-Properties) +- [Slevomat Coding Standard](https://github.com/slevomat/coding-standard) diff --git a/composer.json b/composer.json index 89f82020..024cd1b5 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,52 @@ { "name": "zendframework/zend-coding-standard", - "description": "Zend Framework coding standard", + "type": "phpcodesniffer-standard", + "description": "Zend Framework Coding Standard", "license": "BSD-3-Clause", "keywords": [ "zf", + "zendframework", "coding standard" ], + "support": { + "docs": "https://docs.zendframework.com/zend-coding-standard/", + "issues": "https://github.com/zendframework/zend-coding-standard/issues", + "source": "https://github.com/zendframework/zend-coding-standard", + "rss": "https://github.com/zendframework/zend-coding-standard/releases.atom", + "chat": "https://zendframework-slack.herokuapp.com", + "forum": "https://discourse.zendframework.com/c/questions/components" + }, "require": { - "squizlabs/php_codesniffer": "^2.7" + "php": "^7.1", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "slevomat/coding-standard": "^4.8.0", + "squizlabs/php_codesniffer": "^3.3.2", + "webimpress/coding-standard": "dev-master" + }, + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "ZendCodingStandard\\": "src/ZendCodingStandard" + } + }, + "autoload-dev": { + "psr-4": { + "ZendCodingStandardTest\\": "test/" + } + }, + "scripts": { + "check": [ + "@test-prepare", + "@test-fix", + "@test-diff" + ], + "create-report": "phpcs $(find test/fixable/* | sort) --report=summary --report-file=test/expected-report.txt", + "test-prepare": "rm -rf test/fix/; cp -R test/fixable/ test/fix/;", + "test-fix": "phpcbf test/fix > /dev/null || true", + "test-diff": "diff test/fix test/fixed" } } diff --git a/CONDUCT.md b/docs/CODE_OF_CONDUCT.md similarity index 96% rename from CONDUCT.md rename to docs/CODE_OF_CONDUCT.md index c663d2be..02fafcd1 100644 --- a/CONDUCT.md +++ b/docs/CODE_OF_CONDUCT.md @@ -1,6 +1,6 @@ # Contributor Code of Conduct -The Zend Framework project adheres to [The Code Manifesto](http://codemanifesto.com) +This project adheres to [The Code Manifesto](http://codemanifesto.com) as its guidelines for contributor interactions. ## The Code Manifesto diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 00000000..84009e8a --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,189 @@ +# CONTRIBUTING + +## RESOURCES + +If you wish to contribute to this project, please be sure to +read/subscribe to the following resources: + + - [Coding Standards](https://github.com/zendframework/zend-coding-standard) + - [Forums](https://discourse.zendframework.com/c/contributors) + - [Chat](https://zendframework-slack.herokuapp.com) + - [Code of Conduct](CODE_OF_CONDUCT.md) + +If you are working on new features or refactoring +[create a proposal](https://github.com/zendframework/zend-coding-standard/issues/new). + +## RUNNING TESTS + +To run tests: + +- Clone the repository: + + ```console + $ git clone git://github.com/zendframework/zend-coding-standard.git + $ cd zend-coding-standard + ``` + +- Install dependencies via composer: + + ```console + $ composer install + ``` + + If you don't have `composer` installed, please download it from https://getcomposer.org/download/ + +- Run the tests using the "test" command shipped in the `composer.json`: + + ```console + $ composer test + ``` + +You can turn on conditional tests with the `phpunit.xml` file. +To do so: + + - Copy `phpunit.xml.dist` file to `phpunit.xml` + - Edit `phpunit.xml` to enable any specific functionality you + want to test, as well as to provide test values to utilize. + +## Running Coding Standards Checks + +First, ensure you've installed dependencies via composer, per the previous +section on running tests. + +To run CS checks only: + +```console +$ composer cs-check +``` + +To attempt to automatically fix common CS issues: + +```console +$ composer cs-fix +``` + +If the above fixes any CS issues, please re-run the tests to ensure +they pass, and make sure you add and commit the changes after verification. + +## Recommended Workflow for Contributions + +Your first step is to establish a public repository from which we can +pull your work into the master repository. We recommend using +[GitHub](https://github.com), as that is where the component is already hosted. + +1. Setup a [GitHub account](https://github.com/), if you haven't yet +2. Fork the repository (https://github.com/zendframework/zend-coding-standard) +3. Clone the canonical repository locally and enter it. + + ```console + $ git clone git://github.com/zendframework/zend-coding-standard.git + $ cd zend-coding-standard + ``` + +4. Add a remote to your fork; substitute your GitHub username in the command + below. + + ```console + $ git remote add {username} git@github.com:{username}/zend-coding-standard.git + $ git fetch {username} + ``` + +### Keeping Up-to-Date + +Periodically, you should update your fork or personal repository to +match the canonical ZF repository. Assuming you have setup your local repository +per the instructions above, you can do the following: + + +```console +$ git checkout master +$ git fetch origin +$ git rebase origin/master +# OPTIONALLY, to keep your remote up-to-date - +$ git push {username} master:master +``` + +If you're tracking other branches -- for example, the "develop" branch, where +new feature development occurs -- you'll want to do the same operations for that +branch; simply substitute "develop" for "master". + +### Working on a patch + +We recommend you do each new feature or bugfix in a new branch. This simplifies +the task of code review as well as the task of merging your changes into the +canonical repository. + +A typical workflow will then consist of the following: + +1. Create a new local branch based off either your master or develop branch. +2. Switch to your new local branch. (This step can be combined with the + previous step with the use of `git checkout -b`.) +3. Do some work, commit, repeat as necessary. +4. Push the local branch to your remote repository. +5. Send a pull request. + +The mechanics of this process are actually quite trivial. Below, we will +create a branch for fixing an issue in the tracker. + +```console +$ git checkout -b hotfix/9295 +Switched to a new branch 'hotfix/9295' +``` + +... do some work ... + + +```console +$ git commit +``` + +... write your log message ... + + +```console +$ git push {username} hotfix/9295:hotfix/9295 +Counting objects: 38, done. +Delta compression using up to 2 threads. +Compression objects: 100% (18/18), done. +Writing objects: 100% (20/20), 8.19KiB, done. +Total 20 (delta 12), reused 0 (delta 0) +To ssh://git@github.com/{username}/zend-coding-standard.git + b5583aa..4f51698 HEAD -> master +``` + +To send a pull request, you have two options. + +If using GitHub, you can do the pull request from there. Navigate to +your repository, select the branch you just created, and then select the +"Pull Request" button in the upper right. Select the user/organization +"zendframework" (or whatever the upstream organization is) as the recipient. + +#### What branch to issue the pull request against? + +Which branch should you issue a pull request against? + +- For fixes against the stable release, issue the pull request against the + "master" branch. +- For new features, or fixes that introduce new elements to the public API (such + as new public methods or properties), issue the pull request against the + "develop" branch. + +### Branch Cleanup + +As you might imagine, if you are a frequent contributor, you'll start to +get a ton of branches both locally and on your remote. + +Once you know that your changes have been accepted to the master +repository, we suggest doing some cleanup of these branches. + +- Local branch cleanup + + ```console + $ git branch -d + ``` + +- Remote branch removal + + ```console + $ git push {username} : + ``` diff --git a/docs/ISSUE_TEMPLATE.md b/docs/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..03ff5a14 --- /dev/null +++ b/docs/ISSUE_TEMPLATE.md @@ -0,0 +1,19 @@ + - [ ] I was not able to find an [open](https://github.com/zendframework/zend-coding-standard/issues?q=is%3Aopen) or [closed](https://github.com/zendframework/zend-coding-standard/issues?q=is%3Aclosed) issue matching what I'm seeing. + - [ ] This is not a question. (Questions should be asked on [chat](https://zendframework.slack.com/) ([Signup here](https://zendframework-slack.herokuapp.com/)) or our [forums](https://discourse.zendframework.com/).) + +Provide a narrative description of what you are trying to accomplish. + +### Code to reproduce the issue + + + +```php +``` + +### Expected results + + + +### Actual results + + diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..f00d90c0 --- /dev/null +++ b/docs/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,25 @@ +Provide a narrative description of what you are trying to accomplish: + +- [ ] Are you fixing a bug? + - [ ] Detail how the bug is invoked currently. + - [ ] Detail the original, incorrect behavior. + - [ ] Detail the new, expected behavior. + - [ ] Base your feature on the `master` branch, and submit against that branch. + - [ ] Add a regression test that demonstrates the bug, and proves the fix. + - [ ] Add a `CHANGELOG.md` entry for the fix. + +- [ ] Are you creating a new feature? + - [ ] Why is the new feature needed? What purpose does it serve? + - [ ] How will users use the new feature? + - [ ] Base your feature on the `develop` branch, and submit against that branch. + - [ ] Add only one feature per pull request; split multiple features over multiple pull requests + - [ ] Add tests for the new feature. + - [ ] Add documentation for the new feature. + - [ ] Add a `CHANGELOG.md` entry for the new feature. + +- [ ] Is this related to quality assurance? + + +- [ ] Is this related to documentation? + + diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md new file mode 100644 index 00000000..369891d2 --- /dev/null +++ b/docs/SUPPORT.md @@ -0,0 +1,25 @@ +# Getting Support + +Zend Framework offers three support channels: + +- For real-time questions, use our + [chat](https://zendframework-slack.herokuapp.com) +- For detailed questions (e.g., those requiring examples) use our + [forums](https://discourse.zendframework.com/c/questions/components) +- To report issues, use this repository's + [issue tracker](https://github.com/zendframework/zend-coding-standard/issues/new) + +**DO NOT** use the issue tracker to ask questions; use chat or the forums for +that. Questions posed to the issue tracker will be closed. + +When reporting an issue, please include the following details: + +- A narrative description of what you are trying to accomplish. +- The minimum code necessary to reproduce the issue. +- The expected results of exercising that code. +- The actual results received. + +We may ask for additional details: what version of the library you are using, +and what PHP version was used to reproduce the issue. + +You may also submit a failing test case as a pull request. diff --git a/docs/book/index.md b/docs/book/index.md new file mode 100644 index 00000000..fe840054 --- /dev/null +++ b/docs/book/index.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/docs/book/v1/index.md b/docs/book/v1/index.md new file mode 100644 index 00000000..97635fa6 --- /dev/null +++ b/docs/book/v1/index.md @@ -0,0 +1 @@ +# The coding standard ruleset for Zend Framework components diff --git a/docs/book/v1/intro.md b/docs/book/v1/intro.md new file mode 100644 index 00000000..4a512141 --- /dev/null +++ b/docs/book/v1/intro.md @@ -0,0 +1,51 @@ +# zend-coding-standard + +This component provides the coding standard ruleset for Zend Framework components. + +## Installation + +1. Install the module via composer by running: + + ```bash + $ composer require --dev zendframework/zend-coding-standard + ``` + +2. Add composer scripts into your `composer.json`: + + ```json + "scripts": { + "cs-check": "phpcs", + "cs-fix": "phpcbf" + } + ``` + +3. Create file `phpcs.xml` on base path of your repository with content: + + ```xml + + + + + + config + src + test + + ``` + +You can add or exclude some locations in that file. +For a reference please see: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml + +## Usage + +* To run checks only: + + ```bash + $ composer cs-check + ``` + +* To automatically fix many CS issues: + + ```bash + $ composer cs-fix + ``` diff --git a/docs/book/v1/ruleset.md b/docs/book/v1/ruleset.md new file mode 100644 index 00000000..0e39c371 --- /dev/null +++ b/docs/book/v1/ruleset.md @@ -0,0 +1,16 @@ +# Ruleset + +## Use PSR-2 coding standard as a base +*PSR2* + +## Disallow long array syntax +*Generic.Arrays.DisallowLongArraySyntax* + +## Force whitespace after `!` +*Generic.Formatting.SpaceAfterNot* + +## Forbid spaces before semicolon `;` +*Squiz.WhiteSpace.SemicolonSpacing* + +## Forbid superfluous whitespaces +*Squiz.WhiteSpace.SuperfluousWhitespace, Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines* diff --git a/docs/book/v2/coding-style-guide.md b/docs/book/v2/coding-style-guide.md new file mode 100644 index 00000000..aa23087b --- /dev/null +++ b/docs/book/v2/coding-style-guide.md @@ -0,0 +1,384 @@ +# Zend Framework Coding Style Guide + +This specification extends and expands [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md), +the extended coding style guide and requires adherence to [PSR-1](https://www.php-fig.org/psr/psr-1), +the basic coding standard. + +> Note: PSR-12 is not finalized. e.g. The `!` operator and `:` placement for return values are still under discussion. +We will change these rules, and, when PSR-12 is finalized, adapt them. + +## General + +### Basic Coding Standard + +Code MUST follow all rules outlined in [PSR-1](https://www.php-fig.org/psr/psr-1) and +[PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md), except in +specific cases outlined in this specification, until PSR-12 is accepted as a standard. + +### Indenting and Alignment + +- There should be one space on either side of an equals sign used to assign a value to a variable. In case of a + block of related assignments, more space may be inserted before the equal sign to promote readability. + [*](ruleset.md#genericformattingmultiplestatementalignment) + +```php + 'value1', + 'key2' => 'value2', + 'keyTwenty' => 'value3', +]; + +$var = [ + 'one' => function() { + $foo = [1,2,3]; + $barBar = [ + 1, + 2, + 3, + ]; + }, + 'longer' => 2, + /* three */ 3 => 'three', +]; +``` + +### PHP Keywords, Types, Constants and Functions + +- The `global` keyword may not be used. [*](ruleset.md#squizphpglobalkeyword) +- The `PHP_SAPI` constant must be used instead of the `php_sapi_name()` function. [*](ruleset.md#genericphpsapiusage) +- PHP function calls must be in lowercase. [*](ruleset.md#squizphplowercasephpfunctions) +- PHP functions which are an alias may not be used. [*](ruleset.md#genericphpforbiddenfunctions) +- Deprecated functions should not be used. [*](ruleset.md#genericphpdeprecatedfunctions) + +### Commenting + +- Comments may be omitted and should not be used for typehinted arguments. +- Comments may not start with `#`. [*](ruleset.md#pearcommentinginlinecomment) +- Comments may not be empty. [*](ruleset.md#slevomatcodingstandardcommentingemptycomment) +- The words _private_, _protected_, _static_, _constructor_, _deconstructor_, _Created by_, _getter_ and _setter_, + may not be used in comments. [*](ruleset.md#slevomatcodingstandardcommentingforbiddencomments) +- The annotations `@api`, `@author`, `@category`, `@created`, `@package`, `@subpackage` and `@version` may not + be used in comments. Git commits provide accurate information. [*](ruleset.md#slevomatcodingstandardcommentingforbiddenannotations) +- The asterisks in a doc comment should align, and there should be one space between the asterisk and tag. + [*](ruleset.md#squizcommentingdoccommentalignment) +- Comment tags `@param`, `@throws` and `@return` should not be aligned or contain multiple spaces between the tag, + type and description. [*](ruleset.md#squizcommentingfunctioncomment) +- If a function throws any exceptions, they should be documented in `@throws` tags. + [*](ruleset.md#squizcommentingfunctioncomment) +- The `@var` tag may be used in inline comments to document the _Type_ of properties. [*](ruleset.md#slevomatcodingstandardcommentinginlinedoccommentdeclaration) +- Single-line comments with a `@var` tag should be written as one-liners. [*](ruleset.md#slevomatcodingstandardcommentingrequireonelinepropertydoccomment) +- Shorthand scalar typehint variants must be used in docblocks. [*](ruleset.md#slevomatcodingstandardtypehintslongtypehints) + +## Declare Statements, Namespace, and Import Statements + +In addition to [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md#3-declare-statements-namespace-and-import-statements): + +- Each PHP file should have a page level docblock with `@see`, `@copyright` and `@license`. The copyright date should + only be adjusted if the file has changed. +- Each PHP file should have a strict type declaration at the top after the page level docblock. [*](ruleset.md#slevomatcodingstandardtypehintsdeclarestricttypes) +- Import statements should be alphabetically sorted. [*](ruleset.md#slevomatcodingstandardnamespacesalphabeticallysorteduses) +- Import statements should not be grouped. [*](ruleset.md#slevomatcodingstandardnamespacesdisallowgroupuse) +- Each import statement should be on its own line. [*](ruleset.md#slevomatcodingstandardnamespacesmultipleusesperline) +- Absolute class name references, functions and constants should be imported. [*](ruleset.md#slevomatcodingstandardnamespacesreferenceusednamesonly) +- Unused import statements are not allowed. [*](ruleset.md#slevomatcodingstandardnamespacesunuseduses) +- Classes and function within the same namespace should not be imported. [*](ruleset.md#slevomatcodingstandardnamespacesusefromsamenamespace) +- Imports should not have an alias with the same name. [*](ruleset.md#slevomatcodingstandardnamespacesuselessalias) +- A class should not have unused private constants, (or write-only) properties and methods. [*](ruleset.md#slevomatcodingstandardclassesunusedprivateelements) + +```php + $value) { + // foreach body +} +``` + +### try, catch, finally + +- Catch blocks may be empty. [*](ruleset.md#genericcodeanalysisemptystatementdetectedcatch) +- Catch blocks must be reachable. [*](ruleset.md#slevomatcodingstandardexceptionsdeadcatch) +- Catch blocks must use `Throwable` instead of `Exception`. [*](ruleset.md#slevomatcodingstandardexceptionsreferencethrowableonly) + +```php + $c) { + $variable = $foo ? 'foo' : 'bar'; +} + +$var = 'foo'; +$aVeryLongName = 'bar'; +$function = function ($arg1, $arg2) {}; +``` + +## Closures + +In addition to [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md#7-closures): + +- Unused variables should not be passed to closures via `use`. [*](ruleset.md#slevomatcodingstandardfunctionsunusedinheritedvariablepassedtoclosure) + +```php +` should not have any spaces around it. [*](ruleset.md#squizwhitespaceobjectoperatorspacing) +- Semicolons should not have spaces before them. [*](ruleset.md#squizwhitespacesemicolonspacing) +- The code should not contain superfluous whitespaces. e.g. multiple empty lines, trailing spaces, etc. [*](ruleset.md#squizwhitespacesuperfluouswhitespace) diff --git a/docs/book/v2/index.md b/docs/book/v2/index.md new file mode 100644 index 00000000..97635fa6 --- /dev/null +++ b/docs/book/v2/index.md @@ -0,0 +1 @@ +# The coding standard ruleset for Zend Framework components diff --git a/docs/book/v2/intro.md b/docs/book/v2/intro.md new file mode 100644 index 00000000..7e19599f --- /dev/null +++ b/docs/book/v2/intro.md @@ -0,0 +1,136 @@ +# zend-coding-standard + +The coding standard ruleset for Zend Framework components. + +This specification extends and expands [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md), +the extended coding style guide and requires adherence to [PSR-1](https://www.php-fig.org/psr/psr-1), +the basic coding standard. These are minimal specifications and don't address all factors, including things like: + +- whitespace around operators +- alignment of array keys and operators +- alignment of object operations +- how to format multi-line conditionals +- what and what not to import, and how +- etc. + +Contributors have different coding styles and so do the maintainers. During code reviews there are regularly +discussions about spaces and alignments, where and when was said that a function needs to be imported. And +that's where this coding standard comes in: To have internal consistency in a component and between components. + +> Note: PSR-12 is not finalized. e.g. The `!` operator and `:` placement for return values are still under discussion. +We will change these rules, and, when PSR-12 is finalized, adapt them. + +## Installation + +1. Install the module via composer by running: + + ```bash + $ composer require --dev zendframework/zend-coding-standard + ``` + +2. Add composer scripts into your `composer.json`: + + ```json + "scripts": { + "cs-check": "phpcs", + "cs-fix": "phpcbf" + } + ``` + +3. Create file `phpcs.xml` on base path of your repository with this content: + + ```xml + + + + + + + + + + + + + + config + src + test + + + + + ``` + +You can add or exclude some locations in that file. +For a reference please see: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml + +## Usage + +* To run checks only: + + ```bash + $ composer cs-check + ``` + +* To automatically fix many CS issues: + + ```bash + $ composer cs-fix + ``` + +## Ignoring parts of a File + +> Note: Before PHP_CodeSniffer version 3.2.0, `// @codingStandardsIgnoreStart` and `// @codingStandardsIgnoreEnd` were +> used. These are deprecated and will be removed in PHP_CodeSniffer version 4.0. + +Disable parts of a file: +```php +$xmlPackage = new XMLPackage; +// phpcs:disable +$xmlPackage['error_code'] = get_default_error_code_value(); +$xmlPackage->send(); +// phpcs:enable +``` + +Disable a specific rule: +```php +// phpcs:disable Generic.Commenting.Todo.Found +$xmlPackage = new XMLPackage; +$xmlPackage['error_code'] = get_default_error_code_value(); +// TODO: Add an error message here. +$xmlPackage->send(); +// phpcs:enable +``` + +## Development + +> **New rules or Sniffs may not be introduced in minor or bugfix releases and should always be based on the develop +branch and queued for the next major release, unless considered a bugfix for existing rules.** + +If you want to test changes against ZendFramework components or your own projects, install your forked +zend-coding-standard globally with composer: +```bash +$ composer global config repositories.zend-coding-standard vcs git@github.com:/zend-coding-standard.git +$ composer global require --dev zendframework/zend-coding-standard:dev- + +# For this to work, add this to your path: ~/.composer/vendor/bin +# Using `-s` prints the rules that triggered the errors so they can be reviewed easily. `-p` is for progress display. +$ phpcs -sp --standard=ZendCodingStandard src test +``` +Make sure you remove the global installation after testing from your global composer.json file!!! + +Documentation can be previewed locally by installing [MkDocs](https://www.mkdocs.org/#installation) and run +`mkdocs serve`. This will start a server where you can read the docs. + +## Reference + +Rules can be added, excluded or tweaked locally, depending on your preferences. More information on how to do this can +be found here: + +- [Coding Standard Tutorial](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial) +- [Configuration Options](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options) +- [Selectively Applying Rules](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-Ruleset#selectively-applying-rules) +- [Customisable Sniff Properties](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Customisable-Sniff-Properties) +- [Slevomat Coding Standard](https://github.com/slevomat/coding-standard) diff --git a/docs/book/v2/ruleset.md b/docs/book/v2/ruleset.md new file mode 100644 index 00000000..b470c39e --- /dev/null +++ b/docs/book/v2/ruleset.md @@ -0,0 +1,1170 @@ +# Ruleset + +## PSR2 +Use PSR-2 coding standard as a base + +### PSR2.ControlStructures.ElseIfDeclaration.NotAllowed +_PSR-12:_ The keyword `elseif` should be used instead of `else if` so that all control keywords look like single words. + + + +## Generic + +### Generic.Arrays.ArrayIndent +All values in multiline arrays must be indented with 4 spaces. + +### Generic.Arrays.DisallowLongArraySyntax +Short array syntax must be used to define arrays. + +```php + 'bar']; +``` + +### Generic.PHP.BacktickOperator +The backtick operator may not be used for execution of shell commands. + +*Invalid: Using the backtick operator.* +```php + 0; $i--) { + echo 'hello'; +} +``` + +*Invalid:* +```php +doSomethingElse(); + } +} +``` + +*Invalid: An overriding method that only calls the parent.* +```php +some string here +Beginning content +` tags or the short-echo `` tags; it must not use the other tag +variations. + +### Generic.PHP.ForbiddenFunctions +PHP functions which are an alias may not be used. _This can't be fixed automatically and need to be done manually._ + +| Alias | Replace with | +| ------------ | ---------------- | +| chop | rtrim | +| close | closedir | +| compact | | +| delete | unset | +| doubleval | floatval | +| extract | | +| fputs | fwrite | +| ini_alter | ini_set | +| is_integer | is_int | +| is_long | is_int | +| is_null | null === | +| is_real | is_float | +| is_writeable | is_writable | +| join | implode | +| key_exists | array_key_exists | +| pos | current | +| settype | | +| show_source | highlight_file | +| sizeof | count | +| strchr | strstr | + +### Generic.PHP.LowerCaseType +_PSR-12:_ Any new types and keywords added to future PHP versions must be in lower case. + +### Generic.PHP.SAPIUsage +The `PHP_SAPI` constant must be used instead of the `php_sapi_name()` function. + +*Valid: PHP_SAPI is used.* +```php +get(); + } +} +``` + +### SlevomatCodingStandard.Commenting.RequireOneLinePropertyDocComment +Single-line comments with a `@var` tag should be written as one-liners. + +*Valid: One-line comment* +```php +a >>= 2; +$this->$$parameter ^= 10; +$this->{'a'} += 10; +``` + +### SlevomatCodingStandard.PHP.ShortList +Short list syntax `[...]` should be used instead of `list(...)`. + +*Valid: The short list syntax is used for array destructuring assignment.* +```php + $a, 'b' => $b, 'c' => $c] = $array; +``` + +*Invalid: Usage of `list`.* +```php + $a, 'b' => $b, 'c' => $c) = $array; +``` + +### SlevomatCodingStandard.PHP.TypeCast +_PSR-12:_ Short form of type keywords must be used. i.e. `bool` instead of `boolean`, `int` instead of `integer`, etc. + +The `binary` and `unset` cast operators are not allowed. + +### SlevomatCodingStandard.TypeHints.DeclareStrictTypes +Each PHP file should have a strict type declaration at the top after the page level docblock. + +_PSR-12:_ Declare statements MUST contain no spaces and MUST be exactly `declare(strict_types=1)`. + +```php + true, + 'debug' => false, + 'zend-expressive' => [ + 'raise_throwables' => true, + 'programmatic_pipeline' => true, + 'error_handler' => [ + 'template_404' => 'error::404', + 'template_error' => 'error::error', + ], + ], +]; +``` + +*Invalid: Double arrow symbols are not aligned.* +```php + true, + 'debug' => false, + 'zend-expressive' => [ + 'raise_throwables' => true, + 'programmatic_pipeline' => true, + 'error_handler' => [ + 'template_404' => 'error::404', + 'template_error' => 'error::error', + ], + ], +]; +``` + +### Squiz.Classes.ClassFileName +_PSR-4:_ The class name must correspond to a file name ending in .php. The file name MUST match the case of the +terminating class name. + +### Squiz.Classes.SelfMemberReference +The `self` keyword should be used instead of the current class name, and should not have spaces around `::`. + +*Valid:* +```php +` to access static variables.* +```php +$staticMember; + } +} +``` + +### Squiz.Strings.ConcatenationSpacing +Force whitespace before and after concatenation + +### Squiz.Strings.DoubleQuoteUsage +#### Squiz.Strings.DoubleQuoteUsage.ContainsVar +Double quote strings may only be used if they contain variables. SQL queries containing single quotes are an exception +to the rule. + +*Valid: Double quote strings are only used when it contains a variable.* +```php +` should not have any spaces around it. + +*Valid: No spaces around the object operator.* +```php +bar(); +``` + +*Invalid: Whitespace surrounding the object operator.* +```php + bar(); +``` + +### Squiz.WhiteSpace.ObjectOperatorSpacing +There should be one space before and after an operators. + +*Valid: One space around the operator.* +```php + + + The coding standard for ZendCodingStandard itself. + + + + + + + + src + + + diff --git a/ruleset.xml b/ruleset.xml deleted file mode 100644 index 2e2536e0..00000000 --- a/ruleset.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - Zend Framework Coding Standard - - - - - - - - - - - - - - - - - - - - diff --git a/src/ZendCodingStandard/ruleset.xml b/src/ZendCodingStandard/ruleset.xml new file mode 100644 index 00000000..43dd2702 --- /dev/null +++ b/src/ZendCodingStandard/ruleset.xml @@ -0,0 +1,371 @@ + + + The ZendFramework coding standard. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + error + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Variable "%s" not allowed in double quoted string; use sprintf() or concatenation instead + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + diff --git a/test/expected-report.txt b/test/expected-report.txt new file mode 100644 index 00000000..84d85f92 --- /dev/null +++ b/test/expected-report.txt @@ -0,0 +1,38 @@ + +PHP CODE SNIFFER REPORT SUMMARY +---------------------------------------------------------------------- +FILE ERRORS WARNINGS +---------------------------------------------------------------------- +test/fixable/anonymous-classes.php 9 0 +test/fixable/array-indentation.php 39 1 +test/fixable/class-name-resolution.php 12 0 +test/fixable/closures.php 19 0 +test/fixable/commenting.php 17 0 +test/fixable/concatenation-spacing.php 15 0 +test/fixable/example-class.php 28 0 +test/fixable/extends-and-implements-multiline.php 10 0 +test/fixable/extends-and-implements.php 5 0 +test/fixable/forbidden-comments.php 4 0 +test/fixable/forbidden-functions.php 6 0 +test/fixable/LowCaseTypes.php 2 0 +test/fixable/method-and-function-arguments.php 11 0 +test/fixable/method-and-function-calls.php 13 0 +test/fixable/namespaces-spacing.php 3 0 +test/fixable/new-with-parentheses.php 18 0 +test/fixable/not-spacing.php 7 0 +test/fixable/operators.php 7 0 +test/fixable/return-type-on-methods.php 17 0 +test/fixable/semicolon-spacing.php 3 0 +test/fixable/statement-alignment.php 18 0 +test/fixable/test-case.php 4 0 +test/fixable/traits-uses.php 10 0 +test/fixable/UnusedVariables.php 1 0 +test/fixable/useless-semicolon.php 2 0 +test/fixable/visibility-declaration.php 1 0 +---------------------------------------------------------------------- +A TOTAL OF 281 ERRORS AND 1 WARNING WERE FOUND IN 26 FILES +---------------------------------------------------------------------- +PHPCBF CAN FIX 249 OF THESE SNIFF VIOLATIONS AUTOMATICALLY +---------------------------------------------------------------------- + + diff --git a/test/fixable/LowCaseTypes.php b/test/fixable/LowCaseTypes.php new file mode 100644 index 00000000..41f8803b --- /dev/null +++ b/test/fixable/LowCaseTypes.php @@ -0,0 +1,18 @@ + 1, + 'bar' => 2, + 'baz' => 3, +]; + +$singleLine = [ + 1 => 2, +]; +$singleLine2 = [ 'foo' => 'bar' ] ; + +$serializedRequest = [ + 'method' => 'POST', + 'request_target' => '/foo/bar?baz=bat', + 'uri' => 'http://example.com/foo/bar?baz=bat', + 'protocol_version' => '1.1', + 'headers' => [ + 'Host' => ['example.com'], + 'Accept' => ['application/json'], + 'X-Foo-Bar' => [ + 'Baz', + 'Bat', + ], + ], + + 'body' => '{"test":"value"}', +]; + +// https://github.com/zendframework/zend-diactoros/blob/69dc20275fb8b9f7f8e05d556f6c0da5f36cac64/test/ServerRequestFactoryTest.php#L392-L398 +$files = [ 'files' => [ + 'tmp_name' => 'php://temp', + 'size' => 0, + 'error' => 0, + 'name' => 'foo.bar', + 'type' => 'text/plain', +]]; + +// Long lines test +$config = [ + 'dependencies' => [ + 'factories' => [ + App\Domain\User\UserRepository::class => App\Domain\User\Persistence\DoctrineUserRepositoryFactory::class, + App\Http\Auth\LoginHandler::class => App\Http\Auth\LoginHandlerFactory::class, + App\Http\Auth\LogoutHandler::class => App\Http\Auth\LogoutHandlerFactory::class, + + App\Infrastructure\View\TemplateDefaultsMiddleware::class + => App\Infrastructure\View\TemplateDefaultsMiddlewareFactory::class, + App\Http\HomePageHandler::class => App\Http\HomePageHandlerFactory::class, + App\Http\StaticPageHandler::class => App\Http\StaticPageHandlerFactory::class, + ], + ], +]; diff --git a/test/fixable/class-name-resolution.php b/test/fixable/class-name-resolution.php new file mode 100644 index 00000000..5d228873 --- /dev/null +++ b/test/fixable/class-name-resolution.php @@ -0,0 +1,40 @@ +foo = $foo; + $this->bar = $bar; + $this->baz = $baz; + $this->baxBax = $baxBax; + } + + /** + * Description + */ + public function getFoo(): ? int + { + return $this->foo; + } + + /** + * @return iterable + */ + public function getIterator():array + { + assert($this->bar !== null); + return new \ArrayIterator($this->bar); + } + + public function isBaz() : bool + { + list($foo, $bar, $baz) = $this->bar; + + return $this->baz; + } + + public function mangleBar(int $length) : void + { + if (!$this->baz) { + throw new \InvalidArgumentException(); + } + + $this->bar = (string) $this->baxBax ?? \substr($this->bar, stringLength($this->bar - $length)); + } + + public static function getMinorVersion() : int + { + $version = self::VERSION; + + return $version; + } + + public static function getTestCase() : TestCase + { + return new TestCase(); + } +} diff --git a/test/fixable/extends-and-implements-multiline.php b/test/fixable/extends-and-implements-multiline.php new file mode 100644 index 00000000..fa85e018 --- /dev/null +++ b/test/fixable/extends-and-implements-multiline.php @@ -0,0 +1,20 @@ + 1, + 'bar' => 2, + 'baz' => 3, +]; +extract($bar); + +compact('foo', 'bar'); diff --git a/test/fixable/method-and-function-arguments.php b/test/fixable/method-and-function-arguments.php new file mode 100644 index 00000000..31ff340f --- /dev/null +++ b/test/fixable/method-and-function-arguments.php @@ -0,0 +1,38 @@ +bar ( $arg1 ); +Foo::bar ($arg2 , $arg3) ; + +$foo->bar( + $longArgument, + $longerArgument, + $muchLongerArgument +); + +somefunction($foo, $bar, [ + // ... +], $baz); + +$app->get ('/hello/{name}' , function ($name) use ($app) { + + return 'Hello ' . $app->escape($name); + +}); diff --git a/test/fixable/namespaces-spacing.php b/test/fixable/namespaces-spacing.php new file mode 100644 index 00000000..430900ad --- /dev/null +++ b/test/fixable/namespaces-spacing.php @@ -0,0 +1,18 @@ +sub(new DateInterval('P1D')) + ->format(DATE_RFC3339) +); diff --git a/test/fixable/new-with-parentheses.php b/test/fixable/new-with-parentheses.php new file mode 100644 index 00000000..5bdcbb0e --- /dev/null +++ b/test/fixable/new-with-parentheses.php @@ -0,0 +1,34 @@ +foo = 'Foo'; +$foo = new $classNamesInObject->foo; + +$whitespaceBetweenClassNameAndParentheses = new stdClass ; + +$x = [ + new stdClass, +]; + +$y = [new stdClass]; + +$z = new stdClass ? new stdClass : new stdClass; + +$q = $q ?: new stdClass; +$e = $e ?? new stdClass; + +// The parentheses around `(new Response())` should not be removed +// https://github.com/slevomat/coding-standard/issues/478 +$response = (new Response()) + ->withStatus(200) + ->withAddedHeader('Content-Type', 'text/plain'); diff --git a/test/fixable/not-spacing.php b/test/fixable/not-spacing.php new file mode 100644 index 00000000..d172d8b3 --- /dev/null +++ b/test/fixable/not-spacing.php @@ -0,0 +1,21 @@ + 0) { + echo 1; +} elseif ( !$test === 0) { + echo 0; +} else { + echo 2; +} + +while ( ! true) { + echo 1; +} + +do { + echo 1; +} while ( ! true); diff --git a/test/fixable/operators.php b/test/fixable/operators.php new file mode 100644 index 00000000..10758ba9 --- /dev/null +++ b/test/fixable/operators.php @@ -0,0 +1,33 @@ + $b) { + $variable = $foo ? 'foo' : 'bar'; +} + +$foo = isset($_GET['foo']) ? $_GET['foo'] : 'foo'; + +$bar = isset($bar) ? $bar : 'bar'; + +$bar = isset($bar['baz']) ? $bar['baz'] : 'baz'; + +if (isset($foo)) { + $bar = $foo; +} else { + $bar = 'foo'; +} + +$fooBar = isset($foo, $bar) ? 'foo' : 'bar'; + +$baz = ! isset($foo) ? 'foo' : 'baz'; diff --git a/test/fixable/return-type-on-methods.php b/test/fixable/return-type-on-methods.php new file mode 100644 index 00000000..58bdb665 --- /dev/null +++ b/test/fixable/return-type-on-methods.php @@ -0,0 +1,73 @@ +select() + ->from() + ->where() +; diff --git a/test/fixable/statement-alignment.php b/test/fixable/statement-alignment.php new file mode 100644 index 00000000..14f5a601 --- /dev/null +++ b/test/fixable/statement-alignment.php @@ -0,0 +1,16 @@ + 1, + 'bar' => 2, + 'baz' => 3, +]; + +$singleLine = [ + 1 => 2, +]; +$singleLine2 = ['foo' => 'bar']; + +$serializedRequest = [ + 'method' => 'POST', + 'request_target' => '/foo/bar?baz=bat', + 'uri' => 'http://example.com/foo/bar?baz=bat', + 'protocol_version' => '1.1', + 'headers' => [ + 'Host' => ['example.com'], + 'Accept' => ['application/json'], + 'X-Foo-Bar' => [ + 'Baz', + 'Bat', + ], + ], + + 'body' => '{"test":"value"}', +]; + +// https://github.com/zendframework/zend-diactoros/blob/69dc20275fb8b9f7f8e05d556f6c0da5f36cac64/test/ServerRequestFactoryTest.php#L392-L398 +$files = [ + 'files' => [ + 'tmp_name' => 'php://temp', + 'size' => 0, + 'error' => 0, + 'name' => 'foo.bar', + 'type' => 'text/plain', + ], +]; + +// Long lines test +$config = [ + 'dependencies' => [ + 'factories' => [ + App\Domain\User\UserRepository::class => App\Domain\User\Persistence\DoctrineUserRepositoryFactory::class, + App\Http\Auth\LoginHandler::class => App\Http\Auth\LoginHandlerFactory::class, + App\Http\Auth\LogoutHandler::class => App\Http\Auth\LogoutHandlerFactory::class, + + App\Infrastructure\View\TemplateDefaultsMiddleware::class + => App\Infrastructure\View\TemplateDefaultsMiddlewareFactory::class, + App\Http\HomePageHandler::class => App\Http\HomePageHandlerFactory::class, + App\Http\StaticPageHandler::class => App\Http\StaticPageHandlerFactory::class, + ], + ], +]; diff --git a/test/fixed/class-name-resolution.php b/test/fixed/class-name-resolution.php new file mode 100644 index 00000000..0ffdd44b --- /dev/null +++ b/test/fixed/class-name-resolution.php @@ -0,0 +1,40 @@ +foo = $foo; + $this->bar = $bar; + $this->baz = $baz; + $this->baxBax = $baxBax; + } + + /** + * Description + */ + public function getFoo() : ?int + { + return $this->foo; + } + + /** + * @return iterable + */ + public function getIterator() : array + { + assert($this->bar !== null); + return new ArrayIterator($this->bar); + } + + public function isBaz() : bool + { + [$foo, $bar, $baz] = $this->bar; + + return $this->baz; + } + + public function mangleBar(int $length) : void + { + if (! $this->baz) { + throw new InvalidArgumentException(); + } + + $this->bar = (string) $this->baxBax ?? substr($this->bar, stringLength($this->bar - $length)); + } + + public static function getMinorVersion() : int + { + return self::VERSION; + } + + public static function getTestCase() : TestCase + { + return new TestCase(); + } +} diff --git a/test/fixed/extends-and-implements-multiline.php b/test/fixed/extends-and-implements-multiline.php new file mode 100644 index 00000000..7de04ad8 --- /dev/null +++ b/test/fixed/extends-and-implements-multiline.php @@ -0,0 +1,18 @@ + 1, + 'bar' => 2, + 'baz' => 3, +]; +extract($bar); + +compact('foo', 'bar'); diff --git a/test/fixed/method-and-function-arguments.php b/test/fixed/method-and-function-arguments.php new file mode 100644 index 00000000..c2d6ac79 --- /dev/null +++ b/test/fixed/method-and-function-arguments.php @@ -0,0 +1,38 @@ +bar($arg1); +Foo::bar($arg2, $arg3); + +$foo->bar( + $longArgument, + $longerArgument, + $muchLongerArgument +); + +somefunction($foo, $bar, [ + // ... +], $baz); + +$app->get('/hello/{name}', function ($name) use ($app) { + return 'Hello ' . $app->escape($name); +}); diff --git a/test/fixed/namespaces-spacing.php b/test/fixed/namespaces-spacing.php new file mode 100644 index 00000000..d42bbfef --- /dev/null +++ b/test/fixed/namespaces-spacing.php @@ -0,0 +1,20 @@ +sub(new DateInterval('P1D')) + ->format(DATE_RFC3339) +); diff --git a/test/fixed/new-with-parentheses.php b/test/fixed/new-with-parentheses.php new file mode 100644 index 00000000..4684f85c --- /dev/null +++ b/test/fixed/new-with-parentheses.php @@ -0,0 +1,34 @@ +foo = 'Foo'; +$foo = new $classNamesInObject->foo(); + +$whitespaceBetweenClassNameAndParentheses = new stdClass(); + +$x = [ + new stdClass(), +]; + +$y = [new stdClass()]; + +$z = new stdClass() ? new stdClass() : new stdClass(); + +$q = $q ?: new stdClass(); +$e = $e ?? new stdClass(); + +// The parentheses around `(new Response())` should not be removed +// https://github.com/slevomat/coding-standard/issues/478 +$response = (new Response()) + ->withStatus(200) + ->withAddedHeader('Content-Type', 'text/plain'); diff --git a/test/fixed/not-spacing.php b/test/fixed/not-spacing.php new file mode 100644 index 00000000..b0942488 --- /dev/null +++ b/test/fixed/not-spacing.php @@ -0,0 +1,21 @@ + 0) { + echo 1; +} elseif (! $test === 0) { + echo 0; +} else { + echo 2; +} + +while (! true) { + echo 1; +} + +do { + echo 1; +} while (! true); diff --git a/test/fixed/operators.php b/test/fixed/operators.php new file mode 100644 index 00000000..6addab0b --- /dev/null +++ b/test/fixed/operators.php @@ -0,0 +1,33 @@ + $b) { + $variable = $foo ? 'foo' : 'bar'; +} + +$foo = $_GET['foo'] ?? 'foo'; + +$bar = $bar ?? 'bar'; + +$bar = $bar['baz'] ?? 'baz'; + +if (isset($foo)) { + $bar = $foo; +} else { + $bar = 'foo'; +} + +$fooBar = isset($foo, $bar) ? 'foo' : 'bar'; + +$baz = ! isset($foo) ? 'foo' : 'baz'; diff --git a/test/fixed/return-type-on-methods.php b/test/fixed/return-type-on-methods.php new file mode 100644 index 00000000..67c377fa --- /dev/null +++ b/test/fixed/return-type-on-methods.php @@ -0,0 +1,73 @@ +select() + ->from() + ->where(); diff --git a/test/fixed/statement-alignment.php b/test/fixed/statement-alignment.php new file mode 100644 index 00000000..018efa9e --- /dev/null +++ b/test/fixed/statement-alignment.php @@ -0,0 +1,16 @@ +