Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,27 @@ jobs:
- name: Run code analysis
run: |
docker compose exec -T phpfpm vendor/bin/phpstan analyse --no-progress

code-analysis-rector:
runs-on: ubuntu-latest
name: Rector
steps:
- uses: actions/checkout@v7

- name: Cache vendor
uses: actions/cache@v5
with:
path: vendor
key: vendor-php8.4-${{ hashFiles('composer.lock') }}
restore-keys: vendor-php8.4-

- name: Start docker compose setup and install site
run: |
docker network create frontend
docker compose pull --quiet
docker compose up --detach --wait
docker compose exec -T phpfpm composer install --no-interaction

- name: Check for Rector suggestions
run: |
docker compose exec -T phpfpm vendor/bin/rector process --dry-run --no-progress-bar
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ See [keep a changelog] for information about writing changes to this log.

## [Unreleased]

- [PR-54](https://github.com/itk-dev/event-database-api/pull/54)
Add Rector (relevant sets aligned with PHPStan), apply it across the codebase, and run it in CI
- [PR-53](https://github.com/itk-dev/event-database-api/pull/53)
Compare effective schemas in the oasdiff gate (flatten-allof) so allOf/$ref restructures are not miscounted
- [PR-52](https://github.com/itk-dev/event-database-api/pull/52)
Expand Down
17 changes: 17 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ tasks:
desc: "Run code analysis"
cmds:
- task: code-analysis:phpstan
- task: code-analysis:rector
silent: true

code-analysis:phpstan:
Expand All @@ -175,6 +176,22 @@ tasks:
COMPOSE_ARGS: exec phpfpm vendor/bin/phpstan
silent: true

code-analysis:rector:
desc: "Check for Rector suggestions (dry-run; no changes applied)"
cmds:
- task: compose
vars:
COMPOSE_ARGS: exec phpfpm vendor/bin/rector process --dry-run
silent: true

code-analysis:rector:apply:
desc: "Apply Rector changes"
cmds:
- task: compose
vars:
COMPOSE_ARGS: exec phpfpm vendor/bin/rector process
silent: true

api:test:
desc: Run API tests
cmds:
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"phpstan/phpstan-strict-rules": "^2.0",
"phpstan/phpstan-symfony": "^2.0",
"phpunit/phpunit": "^13",
"rector/rector": "^2.5",
"symfony/browser-kit": "~7.4.0",
"symfony/css-selector": "~7.4.0",
"symfony/maker-bundle": "^1.52",
Expand Down
62 changes: 61 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions public/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1780,21 +1780,21 @@ components:
-
type: object
properties:
slug:
type: string
name:
type: string
slug:
type: string
Vocabulary.jsonld:
allOf:
-
$ref: '#/components/schemas/HydraItemBaseSchema'
-
type: object
properties:
slug:
type: string
name:
type: string
slug:
type: string
description:
type: string
tags:
Expand Down
34 changes: 34 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;

return RectorConfig::configure()
->withPaths([
__DIR__.'/src',
__DIR__.'/tests',
])
->withCache(__DIR__.'/var/cache/rector')
// Coding style and import (`use`) management are owned by php-cs-fixer
// (PostToolUse hook / coding standards), so Rector does not touch them.
//
// Modernize to the language level declared in composer.json (PHP >= 8.3).
->withPhpSets()
// Version-based upgrade + quality rules resolved from the installed package
// versions (Symfony 7.4, PHPUnit 13). No domain Doctrine here — the entities
// and migrations live in event-database-imports — so the Doctrine sets are
// intentionally omitted.
->withComposerBased(symfony: true, phpunit: true)
// Convert any remaining annotations to native PHP attributes.
->withAttributesSets(symfony: true, phpunit: true)
->withPreparedSets(
deadCode: true,
codeQuality: true,
typeDeclarations: true,
privatization: true,
instanceOf: true,
earlyReturn: true,
symfonyCodeQuality: true,
phpunitCodeQuality: true,
);
2 changes: 2 additions & 0 deletions src/Api/Dto/DailyOccurrence.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down
2 changes: 2 additions & 0 deletions src/Api/Dto/Event.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down
2 changes: 2 additions & 0 deletions src/Api/Dto/Location.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down
2 changes: 2 additions & 0 deletions src/Api/Dto/Occurrence.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down
2 changes: 2 additions & 0 deletions src/Api/Dto/Organization.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down
16 changes: 7 additions & 9 deletions src/Api/Dto/Tag.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down Expand Up @@ -52,14 +54,10 @@
)]
readonly class Tag
{
#[ApiProperty(identifier: true)]
public string $slug;

public string $name;

public function __construct(string $name, string $slug)
{
$this->name = $name;
$this->slug = $slug;
public function __construct(
public string $name,
#[ApiProperty(identifier: true)]
public string $slug,
) {
}
}
28 changes: 11 additions & 17 deletions src/Api/Dto/Vocabulary.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Dto;

use ApiPlatform\Metadata\ApiFilter;
Expand Down Expand Up @@ -52,22 +54,14 @@
)]
readonly class Vocabulary
{
#[ApiProperty(
identifier: true,
)]
public string $slug;

public string $name;

public string $description;

public array $tags;

public function __construct(string $name, string $slug, string $description, array $tags)
{
$this->name = $name;
$this->slug = $slug;
$this->description = $description;
$this->tags = $tags;
public function __construct(
public string $name,
#[ApiProperty(
identifier: true,
)]
public string $slug,
public string $description,
public array $tags,
) {
}
}
16 changes: 13 additions & 3 deletions src/Api/Filter/ElasticSearch/BooleanFilter.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Api\Filter\ElasticSearch;

use ApiPlatform\Elasticsearch\Filter\AbstractFilter;
Expand All @@ -16,11 +18,19 @@ public function apply(array $clauseBody, string $resourceClass, ?Operation $oper

/** @var string $property */
foreach ($properties as $property) {
if (!isset($context['filters'][$property]) || '' === $context['filters'][$property] || [] === $context['filters'][$property]) {
if (!isset($context['filters'][$property])) {
// If no value or empty value is set, skip it.
continue;
}
if ('' === $context['filters'][$property]) {
// If no value or empty value is set, skip it.
continue;
}
if ([] === $context['filters'][$property]) {
// If no value or empty value is set, skip it.
continue;
}
$terms[$property] = explode(',', $context['filters'][$property]);
$terms[$property] = explode(',', (string) $context['filters'][$property]);
}

return [] === $terms ? $terms : ['terms' => $terms + ['boost' => 1.0]];
Expand All @@ -33,7 +43,7 @@ public function getDescription(string $resourceClass): array
}

$description = [];
foreach ($this->properties as $filterParameterName => $value) {
foreach (array_keys($this->properties) as $filterParameterName) {
$description[$filterParameterName] = [
'property' => $filterParameterName,
'type' => TypeIdentifier::BOOL->value,
Expand Down
6 changes: 3 additions & 3 deletions src/Api/Filter/ElasticSearch/DateRangeFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function apply(array $clauseBody, string $resourceClass, ?Operation $oper
return $ranges;
}

foreach ($this->properties as $property => $value) {
foreach (array_keys($this->properties) as $property) {
if (isset($context['filters'][$property]) && '' !== $context['filters'][$property] && [] !== $context['filters'][$property]) {
$ranges[] = $this->getElasticSearchQueryRanges($property, $context['filters'][$property]);
}
Expand Down Expand Up @@ -94,15 +94,15 @@ private function getElasticSearchQueryRanges(string $property, string|array $fil
$value = $filter;
} else {
$operator = $this->resolveOperator((string) array_key_first($filter), $throwOnInvalid);
if (null === $operator) {
if (!$operator instanceof DateLimit) {
return [];
}
$value = array_shift($filter);
}

switch ($operator) {
case DateLimit::between:
$values = explode('..', $value);
$values = explode('..', (string) $value);

if (2 !== count($values)) {
if ($throwOnInvalid) {
Expand Down
Loading