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;
});
}
}
Related
I'm following the Laracasts series and have run into an issue on the episode Laravel 5.4 From Scratch: Route Model Binding.
Laravel version:
Laravel Framework 5.6.13
The error:
Class App\Http\Controllers\Panel does not exist
This shows on both the /panel and /panel/1 pages
App\Http\Controllers\PanelController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
// Code works if I uncomment below line, and change the show function to "show($panel)"
//use App;
class PanelController extends Controller
{
public function index()
{
$panels = Panel::all();
return view('panel/index', compact('panels'));
}
public function show(Panel $panel)
{
return $panel;
return view('panel/show', compact('panel'));
}
}
routes/web.php
// Main panel view
Route::get('/panel', 'PanelController#index');
// Individual panel view
Route::get('/panel/{panel}', 'PanelController#show');
App/Panel.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Panel extends Model
{
public static function activePanels()
{
return static::where('status', 1)->get();
}
}
Add this line in panel controller before the class
use App\Panel;
You need to add use App\Panel; to top of class
Or call it by full namespace $panels = App\Panel::all();
You don't included your model to class.
Add App\Panel to main include section:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Panel;
class PanelController extends Controller
{
public function index()
{
$panels = Panel::all();
return view('panel/index', compact('panels'));
}
public function show(Panel $panel)
{
return $panel;
return view('panel/show', compact('panel'));
}
}
or load model in your class method manually:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PanelController extends Controller
{
public function index()
{
$panels = App\Panel::all();
return view('panel/index', compact('panels'));
}
public function show(Panel $panel)
{
return $panel;
return view('panel/show', compact('panel'));
}
}
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
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'.
When I search the error 'Target Interface is not instantiable' I get a lot of results. Somehow I can still not find the solution to my problem.
I am not sure where it goes wrong.
PartnerController.php
<?php use CmsBlox\MOD\PartnerInterface;
class PartnerController extends BaseController {
public function __construct(PartnerInterface $partner)
{
$this->partner = $partner;
}
public function Get()
{
return "I'm the Get function in class PartnerController";
}
}
PartnerServiceProvider.php
<?php namespace CmsBlox\Providers;
use App, Illuminate\Support\ServiceProvider;
class PartnerServiceProvider extends ServiceProvider {
public function register()
{
}
public function boot()
{
app::bind('CmsBlox\MOD\PartnerInterface') ;
}
}
Routes.php
app::bind('CmsBlox\MOD\PartnerInterface') ;
PartnerInterface.php
<?php namespace CmsBlox\MOD;
interface PartnerInterface {
public function get();
}
I have also added the provider to App.php (for testing also a app::bind() in the routes.php)
'CmsBlox\Providers\PartnerServiceProvider'
As far I know every file should be correct. Somehow I am missing something!
I just found the answer! Thanks to the Laravel.io forums.
<?php use CmsBlox\MOD\PartnerInterface;
class PartnerController extends BaseController implements PartnerInterface {
public function get() {...}
}