模板渲染过程中抛出异常“无法解析依赖项 [Parameter #0 [ $listing ]]”

问题描述

我决定升级 Laravel 框架版本以解决关键的安全漏洞。我已成功从 5.8 升级到 6,然后升级到 6.20(漏洞修复)。 但不幸的是,我遇到了从 Laravel 框架 6.19.0 开始的错误,该错误在我的类 (BuyWidget.PHP) 中引发了与 BoundMethod.PHP 相关的异常。我通过互联网检查,发现他们在 BoundMethod.PHP (Illuminate\Container\BoundMethod) 中实现了对非指定类型的检查。

我尝试相应地更改 BuyWidget.PHP 中的所有功能public function run($listing)public function run(Listing $listing) 等。

BuyWidget.PHP

<?PHP

namespace App\Widgets\Order;

use Arrilot\Widgets\AbstractWidget;
use App\Models\Listing;

class BuyWidget extends AbstractWidget
{
    protected $config = [];
    
    public function calculate_price($listing,$params) {
        $fee_percentage = setting('marketplace_percentage_fee');
        $fee_transaction = setting('marketplace_transaction_fee');
        
        $quantity = isset($params['quantity'])?$params['quantity']:1;
        $variants = isset($params['variant'])?$params['variant']:null;
        $shipping = isset($params['shipping_option'])?$params['shipping_option']:null;
        $additional_options = isset($params['additional_option'])?$params['additional_option']:[];
        $additional_options_Meta = isset($params['additional_options_Meta'])?$params['additional_options_Meta']:[];
        
        $listing_price = $listing->price;
        
        #calculate additional variant cost
        $selected_variant = null;
        $error = false;

        $user_choice = [];
        $user_choice[] = ['group' => 'general','name' => 'quantity','value' => $quantity];

        if($variants) {
            $variant_pricing = $listing->variants;
            foreach($variants as $k => $v) {
                $variant_pricing = $variant_pricing->where("Meta.$k",$v);
                $user_choice[] = ['group' => 'variant','name' => $k,'value' => $v];
            }
            
            if($variant_pricing->count() == 1) {
                $selected_variant = $variant_pricing->first();
                $listing_price += $selected_variant->price;
                if($quantity > $selected_variant->stock) {
                    $error = __('Insufficient stock. Please lower the quantity.');
                }               
                if($selected_variant->stock < 1) {
                    $error = __('Out of Stock');
                }
            }
        }
        
        #calculate shipping cost
        $selected_shipping_price = null;
        if(!is_null($shipping)) {
            $selected_shipping_method = $listing->shipping_options->firstWhere('id',$shipping)?:null;
            if($selected_shipping_method) {
                $selected_shipping_price = $selected_shipping_method->price;
            }
            $user_choice[] = ['group' => 'shipping','name' => 'Shipping','value' => $selected_shipping_method->name,'price' => $selected_shipping_method->price];
        }

        #additional pricing
        $additional_options_price = $listing->additional_options->reduce(function ($carry,$item) use($additional_options,$additional_options_Meta) {
            if(in_array($item->id,array_keys($additional_options))) {
                $price = $item->price;
                $quantity = 1;
                if(in_array($item->id,array_keys($additional_options_Meta)) && isset($additional_options_Meta[$item->id]['quantity'])) {               
                    $quantity = (int) $additional_options_Meta[$item->id]['quantity'];
                }               
                return $carry + ($price*$quantity);
            }
                        
            return $carry;
        },0);

        $number = 0;
        foreach($listing->additional_options as $k => $item) {
            if(in_array($item->id,array_keys($additional_options))) {
                $number++;
                $user_choice[] = ['group' => 'additional_options','name' => 'Option '.($k+1),'value' => $item->name,'price' => $item->price];
            }
        }
        
        //date,time,qty
        $subtotal = ($quantity * $listing_price) + $additional_options_price;
        $service_fee_percentage = $subtotal * ($fee_percentage/100);
        $service_fee = (float) $service_fee_percentage + (float) $fee_transaction;
        $total = $subtotal + $service_fee + $selected_shipping_price;

        if($quantity > $listing->stock) {
            $error = __('Insufficient stock. Please lower the quantity.');
        }
        if($listing->stock < 1) {
            $error = __('Out of Stock');
        }
        
        //Now check if we have any slots left for this time
        $price_items = [
            [
                'key'   => 'price','label' => __(':price x :quantity :unit_label',['price' => format_money($listing_price,$listing->currency),'quantity' => $quantity,'unit_label' => $listing->unit]),'price' => ($quantity * $listing_price)
            ]
        ];
        if($selected_shipping_price) {
            $price_items[] = [
                'key'   => 'service','label' => __('Shipping'),'price' => $selected_shipping_price,];
        }

        if($additional_options_price) {
            $price_items[] = [
                'key'   => 'additional','label' => __('Additional options'),'price' => $additional_options_price,];
        }

        if($service_fee > 0) {
            $price_items[] = [
                'key' => 'service','label' => __('Service fee'),'price' => $service_fee,'notice' => __('This fee helps cover the costs of operating the website'),];
        }
        
        return [
            'user_choice'   =>  $user_choice,'error'         =>  $error,'total'         =>  $total,'service_fee'   =>  $service_fee,'price_items'   =>  $price_items,];
    
    }
    
    public function decrease_stock($order,$listing)
    {
        $quantity = $order->listing_options['quantity'];
        $listing->decrement( 'stock',$quantity );

        if(isset($order->listing_options['variant'])) {
            $variants = $order->listing_options['variant'];

            $listing_variants = $listing->variants;
            foreach($variants as $k => $v) {
                $listing_variants = $listing_variants->where("Meta.$k",$v);
            }

            if($listing_variants->count() == 1) {
                $listing_variant = $listing_variants->first();
                $listing_variant->decrement( 'stock',$quantity );
            }
        }
    }

    public function validate_payment($listing,$request)
    {
        $result = $this->calculate_price($listing,request()->all());
        return $result;
    }

    
    /**
     * Treat this method as a controller action.
     * Return view() or other content to display.
     */
    public function run($listing)
    {
        //
        $total = 0;
        $quantity = request('quantity',1);

        $result = $this->calculate_price($listing,request()->all());
        
        return view('listing.widgets.buy_widget',[
            'config'        => $this->config,'listing'       => $listing,'qs'            => http_build_query(request()->all()),'error'         => $result['error'],'total'         => $result['total'],'service_fee'   => $result['service_fee'],'price_items'   => $result['price_items'],]);
    }
}

然而,应用这些更改后,应用无法正常运行,参数始终为空,产品显示为缺货。

已在 sidebar.twig 文件中抛出初始异常,该文件根据列表类型构建小部件。

“在渲染模板期间抛出异常(“无法解析依赖项 [参数 #0 [ $listing ]]”)

sidebar.twig

{% if listing.pricing_model %}
    {{ Widget.run('Order.'~(listing.pricing_model.widget)~'Widget',{},listing) | raw }}
{% endif %}

代码在 Laravel 6.19.0 之前的任何其他版本上都能完美运行。如果我从文件 BoundMethod.PHP 手动恢复更​​改,即使在从未使用过的情况下,代码也会按预期工作。我想找到另一种解决方案来避免修改供应商文件,因为这不是最好的方法

web.PHP

include "admin.PHP";
include "payments.PHP";

Route::get('/cp',function () {
    if(env('DEMO_PANEL')) {
        \Auth::loginUsingId(1,true);
        return redirect("/panel");
    }
});

Route::group(['prefix' => LaravelLocalization::setLocale(),'middleware' => 'jailBanned'],function()
{
    Auth::routes();
    Route::get('email-verification','Auth\EmailVerificationController@sendEmailVerification')->name('email-verification.send');
    Route::get('email-verification/error','Auth\EmailVerificationController@getVerificationError')->name('email-verification.error');
    Route::get('email-verification/check/{token}','Auth\EmailVerificationController@getVerification')->name('email-verification.check');

    Route::get('/','HomeController@index')->name('home');
    Route::get('/browse','browseController@listings')->name('browse');
    Route::get('/categories','browseController@categories')->name('categories');

    Route::get('/pages/{slug?}','PageController@index')->name('page');
    Route::get('/contact','ContactController@index')->name('contact');
    Route::post('/contact','ContactController@postIndex')->name('contact.post');

    Route::get('/profile/{user}','ProfileController@index')->name('profile'); //PROFILE
    Route::get('/profile/{user}/follow','ProfileController@follow')->name('profile.follow'); //PROFILE

    //LISTINGS
    Route::group(['prefix' => 'listing'],function()
    {
        Route::get('/{listing}/{slug}','ListingController@index')->name('listing');
        Route::get('/{listing}/{slug}/card','ListingController@card')->name('listing.card');
        Route::get('/{listing}/{slug}/spotlight','ListingController@spotlight')->middleware('auth.ajax')->name('listing.spotlight');
        Route::get('/{listing}/{slug}/verify','ListingController@verify')->middleware('auth.ajax')->name('listing.verify');
        Route::get('/{listing}/{slug}/star','ListingController@star')->middleware('auth.ajax')->name('listing.star');
        Route::get('/{listing}/{slug}/edit','ListingController@edit')->name('listing.edit');
        #Route::get('/{listing}/{slug}/availability','AvailabilityController@availability')->name('listing.availability');
        Route::any('/{id}/update','ListingController@update')->name('listing.update');

    });


    //ACCOUNT
    Route::group(['middleware' => ['auth','isverified'],'prefix' => 'account','as' => 'account.','namespace' => 'Account'],function()
    {
        Route::get('/',function () {
            return redirect(route('account.edit_profile.index'));
        });
        Route::resource('change_password','PasswordController');
        Route::resource('edit_profile','ProfileController');

        Route::resource('purchase-history','PurchaseHistoryController');
        Route::resource('favorites','FavoritesController');

        Route::resource('listings','ListingsController');
        Route::resource('orders','OrdersController');

        Route::get('payments/{id}/unlink','BankAccountController@unlink')->name('payments.unlink');
        Route::resource('bank-account','BankAccountController');

        Route::get('paypal/connect','PayPalController@connect')->name('paypal.connect');
        Route::get('paypal/callback','PayPalController@callback')->name('paypal.callback');

    });

    //REQUIRES AUTHENTICATION
    Route::group(['middleware' => ['auth','isverified']],function () {

        //INBox
        Route::resource('inBox','InBoxController')->middleware('talk'); //InBox
        Route::get('/inBox/messages/{id}','InBoxController@messages')->name('inBox.messages');

        //CREATE LISTING
        Route::resource('create','CreateController');
        Route::any('/create/{listing}/session','CreateController@session')->name('create.session');
        Route::get('/create/{listing}/images','CreateController@images')->name('create.images');
        Route::get('/create/{listing}/additional','CreateController@additional')->name('create.additional');
        Route::get('/create/{listing}/pricing','CreateController@pricing')->name('create.pricing');
        Route::get('/create/{listing}/times','CreateController@getTimes')->name('create.times');
        Route::post('/create/{listing}/times','CreateController@postTimes')->name('create.times');
        Route::get('/create/{listing}/boost','CreateController@boost')->name('create.boost');

        Route::post('/create/{listing}/uploads','CreateController@upload')->name('create.upload');
        Route::delete('/create/{listing}/image/{uuid?}','CreateController@deleteUpload')->name('create.delete-image');

        //CHECKOUT
        Route::get('/checkout/error','CheckoutController@error_page')->name('checkout.error');
        Route::get('/checkout/{listing}','CheckoutController@index')->name('checkout');
        Route::post('/checkout/{listing}','CheckoutController@store')->name('checkout.store');
        Route::get('/checkout/{session}/callback','CheckoutController@callback')->name('checkout.callback');
        Route::any('/checkout/process/{listing}','CheckoutController@process')->name('checkout.process');
        #Route::any('/checkout/test','CheckoutController@test')->name('checkout.test');
        #Route::resource('stripe','StripeController');
        #Route::any('/stripe/connect','StripeController@connect')->name('stripe.connect');

        Route::any('/paypal/{listing}/start','PaypalController@start')->name('paypal.start');
        Route::any('/paypal/cancel','PaypalController@cancel')->name('paypal.cancel');
        Route::any('/paypal/callback','PaypalController@callback')->name('paypal.callback');
        Route::any('/paypal/confirm','PaypalController@confirm')->name('paypal.confirm');
        #Route::any('/paypal/create_agreement','PaypalController@create_agreement')->name('paypal.create_agreement');


    });

    //REQUIRES AUTHENTICATION
    Route::group(['middleware' => ['auth']],function () {

        Route::get('email-verification','Auth\EmailVerificationController@index')->name('email-verification.index');
        Route::get('resend-verification','Auth\EmailVerificationController@resend')->name('email-verification.resend');
        Route::get('email-verified','Auth\EmailVerificationController@verified')->name('email-verification.verified');

    });

    Route::get('login/facebook','Auth\LoginController@redirectToProvider');
    Route::get('login/facebook/callback','Auth\LoginController@handleProviderCallback');


});

#errors
Route::get('/suspended',function(){
    return 'Sorry something went wrong.';
})->name('error.suspended');

解决方法

public function run(Listing $listing)

并且您在该命名空间中包含了一个与 Listing 匹配的类?还是可以通过服务提供商获得?

,

从函数中移除参数:

public function run();

并将以下行添加到函数中:

$listing = func_get_arg(0);