I try to make a new custom class in laravel 5.4 to check the user type.
I add this new class in a new folder app\ItSolution, code:
<?php
namespace App\ItSolution;
class DemoClass {
public function getPermission() {
switch(Auth::user()->user_type_id) {
case 1:
return 'admin';
break;
case 2:
return 'promoter';
break;
case 3:
return 'customer';
break;
default:
return false;
}
}
}
I want to use this class in all my app , so i try to make a new ServiceProvider, code :
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App;
class AuthLibServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
App::bind('democlass', function()
{
return new \App\ItSolution\DemoClass;
});
}
}
And i make a new facade for my class in the same folder app\ItSolution, code:
<?php
namespace App\ItSolution;
use Illuminate\Support\Facades\Facade;
class DemoClassFacade extends Facade {
protected static function getFacadeAccessor() { return 'democlass'; }
}
After that i add this line in app/config.php
'aliases' => [
...
'DemoClass'=> App\ItSolution\DemoClassFacade::class,
]
'providers' => [
...
App\Providers\AuthLibServiceProvider::class,
]
But i have this error when i try to use the DemoClass alias in my controller
DemoClass::getPermission():
Class 'App\Http\Controllers\DemoClass' not found
How can i fix that please, Thnaks.
In laravel 5.4 you don't need a Service Provider to register a facade, you can use automatic Facadaes, you have to define only the DemoClass.
i.e in a controller:
use Facades\ {
App\ItSolution\DemoClass
};
And call the function
DemoClass::getPermission()
Source here
You're registering this class as facade, so you'll need to add this to the beginning of the class:
use DemoClass;
Or you can just use full namespace when using the facade:
\DemoClass::
Related
I'm working with Laravel 9 and I have a Controller like this:
use App\Repositories\HomeRepositoryInterface;
class HomeController extends Controller
{
private $homeRespository;
public function __construct(HomeRepositoryInterface $homeRepository)
{
$this->homeRespository = $homeRepository;
}
...
And here is the HomeRepositoryInterface:
<?php
namespace App\Repositories;
interface HomeRepositoryInterface
{
public function newest();
}
And this is the HomeRepository itself:
<?php
namespace App\Repositories;
use App\Models\Question;
class HomeRepository implements HomeRepositoryInterface
{
public function newest()
{
return $ques = Question::orderBy('created_at', 'DESC')->paginate(10);
}
}
But now I get this error:
Target [App\Repositories\HomeRepositoryInterface] is not instantiable while building [App\Http\Controllers\HomeController].
So what's going wrong here?
How can I solve this issue?
It seems that you did not introduce the service container.
For this, it is better to create a service provider as shown below and introduce the repository class to the container.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Repositories\HomeRepositoryInterface;
use App\Repositories\HomeRepository;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
// Bind Interface and Repository class together
$this->app->bind(HomeRepositoryInterface::class, HomeRepository::class);
}
}
Next, you should introduce this service provider in the config/app.php file.
'providers' => [
...
...
...
App\Providers\RepositoryServiceProvider::class,
],
Facades in Laravel 8 Are perfectly working in the controller file but I want to use on facade function in the blade file not working
error:
Error Call to undefined method App\PaymentGateway\PaymentFacade::process() (View: D:\alpha\resources\views\admin\auth\register_coverage.blade.php)
**On Blade file, this is facade function **
{{ \Payment::process() }} //// this is not working
Controller file
public function registerStore(Request $request) {
dd(Payment::process()); ///// this is working
}
I want to know the solution to this problem.
Payment File
<?php
namespace App\PaymentGateway;
class Payment {
public static function process(){
return "testing";
}
}
PaymentFacade File
<?php
namespace App\PaymentGateway\Facades;
class PaymentFacade {
protected static function getFacadeAccessor(){
return 'payment';
}
}
PaymentServiceProvier File
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\PaymentGateway\Payment;
class PaymentServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->bind('payment',function(){
return new Payment;
});
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
//
}
}
Config/app file
'providers' => [ App\Providers\PaymentServiceProvider::class,
],
'aliases' => [ 'Payment'=> App\PaymentGateway\Facades\PaymentFacade::class,
],
You should extend the base Facade class. Change App/PaymentGateway/Facades/PaymentFacade.php to
<?php
namespace App\PaymentGateway\Facades;
use Illuminate\Support\Facades\Facade;
class PaymentFacade extends Facade {
protected static function getFacadeAccessor(){
return 'payment';
}
}
I know there are so many answer, but I cannot really solve this.
I did follow this answer (How to make a REST API first web application in Laravel) to create a Repository/Gateway Pattern on Laravel 5.7
I have also the "project" on github, if someone really kindly want test/clone/see : https://github.com/sineverba/domotic-panel/tree/development (development branch)
App\Interfaces\LanInterface
<?php
/**
* Interface for LAN models operation.
*/
namespace App\Interfaces;
interface LanInterface
{
public function getAll();
}
App\Providers\ServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
/**
* Solve the "Key too long" issue
*
* #see https://laravel-news.com/laravel-5-4-key-too-long-error
*/
Schema::defaultStringLength(191);
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
$this->app->register(RepositoryServiceProvider::class);
}
}
App\Providers\RepositoryServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(
'app\Interfaces\LanInterface', // Interface
'app\Repositories\LanRepository' // Eloquent
);
}
}
App\Gateways\LanGateway
<?php
/**
* The gateway talks with Repository
*/
namespace App\Gateways;
use App\Interfaces\LanInterface;
class LanGateway
{
protected $lan_interface;
public function __construct(LanInterface $lan_interface) {
$this->lan_interface = $lan_interface;
}
public function getAll()
{
return $this->lan_interface->getAll();
}
}
App\Repositories\LanRepository
<?php
/**
* Repository for LAN object.
* PRG paradigma, instead of "User"-like class Model
*/
namespace App\Repositories;
use App\Interfaces\LanInterface;
use Illuminate\Database\Eloquent\Model;
class LanRepository extends Model implements LanInterface
{
protected $table = "lans";
public function getAll()
{
return 'bla';
}
}
I did add also App\Providers\RepositoryServiceProvider::class, in providers section of config\app.php
This is finally the controller (I know that it is not complete):
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Gateways\LanGateway;
class LanController extends Controller
{
private $lan_gateway;
/**
* Use the middleware
*
* #return void
*/
public function __construct(LanGateway $lan_gateway)
{
$this->middleware('auth');
$this->lan_gateway = $lan_gateway;
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$this->lan_gateway->getAll();
return view('v110.pages.lan');
}
}
And the error that I get is
Target [App\Interfaces\LanInterface] is not instantiable while building [App\Http\Controllers\LanController, App\Gateways\LanGateway].
I did try:
php artisan config:clear
php artisan clear-compiled
I think #nakov might be right about it being case-sensitive. I don't believe PHP itself cares about upper/lowercase namespaces, but the composer autoloader and the Laravel container use key->value array keys, which do have case-sensitive keys, to bind and retrieve classes from the container.
To ensure the names always match, try using the special ::class constant instead, like this:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Repositories\LanRepository;
use App\Interfaces\LanInterface;
class RepositoryServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(
LanInterface::class,
LanRepository::class
);
}
}
In my case i forgot to enlist the provider to confit/app.php that's why the error.
Clear the old boostrap/cache/compiled.php:
php artisan clear-compiled
Recreate boostrap/cache/compiled.php:
php artisan optimize
I have a Laravel app that requires getting some config vars that need to be used by most of my controllers.
Therefore it seems like this would be the perfect time to use middleware.
Is this the correct use of middleware? and if so, once the middleware gets the config vars, is it best practice to add these to the request object so they can be accessed by my controller?
Thanks to any responders.
J
Not, definitely!
Actually (based on you've written), the best way to go is creating an application service and registering this service on Service Container - App\Providers\AppServiceProvider (in app/Providers/AppServiceProvider.php).
Something like this:
<?php
# The Config Service:
namespace App\Services;
/**
* Config Manager
*/
class Config
{
/** #var SomeDependency */
protected $dependency;
public function __construct(SomeDependency $dependency)
{
$this->dependency = $dependency;
}
public function getVar($var)
{
// ...
}
}
In your Service Provider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
//...
/**
* Register any application services.
*
* #return void
*/
public function register()
{
$this->registerConfigManager();
}
public function registerConfigManager()
{
$this->app->singleton('config_service', function ($app) {
return new \App\Services\Config(new \SomeNamespace\SomeDependency);
});
}
//...
}
And now you can to access the service container via app(), like this:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class MyController extends Controller
{
public function index(Request $request)
{
app('config_service')->getVar('key');
//...
}
}
IMO, middlewares are made for pre-processing requests, restrict user access, and other security related.
I would simply load the configuration in the main Controller class and use it in the extending controllers.
For example:
base controller
namespace App\Http\Controllers;
uses goes here ...;
class Controller extends BaseController
{
protected $configs = [];
public function __construct() {
$this->loadConfigs();
}
protected function loadConfigs()
{
//read configuration files or tables in database
//and put the values into '$this->configs';
}
}
user controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
class User extends Controller
{
public function index()
{
echo $this->configs['toolbar.color']; //just an example
}
}
I've bind my interface called CustomerRepository to EloquentCustomerRepository. This is my CustomerServiceProvider:
public function register()
{
$this->app->bind(CustomerRepository::class,EloquentCustomerRepository::class);
$this->app->bind(PackageRepository::class,EloquentPackageRepository::class);
}
When I try to instantiate it in my controller like this:
<?php
namespace App\Http\Controllers\api\v1;
use Lsupport\repositories\api\v1\customer\CustomerRepository;
use App\Http\Controllers\Controller;
use Lsupport\customer\Customer;
use App\Http\Requests;
class CustomerController extends Controller
{
protected $CustomerRepository;
public function __construct(CustomerRepository $CustomerRepository)
{
$this->CustomerRepository = $CustomerRepository;
}
It throws the following error:
Target [Lsupport\repositories\api\v1\Customer\CustomerRepository] is not instantiable while building [App\Http\Controllers\api\v1\CustomerController].
I also registered it in app.config:
App\Providers\CustomerServiceProvider::class,
What am I doing wrong?
CustomerServiceProvider
<?php
namespace App\Providers;
use Lsupport\repositories\api\v1\customer\EloquentCustomerRepository;
use Lsupport\repositories\api\v1\customer\EloquentPackageRepository;
use Lsupport\repositories\api\v1\customer\CustomerRepository;
use Lsupport\repositories\api\v1\customer\PackageRepository;
use Illuminate\Support\ServiceProvider;
class CustomerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind(CustomerRepository::class,EloquentCustomerRepository::class);
$this->app->bind(PackageRepository::class,EloquentPackageRepository::class);
}
}
CustomerRepository
<?php
namespace Lsupport\repositories\api\v1\Customer;
interface CustomerRepository
{
public function create($request);
}
**EloquentCustomerRepository**
<?php
namespace Lsupport\repositories\api\v1\customer;
use Lsupport\repositories\api\v1\customer\CusteromRepositoryTrait;
use Lsupport\repositories\api\v1\remain\RightTrait;
use Lsupport\repositories\api\v1\remain\JsonTrait;
use Lsupport\customer\Customer;
class EloquentCustomerRepository implements CustomerRepository
{
use JsonTrait;
use RightTrait;
use CustomerRepositoryTrait;
code.....
Ok, the first thing I notice is that you probably want the same namespaces on the interface and on the class. So, the namespace of EloquentCustomerRepository should be
namespace Lsupport\repositories\api\v1\Customer;
and not
namespace Lsupport\repositories\api\v1\customer;
(with lower customer).
Now, on your CustomerServiceProvider, you should use:
public function register()
{
$this->app->bind('Lsupport\repositories\api\v1\Customer\CustomerRepository', 'Lsupport\repositories\api\v1\Customer\EloquentCustomerRepository');
}
Make sure you run composer dumpautoload -o on the command line.