How can I solve Target [App\Repositories\NewsRepository] is not instantiable while building [App\Http\Controllers\Member\NewsController].? - laravel

My controller like this :
...
use App\Repositories\NewsRepository;
class NewsController extends Controller
{
protected $repository;
public function __construct(NewsRepository $repository)
{
$this->repository = $repository;
}
public function store(NewsCreateRequest $request)
{
...
$news = $this->repository->create($input);
...
}
}
My interface like this :
namespace App\Repositories;
use Prettus\Repository\Contracts\RepositoryInterface;
interface NewsRepository extends RepositoryInterface
{
//
}
My class like this :
...
use App\Repositories\NewsRepository;
class NewsRepositoryEloquent extends BaseRepository implements NewsRepository
{
public function model()
{
return News::class;
}
public function boot()
{
$this->pushCriteria(app(RequestCriteria::class));
}
}
My repository service provider like this :
...
class RepositoryServiceProvider extends ServiceProvider
{
...
public function register()
{
...
$this->app->bind(\App\Repositories\NewsRepository::class, \App\Repositories\NewsRepositoryEloquent::class);
}
}
If the method store on the controller executed, there exist error :
(1/1) BindingResolutionException Target
[App\Repositories\NewsRepository] is not instantiable while building
[App\Http\Controllers\Member\NewsRepository].
How can I solve the error?

You have to add constructor to your repository and call parent constructor for setup model like this:
public function __construct(Permission $model)
{
parent::__construct($model);
}

Related

Target class [App\Repositories\User\UserRepository] does not exist

I'm using laravel and try to integrate the repository in laravel.
follow this link https://www.itsolutionstuff.com/post/laravel-5-repository-pattern-tutorial-from-scratchexample.html.
but getting the below issue. don't know what's wrong with code. try to find a solution but not getting any particular solution.
UserInterface
namespace App\Repositories\User;
interface UserInterface {
public function getAll();
public function find($id);
public function delete($id);
}
UserRepoServiceProvide
use Illuminate\Support\ServiceProvider;
class UserRepoServiceProvide extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('App\Repositories\User\UserInterface', 'App\Repositories\User\UserRepository');
}
UserRepository
use App\Repositories\User\UserInterface as UserInterface;
use App\User;
class UserRepository implements UserInterface
{
public $user;
function __construct(User $user) {
$this->user = $user;
}
public function getAll()
{
return $this->user->getAll();
}
public function find($id)
{
return $this->user->findUser($id);
}
public function delete($id)
{
return $this->user->deleteUser($id);
}
}
User Model
public function getAll()
{
return static::all();
}
public function findUser($id)
{
return static::find($id);
}
public function deleteUser($id)
{
return static::find($id)->delete();
}
UserController
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Repositories\User\UserInterface as UserInterface;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function __construct(UserInterface $user)
{
$this->user = $user;
}
public function index()
{
$users = $this->user->getAll();
return view('users.index',['users']);
}
}
composer.json
"autoload": {
"psr-4": {
"App\\": "app/",
"App\\Repositories\\": "app/Repositories/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
but still getting this issue
Please Help.
folder path
In your UserController :
remove
use App\Repositories\User\UserInterface as UserInterface;
and add
use App\Repositories\User\UserRepository as UserInterface;

PHPUnit test for Laravel Artisan command without calling external API in inner instance (dependency injection)

I am trying to write a phpunit test with laravel 5.2 for a console command.
Few resources seems promising, but so far I failed making it work. I am trying to follow info given here:
stackoverflow - PHPUnit test for Laravel Artisan command that calls an external API without calling that API physically?
Laravel binding
The test is calling a command that 'binds' ExternalAPI class in its constructor.
In the test, I mock the ExternalAPI.
The ExternalAPI class:
Class ExternalAPI {
protected $lang;
public function __construct($lang)
{
$this->lang = $lang;
}
public function call_api($myparam){
//do the api stuff here
}
}
The command:
class MyCommand extends Command
{
protected $signature = 'check:mycommand';
protected $externalAPI ;
public function __construct(ExternalAPI $externalAPI)
{
$this->externalAPI = $externalAPI;
parent::__construct();
}
public function handle()
{
$res = $this->externalAPI->call_api('test');
}
}
The test:
class MyCommandTest extends TestCase
{
public function setUp()
{
parent::setUp();
$methods_to_stub = ['call_api'];
$mock = $this->getMockBuilder('\ExternalAPI')
->setConstructorArgs(array('param_value'))
->setMethods($methods_to_stub)
->getMock();
$mock->method('call_api')->willReturn(44.44);
$this->app->instance(ExternalAPI::class, $mock);
}
public function test1()
{
$output = new BufferedOutput;
Artisan::call('check:mycommand', [],$output);
echo "output:$output\n\n";
}
}
The error is:
Illuminate\Contracts\Container\BindingResolutionException:
Unresolvable dependency resolving [Parameter #0 [
$myparam]] in class App\MyLibrary\ExternalAPI
I managed to get it to work using mockery
This is the corrected code that works for me:
The ExternalAPI class (I removed the param from the constructor because right now I didn't check if and how it can be done):
Class ExternalAPI {
protected $lang;
public function __construct()
{
}
public function init($lang)
{
$this->lang = $lang;
}
public function call_api($myparam){
//do the api stuff here
}
}
The command:
class MyCommand extends Command
{
protected $signature = 'check:mycommand';
protected $externalAPI ;
public function __construct()
{
$this->externalAPI = app(ExternalAPI::class);
parent::__construct();
}
public function handle()
{
$this->externalAPI->init('whatever')
$res = $this->externalAPI->call_api('test');
}
}
The AppServiceProvider:
class AppServiceProvider extends ServiceProvider{
public function boot()
{
$this->app->bind('App\MyLibrary\ExternalAPI',function(){
return new \App\MyLibrary\ExternalAPI();
});
}
}
The test:
class MyCommandTest extends TestCase
{
public function setUp()
{
parent::setUp();
$mock = Mockery::mock('ExternalAPI');
$mock->shouldReceive('call_api')->with(Mockery::any())->andReturn(44.44);
$mock->shouldReceive('init')->with(Mockery::any());
$this->app->instance(ExternalAPI::class, $mock);
}
public function test1()
{
$output = new BufferedOutput;
Artisan::call('check:mycommand', [],$output);
echo "output:$output\n\n";
}
}

Add function to laravel Notification

I have next Notification class:
class WelcomeNotification extends Notification
{
use Queueable;
public function __construct()
{
//
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
//
];
}
}
And I want add some function to this. For example:
public function myFunction()
{
return 'something';
}
But $user->notifications->first()->myFunction return nothing
When you call the notifications() relation it turns out is a polymorphic relation using the DatabaseNotification model. The proper way is to inherit DatabaseNotification and write the custom function their.
For example, create app/DatabaseNotification/WelcomeNotification.php and inherit DatabaseNotification model.
namespace App\DatabaseNotification;
use Illuminate\Notifications\DatabaseNotification;
class WelcomeNotification extends DatabaseNotification
{
public function foo() {
return 'bar';
}
}
And override the notifications() function that uses the Notifiable trait:
use App\DatabaseNotification\WelcomeNotification;
class User extends Authenticatable
{
use Notifiable;
...
public function notifications()
{
return $this->morphMany(WelcomeNotification::class, 'notifiable')
->orderBy('created_at', 'desc');
}
...
}
And now you can call the custom function as follows:
$user->notifications->first()->foo();

Magento 2 Error - Model collection resource name is not defined

I'm going through Magento 2 tutorials and I'm having trouble getting a collection from my custom model's factory after calling the create() method. It throws an error saying the "Model collection resource name is not defined". I've already cleared /var/generation and recompiled the di.
Company/Module/Model/Vendor.php
namespace Company\Module\Model;
class Vendor extends \Magento\Framework\Model\AbstractModel {
protected function _constructor() {
$this->_init('Company\Module\Model\Resource\Vendor');
}
}
Company/Module/Model/Resource/Vendor.php
namespace Company\Module\Model\Resource;
class Vendor extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
$this->_init(
'company_vendor',
'vendor_id'
);
}
}
Company/Module/Model/Resource/Vendor/Collection.php
namespace Company\Module\Model\Resource\Vendor;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{
$this->_init(
'Company\Module\Model\Vendor',
'Company\Module\Model\Resource\Vendor'
);
}
}
Company/Module/Block/VendorList.php
namespace Company\Module\Block;
class VendorList extends \Magento\Framework\View\Element\Template {
protected $vendorFactory;
public function __construct(\Magento\Framework\View\Element\Template\Context $context,
\Company\Module\Model\VendorFactory $vendorFactory,
array $data = [])
{
parent::__construct($context, $data);
$this->vendorFactory = $vendorFactory;
}
public function getVendors() {
return $this->vendorFactory->create()->getCollection()->getItems(); //fails on getCollection()
}
This is the error I get:
1 exception(s):
Exception #0 (Magento\Framework\Exception\LocalizedException): Model collection resource name is not defined.
You need to do following change.
Company/Module/Model/Vendor.php
namespace Company\Module\Model;
class Vendor extends \Magento\Framework\Model\AbstractModel {
protected function _constructor() {
$this->_init('Company\Module\Model\ResourceModel\Vendor');
}
}
Company/Module/Model/ResourceModel/Vendor.php
namespace Company\Module\Model\ResourceModel;
class Vendor extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
$this->_init('company_vendor','vendor_id');
}
}
Company/Module/Model/ResourceModel/Vendor/Collection.php
namespace Company\Module\Model\ResourceModel\Vendor;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
public function _construct()
{
$this->_init('Company\Module\Model\Vendor','Company\Module\Model\ResourceModel\Vendor'
);
}
}
The issue was I had _constructor() instead of _construct()
namespace Company\Module\Model;
class Vendor extends \Magento\Framework\Model\AbstractModel {
protected function _construct() {
$this->_init('Company\Module\Model\Resource\Vendor');
}
}

Laravel Multiple module using one Controller

Now I have few modules created like Product, Sale, Category. I found out they actually using same function with similar process. For example update() in Controller :
Category
public function update($id)
{
$instance = Category::findOrFail($id);
$instance->fill(Input::all())->save();
}
Product
public function update($id)
{
$instance = Product::findOrFail($id);
$instance->fill(Input::all())->save();
}
How can I join it together to BaseController by just make the Model dynamic?
Something like this:
abstract class ResourceController extends BaseController
{
protected $entity;
public function __construct(Model $entity){ //or Eloquent, depending on your import alias
$this->entity = $entity;
}
public function update($id)
{
$instance = $this->entity->findOrFail( $id );
$instance->fill( Input::all() )->save();
}
}
class ProductController extends ResourceController{
public function __construct(Product $entity){
parent::__construct($entity);
}
}
class CategoryController extends ResourceController{
public function __construct(Category $entity){
parent::__construct($entity);
}
}

Resources