Complex classes like WC_Structured_Data often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use WC_Structured_Data, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class WC_Structured_Data { |
||
17 | |||
18 | /** |
||
19 | * @var array Partially structured data |
||
20 | */ |
||
21 | private $data; |
||
22 | |||
23 | /** |
||
24 | * Checks if the passed $json variable is an array and stores it into $this->data... |
||
25 | * |
||
26 | * @param array $json Partially structured data |
||
27 | * @return bool Returns false If the param $json is not an array |
||
28 | */ |
||
29 | private function set_data( $json ) { |
||
36 | |||
37 | /** |
||
38 | * Structures and returns the data... |
||
39 | * |
||
40 | * @return array If data is set, returns the structured data, otherwise returns empty array |
||
41 | */ |
||
42 | private function get_data() { |
||
83 | |||
84 | /** |
||
85 | * Contructor |
||
86 | */ |
||
87 | public function __construct() { |
||
95 | |||
96 | /** |
||
97 | * Sanitizes, encodes and echoes the structured data into `wp_footer` action hook. |
||
98 | */ |
||
99 | public function enqueue_data() { |
||
106 | |||
107 | /** |
||
108 | * Sanitizes the structured data. |
||
109 | * |
||
110 | * @param array $data |
||
111 | * @return array $sanitized_data |
||
112 | */ |
||
113 | private function sanitize_data( $data ) { |
||
120 | |||
121 | /** |
||
122 | * Generates the product category structured data... |
||
123 | * Hooked into the `woocommerce_before_shop_loop_item` action hook... |
||
124 | */ |
||
125 | public function generate_product_category_data() { |
||
132 | |||
133 | /** |
||
134 | * Generates the product structured data... |
||
135 | * Hooked into the `woocommerce_single_product_summary` action hook... |
||
136 | * Applies the `woocommerce_structured_data_product` filter hook for clean structured data customization... |
||
137 | */ |
||
138 | public function generate_product_data() { |
||
139 | global $product; |
||
140 | |||
141 | if ( $product->is_downloadable() ) { |
||
142 | switch ( $product->download_type ) { |
||
143 | case 'application' : |
||
144 | $type = "SoftwareApplication"; |
||
145 | break; |
||
146 | case 'music' : |
||
147 | $type = "MusicAlbum"; |
||
148 | break; |
||
149 | default : |
||
150 | $type = "Product"; |
||
151 | break; |
||
152 | } |
||
153 | } else { |
||
154 | $type = "Product"; |
||
155 | } |
||
156 | |||
157 | $json['@type'] = $type; |
||
158 | $json['@id'] = get_the_permalink(); |
||
159 | $json['name'] = get_the_title(); |
||
160 | $json['description'] = get_the_excerpt(); |
||
161 | $json['url'] = get_the_permalink(); |
||
162 | |||
163 | if ( $product->get_rating_count() ) { |
||
164 | $json['aggregateRating'] = array( |
||
165 | '@type' => 'AggregateRating', |
||
166 | 'ratingValue' => $product->get_average_rating(), |
||
167 | 'ratingCount' => $product->get_rating_count(), |
||
168 | 'reviewCount' => $product->get_review_count() |
||
169 | ); |
||
170 | } |
||
171 | |||
172 | if ( $is_multi_variation = count( $product->get_children() ) > 1 ? true : false ) { |
||
173 | $variations = $product->get_available_variations(); |
||
174 | } else { |
||
175 | $variations = array( null ); |
||
176 | } |
||
177 | |||
178 | foreach ( $variations as $variation ) { |
||
179 | $product_variation = $is_multi_variation ? wc_get_product( $variation['variation_id'] ) : $product; |
||
180 | |||
181 | $json_offers[] = array( |
||
182 | '@type' => 'Offer', |
||
183 | 'priceCurrency' => get_woocommerce_currency(), |
||
184 | 'price' => $product_variation->get_price(), |
||
185 | 'availability' => 'http://schema.org/' . $stock = ( $product_variation->is_in_stock() ? 'InStock' : 'OutOfStock' ), |
||
186 | 'sku' => $product_variation->get_sku(), |
||
187 | 'image' => wp_get_attachment_url( $product_variation->get_image_id() ), |
||
188 | 'description' => $is_multi_variation ? $product_variation->get_variation_description() : '' |
||
189 | ); |
||
190 | } |
||
191 | |||
192 | $json['offers'] = $json_offers; |
||
193 | |||
194 | $this->set_data( apply_filters( 'woocommerce_structured_data_product', $json, $product ) ); |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * Generates the product review structured data... |
||
199 | * Hooked into the `woocommerce_review_meta` action hook... |
||
200 | * Applies the `woocommerce_structured_data_product_review` filter hook for clean structured data customization... |
||
201 | * |
||
202 | * @param object $comment From `woocommerce_review_meta` action hook |
||
203 | */ |
||
204 | public function generate_product_review_data( $comment ) { |
||
221 | |||
222 | /** |
||
223 | * Generates the breadcrumbs structured data... |
||
224 | * Hooked into the `woocommerce_breadcrumb` action hook... |
||
225 | * Applies the `woocommerce_structured_data_breadcrumb` filter hook for clean structured data customization... |
||
226 | * |
||
227 | * @param array $args From `woocommerce_breadcrumb` action hook |
||
228 | */ |
||
229 | public function generate_breadcrumb_data( $args ) { |
||
261 | |||
262 | /** |
||
263 | * Generates the shop related structured data... |
||
264 | * Hooked into the `woocommerce_before_main_content` action hook... |
||
265 | * Applies the `woocommerce_structured_data_shop` filter hook for clean structured data customization... |
||
266 | */ |
||
267 | public function generate_shop_data() { |
||
283 | } |
||
284 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.