onomy to get the defining term id for. * @param array $term_ids_by_slug_cache A term ids by slug as generated by get_term_ids_by_slug_cache. * @return int|null The term id, or null if there's no defining id for that taxonomy in that variation. */ private function get_variation_definition_term_id( \WC_Product_Variation $variation, string $taxonomy, array $term_ids_by_slug_cache ) { $variation_attributes = $variation->get_attributes(); $term_slug = ArrayUtil::get_value_or_default( $variation_attributes, $taxonomy ); if ( $term_slug ) { return $term_ids_by_slug_cache[ $taxonomy ][ $term_slug ]; } else { return null; } } /** * Get the variations of a given variable product. * * @param \WC_Product_Variable $product The product to get the variations for. * @return array An array of WC_Product_Variation objects. */ private function get_variations_of( \WC_Product_Variable $product ) { $variation_ids = $product->get_children(); return array_map( function( $id ) { return WC()->call_function( 'wc_get_product', $id ); }, $variation_ids ); } /** * Check if a given product is a variable product. * * @param \WC_Product $product The product to check. * @return bool True if it's a variable product, false otherwise. */ private function is_variable_product( \WC_Product $product ) { return is_a( $product, \WC_Product_Variable::class ); } /** * Check if a given product is a variation. * * @param \WC_Product $product The product to check. * @return bool True if it's a variation, false otherwise. */ private function is_variation( \WC_Product $product ) { return is_a( $product, \WC_Product_Variation::class ); } /** * Return the list of taxonomies used for variations on a product together with * the associated term ids, with the following format: * * [ * 'taxonomy_name' => * [ * 'term_ids' => [id, id, ...], * 'used_for_variations' => true|false * ], ... * ] * * @param \WC_Product $product The product to get the attribute taxonomies for. * @return array Information about the attribute taxonomies of the product. */ private function get_attribute_taxonomies( \WC_Product $product ) { $product_attributes = $product->get_attributes(); $result = array(); foreach ( $product_attributes as $taxonomy_name => $attribute_data ) { if ( ! $attribute_data->get_id() ) { // Custom product attribute, not suitable for attribute-based filtering. continue; } $result[ $taxonomy_name ] = array( 'term_ids' => $attribute_data->get_options(), 'used_for_variations' => $attribute_data->get_variation(), ); } return $result; } /** * Insert one entry in the lookup table. * * @param int $product_id The product id. * @param int $product_or_parent_id The product id for non-variable products, the main/parent product id for variations. * @param string $taxonomy Taxonomy name. * @param int $term_id Term id. * @param bool $is_variation_attribute True if the taxonomy corresponds to an attribute used to define variations. * @param bool $has_stock True if the product is in stock. */ private function insert_lookup_table_data( int $product_id, int $product_or_parent_id, string $taxonomy, int $term_id, bool $is_variation_attribute, bool $has_stock ) { global $wpdb; // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $wpdb->prepare( 'INSERT INTO ' . $this->lookup_table_name . ' ( product_id, product_or_parent_id, taxonomy, term_id, is_variation_attribute, in_stock) VALUES ( %d, %d, %s, %d, %d, %d )', $product_id, $product_or_parent_id, $taxonomy, $term_id, $is_variation_attribute ? 1 : 0, $has_stock ? 1 : 0 ) ); // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared } /** * Tells if a lookup table regeneration is currently in progress. * * @return bool True if a lookup table regeneration is already in progress. */ public function regeneration_is_in_progress() { return 'yes' === get_option( 'woocommerce_attribute_lookup_regeneration_in_progress', null ); } /** * Set a permanent flag (via option) indicating that the lookup table regeneration is in process. */ public function set_regeneration_in_progress_flag() { update_option( 'woocommerce_attribute_lookup_regeneration_in_progress', 'yes' ); } /** * Remove the flag indicating that the lookup table regeneration is in process. */ public function unset_regeneration_in_progress_flag() { delete_option( 'woocommerce_attribute_lookup_regeneration_in_progress' ); } }