I have a class.
<?php class WC_Swatch_Picker { private $size; private $attributes; private $selected_attributes; private $swatch_type_options; public function __construct( $product_id, $attributes, $selected_attributes ) { $this->swatch_type_options = maybe_unserialize( get_post_meta( $product_id, '_swatch_type_options', true ) ); if ( !$this->swatch_type_options ) { $this->swatch_type_options = array(); } $product_configured_size = get_post_meta( $product_id, '_swatch_size', true ); if ( !$product_configured_size ) { $this->size = 'swatches_image_size'; } else { $this->size = $product_configured_size; } $this->attributes = $attributes; $this->selected_attributes = $selected_attributes; } public function picker() { ?> <table class="variations-table" cellspacing="0"> <tbody> <?php $loop = 0; foreach ( $this->attributes as $name => $options ) : $loop++; $st_name = sanitize_title( $name ); $hashed_name = md5( $st_name ); $lookup_name = ''; if ( isset( $this->swatch_type_options[$hashed_name] ) ) { $lookup_name = $hashed_name; } elseif ( isset( $this->swatch_type_options[$st_name] ) ) { $lookup_name = $st_name; } ?> <tr> <td class="label"><label for="<?php echo $st_name; ?>"><?php echo WC_Swatches_Compatibility::wc_attribute_label( $name ); ?></label></td> <td> <?php if ( isset( $this->swatch_type_options[$lookup_name] ) ) { $picker_type = $this->swatch_type_options[$lookup_name]['type']; if ( $picker_type == 'default' ) { $this->render_default( $st_name, $options ); } else { $this->render_picker( $st_name, $options, $name ); } } else { $this->render_default( $st_name, $options ); } ?> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php } I am trying to extend that class so that I can output the picker() method that displays <table> as a <div> instead.
Here is my attempt to extend that class.
class SSi_WC_Swatch_Picker extends WC_Swatch_Picker { public function picker() { ?> <div class="variations-table"> <?php $loop = 0; foreach ( $this->attributes as $name => $options ) : $loop++; $st_name = sanitize_title( $name ); $hashed_name = md5( $st_name ); $lookup_name = ''; if ( isset( $this->swatch_type_options[$hashed_name] ) ) { $lookup_name = $hashed_name; } elseif ( isset( $this->swatch_type_options[$st_name] ) ) { $lookup_name = $st_name; } ?> <div> <div class="label"><label for="<?php echo $st_name; ?>"><?php echo WC_Swatches_Compatibility::wc_attribute_label( $name ); ?></label></div> <div> <?php if ( isset( $this->swatch_type_options[$lookup_name] ) ) { $picker_type = $this->swatch_type_options[$lookup_name]['type']; if ( $picker_type == 'default' ) { $this->render_default( $st_name, $options ); } else { $this->render_picker( $st_name, $options, $name ); } } else { $this->render_default( $st_name, $options ); } ?> </div> </div> <?php endforeach; ?> </div> <?php } } My output on screen shows the <div> like I want but I get: Notice: Undefined property: SSi_WC_Swatch_Picker::$attributes and Warning: Invalid argument supplied for foreach()
I believe that it is because the parent class defines $attributes as private.
Unfortunately I cannot change the parent class.
So my noob questions is can the $attributes be accessed from the subclass somehow? I do not see a __get or __set method in the parent class so I'm guessing there isn't.
The developer is changing the private attributes to protected. So that will solve my issue of accessing the properties.
pickermethod is ugly. You shouldnt switch in and out of PHP like that in a class. I know this is a WP/WooCommerce thing, but im just throwing that out there so that you never do that on your own when you do have a choice :-)protectedinstead ofprivate. Then your subclass could access the parent class variables. That kind of violates encapsulation, but it's something you can do.protectedbut I have not heard back so trying to find an alternate workaround.