I a writing a shipping plugin for WooCommerce, and when I try to get the values of a protected key ([key:protected]) it returns empty. How do we get the value of a protected key from an array or an object?
Specifically, in the calculate_shipping function of the woocommerce_shipping_init it passes in $package, which is an array which also contains some objects, and some of the object keys are protected. So $package looks something like this (this is a simplified version):
Array
(
[contents] => Array
(
[abc123] => Array
(
[quantity] => 1
[data] => WC_Product_Simple Object
(
[object_type:protected] => product
[data:protected] => Array
(
[name] => Carnal Seed CD and Study Guide - Oil Merchant Series
[slug] => carnal-seed-cd-and-study-guide-oil-merchant-series
)
)
)
)
)
So the issue that when I try to get [name] or [slug], I get an empty value back for [data:protected] object (and therefore [name] and [slug] do not exist). For example:
$data = $package['contents']['abc123']['data']->data; // $data returns empty
So how do we get the value of a protected key from an array or an object?
2
Answers
B. Fleming has a better answer than this, but I still wanted to share what I figured out before I saw his response.
First I convert the object to an array. This takes
[key:protected]
from the object, and makes it a protected array key like this[ * key]
.The protected array key can then be accessed like this
$my_array[" * key"]
(you must use double-quotes, as it does not work with single quotes).So my solution was this:
Protected properties cannot be accessed from outside of the object’s internal context, much like private properties. What differentiates protected and private properties, however, is that an extending object may view the parent’s protected properties, but not the private properties.
If you must access the protected properties directly for whatever reason, then extend the target object and provide a getter method:
With that being said, the class
WC_Product_Simple
should already extend a parent object that exposes aget_data()
method. This may be what you’re looking for. In that case, simply execute the following instead: