FATAL ERROR perch_shop_order - error displaying order if product is deleted from catalog after order is placed.

  • When displaying an order using:

    PHP
    1. <?php
    2. perch_shop_order($orderID, [
    3. 'template' => '/shop/orders/order.html'
    4. ]);
    5. ?>

    If the product is deleted from the catalog the order returns a fatal error:


    Fatal error: Uncaught Error: Call to a member function to_array() on boolean in /pathto/site-folder/kpanel/addons/apps/perch_shop/lib/PerchShop_Order.class.php:538 Stack trace: #0 /pathto/site-folder/kpanel/addons/apps/perch_shop/lib/PerchShop_Order.class.php(393): PerchShop_Order->format_invoice_for_template(Array) #1 /pathto/site-folder/kpanel/addons/apps/perch_shop/lib/PerchShop_Order.class.php(402): PerchShop_Order->get_for_template() #2 /pathto/site-folder/kpanel/addons/apps/perch_shop/lib/PerchShop_Runtime.class.php(765): PerchShop_Order->template(Array) #3 /pathto/site-folder/kpanel/addons/apps/perch_shop/runtime/orders.php(62): PerchShop_Runtime->get_order_items(Array) #4 /pathto/site-folder/kpanel/templates/pages/shop/account/orders.php(8): perch_shop_order('16', Ar in /pathto/site-folder/kpanel/addons/apps/perch_shop/lib/PerchShop_Order.class.php on line 538


    Oddly the order information displays OK in the admin area, it just throws an error on the front end - obviously the customer will need to be able to reference historic orders, even for products that have since been deleted.


    Can this be fixed?

  • Hello Byron, thanks for the response.


    The orders are historic orders, they show OK in the admin area, and you can see the ID of the order from the admin OK.


    New orders placed work perfectly fine - until the product or variant within the order is deleted, they then show the same fatal error.


    I'll include the page anyway for you. You can ignore the shipping and billing stuff, I had to jump through hoops to show that on the order :rolleyes:.


    Here is order_better.html:

  • This part of debug has me worried this will require a fix from Drew as the system looks for the product ID and checks deletion, but something isn't working correctly:


    SELECT * FROM perch3_shop_customers WHERE memberID=3

    [1] SELECT * FROM perch3_shop_orders WHERE customerID=3 AND orderID=21 AND orderStatus IN ('paid', 'processing', 'cancelled', 'dispatched', 'returned', 'partial_refund', 'refunded')

    [2] SELECT * FROM perch3_shop_order_items WHERE orderID='21' ORDER BY itemID ASC

    [1] SELECT * FROM perch3_shop_order_statuses WHERE statusKey='paid' AND statusDeleted IS NULL LIMIT 1

    [1] SELECT * FROM perch3_shop_currencies WHERE currencyID=47 LIMIT 1

    [1] SELECT * FROM perch3_shop_shippings WHERE shippingID=4 AND shippingDeleted IS NULL LIMIT 1

    [1] SELECT * FROM perch3_shop_products WHERE productID=144 AND productDeleted IS NULL LIMIT 1

    [1] SELECT * FROM perch3_shop_currencies WHERE currencyActive=1 AND currencyID=47

    [1] SELECT promoID FROM perch3_shop_order_promotions WHERE orderID=21

    [1] SELECT * FROM perch3_shop_promotions WHERE promoID=1 LIMIT 1

    [1] Using template: /templates//shop/orders/order_better.html

  • Ok from checking the checking the core code this is where the error happens

    Code
    1. $item = array_merge($item, $Product->to_array());

    So I'm guessing the product for one of the orders no longer exists. I think you said you regenerated your variants yesterday? The order could be looking for an old product variant that no longer exists.

  • Setting the products to inactive is an option, but has the following issues:


    • Sometimes a product simply has to be removed at the clients request (ease of updating etc).
    • Sometimes a product is mistakenly deleted by the clients admin.


    As mentioned the orders display perfectly in the back end, could the same code from /addons/apps/perch_shop_orders/modes/order.detail.post.php be repurposed for the perch_shop_order function?

  • You can always use the factory methods PerchShop_Orders, PerchShop_Products and which ever other classes you need. Each Base class will have a method to_array() which you can the pass to `perch_template('path_to_template', $array)`. For just the order info for example you could do the following

    PHP
    1. <?php $OrderFactory = new PerchShop_Orders();
    2. $order = $OrderFactory->find($orderID);
    3. perch_template('/shop/orders/order_better.html', $order);

    Unfortunately with this method you lose the additional template handlers, so you can't use `<perch:cartitems>`.