<?php if ( ! class_exists( 'WC_Connect_Service_Schemas_Store' ) ) { class WC_Connect_Service_Schemas_Store { /** * @var WC_Connect_API_Client */ protected $api_client; /** * @var WC_Connect_Logger */ protected $logger; public function __construct( WC_Connect_API_Client $api_client, WC_Connect_Logger $logger ) { $this->api_client = $api_client; $this->logger = $logger; } public function fetch_service_schemas_from_connect_server() { $response_body = $this->api_client->get_service_schemas(); if ( is_wp_error( $response_body ) ) { $error_data = $response_body->get_error_data(); if ( isset( $error_data['response_status_code'] ) ) { $this->update_last_fetch_result_code( $error_data['response_status_code'] ); } $this->logger->log( $response_body, __FUNCTION__ ); return false; } $this->update_last_fetch_result_code( '200' ); $this->logger->log( 'Successfully loaded service schemas from server response.', __FUNCTION__ ); $this->update_last_fetch_timestamp(); $this->maybe_update_heartbeat(); $old_schemas = $this->get_service_schemas(); if ( $old_schemas == $response_body ) { // schemas weren't changed, but were fetched without problems return true; } // If we made it this far, it is safe to store the object return $this->update_service_schemas( $response_body ); } public function get_service_schemas() { return WC_Connect_Options::get_option( 'services', null ); } protected function update_service_schemas( $service_schemas ) { return WC_Connect_Options::update_option( 'services', $service_schemas ); } public function get_last_fetch_timestamp() { return WC_Connect_Options::get_option( 'services_last_update', null ); } protected function update_last_fetch_timestamp() { WC_Connect_Options::update_option( 'services_last_update', time() ); } public function get_last_fetch_result_code() { return WC_Connect_Options::get_option( 'services_last_result_code' ); } /** * @param int $result_status_code */ protected function update_last_fetch_result_code( $result_status_code ) { WC_Connect_Options::update_option( 'services_last_result_code', $result_status_code ); } protected function maybe_update_heartbeat() { $last_heartbeat = WC_Connect_Options::get_option( 'last_heartbeat' ); $now = time(); if ( ! $last_heartbeat ) { $should_update = true; } else { $last_heartbeat = absint( $last_heartbeat ); if ( $last_heartbeat > $now ) { // last heartbeat in the future? wacky $should_update = true; } else { $elapsed = $now - $last_heartbeat; $should_update = $elapsed > DAY_IN_SECONDS; } } if ( $should_update ) { WC_Connect_Options::update_option( 'last_heartbeat', $now ); } } /** * Returns all service ids of a specific type (e.g. shipping) * * @param string $type The type of services to return * * @return array An array of that type's service ids, or an empty array if no such type is known */ public function get_all_service_ids_of_type( $type ) { if ( empty( $type ) ) { return array(); } $service_schemas = $this->get_service_schemas(); if ( ! is_object( $service_schemas ) || ! property_exists( $service_schemas, $type ) || ! is_array( $service_schemas->$type ) ) { return array(); } $service_schema_ids = array(); foreach ( $service_schemas->$type as $service_schema ) { $service_schema_ids[] = $service_schema->id; } return $service_schema_ids; } /** * Returns all shipping method ids * * @return array|bool An array of supported shipping method ids or false if schema does not support method_id */ public function get_all_shipping_method_ids() { $shipping_method_ids = array(); $service_schemas = $this->get_service_schemas(); if ( ! is_object( $service_schemas ) || ! property_exists( $service_schemas, 'shipping' ) || ! is_array( $service_schemas->shipping ) ) { return $shipping_method_ids; } foreach ( $service_schemas->shipping as $service_schema ) { if ( ! property_exists( $service_schema, 'method_id' ) ) { continue; } $shipping_method_ids[] = $service_schema->method_id; } return $shipping_method_ids; } /** * Returns a particular service's schema given its id * * @param string $service_id The service id for which to return the schema * * @return object|null The service schema or null if no such id was found */ public function get_service_schema_by_id( $service_id ) { $service_schemas = $this->get_service_schemas(); if ( ! is_object( $service_schemas ) ) { return null; } foreach ( $service_schemas as $service_type => $service_type_service_schemas ) { $matches = wp_filter_object_list( $service_type_service_schemas, array( 'id' => $service_id ) ); if ( $matches ) { return array_shift( $matches ); } } return null; } /** * Returns a particular service's schema given its method_id * * @param $method_id * * @return object|null The service schema or null if no such id was found */ public function get_service_schema_by_method_id( $method_id ) { $service_schemas = $this->get_service_schemas(); if ( ! is_object( $service_schemas ) ) { return null; } foreach ( $service_schemas as $service_type => $service_type_service_schemas ) { $matches = wp_filter_object_list( $service_type_service_schemas, array( 'method_id' => $method_id ) ); if ( $matches ) { return array_shift( $matches ); } } return null; } /** * Returns a service's schema given its shipping zone instance * * @param string $instance_id The shipping zone instance id for which to return the schema * * @return object|null The service schema or null if no such instance was found */ public function get_service_schema_by_instance_id( $instance_id ) { global $wpdb; $method_id = $wpdb->get_var( $wpdb->prepare( "SELECT method_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE instance_id = %d;", $instance_id ) ); return $this->get_service_schema_by_method_id( $method_id ); } /** * Returns a service's schema given an id or shipping zone instance. * * @param string $id_or_instance_id String ID or numeric instance ID. * @return object|null Service schema on success, null on failure */ public function get_service_schema_by_id_or_instance_id( $id_or_instance_id ) { if ( is_numeric( $id_or_instance_id ) ) { return $this->get_service_schema_by_instance_id( $id_or_instance_id ); } if ( ! empty( $id_or_instance_id ) ) { return $this->get_service_schema_by_method_id( $id_or_instance_id ); } return null; } /** * Returns packages schema * * @return object|null Packages schema on success, null on failure */ public function get_packages_schema() { $service_schemas = $this->get_service_schemas(); if ( ! is_object( $service_schemas ) || ! property_exists( $service_schemas, 'boxes' ) ) { return null; } return $service_schemas->boxes; } public function get_predefined_packages_schema() { $service_schemas = $this->get_service_schemas(); if ( ! is_object( $service_schemas ) ) { return null; } $predefined_packages = array(); foreach ( $service_schemas->shipping as $service_schema ) { if ( ! isset( $service_schema->packages ) ) { continue; } $predefined_packages[ $service_schema->id ] = $service_schema->packages; } return $predefined_packages; } } }