diff --git a/includes/rest-api/class-wp-job-manager-models-job-categories-custom-fields.php b/includes/rest-api/class-wp-job-manager-models-job-categories-custom-fields.php new file mode 100644 index 000000000..86d105420 --- /dev/null +++ b/includes/rest-api/class-wp-job-manager-models-job-categories-custom-fields.php @@ -0,0 +1,26 @@ +taxonomy_type = 'job_listing_type'; - $this->rest_field_name = 'fields'; - - if ( ! isset( $wp_taxonomies[ $this->taxonomy_type ] ) ) { - return false; - } - - if ( $wp_taxonomies[ $this->taxonomy_type ]->show_in_rest ) { - return true; - } - - $wp_taxonomies[ $this->taxonomy_type ]->show_in_rest = true; - $wp_taxonomies[ $this->taxonomy_type ]->rest_base = 'job-types'; - - $this->model_prototype = $environment->model( 'WP_Job_Manager_Models_Job_Types_Custom_Fields' ); - - if ( ! $this->model_prototype ) { - return new WP_Error( 'model-not-found' ); - } - register_rest_field( $this->taxonomy_type, $this->rest_field_name, array( - 'get_callback' => array( $this, 'get_employment_type' ), - 'update_callback' => array( $this, 'update_employment_type' ), - 'schema' => $this->get_item_schema(), - ) ); - - return true; + public function get_taxonomy_type() { + return 'job_listing_type'; } /** - * Get Item Schema + * Gets the REST API base slug. * - * @return array + * @return string Slug for REST API base. */ - public function get_item_schema() { - $fields = $this->model_prototype->get_fields(); - $properties = array(); - $required = array(); - foreach ( $fields as $field_declaration ) { - /** - * Our declaration - * - * @var WP_Job_Manager_REST_Field_Declaration $field_declaration - */ - $properties[ $field_declaration->get_data_transfer_name() ] = $field_declaration->as_item_schema_property(); - if ( $field_declaration->is_required() ) { - $required[] = $field_declaration->get_data_transfer_name(); - } - } - $schema = array( - '$schema' => 'http://json-schema.org/schema#', - 'title' => $this->model_prototype->get_name(), - 'type' => 'object', - 'properties' => (array) apply_filters( 'mixtape_rest_api_schema_properties', $properties, $this->model_prototype ), - ); - - if ( ! empty( $required ) ) { - $schema['required'] = $required; - } - - return $schema; + public function get_rest_base() { + return 'job-types'; } /** - * Our Get Fields. - * - * @param array $object Object. - * @param string $field_name Field Name. - * @param WP_REST_Request $request Request. - * @param string $object_type Object Type. + * Gets the REST API model class name. * - * @return mixed|string - * @throws WP_Job_Manager_REST_Exception If type not there. + * @return string Class name for the taxonomy type's model. */ - public function get_employment_type( $object, $field_name, $request, $object_type ) { - if ( $this->taxonomy_type !== $object_type ) { - return null; - } - - if ( $this->rest_field_name !== $field_name ) { - return null; - } - - $object_id = absint( $object['id'] ); - $model = $this->get_model( $object_id ); - return $model->to_dto(); - } - - /** - * Get a model if exists - * - * @param int $object_id Object ID. - * @return WP_Job_Manager_REST_Interfaces_Model - * @throws WP_Job_Manager_REST_Exception On Error. - */ - private function get_model( $object_id ) { - $data = array(); - foreach ( $this->model_prototype->get_fields( WP_Job_Manager_REST_Field_Declaration::META ) as $field_declaration ) { - $field_name = $field_declaration->get_name(); - if ( metadata_exists( 'term', $object_id, $field_name ) ) { - $meta = get_term_meta( $object_id, $field_name, true ); - $data[ $field_name ] = $meta; - } - } - - return $this->model_prototype->create( $data, array( - 'deserialize' => true, - ) ); - } - - /** - * Our Reader. - * - * @param mixed $data Data. - * @param object $object Object. - * @param string $field_name Field Name. - * @param WP_REST_Request $request Request. - * @param string $object_type Object Type. - * - * @return mixed|string - * @throws WP_Job_Manager_REST_Exception If type not there. - */ - public function update_employment_type( $data, $object, $field_name, $request, $object_type ) { - if ( $this->taxonomy_type !== $object_type ) { - return null; - } - - if ( $this->rest_field_name !== $field_name ) { - return null; - } - - if ( ! is_a( $object, 'WP_Term' ) ) { - return null; - } - - $term_id = absint( $object->term_id ); - if ( ! $term_id ) { - // No way to update this. Bail. - return new WP_Error( 'job-types-error-invalid-id', 'job-types-error-invalid-id', array( - 'status' => 400, - ) ); - } - $existing_model = $this->get_model( $term_id ); - - $updated = $existing_model->update_from_array( $data ); - if ( is_wp_error( $updated ) ) { - return $updated; - } - - $maybe_validation_error = $updated->sanitize()->validate(); - if ( is_wp_error( $maybe_validation_error ) ) { - return $maybe_validation_error; - } - - $serialized_data = $updated->serialize( WP_Job_Manager_REST_Field_Declaration::META ); - - foreach ( $serialized_data as $field_name => $val ) { - if ( metadata_exists( 'term', $term_id, $field_name ) ) { - update_term_meta( $term_id, $field_name, $val ); - } else { - add_term_meta( $term_id, $field_name, $val ); - } - } - - return true; + public function get_model_class_name() { + return 'WP_Job_Manager_Models_Job_Types_Custom_Fields'; } } diff --git a/includes/rest-api/class-wp-job-manager-registrable-taxonomy-type.php b/includes/rest-api/class-wp-job-manager-registrable-taxonomy-type.php new file mode 100644 index 000000000..d50d8c1a0 --- /dev/null +++ b/includes/rest-api/class-wp-job-manager-registrable-taxonomy-type.php @@ -0,0 +1,229 @@ +get_taxonomy_type(); + $this->rest_field_name = 'fields'; + + if ( ! isset( $wp_taxonomies[ $taxonomy_type ] ) ) { + return false; + } + + if ( $wp_taxonomies[ $taxonomy_type ]->show_in_rest ) { + return true; + } + + $wp_taxonomies[ $taxonomy_type ]->show_in_rest = true; + $wp_taxonomies[ $taxonomy_type ]->rest_base = $this->get_rest_base(); + + $this->model_prototype = $environment->model( $this->get_model_class_name() ); + + if ( ! $this->model_prototype ) { + return new WP_Error( 'model-not-found' ); + } + register_rest_field( $taxonomy_type, $this->rest_field_name, array( + 'get_callback' => array( $this, 'get_taxonomy_term' ), + 'update_callback' => array( $this, 'update_taxonomy_term' ), + 'schema' => $this->get_item_schema(), + ) ); + + return true; + } + + /** + * Get Item Schema + * + * @return array + */ + public function get_item_schema() { + $fields = $this->model_prototype->get_fields(); + $properties = array(); + $required = array(); + foreach ( $fields as $field_declaration ) { + /** + * Our declaration + * + * @var WP_Job_Manager_REST_Field_Declaration $field_declaration + */ + $properties[ $field_declaration->get_data_transfer_name() ] = $field_declaration->as_item_schema_property(); + if ( $field_declaration->is_required() ) { + $required[] = $field_declaration->get_data_transfer_name(); + } + } + $schema = array( + '$schema' => 'http://json-schema.org/schema#', + 'title' => $this->model_prototype->get_name(), + 'type' => 'object', + 'properties' => (array) apply_filters( 'mixtape_rest_api_schema_properties', $properties, $this->model_prototype ), + ); + + if ( ! empty( $required ) ) { + $schema['required'] = $required; + } + + return $schema; + } + + /** + * Our Get Fields. + * + * @param array $object Object. + * @param string $field_name Field Name. + * @param WP_REST_Request $request Request. + * @param string $object_type Object Type. + * + * @return mixed|string + * @throws WP_Job_Manager_REST_Exception If type not there. + */ + public function get_taxonomy_term( $object, $field_name, $request, $object_type ) { + if ( $this->get_taxonomy_type() !== $object_type ) { + return null; + } + + if ( $this->rest_field_name !== $field_name ) { + return null; + } + + $object_id = absint( $object['id'] ); + $model = $this->get_model( $object_id ); + return $model->to_dto(); + } + + /** + * Get a model if exists + * + * @param int $object_id Object ID. + * @return WP_Job_Manager_REST_Interfaces_Model + * @throws WP_Job_Manager_REST_Exception On Error. + */ + private function get_model( $object_id ) { + $data = array(); + foreach ( $this->model_prototype->get_fields( WP_Job_Manager_REST_Field_Declaration::META ) as $field_declaration ) { + $field_name = $field_declaration->get_name(); + if ( metadata_exists( 'term', $object_id, $field_name ) ) { + $meta = get_term_meta( $object_id, $field_name, true ); + $data[ $field_name ] = $meta; + } + } + + return $this->model_prototype->create( $data, array( + 'deserialize' => true, + ) ); + } + + /** + * Our Reader. + * + * @param mixed $data Data. + * @param object $object Object. + * @param string $field_name Field Name. + * @param WP_REST_Request $request Request. + * @param string $object_type Object Type. + * + * @return mixed|string + * @throws WP_Job_Manager_REST_Exception If type not there. + */ + public function update_taxonomy_term( $data, $object, $field_name, $request, $object_type ) { + if ( $this->get_taxonomy_type() !== $object_type ) { + return null; + } + + if ( $this->rest_field_name !== $field_name ) { + return null; + } + + if ( ! is_a( $object, 'WP_Term' ) ) { + return null; + } + + $rest_base = $this->get_rest_base(); + $term_id = absint( $object->term_id ); + if ( ! $term_id ) { + // No way to update this. Bail. + return new WP_Error( $rest_base . '-error-invalid-id', $rest_base . '-error-invalid-id', array( + 'status' => 400, + ) ); + } + $existing_model = $this->get_model( $term_id ); + + $updated = $existing_model->update_from_array( $data ); + if ( is_wp_error( $updated ) ) { + return $updated; + } + + $maybe_validation_error = $updated->sanitize()->validate(); + if ( is_wp_error( $maybe_validation_error ) ) { + return $maybe_validation_error; + } + + $serialized_data = $updated->serialize( WP_Job_Manager_REST_Field_Declaration::META ); + + foreach ( $serialized_data as $field_name => $val ) { + if ( metadata_exists( 'term', $term_id, $field_name ) ) { + update_term_meta( $term_id, $field_name, $val ); + } else { + add_term_meta( $term_id, $field_name, $val ); + } + } + + return true; + } +} diff --git a/includes/rest-api/class-wp-job-manager-rest-api.php b/includes/rest-api/class-wp-job-manager-rest-api.php index bbd07cc7b..3d8d4f4cb 100644 --- a/includes/rest-api/class-wp-job-manager-rest-api.php +++ b/includes/rest-api/class-wp-job-manager-rest-api.php @@ -92,8 +92,11 @@ public function define_api( $env ) { include_once 'class-wp-job-manager-controllers-status.php'; include_once 'class-wp-job-manager-models-job-listings-custom-fields.php'; include_once 'class-wp-job-manager-models-job-types-custom-fields.php'; + include_once 'class-wp-job-manager-models-job-categories-custom-fields.php'; include_once 'class-wp-job-manager-registrable-job-listings.php'; + include_once 'class-wp-job-manager-registrable-taxonomy-type.php'; include_once 'class-wp-job-manager-registrable-job-types.php'; + include_once 'class-wp-job-manager-registrable-job-categories.php'; // Models. $env->define_model( 'WP_Job_Manager_Models_Settings' ) @@ -103,6 +106,7 @@ public function define_api( $env ) { $env->define_model( 'WP_Job_Manager_Filters_Status' ); $env->define_model( 'WP_Job_Manager_Models_Job_Listings_Custom_Fields' ); $env->define_model( 'WP_Job_Manager_Models_Job_Types_Custom_Fields' ); + $env->define_model( 'WP_Job_Manager_Models_Job_Categories_Custom_Fields' ); // Endpoints. $env->rest_api( 'wpjm/v1' ) @@ -113,6 +117,7 @@ public function define_api( $env ) { 'WP_Job_Manager_Models_Job_Listings_Custom_Fields', 'fields' ) ); $env->add_registrable( new WP_Job_Manager_Registrable_Job_Types() ); + $env->add_registrable( new WP_Job_Manager_Registrable_Job_Categories() ); } } diff --git a/tests/php/bootstrap.php b/tests/php/bootstrap.php index fd49cb02d..fb9a9da75 100644 --- a/tests/php/bootstrap.php +++ b/tests/php/bootstrap.php @@ -62,10 +62,8 @@ public function __construct() { */ public function load_plugin() { error_reporting( E_ALL ); - $enabled = get_option( 'job_manager_enable_types' ); - if (! $enabled ) { - update_option( 'job_manager_enable_types', true ); - } + update_option( 'job_manager_enable_types', true ); + update_option( 'job_manager_enable_categories', true ); require_once( $this->plugin_dir . '/wp-job-manager.php' ); } diff --git a/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-categories.php b/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-categories.php new file mode 100644 index 000000000..ff32b1f43 --- /dev/null +++ b/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-categories.php @@ -0,0 +1,26 @@ +login_as( $this->default_user_id ); + $response = $this->get( '/wp/v2' ); + $this->assertResponseStatus( $response, 200 ); + $data = $response->get_data(); + + $routes = array_keys( $data['routes'] ); + $this->assertTrue( in_array( '/wp/v2/job-categories', $routes ) ); + } + + /** + * @group rest + */ + function test_get_job_categories_success() { + $this->login_as( $this->default_user_id ); + $response = $this->get( '/wp/v2/job-categories' ); + $this->assertResponseStatus( $response, 200 ); + } +}