Repository navigation
Run on PHP 8.1+ by moving off the pre-PHP-8 dependencies - #23
Merged
Merged
Conversation
Every direct dependency here was capped below PHP 8, so the whole library was pinned to 7.4 and could not be installed on a supported PHP at all. The four that mattered are replaced rather than suppressed, because the old versions also carry published security advisories that composer now refuses to resolve: swiftmailer 5.4 -> symfony/mailer 6.4 (swiftmailer is end of life) twig 1.35 -> twig 3 firebase/php-jwt -> 7.x (CVE-2025-45769 affects < 7.0) dompdf 0.8 -> dompdf 3.x Two call sites needed real changes rather than an import swap. symfony's send() returns void and signals failure by throwing, where Swift returned a recipient count, so Forgot_password's truthiness check would have reported every successful send as a failure. Twig 3 moved setEscaper off the core extension onto EscaperExtension, though it still passes the Environment as the callable's first argument, so Token's json escaper keeps its three parameters and its byte for byte output. CoreThread dropped aza/thread, which has no PHP 8 release and is unmaintained. The used surface was small: wait(), run(), getParam() and the onFork/onShutdown hooks. It now forks with pcntl directly, reaps with SIGCHLD set to SIG_IGN, and falls back to running inline when pcntl is unavailable or the SAPI is not cli. Also removed: four dependencies nothing referenced any more (ProcessManager, office-converter, httpful and the mcrypt era leftovers), a duplicate FAILED_STATUS constant in Transmission that was a hard syntax error on 8.x, and a Swift import block in ForgotpasswordApi. Forgot_password caught SignatureInvalidException without ever importing it, which would have fataled on any invalid token; that import is now present. The two example scripts under tests/ used nategood/httpful, which likewise has no PHP 8 release and was needed by nothing else. They use ext-curl directly. Verified on PHP 8.3: 151 files lint clean, all migrated classes load, twig escaper output unchanged, JWT round trips under HS256 and RS256 with expiry enforced, symfony/mime accepts the bracketed IP addresses validate_email() produces, and CoreThread forks three children into distinct pids leaving no zombies.
The committed lock still pinned twig 1.35 and swiftmailer 5.4, so composer install would have reinstated the pre-PHP-8 packages that composer.json no longer allows.
tahiralmas
pushed a commit
to ictinnovations/ictfax
that referenced
this pull request
Aug 14, 2026
**mod_sofia looked missing.** ICTCore ships sip_profiles/ictcore.xml with a developer's LAN address hardcoded into all four IP params, with the correct block commented out directly above them. sofia cannot bind an address the host does not own, so the profile failed with "Error Creating SIP UA for profile: ictcore", retried three times and was dropped, leaving "sofia status" to answer "Command not found". The module had loaded normally the whole time. The four params now resolve at runtime and vanilla's internal profiles, which contend for the same 5060, are renamed out of sofia.conf.xml's glob. mod_curl and mod_flite are uncommented to match %post freeswitch in the spec. **No email to fax.** The sendmail, poppler-utils, enscript and libreoffice packages behind ictcore.spec's fax and sendmail subpackages were never installed, so nothing listened on 25 and the document conversion path had no binaries. Note that %post writes "$ip localhost" into /etc/hosts, which is fine on a host with a real FQDN but leaves sendmail unable to qualify itself in a container: it then loops on "sleeping for retry" and never binds. The entrypoint writes a qualified name instead. sendmail also runs under a wrapper because -bD never binds on the 8.15.2 build here and -bd forks, which supervisord cannot follow. **PHP 7.4.** Every ICTCore dependency was capped below PHP 8, so the image had no choice. ictinnovations/ictcore#23 replaces them, and until it lands the patch is applied at build time against the pinned ICTCORE_REF. That removes both workarounds this file carried: composer no longer needs its advisory block disabled, and no longer needs --ignore-platform-reqs. It now runs composer audit instead, which reports no advisories across the resulting 24 packages. supervisorctl had no transport configured, so every invocation died with "ini file does not include supervisorctl section" and an operator had no way to restart one service inside the container. Fixed alongside. Verified on the rebuilt image: PHP 8.3.33, the ictcore profile RUNNING on 5060 with no SIP UA errors, an SMTP transaction from outside the container landing in the ictcore mailbox, and the dashboard serving 200. LibreOffice and its Java dependencies take the image from 1.25GB to 2.31GB, which is the cost of the office to fax path working at all.
User::authenticate() still used the v5 three-argument JWT::decode(), which fatals under the v6+ API this branch moves to: JWT::decode(): Argument #3 ($headers) could not be passed by reference Same change already applied to Forgot_password on this branch. That left core/User.php as the one remaining v5 call site, so Bearer authentication would have broken as soon as the dependency bump landed. Reported by @Nibot1 in #25.
…s to docker/Dockerfile still pinned the Remi module stream to 7.4, with a comment saying to bump it once the vendor dependencies were modernised. This branch is that modernisation, and the line was missed. The result was that CI installed the new dependency set on PHP 7.4. thecodingmachine/safe 3.4 requires ^8.1 and uses union types, so PHP 7.4 failed to parse vendor/thecodingmachine/safe/lib/special_cases.php and every request died before reaching any ICTCore code. The container built and FreeSWITCH started, so the failure only showed as the image smoke check exiting 1 with a log full of PHP Parse error: syntax error, unexpected '|'. Same class of miss as core/User.php, which issue #25 caught: the dependencies moved and one file that encodes the old floor stayed behind.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Every direct dependency was capped below PHP 8, so ICTCore could not be installed on a supported PHP at all. The versions it pinned also carry published security advisories, which composer 2.9+ refuses to resolve without
policy.advisories.block=false. Both problems have the same fix.What moved
Dropped as unreferenced: ProcessManager, office-converter, nategood/httpful.
The parts that were not import swaps
Forgot_password— symfony'ssend()returns void and throws on failure, where Swift returned a recipient count. The existing truthiness check would have reported every successful send as a failure.Token— Twig 3 movedsetEscaperontoEscaperExtension, but still passes theEnvironmentas the callable's first argument, so the json escaper keeps three parameters and its byte-for-byte output.CoreThread— forks withpcntl_fork, reaps withSIGCHLDset toSIG_IGN, and runs inline when pcntl is unavailable or the SAPI is not cli.Also fixed: a duplicate
FAILED_STATUSconstant inTransmissionthat was a hard syntax error on 8.x, and aSignatureInvalidExceptioncaught inForgot_passwordwithout ever being imported, which would have fataled on any invalid token.Verified on PHP 8.3
151 files lint clean; all migrated classes load; twig escaper output unchanged; JWT round trips under HS256 and RS256 with expiry enforced; symfony/mime accepts the bracketed-IP addresses
validate_email()produces; CoreThread forks three children into distinct pids leaving no zombies;composer auditreports no advisories across the resulting 24 packages.Built and run end to end in the ICTFax container on the Remi 8.3 stream: dashboard serves, FreeSWITCH profile registers, and an SMTP message delivered through
SendmailTransportlands in the ictcore mailbox.Before merging
ictcore.specrequiresphpunversioned, so an RPM build picks up whatever module stream the host has enabled. Raising the floor to 8.1 means ICTPBX and ICTDialer builds needphp:remi-8.3enabled too. That coordination is why this is a branch rather than a direct push.