NOTE: Every package should be as flexible as possible through published files (configs, views, translations and more),
put hooks in views, setting custom events, extending classes, pipelines and other means necessary - this is especially true for
administrations modules.
├── src
│ ├── config
│ │ ├── marinar_PACKAGE.php
│ │ ├── package.php
│ ├── Contracts
│ ├── Database
│ │ ├── migrations
│ │ ├── Seeds
│ │ │ ├── MarinarPACKAGESeeder.php
│ │ │ ├── MarinarPACKAGERemoveSeeder.php
│ ├── Http
│ │ ├── Controllers
│ │ ├── Middleware
│ │ ├── Requests
│ ├── Mixins
│ ├── Models
│ ├── ModelsBase
│ ├── resources
│ │ ├── lang
│ │ │ ├── en
│ │ ├── views
│ ├── routes
│ ├── Trait
│ ├── PACKAGE.php
│ ├── MarinarPACKAGEServiceProvider.php
├── composer.json
├── README.mdcomposer.json{
"name": "marinar/PACKAGE",
"description": "PACKAGE module",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "NAME",
"email": "YOUR_MAIL@dev.nddesign.no"
}
],
"autoload": {
"psr-4": {
"Marinar\\PACKAGE\\": "src/"
}
},
"require": {
"marinar/helpers": "*"
},
"extra": {
"marinar": {
"module": true,
"plugin": false,
"addon_to": false
},
"laravel": {
"providers": [
"Marinar\\PACKAGE\\MarinarPACKAGEServiceProvider"
],
"aliases": {
"MarinarPACKAGE": "Marinar\\PACKAGE\\MarinarPACKAGE"
}
}
}
}composer.json add"repositories": [
{
"type": "path",
"url": "packages/marinar/PACKAGE"
}
...
"repositories": [
{
"type": "path",
"url": "packages/marinar/PACKAGE",
"options": {
"symlink": false
}
}
...
Run composer dump-autoload - to register the new classes
Create the package ServiceProvicer
namespace Marinar\PACKAGE;
use Illuminate\Support\ServiceProvider;
class MarinarPACKAGEServiceProvider extends ServiceProvider {
public function boot() {
MarinarOrders::preHandle();
if(!\provider_url_check(config('marinar_PACKAGE.provider_route_prefixes')))
return;
$this->loadViewsFrom(__DIR__ . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'views', 'marinar_orders');
$this->loadTranslationsFrom(__DIR__ . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'lang', 'marinar_orders');
MarinarOrders::handle();
}
public function register() {
config(['marinar_orders.package_dir' => __DIR__]);
$this->mergeConfigFrom(__DIR__ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'marinar_orders.php', 'marinar_PACKAGE');
$this->publishes([
__DIR__ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'marinar_orders.php' => config_path('marinar_PACKAGE.php'),
], 'config');
$this->publishes([
__DIR__ . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'views' => resource_path('views/vendor/marinar_PACKAGE'),
], 'views');
$this->publishes([
__DIR__ . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'lang' => resource_path('lang/vendor/marinar_PACKAGE'),
], 'translations');
$this->loadMigrationsFrom(__DIR__ . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'migrations');
MarinarOrders::regHandle();
\PackagesSeeder::$package_seeders[] = \Marinar\PACKAGE\Database\Seeds\MarinarPACKAGESeeder::class;
\TestDataSeeder::$package_seeders[] = \Marinar\PACKAGE\Database\Seeds\MarinarPACKAGETestSeeder::class;
}
}Facade namespace Marinar\PACKAGE;
class MarinarPACKAGE {
public static function route_links() {
return __DIR__.DIRECTORY_SEPARATOR.'routes'.DIRECTORY_SEPARATOR.'web.php';
}
public static function lang_path() {
return __DIR__.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'lang';
}
public static function handle() {
//...
}
public static function preHandle() {
//...
}
public static function regHandle() {
//...
}
}config/marinar_PACKAGE.php return [
//...
//for script, which handle specific routes - facade `handle` method
'provider_route_prefixes' => [
'admin',
'employee',
'salon'
],
//...
];database/seeds/MarinarPACKAGESeeder.phpnamespace Marinar\PACKAGE\Database\Seeds;
use Illuminate\Database\Seeder;
class MarinarPACKAGESeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run() {
$ordersModule = \App\Module::updateOrCreate([
'package' => 'marinar/orders',
], [
'package_prefix' => 'marinar_PACKAGE',
'facade' => 'MarinarPACKAGE',
'version' => '0.0.1', //your version - not required really
'name' => 'PACKAGE',
'icon' => 'fa fa-cubes', //admin icon
'admin_uri' => 'package', //admin uri prefix
]);
}
}remove seeder - database/seeds/MarinarPACKAGERemoveSeeder.phpnamespace Marinar\PACKAGE\Database\Seeds;
use Illuminate\Database\Seeder;
class MarinarPACKAGERemoveSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run() {
\App\Module::wherePackage('marinar/orders')->delete();
}
}config/package.php - for auto install and remove commands$dbDir = [ dirname(__DIR__), 'Database', 'migrations' ];
$dbDir = implode( DIRECTORY_SEPARATOR, $dbDir );
return [
'install' => [
'php artisan migrate --realpath --path="'.$dbDir.DIRECTORY_SEPARATOR.'2019_07_09_115803_create_infopages_table.php" -n',
'php artisan db:seed --class="\Marinar\Infopages\Database\Seeds\MarinarInfopagesSeeder" -n'
],
'remove' => [
'php artisan migrate:refresh --realpath --path="'.$dbDir.DIRECTORY_SEPARATOR.'2019_07_09_115803_create_infopages_table.php" -n',
'php artisan migrate:rollback --realpath --path="'.$dbDir.DIRECTORY_SEPARATOR.'2019_07_09_115803_create_infopages_table.php" -n',
'php artisan db:seed --class="\Marinar\Infopages\Database\Seeds\MarinarInfopagesRemoveSeeder" -n'
]
];Modules are packages for administrating. They give tools and interfaces for list, create, change and delete information.
Modules should give options that help extending them:
hooks - mainly @addons blade directive@addons($addons, "infos_table_th_after_edit")eventsevent( 'info.submited', [$info, $validatedData] );pipelines$subBldQry = app(Pipeline::class)
->send( Infopage::getModel() )
->through(array_merge(
Addon::hookedFacadeMethods( Addon::sortedFacades('marinar/infopages'), 'index_sub_infos' ),
(isset(static::$addon_methods['index_sub_infos'])? static::$addon_methods['index_sub_infos'] : [] )
))
->then(function($bldQry) use ($table) {
$bldQry = $bldQry->orderBy("{$table}.id", 'ASC');
return $bldQry;
}); public static $addon_validations = [
'pipes' => [],
'rules' => [],
'messages' => [],
];Plugins are packages which give logic, which can be used in different modules or addons.
It's good practice to give some functionality, which can be used for validations and submiting (Facade methods).
components are main tools for using same view in many places:Blade::aliasComponent('marinar_activiable::components.activiable', 'activiable');Trait and Mixins are main tools for using same logic in many classes - be careful that in most situation they shouldAddons are extensions to modules. Addon package can be module itself and can be connected to multiple modules, too.
For addons connected to some administration module you can:
macros and `mixins'Infopage::macro('someMethod', function($args) { //macro
//do you stuff
});
Infopage::mixin( new OrderableMixin, false ); //mixinApp\Traits\Addonable for more )Infopage::$addonStatics['ordField'] = 'ord'; //for public static property
Infopage::$addonFillable[] = 'ord';//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 EVENTSInfopageController::$addon_methods['index'][] = function($data, \Closure $next) {
list($bldQry, $viewData) = $data;
$table = Infopage::getModel()->getTable();
$ordField = Infopage::getOrdField();
$bldQry = $bldQry->orderBy("{$table}.{$ordField}", 'ASC');
return $next([$bldQry, $viewData]);
};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);
};project addoning - class or fasade declared in 'config/addons'hook static methods. If such method exists in the facade it will be put in pipeline array.Example for hook static method which is used for lazy extending:
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);
}Extending module views - make blade file with the name of the module view hook
and more ...
GIT bare repository on Turshiassh lpackages@193.93.255.240
cd gits
git init --bare PACKAGE.gitgit remote add turshia ssh://lpackages@193.93.255.240/home/lpackages/gits/PACKAGE.gitMake repository in GITHUB
Tag your package version
git tag v0.0.1git push turshia master
git push turshia --tags
git push -u github master
git push -u github --tagsgit tag -d v0.0.1
git push turshia :v0.0.1
git push -u github :v0.0.1Commit your changes
Add new GIT tag and push to remote repositories
git tag v0.0.1
git push turshia master
git push turshia --tags
git push -u github master
git push -u github --tags