Tim
Tim

Reputation: 456

Dynamic redirect to different controllers

My application has some entities in db, and each one contains data about controller name.

When route is called it calls MainController and followed method which then redirects to different controllers.

Is there any better way of doing this?

UPDATE

Routes.php

Route::get('/print-pdf/{uniqueID}', Logic\EditorController@dispatchPDF');

EditorController.php

protected function dispatchPDF(Request $request, $uniqueID){
   $ent = Entity::find($uniqueID);
   $variable_name = $ent->controller_name;  //for example: LSEntityController
   return resolve("\App\Http\Controllers".$variable_name)->printPDF();
}

Then each entity has different controller:

LSEntityController.php

protected function printPDF(Request $request, $uniqueID){ 
   $pdf = \PDF::loadView('map.2017.print',array('data' => $data));
   $pdf->setPaper('a4', 'portrait');
   return @$pdf->stream('data.pdf'); 

}

SOEntityController.php

 protected function printPDF(Request $request, $uniqueID){  

//here is the difference, this method must call some extra methods

   $this->compileAndReport();
   $pdf = \PDF::loadView('map.2017.print2',array('data' => $data));
   $pdf->setPaper('a4', 'portrait');
   return @$pdf->stream('data.pdf'); 
}

Upvotes: 0

Views: 144

Answers (2)

Dees Oomens
Dees Oomens

Reputation: 5082

Your entity shouldn't contain any information about a controller. It is best to let Laravel handle resolving controllers based on the request. An example of what you could do is:

Create a route for printing PDF to the browser.

Route::get('entities/{entity}/print', 'EntityController@print');

Then create a new controller with the following artisan command: php artisan make:controller EntityController.

The controller should look like this.

<?php

namespace App\Http\Controllers;

use App\Entity;
use Illuminate\Http\Request;

class EntityController extends Controller
{
    public function print(Entity $entity) 
    {

    }
}

Then in the print method you should create some code that prints the PDF. You could use a package for this, like barryvdh/laravel-dompdf.

EDIT

For your code you could update the controller_name row in your entities table to something like: requires_compiling, which could be a boolean. Then if the entity requires to run extra methods before streaming a PDF you could do this:

protected function printPDF(Entity $entity)
{  
    if ($entity->requires_compiling) {
        $this->compileAndReport();
    }

    $pdf = \PDF::loadView('map.2017.print2',array('data' => $data));
    $pdf->setPaper('a4', 'portrait');

    return @$pdf->stream('data.pdf'); 
}

Now you only need one controller for display the PDFs.

Upvotes: 2

delboy1978uk
delboy1978uk

Reputation: 12365

Why not send to one controller? Then switch the classname:

switch (get_class($entity)) {
    case 'ObjectA':
        $svc = new PdfPrintVersion1();
        $pdf = $svc->print($entity);
        break;
    case 'ObjectB':
        $svc = new PdfPrintVersion2();
        $pdf = $svc->print($entity);
        break;
}

Upvotes: 0

Related Questions