Skip to content
prod e051e98
Browse

3 · Vendor customizations

Objective — when no event hook can do the job and a vendor file must be edited, store the edited copy in an overlay that survives composer install, so your patch is never silently lost.

Zajaly architecture aims for zero vendor edits — and most changes can hit that bar through event listeners (the previous step). But some CodeCanyon apps hardcode logic with no hook to listen to: a migration scanner that only checks vendor paths, a calculation with no override point. For those, you edit the file — but you never let the edit live only in vendor/, because the next composer install restores the vanilla copy and your change vanishes.

The overlay solves it. You keep a copy of the edited file under resources/vendor-customizations/, mirroring the vendor’s own folder layout. After every install or vendor update, a restore step copies your overlaid files back over the freshly-installed vanilla ones.

flowchart LR
C["composer install<br/>restores vanilla vendor/"] --> R["restore step<br/>copies overlay back"]
R --> P["vendor/ now carries<br/>your patches again"]

A vendor edit is a last resort. Before reaching for one, prove the event-driven path can’t do the work — otherwise build a ZajModule instead.

  1. Check for a listenable event or override. If the vendor fires an event you can react to, build a ZajModule that listens — do not edit the file.

    • ✅ You have confirmed the vendor’s logic is hardcoded with no hook, so an edit is genuinely required.
  2. Assign a MOD-NNN identifier to the edit so it can be tracked and re-applied.

    • ✅ The change has a reserved MOD-NNN number.

The overlay’s power is that its folder layout matches the vendor’s exactly. The restore step copies file-for-file from the overlay onto the same path inside vendor/, so the mirroring must be precise.

  1. Copy the edited file into the overlay at the same relative path the vendor uses. For a customized package, the overlay path mirrors vendor/{package}/....

    Terminal window
    mkdir -p resources/vendor-customizations/{package}/src/Path/To
    cp vendor/{package}/src/Path/To/EditedFile.php \
    resources/vendor-customizations/{package}/src/Path/To/EditedFile.php
    # Expected: the file now exists under resources/vendor-customizations/ at the mirrored path
    • ✅ The overlay holds your edited copy at the same relative path the vendor uses.

For a vendor edit that lives in the app’s own tree rather than an installed package — like the HomeController.php example below — the same principle applies: keep the patched copy where the restore step can re-apply it, and track it as a MOD-NNN.

Inside the overlaid file, wrap only the lines you added so anyone (including a future vendor diff) can see exactly what is yours and what is the vendor’s. Unmarked vendor code stays identical to the original.

  1. Wrap each inserted block in ZAJ:BEGIN / ZAJ:END marker comments, with a one-line note of what the patch does and the MOD-NNN it belongs to.

    // ZAJ:BEGIN MOD-001 — extend the migration scanner to include ZajModules paths
    $zajCoreMigrations = collect(File::glob(database_path('migrations-zaj/*.php')))
    ->map(fn ($path) => File::name($path));
    $migrationFiles = $migrationFiles->merge($zajCoreMigrations);
    $zajModulePaths = File::glob(base_path('packages/ZajModules/*/src/Database/Migrations/*.php'));
    $migrationFiles = $migrationFiles->merge(
    collect($zajModulePaths)->map(fn ($path) => File::name($path))
    );
    // ZAJ:END MOD-001
    • ✅ Every change you made is bracketed by ZAJ:BEGIN/ZAJ:END; nothing outside the markers differs from the vendor original.
  2. For a wholly new file the overlay owns (not a patch to an existing one), mark it with a ZAJ:FILE header so it reads as Zajaly-owned at a glance.

    • ✅ New overlay files carry a ZAJ:FILE marker; patched files use ZAJ:BEGIN/ZAJ:END.

The overlay only protects you if it’s re-applied. A plain composer install overwrites vendor/ with vanilla files, so the restore step must run after it.

  1. Run the restore step after composer install (and after any vendor update). It scans the overlay and copies each customized file back over its vendor counterpart.

    Terminal window
    composer install
    php Admin-Local/.../restore-vendor-customizations.php
    # Expected: a per-package "Restored N file(s)" summary
    • ✅ The summary reports your customized package(s) restored; the vendor files carry your patches again.

The mechanics of the restore script — and the _CUSTOMIZATIONS log that records every MOD-NNN — are the next step.

Do not mark this step done until every box below is checked.

  • 👤 Edit justified — confirmed no event hook or override could do the job before editing a vendor file.
  • 🤖 Path mirrored — the edited copy sits under resources/vendor-customizations/ at the same relative path as the vendor file.
  • 🤖 Changes marked — inserted lines are wrapped in ZAJ:BEGIN/ZAJ:END (or the file carries ZAJ:FILE) and reference a MOD-NNN.
  • 🔀 Re-applied — the restore step runs after composer install and reports the file(s) restored.