Skip to content

<div style="display: none;" hidden="true" aria-hidden="true">Are you an LLM? You can read better optimized documentation at /changelog/Changelog.4.112.md for this page in Markdown format</div>

Home | Changelog

Version 4

version 4.112

  • [4.112.0] feat(transporters): add client extension seams to AdvTransporters::transportCost() to stop full-method override drift (Advisable-com/ecommercen#389)

    • Why. A client needing custom transport pricing had to override the entire transportCost() method (a legacy application/libraries/Transporters.php extends AdvTransporters subclass), dragging along byte-identical copies of calculateCostExternally/cyprusPostCost/dhlCost/baseGetDhlRates. That caused silent drift (upstream DHL/CyprusPost cost fixes never reached the client — a latent transport-cost correctness risk) and recurring merge breakage (the DHL rate-caching refactor that made $dhlRatesResponse + helpers protected produced a fatal Access level … must be protected against the stale private client copies). Same class of issue as the Apifon seam (#387), legacy-subclass variant.
    • The change. Two protected no-op hooks on AdvTransporters, called from transportCost():
      • customTransportCost($transporterId, $country, $county, $postalCode, $weight, $totalWithVat): ?float — pre-hook on the eshop-calculated path (after the postal-code serviceability guard, before standard pricing). Return non-null to short-circuit the standard free-shipping/overweight logic (covers per-transporter admin postal pricing). Default null → falls through.
      • applyTransportSurcharge(float $price, $transporterId, $country, $county, $postalCode, $weight, $totalWithVat): float — post-hook fired once before return on every serviced path: the standard calculation, the free-shipping branches ($price is 0 there), and a non-null customTransportCost() result — so a client can add an island/carrier surcharge even on otherwise-free shipping, and the two hooks compose. Default returns $price unchanged.
    • Behaviour-preserving. The three free-shipping/overweight early return 0; / return $price; exits were folded into a single-exit if/elseif (the branches are already mutually exclusive on $weight vs $weightLimit), so default output is byte-identical for every existing shop. A client override now shrinks from 5 redeclared members to ~2 small hook overrides.
    • No DB migration, REST API change, or language-key changes.
  • [4.112.0] feat(apifon): widen six Apifon members from private to protected to expose a client-override seam (Advisable-com/ecommercen#387)

    • Advisable\Apifon\Apifon: widened six members from private to protected so client forks can subclass and re-bind it from custom/ instead of editing the upstream src/ file. Now protected: API_BASE_URL, LIST_ENDPOINT (consts), $config, $logger (properties), ensureAuthenticated(), getList() (methods). The Apifon::class DI binding is documented as a client-override seam (re-bind via a custom/Apifon/container.php subclass + alias). No behaviour change; existing call sites unaffected.
    • No DB migration, REST API change, or language-key changes.

Notes

  • [4.112.0] Check for overrides: Client forks whose application/libraries/Transporters.php overrides the whole transportCost() (e.g. smile_v4, which redeclared it plus 4 verbatim cost helpers) should migrate to the two hooks and drop the copied transportCost/calculateCostExternally/cyprusPostCost/dhlCost/baseGetDhlRates redeclarations — that removes the drift surface and the recurring protected-vs-private visibility fatals on upstream pulls:

    php
    class Transporters extends AdvTransporters
    {
        // admin postal pricing that bypasses free shipping
        protected function customTransportCost($transporterId, $country, $county, $postalCode, $weight, $totalWithVat): ?float
        {
            // return a configured price (+ per-kg overweight) for the relevant transporter, else null
            return null;
        }
    
        // carrier island surcharge
        protected function applyTransportSurcharge(float $price, $transporterId, $country, $county, $postalCode, $weight, $totalWithVat): float
        {
            // add the surcharge when $postalCode is an island for the relevant carrier
            return $price;
        }
    }
  • [4.112.0] Check for overrides: Client forks that customized src/Apifon/Apifon.php directly (e.g. by editing the upstream file — as pharm16 and similar clients may have done) should migrate their changes to a Custom\Apifon\Apifon subclass and re-bind it via custom/Apifon/container.php:

    php
    $services->set(\Custom\Apifon\Apifon::class)
        ->arg('$logger', service(NamedLoggerInterface::class))
        ->arg('$registry', null);
    $services->alias(\Advisable\Apifon\Apifon::class, \Custom\Apifon\Apifon::class);

    The six members widened to protected in this release cover the main customization surface (API_BASE_URL, LIST_ENDPOINT, $config, $logger, ensureAuthenticated(), getList()). Direct edits to upstream src/Apifon/Apifon.php will conflict on next upstream pull.