From 84568ad46adfa6a57f3b80b044660318e12c4d75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 May 2026 08:35:25 +0000 Subject: [PATCH 1/2] chore: add php quality workflow and migration docs Agent-Logs-Url: https://github.com/iForumModule/iforum/sessions/dbcaa461-e0be-4886-b4aa-59aa69d7b84a Co-authored-by: fiammybe <3736946+fiammybe@users.noreply.github.com> --- .github/workflows/php-quality.yml | 38 +++++++++++++++++ docs/art-ipf-migration-matrix.md | 19 +++++++++ docs/index.md | 3 ++ docs/phased-refactor-roadmap.md | 27 ++++++++++++ docs/php8-compatibility-checklist.md | 23 ++++++++++ phpcs.xml.dist | 11 +++++ phpstan.neon.dist | 7 ++++ src/include/bootstrap.php | 63 ++++++++++++++++++++++++++++ tools/phpstan-bootstrap.php | 25 +++++++++++ 9 files changed, 216 insertions(+) create mode 100644 .github/workflows/php-quality.yml create mode 100644 docs/art-ipf-migration-matrix.md create mode 100644 docs/phased-refactor-roadmap.md create mode 100644 docs/php8-compatibility-checklist.md create mode 100644 phpcs.xml.dist create mode 100644 phpstan.neon.dist create mode 100644 src/include/bootstrap.php create mode 100644 tools/phpstan-bootstrap.php diff --git a/.github/workflows/php-quality.yml b/.github/workflows/php-quality.yml new file mode 100644 index 0000000..0d49f2b --- /dev/null +++ b/.github/workflows/php-quality.yml @@ -0,0 +1,38 @@ +name: PHP quality checks + +on: + push: + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + quality: + name: PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-version: ['8.2', '8.3', '8.4', '8.5'] + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + tools: parallel-lint, phpcs, phpstan + + - name: Lint PHP sources + run: parallel-lint --exclude .git --exclude vendor src + + - name: Check coding standards + run: phpcs --standard=phpcs.xml.dist + + - name: Run static analysis + run: phpstan analyse --no-progress --configuration=phpstan.neon.dist diff --git a/docs/art-ipf-migration-matrix.md b/docs/art-ipf-migration-matrix.md new file mode 100644 index 0000000..bdf16d5 --- /dev/null +++ b/docs/art-ipf-migration-matrix.md @@ -0,0 +1,19 @@ +# Art → IPF migration matrix + +This module still mixes legacy Art-based persistence patterns with newer ImpressCMS conventions. The matrix below captures the intended migration target without changing runtime behavior in this PR. + +| Legacy area | Current responsibility | IPF-oriented target | Notes for follow-up | +| --- | --- | --- | --- | +| `src/class/art/object.php` and related Art base classes | Shared object lifecycle, validation, and persistence helpers | Replace with IPF object and handler base classes | Start with low-risk handlers that already map cleanly to one table each | +| `src/class/forum.php`, `src/class/topic.php`, `src/class/post.php` | Module domain objects and handler logic | Move table mapping and CRUD concerns into dedicated IPF handlers | Keep public method names stable while adapters are introduced | +| `src/include/functions.ini.php` config loading | Module-wide config bootstrap | Route shared module/config access through the new bootstrap helper first | This reduces repeated dirname lookups before broader refactors | +| Direct `icms_getmodulehandler()` calls throughout `src/` | Per-file handler lookup | Centralize lookup behind helper functions | Lets later refactors swap implementations in one place | +| Install and update hooks in `src/include/module.php` | Schema/bootstrap orchestration | Move schema-aware logic behind dedicated service-style helpers | Leave hook entry points intact for compatibility | +| Template-facing utility functions in `src/include/functions.php` | Mixed rendering and data access helpers | Separate presentation helpers from persistence access | Tackle after handler loading is consolidated | + +## Migration guardrails + +- Preserve the current module entry points and install/update hooks until handler migrations are complete. +- Refactor one handler family at a time so existing forum, topic, and post behavior stays unchanged. +- Prefer adding adapters and compatibility layers before deleting Art-based code. +- Expand CI coverage alongside each phase so new IPF-oriented code is checked on all supported PHP versions. diff --git a/docs/index.md b/docs/index.md index d4ed6ff..3cbd76b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,6 @@ iForum is a full-featured discussion forum for ImpressCMS. [Templates](templates.md) +[Art → IPF migration matrix](art-ipf-migration-matrix.md) +[PHP 8 compatibility checklist](php8-compatibility-checklist.md) +[Phased refactor roadmap](phased-refactor-roadmap.md) diff --git a/docs/phased-refactor-roadmap.md b/docs/phased-refactor-roadmap.md new file mode 100644 index 0000000..ffdf4a4 --- /dev/null +++ b/docs/phased-refactor-roadmap.md @@ -0,0 +1,27 @@ +# Phased refactor roadmap + +This roadmap describes the intended migration path while keeping the module installable and behaviorally stable. + +## Phase 1: Developer safety nets + +- Add CI coverage for PHP linting, coding standards, and static analysis. +- Document the Art → IPF migration path and PHP 8 review expectations. +- Introduce a shared bootstrap helper for module lookup and handler loading without wiring it into runtime paths yet. + +## Phase 2: Shared access consolidation + +- Replace duplicated module dirname and handler lookup code in low-risk files with the shared helper. +- Keep existing public entry points, hook signatures, and handler names unchanged. +- Add narrowly scoped validation to each migrated slice before widening coverage. + +## Phase 3: Persistence layer migration + +- Migrate one handler family at a time from Art-based patterns to IPF-friendly structures. +- Add adapters where needed so existing call sites keep working during the transition. +- Separate persistence concerns from presentation helpers as handlers move over. + +## Phase 4: Cleanup and expansion + +- Broaden coding standards and static analysis coverage once migrated areas are stable. +- Retire duplicate compatibility wrappers only after all call sites move to the shared abstractions. +- Update developer documentation as each migration phase lands. diff --git a/docs/php8-compatibility-checklist.md b/docs/php8-compatibility-checklist.md new file mode 100644 index 0000000..f5c900f --- /dev/null +++ b/docs/php8-compatibility-checklist.md @@ -0,0 +1,23 @@ +# PHP 8 compatibility checklist + +Use this checklist when touching legacy iForum code while PHP 8.2 through PHP 8.5 remain supported in CI. + +## Baseline checks + +- Keep `parallel-lint` green across the full `src/` tree. +- Keep coding standards and static analysis green for the shared bootstrap helper and any newly added developer-facing files. +- Avoid introducing dynamic properties, removed functions, or deprecated string/array access patterns. + +## Review checklist for changes + +- Confirm `include_once` and `require_once` paths still resolve correctly when dirname helpers are touched. +- Check for implicit `null` to scalar conversions and loose comparisons that become noisier on newer PHP versions. +- Prefer explicit return values over relying on legacy truthy/falsy behavior. +- Avoid adding new references to removed PHP extensions or incompatible third-party tooling. +- Keep legacy global state access (`icms::$module`, config arrays, handler factories) wrapped behind helper functions where possible. + +## Before merging refactors + +- Re-run the PHP quality workflow on PHP 8.2, 8.3, 8.4, and 8.5. +- Verify install/update hooks still load through `src/icms_version.php` and `src/include/module.php`. +- Confirm helper-only refactors do not alter templates, routes, or persisted data. diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..3cf7e6f --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,11 @@ + + + Coding standards coverage for the shared bootstrap helper added in this refactor slice. + + + + + src/include/bootstrap.php + + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..070ba61 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,7 @@ +parameters: + level: 0 + paths: + - src/include/bootstrap.php + bootstrapFiles: + - tools/phpstan-bootstrap.php + tmpDir: /tmp/phpstan-iforum diff --git a/src/include/bootstrap.php b/src/include/bootstrap.php new file mode 100644 index 0000000..75ef220 --- /dev/null +++ b/src/include/bootstrap.php @@ -0,0 +1,63 @@ +getVar('dirname', 'n') === iforum_get_module_dirname()) { + $module = icms::$module; + + return $module; + } + + $moduleHandler = icms::handler('icms_module'); + $module = $moduleHandler->getByDirname(iforum_get_module_dirname()); + + return $module; +} + +function &iforum_get_handler($handlerName) +{ + $handler = icms_getmodulehandler($handlerName, iforum_get_module_dirname(), 'iforum'); + + return $handler; +} diff --git a/tools/phpstan-bootstrap.php b/tools/phpstan-bootstrap.php new file mode 100644 index 0000000..41e659f --- /dev/null +++ b/tools/phpstan-bootstrap.php @@ -0,0 +1,25 @@ + Date: Tue, 26 May 2026 08:38:54 +0000 Subject: [PATCH 2/2] fix: make php quality checks pass locally Agent-Logs-Url: https://github.com/iForumModule/iforum/sessions/dbcaa461-e0be-4886-b4aa-59aa69d7b84a Co-authored-by: fiammybe <3736946+fiammybe@users.noreply.github.com> --- phpcs.xml.dist | 1 + src/class/art/functions.locale.php | 2 +- src/include/bootstrap.php | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 3cf7e6f..aa2eac1 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -4,6 +4,7 @@ + src/include/bootstrap.php diff --git a/src/class/art/functions.locale.php b/src/class/art/functions.locale.php index d367c6f..69e5a97 100644 --- a/src/class/art/functions.locale.php +++ b/src/class/art/functions.locale.php @@ -44,7 +44,7 @@ function xoops_local($func) $msg = "The locale version is too old. Please copy
XOOPS/Frameworks/compat/language/english/local.php, local.class.php to XOOPS/language/english/"; if (icms::$config->getConfig("language") != "english") { if (is_dir(ICMS_ROOT_PATH."/Frameworks/compat/language/".icms::$config->getConfig("language")."/")) { - $msg .= "
XOOPS/Frameworks/compat/language/".icms::$config->getConfig("language")."/local.php to XOOPS/language/".icms::$config->getConfig("language"]."/"; + $msg .= "
XOOPS/Frameworks/compat/language/".icms::$config->getConfig("language")."/local.php to XOOPS/language/".icms::$config->getConfig("language")."/"; } else { $msg .= "
And modify XOOPS/language/".icms::$config->getConfig("language")."/local.php according to XOOPS/language/english/local.php"; } diff --git a/src/include/bootstrap.php b/src/include/bootstrap.php index 75ef220..0adf5bc 100644 --- a/src/include/bootstrap.php +++ b/src/include/bootstrap.php @@ -1,4 +1,5 @@ getVar('dirname', 'n') === iforum_get_module_dirname()) { + if ( + isset(icms::$module) + && is_object(icms::$module) + && icms::$module->getVar('dirname', 'n') === iforum_get_module_dirname() + ) { $module = icms::$module; return $module;