konekt/concord
Laravel extension for building modular applications using conventions on top of service providers. Manage in-app and external modules with isolation-friendly structure, version compatibility across Laravel releases, and tooling around module registration and organization.
A module can ship with controllers which can be used directly or via predefined routes.
This feature is available since version 1.15
If you are developing a package you can allow the host application to modify the data injected into the views, by making the controller hookable.
This can be very useful if the application has knowledge and access to data that the package is not aware of.
To do this:
HasControllerHooks trait to your controller;processViewData() method.// Controller code in your package:
use \Konekt\Concord\Hooks\HasControllerHooks;
class ChannelController
{
use HasControllerHooks;
public function create()
{
return view('vanilo::channel.create', $this->processViewData(__METHOD__, [
'countries' => Countries::pluck('name', 'id'),
'currencies' => Currencies::choices(),
'domains' => [],
]));
}
public function edit(Channel $channel)
{
return view('vanilo::channel.edit', $this->processViewData(__METHOD__, [
'channel' => $channel,
'countries' => Countries::pluck('name', 'id'),
'currencies' => Currencies::choices(),
'domains' => [],
]));
}
}
Having the controller prepared this way, the application can modify the data passed to the view.
The example below will populate the domains variable that gets injected into the view with data:
// Application code, most commonly the AppServiceProvider::boot() method:
ChannelController::hookInto('create', 'edit')
->viewDataInjection(function (array $viewData): array {
$viewData['domains'] = tenant()->domains->pluck('domain', 'domain')->toArray();
return $viewData;
});
The hook will be called both in the create and the edit actions.
NOTE: This solution is not Concord-specific, Laravel provides these possibilities out of the box.
In case an app wants to extend a boxes controller AND wants to use the boxes built in routes, it should do the following thing:
You can put this code either in your app's RouteServiceProvider or the
AppServiceProvider (or any service provider you prefer).
Example:
//app/Providers/RouteServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
// [...]
public function boot()
{
parent::boot();
$route = Route::getRoutes()->getByName('vanilo.order.index');
$routeAction = array_merge($route->getAction(), [
'uses' => '\App\Http\Controllers\Admin\OrderController@index',
'controller' => '\App\Http\Controllers\Admin\OrderController@index',
]);
$route->setAction($routeAction);
$route->controller = false;
}
// [...]
}
The Custom Controller:
//app/Http/Controllers/Admin/OrderController.php
namespace App\Http\Controllers\Admin;
class OrderController extends \Vanilo\Framework\Http\Controllers\OrderController
{
public function index()
{
// Custom code
flash('Cogito ergo sum.');
// Invoke the original action - if you want
return parent::index();
}
}
Next: Commands »
How can I help you explore Laravel packages today?