I am trying to call a Controller Action using View::share - php

I'm trying to pass a variable to every view when a user is logged in, and I put the action in my routes.php file;
//functions only execute when the user is logged in
Route::group(array('before' => 'auth'), function(){
View::share('ctxr', 'user is authenticated');
});
I am currently using Laravel 4.2 and using a static variable the share function works as expected. If I call the {{ $ctxr }} from any partial or view, it displays correctly, but the problem is, when I have an action on the basecontroller and I'm thinking of doing something similar to this:
View::share('ctxr', BaseController#getStatistics);
Which returns the stats generated to every view. but I keep getting an error, please what is the best way to call controller functions from a View::share function. I am trying to avoid using sessions, since Laravel has made this available...
Thanks in anticipation.

The second parameter needs to be a string or an array. A callback function won't work, from what I can tell. But what you can do is assign the returned value to a variable and pass that along:
Route::group(array('before' => 'auth'), function(){
$bc = new BaseController();
$stats = $bc->getStatistics();
// Or if getStatistics is defined as a static function
$stats = BaseController::getStatistics();
View::share('ctxr', $stats);
});

Related

How to make every Laravel URL have parameter

So I want to create admin page,
The result I want is like this
foo.com/admin/anthony
foo.com/admin/anthony/dologin
foo.com/admin/anthony/index
I tried using this routes
Route::any('admin/{username}', 'adminController#login'):
Route::any('admin/{username}/login', 'adminController#dologin');
I want to use every username parameter in admin page, but wont redeclare every page.
you can create group of route in laravel, below is the example which might help you.
Route::group(['prefix' => 'admin/{username}'], function () {
Route::get('login', 'adminController#dologin');
});
Let me know if this doesn't work for you.

Detect if action is show or edit in Laravel 5.2

I have a middleware that detects if a user owns a tournament.
So, if user want to edit a tournament he doesn't own, he will get a 403.
Thing is I can't make difference between laravel.dev/tournament/1/edit, and laravel.devl/tournament/1
Off course, I could check the "edit" word in URL, but I would prefer other better param...
I tried method param in Request Object, but it is giving me GET for both, so I can't make difference...
Any Idea???
In your case, you can do like this:
$request->route()->getName();
Now you can do your logic based on this.
What about using a different HTTP method for edit, e.g PATCH or PUT and declaring two different routes, something like:
Route::get('laravel.devl/tournament/1', 'TournamentController#showTournament');
Route::put('laravel.dev/tournament/1/edit', 'TournamentController#editTournament');
Then in the TournamentController you can check if the user has rights to edit.
It sounds like you should just use route specific middleware instead of global middleware. See https://laravel.com/docs/master/middleware#assigning-middleware-to-routes. Then you can just do:
Route::get('/tournament/{id}/edit', ['middleware' => ['tournamentOwner'], function () {
//
}]);
Route::get('/tournament/{id}', ['middleware' => [], function () {
//
}]);
If it's a RESTful route, you can just do:
public function __construct()
{
$this->middleware('tournamentOwner', ['only' => ['edit']]);
}

Laravel sub-domain routing without passing variable to URL::route()

In a Laravel 4 app, i'm using subdomain routing around a bunch of Route::resource's like this:
Route::group(['domain' => '{account}.my.app'], function()
{
Route::group(['before' => 'auth'], function($account)
{
Route::resource('organisations', 'OrganisationsController');
Route::resource('clients', 'ClientsController');
Route::resource('domains', 'DomainsController');
});
});
In my auth filter i'm doing the following:
Route::filter('auth', function($route)
{
// you could now access $account in a controller if it was passed as an argument to the method
$account = $route->getParameter('account');
// share account variable with all views
View::share('account', $account);
// Auth::guest Returns true if the current user is not logged in (a guest).
if (Auth::guest()) return Redirect::guest('login');
});
Within my views I can now access $account, but if I want a call to URL::route() to be correct I have to manually pass the account variable, like URL::route('clients.show',['account' => $account]) otherwise it generates URLs like %7Baccount%7D.my.app.
This is a bit of a pain and doesn't seem that elegant, is there any other or better way to achieve this? I guess I could create my own route helper to use instead of the built-in one.
However, I also do redirects with Redirect::route() within controllers so I would also need to make updates here.
EDIT
As suggested in the comments it may be that extending the Route API is the best approach here. Does anyone have any suggestions how this should be done?
Thanks.

Laravel beforeFilter in controller on POST request throws non-object exception

I try to set some specific filter on all controller methods with:
public function __construct() {
$this->beforeFilter(function(){
//whathever
});
}
and it's working well on normal GET methods, problem occures when there is some POST method:
Route::post('settings/menu-order/{direction}', array(
'as' => 'setting.menu-order.move',
'uses' => function($direction) {
$controller = new CMSSettingsController();
return $controller->doMoveMenu($direction);
}));
after click in a button which send POST with $direction, I'v got
Call to a member function filter() on a non-object
in vendor/laravel/framework/src/Illuminate/Routing/Controller.php
protected function registerClosureFilter(Closure $filter)
{
$this->getFilterer()->filter($name = spl_object_hash($filter), $filter);
return $name;
}
If I use already registred filter it's working, so what's going on?
I have few controllers which need specific function todo before running controller methods, so I can't make global universal filter. Is there any other good solution?
The problem could be that you are calling the controller action directly instead of letting the Router do it for you. When the router tries to apply the filters, instead of applying them on the controller, it ends up attempting to apply them on the output of the doMoveMenu action - which, of course, is not a Controller object and has no method filter.
Instead, your route should look like this:
Route::post('settings/menu-order/{direction}', array(
'as' => 'setting.menu-order.move',
'uses' => 'CMSSettingsController#doMoveMenu'));
The reason you don't need to do the method call manually is that since your Route has a parameter in it and your method accepts a parameter, the Router will automatically pass the parameter into the action method. Additionally, since you are providing a method name as the uses value, Laravel knows that it has to instantiate the Controller and run the filters.

Laravel and routes with multiple "nested" tasks and parameters

I have just started tinkering with Laravel (PHP newbie alert) and I have a doubt on how to implement my REST JSON APIs on this framework.
The desired URL path should be:
http://api.mysite.com/APIKEY/FUNCTION/(ARGUMENTS)*
But what is the best way to do it?
I did not find any enough explanatory guide, because it is assumed that each feature (authentication, search, and so on) are on different routes.
At the moment I managed to create migrations and models for the needed data and I also set a route this way:
Route::get('/{apikey}/{function}/{arg1}/{arg2}/{arg3?}',
//The first two arguments are mandatory, the 3rd optional
function($apikey,$function,$arg1,$arg2)
{
return Response::json(array(
'status'=>'200'),
200);
})
->where(array('function'=>'[A-Za-z]+'));
This should be the correct action flow, but I have some doubts.
Check that apikey is valid, if not return a 404 json response. How do I call such function, where do I define it?
If key check is successful, understand which function is needed (should I use a switch construct or is there a better way to implement this, like a route group? In all examples with Route::group there is a static prefix, but here the prefix is apikey, a variable)
Return data - if available - getting it from the database. I suppose that for each function i should code a specific controller that gets data from the database using the Models.
#1. I think I'd probably use a route filter for this, like so:
Route::filter('apikey', function(){
if (Shared\API::checkIfKeyIsValid(Input::get('key') != true){
return Shared\Errors::handleError("bad-api-key");
}
});
You can see this filter checks to make sure some session variables are set and match, and if it returns ANYTHING, that's failing, and it won't send the user where the route normally goes. You'd call it in the route like so:
Route::get('play/{id}', array('before' => 'loggedin', 'uses' => 'ThingController#doThing'));
#2. I think a route group is how I'd structure this (if I understand what you're asking).
Edit: You've changed the question since I answered, regarding the prefix being a variable. I'd reorder your arguments so the API key is at the end, or you could take a look at this, which might do what you want: https://github.com/jasonlewis/enhanced-router
Route::group(array('prefix' => 'api'), function()
{
//the routes for all API calls
Route::group(array('prefix' => '/v1'), function()
{
//for version 1
Route::group(array('prefix' => '/thing', 'before' => 'loggedin'), function()
{
//for things only
Route::get('/getThing/{id}', 'APIController#getThing');
Route::get('/getDifferentThing/{id}/{aux}/{optional?}', 'APIController#getDifferentThing');
});
});
});
#3. The returning of the data should be done via your controller with the data coming from the model. Either return it as a view, or just return it as JSON like so:
return Response::json($data);

Categories