Skip to content

Commit 580dbf1

Browse files
authored
initial implementation (#1)
* v1 * use Configuration::setDefaultQueryHint() instead of trait * QueryCheckerTreeWalker: fix cs * QueryCheckerTreeWalker: support logging instead of throwing exception * lower required doctrine/dbal & doctrine/orm version * simplify exception message for a single compatible type * fix cs * add readme * move normalization out of getFieldCompatibleTypes * QueryCheckerTreeWalker: improve error message
1 parent 9b48e15 commit 580dbf1

21 files changed

+1718
-0
lines changed

.editorconfig

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[*]
2+
charset = utf-8
3+
end_of_line = lf
4+
trim_trailing_whitespace = true
5+
insert_final_newline = true
6+
indent_style = space
7+
indent_size = 4

.gitattributes

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
* text=auto
2+
3+
/.github export-ignore
4+
/cache export-ignore
5+
/tests export-ignore
6+
7+
/.editorconfig export-ignore
8+
/.gitattributes export-ignore
9+
/.gitignore export-ignore
10+
/phpcs.xml.dist export-ignore
11+
/phpstan.neon.dist export-ignore
12+
/phpunit.xml.dist export-ignore

.github/workflows/checks.yml

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Checks
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- "master"
7+
- "v[0-9]"
8+
jobs:
9+
checks:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
fail-fast: false
13+
steps:
14+
-
15+
name: Checkout code
16+
uses: actions/checkout@v4
17+
-
18+
name: Setup PHP
19+
uses: shivammathur/setup-php@v2
20+
with:
21+
php-version: 8.4
22+
-
23+
name: Install dependencies
24+
run: composer install --no-progress --prefer-dist --no-interaction
25+
26+
-
27+
name: Run checks
28+
run: composer check
29+
30+
tests:
31+
runs-on: ubuntu-latest
32+
strategy:
33+
fail-fast: false
34+
matrix:
35+
php-version: [ '8.1', '8.2', '8.3', '8.4' ]
36+
dependency-version: [ prefer-lowest, prefer-stable ]
37+
steps:
38+
-
39+
name: Checkout code
40+
uses: actions/checkout@v4
41+
-
42+
name: Setup PHP
43+
uses: shivammathur/setup-php@v2
44+
with:
45+
php-version: ${{ matrix.php-version }}
46+
-
47+
name: Install dependencies
48+
run: composer update --no-progress --${{ matrix.dependency-version }} --prefer-dist --no-interaction
49+
-
50+
name: Run tests
51+
run: composer check:tests

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/cache
2+
/vendor
3+
/phpstan.neon
4+
/composer.lock

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Bedabox, LLC dba ShipMonk
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Doctrine Query Checker
2+
3+
Doctrine Query Tree Walker that perform additional checks on the query AST in addition to the default checks performed by Doctrine.
4+
5+
Currently it checks that the types of the parameters passed to the query are correct. For example the following will result in exception:
6+
7+
```php
8+
// throws 'Parameter "created_at" is of type "string", but expected "datetime" (because it\'s used in expression with u.createdAt)'
9+
$this->entityManager->createQueryBuilder()
10+
->select('u')
11+
->from(User::class, 'u')
12+
->where('u.createdAt < :created_at')
13+
->setParameter('created_at', 'not a date')
14+
->getQuery()
15+
->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [QueryCheckerTreeWalker::class]);
16+
->getResult();
17+
```
18+
19+
If you want to log the exceptions instead of throwing them, you can pass a logger to the QueryCheckerTreeWalker:
20+
21+
```php
22+
QueryCheckerTreeWalker::setLogger($logger);
23+
```
24+
25+
## Installation
26+
27+
```bash
28+
composer require shipmonk/doctrine-query-checker
29+
```
30+
31+
## Enabling for a specific query
32+
33+
```php
34+
use Doctrine\ORM\Query;
35+
use ShipMonk\DoctrineQueryChecker\QueryCheckerTreeWalker;
36+
37+
$query = $this->entityManager->createQueryBuilder()
38+
->select('u')
39+
->from(User::class, 'u')
40+
->getQuery()
41+
->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [QueryCheckerTreeWalker::class]);
42+
```
43+
44+
## Enabling for all queries
45+
46+
```php
47+
use Doctrine\ORM\Query;
48+
use ShipMonk\DoctrineQueryChecker\QueryCheckerTreeWalker;
49+
50+
$this->entityManager->getConfiguration()
51+
->setDefaultQueryHint(Query::HINT_CUSTOM_TREE_WALKERS, [QueryCheckerTreeWalker::class]);
52+
```

cache/.gitkeep

Whitespace-only changes.

composer.json

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "shipmonk/doctrine-query-checker",
3+
"description": "Doctrine Query AST validator",
4+
"license": [
5+
"MIT"
6+
],
7+
"require": {
8+
"php": "^8.1",
9+
"doctrine/dbal": "^4.0",
10+
"doctrine/orm": "^3.0",
11+
"psr/log": "^1.0 || ^2.0 || ^3.0"
12+
},
13+
"require-dev": {
14+
"editorconfig-checker/editorconfig-checker": "^10.6.0",
15+
"ergebnis/composer-normalize": "^2.42.0",
16+
"nette/utils": "^4.0",
17+
"phpstan/phpstan": "^2.0",
18+
"phpstan/phpstan-phpunit": "^2.0",
19+
"phpstan/phpstan-strict-rules": "^2.0",
20+
"phpunit/phpunit": "^10.5",
21+
"ramsey/uuid": "^4.7.6",
22+
"ramsey/uuid-doctrine": "^2.1.0",
23+
"shipmonk/composer-dependency-analyser": "^1.8",
24+
"shipmonk/name-collision-detector": "^2.1",
25+
"shipmonk/phpstan-rules": "^4.1",
26+
"slevomat/coding-standard": "^8.15",
27+
"symfony/cache": "^6.4 || ^7.0"
28+
},
29+
"autoload": {
30+
"psr-4": {
31+
"ShipMonk\\DoctrineQueryChecker\\": "src/"
32+
}
33+
},
34+
"autoload-dev": {
35+
"psr-4": {
36+
"ShipMonkTests\\DoctrineQueryChecker\\": "tests/"
37+
}
38+
},
39+
"config": {
40+
"allow-plugins": {
41+
"dealerdirect/phpcodesniffer-composer-installer": true,
42+
"ergebnis/composer-normalize": true
43+
},
44+
"sort-packages": true
45+
},
46+
"scripts": {
47+
"check": [
48+
"@check:composer",
49+
"@check:ec",
50+
"@check:cs",
51+
"@check:types",
52+
"@check:tests",
53+
"@check:dependencies"
54+
],
55+
"check:composer": [
56+
"composer normalize --dry-run --no-check-lock --no-update-lock",
57+
"composer validate --strict"
58+
],
59+
"check:cs": "phpcs",
60+
"check:dependencies": "composer-dependency-analyser",
61+
"check:ec": "ec src tests",
62+
"check:tests": "phpunit tests",
63+
"check:types": "phpstan analyse -vvv",
64+
"fix:cs": "phpcbf"
65+
}
66+
}

0 commit comments

Comments
 (0)