How to get retuned value from one laravel route into another route - php

How to get value of one route into another
Route::get('/first_url', function () {
return "Hello this is test";
});
I Tried something like this but not worked.
Route::get('/second_url', function () {
$other_view = Redirect::to('first_url');
});
I want to get returned value from first_url to variable $other_view in second_url to process and manipulate returned value.
Using Redirect is changing url. Which I dont want to use.
Any Idea ??? Or Am I trying wrong thing to do.

If you just want to return first_url, do this:
Route::get('/first_url', ['as' => 'firstRoute', function () {
return "Hello this is test";
}]);
Route::get('/second_url', function () {
return redirect()->route('firstRoute');
});
Learn more about redirects to routes here.
Update:
If you want to pass variable, you can use form or just create a link with parameters. You can try something like this {{ route('second_url', ['param' => 1]) }}
Then your second route will look like this:
Route::get('/second_url/{param}', ['uses' => 'MyController#myMethod', 'param' => 'param']);
And myMethod method in MyController:
public function myMethod($param){
echo $param;
...

I don't know why you would like to do this, but you can get the rendered contents of the route by executing a simple HTTP request to your route and reading the contents:
Route::get('/second_url', function () {
$other_view = file_get_contents(URL::to('first_url'));
return $other_view; // Outputs whatever 'first_url' renders
});

You need to send HTTP request and then process the response. You can use file_get_contents as #tommy has suggested or you can use HTTP library like Guzzle:
$client = new GuzzleHttp\Client();
$res = $client->get(route('firstRoute'));

in this case u should use a named route.
https://laravel.com/docs/5.1/routing#named-routes
somthing like this:
Route::get('/first_url', ['as' => 'nameOfRoute', function () {
return "Hello this is test";
}]);
Route::get('/second_url', function () {
redirect()->route('nameOfRoute');
});

You can not pass the variable value to another route directly. http is stateless protocol. if you want to preserve the value of variable to another route you can do that by 3 methods query string, sessions and cookies only. Your can pass parameter to to specific route like this
Route::get('/second_url/{param}', ['uses' => 'MyController#myMethod',
'param' => 'param']);

The idea behind achieving what you want is naming the function of your first route and calling it within both the first route and your second route. Your function will simply return the view to the first route, and retrieve the rendered html for your second.
function MyFirstRouteFunction() {
// Do whatever your do in your first route
// I assume your function return here an instance of Laravel's View
}
Route::get('/first_url', MyFirstRouteFunction);
Route::get('/second_url', function () {
$contentsOfFirstRoute = MyFirstRouteFunction()->render();
// Make use of rendered HTML
});
There is no need to make one extra HTTP request.

You should use Guzzle or curl to achive this:
Route::get('/second_url', function () {
//:::::Guzzle example:::::
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'http://...second_url...', []);
//:::::curl example:::::
$ch = curl_init();
//define options
$optArray = array(
CURLOPT_URL => 'http://...second_url...',
CURLOPT_RETURNTRANSFER => true
);
//apply those options
curl_setopt_array($ch, $optArray);
//execute request and get response
$res = curl_exec($ch);
});
Note that using Guzzle may need you to install required libraries.

If you put your first_route closure into a controller action you could try to instantiate that controller and call the method directly.
This is considered as bad practice.
routes.php
Route::get('/first_url', 'TestController#getFirstUrl');
App/Http/Controllers/TestController.php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class TestController extends Controller
{
public function getFirstUrl()
{
return view('my-view');
}
}
routes.php
Route::get('/second_url', function () {
$controller = new \App\Http\Controllers\TestController();
$contentsOfFirstRoute = $controller->getFirstRoute();
// Make use of rendered HTML
});

Related

Add value to route before in slim framework

Hi Folks i upgrading my slim framework from slim 2 to slim 4 for older project
for one route i added the one value before route using slim 2 slim.before in index.php
example code:
$app->hook('slim.before', function () use ($app) {
$env = $app->environment();
$path = $env['PATH_INFO'];
// spliting the route and adding the dynamic value to the route
$uriArray = explode('/', $path);
$dynamicvalue = 'value';
if(array_key_exists($uriArray[1], array)) {
$dynamicvalue = $uriArray[1];
//we are trimming the api route
$path_trimmed = substr($path, strlen($dynamicvalue) + 1);
$env['PATH_INFO'] = $path_trimmed;
}
});
i read about the add beforemiddleware but cannot able find correct way to add it and i cannot able to find the replacement for $app->environment();
i want to append the dynamic value directly to route
for example
i have one route like this
https://api.fakedata.com/fakeid
by using the above route splitting code i appending the value route using slim.before in slim 2
for example take the dynamic value as test
the route will be
https://api.fakedata.com/test/fakeid
the response of the both api will be same we want to just add value to the route
can any one help me how to do with slim 4
I assume you need to and PATH_INFO to the environment so you can later refer to it in the route callback. You can add a middleware to add attributes to the $request the route callback receives:
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class PathInfoMiddleware {
public function __invoke(Request $request, RequestHandler $handler) : Response {
$info = 'some value, path_trimmed for example...'; // this could be whatever you need it to be
$request = $request->withAttribute('PATH_INFO', $info);
return $handler->handle($request);
}
}
// Add middleware to all routes
$app->add(PathInfoMiddleware::class);
// Use the attribute in a route
$app->get('/pathinfo', function(Request $request, Response $response){
$response->getBody()->write($request->getAttribute('PATH_INFO'));
return $response;
});
Now visiting /pathinfo gives the following output:
some value, path_trimmed for example...

Call to a member function name() on null in laravel 5.4

When pressing my send button it's giving error like this-
Here is my routes web.php bellow-
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
Route::resource('message/send', 'MessageController#ajaxSendMessage')->name('message.new');
Route::delete('message/delete/{id}', 'MessageController#ajaxDeleteMessage')->name('message.delete');
});
Here is my controller MessageController.php bellow:
public function ajaxSendMessage(Request $request)
{
if ($request->ajax()) {
$rules = [
'message-data'=>'required',
'_id'=>'required'
];
$this->validate($request, $rules);
$body = $request->input('message-data');
$userId = $request->input('_id');
if ($message = Talk::sendMessageByUserId($userId, $body)) {
$html = view('ajax.newMessageHtml', compact('message'))->render();
return response()->json(['status'=>'success', 'html'=>$html], 200);
}
}
}
Resource routes should be named differently:
Route::prefix('ajax')->group(function () {
Route::resource('messages', 'MessageController', ['names' => [
'create' => 'message.new',
'destroy' => 'message.destroy',
]]);
});
Resource routes also point to a controller, instead of a specific method. In MessageController, you should add create and destroy methods.
More info at https://laravel.com/docs/5.4/controllers#restful-naming-resource-routes
You can't name a resource. Laravel by default name it, if you want to name all routes you must specify each one explicitly. It should be like this:
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
Route::get('message/send', 'MessageController#ajaxSendMessage')->name('message.new');
Route::delete('message/delete/{id}', 'MessageController#ajaxDeleteMessage')->name('message.delete');
});
Update
Another mistake of yours was trying to resource a single method. A Route::resource() is used to map all basic CRUD routes in Laravel by default. Therefore, you have to pass the base route and the class i.e:
<?php
Route::resource('message', 'MessageController');
Look at web.php line 28.
Whatever object you think has a name() method, hasn't been set, therefore you try and call a method on null.
Look before that line and see where it is (supposed to be) defined, and make sure it is set to what it should be!

Silex redirect with argument

I need to redirect from a controller to another.
$app->get('/test', function(Request $request) use ($app) {
return $app->redirect($app["url_generator"]->generate("success", [
"myArg" => $myArg
]));
});
$app->get('/test/success', function(Request $request, $myArg) use ($app) {
return $app['twig']->render('confirmation.twig', [
'myArg' => $myArg,
]);
})->bind('success');
But it seems to doesn't be the good way to do it... I just want to redirect to the route "/test/success" and passing the $myArg variable to my confirmation.twig template.
Thanks for help.
By putting $myArg in the arguments of your function, Silex expects it to be a parameter from your URL, however your route definition isn't dynamic so it can't work.
If you want to get the parameter from the arguments of your function you have to modify your route definition to something like /test/success/{myArg}.

Sending header data to laravel controller?

I'm building an API for a webapp I made to train myself in Laravel. I integrated a token based authentication system by Tappleby, like this:
Route::get('api/v1/auth', 'Tappleby\AuthToken\AuthTokenController#index');
Route::post('api/v1/auth', 'Tappleby\AuthToken\AuthTokenController#store');
Route::delete('api/v1/auth', 'Tappleby\AuthToken\AuthTokenController#destroy');
Route::group(['prefix' => 'api/v1', 'before' => 'auth.token'], function ()
{
Route::resource('user', 'ApiUsersController');
});
In ApiUsersController I, ideally, want to do something like this:
public function index()
{
$payload = $request->header('X-Auth-Token');
if(empty($payload)) {
return $this->respondNotFound('User does not exist.');
}
$user = $this->driver->validate($payload);
return $user;
}
However, header() is not available for the controller. How can I solve this?
In Laravel, you can retrieve the HTTP headers like so:
$value = Request::header('Content-Type');
Add this to your controller and you can then do what you need to with it.
Also, you can change Content-Type to whatever it should be.
Read more here: http://laravel.com/docs/4.2/requests

How to call a controller action in Laravel 4.1 and get the filters executed

So the title describes my problem pretty well I think, but let me explain why I want to do this as theremight be an other solution to my problem that I haven't thought about.
Let's say that I have a route specifying the class of the object it will patch:
Route::patch('{class}/{id}', array(
'as' => 'object.update',
function ($class, $id) {
$response = ...;
// here I want to call the update action of the right controller which will
// be named for instance CarController if $class is set to "car")
return $response;
}
));
This is something pretty easy to do with $app->make($controllerClass)->callAction($action, $parameters); but doing it this way won't call the filters set on the controller.
I was able to do it with laravel 4.0 with the callAction method, passing the app and its router, but the method has changed now and the filters are called in the ControllerDispatcher class instead of the Controller class.
If you have routes declared for your classes then you may use something like this:
$request = Request::create('car/update', 'POST', array('id' => 10));
return Route::dispatch($request)->getContent();
In this case you have to declare this in routes.php file:
Route::post('car/update/{id}', 'CarController#update');
If you Use this approach then filters will be executed automatically.
Also you may call any filter like this (not tested but should work IMO):
$response = Route::callRouteFilter('filtername', 'filter parameter array', Route::current(), Request::instance());
If your filter returns any response then $response will contain that, here filter parameter array is the parameter for the filter (if there is any used) for example:
Route::filter('aFilter', function($route, $request, $param){
// ...
});
If you have a route like this:
Route::get('someurl', array('before' => 'aFilter:a_parameter', 'uses' => 'someClass'));
Then the a_parameter will be available in the $param variable in your aFilter filter's action.
So I might have found a solution to my problem, it might not be the best solution but it works. Don't hesitate to propose a better solution!
Route::patch('{class}/{id}', array(
'as' => 'object.update',
function ($class, $id) {
$router = app()['router']; // get router
$route = $router->current(); // get current route
$request = Request::instance(); // get http request
$controller = camel_case($class) . 'Controller'; // generate controller name
$action = 'update'; // action is update
$dispatcher = $router->getControllerDispatcher(); // get the dispatcher
// now we can call the dispatch method from the dispatcher which returns the
// controller action's response executing the filters
return $dispatcher->dispatch($route, $request, $controller, $action);
}
));

Categories