Skip to content

Integrate php cs fixer into quantum starter project#178

Merged
armanist merged 4 commits intosoftberg:masterfrom
armanist:177-Integrate-PHP-CS-Fixer-into-Quantum-Starter-Project
Apr 2, 2026
Merged

Integrate php cs fixer into quantum starter project#178
armanist merged 4 commits intosoftberg:masterfrom
armanist:177-Integrate-PHP-CS-Fixer-into-Quantum-Starter-Project

Conversation

@armanist
Copy link
Copy Markdown
Member

@armanist armanist commented Apr 2, 2026

Closes #177

Summary by CodeRabbit

  • Chores

    • Added automated code-style checks to CI and a project style config.
    • Standardized code formatting and updated ignore rules across the repository.
  • Bug Fixes

    • Improved URL language routing behavior.
    • Enhanced test helper utilities and test formatting for more reliable test runs.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5fd6033f-3d61-4f11-9172-59b207d050c2

📥 Commits

Reviewing files that changed from the base of the PR and between 749f639 and 634de96.

📒 Files selected for processing (3)
  • .gitignore
  • .php-cs-fixer.php
  • shared/config/modules.php
💤 Files with no reviewable changes (1)
  • shared/config/modules.php
✅ Files skipped from review due to trivial changes (2)
  • .gitignore
  • .php-cs-fixer.php

📝 Walkthrough

Walkthrough

Adds PHP CS Fixer to the project (dev dependency + .php-cs-fixer.php), adds Composer scripts (cs:check, cs:fix), adds a CI step to run composer cs:check, deletes shared/config/modules.php, and applies wide-ranging non-functional formatting changes and a few constant visibility widenings across the codebase.

Changes

Cohort / File(s) Summary
CI / Coding tools
​.github/workflows/php.yml, composer.json, .php-cs-fixer.php, .gitignore
Added CI step to run composer cs:check; added friendsofphp/php-cs-fixer dev dependency, PHP platform constraint, Composer scripts cs:check/cs:fix; added PHP-CS-Fixer config; updated .gitignore to ignore CS/cache and generated assets.
Configuration files
shared/config/*, tests/_root/shared/config/*, shared/config/modules.php
Normalized array formatting, trailing commas, single-quoted env() usage, EOF newlines; notably removed shared/config/modules.php (deleted).
Helpers & bootstrap
helpers/functions.php, tests/_root/helpers/functions.php, public/index.php, tests/bootstrap.php
Adjusted url_with_lang() regex replacements/spacing, added filesystem creation/.gitkeep in test helper, changed constant DS define to block form, and minor bootstrap formatting changes.
Visibility changes
shared/Enums/Role.php, shared/Commands/DemoCommand.php, shared/Commands/PostShowCommand.php, tests/Unit/shared/Services/PostServiceTest.php
Widened several class constants to public const (roles, default password, posts/page and test constants).
Codebase formatting edits
shared/Commands/*, shared/DTOs/*, shared/Models/*, shared/Services/*, shared/Transformers/*, many tests/* files
Large set of non-functional formatting changes: trailing newlines, trailing commas, spacing in casts, blank-line removals, indentation normalization; no logic changes except helper filesystem behavior noted above.
Language/resource files
shared/resources/lang/*, tests/_root/shared/resources/lang/*
Added/ensured EOF newlines only; no content changes.
Tests
tests/Feature/*, tests/Unit/*, tests/_root/*
Formatting and whitespace normalization, some array trailing commas, minor test helper behavior change (filesystem .gitkeep creation).

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Repo as Repository (push)
    participant GH as GitHub Actions
    participant Composer as Composer
    participant Fixer as PHP-CS-Fixer

    Dev->>Repo: push branch
    Repo->>GH: trigger php.yml workflow
    GH->>Composer: composer install
    Composer->>Fixer: run vendor/bin/php-cs-fixer check (via script cs:check)
    Fixer-->>GH: return pass/fail
    alt fail
        GH-->>Dev: CI fails (style errors)
    else pass
        GH-->>Dev: CI passes
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

help wanted

Suggested reviewers

  • Arno2005
  • Vahram1995
  • andrey-smaelov

Poem

🐰 Hopping through files with a tidy fix,
I add commas, trim the mix,
CI hums as styles align,
Code looks neat and tests still shine,
A little rabbit clap — formatting bliss! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main objective: integrating PHP CS Fixer into the Quantum starter project, matching the primary change throughout the changeset.
Linked Issues check ✅ Passed The pull request successfully addresses the core requirements from issue #177: PHP CS Fixer is installed as a dev dependency, a .php-cs-fixer.php configuration file is created, Composer scripts (cs:check and cs:fix) are added, and the entire codebase is formatted accordingly.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing PHP CS Fixer integration. Extensive code formatting changes align with the stated objective of applying the tool to the codebase, and the removal of modules.php configuration follows naturally from the formatting scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@armanist armanist added this to the 3.0.0 milestone Apr 2, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
tests/Helpers/functions.php (1)

68-74: Consider failing fast when directory/file creation fails.

mkdir() and file_put_contents() can fail silently here, which can make later test failures harder to diagnose.

Suggested hardening
-    if (!is_dir(uploads_dir())) {
-        mkdir(uploads_dir(), 0777, true);
-    }
+    if (!is_dir(uploads_dir()) && !mkdir(uploads_dir(), 0777, true) && !is_dir(uploads_dir())) {
+        throw new RuntimeException('Failed to create uploads directory: ' . uploads_dir());
+    }

-    if (!file_exists(uploads_dir() . DS . '.gitkeep')) {
-        file_put_contents(uploads_dir() . DS . '.gitkeep', '');
-    }
+    if (!file_exists(uploads_dir() . DS . '.gitkeep') && file_put_contents(uploads_dir() . DS . '.gitkeep', '') === false) {
+        throw new RuntimeException('Failed to create .gitkeep in uploads directory');
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Helpers/functions.php` around lines 68 - 74, The current setup in
tests/Helpers/functions.php uses mkdir() and file_put_contents() without
checking their return values, so if uploads_dir() creation or writing the
'.gitkeep' file fails the tests will continue with a hidden failure; update the
block that checks is_dir(uploads_dir()) and file_exists(uploads_dir() . DS .
'.gitkeep') to validate the return values of mkdir() and file_put_contents() and
throw or trigger a failure (e.g., throw RuntimeException or call the test
framework's fail) when either returns false, including the uploads_dir() path in
the error message so failures are immediate and actionable.
composer.json (1)

8-8: PHP version constraint doesn't cover all CI-tested versions.

The constraint ^7.4 || ^8.0 covers PHP 7.4, 8.0, and all 8.x versions. However, it's worth confirming this matches your CI matrix (which tests 7.4, 8.0, 8.1). The constraint is technically correct since ^8.0 includes 8.1, but consider using ^7.4 || ^8.0 || ^8.1 for explicit clarity, or simply >=7.4 if you intend to support all future PHP versions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@composer.json` at line 8, Update the PHP platform constraint in composer.json
(the "php" version requirement) so it explicitly matches the CI-tested matrix;
replace the current value "^7.4 || ^8.0" with either "^7.4 || ^8.0 || ^8.1" for
clarity or use ">=7.4" if you intend to support all future PHP releases—edit the
"php" field accordingly in composer.json (the string key "php") to reflect the
chosen constraint.
helpers/functions.php (1)

37-38: Minor inconsistency: preg_quote() delimiter usage.

Line 38 correctly adds the '/' delimiter argument to preg_quote(), but line 37's preg_match() still uses preg_quote(current_lang()) without it. While unlikely to cause issues (language codes typically don't contain /), consider adding the delimiter argument consistently for defensive coding.

-    if (preg_match('/' . preg_quote(current_lang()) . '/', route_uri())) {
+    if (preg_match('/' . preg_quote(current_lang(), '/') . '/', route_uri())) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@helpers/functions.php` around lines 37 - 38, In the preg_match call inside
the function (using preg_match('/' . preg_quote(current_lang()) . '/',
route_uri())), make preg_quote usage consistent by passing the delimiter as the
second argument (i.e., preg_quote(current_lang(), '/')), so update the
preg_match to use preg_quote(current_lang(), '/') to match the style used in the
subsequent preg_replace and avoid delimiter-related edge cases; locate and
modify the preg_match line in helpers/functions.php accordingly.
shared/Commands/DemoCommand.php (1)

375-383: Guard against empty candidate set before array_rand.

Line 382 can fail when $candidates is empty. Add a defensive check to avoid runtime errors in edge cases.

Defensive fix
     private function getRandomUserExcept(array $users, string $excludeUuid): array
     {
         $candidates = array_filter($users, function ($u) use ($excludeUuid) {
             return $u['uuid'] !== $excludeUuid;
         });

         $candidates = array_values($candidates);
+        if (empty($candidates)) {
+            throw new \RuntimeException('No eligible users found for comment generation.');
+        }
         return $candidates[array_rand($candidates)];
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shared/Commands/DemoCommand.php` around lines 375 - 383, The
getRandomUserExcept function can call array_rand on an empty $candidates array;
add a defensive guard after building $candidates in getRandomUserExcept(array
$users, string $excludeUuid): array — if count($candidates) === 0 then throw a
clear exception (e.g., InvalidArgumentException or RuntimeException) with a
message like "no candidate users available after excluding {uuid}" (or
alternatively return a sensible default if caller expects that), otherwise
proceed to array_values and array_rand as before; ensure the thrown exception
matches the project's error handling conventions.
tests/Unit/shared/Services/PostServiceTest.php (1)

17-19: Prefer non-public constant visibility in this test class.

Line 17 and Line 19 expose constants publicly without a clear need. Keeping them internal avoids accidental coupling to test internals.

Proposed tweak
-    public const PER_PAGE = 10;
-    public const CURRENT_PAGE = 1;
+    private const PER_PAGE = 10;
+    private const CURRENT_PAGE = 1;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Unit/shared/Services/PostServiceTest.php` around lines 17 - 19, Change
the two public constants in the PostServiceTest class (PER_PAGE and
CURRENT_PAGE) to non-public visibility (e.g., private const PER_PAGE = 10;
private const CURRENT_PAGE = 1;) and update any internal references inside
PostServiceTest to use self::PER_PAGE and self::CURRENT_PAGE instead of external
class accessors so the constants remain internal to the test implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/php.yml:
- Around line 45-47: The workflow runs the composer script cs:check but the
repository lacks a php-cs-fixer config file, so add a project-specific
configuration file named .php-cs-fixer.php (or .php-cs-fixer.dist.php) that
configures PSR-12 as the baseline, enables strict types
(declare(strict_types=1)), enforces short_array_syntax, ordered_imports and
no_unused_imports rules (and any other project rules like line
endings/whitespace) so php-cs-fixer uses these preferences instead of defaults;
update or confirm the composer cs:check script will use that config when
invoked.

In `@shared/config/modules.php`:
- Around line 3-12: This change introduces behavior by enabling 'Api' and 'Web'
modules (keys 'Api' and 'Web' with 'prefix' and 'enabled'), which breaks the "no
functional changes" rule; revert the file to the prior no-op config (e.g.,
return an empty array) or otherwise remove/disable the 'Api' and 'Web' entries
so no modules are implicitly enabled by this PR, leaving a neutral/default
configuration.

---

Nitpick comments:
In `@composer.json`:
- Line 8: Update the PHP platform constraint in composer.json (the "php" version
requirement) so it explicitly matches the CI-tested matrix; replace the current
value "^7.4 || ^8.0" with either "^7.4 || ^8.0 || ^8.1" for clarity or use
">=7.4" if you intend to support all future PHP releases—edit the "php" field
accordingly in composer.json (the string key "php") to reflect the chosen
constraint.

In `@helpers/functions.php`:
- Around line 37-38: In the preg_match call inside the function (using
preg_match('/' . preg_quote(current_lang()) . '/', route_uri())), make
preg_quote usage consistent by passing the delimiter as the second argument
(i.e., preg_quote(current_lang(), '/')), so update the preg_match to use
preg_quote(current_lang(), '/') to match the style used in the subsequent
preg_replace and avoid delimiter-related edge cases; locate and modify the
preg_match line in helpers/functions.php accordingly.

In `@shared/Commands/DemoCommand.php`:
- Around line 375-383: The getRandomUserExcept function can call array_rand on
an empty $candidates array; add a defensive guard after building $candidates in
getRandomUserExcept(array $users, string $excludeUuid): array — if
count($candidates) === 0 then throw a clear exception (e.g.,
InvalidArgumentException or RuntimeException) with a message like "no candidate
users available after excluding {uuid}" (or alternatively return a sensible
default if caller expects that), otherwise proceed to array_values and
array_rand as before; ensure the thrown exception matches the project's error
handling conventions.

In `@tests/Helpers/functions.php`:
- Around line 68-74: The current setup in tests/Helpers/functions.php uses
mkdir() and file_put_contents() without checking their return values, so if
uploads_dir() creation or writing the '.gitkeep' file fails the tests will
continue with a hidden failure; update the block that checks
is_dir(uploads_dir()) and file_exists(uploads_dir() . DS . '.gitkeep') to
validate the return values of mkdir() and file_put_contents() and throw or
trigger a failure (e.g., throw RuntimeException or call the test framework's
fail) when either returns false, including the uploads_dir() path in the error
message so failures are immediate and actionable.

In `@tests/Unit/shared/Services/PostServiceTest.php`:
- Around line 17-19: Change the two public constants in the PostServiceTest
class (PER_PAGE and CURRENT_PAGE) to non-public visibility (e.g., private const
PER_PAGE = 10; private const CURRENT_PAGE = 1;) and update any internal
references inside PostServiceTest to use self::PER_PAGE and self::CURRENT_PAGE
instead of external class accessors so the constants remain internal to the test
implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c1171d01-e9a1-4054-b878-50b9b00054f1

📥 Commits

Reviewing files that changed from the base of the PR and between 0192922 and 749f639.

📒 Files selected for processing (68)
  • .github/workflows/php.yml
  • composer.json
  • helpers/functions.php
  • migrations/create_table_comments_1698145440.php
  • migrations/create_table_posts_1669639752.php
  • migrations/create_table_users_1669639740.php
  • public/index.php
  • shared/Commands/CommandValidationTrait.php
  • shared/Commands/CommentCreateCommand.php
  • shared/Commands/CommentDeleteCommand.php
  • shared/Commands/DemoCommand.php
  • shared/Commands/PostCreateCommand.php
  • shared/Commands/PostDeleteCommand.php
  • shared/Commands/PostShowCommand.php
  • shared/Commands/PostUpdateCommand.php
  • shared/Commands/UserCreateCommand.php
  • shared/Commands/UserDeleteCommand.php
  • shared/Commands/UserShowCommand.php
  • shared/DTOs/CommentDTO.php
  • shared/Enums/Role.php
  • shared/Models/Comment.php
  • shared/Models/Post.php
  • shared/Models/User.php
  • shared/Services/AuthService.php
  • shared/Services/CommentService.php
  • shared/Services/PostService.php
  • shared/Transformers/PostTransformer.php
  • shared/config/cache.php
  • shared/config/captcha.php
  • shared/config/database.php
  • shared/config/dependencies.php
  • shared/config/env.php
  • shared/config/fs.php
  • shared/config/lang.php
  • shared/config/logging.php
  • shared/config/mailer.php
  • shared/config/modules.php
  • shared/config/session.php
  • shared/config/view.php
  • shared/config/view_cache.php
  • shared/resources/lang/en/common.php
  • shared/resources/lang/en/validation.php
  • shared/resources/lang/es/common.php
  • shared/resources/lang/es/validation.php
  • tests/Feature/AppTestCase.php
  • tests/Feature/modules/Api/AuthControllerTest.php
  • tests/Feature/modules/Api/CommentControllerTest.php
  • tests/Feature/modules/Api/PostControllerTest.php
  • tests/Feature/modules/Api/PostManagementControllerTest.php
  • tests/Helpers/functions.php
  • tests/Unit/shared/Services/AuthServiceTest.php
  • tests/Unit/shared/Services/CommentServiceTest.php
  • tests/Unit/shared/Services/PostServiceTest.php
  • tests/_root/helpers/functions.php
  • tests/_root/shared/config/app.php
  • tests/_root/shared/config/database.php
  • tests/_root/shared/config/dependencies.php
  • tests/_root/shared/config/env.php
  • tests/_root/shared/config/fs.php
  • tests/_root/shared/config/lang.php
  • tests/_root/shared/config/logging.php
  • tests/_root/shared/config/mailer.php
  • tests/_root/shared/config/view.php
  • tests/_root/shared/resources/lang/en/common.php
  • tests/_root/shared/resources/lang/en/validation.php
  • tests/_root/shared/resources/lang/es/common.php
  • tests/_root/shared/resources/lang/es/validation.php
  • tests/bootstrap.php
💤 Files with no reviewable changes (3)
  • migrations/create_table_users_1669639740.php
  • migrations/create_table_comments_1698145440.php
  • migrations/create_table_posts_1669639752.php

@armanist armanist merged commit 44c41b7 into softberg:master Apr 2, 2026
5 checks passed
@armanist armanist deleted the 177-Integrate-PHP-CS-Fixer-into-Quantum-Starter-Project branch April 2, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate PHP CS Fixer into Quantum Starter Project

1 participant