Each topic has basic crud functionality ?? You can abstract this away. I made this for an app that have ~10 entities.
First, you need a topic interface.
<?php namespace App\Types;
interface TopicInterface{
public function performSave(Array $data = []);
public function performDestroy(Array $data = []);
// Whatever method common to all topics
}
Then each topic implements it
<?php namespace App\Entities;
class Supplier extends Model implements TopicInterface{
// Implementation of performSave and performDestroy
}
Do this with form requests too. TopicFormRequestInterface etc.
Then you can bind the correct implementation of the topic based on the first segment of the url. Use config to do the mapping.
# file : config/your_app_name.php
return [
'topics' => [
'supplier' => [
'fqcn_model' => 'App\Entities\Supplier',
'fqcn_form_request' => 'App\Http\Requests\SupplierFormRequest',
'view_namespace' => 'resources/views/suppliers',
],
// ...
],
];
Then you can bind the Model and FormRequests and register the view namespace based on the first segment of the url :
use Illuminate\Http\Request;
use Illuminate\Contracts\View\Factory as ViewFactory;
class AppServiceProvider extends ServiceProvider {
public function register(Request $request, ViewFactory $view)
{
$config = config('your_app_name');
$topic_token = $request->segment(1);
$this->app->bind('App\Types\TopicInterface', $config['topic'][$topic_token]['fqcn_model']);
$this->app->bind('App\Types\TopicFormRequestInterface', $config['topic'][$topic_token]['fqcn_form_request']);
$view->prependNamespace('topics', [base_path($config['topic'][$topic_token]['view_namespace'])]);
}
}
Then you can inject it in your TopicsController. And use the view namespace.
use App\Types\TopicInterface;
use App\Types\TopicFormRequestInterface;
class TopicsController extends controller{
private $topic;
public function __construct(TopicInterface $topic)
{
$this->topic = $topic;
}
public function index()
{
$topics = $this->topic->all();
return view('topics::index', ['topics' => $topics]);
}
public function show($topic_token, $id)
{
$topic = $this->topic->findOrFail($id);
return view('topics::show', ['topic' => $topic]);
}
public function save(TopicFormRequestInterface $request, $topic_token)
{
$topic = $this->topic->newInstance();
$topic->performSave($request->all());
redirect('topics.show', [$topic_token, $topic]);
}
// Etc etc....
}
Last thing you route all the topics to the topic controller :
$topic_tokens = array_keys(config('your_app_name.topics'));
$router->pattern('topic', implode('|', $topic_tokens));
$router->get('{topic}', ['as' => 'topics.index', 'uses' => 'TopicsController@index']);
$router->get('{topic}/{id}', ['as' => 'topics.show', 'uses' => 'TopicsController@show']);
// Etc etc....
If one of your Topic have a very specific implementation a particular action, you can create its own Controller, extends it from the TopicsController and override this specific action.