Extending modules is through two types:

New Package development

The process goes through this steps:

  1. Prepare addon development package - you can check Packages documentation
  2. For addon seeder should be create addon to particular module:
if(!($infopagesModule = \App\Module::wherePackage_prefix( 'marinar_infopages' )->first())) {
    return;
}
$infopagesModule->addons()->updateOrCreate([
    'package' => 'marinar/infopages_metable',
], [
    'version' => '0.0.1',
    'package_prefix' => 'marinar_infopages_metable',
    'facade' => 'MarinarInfopagesMetable',
    'name' => 'Infopage metable',
]);

NOTE: 'facade' is important for finding addon routes, translations and lazy extending

  1. If there are addon's routes - you can use facade's static method route_links, which return the path to routes
    declarations file.
public static function route_links() {
    return __DIR__.DIRECTORY_SEPARATOR.'routes'.DIRECTORY_SEPARATOR.'web.php';
}
  1. If there are addon's translations - you can use facade's static method lang_path, which return the path to
    translations directory.

NOTE: This is needed for translations module.

public static function lang_path() {
    return __DIR__.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'lang';
}
  1. Extending models and listen for modules and models events - can, be made normally - check Packages documentation
public static function preHandle() {
    Infopage::mixin( new OrderableMixin, false );
    Infopage::mixin( new InfopageOrderableMixin, false );
    Infopage::$addonStatics['ordField'] = 'ord'; //for public static property
    Infopage::$addonFillable[] = 'ord';
}
public static function handle() {
    //EVENTS
    Infopage::creating(Infopage::class . '@onCreating_orderable');
    Infopage::updating(Infopage::class . '@onUpdating_orderable');
    Infopage::updated(Infopage::class . '@onUpdated_orderable');
    Infopage::deleted(Infopage::class . '@onDeleted_orderable');
    //END EVENTS
}
  1. Hooking

NOTE: This is not preferable, because of used resources everywhere, not only
where are needed

InfopageRequest::$addon_validations['pipes']['marinar_infopages_uriable'] = function($request, \Closure $next) {
    InfopageRequest::$addon_validations['rules'] = array_merge(
        MarinarUriable::validation_rules(
            config('marinar_infopages.input_bag'),
            array_keys(config('marinar_infopages_uriable.point_to_options')),
            'marinar_infopages_uriable::validation.uri',
            true, //with base
            true, //check for same slug
            ($chInfo = request()->route(config('marinar_infopages.route_param_chInfo')))
        ),
        InfopageRequest::$addon_validations['rules']
    );
    InfopageRequest::$addon_validations['messages'] = marinar_assoc_arr_merge(
        (array)trans('marinar_uriable::validation'),
        (array)trans('marinar_infopages_uriable::validation'),
        InfopageRequest::$addon_validations['messages']
    );

    $inputBag = config('marinar_infopages.input_bag');
    $request = MarinarUriable::validation_prework($request, $inputBag);

    //some prework on request
    return $next($request);
};

EXAMPLE: hook to infopages validation module request

public static function request($request, \Closure $next) {
    InfopageRequest::$addon_validations['rules'] = array_merge(
        InfopageRequest::$addon_validations['rules'],
        MarinarMetable::validation_rules( 'marinar_infopages_metable::validation' )
    );
    InfopageRequest::$addon_validations['messages'] = marinar_assoc_arr_merge(
        (array)trans('marinar_metable::validation'),
        (array)trans('marinar_infopages_metable::validation'),
        InfopageRequest::$addon_validations['messages']
    );
    return $next($request);
}

NOTE: this way this script will be executed only when request in module is made.

Project addoning

This extending type is mainly for fast fixes, and small project changes.

  1. Make some facade or class
namespace App\Http\Addons;
use Marinar\Infopages\Http\Requests\InfopageRequest;

class Infopages {

    public static function request($request, \Closure $next) {
        InfopageRequest::$addon_validations['rules'] = array_merge(
            InfopageRequest::$addon_validations['rules'],
            [ 'add.subtitle' => 'required|max:255' ]
        );

        InfopageRequest::$addon_validations['messages'] = marinar_assoc_arr_merge(
            (array)trans('admin/addons/infopages/validation'),
            InfopageRequest::$addon_validations['messages']
        );
        return $next($request);
    }

    public static function templatePrefix() {
        return 'admin.addons.infopages';
    }
}
  1. Add facade or class at config/addons set to key as module package name
'marinar/infopages' => [
    \App\Http\Addons\Infopages::class,
]

NOTE: Dynamic project declared addoning is after normal addons if not sorted manually

  1. Extending models and listen for modules and models events on this type is still through help of Service provider,
    which must be made

  2. Hooking - like in New Package development

  3. Template prefix - return the path to directory, where addon's blade templates can be found.
    NOTE: it's used for @addons blade component.

  4. Migrations and routes should be put as normal in laravel project.

Sorting

For the perpose of addons sorting are created config files:

  1. config/addons_request - for sorting scripts which hook to declared module's hooks. Here the facades or classes
    should be order manually, in order the client want, set to key as module package name
'marinar/infopages' => [
    'MarinarInfopagesUriable',
    'MarinarInfopagesMetable'
]

NOTE: If there are other addons not set in this order but still declared in config/addons or in database they will
be put last.

  1. config/addons_prefix - order addon's template searching. Here should be put manually addon's template prefixes to
    key as module package name.
'marinar/infopages' => [
    'admin.addons.infopages',
    'marinar_infopages_uriable',
]

NOTE: If there are other addons not set in this order but still declared in config/addons or in database they will
be put last.