item_id == $object_id ) ? WC_Order_Factory::get_order_item( $object_id ) : wc_get_order( $object_id ); $object->add_meta_data( 'random_other', 'This might disappear :cry:.' ); $object->save(); // 'random_other' will be saved correctly, 'random' will also be saved // Now set some meta data for it using the pre-CRUD approach if ( $this->item_id == $object_id ) { wc_update_order_item_meta( $object_id, 'random_other_pre_crud', 'This might disappear too :sob:.' ); } else { update_post_meta( $object_id, 'random_other_pre_crud', 'This might disappear too :sob:.' ); } } /** * Instantiate an instance of an order line item, save meta on that item, then trigger a hook which only passes the * item's ID to callbacks. Afterwards, save the existing item without that other meta here and log the result to * show that data has been removed. */ function test_disappearing_item_meta() { // Setup for testing by making an item. $item = new WC_Order_Item_Product(); $this->item_id = $item->save(); $item = WC_Order_Factory::get_order_item( $this->item_id ); // First make sure we're starting from a clean slate $item->delete_meta_data( 'random' ); $item->delete_meta_data( 'random_other' ); $item->delete_meta_data( 'random_other_pre_crud' ); $item->save(); // Now add one piece of meta $item->add_meta_data( 'random', (string) rand( 0, 0xffffff ) ); $item->save(); // 'random' will be saved correctly // Run callback that passes just the item's ID to mimic this kind of normal behaviour in WP/WC $this->add_different_object_meta( $this->item_id ); // Resave our current item that has our meta data, but not the other piece of meta data $item->save(); // Get a new instance that should have both 'random' and 'random_other' set on it $new_item = WC_Order_Factory::get_order_item( $this->item_id ); // The original $item should have 1 item of meta - random. $this->assertCount( 1, $item->get_meta_data() ); $this->assertTrue( in_array( 'random', wp_list_pluck( $item->get_meta_data(), 'key' ) ) ); // The new $item should have 3 items of meta since it's freshly loaded. $this->assertCount( 3, $new_item->get_meta_data() ); $this->assertTrue( in_array( 'random', wp_list_pluck( $new_item->get_meta_data(), 'key' ) ) ); $this->assertTrue( in_array( 'random_other', wp_list_pluck( $new_item->get_meta_data(), 'key' ) ) ); $this->assertTrue( in_array( 'random_other_pre_crud', wp_list_pluck( $new_item->get_meta_data(), 'key' ) ) ); } /** * Instantiate an instance of an order, save meta on that order, then trigger a hook which only passes the order's ID to * callbacks. Afterwards, save the existing order without that other meta here and log the result to show that data * has been removed. */ function test_disappearing_order_meta() { // Setup for testing by making an item. $order = new WC_Order(); $this->order_id = $order->save(); $order = wc_get_order( $this->order_id ); // First make sure we're starting from a clean slate $order->delete_meta_data( 'random' ); $order->delete_meta_data( 'random_other' ); $order->delete_meta_data( 'random_other_pre_crud' ); $order->save(); // Now add one piece of meta $order->add_meta_data( 'random', (string) rand( 0, 0xffffff ) ); $order->save(); // 'random' will be saved correctly // Run callback that passes just the item's ID to mimic this kind of normal behaviour in WP/WC $this->add_different_object_meta( $this->order_id ); // Resave our current item that has our meta data, but not the other piece of meta data $order->save(); // Get a new instance of the same order. It should have both 'random' and 'random_other' set on it $new_order = wc_get_order( $this->order_id ); // The original $order should have 1 item of meta - random. $this->assertCount( 1, $order->get_meta_data() ); $this->assertTrue( in_array( 'random', wp_list_pluck( $order->get_meta_data(), 'key' ) ) ); // The new $order should have 3 items of meta since it's freshly loaded. $this->assertCount( 3, $new_order->get_meta_data() ); $this->assertTrue( in_array( 'random', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) ); $this->assertTrue( in_array( 'random_other', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) ); $this->assertTrue( in_array( 'random_other_pre_crud', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) ); } /** * Tests that the meta data cache gets flushed when update_post_meta updates the object's meta. * @see https://github.com/woocommerce/woocommerce/issues/15274 */ function test_get_meta_data_after_update_post_meta() { // Create an object. $object = new WC_Product; $object->save(); // Update a meta value. update_post_meta( $object->get_id(), '_some_meta_key', 'val1' ); $product = wc_get_product( $object->get_id() ); $this->assertEquals( 'val1', $product->get_meta( '_some_meta_key', true ) ); // Update meta to diff value. update_post_meta( $object->get_id(), '_some_meta_key', 'val2' ); $product = wc_get_product( $object->get_id() ); $this->assertEquals( 'val2', $product->get_meta( '_some_meta_key', true ) ); } /** * Tests setting objects and strings in meta to ensure slashing/unslashing works. */ function test_strings_in_meta() { // Create objects. $object = new WC_Product; $object_to_store = new stdClass(); $object_to_store->prop1 = 'prop_value'; $object_to_store->prop2 = 'prop_value_with_\\\"quotes"'; $object->add_meta_data( 'Test Object', $object_to_store ); $object->add_meta_data( 'Test meta with slash', 'Test\slashes' ); $object_id = $object->save(); // Get object and check it. $object = wc_get_product( $object_id ); $value = $object->get_meta( 'Test Object', true ); $this->assertEquals( $object_to_store, $object->get_meta( 'Test Object', true ) ); $this->assertEquals( 'Test\slashes', $object->get_meta( 'Test meta with slash', true ) ); // clean $object->delete(); } }