I have a route defined which calls a test function in TestController.
Route::get('/test/{function_name}','TestController#test');
This test function calls internally the function that matches the name inside the TestController.
This works for the functions that doesn't need paramters. However certain functions needs paramters and then the route becomes invalid.
public function test($function_name)
{
try
{
var_dump($this->$function_name());
return;
}
catch(Exception $ex)
{
throw $ex;
}
}
// This functions get called fine
public function getRecord(){}
// But this functions does not work because i am passing extra paramters in the url which in turns makes the route invalid
public function getRecordByNameAndPrice($name, $price){}
So is there any way that i can defined a route in such a way that it should contain 1 parameter but should also allow N number of extra parameters so that i can call those functions that needs paramters.
Thanks
Use the where method to allow your rest to contain slashes:
Route::get('test/{func}/{rest?}', 'TestController#test')->where('rest', '.*');
Then use $request->segments() to get them all as separate values:
public function test($method, Request $request)
{
$params = array_slice($request->segments(), 2);
return call_user_func_array([$this, $method], $params);
}
Don't forget to use Illuminate\Http\Request up top.
let's say your url is
/products?id=999&format=json&apikey=123456
and define your route like this
Route::get('/prodcuts',function(){
return Request::all();
})
// output
{"id":"999","format":"json","apikey"=>"123456"}
Related
In my API I used "with" method to get parent's model relation and everything works fine.
I want to add an attribute in my relation and return it in my API but I should use request in my model.
Something like this :
Book.php
protected $appends = ['userState'];
public function getUserStateAttribute () {
return User::find($request->id); //request not exists here currently
}
I have $request in my controller (api controller)
Controller.php
public function get(Request $request) {
Post::with('books')->all();
}
I believe using static content to append in array of model is so easy but how about using request's based content ?
I guess you can use request() helper :
public function getUserStateAttribute () {
return User::find(request()->get('id'));
}
Sure this is not really MVC pattern, but it can work
You want to take request as a parameter here:
public function getUserStateAttribute (Request $request) {
return User::find($request->id);
}
That way you can access it in the function. You will just need to always pass the Request object whenever you call that function.
e.g. $book->getUserStateAttribute($request);
Alternatively, you could just pass the ID, that way you need not always pass a request, like so:
public function getUserStateAttribute ($id) {
return User::find($id);
}
Which you would call like:
e.g. $book->getUserStateAttribute($request->id);
i have 2 routes with POST methods
Route::post('/payment/checkOrder','Finance\PaymentCallbackController#checkOrder');
Route::post('/payment/paymentAviso', 'Finance\PaymentCallbackController#paymentAviso');
how can i create legacy links for these routes?
/plat.php?paysystem=5&method=checkOrder
/plat.php?paysystem=5&method=paymentAviso
You can have a single route that recieves a method string, and then call the desired functions according to it.
Route::post('/payment/{method}','Finance\PaymentCallbackController#handler');
// PaymentCallbackController.php
public function handler(Request $request){
// make sure to validate what methods get sent here
$this->{$request->method}($request);
// use $this if its in this controller, for otherControllers
// try something with the looks of app('App\Http\Controllers\OtherControllerController')->{$request->method}->($request);
}
Add this route:
Route::post('/plat.php', 'SomeController#action');
In your controller function:
// SomeController.php
public function someAction()
{
$paysystem = $request->query('paysystem');
$method = $request->query('method');
// some logic here
return view('something');
}
I am creating a public API using Laravel 5.2. To keep the code in the controller short, I have created several helper functions, one of which is a function to return a response to the API call, as shown below:
if (! function_exists('buildResponse'))
{
function buildResponse($data)
{
return response()->json($data)->header('foo', 'bar');
}
}
This is how I would call it from the controller:
public function registration()
{
buildResponse(['a' => 'Success']);
}
However this does not work. It only works if I add a return in front of the function.
public function registration()
{
return buildResponse(['a' => 'Success']);
}
One might say, "Okay, then just include the return!". The thing is, this particular function will be called by another helper function, for example:
if (! function_exists('throwResponseCode'))
{
/**
* Throws a response code to the client.
* #param $code
* #return mixed
*/
function throwResponseCode($code)
{
switch ($code) {
case '101':
$data[$code] = 'Unable to establish a database connection';
return buildResponse($data);
// Other cases here
}
}
}
Is there any way that I can send a response to the client from the helper function?
Keep it simple bro!
Change
return response()->json($data)->header('foo', 'bar');
To
return response()->json($data)->header('foo', 'bar')->send();
Short answer, no. Not directly.
The purpose of return is to finish the function and give results. Laravel considers the return value of controller to be the response, so other functions can not do this using return.
There are someways around this. Consider this. Create a middleware, that works after the response has been generated by controller, i.e. calls $next($request) in the first line. Here you can change the response as you wish. To connect helpers to this middleware, you can use static methods or properties. The logic of middleware would be that if someone has put something in, say, $response static property of middleware, then send this one instead of controller response.
So I have a Laravel Controller (MainController.php) with the following lines:
...
public function _settings_a(){
return view('_settings_a');
}
public function _settings_b(){
return view('_settings_b');
}
public function _settings_c(){
return view('_settings_c');
}
public function _settings_d(){
return view('_settings_d');
}
public function _staff_a(){
return view('_staff_a');
}
public function _staff_b(){
return view('_staff_b');
}
public function _staff_c(){
return view('_staff_c');
}
...
And my routes.php is as follows:
Route::any('_staff_a''MainController#_staff_a');
Route::any('_staff_b''MainController#_staff_b');
...
etc.
It seems there are a LOT of lines and a LOT of things to change if I change my mind...
I was wondering if I can have some regex in routes.php and an equivalent regex in MainController.php for handling routes that begin with an underscore (_)?
Can any Laravel experts share some tips/suggestions? I'm quite new to the framework.
Sure - just add it as a parameter. E.g. like this:
Route::any('_staff_{version}', 'MainController#_staff');
public function _staff($version) {
return view('_staff_'.$version);
}
I don't think you need to mess with regex. You can use implicit controllers Route::controller() which isn't the BEST solution, but will do what I think you are wanting.
So instead of
Route::any(..)
you can do
Route::controller('url', 'MainController');
So your route to whatever 'url' is will send you to this controller. Follow that with a '/' and then add whichever method in the controller you want to call.
Here is an example:
My url: 'http://www.example.com/users'
// routes.php
Route::controller('users', UserController');
// UserController.php
public function getIndex()
{
// index stuff
}
Now I send a request like: http://www.example.com/users/edit-user/125
// UserController.php
public function getEditUser($user_id)
{
// getEditUser, postEditUser, anyEditUser can be called on /users/edit-user
// and 125 is the parameter pasted to it
}
Doing it this way should allow you to be able to just send a request (post or get) to a url and the controller should be able to call the correct method depending on the url.
Here are some more rules about it: http://laravel.com/docs/5.1/controllers#implicit-controllers
I am building RESTful API in Zend Framework 2. My route is article/person. I know that if id is not passed in url then it will call getList() method, not get().
In my case, I don't pass id as a get or post parameter but I pass it in HTTP header. As I use id to perform database operations, I want it to call get() method, not getList(). How can I tweak the code to do that?
Is it possible to specify exact method name to call in routing?
I don't pass id as a get or post parameter but I pass it in HTTP header
This does make your REST invalid, so it isn't actually REST anymore. You therefor cannot use the RestfulAbstractController without customization.
You can either write your own abstract controller or you override the getIdentifier method:
protected function getIdentifier($routeMatch, $request)
{
$identifier = $this->getIdentifierName();
$headers = $request->getHeaders();
$id = $headers->get($identifier)->getFieldValue();
if ($id !== false) {
return $id;
}
return false;
}
Make sure you set the correct identifier name in each controller. In this case, the identifier name should match the name of the header you are using.
Note this will be used for GET, PUT, PATCH, DELETE and HEAD requests, not only for GET!
/edit:
The getIdentifier method is called in the flow a controller determines which method to run. Normally, it's this:
The controller is constructed
The controller's dispatch is called (the controller is Dispatchable)
The dispatch triggers an event "dispatch"
The method onDispatch listens to this event
In the AbstractRestfulController the method tries to determine which method to call
For #5, it checks for example if the request is a GET request. If so, it checks if there is an identifier given. If so, the get() is used. If not, the getList() is used. The "if there is an identifier given" check is done with the getIdentifier() method.
If you extend the AbstractRestfulController with your own abstract controller and override the getIdentifier(), you can determine your own identifier. This way, you can check for the header instead of the route parameter or query parameter.
Override AbstractRestfulController to be able to tweak all the functionality related to the id.
class YourController extends AbstractRestfulController {
//in the constructor, ensure that your id name is set to the header variable you are using
public function __construct() {
$this->identifierName = 'id'; // Override $identifierName value specified in AbstractRestfulController, if you need it
}
protected function getIdentifier($routeMatch, $request)
{
//first of all, check if the id is set in the $routeMatch params, this is, in the normal way
$id= parent::getIdentifier($routeMatch, $request);
if ($id !== false) {
return $id;
}
//if the id its not set, check out the headers
$id = $request->getHeaders()->get($this->getIdentifierName())->getFieldValue();
if ($id !== false) {
return $id;
}
return false;
}
}
I think the easiest approach is to call get method from getList method
public function getList(){
// get id from header
$id = $this->getRequest()->getHeaders()->get("id-header-field");
if ($id){
return $this->get($id);
}
else{ /* return list */}
}
public function get($id){
return JsonModel($data);
}