Laravel service provider not binding to contract - php

i have below contract/interface which is binded by a service provider ,however the i get below error :
ReflectionException in RouteDependencyResolverTrait.php line 81:
Class App\Http\Controllers\RocketShipContract does not exist
What am i doing wrong ?
Contract
namespace App\Contracts\Helpers;
Interface RocketShipContract
{
public function blastOff();
}
The concrete class
namespace app\Contracts;
use App\Contracts\Helpers\RocketShipContract;
class RocketShip implements RocketShipContract
{
public function blastOff()
{
return 'Houston, we have ignition';
}
}
The service provider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Contracts\RocketShip;
class RocketShipServiceProvider extends ServiceProvider
{
protected $defer = true;
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('App\Contracts\Helpers\RocketShipContract', function($app){
return new App\Contracts\RocketShip($app['HttpClient']);
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides()
{
return ['App\Contracts\Helpers\RocketShipContract'];
}
}
The controller
public function test(RocketShipContract $rocketship)
{
$boom = $rocketship->blastOff();
return view('test.index', compact('boom'));
}

The error you're getting hints at the problem: the class is being resolved in the App\Http\Controllers namespace. That's because you need to specify the full namespace of your interface in the controller.
So either include it with a use statement:
use App\Contracts\Helpers\RocketShipContract;
Or type hint the full namespace:
public function test(App\Contracts\Helpers\RocketShipContract $rocketship)
{
// ...
}

Related

Laravel Trait with constructor works in controller but not in model

I have a StripeClient service provider which needs a key to instantiate:-
namespace App\Providers;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
use Stripe\StripeClient;
class StripeServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
$this->app->singleton(StripeClient::class, function ($app) {
return new StripeClient(config('services.stripe.secret'));
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides()
{
return [StripeClient::class];
}
Then a trait with a bunch of api call functions like this:-
trait StripeClientTrait
{
protected $stripe;
function __construct(StripeClient $stripeClient)
{
$this->stripe = $stripeClient;
}
/**
* #param User $user
*
* #return \Stripe\Customer
* #throws \Stripe\Exception\ApiErrorException
*/
function createCustomer(User $user)
{
return $this->stripe->customers->create([ 'name' => $user->fullname,
'email' => $user->email
]);
}
...
The trait works in a controller perfectly as expected:-
class SubscriptionContoller extends Controller
{
use StripeClientTrait;
public function checkout()
{
try {
$customer = $this->createCustomer(Auth::user());
if($checkoutSession = $this->createCheckoutSession($customer)) {
return redirect($checkoutSession->url);
}
} catch (ApiErrorException $ex){
Log::error($ex->getMessage());
return back()->with(['error'=>$ex->getMessage()]);
}
return back();
}
...
But I now need to use the trait in a model to provide access to some api functions.
class Company extends Tenant
{
use HasFactory, StripeClientTrait;
but adding the trait causes:-
Too few arguments to function App\Models\Company::__construct(), 0 passed in /home/vagrant/code/profiler/vendor/spatie/laravel-multitenancy/src/Models/Concerns/UsesTenantModel.php on line 13 and exactly 1 expected
Can anyone tell me how to implement the trait without using the constructor? I just need some static function helpers to lookup stuff on the API.
Thanks for any guidance :-)
having persevered I've found this way to use the service container in a model:-
public function getPrices()
{
$stripe = app(StripeClient::class);
return $stripe->prices->all(['active'=>true]);
}
But would still like to understand how to use the trait in the model, if anyone could explain I'd be grateful

Laravel service provider is no loading the Collection methods Undefined method 'values'.intelephense(1013)

I want to make a Collection macro function in the service provider.
The problem is after importing the Collection class i can not access the collection funtion $this->values()
But when I use the same code in the controller is working fine.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Collection;
class CollectionExtensions extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
Collection::macro('transpose', function () {
$items = array_map(function (...$items) {
return $items;
}, ...$this->values());
return new static($items);
});
}
}

Laravel container returning multiple Singleton instances

I've created a CustomProvider, added it to the app.php array of providers and registered a class as singleton:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\ReserveCart;
class CustomProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton('App\ReserveCart', function($app){
return new ReserveCart;
});
}
}
but everytime I request for the object with $rc = resolve('App\ReserveCart'); it keeps giving me different instances of the object instead of a single one (I've done some echo tracking).
Also tried passing the dependency to methods acording to Laravel Documentation. e.g
public function foo(App\ReserveCart $rc){
//
}
but the issue persists.
Is the output below same ?
$rc = resolve('App\ReserveCart');
$rc1 = resolve('App\ReserveCart');
dd(spl_object_hash($rc), spl_object_hash($rc1));

Laravel 5.4 – error while creating facade

This is how I create helper (App\Helpers\Settings.php)
namespace App\Helpers;
use Illuminate\Database\Eloquent\Model;
class Settings {
protected $settings = [];
public function __construct() {
$this->settings['AppName'] = 'Test';
}
/**
* Fetch all values
*
* #return mixed
*/
public function getAll () {
return $this->settings;
}
}
Creating facade (App\Helpers\Facades\SettingsFacade.php)
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Settings extends Facade {
protected static function getFacadeAccessor() {
return 'Settings';
}
}
Creating Service Provider (App\Providers\SettingsServiceProvider.php)
namespace App\Providers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
class SettingsServiceProvider extends ServiceProvider {
/**
* Bootstrap the application events.
*
* #return void
*/
public function boot() {
}
/**
* Register the service provider.
*
* #return void
*/
public function register() {
App::bind( 'Settings', function () {
return new \App\Helpers\Settings;
});
} */
}
Registering provider (App\Providers\SettingsServiceProvider::class)
Creating alias: 'Settings' => App\Facades\Settings::class
Running composer dump-autoload
Trying to use facade Settings::getAll();
Getting error Class 'App\Http\Controllers\Settings' not found
Can’t figure out why I cannot create facade and getting that error
try this one.
App\Helpers\Settings.php
namespace App\Helpers;
use Illuminate\Database\Eloquent\Model;
class Settings {
protected $settings = [];
public function __construct() {
$this->settings['AppName'] = 'Test';
}
/**
* Fetch all values
*
* #return mixed
*/
public function getAll () {
return $this->settings;
}
}
App/Http/Controllers/XyzController.php
use Facades\App\Settings;
class XyzController extends Controller
{
public function showView()
{
return Settings::getAll();
}
}
web.php
Route::get('/','XyzController#showView');
use Facades\App\Helpers\Settings;
Route::get('/direct',function() {
return Settings::getAll();
});
use laravel Real time facades

ServiceProvider binded class not found

Case (L5.4)
Currently trying to write an api wrapper using the package development Laravel offers.
I got a ServiceProvider which binds the model (Niki::class)
class NikiServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
$this->publishes([
__DIR__ . '/config/niki.php' => config_path('niki.php'),
]);
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('niki', function () {
return new Niki;
});
}
}
A Facade which registers the name of the component
class Facade extends \Illuminate\Support\Facades\Facade
{
/**
* Get the registered name of the component.
*
* #return string
*/
public static function getFacadeAccessor()
{
return 'niki';
}
}
And a model
class Niki extends Model
{
/**
* Config
*
* #var array
*/
public function __construct()
{
$this->config = config('niki')['api_key'];
}
public static function getHouses()
{
$response = $this->config;
return $response;
}
}
Above files are located in packages/prsc/niki/src and are being loaded using the psr-4 autoloading:
"psr-4": {
"App\\": "app/",
"PRSC\\Niki\\": "packages/prsc/niki/src/"
},
Error
So now my problem, the bind in the ServiceProvider returns a FatalError because of the file not being found.
FatalThrowableError in NikiServiceProvider.php line 37: Class
'PRSC\Niki' not found
I think it's just a namespace problem. I'm not sure I have all the clue about your namespaces, but here is something that should work (if I did not misunderstood):
Replace:
return new Niki;
By:
return new \PRSC\Niki\Niki;
If it does not work, please add your namespaces in each code snippet you pasted.

Categories