d'] ?? '', 'mc_price_country_code' => $price_competitiveness['country_code'] ?? '', 'mc_product_currency_code' => $price_competitiveness['benchmark_price_currency_code'] ?? '', 'mc_product_price_micros' => $price_competitiveness['price_micros'] ?? '', 'mc_price_benchmark_price_micros' => $price_competitiveness['benchmark_price_micros'] ?? '', 'mc_price_benchmark_price_currency_code' => $price_competitiveness['benchmark_price_currency_code'] ?? '', 'mc_insights_suggested_price_micros' => $price_insights['suggested_price_micros'] ?? '', 'mc_insights_suggested_price_currency_code' => $price_insights['suggested_price_currency_code'] ?? '', 'mc_insights_predicted_impressions_change_fraction' => $price_insights['predicted_impressions_change_fraction'] ?? 0, 'mc_insights_predicted_clicks_change_fraction' => $price_insights['predicted_clicks_change_fraction'] ?? 0, 'mc_insights_predicted_conversions_change_fraction' => $price_insights['predicted_conversions_change_fraction'] ?? 0, 'mc_insights_effectiveness' => isset( $price_insights['effectiveness'] ) ? $this->get_effectiveness( $price_insights['effectiveness'] ) : 0, 'mc_metrics_clicks' => $performance['clicks'] ?? 0, 'mc_metrics_impressions' => $performance['impressions'] ?? 0, 'mc_metrics_ctr' => $performance['ctr'] ?? 0, 'mc_metrics_conversions' => $performance['conversions'] ?? 0, 'price_compared_with_benchmark' => $this->price_compared_with_benchmark( (int) $price_competitiveness['price_micros'], (int) $price_competitiveness['benchmark_price_micros'] ), ]; }, $mapped_data ); return $response_data; } /** * Retrieves the product thumbnail URL. * * @param int $product_id WooCommerce product ID. * @return string Product thumbnail URL or an empty string if not found. */ protected function get_product_thumbnail( int $product_id ): ?string { $thumbnail_id = get_post_thumbnail_id( $product_id ); if ( ! $thumbnail_id ) { return ''; } $thumbnail_url = wp_get_attachment_url( $thumbnail_id ); return $thumbnail_url ?? ''; } /** * Returns the key for the given effectiveness value. * * @param string $value Effectiveness value. * @return int The corresponding key if value is found, otherwise 0. */ public function get_effectiveness( $value ) { $effectiveness_map = [ 'EFFECTIVENESS_UNSPECIFIED' => 0, 'LOW' => 1, 'MEDIUM' => 2, 'HIGH' => 3, ]; return $effectiveness_map[ $value ] ?? 0; } /** * Update price benchmarks by querying the Google Content API and saving the data locally. */ public function update_price_benchmarks(): void { try { $benchmarks = $this->get_price_benchmarks_response( [] ); if ( empty( $benchmarks ) ) { return; } /** @var MerchantPriceBenchmarksQuery $query */ $query = $this->container->get( MerchantPriceBenchmarksQuery::class ); // Clear existing data before updating. $query->reload_data(); // Insert new benchmark data. foreach ( $benchmarks as $benchmark_item ) { $query->insert( $benchmark_item ); } } catch ( \Exception $e ) { do_action( 'woocommerce_gla_debug_message', $e->getMessage(), __METHOD__ ); } } /** * Compares a given price with a benchmark price. * * This function takes two prices in micros (1,000,000 micros = 1 unit of currency) * and performs a comparison to determine their relationship. * * @param int $price_micros The price to compare, in micros. * @param int $benchmark_price_micros The benchmark price to compare against, in micros. * @return bool Returns specific price compare group if the price meets the comparison criteria with the benchmark. */ private function price_compared_with_benchmark( $price_micros, $benchmark_price_micros ) { if ( empty( $price_micros ) || empty( $benchmark_price_micros ) ) { return 0; } elseif ( abs( $price_micros - $benchmark_price_micros ) <= ( $benchmark_price_micros * 0.01 ) ) { return 2; } elseif ( $price_micros < $benchmark_price_micros ) { return 1; } elseif ( $price_micros > $benchmark_price_micros ) { return 3; } } /** * Get a summary of price benchmarks. * * @return array */ public function get_summary(): array { /** @var MerchantPriceBenchmarksQuery $query */ $query = $this->container->get( MerchantPriceBenchmarksQuery::class ); // Get counts for all price comparison groups in one query. $benchmark_counts_result = $query->get_price_benchmark_counts(); // Convert raw DB results to an associative array with all groups. $benchmark_counts = $this->get_price_benchmark_counts_data( $benchmark_counts_result ); return [ 'total_products' => $benchmark_counts['total'] ?? 0, // Total products 'price_unknown' => $benchmark_counts[0] ?? 0, // Unknown/missing 'price_lower' => $benchmark_counts[1] ?? 0, // Lower price 'price_similar' => $benchmark_counts[2] ?? 0, // Similar price 'price_higher' => $benchmark_counts[3] ?? 0, // Higher price ]; } /** * Converts raw benchmark counts from the database to an associative array. * * @param array $rows Raw benchmark counts result from the database. * @return array Associative array with counts for each price comparison group and total. */ public function get_price_benchmark_counts_data( array $rows ): array { // Convert the results to a more usable format $counts = []; $total = 0; foreach ( $rows as $row ) { $price_compared_value = (int) $row['price_compared_with_benchmark']; $counts[ $price_compared_value ] = (int) $row['count']; $total += $counts[ $price_compared_value ]; } // Make sure all possible values are represented (0, 1, 2, 3) $all_values = [ 0, 1, 2, 3 ]; foreach ( $all_values as $value ) { if ( ! isset( $counts[ $value ] ) ) { $counts[ $value ] = 0; } } $counts['total'] = $total; return $counts; } /** * Retrieves formatted price benchmarks data from the local database. * * @param array $args { * Optional. Arguments to filter and paginate results. * * @type array|null $include List of product IDs to include. Default null. * @type int $page Offset for the results. Default 1. * @type int $per_page Maximum number of items returned. Default 10. * @type string $search Search string to filter results. Default null. * @type string $order Sort order: 'asc' or 'desc'. Default 'desc'. * @type string $orderby Attribute to sort by. Default 'mc_insights_effectiveness'. * } * @return array { * @type array $results List of formatted price benchmarks. * @type int $total Total number of price benchmarks available. * } */ public function get_price_benchmarks_data( array $args = [] ): array { $defaults = [ 'include' => null, 'page' => 1, 'per_page' => 10, 'search' => null, 'order' => 'desc', 'orderby' => self::DEFAULT_ORDERBY, ]; $args = wp_parse_args( array_intersect_key( $args, $defaults ), $defaults ); /** @var MerchantPriceBenchmarksQuery $query */ $query = $this->container->get( MerchantPriceBenchmarksQuery::class ); // Apply filters. if ( ! empty( $args['include'] ) && is_array( $args['include'] ) ) { $query->where( 'product_id', $args['include'], 'IN' ); } if ( ! empty( $args['search'] ) ) { $search = trim( $args['search'] ); $search_query = new \WP_Query( [ 'post_type' => [ 'product' ], 'post_status' => 'publish', 's' => $search, 'fields' => 'ids', 'posts_per_page' => -1, ] ); $product_ids = $search_query->posts; // If no products found, return empty results. if ( empty( $product_ids ) ) { return [ 'results' => [], 'total' => 0, ]; } $query->where( 'product_id', $product_ids, 'IN' ); } // Set order and orderby. $order = strtoupper( $args['order'] ); if ( ! in_array( $order, [ 'ASC', 'DESC' ], true ) ) { $order = 'DESC'; } $orderby = $this->map_orderby_to_db_value( $args['orderby'] ); $query->set_order( $orderby, $order ); // Set offset and limit. $query->set_offset( (int) ( $args['page'] - 1 ) * $args['per_page'] ); $query->set_limit( (int) $args['per_page'] ); // Get total count before limiting. $total = $query->get_count(); // Get results. $rows = $query->get_results(); // Format results. $results = []; foreach ( $rows as $row ) { $wc_product_id = (int) $row['product_id']; $product = wc_get_product( $wc_product_id ); $thumbnail = $this->get_product_thumbnail( $wc_product_id ); $results[] = [ 'product' => [ 'id' => $wc_product_id, 'thumbnail' => $thumbnail, 'title' => $product instanceof \WC_Product ? $product->get_name() : '', ], 'effectiveness' => (int) $row['mc_insights_effectiveness'] ?? 0, 'country_code' => $row['mc_price_country_code'] ?? '', 'currency_code' => $row['mc_product_currency_code'] ?? '', 'product_price' => $this->micros_to_float( (int) $row['mc_product_price_micros'] ), 'benchmark_price' => $this->micros_to_float( (int) $row['mc_price_benchmark_price_micros'] ), 'benchmark_price_currency_code' => $row['mc_price_benchmark_price_currency_code'] ?? '', 'price_gap' => $this->micros_to_float( (int) $row['mc_price_benchmark_price_micros'] - (int) $row['mc_product_price_micros'] ), 'suggested_price' => $this->micros_to_float( (int) $row['mc_insights_suggested_price_micros'] ), 'suggested_price_currency_code' => $row['mc_insights_suggested_price_currency_code'] ?? '', 'predicted_impressions_change' => $row['mc_insights_predicted_impressions_change_fraction'] ?? '', 'predicted_clicks_change' => $row['mc_insights_predicted_clicks_change_fraction'] ?? '', 'predicted_conversions_change' => $row['mc_insights_predicted_conversions_change_fraction'] ?? '', 'clicks' => (int) $row['mc_metrics_clicks'] ?? 0, 'impressions' => (int) $row['mc_metrics_impressions'] ?? 0, 'ctr' => $row['mc_metrics_ctr'] ?? 0, 'conversions' => (int) $row['mc_metrics_conversions'] ?? 0, 'price_compared_with_benchmark' => (int) $row['price_compared_with_benchmark'] ?? 0, ]; } return [ 'results' => $results, 'total' => $total, ]; } /** * Maps the orderby parameter to the corresponding database column name. * * @param string $order_by The orderby parameter from the request. * @return string The corresponding database column name. */ private function map_orderby_to_db_value( string $order_by ): string { // If the $order_by value is not in the COLUMN_MAP, use the default. if ( ! in_array( $order_by, array_keys( self::COLUMN_MAP ), true ) ) { $order_by = self::DEFAULT_ORDERBY; } return self::COLUMN_MAP[ $order_by ]; } /** * Converts a value in micros to a float representation. * * @param int $micros The value in micros (1,000,000 micros = 1 unit of currency). * @return float The converted float value. */ private function micros_to_float( int $micros ): float { // Convert micros to a float value. return round( $micros / 1000000, 2 ); } }
Warning: class_implements(): Class Automattic\WooCommerce\GoogleListingsAndAds\MerchantCenter\PriceBenchmarks does not exist and could not be loaded in /htdocs/wp-content/plugins/google-listings-and-ads/src/Internal/DependencyManagement/AbstractServiceProvider.php on line 73

Warning: foreach() argument must be of type array|object, false given in /htdocs/wp-content/plugins/google-listings-and-ads/src/Internal/DependencyManagement/AbstractServiceProvider.php on line 73
Events for December 17, 2025 – The CandleLIT Experience Skip to the content
  • Workshops
  • Offers
    • CandleLIT Bar Cart
    • Group Workshop
    • 1:1 Candle-making Session
    • Date Night Jackson, MS
    • Date Night Dallas
    • Join The Candle Bar
  • shop
  • About Us
  • Contact
logo mainlogo darklogo light
Events
0 Cart

No products in the cart.

logo main
  • Workshops
  • Offers
    • CandleLIT Bar Cart
    • Group Workshop
    • 1:1 Candle-making Session
    • Date Night Jackson, MS
    • Date Night Dallas
    • Join The Candle Bar
  • shop
  • About Us
  • Contact
0 Cart

No products in the cart.

0 events found.

candle

  1. Events
  2. candle

Events for December 17, 2025

Notice
No events scheduled for December 17, 2025. Jump to the next upcoming events.
Notice
No events scheduled for December 17, 2025. Jump to the next upcoming events.

Events Search and Views Navigation

Event Views Navigation

  • List
  • Month
  • Day
Today
  • Previous Day
  • Next Day
  • Google Calendar
  • iCalendar
  • Outlook 365
  • Outlook Live
  • Export .ics file
  • Export Outlook .ics file
Stay Updated

Subscribe to our newsletter to receive our events info, launches, and tips.

Subscription Form
Legals
  • Terms and Conditions
  • Liability Disclaimer
Follow
Instagram
Facebook
Pinterest
Tiktok
top