I want to inject service globally for all application views
can i inject it thorough application service provider boot method ?
What service you want to inject? How will you use it?
An easy way to share variables across all views is to call the share method:
view()->share([
'myService' => app()->make(My\Service::class),
]);
You can call this within your controller or maybe inside a middleware to work across many different controllers, too.
Then, in your views, something like this:
#foreach ($myService->getItems() as $item)
...
#endforeach
Follow this steps:
create service provider: php artisan make:provider UserServiceProvider
Go to
app\providers\UserServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use Auth;
class UserServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
// key can be anything
// value what you want
View::share('key', 'value');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
}
}
Than register this service provider inside the config\app.php
App\Providers\UserServiceProvider::class,
Now you can access this key for every views.
Related
I am building an app where each company have multiple users. And all users can upload documents/images/xls etc. I want to keep all company data in company separate folder. To complete this I am checking the company detail for every user and then upload data to company specific folder. Can I check company database once per user login and share user's company details to all controller and can easily access.
Use view composer in your AppServiceProvider
App\Providers\AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->composer('*',function($view) {
if(auth()->user()) {
$comanyData = App\Company::where('user_id',auth()->user()->id);
$view->with('companyData', $companyData);
}
});
}
}
You can make the helper function to use in controllers or blades files.
Let’s create a helper!
Create a simple PHP file.
Create Helper.php inside the app directory or wherever directory you want.
<?php
/**
* get company data
*
*/
function companyData()
{
// Create logic of company data
// return company data
}
Autoload Composer
After we created our helper, Laravel won’t recognize our file so we need to register the helper file to our composer.json. Add File array inside the autoload section. It may look like this:
"autoload": {
"classmap": ["database"],
"psr-4": {"App\\": "app/"},
"files" : ["app/Helper.php"]
}
Then don’t forget to run
composer dumpautoload
Using helper function
Our helper is autoloaded now, so we should be able to use our helper immediately on different controllers. Just call our function in any class
$companyData = companyData();
or in blade view
{{ companyData() }}
Let me know if you are facing an issue.
Below is how to share a variable with your entire application via the AppServiceProvider, You can also do this inside of your base controller in the construct method.
File: App\Providers\AppServiceProvider.php
<?php
namespace App\Providers;
use View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
View::share('key', 'value');
}
}
You can then access $key inside of any view.
In laravel we can use with() along with redirect(), like
return redirect('home')->with(['message' => 'Some message');
I want to create some other functions like withError(), withSuccess().
How and where to create this ?
As the Laravel RedirectResponse class uses the Macroable trait, you can register response macros to do this.
Just create a new service provider say ResponseMacroServiceProvider. Register it in your app.php and register a macro in the boot method like so:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Http\RedirectResponse;
class ResponseMacroServiceProvider extends ServiceProvider
{
/**
* Register the application's response macros.
*
* #return void
*/
public function boot()
{
RedirectResponse::macro('withError', function ($value) {
return; // add logic here
});
RedirectResponse::macro('withSuccess', function ($value) {
return; // add logic here
});
}
}
I noticed that many of the examples in the Laravel docs seem to have Controllers where the class has only one use/method.
For example, in this part of the doc, they have a UpdatePasswordController class with a single method, update():
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;
class UpdatePasswordController extends Controller
{
/**
* Update the password for the user.
*
* #param Request $request
* #return Response
*/
public function update(Request $request)
{
// Validate the new password length...
$request->user()->fill([
'password' => Hash::make($request->newPassword)
])->save();
}
}
Normally, I would put a method called updatePassword() in my UserController class (along with signIn(), signUp(), resetPassword(), etc.), but I'm wondering if it's better to create multiple classes, each with a single action?
Normally class is defined for a single purpose. In laravel , for authentication there is a Illuminate base bundle which is optimized for years.
As an example UpdatePasswordController only responsible for updating password,
AuthController only responsible for authentication.
I prefer you to reserch some MVC best practices
I have the following problem, I want to share an array to all views in my project so I followed the documentation and it works fine, but I want to get the authenticated user in service provider boot function and it always return null ?
any suggestions ?
this is my code
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public $myusers;
public function boot()
{
$origLat=\Auth::user()->lat;
$origLon=\Auth::user()->lng;
$dist=5;
$lon1=$origLon-$dist/cos(deg2rad($origLat))*73.2044736;
$lon2=$origLon+$dist/cos(deg2rad($origLat));
$lat1=$origLat-($dist/73.2044763);
$lat2=$origLat+($dist/73.2044763);
$id=\Auth::user()->id;
$pictures=User::find($id)->pictures;
$this->myusers = DB::table('users')->select(
DB::raw("*,
3956 * 2 *
ASIN(SQRT( POWER(SIN(($origLat- lat)*pi()/180/2),2)
+COS($origLat*pi()/180 )*COS(lat*pi()/180)
*POWER(SIN(($origLon-lng)*pi()/180/2),2)))*1.609344
as distance"
))
->where('users.id', '!=', \Auth::user()->id)
->whereBetween('lng',[$lon1,$lon2])
->whereBetween('lat',[$lat1,$lat2])
->having("distance", "<", "$dist")
->orderBy("distance")
->get();
view()->share('myusers', $this->myusers);
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
Unfortunately, at this point the Laravel application request lifecycle works in such a way that when the boot method of the App\Providers\AppServiceProvider class is executed the session is not yet initialised (since that's done in a middleware that is executed after the boot method).
Since the authentication systems needs the session in order to get the authenticated user, in your particular case you can't use view()->share() successfully there (although it's the recommended approach). Instead you can use an alternative approach by doing that in a middleware. Here are the steps that you can follow to make this work:
1. Create a middleware class, let's call it LoadUsers, by running this command:
php artisan make:middleware LoadUsers
2. That will generate a class in app/Http/Middleware/LoadUsers.php. Now you just need to move your code from the AppServiceProvider to the handle method of the middleware:
class LoadUsers
{
public function handle($request, Closure $next)
{
// Your code that shares the data for all views goes here
return $next($request);
}
}
3. Next you need to register the middleware with the App\Http\Kernel class. You can add it to the web group from $routeMiddleware if you want to apply the middleware to all routes that that use that or create your specific group or route middleware. So something like this if you want to add it to web:
protected $middlewareGroups = [
'web' => [
...
// Make sure to add this line is after the
// StartSession middleware in this list
\App\Http\Middleware\LoadUsers::class,
],
...
];
Now you should have the proper shared data for all your views that can depend on Auth::user().
whenever i tried to use \Auth::User() i am getting non object property because my Auth::guest() returns true whenever i use them in service provider
use Illuminate\Contracts\View\View;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\View\Factory;
use App\relations;
use App\User;
use DB;
use Illuminate\Support\Facades\Auth;
class RelationServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
\Auth::User()->id;
$relation_friend_for_logged_user = DB::select( DB::raw("SELECT * FROM users"));
$value = "asd";
// for injecting objct
View()->share('count', $value);
}
but why \Auth::guest() is returning true whether i am logged in
You probably want to use a View Composer for this. As far as I know the authenticated user is not yet available in your service providers boot method.
public function boot(Guard $auth) {
view()->composer('*', function($view) use ($auth) {
// get the current user
$currentUser = $auth->user();
// do stuff with the current user
// ...
// pass the data to the view
$view->with('currentUser', $currentUser);
});
}
Code modified from https://laracasts.com/discuss/channels/general-discussion/how-do-i-get-the-current-authenticated-user-laravel-5