diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..0b98694 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: Lansoweb diff --git a/.github/ISSUE_TEMPLATE/Bug_Report.md b/.github/ISSUE_TEMPLATE/Bug_Report.md new file mode 100644 index 0000000..1d003a7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_Report.md @@ -0,0 +1,35 @@ +--- +name: Bug Report +about: Create a bug report to help us improve +labels: bug +assignees: +--- + + +## Description + + +## Steps to reproduce + +1. Step one... +2. Step two... +3. Step three... + +## Expected behavior + + +## Screenshots or output + + +## Environment details + +- version of this package: *e.g. 1.0.0, 1.0.1, 1.1.0* +- PHP version: *e.g. 7.3.16, 7.4.4* +- OS: *e.g. Windows 10, Linux (Ubuntu 18.04.1), macOS Catalina (10.15.3)* + +## Additional context + diff --git a/.github/ISSUE_TEMPLATE/Feature_Request.md b/.github/ISSUE_TEMPLATE/Feature_Request.md new file mode 100644 index 0000000..fdde4b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_Request.md @@ -0,0 +1,31 @@ +--- +name: Feature Request +about: Suggest a feature for this project +labels: enhancement +assignees: +--- + + + +## My feature title + + +## Background/problem + + +## Proposal/solution + + +## Alternatives + + +## Additional context + diff --git a/.github/ISSUE_TEMPLATE/Question.md b/.github/ISSUE_TEMPLATE/Question.md new file mode 100644 index 0000000..5c76b2a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Question.md @@ -0,0 +1,19 @@ +--- +name: Question +about: Ask a question about how to use this library +labels: question +assignees: +--- + + + +## How do I... ? + + +## Example code + diff --git a/.github/PULL_REQUEST_TEMPLATE/Pull_Request_Template.md b/.github/PULL_REQUEST_TEMPLATE/Pull_Request_Template.md new file mode 100644 index 0000000..df4646c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/Pull_Request_Template.md @@ -0,0 +1,30 @@ + + +## Description + + +## Motivation and context + + + +## How has this been tested? + + + + +## Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## PR checklist + + +- [ ] My code follows the code style of this project. +- [ ] My change requires a change to the documentation. +- [ ] I have updated the documentation accordingly. +- [ ] I have read the **CONTRIBUTING** document. +- [ ] I have added tests to cover my changes. +- [ ] All new and existing tests passed. +- [ ] I have run `composer test` locally, and there were no failures or errors. diff --git a/.github/workflows/coding-standard.yml b/.github/workflows/coding-standard.yml new file mode 100644 index 0000000..4d504e2 --- /dev/null +++ b/.github/workflows/coding-standard.yml @@ -0,0 +1,45 @@ +name: "Check Coding Standards" + +on: + pull_request: + push: + branches: + - "master" + +jobs: + coding-standards: + name: "Check Coding Standards" + + runs-on: ${{ matrix.operating-system }} + + strategy: + matrix: + dependencies: + - "highest" + php-version: + - "8.2" + operating-system: + - "ubuntu-latest" + + steps: + - name: "Checkout" + uses: "actions/checkout@v3" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2 + + - uses: "ramsey/composer-install@v1" + with: + dependency-versions: "${{ matrix.dependencies }}" + composer-options: "${{ matrix.composer-options }}" + + - name: "phpcs" + run: "vendor/bin/phpcs" + + - name: "phpstan" + run: "vendor/bin/phpstan analyze" diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml new file mode 100644 index 0000000..c7613e4 --- /dev/null +++ b/.github/workflows/release-on-milestone-closed.yml @@ -0,0 +1,65 @@ +name: "Automatic Releases" + +on: + milestone: + types: + - "closed" + +jobs: + release: + name: "GIT tag, release & create merge-up PR" + runs-on: ubuntu-latest + + steps: + - name: "Checkout" + uses: "actions/checkout@v3" + + - name: "Release" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:release" + env: + "GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create Merge-Up Pull Request" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:create-merge-up-pull-request" + env: + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create and/or Switch to new Release Branch" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor" + env: + "GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Bump Changelog Version On Originating Release Branch" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:bump-changelog" + env: + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} + + - name: "Create new milestones" + uses: "laminas/automatic-releases@v1" + with: + command-name: "laminas:automatic-releases:create-milestones" + env: + "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} + "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} + "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} + "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} diff --git a/.gitignore b/.gitignore index 69e0fc9..a2fe4a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ vendor composer.lock clover.xml -build +/build +/.phpunit.result.cache diff --git a/composer.json b/composer.json index ef60b77..b4e4150 100644 --- a/composer.json +++ b/composer.json @@ -11,18 +11,17 @@ } ], "require": { - "php": "^7.4 | ^8.0", - "ext-json": "*", - "psr/http-message": "^1.0" + "php": "^8.1", + "psr/http-message": "^1.0 || ^2.0" }, "require-dev": { "laminas/laminas-db": "^2.9", - "squizlabs/php_codesniffer": "^3.6", - "phpstan/phpstan": "^0.12.85", - "phpunit/phpunit": "^9.5", - "laminas/laminas-diactoros": "^2.0", - "php-coveralls/php-coveralls": "^2.0", - "doctrine/coding-standard": "^9.0" + "squizlabs/php_codesniffer": "^3.7", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.3", + "laminas/laminas-diactoros": "^3.2", + "php-coveralls/php-coveralls": "^2.6", + "doctrine/coding-standard": "^12.0" }, "autoload": { "psr-4": { @@ -42,9 +41,14 @@ ], "cs-check": "phpcs -s", "cs-fix": "phpcbf", - "phpstan": "phpstan analyse -l max src", + "phpstan": "phpstan analyse", "test": "phpunit --colors=always", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", "upload-coverage": "coveralls -v" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..5c84d78 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,24 @@ + + + + Project coding standards + + + + + + ./src + + + + + + + + + + + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..4004964 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,9 @@ +parameters: + level: max + tmpDir: ./build/cache/phpstan + checkMissingIterableValueType: false + paths: + - ./src + ignoreErrors: + - '#mixed#' + - '#on a separate line does not do anything#' diff --git a/src/BuilderInterface.php b/src/BuilderInterface.php index 615e596..90bebf9 100644 --- a/src/BuilderInterface.php +++ b/src/BuilderInterface.php @@ -60,8 +60,6 @@ interface BuilderInterface */ public function fromRequest(ServerRequestInterface $request); - /** - * @return Select|array - */ + /** @return Select|array */ public function fromParams(array $query, array $hint = []); } diff --git a/src/ElasticSearchBuilder.php b/src/ElasticSearchBuilder.php index 79ba6a5..82f1a18 100644 --- a/src/ElasticSearchBuilder.php +++ b/src/ElasticSearchBuilder.php @@ -7,8 +7,10 @@ use Psr\Http\Message\ServerRequestInterface; use function array_merge; +use function assert; use function in_array; use function is_array; +use function is_string; use function json_decode; use function key; use function reset; @@ -16,14 +18,10 @@ final class ElasticSearchBuilder implements BuilderInterface { - private string $queryName; - private string $hintName; private array $params = []; - public function __construct(string $queryName = 'q', string $hintName = 'h') + public function __construct(private string $queryName = 'q', private string $hintName = 'h') { - $this->queryName = $queryName; - $this->hintName = $hintName; } public function fromRequest(ServerRequestInterface $request): array @@ -109,6 +107,8 @@ private function parseQuery(string $key, $value, bool $withoutOperator = false): $opValue = reset($value); $op = key($value); + assert(is_string($op)); + if (in_array($op, BuilderInterface::OP_LOGIC)) { return $this->parseLogic($key, $op, $opValue); } diff --git a/src/Exception/MalformedException.php b/src/Exception/MalformedException.php index 40e9b5a..00c276b 100644 --- a/src/Exception/MalformedException.php +++ b/src/Exception/MalformedException.php @@ -6,9 +6,7 @@ use RuntimeException; -/** - * @phpcs:disable SlevomatCodingStandard.Classes.SuperfluousExceptionNaming.SuperfluousSuffix - */ +/** @phpcs:disable SlevomatCodingStandard.Classes.SuperfluousExceptionNaming.SuperfluousSuffix */ class MalformedException extends RuntimeException { } diff --git a/src/ZendDbBuilder.php b/src/LaminasDbBuilder.php similarity index 90% rename from src/ZendDbBuilder.php rename to src/LaminasDbBuilder.php index 6adf3e1..e8d58ee 100644 --- a/src/ZendDbBuilder.php +++ b/src/LaminasDbBuilder.php @@ -10,23 +10,21 @@ use Laminas\Db\Sql\Select; use Psr\Http\Message\ServerRequestInterface; +use function assert; use function in_array; use function is_array; +use function is_string; use function json_decode; use function key; use function reset; -final class ZendDbBuilder implements BuilderInterface +final class LaminasDbBuilder implements BuilderInterface { - private string $queryName; - private string $hintName; private Select $select; - public function __construct(Select $select, string $queryName = 'q', string $hintName = 'h') + public function __construct(Select $select, private string $queryName = 'q', private string $hintName = 'h') { - $this->queryName = $queryName; - $this->hintName = $hintName; - $this->select = clone $select; + $this->select = clone $select; } public function fromRequest(ServerRequestInterface $request): Select @@ -111,6 +109,8 @@ private function parseQuery(string $key, $value, Predicate $where): void $opValue = reset($value); $op = key($value); + assert(is_string($op)); + if (in_array($op, BuilderInterface::OP_LOGIC)) { $this->parseLogic($key, $op, $opValue, $where); @@ -124,7 +124,7 @@ private function parseQuery(string $key, $value, Predicate $where): void } } - private function parseLogic(string $key, string $op, $value, Predicate $where): void + private function parseLogic(string $key, string $op, mixed $value, Predicate $where): void { if ($op === BuilderInterface::OP_NOT) { $where->notEqualTo($key, $value); @@ -148,7 +148,7 @@ private function parseLogic(string $key, string $op, $value, Predicate $where): $where->like($key, $value); } - private function parseConditional(string $key, string $op, $value, Predicate $where): void + private function parseConditional(string $key, string $op, mixed $value, Predicate $where): void { if ($op === BuilderInterface::OP_GREATER) { $where->greaterThan($key, $value); @@ -178,7 +178,7 @@ private function parseConditional(string $key, string $op, $value, Predicate $wh $where->between($key, $value[0], $value[1]); } - private function parseHint(string $key, $value, Select $select): void + private function parseHint(string $key, mixed $value, Select $select): void { if ($key === BuilderInterface::HINT_SORT) { if (! is_array($value)) { diff --git a/test/ZendDbBuilderTest.php b/test/LaminasDbBuilderTest.php similarity index 97% rename from test/ZendDbBuilderTest.php rename to test/LaminasDbBuilderTest.php index 09bfd02..2d3d76b 100644 --- a/test/ZendDbBuilderTest.php +++ b/test/LaminasDbBuilderTest.php @@ -4,20 +4,20 @@ namespace Los\UqlTests; use Los\Uql\Exception\MalformedException; -use Los\Uql\ZendDbBuilder; +use Los\Uql\LaminasDbBuilder; use Los\UqlTests\TestAssets\TrustingSql92Platform; use PHPUnit\Framework\TestCase; use Laminas\Db\Sql\Select; use Laminas\Diactoros\ServerRequest; -class ZendDbBuilderTest extends TestCase +class LaminasDbBuilderTest extends TestCase { - /** @var ZendDbBuilder */ + /** @var LaminasDbBuilder */ private $builder; - protected function setUp() + protected function setUp(): void { - $this->builder = new ZendDbBuilder(new Select('test')); + $this->builder = new LaminasDbBuilder(new Select('test')); } public function testFromRequestWithInvalidQuery()