Skip to content

MethodTransformers ​

Namespace: Unusualify\Modularous\Repositories\Logic\MethodTransformers

The lifecycle-hook dispatcher at the heart of every Repository. Composes ManageTraits (which enumerates hook methods from loaded traits via naming conventions) and CacheableTrait. All repository traits plug into the lifecycle through this class.

Lifecycle Methods ​

Each method fans out to every {hookName}{TraitName} method discovered by traitsMethods():

MethodSignatureWhen called
prepareFieldsBeforeCreate($fields): arrayBefore model->create()
prepareFieldsBeforeSave($object, $fields): arrayBefore any $object->save() — receives and must return modified $fields
beforeSave($object, $fields): voidJust before $object->save()
afterSave($object, $fields): voidImmediately after save — side effects (file moves, pivot syncs, etc.)
afterUpdateBasic($object, $fields): voidAfter a basic update (non-form-save path)
afterDelete($object): voidAfter soft-delete
afterForceDelete($object): voidAfter hard-delete
afterRestore($object): voidAfter restore from trash
hydrate($object, $fields): ModelSets in-memory relationships on the model before save
getFormFields($object, $schema, $noSerialization): arrayBuilds the full form-field payload for the edit form — calls setColumns() first
getShowFields($object, $schema): arrayBuilds the field payload for a show/detail view
filter($query, $scopes): BuilderApplies all filter hooks from traits, then processes remaining scopes (scoped methods, LIKE, whereIn, exact-match)
order($query, $orders): BuilderApplies all order hooks from traits, then applies explicit column→direction orders
getTableFilters($scope): arrayAggregates filter tab definitions from all traits
getFormActions($scope): arrayAggregates form action button definitions from all traits
appendFormSchema($scope): arrayAggregates schema additions to append to the form
prependFormSchema($scope): arrayAggregates schema additions to prepend to the form

Column Management ​

MethodSignatureDescription
setColumns($inputs): voidCalls every setColumns{Trait} hook, merges results into $this->traitColumns
getColumns(?string $trait): arrayReturns the registered column names for a specific trait (used inside trait hooks to know which inputs they own)
traitHasInput(string $traitClass, string $inputName): boolChecks if a given trait has registered a specific input name
anyTraitHasInput(array $traitClasses, string $inputName): boolReturns true if any of the given traits owns the input name

Field Cleanup ​

cleanupFields($object, $fields) runs automatically before every prepareFieldsBeforeCreate / prepareFieldsBeforeSave:

  • Checkboxes ($model->checkboxes): missing → false, present → cast to bool.
  • Nullable ($model->nullable): missing fields → null.

Scope Filtering (in filter()) ​

The filter() method processes scopes in three passes:

  1. Trait hooks — each filter{Trait}($query, $scopes) runs first, modifying the query in-place.
  2. Relation scopes (addRelation{Relation}) — resolved via reflection; handles MorphTo, HasOneThrough, HasOne, and BelongsTo automatically.
  3. Remaining scopes — dispatched as:
    • Eloquent scope method if $model->hasScope($column)
    • LIKE if column starts with %
    • Negation (!value) → <>
    • Array value → whereIn
    • Scalar value → where

Status Counts ​

getCountByStatusSlug($slug, $scope) delegates to trait-level getCountByStatusSlug{Trait} hooks, falling back to the built-in slugs: all, published, draft, trash.

Usage ​

php
// The lifecycle methods are called by Repository internally.
// Override in your repository class to customise behaviour:

class PostRepository extends Repository
{
    use TranslationsTrait, FilesTrait;

    public function prepareFieldsBeforeSaveMyHook($object, $fields): array
    {
        $fields['slug'] = Str::slug($fields['title']);
        return $fields;
    }
}