pass user information in every function of the controller in laravel - php

I have a Controller witch contains more than 150 functions. almost all of the functions inside the controller are returning views.
each view should change if the user is logged in.
I almost handled this in the view side by using parent blades and etc. But in the controller side for almost every function i should check if the user is logged in and return some specific data about the user along with the view.
for example:
$user=[];
if(Auth::check())
{
$user=Auth::user;
$reputation=$user['reputation'];
$messages=$user->messages();
$notifications=$user->notification();
}
return view('pages.profile')->with(['user'=>$user , 'messages'=>$messages , 'notifications'=>$notifications]);
I thought that this is possible using middlewares but i could not figure it out.
what are the alternatives here?
for more information i am using laravel 5.

One solution could be using your custom function instead of view(). Sth like:
//in your controller action
public function someAction() {
return $this->view('pages.profile');
}
protected function view($template, $data = array()) {
return view($template)->with($data)->with([data that needs to be passed to all views]);
}

Related

Yii2 PHP Perform checking user with beforeAction in Controller

I'm aware there's a similar post to this but just to confirm my understanding.
I just start using Yii2 PHP. I've used dektrium/yii2-user that can login and register. I want to do a beforeAction() to check logged user auth.key if exist in database (XAMPP MYSQL). Below is the code I want to performed on.
//Action direct to json.php.
public function actionJson()
{
return $this->render('json');
}
If the statement true will direct to the page, else shows a alert error.
I know the exact code is
public function beforeAction($action){}
What I'm confused on is where do I actually put beforeAction() at.
BeforeAction()
This method is invoked right before an action is executed.
https://www.yiiframework.com/doc/api/2.0/yii-base-controller#beforeAction()-detail
Where to place it?
You must place it inside your login controller (LoginController.php) class.
Remember to call the parent inside the function as :
public function beforeAction($action)
{
if (!parent::beforeAction($action)) {
return false;
}
return true; // or false to not run the action
}
Then all the actions from that controller will use your custom beforeAction function.

Passing parameter / variable through two controllers in Laravel difficulty

I have a Data model that I want people to be able to view individual records of and then edit/add data to. I have managed to get the view route working;
Route::get('/data/{data_token}', 'DataController#show');
Data_token, is a unique string. This then uses this DataController function;
Public function show($data) {
$data = Data::where('data_token',$data)->first();
return view('data.show', compact('data'))
}
After which I can display the data on the page, and have a form for editing (actually its for adding data that doesn't exist, but whatever, same principle right).
On the form on the data.show view, I am sending it to a different view;
Route::get('/data/{data_token}/edit', 'DataController#edit');
This can use the $request variable to return the forms values, but I can't relate it to the data row I was previously editing?
how do I get the {data_token} passed to the edit function of the controller?
Edit( adding route files)
Noticed I forgot the {'data_token'} in the post route.
/Begs forgiveness
I think you've misunderstood how the routes and controllers work. What you're looking at is a fairly simple CRUD setup like the following;
Route::get('/data/{data_token}', 'DataController#show');
Route::get('/data/{data_token}/edit', 'DataController#edit');
Route::post('/data/{data_token}/edit', 'DataController#update');
Now your controller would have;
public function show($dataToken) { ... }
public function edit($dataToken) { ... }
public function update($dataToken, Request $request) { ... }
Then you'd have your form on the edit view like so;
<form action="{{ route('DataController#update') }}" method="post">
Laravels router will always try to pass in the URI variables as arguments to the methods provided.
Providing that I have understood what you need, this should suffice.

Passing variable from backend to frontend laravel

I have 5 controllers and 5 models and they are all related to backend. I can easily output data in the backend but I need to that for the frontend as well. Not all of course but some of them.
For example I have controller called BooksController:
public function getBooks(Request $request)
{
$books = Books::all();
return view('backend.books.show', compact('images'));
}
So this will show it in backend without any problems but what I want is for example to loop through all the books and show their images in welcome.blade.php which doesn't have controller.
And also to pass other parameters to that same view from different controllers.
Is this is possible?
Thank you.
You are having an error because you did not declare the variable $image
public function getBooks(Request $request)
{
$books = Books::all();
$images = array_map(function($book) {
$book->image;
}, $books);
return view('backend.books.show', compact('images'));
}
It sounds like you are potentially caught up on some terminology. In this case, it sounds like backend is referring to your admin-facing interface, and frontend is referring to your user-facing interface.
You also seem to be locked on the idea of controllers. Unless the route is verrrrrry basic, create a controller for it.
Have a controller for your welcome view, for your admin view, basically (with some exceptions) a controller per resource or view is fine.
In this case, you would have one controller for your admin book view, and a seperate controller for your welcome view. Both of which would pull the books out of the db and render them in their own way

Ignore route in Laravel 5.1

I want to create dynamic pages CMS for my Laravel app. Admin is allowed to provide any URI for any page, so for example, he can create page with one/two/three URI and http://example.com/one/two/three will point to this site. I already figured out it's possible to add single route for multiple level URLs like this:
get('{uri}', 'PageController#view')->where('uri', '.+');
Now, I also want to have /{username} URLs to point to users profiles. That means, if I need to make it work together. For me, the perfect code would be something like this:
get('{username}', 'ProfileController#view');
get('{uri}', 'PageController#view')->where('uri', '.+');
Then, in ProfileController I'd like to make my route go further just like it wasn't there. Something like this:
// ProfileController
public function view()
{
$user = User::whereUsername($username)->first();
if ($user === null) {
// Go to the next route.
}
}
Can it be done with Laravel?
I can think of another solution, just to have dynamic routing controller for both usernames and page uris mapping, but I would prefer to have it as separate routes.
You can resolve a new PageController instance out of the Service Container if $user is null.
// ProfileController
public function view()
{
$user = User::whereUsername($username)->first();
if ($user === null) {
// Go to the next route.
$params = []; // If your view method on the PageController has any parameters, define them here
$pageController = app(PageController::class);
return $pageController->callAction('view', $params)
}
}
This way, the {username} route will stay but will show custom content defined by the admin.
Edit:
If you don't want to call a controller manually, you could analyze the current URL segments and check for an existing user before you define your route. In order to not make your routes.php file too complex, I'd add a dedicated service class that analyzes your URL segments:
App\Services\RouteService.php:
<?php
namespace App\Services;
class RouteService {
public static function isUserRoute()
{
if(count(Request::segments()) == 1)
return !! User::whereUsername(Request::segment(1))->first();
}
return false;
}
}
routes.php:
<?php
use App\Services\RouteService;
if(RouteService::isUserRoute())
{
get('{username}', 'ProfileController#view');
}
get('{uri}', 'PageController#view')->where('uri', '.+');
I have not tested this, but it should work. Adjust the RouteService class to your needs.
I'm using the first approach in my CMS and it works realy well. The only difference is that I have written a Job that handles all incoming requests and calls the controller actions respectively.

Laravel Routing to same view different function

I am trying to return values from a MySQL database into a datatable using Chumper. I am trying to obtain values from 2 tables; but I am having what I believe to be a routing issue as I do not know how to include 2 controller functions to the same view ie in my search view I want to render the result of 2 functions like : for a deeper understanding of what I am trying to accomplish see question : Laravel Chumper Datatable getting data into one datatable from multiple MySQL tables
Route::get('search', array('as' => 'instance.search', 'uses' => 'CRUDController#instances'));
Route::get('search', array('as' => 'accid.search', 'uses' => 'CRUDController#account_ids'));
any ideas ?
Only a single route will ever match any given URL requested of the system. I believe what Laravel will do is choose the second one (as in the second definition will overwrite the first).
You have some options here. All I can really tell from your question is that you want two methods to be executed when that route gets hit. This is indirectly possible, consider:
Route::get('search', 'MyController#instances');
class MyController extends Controller
{
public function instances()
{
$mydata = $this->account_ids();
$myotherdata = $this->getOtherData();
return View::make('myview')
->with('mydata', $mydata)
->with('myotherdata', $myotherdata);
}
private function getOtherData() { /* ... */ }
}
This isn't really clean, though, and eventually will lead to convoluted controller logic which is an anti-pattern in MVC. Fortunately, Laravel let's you use View Composers, which can greatly clean up your controller logic:
public function instances()
{
return View::make('myview');
}
Wow. Nice and simple. Now the view composer part:
// Inside of a service provider...
View::composer('search', 'App\Http\ViewComposers\AViewComposer');
use View;
class AViewComposer
{
public function compose(View $view)
{
$view->with('instances', $this->instances());
$view->with('accountIds', $this->accountIds());
}
public function instances()
{
// generate your instance data here and return it...
return $instances;
}
public function accountIds()
{
// generate your account id data here and return it...
return $accountIds;
}
}
You could take this a step further and inject another class into the constructor of this view composer to completely off-load the responsibility of determining what 'instances' and 'account ids' actually mean, should you need that same functionality elsewhere. This will help you keep your code extremely DRY.
You are having those 2 routes but with same domain so the second one is running over the second one.
Or you change the URL of on of them or you change the method for post instead of get

Categories