How to pass query string params to routes in Laravel4 - api

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

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 can I refer a laravel route to different api controllers based on type of the model type injected in the route?

I have an apiResource route whose URL contains a factory and a product model.
Depend on the product type, I need two different controllers. I also need to inject factory instance and product instance to both controllers. Something like this:
Route::apiResource('factories/{factory}/products', function(Product $product) {
if ($product->type == 'typeA') {
Route::apiResource('factories/{factory}/typeAs', 'TypeAController')
}
if ($product->type == 'typeB') {
Route::apiResource('factories/{factory}/typeBs', 'TypeBController')
}
}
1- The first question is what the correct way to do so is and how I should define the routes?
2- The second question is: product instance is injected into the main URL by its slug. I need the product instance to be injected in both sub routes. How should I do that?
You can use binding route in RouteServiceProvider. When your route have factory parameter, it returns you a model of factory which has product_id:
public function boot()
{
Route::bind('factory', function () {
$product_type = \App\Models\Factory::where('{factory}', request()->type);
return $product_type->firstOrFail();
});
parent::boot();
}

Passing array from AuthController to login view in Laravel 5

Am having a problem passing an array from Laravel's AuthController to auth.login view. What am trying to do is retrieve data from News model and send it to the view. I know how to use eloquent to retrieve data, passing from the controller to the view is my problem as I cannot see the how/where Laravel is rendering the view.
Add an array as second parameter to the view method when returning it in the controller.
return view('greetings', ['name' => 'Victoria']); // in controller
Then in your view, you should be able to access the variable $name which should be equal to Victoria
var_dump($name); // in view
More in the documentation
I solved it by passing the variable through the Controller on the redirect method.
I am not entirely sure what the objective is here, but you said:
I cannot see the how/where Laravel is rendering the view.
So to answer that:
Laravel's AuthController pulls in a trait AuthenticatesAndRegistersUsers which itself pulls in a few other traits, one being AuthenticatesUsers and another being RegistersUsers.
In AuthenticatesUsers you will find a method like so:
/**
* Show the application login form.
*
* #return \Illuminate\Http\Response
*/
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('auth.login');
}
There is likewise a similar method in the RegistersUsers trait.
This is where the AuthController returns its views.
If you need to tweak this behavior, or return the view with some data, you could override these methods in your controller, if this is really the best solution to your given situation.
Meanwhile I found a better way to do that.
You can override the showRegistrationForm() method in AuthController.php and pass along the data you want to use in the view. Ex.:
public function showRegistrationForm()
{
$results = Model::all();
return view('auth.register', ['results' => $results]);
}

Kohana - Best way to pass an ORM object between controllers?

I have Model_Group that extends ORM.
I have Controller_Group that gets a new ORM:
public function before()
{
global $orm_group;
$orm_group = ORM::factory('Group');
}
...and it has various methods that use it to get different subsets of data, such as...
public function action_get_by_type()
{
global $orm_group;
$type = $this->request->param('type');
$result = $orm_group->where('type', '=', $type)->find_all();
}
Then I have another controller (in a separate module) that I want to use to manipulate the object and call the relevant view. Let's call it Controller_Pages.
$orm_object = // Get the $result from Controller_Group somehow!
$this->template->content = View::factory( 'page1' )
->set('orm_object', $orm_object)
What is the best way to pass the ORM object from Controller_Group to Controller_Pages? Is this a good idea? If not, why not, and what better way is there of doing it?
The reason for separating them out into different controllers is because I want to be able to re-use the methods in Controller_Group from other modules. Each module may want to deal with the object in a different way.
This is the way I would do it, but first I would like to note that you shouldn't use global in this context.
If you want to set your ORM model in the before function, just make a variable in your controller and add it like this.
public function before()
{
$this->orm_group = ORM::factory('type');
}
In your Model your should also add the functions to access data and keep the controllers as small as possible. You ORM model could look something like this.
public class Model_Group extends ORM {
//All your other code
public function get_by_type($type)
{
return $this->where('type', '=', $type)->find_all();
}
}
Than in your controllers you can do something like this.
public function action_index()
{
$type = $this->request->param('type');
$result = $this->orm_group->get_by_type($type);
}
I hope this helps.
I always create an helper class for stuff like this
Class Grouphelper{
public static function getGroupByType($type){
return ORM::factory('Group')->where('type','=',$type)->find_all();
}
}
Now you're been able to get the groups by type where you want:
Grouphelper::getGroupByType($type);

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'];