Better routing in Yii - 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'];

Related

How to validate route requests in 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

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().

ASP.Net Web API Route based on HTTP Method

Is there any way to route based on the HTTP method specified in the request? I'm looking to have a GET and PUT at the same URI, but I can't seem to find the option to set the route between the two. The [HttpGet] and [HttpPut] attributes merely act as filters, so a PUT request is hitting the first action and erroring out with a 405 since it hits the GEt handler first.
What I want to do
~/User/PP GET -> UserController.GetPrivacyPolicy
~/User/PP PUT -> UserController.UpdateUserPrivacyPolicy
Whats currently happening
~/User/PP GET -> UserController.GetPrivacyPolicy
~/User/PP PUT -> UserController.GetPrivacyPolicy
(this errors out because i have a [HttpGet] filter on the GetPrivacyPolicy method)
Update:
Just to compliment what was posted below, it looks like I misunderstood how the [HttpGet] and [HttpPut] attributes work, they ARE part of the routing process. I was able to achieve my desired result with the following
[HttpGet]
[Route("~/User/PP")]
public string GetPrivacyPolicy()
{
return "Get PP";
}
[HttpPut]
[Route("~/User/PP")]
public void UpdatePrivacyPolicy()
{
return "Put PP";
}
What you'll need to do is create your controller with identically named actions but decorated with different Http method attributes
public class UserController : Controller {
[HttpGet]
public ActionResult PrivacyPolicy(int id) {
// Put your code for GetPrivacyPolicy here
}
[HttpPut]
public ActionResult PrivacyPolicy(int id, YourViewModel model) {
// Put your code for UpdatePrivacyPolicy here
}
}
Of course there are appropriate actions for the other methods e.g. HttpPost, HttpDelete, HttpPatch.

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();
}
}