OFFLINE-GmbH/oc-mall-plugin

Call to a member function mapWithKeys() on array error if Old Price disabled

dathwa opened this issue ยท 6 comments

Hello.
just updated to Mall 3.2.1. Some great new features. Awesome.
Here's a small issue.
With the new enabled/disabled option for price categories, I disabled "Old Price".
And then when I try to update product prices, I'm getting the error below...
For now i've re-enabled Old Price.
Can u fix it?

And while i'm here, In backend, virtual products,

This product does not have a file attached. Please make sure to add one or programmatically generate it during checkout.
You can find information on how to do this [in the documentation](https://offline-gmbh.github.io/oc-mall-plugin/digging-deeper/virtual-products.html#generate-user-specific-product-files).

the link is dead!

Thanks

[2024-05-01 13:15:39] development.ERROR: Error: Call to a member function mapWithKeys() on array in \plugins\offline\mall\classes\traits\PriceAccessors.php:86
Stack trace:
#0 \plugins\offline\mall\classes\traits\ProductPriceAccessors.php(80): OFFLINE\Mall\Models\Product->mapCurrencyPrices(Array)
#1 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php(661): OFFLINE\Mall\Models\Product->getOldPriceAttribute(NULL)
#2 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php(2083): Illuminate\Database\Eloquent\Model->mutateAttribute('old_price', NULL)
#3 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php(492): Illuminate\Database\Eloquent\Model->transformModelValue('old_price', NULL)
#4 \vendor\october\rain\src\Database\Concerns\HasAttributes.php(111): Illuminate\Database\Eloquent\Model->getAttributeValue('old_price')
#5 \vendor\october\rain\src\Database\Concerns\HasAttributes.php(75): October\Rain\Database\Model->getAttributeValue('old_price')
#6 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php(2222): October\Rain\Database\Model->getAttribute('old_price')
#7 \vendor\october\rain\src\Extension\ExtendableTrait.php(440): Illuminate\Database\Eloquent\Model->__get('old_price')
#8 \vendor\october\rain\src\Database\Model.php(271): October\Rain\Database\Model->extendableGet('old_price')
#9 \plugins\offline\mall\classes\traits\ProductPriceAccessors.php(85): October\Rain\Database\Model->__get('old_price')
#10 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php(661): OFFLINE\Mall\Models\Product->getOnSaleAttribute(NULL)
#11 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php(2083): Illuminate\Database\Eloquent\Model->mutateAttribute('on_sale', NULL)
#12 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php(492): Illuminate\Database\Eloquent\Model->transformModelValue('on_sale', NULL)
#13 \vendor\october\rain\src\Database\Concerns\HasAttributes.php(111): Illuminate\Database\Eloquent\Model->getAttributeValue('on_sale')
#14 \vendor\october\rain\src\Database\Concerns\HasAttributes.php(75): October\Rain\Database\Model->getAttributeValue('on_sale')
#15 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php(2222): October\Rain\Database\Model->getAttribute('on_sale')
#16 \vendor\october\rain\src\Extension\ExtendableTrait.php(440): Illuminate\Database\Eloquent\Model->__get('on_sale')
#17 \vendor\october\rain\src\Database\Model.php(271): October\Rain\Database\Model->extendableGet('on_sale')
#18 \plugins\offline\mall\classes\index\ProductEntry.php(28): October\Rain\Database\Model->__get('on_sale')
#19 \plugins\offline\mall\classes\observers\ProductObserver.php(48): OFFLINE\Mall\Classes\Index\ProductEntry->__construct(Object(OFFLINE\Mall\Models\Product))
#20 \plugins\offline\mall\classes\traits\ProductPriceTable.php(94): OFFLINE\Mall\Classes\Observers\ProductObserver->updated(Object(OFFLINE\Mall\Models\Product))
#21 \modules\system\traits\DependencyMaker.php(29): OFFLINE\Mall\Controllers\Products->onPriceTablePersist('88')
#22 \modules\backend\classes\Controller.php(646): Backend\Classes\Controller->makeCallMethod(Object(OFFLINE\Mall\Controllers\Products), 'onPriceTablePer...', Array)
#23 \modules\backend\classes\Controller.php(457): Backend\Classes\Controller->runAjaxHandler('onPriceTablePer...')
#24 \modules\backend\classes\Controller.php(265): Backend\Classes\Controller->execAjaxHandlers()
#25 \modules\backend\classes\BackendController.php(137): Backend\Classes\Controller->run('update', Array)
#26 \vendor\laravel\framework\src\Illuminate\Routing\Controller.php(54): Backend\Classes\BackendController->run('offline/mall/pr...')
#27 \vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction('run', Array)
#28 \vendor\laravel\framework\src\Illuminate\Routing\Route.php(260): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Backend\Classes\BackendController), 'run')
#29 \vendor\laravel\framework\src\Illuminate\Routing\Route.php(205): Illuminate\Routing\Route->runController()
#30 \vendor\laravel\framework\src\Illuminate\Routing\Router.php(798): Illuminate\Routing\Route->run()
#31 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#32 \vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#33 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#34 \vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#35 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#36 \vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#37 \vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest(Object(Illuminate\Http\Request), Object(Illuminate\Session\Store), Object(Closure))
#38 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#39 \vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#40 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#41 \vendor\laravel\framework\src\Illuminate\Cookie\Middleware\EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#42 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#43 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#44 \vendor\laravel\framework\src\Illuminate\Routing\Router.php(799): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#45 \vendor\laravel\framework\src\Illuminate\Routing\Router.php(776): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#46 \vendor\laravel\framework\src\Illuminate\Routing\Router.php(740): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
#47 \vendor\october\rain\src\Router\CoreRouter.php(32): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#48 \vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(190): October\Rain\Router\CoreRouter->dispatch(Object(Illuminate\Http\Request))
#49 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#50 \plugins\offline\speedy\classes\middleware\CDNMiddleware.php(23): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#51 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): OFFLINE\Speedy\Classes\Middleware\CDNMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
#52 \plugins\offline\speedy\classes\middleware\Http2Middleware.php(38): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#53 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): OFFLINE\Speedy\Classes\Middleware\Http2Middleware->handle(Object(Illuminate\Http\Request), Object(Closure))
#54 \plugins\offline\responsiveimages\classes\ResponsiveImagesMiddleware.php(30): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#55 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): OFFLINE\ResponsiveImages\Classes\ResponsiveImagesMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
#56 \vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#57 \vendor\october\rain\src\Foundation\Http\Middleware\CheckForMaintenanceMode.php(23): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure))
#58 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): October\Rain\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#59 \vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#60 \vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(165): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#61 \vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(134): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#62 \index.php(43): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#63 {main}  

Hello,

thanks for reporting this issue. I fixed both, the PHP error and the documentation link. Available in the next branch, will be released with v3.2.2.

Sincerely,
Sam.

In our case, we had no records under Settings > Price Categories simply because we started with a fresh installation. A temporary fix until 3.2.2 is release is:

  • Create new record under Settings > Price Categories
  • Make sure code is set to old_price ( not old-price )
  • Keep it enabled as suggested by @dathwa

This fix will be released in v3.2.2.

Hello @tobias-kuendig .
Mall 3.3.0. After disabling "Old Price", I'm seeing this error on front end...
development.ERROR: Twig\Error\RuntimeError: Impossible to access an attribute ("integer") on a null variable in "\plugins/offline/mall/components/product/price.htm" at line 3. in \vendor\twig\twig\src\Extension\CoreExtension.php:1510

This happens when CMS_STRICT_VARIABLES=true

Thanks

You can overwrite the partial within your theme and remove the oldPrice part in the mentioned file.

{% set price = price|default(item.price()) %}

{% if price.official or item.oldPrice() %}
    <div class="mall-product__old-price">
        {% if price.official %}
            {{ price.official.string|raw }}
        {% else %}
            {# item.oldPrice().string|raw #}
        {% endif %}
    </div>
{% endif %}
<div class="mall-product__current-price">
    {% partial __SELF__ ~ '::currentprice' price=price.string %}
</div>

Fixed in next branch, released in v3.3.1.