diff --git a/.DS_Store b/.DS_Store index 7f88e62b..8449ada3 100755 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/assets/3rd/.DS_Store b/assets/3rd/.DS_Store old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/.DS_Store b/assets/3rd/fontawesome/.DS_Store old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/css/.DS_Store b/assets/3rd/fontawesome/css/.DS_Store old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/css/all.min.css b/assets/3rd/fontawesome/css/all.min.css old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.eot b/assets/3rd/fontawesome/webfonts/fa-brands-400.eot old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.svg b/assets/3rd/fontawesome/webfonts/fa-brands-400.svg old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.ttf b/assets/3rd/fontawesome/webfonts/fa-brands-400.ttf old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.woff b/assets/3rd/fontawesome/webfonts/fa-brands-400.woff old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.woff2 b/assets/3rd/fontawesome/webfonts/fa-brands-400.woff2 old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.eot b/assets/3rd/fontawesome/webfonts/fa-regular-400.eot old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.svg b/assets/3rd/fontawesome/webfonts/fa-regular-400.svg old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.ttf b/assets/3rd/fontawesome/webfonts/fa-regular-400.ttf old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.woff b/assets/3rd/fontawesome/webfonts/fa-regular-400.woff old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.woff2 b/assets/3rd/fontawesome/webfonts/fa-regular-400.woff2 old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.eot b/assets/3rd/fontawesome/webfonts/fa-solid-900.eot old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.svg b/assets/3rd/fontawesome/webfonts/fa-solid-900.svg old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.ttf b/assets/3rd/fontawesome/webfonts/fa-solid-900.ttf old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.woff b/assets/3rd/fontawesome/webfonts/fa-solid-900.woff old mode 100644 new mode 100755 diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.woff2 b/assets/3rd/fontawesome/webfonts/fa-solid-900.woff2 old mode 100644 new mode 100755 diff --git a/assets/images/.DS_Store b/assets/images/.DS_Store old mode 100644 new mode 100755 diff --git a/assets/scss/admin.scss b/assets/scss/admin.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/_grid.scss b/assets/scss/bootstrap/_grid.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/_mixins.scss b/assets/scss/bootstrap/_mixins.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/_unlities.scss b/assets/scss/bootstrap/_unlities.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/_variables.scss b/assets/scss/bootstrap/_variables.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_clearfix.scss b/assets/scss/bootstrap/mixins/_clearfix.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_grid-framework.scss b/assets/scss/bootstrap/mixins/_grid-framework.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_grid.scss b/assets/scss/bootstrap/mixins/_grid.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_opacity.scss b/assets/scss/bootstrap/mixins/_opacity.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_resize.scss b/assets/scss/bootstrap/mixins/_resize.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_size.scss b/assets/scss/bootstrap/mixins/_size.scss old mode 100755 new mode 100644 diff --git a/assets/scss/bootstrap/mixins/_vendor-prefixes.scss b/assets/scss/bootstrap/mixins/_vendor-prefixes.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2-front.scss b/assets/scss/cmb2-front.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/cmb2-display.scss b/assets/scss/cmb2/cmb2-display.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/cmb2-front.scss b/assets/scss/cmb2/cmb2-front.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/cmb2.scss b/assets/scss/cmb2/cmb2.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/index.html b/assets/scss/cmb2/index.html old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/index.php b/assets/scss/cmb2/index.php old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_collapsible_ui.scss b/assets/scss/cmb2/partials/_collapsible_ui.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_context_metaboxes.scss b/assets/scss/cmb2/partials/_context_metaboxes.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_display.scss b/assets/scss/cmb2/partials/_display.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_front.scss b/assets/scss/cmb2/partials/_front.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_jquery_ui.scss b/assets/scss/cmb2/partials/_jquery_ui.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_main_wrap.scss b/assets/scss/cmb2/partials/_main_wrap.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_misc.scss b/assets/scss/cmb2/partials/_misc.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_mixins.scss b/assets/scss/cmb2/partials/_mixins.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_new_term.scss b/assets/scss/cmb2/partials/_new_term.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_options-page.scss b/assets/scss/cmb2/partials/_options-page.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_post_metaboxes.scss b/assets/scss/cmb2/partials/_post_metaboxes.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_sidebar_placements.scss b/assets/scss/cmb2/partials/_sidebar_placements.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/_variables.scss b/assets/scss/cmb2/partials/_variables.scss old mode 100755 new mode 100644 diff --git a/assets/scss/cmb2/partials/index.php b/assets/scss/cmb2/partials/index.php old mode 100755 new mode 100644 diff --git a/assets/scss/components/_grid.scss b/assets/scss/components/_grid.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/_mixins.scss b/assets/scss/components/_mixins.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/_variables.scss b/assets/scss/components/_variables.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/mixins/_functions.scss b/assets/scss/components/mixins/_functions.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/mixins/_rtl.scss b/assets/scss/components/mixins/_rtl.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/mixins/_template-mixins.scss b/assets/scss/components/mixins/_template-mixins.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/vars/_elements.scss b/assets/scss/components/vars/_elements.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/vars/_form.scss b/assets/scss/components/vars/_form.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/vars/_layout.scss b/assets/scss/components/vars/_layout.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/vars/_nav.scss b/assets/scss/components/vars/_nav.scss old mode 100755 new mode 100644 diff --git a/assets/scss/components/vars/_widget.scss b/assets/scss/components/vars/_widget.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate.scss b/assets/scss/opalestate.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_3rd.scss b/assets/scss/opalestate/_3rd.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_agency-loop.scss b/assets/scss/opalestate/_agency-loop.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_archive.scss b/assets/scss/opalestate/_archive.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_dashboard.scss b/assets/scss/opalestate/_dashboard.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_elements.scss b/assets/scss/opalestate/_elements.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_form.scss b/assets/scss/opalestate/_form.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_layout.scss b/assets/scss/opalestate/_layout.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_modules.scss b/assets/scss/opalestate/_modules.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_page.scss b/assets/scss/opalestate/_page.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_properties-loop.scss b/assets/scss/opalestate/_properties-loop.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_shortcodes.scss b/assets/scss/opalestate/_shortcodes.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_single.scss b/assets/scss/opalestate/_single.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_styles.scss b/assets/scss/opalestate/_styles.scss old mode 100755 new mode 100644 diff --git a/assets/scss/opalestate/_vars.scss b/assets/scss/opalestate/_vars.scss old mode 100755 new mode 100644 diff --git a/assets/scss/submission.scss b/assets/scss/submission.scss old mode 100755 new mode 100644 diff --git a/inc/.DS_Store b/inc/.DS_Store index 85240704..c3ad825f 100755 Binary files a/inc/.DS_Store and b/inc/.DS_Store differ diff --git a/inc/agency/class-opalestate-agency-query.php b/inc/agency/class-opalestate-agency-query.php index 65268752..068ce992 100755 --- a/inc/agency/class-opalestate-agency-query.php +++ b/inc/agency/class-opalestate-agency-query.php @@ -17,4 +17,226 @@ if ( !defined( 'ABSPATH' ) ) exit; class Opalestate_Agency_Query extends OpalEstate_Abstract_Query { + public $count = 0; + + /** + * Default query arguments. + * + * Not all of these are valid arguments that can be passed to WP_Query. The ones that are not, are modified before + * the query is run to convert them to the proper syntax. + * + * @since 2.5.0 + * @access public + * + * @param $args array The array of arguments that can be passed in and used for setting up this form query. + */ + public function __construct( $args = array() ) { + + $defaults = array( + 'output' => 'collection', + 'post_type' => array( 'opaljob_job' ), + 'number' => 20, + 'offset' => 0, + 'paged' => 1, + 'orderby' => 'id', + 'order' => 'DESC' + ); + + $args['update_post_meta_cache'] = false; + + $this->args = $this->_args = wp_parse_args( $args, $defaults ); + } + + /** + * Render Sidebar + * + * Display Sidebar on left side and next is main content + * + * @since 1.0 + * + * @return string + */ + public function get_query_object() { + /* @var WP_Query $query */ + $query = new WP_Query( $this->args ); + return $query; + } + + /** + * Render Sidebar + * + * Display Sidebar on left side and next is main content + * + * @since 1.0 + * + * @return string + */ + public function get_list () { + + $output = array( + 'founds' => 0 , + 'collection' => [] + ); + + $query = $this->get_query_object(); + if ( $query ) { + $i = 0; + $collection = array(); + if( $query->have_posts() ) { + while( $query->have_posts() ){ $query->the_post(); global $post; + $collection[] = new OpalEstate_Agency( $post->ID ); + } + } + wp_reset_postdata(); + $output['collection'] = $collection; + $output['found'] = $query->found_posts; + } + + + return $output; + } + + /** + * Render Sidebar + * + * Display Sidebar on left side and next is main content + * + * @since 1.0 + * + * @return string + */ + public function get_api_list () { + $output = array( + 'founds' => 0 , + 'collection' => [] + ); + + $query = $this->get_query_object(); + if ( $query ) { + $i = 0; + $collection = array(); + if( $query->have_posts() ) { + while( $query->have_posts() ){ $query->the_post(); global $post; + $collection[] = $this->get_agency_data( $post ); + } + } + wp_reset_postdata(); + $output['collection'] = $collection; + $output['found'] = $query->found_posts; + } + + return $output; + } + + /** + * 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 + */ + + public function get_agency_data( $agency_info ){ + + $agency = new OpalEstate_Agency( $agency_info->ID ); + + $ouput = array(); + + $ouput['info']['id'] = $agency_info->ID; + $ouput['info']['slug'] = $agency_info->post_name; + $ouput['info']['title'] = $agency_info->post_title; + $ouput['info']['status'] = $agency_info->post_status; + $ouput['info']['link'] = html_entity_decode( $agency_info->guid ); + $ouput['info']['content'] = $agency_info->post_content; + $ouput['info']['thumbnail'] = wp_get_attachment_url( get_post_thumbnail_id( $agency_info->ID ) ); + + $agency = new OpalEstate_Agency( $agency_info->ID ); + + $ouput['info']['featured'] = (int)$agency->is_featured(); + $ouput['info']['trusted'] = $agency->get_meta( 'trusted' ); + $ouput['info']['avatar'] = $agency->get_meta( 'avatar' ); + $ouput['info']['web'] = $agency->get_meta( 'web' ); + $ouput['info']['phone'] = $agency->get_meta( 'phone' ); + $ouput['info']['mobile'] = $agency->get_meta( 'mobile' ); + $ouput['info']['fax'] = $agency->get_meta( 'fax' ); + $ouput['info']['email'] = $agency->get_meta( 'email' ); + $ouput['info']['address'] = $agency->get_meta( 'address' ); + $ouput['info']['map'] = $agency->get_meta( 'map' ); + + $terms = wp_get_post_terms( $agency_info->ID, 'opalestate_agency_location' ); + $ouput['info']['location'] = $terms && !is_wp_error($terms) ? $terms : array(); + + $ouput['socials'] = $agency->get_socials(); + + $ouput['category'] = $agency->get_category_tax(); + + return apply_filters( 'opalestate_api_agency', $ouput ); + } + + /** + * Get search query base on user request to filter collection of Agents + */ + public static function get_search_agencies_query( $args = [] ) { + $s = isset( $_GET['search_text'] ) ? sanitize_text_field( $_GET['search_text'] ) : null; + + $paged = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' ); + $default = [ + 'post_type' => 'opalestate_agency', + 'posts_per_page' => apply_filters( 'opalestate_agency_per_page', 12 ), + 'paged' => $paged, + ]; + $args = array_merge( $default, $args ); + + $tax_query = []; + + + if ( isset( $_GET['location'] ) && $_GET['location'] != -1 ) { + $tax_query[] = + [ + 'taxonomy' => 'opalestate_location', + 'field' => 'slug', + 'terms' => sanitize_text_field( $_GET['location'] ), + ]; + } + + if ( isset( $_GET['types'] ) && $_GET['types'] != -1 ) { + $tax_query[] = + [ + 'taxonomy' => 'opalestate_types', + 'field' => 'slug', + 'terms' => sanitize_text_field( $_GET['types'] ), + ]; + } + + if ( $tax_query ) { + $args['tax_query'] = [ 'relation' => 'AND' ]; + $args['tax_query'] = array_merge( $args['tax_query'], $tax_query ); + } + + $args['meta_query'] = [ 'relation' => 'AND' ]; + + + return new WP_Query( $args ); + } + + + /** + * Get Query Object to display list of agents + */ + public static function get_agencies( $args = [], $featured = false ) { + $default = [ + 'post_type' => 'opalestate_agency', + 'posts_per_page' => 10, + ]; + $args = array_merge( $default, $args ); + if ( $featured ) { + $args['meta_key'] = OPALESTATE_AGENCY_PREFIX . 'featured'; + $args['meta_value'] = 1; + $args['meta_compare'] = '='; + } + + return new WP_Query( $args ); + } } \ No newline at end of file diff --git a/inc/agency/class-opalestate-agency.php b/inc/agency/class-opalestate-agency.php index 30845e69..bea6bc37 100755 --- a/inc/agency/class-opalestate-agency.php +++ b/inc/agency/class-opalestate-agency.php @@ -24,6 +24,20 @@ class OpalEstate_Agency { */ protected $author_name; + /** + * @var String $author_name + * + * @access protected + */ + public $post_id; + + /** + * @var String $author_name + * + * @access protected + */ + public $author; + /** * @var Boolean $is_featured * @@ -43,14 +57,17 @@ class OpalEstate_Agency { return $_instance; } - /** * Constructor */ public function __construct( $post_id = null ) { - global $post; + global $post ; - $this->post = $post; + if( $post == null ) { + $post = WP_Post::get_instance( $post_id ); + } + + $this->post = $post; $this->post_id = $post_id ? $post_id : get_the_ID(); $this->author = get_userdata( $post->post_author ); $this->author_name = ! empty( $this->author ) ? sprintf( '%s %s', $this->author->first_name, $this->author->last_name ) : null; @@ -58,6 +75,12 @@ class OpalEstate_Agency { $this->is_trusted = $this->get_meta( 'trusted' ); } + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function get_id() { return $this->post_id; } @@ -129,7 +152,12 @@ class OpalEstate_Agency { return $this->is_featured; } - + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function render_avatar() { } @@ -141,16 +169,32 @@ class OpalEstate_Agency { } - + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function get_gallery() { return $this->get_meta( 'gallery' ); } - + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function get_trusted() { return $this->is_trusted; } + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function get_members() { $team = []; $ids = get_post_meta( $this->post_id, OPALESTATE_AGENCY_PREFIX . 'team', true ); @@ -171,6 +215,12 @@ class OpalEstate_Agency { return $team; } + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public static function get_link( $agency_id ) { $agency = get_post( $agency_id ); $url = self::get_avatar_url( $agency_id ); @@ -182,6 +232,12 @@ class OpalEstate_Agency { ]; } + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public static function metaboxes_fields() { $metabox = new Opalestate_Agency_MetaBox(); $fields = $metabox->metaboxes_admin_fields(); @@ -219,6 +275,12 @@ class OpalEstate_Agency { return $this->get_meta( 'review_count' ) ? $this->get_meta( 'review_count' ) : 0; } + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function get_rating_count_stats() { return $this->get_meta( 'rating_count_stats' ) ? $this->get_meta( 'rating_count_stats' ) : [ 5 => 0, @@ -229,6 +291,22 @@ class OpalEstate_Agency { ]; } + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_category_tax ( ) { + return wp_get_post_terms( $this->post_id, 'opalestate_agency_cat' ); + } + + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ public function get_rating_average_stats() { return $this->get_meta( 'rating_average_stats' ); } diff --git a/inc/agent/class-opalestate-agent.php b/inc/agent/class-opalestate-agent.php index edfc02f7..2ba759bd 100755 --- a/inc/agent/class-opalestate-agent.php +++ b/inc/agent/class-opalestate-agent.php @@ -31,6 +31,13 @@ class OpalEstate_Agent { */ protected $is_featured; + /** + * @var Boolean $is_featured + * + * @access protected + */ + public $post_id; + /** * Constructor */ diff --git a/inc/api/class-api-auth.php b/inc/api/class-api-auth.php new file mode 100755 index 00000000..1fcd5ed4 --- /dev/null +++ b/inc/api/class-api-auth.php @@ -0,0 +1,110 @@ + + * @license https://opensource.org/licenses/gpl-license GNU Public License + * @since 1.0 + */ +/** + * Api_Auth class for authorizing to access api resources + * + * @since 1.0.0 + * @package Opal_Job + * @subpackage Opal_Job/API + */ +class Api_Auth extends Base_API { + + /** + * Register user endpoints. + * + * to check post method need authorization to continue completing action + * + * @since 1.0 + * + * @return avoid + */ + public function register_routes() { + // check all request must to have public key and token + register_rest_route( $this->namespace, '/job/list', array( + 'methods' => 'GET', + 'permission_callback' => array( $this, 'validate_request' ), + ), 9 ); + + ////////////////// Check User Authorizcation must to have account logined + // check authorcation for all delete in route + register_rest_route($this->namespace, '/(?P[\S]+)/delete', array( + 'methods' => 'GET', + 'callback' => array( $this, 'check' ), + )); + // check authorcation for all delete in route + register_rest_route($this->namespace, '/(?P[\S]+)/edit', array( + 'methods' => 'GET', + 'callback' => array( $this, 'check' ), + )); + // check authorcation for all delete in route + register_rest_route($this->namespace, '/(?P[\S]+)/create', array( + 'methods' => 'GET', + 'callback' => array( $this, 'check' ), + )); + } + + + /** + * Check authorization + * + * check user request having passing username and password, then check them be valid or not. + * + * @param WP_REST_Request $request + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function check( WP_REST_Request $request ) { + $response = array(); + + $default = array( + 'username' => '', + 'password' => '' + ); + + $parameters = $request->get_params(); + $parameters = array_merge( $default, $parameters ); + + $username = sanitize_text_field( $parameters['username'] ); + $password = sanitize_text_field( $parameters['password'] ); + + // Error Handling. + $error = new WP_Error(); + if ( empty( $username ) ) { + $error->add( + 400, + __( "Username field is required", 'rest-api-endpoints' ), + array( 'status' => 400 ) + ); + return $error; + } + if ( empty( $password ) ) { + $error->add( + 400, + __( "Password field is required", 'rest-api-endpoints' ), + array( 'status' => 400 ) + ); + return $error; + } + $user = wp_authenticate( $username, $password ); + + // If user found + if ( ! is_wp_error( $user ) ) { + $response['status'] = 200; + $response['user'] = $user; + } else { + // If user not found + $error->add( 406, esc_html_e( 'User not found. Check credentials', 'rest-api-endpoints' ) ); + return $error; + } + return new WP_REST_Response( $response ); + } +} \ No newline at end of file diff --git a/inc/api/class-base-api.php b/inc/api/class-base-api.php new file mode 100755 index 00000000..94191c9a --- /dev/null +++ b/inc/api/class-base-api.php @@ -0,0 +1,194 @@ + + * @license https://opensource.org/licenses/gpl-license GNU Public License + * @since 1.0 + */ +//// call http://domain.com/wp-json/job-api/v1/jobs +/** + * Abstract class to define/implement base methods for all controller classes + * + * @since 1.0.0 + * @package Opal_Job + * @subpackage Opal_Job/controllers + */ +abstract class Base_API { + + /** + * The unique identifier of this plugin. + * + * @since 1.0.0 + * @access protected + * @var string $plugin_base_name The string used to uniquely identify this plugin. + */ + public $base ; + + /** + * The unique identifier of this plugin. + * + * @since 1.0.0 + * @access protected + * @var string $plugin_base_name The string used to uniquely identify this plugin. + */ + public $namespace = 'estate-api/v1'; + + /** + * Definition + * + * Register all Taxonomy related to Job post type as location, category, Specialism, Types + * + * @since 1.0 + * + * @return avoid + */ + public function __construct () { + add_action( 'rest_api_init', array( $this, 'register_routes' ) ); + } + + /** + * Definition + * + * Register all Taxonomy related to Job post type as location, category, Specialism, Types + * + * @since 1.0 + * + * @return avoid + */ + public function register_routes() { + + + } + + public function get_response ( $code, $output ) { + + $response = array(); + + $response['status'] = $code; + $response = array_merge( $response, $output ); + + return new WP_REST_Response( $response ); + } + + public function output ( $code ) { + + $this->data['status'] = $code; + return new WP_REST_Response( $this->data ); + } + /** + * 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 Opaljob_API::get_user() + * @uses Opaljob_API::invalid_key() + * @uses Opaljob_API::invalid_auth() + * @since 1.1 + * @return void + */ + public function validate_request( WP_REST_Request $request ) { + + return true; + $response = array(); + + // Make sure we have both user and api key + $api_admin = API_Admin::get_instance(); + + if ( empty( $request['token'] ) || empty( $request['key'] ) ) { + return $this->missing_auth(); + } + + // Retrieve the user by public API key and ensure they exist + if ( ! ( $user = $api_admin->get_user( $request['key'] ) ) ) { + + $this->invalid_key(); + + } else { + + $token = urldecode( $request['token'] ); + $secret = $api_admin->get_user_secret_key( $user ); + $public = urldecode( $request['key'] ); + + if ( hash_equals( md5( $secret . $public ), $token ) ) { + return true; + } else { + $this->invalid_auth(); + } + } + + return false; + } + + /** + * 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 ); + } + + /** + * Displays a missing authentication error if all the parameters aren't + * provided + * + * @access private + * @return WP_Error with message key rest_forbidden + * @since 1.1 + */ + private function missing_auth() { + return new WP_Error( 'rest_forbidden', esc_html__( 'You must specify both a token and API key!' ), array( 'status' => rest_authorization_required_code() ) ); + } + + /** + * Displays an authentication failed error if the user failed to provide valid + * credentials + * + * @access private + * @since 1.1 + * @uses Opaljob_API::output() + * @return WP_Error with message key rest_forbidden + */ + private function invalid_auth() { + return new WP_Error( 'rest_forbidden', esc_html__( 'Your request could not be authenticated!', 'opaljob' ), array( 'status' => 403 ) ); + } + + /** + * Displays an invalid API key error if the API key provided couldn't be + * validated + * + * @access private + * @since 1.1 + * @return WP_Error with message key rest_forbidden + */ + private function invalid_key() { + return new WP_Error( 'rest_forbidden', esc_html__( 'Invalid API key!' ), array( 'status' => rest_authorization_required_code() ) ); + } +} \ No newline at end of file diff --git a/inc/api/class-opalestate-api-remove.php b/inc/api/class-opalestate-api-remove.php new file mode 100755 index 00000000..805ceec5 --- /dev/null +++ b/inc/api/class-opalestate-api-remove.php @@ -0,0 +1,1367 @@ +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; + + } + +} diff --git a/inc/api/class-opalestate-api.php b/inc/api/class-opalestate-api.php index 805ceec5..08607186 100755 --- a/inc/api/class-opalestate-api.php +++ b/inc/api/class-opalestate-api.php @@ -1,166 +1,41 @@ + * @license https://opensource.org/licenses/gpl-license GNU Public License + * @since 1.0 */ - -// Exit if accessed directly +// namespace Opal_Job\API; +// Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } +use Opal_Job\API\Api_Auth; +use Opal_Job\API\API_Admin; /** - * Opalestate_API Class + * Abstract class to define/implement base methods for all controller classes * - * Renders API returns as a JSON/XML array - * - * @since 1.1 + * @since 1.0.0 + * @package Opal_Job + * @subpackage Opal_Job/controllers */ class Opalestate_API { - + /** - * Latest API Version - */ - const VERSION = 1; - - /** - * Pretty Print? + * The unique identifier of this plugin. * - * @var bool - * @access private - * @since 1.1 - */ - private $pretty_print = false; - - /** - * Log API requests? - * - * @var bool - * @access public - * @since 1.1 - */ - public $log_requests = true; - - /** - * Is this a valid request? - * - * @var bool - * @access private - * @since 1.1 - */ - private $is_valid_request = false; - - /** - * User ID Perpropertying the API Request - * - * @var int - * @access public - * @since 1.1 - */ - public $user_id = 0; - - /** - * Instance of Opalestate Stats class - * - * @var object - * @access private - * @since 1.1 - */ - private $stats; - - /** - * Response data to return - * - * @var array - * @access private - * @since 1.1 - */ - private $data = array(); - - /** - * - * @var bool - * @access public - * @since 1.1 - */ - public $override = true; - - /** - * Version of the API queried - * - * @var string - * @access public - * @since 1.1 - */ - private $queried_version; - - /** - * All versions of the API - * - * @var string - * @access protected - * @since 1.1 - */ - protected $versions = array(); - - /** - * Queried endpoint - * - * @var string - * @access private - * @since 1.1 - */ - private $endpoint; - - /** - * Endpoints routes - * - * @var object - * @access private - * @since 1.1 - */ - private $routes; - - /** - * Setup the Opalestate API - * - * @since 1.1 - * @access public - */ - public function __construct() { - - $this->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 ); - + * @since 1.0.0 + * @access protected + * @var string $plugin_base_name The string used to uniquely identify this plugin. + */ + public $base = 'job-api'; + public function __construct () { + return $this->init(); } /** @@ -172,1196 +47,68 @@ class Opalestate_API { * * @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; + public function init() { - return apply_filters( 'opalestate_api_results_per_page', $per_page ); + $this->includes( [ + 'class-base-api.php', + 'v1/property.php', + 'v1/agent.php', + 'v1/agency.php', + 'class-api-auth.php' + ] ); + + add_action( 'rest_api_init', [$this,'register_resources'] ); } + + /** + * 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( $this->base, EP_ALL ); + } + + /** + * Include list of collection files + * + * @var array $files + */ + public function includes( $files ) { + foreach ( $files as $file ) { + $file = OPALESTATE_PLUGIN_DIR . 'inc/api/' . $file; + include_once $file; + } + } + + /** + * Registers a new rewrite endpoint for accessing the API + * + * @access public + * + * @param array $rewrite_rules WordPress Rewrite Rules + * + * @since 1.1 + */ + public function register_resources ( ) { - - /** - * - * - */ - 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 ); - - } + $api_classes = apply_filters( 'opaljob_api_classes', + array( + 'Property_Api', + 'Agent_Api', + 'Agency_Api' + ) + ); - - - /** - * 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; + foreach ( $api_classes as $api_class ) { + $api_class = new $api_class( ); + $api_class->register_routes(); } } - /** - * 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; - - } - -} +} \ No newline at end of file diff --git a/inc/api/v1/agency.php b/inc/api/v1/agency.php new file mode 100644 index 00000000..04e7b140 --- /dev/null +++ b/inc/api/v1/agency.php @@ -0,0 +1,140 @@ + + * @license https://opensource.org/licenses/gpl-license GNU Public License + * @since 1.0 + */ +// Exit if accessed directly. +if ( ! defined( 'ABSPATH' ) ) { + exit; +} +/** + * @class Job_Api + * + * @since 1.0.0 + * @package Opal_Job + * @subpackage Opal_Job/controllers + */ +class Agency_Api extends Base_Api { + + /** + * The unique identifier of the route resource. + * + * @since 1.0.0 + * @access public + * @var string $base. + */ + public $base = '/agency'; + + /** + * Register Routes + * + * Register all CURD actions with POST/GET/PUT and calling function for each + * + * @since 1.0 + * + * @return avoid + */ + public function register_routes ( ) { + /// call http://domain.com/wp-json/job-api/v1/job/list //// + register_rest_route( $this->namespace, $this->base.'/list', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_list' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/1 //// + register_rest_route( $this->namespace, $this->base.'/(?P\d+)', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_job' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /// call http://domain.com/wp-json/job-api/v1/job/create //// + register_rest_route( $this->namespace, $this->base.'/create', array( + 'methods' => 'GET', + 'callback' => array( $this, 'create' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/edit //// + register_rest_route( $this->namespace, $this->base.'/edit', array( + 'methods' => 'GET', + 'callback' => array( $this, 'edit' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/delete //// + register_rest_route( $this->namespace, $this->base.'/delete', array( + 'methods' => 'GET', + 'callback' => array( $this, 'delete' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /** + * List job by tags and taxonmies + */ + /// call http://domain.com/wp-json/job-api/v1/jobs //// + register_rest_route( $this->namespace, $this->base.'/tags', array( + 'methods' => 'GET', + 'callback' => array( $this, 'delete' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + } + + + + /** + * Get List Of Job + * + * Based on request to get collection + * + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function get_list ( $request ) { + + $query = new Opalestate_Agency_Query( + array( + 'post_type' => 'opalestate_agency', + 'posts_per_page' => $this->per_page(), + 'suppress_filters' => true, + 'paged' => $this->get_paged() + ) + ); + + $data = $query->get_api_list(); + $response['collection'] = $data['collection']; + $response['found'] = $data['found']; + $response['current'] = 1; + + return $this->get_response( 200, $response ); + } + + /** + * Delete job + * + * Based on request to get collection + * + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function delete( ) { + + } + + + public function reviews () { + + } + + public function categories () { + + } + + public function tags () { + + } +} \ No newline at end of file diff --git a/inc/api/v1/agent.php b/inc/api/v1/agent.php new file mode 100644 index 00000000..ea4c99f9 --- /dev/null +++ b/inc/api/v1/agent.php @@ -0,0 +1,209 @@ + + * @license https://opensource.org/licenses/gpl-license GNU Public License + * @since 1.0 + */ +// Exit if accessed directly. +if ( ! defined( 'ABSPATH' ) ) { + exit; +} +/** + * @class Job_Api + * + * @since 1.0.0 + * @package Opal_Job + * @subpackage Opal_Job/controllers + */ +class Agent_Api extends Base_Api { + + /** + * The unique identifier of the route resource. + * + * @since 1.0.0 + * @access public + * @var string $base. + */ + public $base = '/agent'; + + /** + * Register Routes + * + * Register all CURD actions with POST/GET/PUT and calling function for each + * + * @since 1.0 + * + * @return avoid + */ + public function register_routes ( ) { + /// call http://domain.com/wp-json/job-api/v1/job/list //// + register_rest_route( $this->namespace, $this->base.'/list', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_list' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/1 //// + register_rest_route( $this->namespace, $this->base.'/(?P\d+)', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_job' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /// call http://domain.com/wp-json/job-api/v1/job/create //// + register_rest_route( $this->namespace, $this->base.'/create', array( + 'methods' => 'GET', + 'callback' => array( $this, 'create' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/edit //// + register_rest_route( $this->namespace, $this->base.'/edit', array( + 'methods' => 'GET', + 'callback' => array( $this, 'edit' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/delete //// + register_rest_route( $this->namespace, $this->base.'/delete', array( + 'methods' => 'GET', + 'callback' => array( $this, 'delete' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /** + * List job by tags and taxonmies + */ + /// call http://domain.com/wp-json/job-api/v1/jobs //// + register_rest_route( $this->namespace, $this->base.'/tags', array( + 'methods' => 'GET', + 'callback' => array( $this, 'delete' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + } + + + + /** + * Get List Of Job + * + * Based on request to get collection + * + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function get_list ( $request ) { + + $agents = array(); + $error = array(); + $agent = null; + 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; + } + } + + $response['collection'] = $agents['agents']; + $response['pages'] = 4; + $response['current'] = 1; + return $this->get_response( 200, $response ); + } + + + /** + * 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 + */ + + 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 ); + } + + /** + * Delete job + * + * Based on request to get collection + * + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function delete( ) { + + } + + + public function reviews () { + + } + + public function categories () { + + } + + public function tags () { + + } +} \ No newline at end of file diff --git a/inc/api/v1/property.php b/inc/api/v1/property.php new file mode 100755 index 00000000..9dd7ec7f --- /dev/null +++ b/inc/api/v1/property.php @@ -0,0 +1,264 @@ + + * @license https://opensource.org/licenses/gpl-license GNU Public License + * @since 1.0 + */ +// Exit if accessed directly. +if ( ! defined( 'ABSPATH' ) ) { + exit; +} +/** + * @class Job_Api + * + * @since 1.0.0 + * @package Opal_Job + * @subpackage Opal_Job/controllers + */ +class Property_Api extends Base_Api { + + /** + * The unique identifier of the route resource. + * + * @since 1.0.0 + * @access public + * @var string $base. + */ + public $base = '/property'; + + /** + * Register Routes + * + * Register all CURD actions with POST/GET/PUT and calling function for each + * + * @since 1.0 + * + * @return avoid + */ + public function register_routes ( ) { + /// call http://domain.com/wp-json/job-api/v1/job/list //// + register_rest_route( $this->namespace, $this->base.'/list', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_list' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /// call http://domain.com/wp-json/job-api/v1/job/featured //// + register_rest_route( $this->namespace, $this->base.'/featured', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_featured_list' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /// call http://domain.com/wp-json/job-api/v1/job/1 //// + register_rest_route( $this->namespace, $this->base.'/(?P\d+)', array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_job' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /// call http://domain.com/wp-json/job-api/v1/job/create //// + register_rest_route( $this->namespace, $this->base.'/create', array( + 'methods' => 'GET', + 'callback' => array( $this, 'create' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/edit //// + register_rest_route( $this->namespace, $this->base.'/edit', array( + 'methods' => 'GET', + 'callback' => array( $this, 'edit' ), + )); + /// call http://domain.com/wp-json/job-api/v1/job/delete //// + register_rest_route( $this->namespace, $this->base.'/delete', array( + 'methods' => 'GET', + 'callback' => array( $this, 'delete' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + + /** + * List job by tags and taxonmies + */ + /// call http://domain.com/wp-json/job-api/v1/jobs //// + register_rest_route( $this->namespace, $this->base.'/tags', array( + 'methods' => 'GET', + 'callback' => array( $this, 'delete' ), + 'permission_callback' => array( $this, 'validate_request' ), + )); + } + + public function get_featured_list() { + $properties = array(); + $error = array(); + + $property = null; + + if ( $property == null ) { + $properties = array(); + + $property_list = get_posts( array( + 'post_type' => 'opalestate_property', + 'posts_per_page' => $this->per_page(), + 'suppress_filters' => true, + 'meta_key' => OPALESTATE_PROPERTY_PREFIX . 'featured', + 'meta_value' => 'on', + 'paged' => $this->get_paged() + ) ); + + if ( $property_list ) { + $i = 0; + foreach ( $property_list as $property_info ) { + $properties[ $i ] = $this->get_property_data( $property_info ); + $i ++; + } + } + } else { + if ( get_post_type( $property ) == 'opalestate_property' ) { + $property_info = get_post( $property ); + + $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; + } + } + + $response['collection'] = $properties; + $response['pages'] = 4; + $response['current'] = 1; + + return $this->get_response( 200, $response ); + } + + /** + * Get List Of Job + * + * Based on request to get collection + * + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function get_list ( $request ) { + + $properties = array(); + $error = array(); + + $property = null; + + if ( $property == null ) { + $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[ $i ] = $this->get_property_data( $property_info ); + $i ++; + } + } + } else { + if ( get_post_type( $property ) == 'opalestate_property' ) { + $property_info = get_post( $property ); + + $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; + } + } + + $response['collection'] = $properties; + $response['pages'] = 4; + $response['current'] = 1; + return $this->get_response( 200, $response ); + } + + + /** + * 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(); + + return apply_filters( 'opalestate_api_properties_property', $property ); + + } + + /** + * Delete job + * + * Based on request to get collection + * + * @since 1.0 + * + * @return WP_REST_Response is json data + */ + public function delete( ) { + + } + + + public function reviews () { + + } + + public function categories () { + + } + + public function tags () { + + } +} \ No newline at end of file diff --git a/inc/message/class-opalestate-message.php b/inc/message/class-opalestate-message.php index 03c88fea..9efe875f 100755 --- a/inc/message/class-opalestate-message.php +++ b/inc/message/class-opalestate-message.php @@ -23,14 +23,23 @@ if ( ! defined( 'ABSPATH' ) ) { class OpalEstate_User_Message { /** + * ID of current user id * + * @return user_id */ protected $user_id = 0; + /** + * Gets types. + * + * @return boolean $is_log + */ protected $is_log; /** + * Gets a instance of this object. * + * @return OpalEstate_User_Message */ public static function get_instance() { static $_instance; @@ -41,6 +50,11 @@ class OpalEstate_User_Message { return $_instance; } + /** + * Gets types. + * + * @return array + */ public function get_types() { return [ diff --git a/inc/mixes-functions.php b/inc/mixes-functions.php index 7c648e31..ad937892 100755 --- a/inc/mixes-functions.php +++ b/inc/mixes-functions.php @@ -1169,47 +1169,48 @@ function opalestate_get_property_statuses() { * @param $key */ function opalestate_get_property_meta_icon( $key ) { - $classes = []; - $classes[] = 'icon-property-' . esc_attr( $key ); - $prefix = 'far'; - $classes[] = $prefix; + $classes = ''; + $classes .= 'icon-property-' . esc_attr( $key ); + switch ( $key ) { case 'builtyear': - $icon = $prefix . '-' . 'calendar'; + $icon = 'fas fa-calendar'; break; case 'parking': - $icon = $prefix . '-' . 'car'; + $icon = 'fas fa-car'; break; case 'bedrooms': - $icon = $prefix . '-' . 'bed'; + $icon = 'fas fa-bed'; break; case 'bathrooms': - $icon = $prefix . '-' . 'bath'; + $icon = 'fas fa-bath'; break; case 'plotsize': - $icon = $prefix . '-' . 'map'; + $icon = 'fas fa-map'; break; case 'areasize': - $icon = $prefix . '-' . 'arrows-alt'; + $icon = 'fas fa-arrows-alt'; break; case 'orientation': - $icon = $prefix . '-' . 'compass'; + $icon = 'fas fa-compass'; break; case 'livingrooms': - $icon = $prefix . '-' . 'tv'; + $icon = 'fas fa-tv'; break; case 'kitchens': - $icon = $prefix . '-' . 'utensils'; + $icon = 'fas fa-utensils'; break; case 'amountrooms': - $icon = $prefix . '-' . 'building'; + $icon = 'fas fa-building'; break; default: $icon = $key; break; } - $classes[] = apply_filters( 'opalestate_property_meta_icon', $icon, $key ); + $classes .= ' '; - return esc_attr( implode( ' ', array_map( 'sanitize_html_class', $classes ) ) ); + $classes .= apply_filters( 'opalestate_property_meta_icon', $icon, $key ); + + return $classes; } diff --git a/inc/property/class-opalestate-property.php b/inc/property/class-opalestate-property.php index e5e40655..e9669d94 100755 --- a/inc/property/class-opalestate-property.php +++ b/inc/property/class-opalestate-property.php @@ -103,7 +103,7 @@ class Opalestate_Property { /** * Constructor */ - public function __construct( $post_id ) { + public function __construct( $post_id ) { $this->post_id = $post_id; $this->map = $this->get_metabox_value( 'map' ); @@ -112,7 +112,7 @@ class Opalestate_Property { $this->saleprice = $this->get_metabox_value( 'saleprice' ); $this->before_pricelabel = $this->get_metabox_value( 'before_pricelabel' ); $this->pricelabel = $this->get_metabox_value( 'pricelabel' ); - $this->featured = $this->get_metabox_value( 'featured' ); + $this->featured = $this->get_metabox_value( 'featured' ); $this->sku = $this->get_metabox_value( 'sku' ); $this->latitude = isset( $this->map['latitude'] ) ? $this->map['latitude'] : ''; @@ -153,7 +153,7 @@ class Opalestate_Property { ]; foreach ( $keys as $key ) { - $this->property_settings[ $key ] = opalestate_get_option( 'enable_single_' . $key ); + $this->property_settings[ $key ] = opalestate_get_option( 'enable_single_' . $key, 'on' ); } } diff --git a/inc/template-functions.php b/inc/template-functions.php index 323974b4..2f62f47b 100755 --- a/inc/template-functions.php +++ b/inc/template-functions.php @@ -576,7 +576,7 @@ function opalestate_property_author_v2() { echo opalestate_load_template_path( 'single-property/author-v2' ); } -function opalestate_property_author_v3() { +function opalestate_property_author_v3() { echo opalestate_load_template_path( 'single-property/author-v3' ); } diff --git a/inc/template-hook-functions.php b/inc/template-hook-functions.php index 7bbb38ff..8425c4f4 100755 --- a/inc/template-hook-functions.php +++ b/inc/template-hook-functions.php @@ -40,7 +40,7 @@ function opalestate_single_property_layout_default() { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_equiry_form', 6 ); // add_action( 'opalestate_single_property_sidebar', 'opalestate_property_request_viewing_button', 7 ); - if ( opalestate_get_option( 'enable_single_mortgage' ) ) { + if ( opalestate_get_option( 'enable_single_mortgage', 'on' ) == 'on' ) { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_mortgage', 9 ); } @@ -83,7 +83,7 @@ function opalestate_single_property_layout_v2() { /// /// sidebar //////// - if ( opalestate_get_option( 'enable_single_mortgage' ) ) { + if ( opalestate_get_option( 'enable_single_mortgage', 'on' ) == 'on' ) { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_mortgage', 9 ); } @@ -125,7 +125,7 @@ function opalestate_single_property_layout_v3() { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_author_v2', 5 ); add_action( 'opalestate_single_property_sidebar', 'opalestate_property_equiry_form', 6 ); - if ( opalestate_get_option( 'enable_single_mortgage' ) ) { + if ( opalestate_get_option( 'enable_single_mortgage' , 'on' ) == 'on' ) { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_mortgage' ); } } @@ -161,7 +161,7 @@ function opalestate_single_property_layout_v4() { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_author_v2', 5 ); add_action( 'opalestate_single_property_sidebar', 'opalestate_property_equiry_form', 6 ); - if ( opalestate_get_option( 'enable_single_mortgage' ) ) { + if ( opalestate_get_option( 'enable_single_mortgage' , 'on' ) == 'on' ) { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_mortgage', 9 ); } } @@ -204,7 +204,7 @@ function opalestate_single_property_layout_v5() { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_author_v2', 5 ); add_action( 'opalestate_single_property_sidebar', 'opalestate_property_equiry_form', 6 ); - if ( opalestate_get_option( 'enable_single_mortgage' ) ) { + if ( opalestate_get_option( 'enable_single_mortgage' ,'on' ) == 'on' ) { add_action( 'opalestate_single_property_sidebar', 'opalestate_property_mortgage', 9 ); } } diff --git a/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php b/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php index d327b7f6..1614acb7 100755 --- a/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php +++ b/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php @@ -17,7 +17,18 @@ if( !class_exists( 'CMB2_Switch_Button' ) ) { public function __construct() { add_action( 'cmb2_render_switch', array( $this, 'callback' ), 10, 5 ); add_action( 'admin_head', array( $this, 'admin_head' ) ); + + add_filter( 'cmb2_sanitize_switch', array( $this, 'sanitize' ), 10, 4 ); } + + public function sanitize ( $override_value, $value, $object_id, $field_args ) { + + if( $value != "on" ) { + $value = 'off'; + } + return $value; + } + public function callback($field, $escaped_value, $object_id, $object_type, $field_type_object) { $field_name = $field->_name(); diff --git a/inc/vendors/cmb2-plugins/custom-fields/iconpicker/iconpicker.php b/inc/vendors/cmb2-plugins/custom-fields/iconpicker/iconpicker.php old mode 100755 new mode 100644 diff --git a/inc/vendors/cmb2-plugins/custom-fields/user/user.php b/inc/vendors/cmb2-plugins/custom-fields/user/user.php old mode 100755 new mode 100644 diff --git a/templates/elementor-templates/opalestate-agency-collection.php b/templates/elementor-templates/opalestate-agency-collection.php index fb8fd4a9..2ccea4a5 100755 --- a/templates/elementor-templates/opalestate-agency-collection.php +++ b/templates/elementor-templates/opalestate-agency-collection.php @@ -11,9 +11,9 @@ } $onlyfeatured = 0; if( isset($_GET['s_agents']) ) { - $query = Opalestate_Query::get_agencies( array("posts_per_page"=>$limit, 'paged' => $paged), $onlyfeatured ); + $query = Opalestate_Agency_Query::get_agencies( array("posts_per_page"=>$limit, 'paged' => $paged), $onlyfeatured ); } else { - $query = OpalEstate_Search::get_search_agencies_query(); + $query = Opalestate_Agency_Query::get_search_agencies_query(); } $rowcls = apply_filters('opalestate_row_container_class', 'opal-row'); diff --git a/templates/messages/enquiry-form.php b/templates/messages/enquiry-form.php index 69f3799d..bb68cdf4 100755 --- a/templates/messages/enquiry-form.php +++ b/templates/messages/enquiry-form.php @@ -1,7 +1,7 @@
- +
@@ -54,7 +54,7 @@ switch ( $type ) {
- + true ] ); ?>
diff --git a/templates/single-property/author.php b/templates/single-property/author.php index a4feead1..876e742d 100755 --- a/templates/single-property/author.php +++ b/templates/single-property/author.php @@ -48,7 +48,7 @@ switch ( $type ) {
- +
@@ -56,7 +56,7 @@ switch ( $type ) {
- +
true ] ); ?>