versions = array( 'v1' => 'Opalestate_API', ); add_action( 'init', array( $this, 'add_endpoint' ) ); add_action( 'wp', array( $this, 'process_query' ), - 1 ); add_filter( 'query_vars', array( $this, 'query_vars' ) ); add_action( 'show_user_profile', array( $this, 'user_key_field' ) ); add_action( 'edit_user_profile', array( $this, 'user_key_field' ) ); add_action( 'personal_options_update', array( $this, 'update_key' ) ); add_action( 'edit_user_profile_update', array( $this, 'update_key' ) ); add_action( 'opalestate_process_api_key', array( $this, 'process_api_key' ) ); // Setup a backwards compatibility check for user API Keys add_filter( 'get_user_metadata', array( $this, 'api_key_backwards_compat' ), 10, 4 ); // Determine if JSON_PRETTY_PRINT is available $this->pretty_print = defined( 'JSON_PRETTY_PRINT' ) ? JSON_PRETTY_PRINT : null; // Allow API request logging to be turned off $this->log_requests = apply_filters( 'opalestate_api_log_requests', $this->log_requests ); } /** * Registers a new rewrite endpoint for accessing the API * * @access public * * @param array $rewrite_rules WordPress Rewrite Rules * * @since 1.1 */ public function add_endpoint( $rewrite_rules ) { add_rewrite_endpoint( 'opalestate-api', EP_ALL ); } /** * Registers query vars for API access * * @access public * @since 1.1 * * @param array $vars Query vars * * @return string[] $vars New query vars */ public function query_vars( $vars ) { $vars[] = 'token'; $vars[] = 'key'; $vars[] = 'query'; $vars[] = 'type'; $vars[] = 'property'; $vars[] = 'number'; $vars[] = 'date'; $vars[] = 'startdate'; $vars[] = 'enddate'; $vars[] = 'donor'; $vars[] = 'propertyat'; $vars[] = 'id'; $vars[] = 'purchasekey'; $vars[] = 'email'; return $vars; } /** * Retrieve the API versions * * @access public * @since 1.1 * @return array */ public function get_versions() { return $this->versions; } /** * Retrieve the API version that was queried * * @access public * @since 1.1 * @return string */ public function get_queried_version() { return $this->queried_version; } /** * Retrieves the default version of the API to use * * @access public * @since 1.1 * @return string */ public function get_default_version() { $version = get_option( 'opalestate_default_api_version' ); if ( defined( 'OPALESTATE_API_VERSION' ) ) { $version = OPALESTATE_API_VERSION; } elseif ( ! $version ) { $version = 'v1'; } return $version; } /** * Sets the version of the API that was queried. * * Falls back to the default version if no version is specified * * @access private * @since 1.1 */ private function set_queried_version() { global $wp_query; $version = $wp_query->query_vars['opalestate-api']; if ( strpos( $version, '/' ) ) { $version = explode( '/', $version ); $version = strtolower( $version[0] ); $wp_query->query_vars['opalestate-api'] = str_replace( $version . '/', '', $wp_query->query_vars['opalestate-api'] ); if ( array_key_exists( $version, $this->versions ) ) { $this->queried_version = $version; } else { $this->is_valid_request = false; $this->invalid_version(); } } else { $this->queried_version = $this->get_default_version(); } } /** * Validate the API request * * Checks for the user's public key and token against the secret key * * @access private * @global object $wp_query WordPress Query * @uses Opalestate_API::get_user() * @uses Opalestate_API::invalid_key() * @uses Opalestate_API::invalid_auth() * @since 1.1 * @return void */ private function validate_request() { global $wp_query; $this->override = false; // Make sure we have both user and api key if ( ! empty( $wp_query->query_vars['opalestate-api'] ) && ( $wp_query->query_vars['opalestate-api'] != 'properties' || ! empty( $wp_query->query_vars['token'] ) ) ) { if ( empty( $wp_query->query_vars['token'] ) || empty( $wp_query->query_vars['key'] ) ) { $this->missing_auth(); } // Retrieve the user by public API key and ensure they exist if ( ! ( $user = $this->get_user( $wp_query->query_vars['key'] ) ) ) { $this->invalid_key(); } else { $token = urldecode( $wp_query->query_vars['token'] ); $secret = $this->get_user_secret_key( $user ); $public = urldecode( $wp_query->query_vars['key'] ); if ( hash_equals( md5( $secret . $public ), $token ) ) { $this->is_valid_request = true; } else { $this->invalid_auth(); } } } elseif ( ! empty( $wp_query->query_vars['opalestate-api'] ) && $wp_query->query_vars['opalestate-api'] == 'properties' ) { $this->is_valid_request = true; $wp_query->set( 'key', 'public' ); } } /** * Retrieve the user ID based on the public key provided * * @access public * @since 1.1 * @global WPDB $wpdb Used to query the database using the WordPress * Database API * * @param string $key Public Key * * @return bool if user ID is found, false otherwise */ public function get_user( $key = '' ) { global $wpdb, $wp_query; if ( empty( $key ) ) { $key = urldecode( $wp_query->query_vars['key'] ); } if ( empty( $key ) ) { return false; } $user = get_transient( md5( 'opalestate_api_user_' . $key ) ); if ( false === $user ) { $user = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s LIMIT 1", $key ) ); set_transient( md5( 'opalestate_api_user_' . $key ), $user, DAY_IN_SECONDS ); } if ( $user != null ) { $this->user_id = $user; return $user; } return false; } public function get_user_public_key( $user_id = 0 ) { global $wpdb; if ( empty( $user_id ) ) { return ''; } $cache_key = md5( 'opalestate_api_user_public_key' . $user_id ); $user_public_key = get_transient( $cache_key ); if ( empty( $user_public_key ) ) { $user_public_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'opalestate_user_public_key' AND user_id = %d", $user_id ) ); set_transient( $cache_key, $user_public_key, HOUR_IN_SECONDS ); } return $user_public_key; } public function get_user_secret_key( $user_id = 0 ) { global $wpdb; if ( empty( $user_id ) ) { return ''; } $cache_key = md5( 'opalestate_api_user_secret_key' . $user_id ); $user_secret_key = get_transient( $cache_key ); if ( empty( $user_secret_key ) ) { $user_secret_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'opalestate_user_secret_key' AND user_id = %d", $user_id ) ); set_transient( $cache_key, $user_secret_key, HOUR_IN_SECONDS ); } return $user_secret_key; } /** * Displays a missing authentication error if all the parameters aren't * provided * * @access private * @uses Opalestate_API::output() * @since 1.1 */ private function missing_auth() { $error = array(); $error['error'] = esc_html__( 'You must specify both a token and API key!', 'opalestate-pro' ); $this->data = $error; $this->output( 401 ); } /** * Displays an authentication failed error if the user failed to provide valid * credentials * * @access private * @since 1.1 * @uses Opalestate_API::output() * @return void */ private function invalid_auth() { $error = array(); $error['error'] = esc_html__( 'Your request could not be authenticated!', 'opalestate-pro' ); $this->data = $error; $this->output( 403 ); } /** * Displays an invalid API key error if the API key provided couldn't be * validated * * @access private * @since 1.1 * @uses Opalestate_API::output() * @return void */ private function invalid_key() { $error = array(); $error['error'] = esc_html__( 'Invalid API key!', 'opalestate-pro' ); $this->data = $error; $this->output( 403 ); } /** * Displays an invalid version error if the version number passed isn't valid * * @access private * @since 1.1 * @uses Opalestate_API::output() * @return void */ private function invalid_version() { $error = array(); $error['error'] = esc_html__( 'Invalid API version!', 'opalestate-pro' ); $this->data = $error; $this->output( 404 ); } /** * Listens for the API and then processes the API requests * * @access public * @global $wp_query * @since 1.1 * @return void */ public function process_query() { global $wp_query; // Start logging how long the request takes for logging $before = microtime( true ); // Check for opalestate-api var. Get out if not present if ( empty( $wp_query->query_vars['opalestate-api'] ) ) { return; } // Determine which version was queried $this->set_queried_version(); // Determine the kind of query $this->set_query_mode(); // Check for a valid user and set errors if necessary $this->validate_request(); // Only proceed if no errors have been noted if ( ! $this->is_valid_request ) { return; } if ( ! defined( 'OPALESTATE_DOING_API' ) ) { define( 'OPALESTATE_DOING_API', true ); } $data = array(); $this->routes = new $this->versions[$this->get_queried_version()]; $this->routes->validate_request(); switch ( $this->endpoint ) : case 'properties' : $property = isset( $wp_query->query_vars['property'] ) ? $wp_query->query_vars['property'] : null; $data = $this->routes->get_properties( $property ); break; case 'featured' : $property = isset( $wp_query->query_vars['property'] ) ? $wp_query->query_vars['property'] : null; $data = $this->routes->get_featured_properties( $property ); break; case 'agents' : $agent = isset( $wp_query->query_vars['agent'] ) ? $wp_query->query_vars['agent'] : null; $data = $this->routes->get_agents( $agent ); break; endswitch; // Allow extensions to setup their own return data $this->data = apply_filters( 'opalestate_api_output_data', $data, $this->endpoint, $this ); $after = microtime( true ); $request_time = ( $after - $before ); $this->data['request_speed'] = $request_time; // Log this API request, if enabled. We log it here because we have access to errors. $this->log_request( $this->data ); // Send out data to the output function $this->output(); } /** * Returns the API endpoint requested * * @access public * @since 1.1 * @return string $query Query mode */ public function get_query_mode() { return $this->endpoint; } /** * Determines the kind of query requested and also ensure it is a valid query * * @access public * @since 1.1 * @global $wp_query */ public function set_query_mode() { global $wp_query; // Whitelist our query options $accepted = apply_filters( 'opalestate_api_valid_query_modes', array( 'agents', 'properties', 'featured' ) ); $query = isset( $wp_query->query_vars['opalestate-api'] ) ? $wp_query->query_vars['opalestate-api'] : null; $query = str_replace( $this->queried_version . '/', '', $query ); $error = array(); // Make sure our query is valid if ( ! in_array( $query, $accepted ) ) { $error['error'] = esc_html__( 'Invalid query!', 'opalestate-pro' ); $this->data = $error; // 400 is Bad Request $this->output( 400 ); } $this->endpoint = $query; } /** * Get page number * * @access public * @since 1.1 * @global $wp_query * @return int $wp_query->query_vars['page'] if page number returned (default: 1) */ public function get_paged() { global $wp_query; return isset( $wp_query->query_vars['page'] ) ? $wp_query->query_vars['page'] : 1; } /** * Number of results to display per page * * @access public * @since 1.1 * @global $wp_query * @return int $per_page Results to display per page (default: 10) */ public function per_page() { global $wp_query; $per_page = isset( $wp_query->query_vars['number'] ) ? $wp_query->query_vars['number'] : 10; return apply_filters( 'opalestate_api_results_per_page', $per_page ); } /** * * */ public function get_agents( $agent = null ) { $agents = array(); $error = array(); if ( $agent == null ) { $agents['agents'] = array(); $property_list = get_posts( array( 'post_type' => 'opalestate_agent', 'posts_per_page' => $this->per_page(), 'suppress_filters' => true, 'paged' => $this->get_paged() ) ); if ( $property_list ) { $i = 0; foreach ( $property_list as $agent_info ) { $agents['agents'][ $i ] = $this->get_agent_data( $agent_info ); $i ++; } } } else { if ( get_post_type( $agent ) == 'opalestate_property' ) { $agent_info = get_post( $agent ); $agents['agents'][0] = $this->get_agent_data( $agent_info ); } else { $error['error'] = sprintf( /* translators: %s: property */ esc_html__( 'Form %s not found!', 'opalestate-pro' ), $agent ); return $error; } } return $agents; } /** * * */ public function get_agent_data( $agent_info ){ $ouput = array(); $ouput['info']['id'] = $agent_info->ID; $ouput['info']['slug'] = $agent_info->post_name; $ouput['info']['title'] = $agent_info->post_title; $ouput['info']['create_date'] = $agent_info->post_date; $ouput['info']['modified_date'] = $agent_info->post_modified; $ouput['info']['status'] = $agent_info->post_status; $ouput['info']['link'] = html_entity_decode( $agent_info->guid ); $ouput['info']['content'] = $agent_info->post_content; $ouput['info']['thumbnail'] = wp_get_attachment_url( get_post_thumbnail_id( $agent_info->ID ) ); $agent = new OpalEstate_Agent( $agent_info->ID ); $ouput['info']['featured'] = (int)$agent->is_featured(); $ouput['info']['email'] = get_post_meta( $agent_info->ID, OPALESTATE_AGENT_PREFIX . 'email', true ); $ouput['info']['address'] = get_post_meta( $agent_info->ID, OPALESTATE_AGENT_PREFIX . 'address', true ); $terms = wp_get_post_terms( $agent_info->ID, 'opalestate_agent_location' ); $ouput['info']['location'] = $terms && !is_wp_error($terms) ? $terms : array(); $ouput['socials'] = $agent->get_socials(); $ouput['levels'] = wp_get_post_terms( $agent_info->ID, 'opalestate_agent_level' ); return apply_filters( 'opalestate_api_agents', $ouput ); } /** * Process Get Products API Request * * @access public * @since 1.1 * * @param int $property Opalestate Form ID * * @return array $customers Multidimensional array of the properties */ public function get_featured_properties( $property = null ) { $properties = array(); $error = array(); if ( $property == null ) { $properties['properties'] = array(); $property_list = get_posts( array( 'post_type' => 'opalestate_property', 'posts_per_page' => $this->per_page(), 'suppress_filters' => true, 'paged' => $this->get_paged(), 'meta_key' => OPALESTATE_PROPERTY_PREFIX . 'featured', 'meta_value' => 1, 'meta_compare' => '=' ) ); if ( $property_list ) { $i = 0; foreach ( $property_list as $property_info ) { $properties['properties'][ $i ] = $this->get_property_data( $property_info ); $i ++; } } } else { if ( get_post_type( $property ) == 'opalestate_property' ) { $property_info = get_post( $property ); $properties['properties'][0] = $this->get_property_data( $property_info ); } else { $error['error'] = sprintf( /* translators: %s: property */ esc_html__( 'Form %s not found!', 'opalestate-pro' ), $property ); return $error; } } return $properties; } /** * Process Get Products API Request * * @access public * @since 1.1 * * @param int $property Opalestate Form ID * * @return array $customers Multidimensional array of the properties */ public function get_properties( $property = null ) { $properties = array(); $error = array(); if ( $property == null ) { $properties['properties'] = array(); $property_list = get_posts( array( 'post_type' => 'opalestate_property', 'posts_per_page' => $this->per_page(), 'suppress_filters' => true, 'paged' => $this->get_paged() ) ); if ( $property_list ) { $i = 0; foreach ( $property_list as $property_info ) { $properties['properties'][ $i ] = $this->get_property_data( $property_info ); $i ++; } } } else { if ( get_post_type( $property ) == 'opalestate_property' ) { $property_info = get_post( $property ); $properties['properties'][0] = $this->get_property_data( $property_info ); } else { $error['error'] = sprintf( /* translators: %s: property */ esc_html__( 'Form %s not found!', 'opalestate-pro' ), $property ); return $error; } } return $properties; } /** * Opalestaten a opalestate_property post object, generate the data for the API output * * @since 1.1 * * @param object $property_info The Download Post Object * * @return array Array of post data to return back in the API */ private function get_property_data( $property_info ) { $property = array(); $property['info']['id'] = $property_info->ID; $property['info']['slug'] = $property_info->post_name; $property['info']['title'] = $property_info->post_title; $property['info']['create_date'] = $property_info->post_date; $property['info']['modified_date'] = $property_info->post_modified; $property['info']['status'] = $property_info->post_status; $property['info']['link'] = html_entity_decode( $property_info->guid ); $property['info']['content'] = $property_info->post_content; $property['info']['thumbnail'] = wp_get_attachment_url( get_post_thumbnail_id( $property_info->ID ) ); $data = opalesetate_property( $property_info->ID ); $gallery = $data->get_gallery(); $property['info']['gallery'] = isset($gallery[0]) && !empty($gallery[0]) ? $gallery[0]: array(); $property['info']['price'] = opalestate_price_format( $data->get_price() ); $property['info']['map'] = $data->get_map(); $property['info']['address'] = $data->get_address(); $property['meta'] = $data->get_meta_shortinfo(); $property['status'] = $data->get_status(); $property['locations'] = $data->get_locations(); $property['amenities'] = $data->get_amenities(); $property['types'] = $data->get_types_tax(); if ( user_can( $this->user_id, 'view_opalestate_sensitive_data' ) || $this->override ) { //Sensitive data here do_action( 'opalestate_api_sensitive_data' ); } return apply_filters( 'opalestate_api_properties_property', $property ); } /** * Retrieve the output propertyat * * Determines whether results should be displayed in XML or JSON * * @since 1.1 * @access public * * @return mixed|void */ public function get_output_propertyat() { global $wp_query; $propertyat = isset( $wp_query->query_vars['propertyat'] ) ? $wp_query->query_vars['propertyat'] : 'json'; return apply_filters( 'opalestate_api_output_propertyat', $propertyat ); } /** * Log each API request, if enabled * * @access private * @since 1.1 * * @global Opalestate_Logging $opalestate_logs * @global WP_Query $wp_query * * @param array $data * * @return void */ private function log_request( $data = array() ) { if ( ! $this->log_requests ) { return; } /** * @var Opalestate_Logging $opalestate_logs */ global $opalestate_logs; /** * @var WP_Query $wp_query */ global $wp_query; $query = array( 'opalestate-api' => $wp_query->query_vars['opalestate-api'], 'key' => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null, 'token' => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null, 'query' => isset( $wp_query->query_vars['query'] ) ? $wp_query->query_vars['query'] : null, 'type' => isset( $wp_query->query_vars['type'] ) ? $wp_query->query_vars['type'] : null, 'property' => isset( $wp_query->query_vars['property'] ) ? $wp_query->query_vars['property'] : null, 'customer' => isset( $wp_query->query_vars['customer'] ) ? $wp_query->query_vars['customer'] : null, 'date' => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null, 'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null, 'enddate' => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null, 'id' => isset( $wp_query->query_vars['id'] ) ? $wp_query->query_vars['id'] : null, 'purchasekey' => isset( $wp_query->query_vars['purchasekey'] ) ? $wp_query->query_vars['purchasekey'] : null, 'email' => isset( $wp_query->query_vars['email'] ) ? $wp_query->query_vars['email'] : null, ); $log_data = array( 'log_type' => 'api_request', 'post_excerpt' => http_build_query( $query ), 'post_content' => ! empty( $data['error'] ) ? $data['error'] : '', ); $log_meta = array( 'request_ip' => opalestate_get_ip(), 'user' => $this->user_id, 'key' => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null, 'token' => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null, 'time' => $data['request_speed'], 'version' => $this->get_queried_version() ); } /** * Retrieve the output data * * @access public * @since 1.1 * @return array */ public function get_output() { return $this->data; } /** * Output Query in either JSON/XML. The query data is outputted as JSON * by default * * @since 1.1 * @global WP_Query $wp_query * * @param int $status_code */ public function output( $status_code = 200 ) { /** * @var WP_Query $wp_query */ global $wp_query; $propertyat = $this->get_output_propertyat(); status_header( $status_code ); do_action( 'opalestate_api_output_before', $this->data, $this, $propertyat ); switch ( $propertyat ) : case 'xml' : require_once OPALESTATE_PLUGIN_DIR . 'inc/libraries/array2xml.php'; $xml = Array2XML::createXML( 'opalestate-pro', $this->data ); echo $xml->saveXML(); break; case 'json' : header( 'Content-Type: application/json' ); if ( ! empty( $this->pretty_print ) ) { echo json_encode( $this->data, $this->pretty_print ); } else { echo json_encode( $this->data ); } break; default : // Allow other propertyats to be added via extensions do_action( 'opalestate_api_output_' . $propertyat, $this->data, $this ); break; endswitch; do_action( 'opalestate_api_output_after', $this->data, $this, $propertyat ); die(); } /** * Modify User Profile * * Modifies the output of profile.php to add key generation/revocation * * @access public * @since 1.1 * * @param object $user Current user info * * @return void */ function user_key_field( $user ) { if ( ( opalestate_get_option( 'api_allow_user_keys', false ) || current_user_can( 'manage_opalestate_settings' ) ) && current_user_can( 'edit_user', $user->ID ) ) { $user = get_userdata( $user->ID ); ?>
get_user_public_key( $user->ID ); $secret_key = $this->get_user_secret_key( $user->ID ); ?> opalestate_user_public_key ) ) { ?>  
 
 
403 ) ); } if ( empty( $args['user_id'] ) ) { wp_die( esc_html__( 'User ID Required.', 'opalestate-pro' ), esc_html__( 'Error', 'opalestate-pro' ), array( 'response' => 401 ) ); } if ( is_numeric( $args['user_id'] ) ) { $user_id = isset( $args['user_id'] ) ? absint( $args['user_id'] ) : get_current_user_id(); } else { $userdata = get_user_by( 'login', $args['user_id'] ); $user_id = $userdata->ID; } $process = isset( $args['opalestate_api_process'] ) ? strtolower( $args['opalestate_api_process'] ) : false; if ( $user_id == get_current_user_id() && ! opalestate_get_option( 'allow_user_api_keys' ) && ! current_user_can( 'manage_opalestate_settings' ) ) { wp_die( sprintf( /* translators: %s: process */ esc_html__( 'You do not have permission to %s API keys for this user.', 'opalestate-pro' ), $process ), esc_html__( 'Error', 'opalestate-pro' ), array( 'response' => 403 ) ); } elseif ( ! current_user_can( 'manage_opalestate_settings' ) ) { wp_die( sprintf( /* translators: %s: process */ esc_html__( 'You do not have permission to %s API keys for this user.', 'opalestate-pro' ), $process ), esc_html__( 'Error', 'opalestate-pro' ), array( 'response' => 403 ) ); } switch ( $process ) { case 'generate': if ( $this->generate_api_key( $user_id ) ) { delete_transient( 'opalestate_total_api_keys' ); wp_redirect( add_query_arg( 'opalestate-message', 'api-key-generated', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); exit(); } else { wp_redirect( add_query_arg( 'opalestate-message', 'api-key-failed', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); exit(); } break; case 'regenerate': $this->generate_api_key( $user_id, true ); delete_transient( 'opalestate_total_api_keys' ); wp_redirect( add_query_arg( 'opalestate-message', 'api-key-regenerated', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); exit(); break; case 'revoke': $this->revoke_api_key( $user_id ); delete_transient( 'opalestate_total_api_keys' ); wp_redirect( add_query_arg( 'opalestate-message', 'api-key-revoked', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); exit(); break; default; break; } } /** * Generate new API keys for a user * * @access public * @since 1.1 * * @param int $user_id User ID the key is being generated for * @param boolean $regenerate Regenerate the key for the user * * @return boolean True if (re)generated succesfully, false otherwise. */ public function generate_api_key( $user_id = 0, $regenerate = false ) { if ( empty( $user_id ) ) { return false; } $user = get_userdata( $user_id ); if ( ! $user ) { return false; } $public_key = $this->get_user_public_key( $user_id ); $secret_key = $this->get_user_secret_key( $user_id ); if ( empty( $public_key ) || $regenerate == true ) { $new_public_key = $this->generate_public_key( $user->user_email ); $new_secret_key = $this->generate_private_key( $user->ID ); } else { return false; } if ( $regenerate == true ) { $this->revoke_api_key( $user->ID ); } update_user_meta( $user_id, $new_public_key, 'opalestate_user_public_key' ); update_user_meta( $user_id, $new_secret_key, 'opalestate_user_secret_key' ); return true; } /** * Revoke a users API keys * * @access public * @since 1.1 * * @param int $user_id User ID of user to revoke key for * * @return string */ public function revoke_api_key( $user_id = 0 ) { if ( empty( $user_id ) ) { return false; } $user = get_userdata( $user_id ); if ( ! $user ) { return false; } $public_key = $this->get_user_public_key( $user_id ); $secret_key = $this->get_user_secret_key( $user_id ); if ( ! empty( $public_key ) ) { delete_transient( md5( 'opalestate_api_user_' . $public_key ) ); delete_transient( md5( 'opalestate_api_user_public_key' . $user_id ) ); delete_transient( md5( 'opalestate_api_user_secret_key' . $user_id ) ); delete_user_meta( $user_id, $public_key ); delete_user_meta( $user_id, $secret_key ); } else { return false; } return true; } public function get_version() { return self::VERSION; } /** * Generate and Save API key * * Generates the key requested by user_key_field and stores it in the database * * @access public * @since 1.1 * * @param int $user_id * * @return void */ public function update_key( $user_id ) { if ( current_user_can( 'edit_user', $user_id ) && isset( $_POST['opalestate_set_api_key'] ) ) { $user = get_userdata( $user_id ); $public_key = $this->get_user_public_key( $user_id ); $secret_key = $this->get_user_secret_key( $user_id ); if ( empty( $public_key ) ) { $new_public_key = $this->generate_public_key( $user->user_email ); $new_secret_key = $this->generate_private_key( $user->ID ); update_user_meta( $user_id, $new_public_key, 'opalestate_user_public_key' ); update_user_meta( $user_id, $new_secret_key, 'opalestate_user_secret_key' ); } else { $this->revoke_api_key( $user_id ); } } } /** * Generate the public key for a user * * @access private * @since 1.1 * * @param string $user_email * * @return string */ private function generate_public_key( $user_email = '' ) { $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; $public = hash( 'md5', $user_email . $auth_key . date( 'U' ) ); return $public; } /** * Generate the secret key for a user * * @access private * @since 1.1 * * @param int $user_id * * @return string */ private function generate_private_key( $user_id = 0 ) { $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; $secret = hash( 'md5', $user_id . $auth_key . date( 'U' ) ); return $secret; } /** * Retrieve the user's token * * @access private * @since 1.1 * * @param int $user_id * * @return string */ public function get_token( $user_id = 0 ) { return hash( 'md5', $this->get_user_secret_key( $user_id ) . $this->get_user_public_key( $user_id ) ); } /** * API Key Backwards Compatibility * * A Backwards Compatibility call for the change of meta_key/value for users API Keys * * @since 1.3.6 * * @param string $check Whether to check the cache or not * @param int $object_id The User ID being passed * @param string $meta_key The user meta key * @param bool $single If it should return a single value or array * * @return string The API key/secret for the user supplied */ public function api_key_backwards_compat( $check, $object_id, $meta_key, $single ) { if ( $meta_key !== 'opalestate_user_public_key' && $meta_key !== 'opalestate_user_secret_key' ) { return $check; } $return = $check; switch ( $meta_key ) { case 'opalestate_user_public_key': $return = Opalestate()->api->get_user_public_key( $object_id ); break; case 'opalestate_user_secret_key': $return = Opalestate()->api->get_user_secret_key( $object_id ); break; } if ( ! $single ) { $return = array( $return ); } return $return; } }