laravellaravel-componentslaravel-service-container

Why I can not call Implementation method from library class?


In laravel 9 app I created class app/Implementations/LocalStorageUploadedFileManagement.php :

<?php

namespace App\Implementations;

use App\Interfaces\UploadedFileManagement;
...
use Intervention\Image\Facades\Image as Image;

class LocalStorageUploadedFileManagement implements UploadedFileManagement
{
    ...
    public function getImageFileDetails(string $itemId, string $image = null, string $itemUploadsDirectory = '',
        bool $skipNonExistingFile = false): array {
        \Log::info('++ getImageFileDetails$image ::');
        \Log::info( $image );

    }
    ...

and Interface class in app/Interfaces/UploadedFileManagement.php :

<?php

namespace App\Interfaces;

use Illuminate\Http\Request;

interface UploadedFileManagement
{
    ...
    public function getImageFileDetails(string $itemId, string $image = null, string $itemUploadsDirectory = '',
        bool $skipNonExistingFile = false): array;

}

In app/Providers/AppServiceProvider.php I have:

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('App\Interfaces\UploadedFileManagement', 'App\Implementations\LocalStorageUploadedFileManagement');
        
    }

so I can use it in my controller app/Http/Controllers/Admin/ProductController.php:

<?php

namespace App\Http\Controllers\Admin;
...
use App\Interfaces\UploadedFileManagement;

class ProductController extends Controller  // http://local-mng-products.com/admin/products
{

    public function __construct()
    {
    }

    public function edit(string $productId, UploadedFileManagement $uploadedFileManagement)
    {
        ...
        $productImgProps = $uploadedFileManagement->getImageFileDetails(
            itemId : $product->_id,
            itemUploadsDirectory : Product::getUploadsProductDir(),
            image : $product->image,
            skipNonExistingFile : true);
        
        ...

abd it works ok

But I got error :

Cannot instantiate interface App\Interfaces\UploadedFileManagement

when I try to use UploadedFileManagement in library app/Library/ReportProduct.php class :

<?php

namespace App\Library;

use App\Interfaces\UploadedFileManagement;
...
class ReportProduct
{

    public function getImageProps()
    {
        $uploadedFileManagement= new UploadedFileManagement();  // This line raised the error
        $imgProps = $uploadedFileManagement->getImageFileDetails($this->product->_id, $this->product->image, Product::getUploadsProductDir(),true);
        return $imgProps;
    }

getImageProps method is called from ProductCardReport component, which I created with command :

php artisan make:component  ProductCardReport

and it has in file app/View/Components/ProductCardReport.php :

<?php

namespace App\View\Components;

use App\Library\ReportProduct;
use Illuminate\View\Component;

class ProductCardReport extends Component
{
    public string $productId;

    public function __construct(string $productId)
    {
        $this->productId = $productId;
    }

    public function render()
    {
        $reportProduct = new ReportProduct($this->productId);
        $reportProduct->loadProduct();
        $productData = $reportProduct->getProductData(true);

        $productImgProps = $reportProduct->getImageProps();
        ...
    

Why I got error in ReportProduct.php class on using of UploadedFileManagement service?

How that can be done ?

MODIFIED BLOCK : I tried to inject it in the same way I did in ProductController edit function. But I failed as If I try to edit app/Library/ReportProduct.php with similar injection :

<?php

namespace App\Library;

use App\Interfaces\UploadedFileManagement;
...

class ReportProduct
{
    public function __construct(Product | string $product, UploadedFileManagement $uploadedFileManagement = null)
    {
        $this->uploadedFileManagement = $uploadedFileManagement;
        ...

But as I create ReportProduct and call getImageProps from app/View/Components/ProductCardReport.php component I need to UploadedFileManagement class from somewhere for the 1st time . I can not inject UploadedFileManagement in app/View/Components/ProductCardReport.php. Not shure how injection works here and how can I use it in chain Component->customClass?

Thanks!


Solution

  • Valid decision is :

    $uploadedFileManagement= app(UploadedFileManagement::class);
    $productImgProps = $uploadedFileManagement->getImageFileDetails(
        itemId : $product->_id,
        itemUploadsDirectory : Product::getUploadsProductDir(),
        image : $product->image,
        skipNonExistingFile : true);