I am having an issue that seems to be fairly common across the interwebs, but I'm afraid I can't pinpoint the solution.
Error
BindingResolutionException in Container.php line 888:
Unresolvable dependency resolving [Parameter #0 [ <required> $app ]] in class Illuminate\Support\ServiceProvider
Service Provider (Providers/SocialAccountServiceProvider.php)
Here is my relatively simple service provider.
namespace App\Providers;
use App\User;
use Socialite;
use App\SocialAccount;
use Illuminate\Support\ServiceProvider;
class SocialAccountServiceProvider extends ServiceProvider
{
protected $socialNetwork = '';
public function boot()
{
//
}
public function register()
{
//
}
public function resolveTwitterUser()
{
$this->socialNetwork = 'twitter';
return $this->resolveUser();
}
public function resolveFacebookUser()
{
$this->socialNetwork = 'facebook';
return $this->resolveUser();
}
public function resolveUser()
{
return $resolvedUser;
}
}
Registration (config/app.php)
And I have registered the service provider with the app like so.
App\Providers\SocialAccountServiceProvider::class,
Controller (Controllers/TwitterAuthController.php)
My controller is quite simple as well.
use App\User;
use Socialite;
use App\SocialAccount;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Providers\SocialAccountServiceProvider;
class TwitterAuthController extends Controller
{
public function redirect()
{
return Socialite::driver('twitter')->redirect();
}
public function callback(SocialAccountServiceProvider $account)
{
$user = $account->resolveTwitterUser();
if (Auth::loginUsingId($user->id, true))
return redirect()->to('/');
else
return redirect()->to('/login');
}
}
Would any kind souls be willing to help? 🙏
Deets:
- Laravel: 5.4
- Socialite: 3.0
Related
I have a custom middleware where I want to use a singleton I use to pass php variables into my frontend, however I get the following error:
ReflectionException (-1)
Class App\Http\Middleware\Javascript does not exist
My middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Auth;
class AuthAdmin
{
public function handle($request, Closure $next)
{
$user = Auth::user();
if($user && $user['privileges'] > 2)
{
return $next($request);
}
app(Javascript::class)->put(['showLoginModal' => true]);
return redirect('/');
}
}
My ServiceProvider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Helpers\Javascript;
class JavascriptServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Javascript::class, Javascript::class);
}
}
composer dump-autoload didn't fix anything, I have been having problems where the Javascript Class is not found for some reason, any ideas or sugestions?
Try importing Javascript class in your middleware. It's trying to find it in wrong namespace.
middleware:
<?php
namespace App\Http\Middleware;
use App\Helpers\Javascript;
I got the service provider and my class for shopping cart.
This is my service provider:
<?php
namespace Alexxosipov\Cart;
use Illuminate\Support\ServiceProvider;
use Alexxosipov\Cart\Cart as Cart;
class CartServiceProvider extends ServiceProvider {
public function boot() {
}
public function register() {
$this->app->singleton('cart', function() {
return new Cart;
});
}
}
but my phpstorm says me, that use Alexxosipov\Cart\Cart as Cart; is never used in code. Where did I go wrong?
According to laravel documentation, you need to type hint the Cart interface:
<?php
namespace Alexxosipov\Cart;
use Illuminate\Support\ServiceProvider;
use Alexxosipov\Cart\Cart as Cart;
class CartServiceProvider extends ServiceProvider {
public function boot() {
}
public function register() {
$this->app->singleton(Cart::class, function() {
return new Cart;
});
}
}
I have a interface dependency inject Question,
the error message look like can`t catch the class,
have any ideal?
Error Message:
FatalThrowableError in UserController.php line 27:
Class 'App\Http\Controllers\App' not found
My folder path :
UserController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Domain\Services\Social\SocialService;
use Domain\Services\Social\SocialInterface;
use Domain\Services\Social\Facebook;
class UserController extends Controller
{
public function fb(Request $request)
{
App::bind(SocialInterface::class, Facebook::class);
$target = App::make(SocialService::class);
return $target ->getCallbackData($request);
}
}
SocialService.php
namespace Domain\Services\Social;
class SocialService
{
public function getCallbackData(SocialInterface $social,$request)
{
return $social->getCallbackData($request);
}
}
Facebook.php
namespace Domain\Services\Social;
class Facebook implements SocialInterface
{
public function getCallbackData($request)
{
//Somethig inside...
}
}
public function fb(Request $request)
{
\App::bind(SocialInterface::class, Facebook::class);
$target = \App::make(SocialService::class);
return $target ->getCallbackData($request);
}
Try it with backslash.
I'm trying to write an SSO implementation and for that I need to override some methods such as Auth::check() which are implemented in the Guard class.
I don't understand, however, how to extend that class using service providers. I tried looking in the AuthServiceProvider but there is a whole lot of mumbo jumbo going on I don't understand.
I figured it out! Fairly simple:
<?php
namespace Animekyun\Providers;
use Animekyun\Auth\CustomGuard;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Support\ServiceProvider;
class SsoServiceProvider extends ServiceProvider
{
public function boot()
{
\Auth::extend('custom', function () {
return new CustomGuard(
new EloquentUserProvider(
$this->app['hash'],
$this->app['config']['auth.model']),
$this->app['session.store']);
});
}
public function register()
{
}
}
and the CustomGuard class:
<?php
namespace Animekyun\Auth;
use Illuminate\Auth\Guard;
class CustomGuard extends Guard
{
public function check() {
// do some stuff
return parent::check();
}
}
I have a class which acts like a storage (add/get item). I try to bind it as a singleton in one service provider, and resolve it in another's boot method.
The code is changed for simplicity.
app/Providers/BindingProvider.php
<?php namespace App\Providers;
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\ServiceProvider as ServiceProvider;
class MyBindingFacade extends Facade {
public static function getFacadeAccessor() {
return 'my.binding';
}
}
class MyBinding {
protected $items = [];
public function add($name, $item) {
$this->items[$name] = $item;
}
public function get($name) {
return $this->items[$name];
}
public function getAll() {
return $this->items;
}
}
class BindingProvider extends ServiceProvider {
public function register() {
$this->app->singleton('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
}
public function provides() {
return [
'my.binding',
];
}
}
app/Providers/ResolvingProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider as ServiceProvider;
use App\Providers\MyBinding;
class ResolvingProvider extends ServiceProvider {
public function boot(MyBinding $binding) {
$binding->add('foo', 'bar');
// $manual = $this->app->make('my.binding');
// $manual->add('foo', 'bar');
}
public function register() {}
}
app/Http/Controllers/WelcomeController.php
<?php
namespace App\Http\Controllers;
use App\Providers\MyBindingFacade;
class WelcomeController extends Controller {
public function index()
{
dd(MyBindingFacade::getAll()); // debug items
}
}
When I try to debug MyBinding state in my WelcomeController I'm getting empty item array. However, if I uncomment $manual part from my ResolvingProvider it returns an array containing 'foo' => 'bar'. Does it mean IoC resolution is broken in ServiceProvider::boot() method or am I misusing Laravel functionality?
Laravel version: 5.0.28
UPDATE: Added code sample from WelcomeController.
With this:
$this->app->singleton('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
You're saying: my.binding is a singleton and resolves to an instance of App\Providers\MyBinding.
That doesn't mean that App\Providers\MyBinding is registered as singleton too. What you should do instead is this:
$this->app->singleton('App\Providers\MyBinding');
$this->app->bind('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
Because the Facade binding uses $app->make() you should get the same instance you registered with $this->app->singleton() right above.
In the first example you are not using the Facade, you should be using:
use App\Providers\MyBindingFacade as MyBinding;
Which will in fact call make it using 'my.binding'.