Appearance
<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>
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 legacyapplication/libraries/Transporters.php extends AdvTransporterssubclass), dragging along byte-identical copies ofcalculateCostExternally/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+ helpersprotectedproduced a fatalAccess level … must be protectedagainst the staleprivateclient copies). Same class of issue as the Apifon seam (#387), legacy-subclass variant. - The change. Two
protectedno-op hooks onAdvTransporters, called fromtransportCost():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). Defaultnull→ 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 ($priceis0there), and a non-nullcustomTransportCost()result — so a client can add an island/carrier surcharge even on otherwise-free shipping, and the two hooks compose. Default returns$priceunchanged.
- Behaviour-preserving. The three free-shipping/overweight early
return 0;/return $price;exits were folded into a single-exitif/elseif(the branches are already mutually exclusive on$weightvs$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.
- Why. A client needing custom transport pricing had to override the entire
[4.112.0] feat(apifon): widen six
Apifonmembers fromprivatetoprotectedto expose a client-override seam (Advisable-com/ecommercen#387)Advisable\Apifon\Apifon: widened six members fromprivatetoprotectedso client forks can subclass and re-bind it fromcustom/instead of editing the upstreamsrc/file. Nowprotected:API_BASE_URL,LIST_ENDPOINT(consts),$config,$logger(properties),ensureAuthenticated(),getList()(methods). TheApifon::classDI binding is documented as a client-override seam (re-bind via acustom/Apifon/container.phpsubclass + 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.phpoverrides the wholetransportCost()(e.g.smile_v4, which redeclared it plus 4 verbatim cost helpers) should migrate to the two hooks and drop the copiedtransportCost/calculateCostExternally/cyprusPostCost/dhlCost/baseGetDhlRatesredeclarations — that removes the drift surface and the recurringprotected-vs-privatevisibility fatals on upstream pulls:phpclass 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.phpdirectly (e.g. by editing the upstream file — as pharm16 and similar clients may have done) should migrate their changes to aCustom\Apifon\Apifonsubclass and re-bind it viacustom/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
protectedin this release cover the main customization surface (API_BASE_URL,LIST_ENDPOINT,$config,$logger,ensureAuthenticated(),getList()). Direct edits to upstreamsrc/Apifon/Apifon.phpwill conflict on next upstream pull.