2
Arsitektur Paket
Isi src/ hanya terdiri atas lima titik masuk, dan semuanya bekerja pada dua jalur yang tidak saling memanggil: jalur schema yang menyiapkan kolom lewat macro Blueprint, dan jalur model yang mengisi kolom itu lewat observer. UserstampsServiceProvider adalah satu-satunya kelas yang dipakai untuk mendaftarkan seluruh isi paket; ia mengurus config dan menyerahkan pendaftaran macro ke UserstampsMacro (src/UserstampsServiceProvider.php:9-241).
Peta modul
graph TD
CFG["config/userstamps.php"]
SP["UserstampsServiceProvider::bootingPackage"]
MAC["UserstampsMacro::register"]
M1["Blueprint::userstamps"]
M2["Blueprint::softUserstamps"]
M3["Blueprint::dropUserstamps"]
M4["Blueprint::dropSoftUserstamps"]
MIG["berkas migration"]
DB[("kolom di tabel")]
MODEL["model Eloquent"]
TRAIT["HasUserstamps"]
OBS["UserstampsObserver"]
AUTH["auth()->user()"]
CFG --> SP
SP --> MAC
MAC --> M1
MAC --> M2
MAC --> M3
MAC --> M4
M1 --> MIG
M2 --> MIG
M3 --> DB
M4 --> DB
MIG --> DB
CFG --> TRAIT
CFG --> OBS
MODEL --> TRAIT
TRAIT --> OBS
OBS --> DB
OBS --> AUTH
style CFG fill:#f59e0b,color:#000
style SP fill:#f59e0b,color:#000
style MAC fill:#f59e0b,color:#000
style DB fill:#336791,color:#fff
style AUTH fill:#8b5cf6,color:#fff
style OBS fill:#2d7d46,color:#fff
style TRAIT fill:#2d7d46,color:#fff
style M3 fill:#dc2626,color:#fff
style M4 fill:#dc2626,color:#fff
%% fig: Ketergantungan modul di dalam src/
%% desc: Service provider memicu pendaftaran empat macro Blueprint yang membentuk kolom lewat migration, sementara trait HasUserstamps memasang observer yang menulis kolom yang sama saat model disimpan.Grafik di atas menunjukkan bahwa kedua jalur bertemu hanya di kolom tabel: macro menulis definisi kolom, observer menulis nilainya. Tidak ada pemanggilan langsung dari UserstampsMacro ke UserstampsObserver, dan tidak ada kelas yang menyimpan state sendiri. Keduanya membaca kumpulan kunci config yang sama, termasuk is_using_morph yang default-nya false (config/userstamps.php:182) dan with_trashed yang juga default false (config/userstamps.php:1203).
Titik masuk per modul
| Modul | Titik masuk | Tanggung jawab | Rujukan |
|---|---|---|---|
UserstampsServiceProvider | configurePackage, bootingPackage | mendaftarkan config userstamps dan memicu pendaftaran macro | src/UserstampsServiceProvider.php:9-241 |
UserstampsMacro | register() | mendaftarkan empat macro Blueprint | src/Database/Schema/Macros/UserstampsMacro.php:9-154 |
MacroInterface | register() | kontrak yang dipenuhi UserstampsMacro | src/Database/Schema/Macros/MacroInterface.php:5-85 |
HasUserstamps | bootHasUserstamps(), createdBy(), updatedBy(), deletedBy(), usingSoftDeletes() | memasang observer dan menyediakan relasi user | src/Concerns/HasUserstamps.php:12-176 |
UserstampsObserver | creating, updating, deleting, restoring | mengisi kolom userstamp pada model | src/Observers/UserstampsObserver.php:9-287 |
Userstamps | tidak ada metode | kelas kosong tanpa perilaku | src/Userstamps.php:58 |
Peran service provider
UserstampsServiceProvider extends PackageServiceProvider dari spatie/laravel-package-tools. configurePackage memberi nama paket laravel-userstamps lalu memanggil hasConfigFile('userstamps'), sedangkan bootingPackage() hanya berisi satu pernyataan: (new UserstampsMacro)->register() (src/UserstampsServiceProvider.php:9-241). Karena seluruh pendaftaran macro terjadi di bootingPackage, macro sudah tersedia sebelum migration apa pun dijalankan.
Provider itu sendiri didaftarkan lewat package discovery composer pada kunci extra.laravel.providers (composer.json:69-789).
Kontrak macro
UserstampsMacro implements MacroInterface, dan MacroInterface hanya menuntut satu metode register() (src/Database/Schema/Macros/MacroInterface.php:5-85). Implementasinya memanggil empat metode privat berurutan, yaitu registerUserstamps, registerSoftUserstamps, registerDropUserstamps, dan registerDropSoftUserstamps (src/Database/Schema/Macros/UserstampsMacro.php:9-154). Setiap metode mendaftarkan satu macro Blueprint dengan nama userstamps, softUserstamps, dropUserstamps, dan dropSoftUserstamps.
⚠️ Dua macro terakhir bersifat destruktif:
dropUserstampsdandropSoftUserstampsmenghapus kolom, bukan sekadar menghapus foreign key.
Rincian perilaku tiap macro, termasuk pemilihan tipe kolom ID, dibahas di Lapisan Schema dan Macro Blueprint.
Jalur model
Trait HasUserstamps tidak memasang observer pada boot, melainkan mendaftarkan booted lewat static::registerModelEvent, lalu memanggil static::observe(UserstampsObserver::class) di dalam callback tersebut (src/Concerns/HasUserstamps.php:12-176). Pola ini membuat observer baru terpasang setelah model selesai di-boot, sehingga UserstampsObserver selalu menerima model yang sudah lengkap.
Trait yang sama menyediakan tiga relasi, createdBy, updatedBy, dan deletedBy. Ketiganya memilih morphTo ketika config('userstamps.is_using_morph') bernilai benar, atau belongsTo ke config('userstamps.users_model') ketika bernilai salah, lalu membungkus hasilnya dengan withTrashed() bila config('userstamps.with_trashed') aktif (src/Concerns/HasUserstamps.php:19-6210). Pembahasan relasi dan pemakaian trait ada di Trait HasUserstamps dan Relasi User.
usingSoftDeletes() memeriksa apakah SoftDeletes::class ada di class_uses_recursive(static::class) (src/Concerns/HasUserstamps.php:64-6711). Observer memakai hasil pemeriksaan itu sebagai gerbang: hanya model yang memakai soft delete yang mendapat perlakuan khusus pada deleting dan restoring.
Observer sebagai penulis kolom
UserstampsObserver menangani empat event. Pada creating ia mengisi kolom created-by dan updated-by hanya jika kolom tersebut masih bersih menurut isClean (src/Observers/UserstampsObserver.php:9-287). Pada updating ia hanya mengisi kolom updated-by dengan syarat yang sama (src/Observers/UserstampsObserver.php:30-4012).
Pada deleting observer mengisi kolom deleted-by sekaligus updated-by, lalu menyimpan model lewat saveWithoutEventDispatching (src/Observers/UserstampsObserver.php:42-5913). Pada restoring ia mengosongkan kolom deleted-by menjadi null, mengisi updated-by, lalu menyimpan dengan cara yang sama (src/Observers/UserstampsObserver.php:61-7814).
saveWithoutEventDispatching melepas event dispatcher dengan unsetEventDispatcher(), memanggil $model->save(), lalu mengembalikan dispatcher semula (src/Observers/UserstampsObserver.php:80-8915). Inilah yang mencegah event updating terpicu berulang saat observer menulis kolomnya sendiri.
Sumber nilai user adalah getUserPrimaryValueAndClass(). Bila auth()->check() bernilai salah, metode itu mengembalikan id dan type bernilai null; bila benar, ia memakai auth()->id() atau kolom yang ditunjuk users_table_id_column_name (src/Observers/UserstampsObserver.php:91-10716). Siklus event selengkapnya diuraikan di Observer dan Siklus Event Model.
Kelas Userstamps
Berkas src/Userstamps.php hanya berisi class Userstamps {} tanpa satu pun metode (src/Userstamps.php:58), sehingga tidak ada logika yang dapat dipanggil darinya. Sementara itu composer.json mendaftarkan alias Userstamps yang menunjuk ke TwintyLabs\Userstamps\Facades\Userstamps (composer.json:69-789); direktori Facades tidak ada di dalam src/ pada commit ini. Jangan andalkan alias tersebut sebagai pintu masuk API paket.