How to validate route requests in Laravel 9? - laravel-9

I've got a route like this:
Route::get('/{library}/{media}/{genre}/{title}', [BookController::class, 'showBook']);
And controller:
class BookController extends Controller
{
public function showBook(Request $request, $library, $media, $genre, $title)
{
//??
}
}
Now how do I validate all these parameters to make sure they are valid slugs before I use them in an Eloquent query?
Should I extend FormRequest and add rules there?

You can use the find or fail method on each model:
Library::findOrFail($library);
Media::findOrFail($media);
// etc
This will return a collection, or fail out if false.
https://laravel.com/docs/9.x/eloquent#not-found-exceptions

Related

How to Redirect from one view to another view with data - Yii2

i want to pass 1 variables from a view to another view with post method. use this redirect code but its not working
Yii::$app->getResponse()->redirect('home','id'=>$id)->send();
try this
Yii::$app->getResponse()->redirect(['home','id' => $id])->send();
For the sake of completeness in a controller context you may use:
class MyController extends \yii\web\Controller
{
public function actionIndex()
{
return $this->redirect(['home', 'id' => 123]);
}
}
Where the array parameter of redirect() is equal to yii\helpers\Url::to().

How to pass query string params to routes in Laravel4

I'm writing an api in Laravel 4. I'd like to pass query string parameters to my controllers. Specifically, I want to allow something like this:
api/v1/account?fields=email,acct_type
where the query params are passed along to the routed controller method which has a signature like this:
public function index($cols)
The route in routes.php looks like this:
Route::get('account', 'AccountApiController#index');
I am manually specifying all my routes for clarity and flexibility (rather than using Route::controller or Route::resource) and I am always routing to a controller and method.
I made a (global) helper function that isolates the 'fields' query string element into an array $cols, but calling that function inside every method of every controller isn't DRY. How can I effectively pass the $cols variable to all of my Route::get routes' controller methods? Or, more generally, how can I efficiently pass one or more extra parameters from a query string through a route (or group of routes) to a controller method? I'm thinking about using a filter, but that seems a bit off-label.
You might want to implement this in your BaseController. This is one of the possible solutions:
class BaseController extends Controller {
protected $fields;
public function __construct(){
if (Input::has('fields')) {
$this->fields = Input::get('fields');
}
}
}
After that $fields could be accessed in every route which is BaseController child:
class AccountApiController extends \BaseController {
public function index()
{
dd($this->fields);
}
}

Creating a simple controller alias

I'm not sure I am using the proper terminology, so I will describe what I want to achieve.
I have a controller called ControllerA and want a "virtual" controller called ControllerB to function exactly the same as ControllerA.
Basically I just want the url site.com/ControllerB to load up the same page as site.com/ControllerA (but not redirect).
Hope my description is clear enough.
You can achieve what you want with a simple URL rule:
'controllerA/<a>' => 'controllerA/<a>',
'controllerB/<a>' => 'controllerA/<a>',
Read more about URL rules here: http://www.yiiframework.com/doc/guide/1.1/en/topics.url#user-friendly-urls
You can extend ControllerA with ControllerB and provide extended controller name. Next override getViewPath method. Attribute extendedControler give us basic controller name.
class ControllerBController extends ControllerAController
{
private $extendedControler = 'ControllerA';
public function getViewPath() {
$nI = Yii::app()->createController($this->extendedControler);
return $nI[0]->getViewPath();
}
}
Of course you can use some string modification. Like str_ireplace:
class Klient2Controller extends KlientController
{
public function getViewPath() {
//We must extract parent class views directory
$c = get_parent_class($this);
$c = str_ireplace('Controller', '', $c); //Extract only controller name
$nI = Yii::app()->createController($c);
return $nI[0]->getViewPath();
}
}

how to implement afterSave method to a specific controller action only?

let's say i have model A..then this model A is being used by many controllers...
now I want to implement the afterSave method, only in one of the controllers that uses
model A . e.g in Controller C it calls the save() function, so I want the afterSave to be called in that function only.how is that ?
protected function afterSave()
{
parent::afterSave();
if($this->isNewRecord)
{
echo "hello";
exit;
}
}
BECAUSE: afterSave() affects all the save() call of all the controllers that uses the Model A
You can try this in you afterSave function :
if (Yii::app()->controller->id!=='yourcontroller')
{
// do what you want
}
If needed, you can also test value of Yii::app()->controller->action->id.
EDIT : or take a look at Jelle de Fries answer.
I don't get why you would need an afterSave() method for this.
In your action you are calling $model->save().
Can't you just do what you have to do after calling this?
like so:
public function actionMyAction(){
$model=new myModel;
$model->attribute = 5;
$model->save();
$model->doLogicAfterSave(); //<-this
$this->render('myView',array(
'model'=>$model,
));
}
Since it's only for 1 controller.

Better routing in Yii

I'm new to Yii. I have a controller like this:
<?php
class EventsController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
}
How can i make the following url render the correct view. eg.
localhost/events/intaglio -> $this->render('intaglio');
localhost/events/burrito-> $this->render('burrito');
localhost/events/jerrito -> $this->render('jerrito');
Worse case, I'll have to have separate actions for each
public function actionIntagio {...}
public function actionBurrito {...}
public function actionJerrito {...}
Is there a smarter way of doing this?
Setup URL rules (in protected/config/main.php) to handle those URL's dynamically, eg:
events/<event_name:.+> => events/myaction
This points any URL with events/whatever to the Controller/Action events/myaction. You can then access the event_name portion of the URL with a $_GET variable, eg:
echo $_GET['event_name'];