-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat(docker): Add Apache
image for Debian Trixie.
#1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds repository configs (.editorconfig, .gitattributes, .gitignore, LICENSE) and GitHub meta (.github/*). Introduces multi-stage Apache/PHP Dockerfile and docker-compose with dev/prod/full stacks plus DB services. Adds Apache and PHP configs, Xdebug settings, and shell scripts for entrypoint, MSSQL, and Oracle driver installation. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant D as Docker Engine
participant DF as Dockerfile.apache
participant MS as install-mssql.sh
participant OR as install-oracle.sh
Dev->>D: docker build --build-arg BUILD_TYPE=dev|prod|full
D->>DF: Execute multi-stage build
activate DF
DF->>DF: base → builder → asset-builder
alt BUILD_TYPE == dev|full
DF->>DF: dev stage (tools, xdebug)
end
alt BUILD_TYPE == full
DF->>MS: Optional MSSQL drivers/extensions
DF->>OR: Optional Oracle client/extensions
end
alt BUILD_TYPE == prod
DF->>DF: prod stage (prod extensions)
end
DF->>DF: final stage FROM ${BUILD_TYPE}
deactivate DF
D-->>Dev: Emits final image
sequenceDiagram
autonumber
actor U as User
participant C as Container (Entrypoint)
participant A as Apache/PHP
participant APP as Yii2 App
participant DB as Databases (MySQL/PG/MSSQL/Oracle/Mongo/Redis)
U->>C: docker compose up
activate C
C->>C: Configure Apache/PHP, Xdebug, memory
C->>DB: wait_for_service(...) (conditional per env)
C->>APP: composer install (if needed)
alt RUN_MIGRATIONS == true and not test
C->>APP: yii migrate --interactive=0
end
C->>APP: Optional /web/health.php generation
C->>A: exec apache2 -DFOREGROUND
deactivate C
U->>A: HTTP requests (/)
A->>APP: Route to index.php (rewrites)
APP-->>DB: Query/Cache (as configured)
A-->>U: Response
U->>A: GET /health
A->>APP: health.php (if enabled)
APP-->>U: JSON status
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60–90 minutes Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
✨ Finishing Touches
🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
…ct, Funding, Issue and Pull Request templates, and Dependabot settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 46
🧹 Nitpick comments (87)
.github/FUNDING.yml (1)
4-4
: Remove stray trailing content.There appears to be an extra line containing just “4”. Clean it up to avoid YAML parsing noise.
-4 +.github/ISSUE_TEMPLATE.md (2)
10-14
: Tighten placeholders and make version guidance clearer.Use a concrete semver placeholder and nudge reporters to paste exact versions.
-| Version | 1.0.? -| PHP version | +| App/Template version | 1.x (exact: e.g., 1.2.3) +| PHP version | 8.x (exact: e.g., 8.3.9)
1-9
: Consider migrating to Issue Forms for structured input.GitHub Issue Forms (YAML) give required fields, dropdowns, and validation; fewer back-and-forths.
I can draft
bug_report.yml
andfeature_request.yml
under.github/ISSUE_TEMPLATE/
if you want.docker/configs/php/xdebug.ini (1)
4-8
: Improve cross-OS connectivity (Linux) and debuggability.
host.docker.internal
may not resolve on Linux. Enabling client discovery is a safe default for dev; also add an optional log path for faster troubleshooting.xdebug.client_host = host.docker.internal xdebug.client_port = 9003 xdebug.start_with_request = yes xdebug.idekey = PHPSTORM -xdebug.discover_client_host = 0 +xdebug.discover_client_host = 1 xdebug.log_level = 0 +; Uncomment for troubleshooting when log_level > 0 +; xdebug.log = /tmp/xdebug.logPlease verify this still aligns with any overrides done in your entrypoint or env vars.
.github/PULL_REQUEST_TEMPLATE.md (2)
1-6
: Use actual checkboxes and auto-close keywords.Checkboxes render better with
[ ]/[x]
, and using “Fixes #ID” auto-closes issues on merge.-| Q | A -| ------------- | --- -| Is bugfix? | ✔️/❌ -| New feature? | ✔️/❌ -| Breaks BC? | ✔️/❌ -| Fixed issues | <!-- comma-separated list of tickets # fixed by the PR, if any --> +| Q | A +| ------------- | --- +| Is bugfix? | [ ] Yes [ ] No +| New feature? | [ ] Yes [ ] No +| Breaks BC? | [ ] Yes [ ] No +| Fixes | <!-- e.g. Fixes #123, Closes #456 -->
1-6
: Add “How to test” and “Breaking changes” sections.Helps reviewers and downstream users when BC breaks are marked “Yes”.
| Breaks BC? | [ ] Yes [ ] No | Fixes | <!-- e.g. Fixes #123, Closes #456 --> + +## How to test +<!-- Steps, commands, sample env vars --> + +## Breaking changes +<!-- Migration notes, config changes, deprecations -->.github/dependabot.yml (2)
4-8
: Reduce noise and add metadata to updates.Optional tweaks: limit concurrent PRs and add labels to aid triage; schedule weekly to avoid churn.
- package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" + interval: "weekly" + open-pull-requests-limit: 5 + labels: ["dependencies"] + target-branch: "main"
10-14
: Composer updates: same quality-of-life improvements.Keep
increase-if-necessary
, add labeling/limits/explicit target branch.- package-ecosystem: "composer" directory: "/" schedule: - interval: "daily" + interval: "weekly" versioning-strategy: increase-if-necessary + open-pull-requests-limit: 5 + labels: ["dependencies", "composer"] + target-branch: "main".editorconfig (2)
20-21
: Add YAML extension alias (.yaml) to keep settings consistent.Many repos use both .yml and .yaml. Include both to avoid drift.
-[*.yml] -indent_size = 2 +[*.{yml,yaml}] +indent_size = 2
13-16
: JetBrains-specific keys are fine; consider scoping/commenting them.The ij_php_* options are IDE-specific. Add a short comment above to clarify for non-IntelliJ users.
LICENSE.md (1)
3-3
: Confirm copyright year range.If the project is active through 2025, consider “2008–2025” to reflect continuity.
.gitignore (2)
11-13
: Optional: ignore common local files.Add .DS_Store and .vscode to reduce noise.
# phpstorm project files .idea +.vscode +.DS_Store
20-21
: Minor wording nit: comment capitalization.Match style of other comments.
-#yii3 config packages +# Yii3 config packages.github/CODE_OF_CONDUCT.md (3)
5-6
: Tighten wording for clarity.Small grammar tweaks.
-As contributors and maintainers of this project, and in order to keep community open and welcoming, we ask to -respect all community members. +As contributors and maintainers of this project, to keep the community open and welcoming, we ask that you +respect all community members.
39-41
: Polish example phrasing.Improves readability.
- address, posting via an official social media account, within project GitHub, official forum or acting as an appointed + address, posting via an official social media account, on the project’s GitHub or official forum, or acting as an appointed
45-46
: Add a concrete reporting channel.Specify an email or URL for incident reports (e.g., abuse@example.org or a GitHub Security Advisory contact).
Share the preferred contact and I can amend the section.
docker/requirements/assets/css/app.css (3)
31-45
: Consider 100dvh for mobile browser chrome.100vh can be problematic on iOS; 100dvh adapts to dynamic viewport.
- height: 100vh; + height: 100dvh;
476-496
: Respect prefers-reduced-motion.Reduce animations for accessibility.
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .status-indicator, .requirement-item, .nav.flex-column .nav-link:hover { animation: none !important; transition: none !important; transform: none !important; } }
14-25
: Add a global border-box reset to avoid sizing surprises.Helps keep layout predictable with paddings/borders.
*, *::before, *::after { box-sizing: border-box; }.gitattributes (3)
14-14
: Ensure .bat scripts use CRLF to avoid breakage on WindowsGlobal
eol=lf
forces LF on checkout; override.bat
to CRLF.Apply:
-*.bat text +*.bat text eol=crlf
12-17
: Cover common text config extensionsAdd yaml/conf/ini/env to keep consistent EOL/filters.
*.xml text *.json text -*.bat text +*.bat text eol=crlf *.sql text *.yml text +*.yaml text +*.conf text +*.ini text +*.env text
18-23
: Broaden binary pinning for assetsPrevents diff/filters from mangling binaries.
*.png binary *.jpg binary +*.jpeg binary *.gif binary *.ttf binary +*.woff binary +*.woff2 binary +*.eot binary +*.ico binary +*.webp binary +*.pdf binarydocker/configs/apache/vhost.conf (6)
7-11
: Harden directory scope and disable .htaccess parsingUse
AllowOverride None
(perf/security) and addDirectoryIndex
.- <Directory /var/www/app/web> - Options -Indexes +FollowSymLinks - AllowOverride All + <Directory /var/www/app/web> + Options -Indexes -MultiViews +FollowSymLinks + AllowOverride None Require all granted + DirectoryIndex index.php
15-19
: Simplify trailing-slash redirect to avoid REQUEST_URI couplingCleaner and avoids edge-cases in Directory context.
- # Redirect trailing slashes if not a directory - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_URI} (.+)/$ - RewriteRule ^ %1 [L,R=301] + # Redirect trailing slashes if not a directory + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.+?)/$ $1 [R=301,L]
43-49
: Prefer Brotli when available; keep Deflate as fallbackBrotli provides better compression for text assets.
# Compression <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css AddOutputFilterByType DEFLATE text/javascript application/javascript application/json AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml </IfModule> + + <IfModule mod_brotli.c> + BrotliCompressionQuality 5 + AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css \ + application/javascript application/json application/xml image/svg+xml + </IfModule>
26-41
: Deny sensitive files inside DocumentRoot instead of out-of-root dirsApache won’t serve
/runtime
,/vendor
,/tests
,/config
outside the docroot. Deny common secrets within/web
instead.# Protect sensitive directories - <Directory /var/www/app/runtime> - Require all denied - </Directory> - - <Directory /var/www/app/vendor> - Require all denied - </Directory> - - <Directory /var/www/app/tests> - Require all denied - </Directory> - - <Directory /var/www/app/config> - Require all denied - </Directory> + <FilesMatch "(\.env|\.env\.[A-Za-z0-9_-]+|composer\.(json|lock)|package(-lock)?\.json|yarn\.lock)"> + Require all denied + </FilesMatch>Please confirm your app indeed serves only from
/var/www/app/web
; if you expose aliases/symlinks into parent paths, keep explicit denies.
68-73
: Replace deprecated X-XSS-Protection; add CSP and hide X-Powered-ByModern hardening without breaking defaults (tune CSP per app).
# Security headers <IfModule mod_headers.c> Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" - Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" + Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'" + Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()" + Header always set Cross-Origin-Opener-Policy "same-origin" + Header always set Cross-Origin-Resource-Policy "same-origin" + Header always unset X-Powered-By </IfModule>If you load assets from CDNs, extend CSP
script-src
/style-src
/img-src
accordingly.
3-6
: Add ServerName to avoid AH00558 warningsPrevents startup noise and ensures proper vhost matching.
<VirtualHost *:80> - ServerAdmin webmaster@localhost + ServerAdmin webmaster@localhost + ServerName localhostdocker/requirements/views/components/category-section.php (4)
9-10
: Guard against missing summary keys and clamp percentPrevents notices and keeps percent within 0–100.
-$summary = $category['summary']; -$successRate = $summary['total'] > 0 ? round(($summary['passed'] / $summary['total']) * 100, 1) : 0; +$summary = $category['summary'] ?? ['total' => 0, 'passed' => 0]; +$successRate = ($summary['total'] ?? 0) > 0 + ? min(100, round((($summary['passed'] ?? 0) / $summary['total']) * 100, 1)) + : 0;
29-29
: Add accessibility attributes to progress barImproves screen reader support.
- <div class="progress-bar bg-success" style="width: <?= $successRate ?>%"></div> + <div class="progress-bar bg-success" + role="progressbar" + aria-valuenow="<?= $successRate ?>" + aria-valuemin="0" + aria-valuemax="100" + style="width: <?= $successRate ?>%"></div>
114-114
: Escape status label textMinor hardening.
- <?= ucfirst($requirement['status']) ?> + <?= ViewRenderer::escape(ucfirst((string)($requirement['status'] ?? ''))) ?>
135-211
: Move inline styles to the shared CSS assetKeeps views lean and caches CSS effectively.
I can draft the corresponding rules in
docker/requirements/assets/css/app.css
and update the view to drop the<style>
block—say the word.docker/configs/php/prod.ini (4)
16-16
: Modernize error_reporting mask.
E_STRICT
is obsolete. Optionally exclude user deprecations.-error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +error_reporting = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED
30-31
: Samesite=Strict and cookie_secure=1 can block auth behind proxies.Strict can break OAuth/SSO;
cookie_secure=1
drops cookies if PHP doesn’t detect HTTPS behind a reverse proxy. Verify deployment headers (X-Forwarded-Proto) or adjust.-session.cookie_samesite = Strict +session.cookie_samesite = LaxIf staying Strict, ensure proxy HTTPS detection is correctly configured.
44-45
: Doc comments stripped may break libraries using annotations/reflection.Consider keeping comments unless you’re certain they’re unused.
-opcache.save_comments = 0 +opcache.save_comments = 1
47-49
: Nit: JIT note.JIT has existed since PHP 8.0; the comment “PHP 8.4+” is misleading.
-; JIT for PHP 8.4+ +; JIT (PHP 8+)docker/configs/php/dev.ini (1)
48-54
: Make Xdebug host resolution portable.On Linux,
host.docker.internal
may not resolve. Let Xdebug auto-detect.[xdebug] xdebug.client_host = host.docker.internal xdebug.client_port = 9003 xdebug.idekey = PHPSTORM xdebug.log_level = 0 xdebug.mode = debug,develop,coverage xdebug.start_with_request = yes +; auto-detect client on Linux +xdebug.discover_client_host = 1docker/configs/php/full.ini (1)
49-56
: Same portability tweak for Xdebug.[xdebug] xdebug.client_host = host.docker.internal xdebug.client_port = 9003 xdebug.idekey = PHPSTORM xdebug.log_level = 1 xdebug.mode = debug,develop,coverage,profile xdebug.output_dir = /tmp/xdebug xdebug.start_with_request = yes +; auto-detect client on Linux +xdebug.discover_client_host = 1docker/scripts/install-mssql.sh (2)
61-68
: Slim image: remove php-pear and curl after build.They’re not needed at runtime.
apt-get remove -y --purge \ gnupg \ apt-transport-https \ php${PHP_VER}-dev \ build-essential \ + php-pear \ + curl \
2-2
: Stricter shell options improve robustness.-set -e +set -Eeuo pipefaildocker/scripts/install-oracle.sh (3)
9-16
: Trim runtime by removing transient tools.
wget
/unzip
aren’t needed at runtime; uninstall after use.apt-get update && apt-get install -y --no-install-recommends \ libaio1t64 \ wget \ unzip \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*After extraction:
+apt-get remove -y --purge wget unzip && apt-get autoremove -y && apt-get clean
27-35
: Add checksum verification for Oracle downloads.Reduce supply-chain risk by validating ZIPs.
46-49
: LD_LIBRARY_PATH export only affects current shell.You already call
ldconfig
; the exports are unnecessary unless building immediately (you are). Keep, but consider dropping them after build to avoid polluting environment.docker/scripts/entrypoint.sh (2)
43-46
: Avoid accumulating duplicate ServerName entriesAppend only if not already present.
-if [ -n "$APACHE_SERVER_NAME" ]; then - echo "ServerName ${APACHE_SERVER_NAME}" >> /etc/apache2/apache2.conf +if [ -n "$APACHE_SERVER_NAME" ]; then + grep -qE "^\\s*ServerName\\s+${APACHE_SERVER_NAME}\\b" /etc/apache2/apache2.conf || \ + echo "ServerName ${APACHE_SERVER_NAME}" >> /etc/apache2/apache2.conf fi
54-73
: Xdebug sed may no-op if keys absent; guard file and append defaultsIf keys are missing, sed does nothing. Guard the ini file and append when needed.
-if [ "$BUILD_TYPE" = "dev" ] || [ "$BUILD_TYPE" = "full" ]; then +if [ "$BUILD_TYPE" = "dev" ] || [ "$BUILD_TYPE" = "full" ]; then if [ "$XDEBUG_ENABLED" = "true" ]; then echo -e "${YELLOW}Enabling Xdebug...${NC}" phpenmod xdebug - - # Update Xdebug settings if provided - if [ -n "$XDEBUG_HOST" ]; then - sed -i "s/xdebug.client_host.*/xdebug.client_host = ${XDEBUG_HOST}/g" /etc/php/${PHP_VERSION}/mods-available/xdebug.ini - fi + ini="/etc/php/${PHP_VERSION}/mods-available/xdebug.ini" + [ -f "$ini" ] || ini="/etc/php/${PHP_VERSION}/apache2/conf.d/20-xdebug.ini" + touch "$ini" + # Update Xdebug settings if provided (append if not present) + if [ -n "$XDEBUG_HOST" ]; then + grep -q '^xdebug.client_host' "$ini" && \ + sed -i "s|^xdebug.client_host.*|xdebug.client_host = ${XDEBUG_HOST}|" "$ini" || \ + echo "xdebug.client_host = ${XDEBUG_HOST}" >> "$ini" + fi if [ -n "$XDEBUG_PORT" ]; then - sed -i "s/xdebug.client_port.*/xdebug.client_port = ${XDEBUG_PORT}/g" /etc/php/${PHP_VERSION}/mods-available/xdebug.ini + grep -q '^xdebug.client_port' "$ini" && \ + sed -i "s|^xdebug.client_port.*|xdebug.client_port = ${XDEBUG_PORT}|" "$ini" || \ + echo "xdebug.client_port = ${XDEBUG_PORT}" >> "$ini" fi if [ -n "$XDEBUG_MODE" ]; then - sed -i "s/xdebug.mode.*/xdebug.mode = ${XDEBUG_MODE}/g" /etc/php/${PHP_VERSION}/mods-available/xdebug.ini + grep -q '^xdebug.mode' "$ini" && \ + sed -i "s|^xdebug.mode.*|xdebug.mode = ${XDEBUG_MODE}|" "$ini" || \ + echo "xdebug.mode = ${XDEBUG_MODE}" >> "$ini" fi elseAlso applies to: 60-68
docker/requirements/classes/ComponentHelper.php (2)
59-68
: getOverallStatus: avoid undefined index noticesUse null coalescing; cast to int.
- if ($summary['failed'] > 0 || $summary['errors'] > 0) { + $failed = (int)($summary['failed'] ?? 0); + $errors = (int)($summary['errors'] ?? 0); + $warnings = (int)($summary['warnings'] ?? 0); + if ($failed > 0 || $errors > 0) { return 'danger'; } - if ($summary['warnings'] > 0) { + if ($warnings > 0) { return 'warning'; } return 'success';
73-89
: getStatusMessage: avoid undefined index notices; minor grammar tweakCoalesce values; keep message stable.
- $total = $summary['total']; - $passed = $summary['passed']; - $warnings = $summary['warnings']; - $failed = $summary['failed']; + $total = (int)($summary['total'] ?? 0); + $passed = (int)($summary['passed'] ?? 0); + $warnings = (int)($summary['warnings'] ?? 0); + $failed = (int)($summary['failed'] ?? 0);docker/requirements/assets/js/app.js (3)
71-88
: Anchor selector likely mismatched
data-bs-spy="scroll"
is usually on the container, not links. If your links carry this attr intentionally, ignore; otherwise use a more typical selector.-document.querySelectorAll('a[data-bs-spy="scroll"]').forEach(link => { +document.querySelectorAll('a[href^="#"]').forEach(link => {
224-245
: Export: include app/version metadata and content-type hintOptional: enrich the export and set an explicit charset.
- const dataBlob = new Blob([dataStr], {type: 'application/json'}); + const dataBlob = new Blob([dataStr], {type: 'application/json;charset=utf-8'});Additionally, consider adding
{ app: 'yii2-requirements', version: window.appVersion || 'unknown' }
intoreportData
.
126-136
: Throttle frequency: consider 150–200ms to reduce work on low-end devicesMinor perf tweak; 100ms is fine, but 150–200ms is usually indistinguishable and cheaper.
- }, 100)); + }, 180));docker/requirements/classes/RequirementsChecker.php (7)
632-639
: Remove dead code: unused private evaluateExpression()This method is no longer used (you moved to direct boolean conditions). Keeping an eval-based helper around is unnecessary risk and noise.
- /** - * Evaluate PHP expression safely - */ - private function evaluateExpression(string $expression): bool - { - try { - return (bool) eval("return $expression;"); - } catch (Throwable $e) { - return false; - } - }
214-231
: Clarify JIT buffer metric naming (it reports total, not “used”)
$metrics['jit_buffer_used']
is set frombuffer_size
, which represents total JIT buffer size. Either rename tojit_buffer_total
(and optionally addjit_buffer_free
) or compute “used = total - free” if the free key is available.- if (isset($status['jit'])) { - $metrics['jit_buffer_used'] = isset($status['jit']['buffer_size']) - ? round($status['jit']['buffer_size'] / 1024 / 1024, 2) . ' MB' - : 'Unknown'; - $metrics['jit_compiled_funcs'] = $status['jit']['num_traces'] ?? 0; - } + if (isset($status['jit'])) { + if (isset($status['jit']['buffer_size'])) { + $metrics['jit_buffer_total'] = round($status['jit']['buffer_size'] / 1024 / 1024, 2) . ' MB'; + } + // If a "buffer_free" key exists, expose it (compute "used" if both present). + if (isset($status['jit']['buffer_free']) || isset($status['jit']['buffer_free_size'])) { + $free = ($status['jit']['buffer_free'] ?? $status['jit']['buffer_free_size']); + $metrics['jit_buffer_free'] = round($free / 1024 / 1024, 2) . ' MB'; + if (isset($status['jit']['buffer_size'])) { + $metrics['jit_buffer_used'] = round(($status['jit']['buffer_size'] - $free) / 1024 / 1024, 2) . ' MB'; + } + } + $metrics['jit_compiled_traces'] = $status['jit']['num_traces'] ?? 0; + }Please confirm the exact key names present in your PHP build (
opcache_get_status()['jit']
). Keys vary across versions.
568-574
: Normalize boolean ini values robustly
ini_get()
returns strings; handle “on/off/true/false/1/0” consistently.- $enabled = ini_get('opcache.enable'); - return $enabled === '1' || $enabled === 1 || $enabled === true; + $enabled = ini_get('opcache.enable'); + return filter_var($enabled, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false;
585-587
: Same boolean handling for CLI flag- $enabled = ini_get('opcache.enable_cli'); - return $enabled === '1' || $enabled === 1 || $enabled === true; + $enabled = ini_get('opcache.enable_cli'); + return filter_var($enabled, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false;
30-31
: Prefer PHP_SAPI over php_sapi_name()Minor simplification; avoids a function call.
- 'php_sapi' => php_sapi_name(), + 'php_sapi' => PHP_SAPI,
256-263
: Revisit “core” extensions list
unicode
isn’t a typical entry fromget_loaded_extensions()
on PHP 8.x. Consider adjusting baseline “core” set or deriving it dynamically to avoid misleading counts.
272-289
: Double‑check messaging vs. base image PHP versionThe requirement says “8.1.0 or higher” and the recommendation text mentions upgrading to 8.1. If your Debian Trixie image ships with PHP 8.2/8.3, update the copy to match.
docker/requirements/views/layouts/error.php (4)
5-7
: Broaden type to ThrowableErrors (TypeError, Error) won’t render details with the current
Exception
check. UseThrowable
in phpdoc and runtime checks.- * @var Exception $error + * @var Throwable $errorAnd below:
- <?php if (isset($error) && $error instanceof Exception): ?> + <?php if (isset($error) && $error instanceof Throwable): ?>
106-113
: Escape line number for consistency (minor)It’s an int, but for consistency with other fields you can escape/cast.
- <dd class="col-sm-8"><?= ViewRenderer::escape($error->getFile()) ?>:<?= $error->getLine() ?></dd> + <dd class="col-sm-8"><?= ViewRenderer::escape($error->getFile()) ?>:<?= ViewRenderer::escape((string)$error->getLine()) ?></dd>
16-18
: Optional: add Subresource Integrity (SRI) and crossorigin to CDN linksImproves supply‑chain safety when loading from CDNs.
78-81
: Optional: preserve existing query params when switching to JSONUsing
?format=json
drops any existing filters. Consider building the URL fromlocation.search
to retain params.docker/requirements/views/layout.php (1)
23-25
: Add SRI to CDN assetsAdd integrity/crossorigin to Bootstrap CSS/JS and Icons CDN links for supply-chain hardening.
Would you like me to add the correct SRI hashes for the pinned versions?
Also applies to: 79-83
docker/requirements/views/components/header.php (1)
69-74
: Add ARIA for progress segmentsImprove accessibility by setting
aria-label
,aria-valuenow/min/max
.- <div class="progress"> - <div class="progress-bar bg-success" style="width: <?php echo $successRate; ?>%"></div> - <div class="progress-bar bg-warning" style="width: <?php echo $warningRate; ?>%"></div> - <div class="progress-bar bg-danger" style="width: <?php echo $errorRate; ?>%"></div> - </div> + <div class="progress" role="progressbar" aria-label="Requirement status" aria-valuemin="0" aria-valuemax="100"> + <div class="progress-bar bg-success" style="width: <?= $successRate ?>%" aria-valuenow="<?= (int)$successRate ?>"></div> + <div class="progress-bar bg-warning" style="width: <?= $warningRate ?>%" aria-valuenow="<?= (int)$warningRate ?>"></div> + <div class="progress-bar bg-danger" style="width: <?= $errorRate ?>%" aria-valuenow="<?= (int)$errorRate ?>"></div> + </div>docker/requirements/views/components/system-info.php (1)
141-151
: Avoid instantiating the checker in a viewConsider moving byte-size parsing behind a helper (e.g.,
ComponentHelper::getByteSize()
) or pass precomputed values from the controller to keep view logic thin.I can refactor this by adding a helper and wiring precomputed memory-limit bytes into the view data.
docker/requirements/views/components/navigation.php (2)
43-53
: Remove misused ScrollSpy attributes on links
data-bs-spy="scroll"
belongs on the scroll container (e.g.,body
), not on anchor tags. These attributes here have no effect.- <a class="nav-link" href="#overview" data-bs-spy="scroll"> + <a class="nav-link" href="#overview"> @@ - <a class="nav-link" href="#system-info" data-bs-spy="scroll"> + <a class="nav-link" href="#system-info">
26-37
: Cast quick stats to intEnsure numeric output is safe and consistent.
- <span class="stat-number text-success"><?php echo $summary['passed']; ?></span> + <span class="stat-number text-success"><?= (int)($summary['passed'] ?? 0); ?></span> @@ - <span class="stat-number text-warning"><?php echo $summary['warnings']; ?></span> + <span class="stat-number text-warning"><?= (int)($summary['warnings'] ?? 0); ?></span> @@ - <span class="stat-number text-danger"><?php echo $summary['failed']; ?></span> + <span class="stat-number text-danger"><?= (int)($summary['failed'] ?? 0); ?></span>docker/requirements/index.php (2)
68-79
: Avoid leaking stack traces by defaultReturning full stack traces in production JSON can expose sensitive details. Gate it behind a
debug=1
flag or environment variable.- echo json_encode([ - 'error' => true, - 'message' => 'Requirements check failed: ' . $e->getMessage(), - 'timestamp' => date('c'), - 'trace' => $e->getTraceAsString() - ], JSON_PRETTY_PRINT); + $payload = [ + 'error' => true, + 'message' => 'Requirements check failed: ' . $e->getMessage(), + 'timestamp' => date('c'), + ]; + if (($_GET['debug'] ?? '') === '1') { + $payload['trace'] = $e->getTraceAsString(); + } + echo json_encode($payload, JSON_PRETTY_PRINT);
41-44
: Harden response headersAdd
X-Content-Type-Options: nosniff
and a conservativeReferrer-Policy
in both HTML and JSON responses.- header('Cache-Control: no-cache, must-revalidate'); + header('Cache-Control: no-cache, must-revalidate'); + header('X-Content-Type-Options: nosniff'); + header('Referrer-Policy: no-referrer'); @@ - header('Cache-Control: no-cache, must-revalidate'); + header('Cache-Control: no-cache, must-revalidate'); + header('X-Content-Type-Options: nosniff'); + header('Referrer-Policy: no-referrer');Also applies to: 33-39
docker/requirements/views/components/breadcrumbs.php (1)
35-44
: Wire Prev/Next controls or remove until implemented.These buttons are present but no handlers in this file; ensure they’re functional somewhere else or hide them to avoid UX dead ends.
I can add minimal handlers to traverse window.breadcrumbSections and update the DOM if desired.
docker/requirements/views/layouts/main.php (3)
21-21
: Guard against undefined indexes in $system.If build_type is missing, this will emit notices. Use null-coalescing with a sensible default.
-<title>Yii2 Requirements Checker - <?= ViewRenderer::escape(ucfirst($system['build_type'])) ?> Build</title> +<title>Yii2 Requirements Checker - <?= ViewRenderer::escape(ucfirst($system['build_type'] ?? 'unknown')) ?> Build</title> ... -<small><?= ViewRenderer::escape(ucfirst($system['build_type'])) ?> Build</small> +<small><?= ViewRenderer::escape(ucfirst($system['build_type'] ?? 'unknown')) ?> Build</small> ... -Build: <?= ViewRenderer::escape($system['build_type']) ?> +Build: <?= ViewRenderer::escape($system['build_type'] ?? 'unknown') ?>Also applies to: 282-282, 376-376
405-420
: Limit “active” class updates to the sidebar nav to avoid clobbering other anchors.Current code adds active to any hash link (e.g., breadcrumbs), leaving the sidebar without an active item.
- document.querySelectorAll('a[href^="#"]').forEach(link => { + document.querySelectorAll('a[href^="#"]').forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const target = document.querySelector(link.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); - - // Update active nav - document.querySelectorAll('.nav-link').forEach(navLink => { - navLink.classList.remove('active'); - }); - link.classList.add('active'); + // Update active state only for sidebar nav links + if (link.matches('.sidebar .nav .nav-link')) { + document.querySelectorAll('.sidebar .nav .nav-link').forEach(navLink => { + navLink.classList.remove('active'); + }); + link.classList.add('active'); + } } }); });
445-473
: Make mobile sidebar responsive to viewport changes.Mobile overlay/toggle is only initialized on first load if window.innerWidth <= 991. Handle resize via matchMedia to avoid stale UI when rotating or resizing.
docker/requirements/views/components/summary-cards.php (2)
96-100
: Add progressbar ARIA attributes for accessibility.Expose roles and values so assistive tech can interpret the progress breakdown.
- <div class="progress mb-2" style="height: 8px;"> - <div class="progress-bar bg-success" style="width: <?= $successRate ?>%"></div> - <div class="progress-bar bg-warning" style="width: <?= $summary['total'] > 0 ? round(($summary['warnings'] / $summary['total']) * 100, 1) : 0 ?>%"></div> - <div class="progress-bar bg-danger" style="width: <?= $summary['total'] > 0 ? round(($summary['failed'] / $summary['total']) * 100, 1) : 0 ?>%"></div> - </div> + <div class="progress mb-2" style="height: 8px;"> + <div class="progress-bar bg-success" role="progressbar" aria-label="Passed" + style="width: <?= $successRate ?>%" aria-valuenow="<?= $successRate ?>" aria-valuemin="0" aria-valuemax="100"></div> + <?php $warn = $summary['total'] > 0 ? round(($summary['warnings'] / $summary['total']) * 100, 1) : 0; ?> + <div class="progress-bar bg-warning" role="progressbar" aria-label="Warnings" + style="width: <?= $warn ?>%" aria-valuenow="<?= $warn ?>" aria-valuemin="0" aria-valuemax="100"></div> + <?php $fail = $summary['total'] > 0 ? round(($summary['failed'] / $summary['total']) * 100, 1) : 0; ?> + <div class="progress-bar bg-danger" role="progressbar" aria-label="Failed" + style="width: <?= $fail ?>%" aria-valuenow="<?= $fail ?>" aria-valuemin="0" aria-valuemax="100"></div> + </div>
7-7
: Guard against missing keys in $summary.If any of total/passed are absent, notices occur. Optional: normalize $summary with defaults before computing $successRate.
docker/requirements/views/partials/status-alert.php (1)
141-147
: Make highlight re-triggerable on repeated clicks.Clear the animation style after it ends; otherwise subsequent clicks may not highlight.
Apply:
function scrollToFirstError() { const firstError = document.querySelector('.requirement-item.failed'); if (firstError) { firstError.scrollIntoView({ behavior: 'smooth', block: 'center' }); - firstError.style.animation = 'highlight 2s ease-in-out'; + firstError.style.animation = 'highlight 2s ease-in-out'; + firstError.addEventListener('animationend', () => { + firstError.style.animation = ''; + }, { once: true }); } } @@ function scrollToFirstWarning() { const firstWarning = document.querySelector('.requirement-item.warning'); if (firstWarning) { firstWarning.scrollIntoView({ behavior: 'smooth', block: 'center' }); - firstWarning.style.animation = 'highlight 2s ease-in-out'; + firstWarning.style.animation = 'highlight 2s ease-in-out'; + firstWarning.addEventListener('animationend', () => { + firstWarning.style.animation = ''; + }, { once: true }); } }Also applies to: 149-155
docker/requirements/views/components/footer.php (2)
236-246
: Use a reliable reload and align the action name with behavior.
window.location.reload(true)
is deprecated and removing a couple of localStorage keys isn’t “clearing cache”.Apply:
-function clearCache() { - if (confirm('Clear browser cache for this page? This will refresh the page.')) { - // Clear localStorage - localStorage.removeItem('theme'); - localStorage.removeItem('viewMode'); - - // Force refresh with cache bypass - window.location.reload(true); - } -} +function clearCache() { + if (confirm('Reset saved preferences for this page and refresh?')) { + localStorage.removeItem('theme'); + localStorage.removeItem('viewMode'); + // Cache-busting refresh + const url = new URL(window.location.href); + url.searchParams.set('cb', Date.now().toString()); + window.location.replace(url.toString()); + } +}
257-271
: Guard for missing footer element.Defensive check prevents errors if the component is used without the footer present.
Apply:
-const footer = document.querySelector('.requirements-footer'); +const footer = document.querySelector('.requirements-footer'); +if (!footer) { return; }docker/requirements/classes/ViewRenderer.php (2)
83-86
: Escape helper is correct; consider nullable input if templates pass non-strings.Optional: widen signature to
?string
and coerce null to empty string.Example:
-public static function escape(string $text): string +public static function escape(?string $text): string { - return htmlspecialchars($text, ENT_QUOTES | ENT_HTML5, 'UTF-8'); + return htmlspecialchars((string)$text, ENT_QUOTES | ENT_HTML5, 'UTF-8'); }
17-25
: Global data persistence across long-lived runtimes.If this ever runs under a long-lived PHP process (Swoole/RoadRunner), expose a
resetGlobalData()
to avoid data bleed.Proposed addition (outside current hunks):
public static function resetGlobalData(): void { self::$globalData = []; }Dockerfile.apache (4)
17-36
: Remove duplicated package (netcat-openbsd).You install netcat-openbsd twice; drop one to keep layers lean.
RUN apt-get update && apt-get install -y --no-install-recommends \ apache2 \ libapache2-mod-php${PHP_VERSION} \ php${PHP_VERSION}-cli \ php${PHP_VERSION}-common \ php${PHP_VERSION}-curl \ php${PHP_VERSION}-mbstring \ php${PHP_VERSION}-xml \ php${PHP_VERSION}-zip \ php${PHP_VERSION}-intl \ php${PHP_VERSION}-bcmath \ php${PHP_VERSION}-opcache \ ca-certificates \ curl \ unzip \ - netcat-openbsd \ netcat-openbsd \
80-98
: Asset builder stage is unused (dead build time).Nothing is copied from asset-builder; it adds time/attack surface. Remove it or wire its artifacts into later stages.
Option A (remove):
-########################################### -# Stage 3: Asset Builder (Node.js/NPM) -########################################### -FROM node:20-slim AS asset-builder - -WORKDIR /build - -# Install composer for foxy integration -RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ - git \ - unzip \ - netcat-openbsd \ - && curl -sS https://getcomposer.org/installer | php -- \ - --install-dir=/usr/local/bin \ - --filename=composer \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Pre-install foxy globally to speed up builds -RUN composer global require php-forge/foxyOption B (keep): copy /root/.composer from asset-builder into dev/full to reuse foxy cache.
268-276
: Validate config paths exist at build-time.Ensure docker/configs/php/{dev,full,prod}.ini and apache files exist, or the build will fail for certain BUILD_TYPE values.
If you want the image to build even when a profile’s ini is missing, guard with multi-stage COPY --from trick or ADD only what exists.
287-293
: Confirm /health is actually served.Healthcheck hits /health, but the Dockerfile only copies a requirements template. Make sure entrypoint or vhost routes /health; otherwise health will flap.
If missing, add a lightweight /health PHP file under web/ and wire in vhost.
docker-compose.yml (2)
226-236
: Pin Oracle image tag and consider a modern XE.latest is volatile; prefer a fixed digest or version to keep CI reproducible. Also 11g is EOL; if possible use a maintained XE image/version.
1-1
: Add trailing newline; satisfy yamllint.Ends without newline; add one to silence tooling.
- oracle_data: + oracle_data: +Also applies to: 241-251
docker/requirements/Checker.php (2)
589-601
: Handle units robustly; support uppercase and 'B' suffix gracefully.Current parser ignores bytes suffix and relies on last char only. This is okay, but consider normalizing unexpected inputs.
If you want, I can provide a stricter parser using filter_var + regex.
625-631
: $result assignment is used by included template; mark intent.Static analyzers flag it as unused. Add a comment to clarify or inline into include.
- $result = $this->result; + $result = $this->result; // used by template.php
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (39)
.editorconfig
(1 hunks).gitattributes
(1 hunks).github/CODE_OF_CONDUCT.md
(1 hunks).github/FUNDING.yml
(1 hunks).github/ISSUE_TEMPLATE.md
(1 hunks).github/PULL_REQUEST_TEMPLATE.md
(1 hunks).github/dependabot.yml
(1 hunks).gitignore
(1 hunks)Dockerfile.apache
(1 hunks)LICENSE
(0 hunks)LICENSE.md
(1 hunks)docker-compose.yml
(1 hunks)docker/configs/apache/apache2.conf
(1 hunks)docker/configs/apache/vhost.conf
(1 hunks)docker/configs/php/dev.ini
(1 hunks)docker/configs/php/full.ini
(1 hunks)docker/configs/php/prod.ini
(1 hunks)docker/configs/php/xdebug.ini
(1 hunks)docker/requirements/Checker.php
(1 hunks)docker/requirements/assets/css/app.css
(1 hunks)docker/requirements/assets/js/app.js
(1 hunks)docker/requirements/classes/ComponentHelper.php
(1 hunks)docker/requirements/classes/RequirementsChecker.php
(1 hunks)docker/requirements/classes/ViewRenderer.php
(1 hunks)docker/requirements/index.php
(1 hunks)docker/requirements/views/components/breadcrumbs.php
(1 hunks)docker/requirements/views/components/category-section.php
(1 hunks)docker/requirements/views/components/footer.php
(1 hunks)docker/requirements/views/components/header.php
(1 hunks)docker/requirements/views/components/navigation.php
(1 hunks)docker/requirements/views/components/summary-cards.php
(1 hunks)docker/requirements/views/components/system-info.php
(1 hunks)docker/requirements/views/layout.php
(1 hunks)docker/requirements/views/layouts/error.php
(1 hunks)docker/requirements/views/layouts/main.php
(1 hunks)docker/requirements/views/partials/status-alert.php
(1 hunks)docker/scripts/entrypoint.sh
(1 hunks)docker/scripts/install-mssql.sh
(1 hunks)docker/scripts/install-oracle.sh
(1 hunks)
💤 Files with no reviewable changes (1)
- LICENSE
🧰 Additional context used
🪛 LanguageTool
.github/CODE_OF_CONDUCT.md
[style] ~5-~5: Consider a more concise word here.
Context: ...rs and maintainers of this project, and in order to keep community open and welcoming, we a...
(IN_ORDER_TO_PREMIUM)
[grammar] ~5-~5: There might be a mistake here.
Context: ...ainers of this project, and in order to keep community open and welcoming, we ask to...
(QB_NEW_EN)
[grammar] ~5-~5: There might be a mistake here.
Context: ... community open and welcoming, we ask to respect all community members. ## Our S...
(QB_NEW_EN)
[grammar] ~12-~12: There might be a mistake here.
Context: ...empathy and kindness toward other people * Being respectful of differing opinions, ...
(QB_NEW_EN)
[grammar] ~13-~13: There might be a mistake here.
Context: ...ng opinions, viewpoints, and experiences * Giving and gracefully accepting construc...
(QB_NEW_EN)
[grammar] ~14-~14: There might be a mistake here.
Context: ...acefully accepting constructive feedback * Accepting responsibility and apologizing...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...stakes, and learning from the experience * Focusing on what is best not just for us...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...sexual attention or advances of any kind * Trolling, insulting or derogatory commen...
(QB_NEW_EN)
[style] ~21-~21: Try using a synonym here to strengthen your wording.
Context: ...ind * Trolling, insulting or derogatory comments, and personal or political attacks * Pu...
(COMMENT_REMARK)
[grammar] ~21-~21: There might be a mistake here.
Context: ...ments, and personal or political attacks * Public or private harassment * Publishin...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...l attacks * Public or private harassment * Publishing others' private information, ...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...dress, without their explicit permission * Other conduct which could reasonably be ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...m inappropriate, threatening, offensive, or harmful. Core team members have the ...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ...ect comments, commits, code, wiki edits, issues, and other contributions that are...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...an individual is officially representing the community in public spaces. Examples...
(QB_NEW_EN)
[grammar] ~39-~39: There might be a mistake here.
Context: ...mmunity include using an official e-mail address, posting via an official social ...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...official forum or acting as an appointed representative at an online or offline e...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...ted by contacting core team members. All complaints will be reviewed and investig...
(QB_NEW_EN)
[grammar] ~52-~52: There might be a mistake here.
Context: ...ing the consequences for any action they deem in violation of this Code of Conduc...
(QB_NEW_EN)
[grammar] ~82-~82: There might be a mistake here.
Context: ...dards, including sustained inappropriate behavior, harassment of an individual, o...
(QB_NEW_EN)
[grammar] ~89-~89: There might be a mistake here.
Context: ...nt][homepage], version 2.1, available at [https://www.contributor-covenant.org/ve...
(QB_NEW_EN)
[grammar] ~95-~95: There might be a mistake here.
Context: ...faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/tr...
(QB_NEW_EN)
.github/PULL_REQUEST_TEMPLATE.md
[grammar] ~3-~3: There might be a mistake here.
Context: ...----------- | --- | Is bugfix? | ✔️/❌ | New feature? | ✔️/❌ | Breaks BC? |...
(QB_NEW_EN)
[grammar] ~4-~4: There might be a mistake here.
Context: ...bugfix? | ✔️/❌ | New feature? | ✔️/❌ | Breaks BC? | ✔️/❌ | Fixed issues |...
(QB_NEW_EN)
[grammar] ~5-~5: There might be a mistake here.
Context: ... feature? | ✔️/❌ | Breaks BC? | ✔️/❌ | Fixed issues | <!-- comma-separated l...
(QB_NEW_EN)
LICENSE.md
[grammar] ~10-~10: There might be a mistake here.
Context: ...conditions and the following disclaimer. * Redistributions in binary form must repr...
(QB_NEW_EN)
[grammar] ~13-~13: There might be a mistake here.
Context: ...aterials provided with the distribution. * Neither the name of Yii2 Extensions (Ter...
(QB_NEW_EN)
[grammar] ~18-~18: There might be a mistake here.
Context: ...GHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLU...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...IGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIA...
(QB_NEW_EN)
[grammar] ~26-~26: There might be a mistake here.
Context: ...RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBI...
(QB_NEW_EN)
[grammar] ~27-~27: There might be a mistake here.
Context: ...VISED OF THE POSSIBILITY OF SUCH DAMAGE.
(QB_NEW_EN)
.github/ISSUE_TEMPLATE.md
[grammar] ~13-~13: There might be a mistake here.
Context: ...n | 1.0.? | PHP version | | Operating system |
(QB_NEW_EN)
🪛 PHPMD (2.15.0)
docker/requirements/classes/RequirementsChecker.php
500-500: Avoid unused local variables such as '$output'. (Unused Code Rules)
(UnusedLocalVariable)
632-639: Avoid unused private methods such as 'evaluateExpression'. (Unused Code Rules)
(UnusedPrivateMethod)
docker/requirements/Checker.php
555-555: Avoid unused local variables such as '$output'. (Unused Code Rules)
(UnusedLocalVariable)
607-610: Avoid unused private methods such as 'evaluateExpression'. (Unused Code Rules)
(UnusedPrivateMethod)
629-629: Avoid unused local variables such as '$result'. (Unused Code Rules)
(UnusedLocalVariable)
🪛 YAMLlint (1.37.1)
docker-compose.yml
[error] 251-251: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (14)
.github/FUNDING.yml (1)
1-3
: LGTM — valid GitHub Sponsors config.Recognized format; should enable the sponsor button for
terabytesoftw
..gitignore (1)
6-6
: Reconsider ignoring composer.lock.For apps/images, committing composer.lock improves reproducibility; for libraries it’s commonly ignored. Pick one intentionally.
docker/requirements/views/components/category-section.php (1)
31-33
: No changes needed: getOverallStatus returns valid Bootstrap badge classes
The function only returns'danger'
,'warning'
, or'success'
, all of which map to Bootstrap’s contextual badge colors.docker/configs/php/full.ini (1)
41-43
: Opcache revalidate on every request is heavy.For “Full Testing” this may be fine, but confirm it’s intentional.
docker/scripts/install-mssql.sh (1)
20-27
: Mixing Bookworm repo on Trixie—confirm compatibility.Using the Debian 12 (bookworm) Microsoft repo on Debian 13 (trixie) can cause ABI issues. Verify runtime with your base image.
docker/requirements/classes/ComponentHelper.php (1)
94-98
: Badge escaping dependency: ensure ViewRenderer::escape is availableIf ViewRenderer isn’t loaded here, this will fatal. Either import/require it or provide a local fallback.
I can add a local
escape()
fallback inside this class if you prefer.docker/requirements/classes/RequirementsChecker.php (1)
481-491
: checkMemoryLimit: good handling of “-1” unlimitedUnlimited is correctly treated as pass. LGTM.
docker/configs/apache/apache2.conf (2)
29-33
: Good hardening defaults
ServerTokens Prod
,ServerSignature Off
, andTraceEnable Off
are solid production settings.
52-54
: Rewrite rules confirmed in vhost.conf
The Directory/var/www/app/web
indocker/configs/apache/vhost.conf
enablesAllowOverride All
and includes the necessaryRewriteEngine On
andRewriteRule
directives, so disabling.htaccess
in the main config won’t break URL rewriting.docker/requirements/views/layout.php (1)
49-58
: Ignore missing anchor IDs The#overview
and#system-info
targets are defined in the parent layout (docker/requirements/views/layouts/main.php
), so the navigation links already work as intended.Likely an incorrect or invalid review comment.
docker/requirements/views/components/breadcrumbs.php (1)
51-58
: Resolved: ComponentHelper::getCategoryIcon is already safe
Uses a hard-coded map of category names to icon identifiers (only letters, numbers, and hyphens) with a default of “gear,” so no injection risk remains.docker/requirements/views/partials/status-alert.php (1)
74-108
: Nice UX for success state.Clear copy, accessible actions, and vertical button group read well.
docker/requirements/views/components/footer.php (1)
202-234
: Keyboard Shortcuts modal looks solid.Clean Bootstrap usage and scoped content structure.
docker/requirements/classes/ViewRenderer.php (1)
71-77
: Good exception-safe buffering.ob_start + cleanup + context-rich RuntimeException is appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
docker/requirements/Checker.php (2)
129-135
: Nice: removed eval-path; conditions are now true booleans.This resolves the prior “always truthy string” bug.
369-374
: Good fix: Composer check uses a real boolean now.This replaces the old
'eval:'
string approach.
🧹 Nitpick comments (5)
docker/requirements/Checker.php (5)
589-604
: GuardgetByteSize()
against empty strings and add types.Empty input triggers an undefined offset; adding a quick guard prevents that.
- public function getByteSize($size) + public function getByteSize(string $size): int { $size = trim($size); + if ($size === '') { + return 0; + } - $last = strtolower($size[strlen($size)-1]); + $last = strtolower($size[strlen($size)-1]); - $size = (int) $size; + $size = (int) $size;
616-626
: PHPMD false-positive:$result
is used by the included template.Suppress the warning at method level.
- /** - * Render HTML output - */ + /** + * Render HTML output + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ public function renderHtml() { if (!$this->result) { $this->check(); } $result = $this->result; include __DIR__ . '/template.php'; }
42-50
: Make uptime detection OS-aware and resilient to read failures.Avoids warnings on non-Linux or rare read errors.
- if (file_exists('/proc/uptime')) { - $uptime = file_get_contents('/proc/uptime'); - $uptime = (float) explode(' ', $uptime)[0]; - return $this->formatUptime($uptime); - } + if (PHP_OS_FAMILY === 'Linux' && is_readable('/proc/uptime')) { + $raw = @file_get_contents('/proc/uptime'); + if ($raw !== false) { + $uptime = (float) explode(' ', $raw)[0]; + return $this->formatUptime($uptime); + } + } return 'Unknown';
55-62
: Add type hints toformatUptime()
(and consider reusing the shared formatter).Keeps behavior consistent with
classes/ComponentHelper::formatUptime()
and improves static analysis.- private function formatUptime($seconds) + private function formatUptime(float $seconds): string { - $days = floor($seconds / 86400); - $hours = floor(($seconds % 86400) / 3600); - $minutes = floor(($seconds % 3600) / 60); + $seconds = (int)$seconds; + $days = intdiv($seconds, 86400); + $hours = intdiv($seconds % 86400, 3600); + $minutes = intdiv($seconds % 3600, 60); return sprintf('%dd %dh %dm', $days, $hours, $minutes); }
5-11
: Avoid duplication withclasses/RequirementsChecker.php
.This class mirrors logic already present in
docker/requirements/classes/RequirementsChecker.php
(uptime, byte-size/compare, OPcache checks). Consider consolidating to a single source of truth to prevent drift.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
Dockerfile.apache
(1 hunks)LICENSE
(1 hunks)docker/requirements/Checker.php
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- LICENSE
🚧 Files skipped from review as they are similar to previous changes (1)
- Dockerfile.apache
🧰 Additional context used
🧬 Code graph analysis (1)
docker/requirements/Checker.php (2)
docker/requirements/classes/RequirementsChecker.php (22)
__construct
(16-21)initSystemInfo
(26-41)getUptime
(46-61)formatUptime
(66-73)check
(78-131)getDefaultRequirements
(269-478)normalizeRequirement
(152-163)processRequirement
(136-147)runPerformanceTest
(168-176)getOpcacheMetrics
(181-237)getMemoryMetrics
(242-249)getExtensionMetrics
(254-264)checkOpcacheLoaded
(553-561)checkMemoryLimit
(483-491)checkOpcacheEnabled
(566-574)checkOpcacheCliEnabled
(579-587)checkJitEnabled
(619-627)checkCommandExists
(496-505)compareByteSize
(510-523)getByteSize
(528-548)getResult
(644-647)getJson
(652-659)docker/requirements/classes/ComponentHelper.php (1)
formatUptime
(138-150)
🪛 PHPMD (2.15.0)
docker/requirements/Checker.php
557-557: Avoid unused local variables such as '$void'. (Unused Code Rules)
(UnusedLocalVariable)
624-624: Avoid unused local variables such as '$result'. (Unused Code Rules)
(UnusedLocalVariable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
docker/requirements/Checker.php (1)
189-199
: Harden OPcache metrics: guard missing keys to avoid notices.Some builds omit sub-keys; direct indexing can emit notices. Use null coalescing/isset with sane defaults.
Apply:
- $metrics = [ - 'enabled' => $status['opcache_enabled'], - 'memory_usage' => round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . ' MB', - 'memory_free' => round($status['memory_usage']['free_memory'] / 1024 / 1024, 2) . ' MB', - 'memory_wasted' => round($status['memory_usage']['wasted_memory'] / 1024 / 1024, 2) . ' MB', - 'cached_files' => $status['opcache_statistics']['num_cached_scripts'], - 'max_cached_files' => ini_get('opcache.max_accelerated_files'), - 'hit_rate' => round($status['opcache_statistics']['opcache_hit_rate'], 2) . '%', - 'cache_misses' => $status['opcache_statistics']['misses'], - 'cache_hits' => $status['opcache_statistics']['hits'] - ]; + $mu = $status['memory_usage'] ?? []; + $st = $status['opcache_statistics'] ?? []; + $metrics = [ + 'enabled' => $status['opcache_enabled'] ?? false, + 'memory_usage' => isset($mu['used_memory']) ? round($mu['used_memory'] / 1048576, 2) . ' MB' : 'Unknown', + 'memory_free' => isset($mu['free_memory']) ? round($mu['free_memory'] / 1048576, 2) . ' MB' : 'Unknown', + 'memory_wasted' => isset($mu['wasted_memory']) ? round($mu['wasted_memory'] / 1048576, 2) . ' MB' : 'Unknown', + 'cached_files' => $st['num_cached_scripts'] ?? 0, + 'max_cached_files' => (int) (ini_get('opcache.max_accelerated_files') ?: 0), + 'hit_rate' => isset($st['opcache_hit_rate']) ? round($st['opcache_hit_rate'], 2) . '%' : '0%', + 'cache_misses' => $st['misses'] ?? 0, + 'cache_hits' => $st['hits'] ?? 0, + ];- if (isset($status['jit'])) { - $metrics['jit_buffer_used'] = round($status['jit']['buffer_size'] / 1024 / 1024, 2) . ' MB'; - $metrics['jit_compiled_funcs'] = $status['jit']['num_traces']; - } + if (isset($status['jit'])) { + $jit = $status['jit']; + $metrics['jit_buffer_used'] = isset($jit['buffer_size']) + ? round($jit['buffer_size'] / 1048576, 2) . ' MB' : 'Unknown'; + $metrics['jit_compiled_funcs'] = $jit['num_traces'] ?? 0; + }Also applies to: 211-214
🧹 Nitpick comments (7)
docker/requirements/Checker.php (7)
618-628
: Silence false positive on$result
and add return type.The template consumes
$result
. Add suppression and avoid
return.Apply:
- /** - * Render HTML output - */ - public function renderHtml() + /** + * Render HTML output + * @SuppressWarnings(PHPMD.UnusedLocalVariable) // consumed by template.php + */ + public function renderHtml(): void { if (!$this->result) { $this->check(); } $result = $this->result; include __DIR__ + '/template.php'; }Note: keep the include path operator as concatenation (.). If
+
here is a typo, correct to.
in your patch.
26-26
: Prefer PHP_SAPI constant over php_sapi_name().Minor speed/readability win; no behavior change.
Apply:
- 'php_sapi' => php_sapi_name(), + 'php_sapi' => PHP_SAPI,
537-545
: Type-hint memory-limit check and tighten contract.Clarify input/return types and auto-handle unchecked state.
Apply:
- public function checkMemoryLimit($minimumLimit) + public function checkMemoryLimit(string|int $minimumLimit): bool { $memoryLimit = ini_get('memory_limit'); if ($memoryLimit === '-1') { return true; // Unlimited } return $this->compareByteSize($memoryLimit, $minimumLimit, '>='); }
567-586
: Add types for size helpers; handle unexpected formats safely.Expose intent and avoid accidental int coercions.
Apply:
- public function compareByteSize($a, $b, $operator = '>=') + public function compareByteSize(string|int $a, string|int $b, string $operator = '>='): bool { $bytesA = $this->getByteSize($a); $bytesB = $this->getByteSize($b);- public function getByteSize($size) + public function getByteSize(string|int $size): int { - $size = trim($size); - $last = strtolower($size[strlen($size)-1]); - $size = (int) $size; + if (is_int($size)) { + return $size; + } + $size = trim($size); + if ($size === '') { + return 0; + } + $last = strtolower($size[strlen($size)-1]); + $size = (int) $size; switch($last) { case 'g': $size *= 1024; case 'm': $size *= 1024; case 'k': $size *= 1024; } return $size; }Also applies to: 591-607
242-247
: Core extensions list: drop non-existent 'unicode'.It inflates “additional” count on modern PHP. Consider removing it.
Apply:
- $core = ['Core', 'date', 'libxml', 'pcre', 'unicode', 'filter', 'SPL', 'session', 'standard']; + $core = ['Core', 'date', 'libxml', 'pcre', 'filter', 'SPL', 'session', 'standard'];
633-640
: Add JSON_UNESCAPED_UNICODE; optional throws for errors.Prevents Unicode escaping; consider throws if you want strictness.
Apply:
- return json_encode($this->result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + return json_encode($this->result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
67-76
: Add method signatures to solidify the public API.Union types are available; returning self eases chaining; auto-check in getResult helps.
Apply:
- public function check($requirements = null) + public function check(array|string|null $requirements = null): self- return $this; + return $this;- public function getResult() + public function getResult(): array { - return $this->result; + if ($this->result === null) { + $this->check(); + } + return $this->result; }Also applies to: 123-124, 612-616
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
docker/requirements/Checker.php
(1 hunks)docker/scripts/install-mssql.sh
(1 hunks)docker/scripts/install-oracle.sh
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- docker/scripts/install-mssql.sh
- docker/scripts/install-oracle.sh
🧰 Additional context used
🪛 PHPMD (2.15.0)
docker/requirements/Checker.php
559-559: Avoid unused local variables such as '$_'. (Unused Code Rules)
(UnusedLocalVariable)
626-626: Avoid unused local variables such as '$result'. (Unused Code Rules)
(UnusedLocalVariable)
🔇 Additional comments (3)
docker/requirements/Checker.php (3)
129-140
: Good cleanup: dropped eval-path and centralized status/metrics.The status derivation is clear, and metrics are attached only when requested. Nice.
487-495
: Robust OPcache detection. LGTM.Covers core/extension/function paths; good cross-version handling.
500-508
: Boolean normalization for OPcache/JIT checks. LGTM.Using filter_var for ini flags and explicit JIT off-values looks correct.
Also applies to: 512-520, 524-532
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (2)
docker/requirements/views/layouts/main.php (2)
23-26
: Avoid bare CDN includes; add SRI/crossorigin or self-host assets.Add integrity/crossorigin to bootstrap-icons and JS, or ship local assets under the image for hermetic builds and CSP compliance.
Also applies to: 381-382
385-474
: Inline JS will be blocked under a strict CSP; move to an external asset or use a nonce.Extract this block to a static JS file and/or emit a per-request nonce used in both the CSP header and the script tag.
🧹 Nitpick comments (6)
docker/requirements/views/layouts/main.php (2)
312-318
: Deduplicate category icon mapping to avoid inconsistencies.This view uses ComponentHelper::getCategoryIcon; navigation.php defines its own mapping. Prefer the helper everywhere to keep icons consistent.
270-274
: Add accessible names to icon-only buttons.Provide aria-labels for the theme toggle and mobile toggle for screen readers.
- <button class="btn btn-outline-secondary btn-sm" type="button" id="themeToggle"> + <button class="btn btn-outline-secondary btn-sm" type="button" id="themeToggle" aria-label="Toggle theme">- toggleBtn.innerHTML = '<i class="bi bi-list"></i>'; + toggleBtn.innerHTML = '<i class="bi bi-list" aria-hidden="true"></i>'; + toggleBtn.setAttribute('aria-label', 'Toggle navigation');Also applies to: 455-473
docker/requirements/Checker.php (4)
55-62
: Add types to formatUptime() and use intdiv for clarity.- private function formatUptime($seconds) - { - $days = floor($seconds / 86400); - $hours = floor(($seconds % 86400) / 3600); - $minutes = floor(($seconds % 3600) / 60); - - return sprintf('%dd %dh %dm', $days, $hours, $minutes); - } + private function formatUptime(float $seconds): string + { + $s = (int) $seconds; + $days = intdiv($s, 86400); + $hours = intdiv($s % 86400, 3600); + $minutes = intdiv($s % 3600, 60); + return sprintf('%dd %dh %dm', $days, $hours, $minutes); + }
7-11
: Add typed properties (with safe defaults) to match strict_types.Prevents accidental uninitialized access and improves static analysis.
-final class Checker +final class Checker { - private $result; - private $buildType; - private $phpVersion; - private $systemInfo; + private array $result = []; + private string $buildType; + private string $phpVersion; + private array $systemInfo = [];
537-546
: Add missing parameter/return types for sizing helpers.Improves correctness with strict_types and documents the contract.
- public function checkMemoryLimit($minimumLimit) + public function checkMemoryLimit(string $minimumLimit): bool- public function compareByteSize($a, $b, $operator = '>=') + public function compareByteSize(string $a, string $b, string $operator = '>='): bool- public function getByteSize($size) + public function getByteSize(string $size): intAlso applies to: 567-586, 591-607
620-628
: PHPMD false-positive: $result appears unused.The included template likely consumes $result. Consider adding a local comment or PHPMD suppression to silence the false positive, or switch to a renderer pattern for clarity.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
docker/requirements/Checker.php
(1 hunks)docker/requirements/views/layouts/main.php
(1 hunks)docker/scripts/entrypoint.sh
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- docker/scripts/entrypoint.sh
🧰 Additional context used
🧬 Code graph analysis (2)
docker/requirements/views/layouts/main.php (3)
docker/requirements/classes/ComponentHelper.php (5)
ComponentHelper
(9-153)getOverallStatus
(59-68)getStatusMessage
(73-89)getCategoryIcon
(14-28)getStatusIcon
(46-54)docker/requirements/classes/ViewRenderer.php (5)
ViewRenderer
(9-103)escape
(83-86)formatNumber
(91-94)formatPercent
(99-102)renderComponent
(38-41)docker/requirements/views/components/navigation.php (1)
getCategoryIcon
(99-112)
docker/requirements/Checker.php (2)
docker/requirements/classes/RequirementsChecker.php (22)
__construct
(16-21)initSystemInfo
(26-41)getUptime
(46-61)formatUptime
(66-73)check
(78-131)getDefaultRequirements
(269-478)normalizeRequirement
(152-163)processRequirement
(136-147)runPerformanceTest
(168-176)getOpcacheMetrics
(181-237)getMemoryMetrics
(242-249)getExtensionMetrics
(254-264)checkOpcacheLoaded
(553-561)checkMemoryLimit
(483-491)checkOpcacheEnabled
(566-574)checkOpcacheCliEnabled
(579-587)checkJitEnabled
(619-627)checkCommandExists
(496-505)compareByteSize
(510-523)getByteSize
(528-548)getResult
(644-647)getJson
(652-659)docker/requirements/classes/ComponentHelper.php (1)
formatUptime
(140-152)
🪛 PHPMD (2.15.0)
docker/requirements/Checker.php
559-559: Avoid unused local variables such as '$_'. (Unused Code Rules)
(UnusedLocalVariable)
626-626: Avoid unused local variables such as '$result'. (Unused Code Rules)
(UnusedLocalVariable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
docker/requirements/Checker.php (2)
557-569
: Silence PHPMD unused var in exec capture or rename the var.PHPMD flags
$_
as unused. Add suppression or use a clearly named variable.public function checkCommandExists(string $command): bool { $locator = (PHP_OS_FAMILY === 'Windows') ? 'where' : 'command -v'; $redirect = (PHP_OS_FAMILY === 'Windows') ? ' > nul 2>&1' : ' > /dev/null 2>&1'; $arg = escapeshellarg($command); $code = 1; - - exec("$locator $arg$redirect", $_, $code); + /** @SuppressWarnings(PHPMD.UnusedLocalVariable) */ + $unusedOutput = []; + exec("$locator $arg$redirect", $unusedOutput, $code); return $code === 0; }
5-6
: Confirm this Checker isn’t a duplicate of classes/RequirementsChecker.php. If unused, delete to avoid drift.Run the script to verify usage and decide whether to keep or remove this class/template.
#!/bin/bash # Find any instantiations/usages of this class rg -nP -C2 '\bnew\s+Checker\s*\(' rg -nP -C2 '\bChecker::' # Also check for entry points rendering via this class rg -nP -C2 '\brenderHtml\s*\(' rg -nP -C2 '\bgetJson\s*\('
🧹 Nitpick comments (5)
docker/requirements/Checker.php (5)
194-205
: Avoid notices by guarding optional OPcache status keys.Accessing nested keys directly may emit notices on some PHP builds/configs.
- $metrics = [ - 'enabled' => $status['opcache_enabled'], - 'memory_usage' => round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . ' MB', - 'memory_free' => round($status['memory_usage']['free_memory'] / 1024 / 1024, 2) . ' MB', - 'memory_wasted' => round($status['memory_usage']['wasted_memory'] / 1024 / 1024, 2) . ' MB', - 'cached_files' => $status['opcache_statistics']['num_cached_scripts'], - 'max_cached_files' => ini_get('opcache.max_accelerated_files'), - 'hit_rate' => round($status['opcache_statistics']['opcache_hit_rate'], 2) . '%', - 'cache_misses' => $status['opcache_statistics']['misses'], - 'cache_hits' => $status['opcache_statistics']['hits'] - ]; + $metrics = [ + 'enabled' => $status['opcache_enabled'] ?? false, + 'memory_usage' => isset($status['memory_usage']['used_memory']) + ? round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . ' MB' : 'Unknown', + 'memory_free' => isset($status['memory_usage']['free_memory']) + ? round($status['memory_usage']['free_memory'] / 1024 / 1024, 2) . ' MB' : 'Unknown', + 'memory_wasted' => isset($status['memory_usage']['wasted_memory']) + ? round($status['memory_usage']['wasted_memory'] / 1024 / 1024, 2) . ' MB' : 'Unknown', + 'cached_files' => $status['opcache_statistics']['num_cached_scripts'] ?? 0, + 'max_cached_files' => ini_get('opcache.max_accelerated_files'), + 'hit_rate' => isset($status['opcache_statistics']['opcache_hit_rate']) + ? round($status['opcache_statistics']['opcache_hit_rate'], 2) . '%' : '0%', + 'cache_misses' => $status['opcache_statistics']['misses'] ?? 0, + 'cache_hits' => $status['opcache_statistics']['hits'] ?? 0 + ];- $metrics['jit_buffer_used'] = round($status['jit']['buffer_size'] / 1024 / 1024, 2) . ' MB'; - $metrics['jit_compiled_funcs'] = $status['jit']['num_traces']; + $metrics['jit_buffer_used'] = isset($status['jit']['buffer_size']) + ? round($status['jit']['buffer_size'] / 1024 / 1024, 2) . ' MB' : 'Unknown'; + $metrics['jit_compiled_funcs'] = $status['jit']['num_traces'] ?? 0;Also applies to: 216-219
617-626
: Suppress false-positive PHPMD warning for$result
used by included template.The variable is consumed inside the included file; PHPMD can’t see across include boundaries.
- public function renderHtml(): void + /** + * Render HTML output + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function renderHtml(): void { if ($this->result === null) { $this->check(); } $result = $this->result; include __DIR__ . '/template.php'; }
131-142
: Tighten type hints for internal helpers for consistency with strict_types.Add array/string/bool return types to avoid accidental misuse.
- private function processRequirement(&$requirement): void + private function processRequirement(array &$requirement): void { ... }- private function normalizeRequirement($requirement): array + private function normalizeRequirement(array $requirement): array { ... }- private function runPerformanceTest($testType): array|null + private function runPerformanceTest(string $testType): ?array { ... }- public function checkMemoryLimit($minimumLimit): bool + public function checkMemoryLimit(string $minimumLimit): bool { ... }- public function compareByteSize($a, $b, $operator = '>='): bool + public function compareByteSize(string $a, string $b, string $operator = '>='): bool { ... }Also applies to: 147-161, 166-178, 543-552, 574-587
505-513
: Add explicit return types to OPcache enablement checks.Small clarity/readability win.
- public function checkOpcacheEnabled() + public function checkOpcacheEnabled(): bool { ... }- public function checkOpcacheCliEnabled() + public function checkOpcacheCliEnabled(): bool { ... }Also applies to: 517-524
69-79
: Validate requirement file path before require and type the parameter.Prevent warnings on invalid paths; clarify accepted types.
- public function check($requirements = null): static + public function check(array|string|null $requirements = null): static { if ($requirements === null) { $requirements = $this->getDefaultRequirements(); } - if (is_string($requirements)) { - $requirements = require $requirements; + if (is_string($requirements)) { + if (!is_file($requirements) || !is_readable($requirements)) { + throw new \RuntimeException("Requirements file not found or unreadable: $requirements"); + } + $requirements = require $requirements; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
docker/requirements/Checker.php
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
docker/requirements/Checker.php (2)
docker/requirements/classes/RequirementsChecker.php (17)
__construct
(16-21)initSystemInfo
(26-41)getUptime
(46-61)formatUptime
(66-73)check
(78-131)normalizeRequirement
(152-163)processRequirement
(136-147)runPerformanceTest
(168-176)getOpcacheMetrics
(181-237)getMemoryMetrics
(242-249)getExtensionMetrics
(254-264)checkMemoryLimit
(483-491)checkCommandExists
(496-505)compareByteSize
(510-523)getByteSize
(528-548)getResult
(644-647)getJson
(652-659)docker/requirements/classes/ComponentHelper.php (1)
formatUptime
(140-152)
🪛 PHPMD (2.15.0)
docker/requirements/Checker.php
566-566: Avoid unused local variables such as '$_'. (Unused Code Rules)
(UnusedLocalVariable)
623-623: Avoid unused local variables such as '$result'. (Unused Code Rules)
(UnusedLocalVariable)
@coderabbitai review |
✅ Actions performedReview triggered.
|
…it configuration.
Summary by CodeRabbit
New Features
Documentation
Chores