diff --git a/includes/class-wp-job-manager-post-types.php b/includes/class-wp-job-manager-post-types.php index af894afcf..3a1d05c3b 100644 --- a/includes/class-wp-job-manager-post-types.php +++ b/includes/class-wp-job-manager-post-types.php @@ -700,6 +700,7 @@ public function job_feed_item() { $company = get_the_company_name( $post_id ); $job_types = wpjm_get_the_job_types( $post_id ); $salary = get_the_job_salary( $post_id ); + $salarymax = get_the_job_salary_max( $post_id ); if ( $location ) { echo '\n"; @@ -714,6 +715,9 @@ public function job_feed_item() { if ( $salary ) { echo '\n"; } + if ( $salarymax ) { + echo '\n"; + } /** * Fires at the end of each job RSS feed item. @@ -1605,7 +1609,7 @@ public static function get_job_listing_fields() { 'show_in_rest' => true, ], '_job_salary' => [ - 'label' => __( 'Salary', 'wp-job-manager' ), + 'label' => __( 'Salary / Salary (min)', 'wp-job-manager' ), 'type' => 'text', 'placeholder' => __( 'e.g. 20000', 'wp-job-manager' ), 'priority' => 13, @@ -1614,12 +1618,22 @@ public static function get_job_listing_fields() { 'show_in_admin' => (bool) get_option( 'job_manager_enable_salary' ), 'show_in_rest' => true, ], + '_job_salary_max' => [ + 'label' => __( 'Salary (max)', 'wp-job-manager' ), + 'type' => 'text', + 'placeholder' => __( 'e.g. 25000', 'wp-job-manager' ), + 'priority' => 14, + 'description' => __( 'Add a max salary field, this field is optional.', 'wp-job-manager' ), + 'data_type' => 'string', + 'show_in_admin' => (bool) get_option( 'job_manager_enable_salary' ), + 'show_in_rest' => true, + ], '_job_salary_currency' => [ 'label' => __( 'Salary Currency', 'wp-job-manager' ), 'type' => 'text', 'data_type' => 'string', 'placeholder' => __( 'e.g. USD', 'wp-job-manager' ), - 'priority' => 14, + 'priority' => 15, 'description' => __( 'Add a salary currency, this field is optional. Leave it empty to use the default salary currency.', 'wp-job-manager' ), 'default' => '', 'show_in_admin' => get_option( 'job_manager_enable_salary' ) && get_option( 'job_manager_enable_salary_currency' ), @@ -1630,7 +1644,7 @@ public static function get_job_listing_fields() { 'type' => 'select', 'data_type' => 'string', 'options' => job_manager_get_salary_unit_options(), - 'priority' => 15, + 'priority' => 16, 'description' => __( 'Add a salary period unit, this field is optional. Leave it empty to use the default salary unit, if one is defined.', 'wp-job-manager' ), 'default' => '', 'show_in_admin' => get_option( 'job_manager_enable_salary' ) && get_option( 'job_manager_enable_salary_unit' ), diff --git a/includes/forms/class-wp-job-manager-form-submit-job.php b/includes/forms/class-wp-job-manager-form-submit-job.php index b76593797..bd8628a3b 100644 --- a/includes/forms/class-wp-job-manager-form-submit-job.php +++ b/includes/forms/class-wp-job-manager-form-submit-job.php @@ -276,19 +276,26 @@ public function init_fields() { 'priority' => 7, ], 'job_salary' => [ - 'label' => __( 'Salary', 'wp-job-manager' ), + 'label' => __( 'Salary / Salary (min)', 'wp-job-manager' ), 'type' => 'text', 'required' => false, 'placeholder' => __( 'e.g. 20000', 'wp-job-manager' ), 'priority' => 8, ], + 'job_salary_max' => [ + 'label' => __( 'Salary (max)', 'wp-job-manager' ), + 'type' => 'text', + 'required' => false, + 'placeholder' => __( 'e.g. 25000', 'wp-job-manager' ), + 'priority' => 9, + ], 'job_salary_currency' => [ 'label' => __( 'Salary Currency', 'wp-job-manager' ), 'type' => 'text', 'required' => false, 'placeholder' => __( 'e.g. USD', 'wp-job-manager' ), 'description' => __( 'Add a salary currency, this field is optional. Leave it empty to use the default salary currency.', 'wp-job-manager' ), - 'priority' => 9, + 'priority' => 10, ], 'job_salary_unit' => [ 'label' => __( 'Salary Unit', 'wp-job-manager' ), @@ -296,7 +303,7 @@ public function init_fields() { 'options' => job_manager_get_salary_unit_options(), 'description' => __( 'Add a salary period unit, this field is optional. Leave it empty to use the default salary unit, if one is defined.', 'wp-job-manager' ), 'required' => false, - 'priority' => 10, + 'priority' => 11, ], ], 'company' => [ @@ -371,7 +378,7 @@ public function init_fields() { unset( $this->fields['job']['job_salary_unit'] ); } } else { - unset( $this->fields['job']['job_salary'], $this->fields['job']['job_salary_currency'], $this->fields['job']['job_salary_unit'] ); + unset( $this->fields['job']['job_salary'], $this->fields['job']['job_salary_max'], $this->fields['job']['job_salary_currency'], $this->fields['job']['job_salary_unit'] ); } if ( ! get_option( 'job_manager_enable_remote_position' ) ) { unset( $this->fields['job']['remote_position'] ); diff --git a/includes/promoted-jobs/class-wp-job-manager-promoted-jobs-api.php b/includes/promoted-jobs/class-wp-job-manager-promoted-jobs-api.php index 6e5168e19..f128c3940 100644 --- a/includes/promoted-jobs/class-wp-job-manager-promoted-jobs-api.php +++ b/includes/promoted-jobs/class-wp-job-manager-promoted-jobs-api.php @@ -242,9 +242,10 @@ private function prepare_item_for_response( WP_Post $item ) { 'is_remote' => (bool) get_post_meta( $item->ID, '_remote_position', true ), 'job_type' => $terms_array, 'salary' => [ - 'amount' => get_post_meta( $item->ID, '_job_salary', true ), - 'currency' => get_the_job_salary_currency( $item ), - 'unit' => get_the_job_salary_unit_display_text( $item ), + 'amount' => get_post_meta( $item->ID, '_job_salary', true ), + 'amountmax' => get_post_meta( $item->ID, '_job_salary_max', true ), + 'currency' => get_the_job_salary_currency( $item ), + 'unit' => get_the_job_salary_unit_display_text( $item ), ], ]; } diff --git a/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-listings.php b/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-listings.php index 8fc5c3763..d38cb22be 100644 --- a/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-listings.php +++ b/tests/php/tests/includes/rest-api/test_class.wp-job-manager-job-listings.php @@ -171,7 +171,7 @@ public function test_get_job_listings_success_guest() { * Tests to make sure public meta fields are exposed to guest users and private meta fields are hidden. */ public function test_guest_can_read_only_public_fields() { - $public_fields = [ '_job_location', '_application', '_company_name', '_company_website', '_company_tagline', '_company_twitter', '_company_video', '_filled', '_featured', '_remote_position', '_job_salary', '_job_salary_currency', '_job_salary_unit' ]; + $public_fields = [ '_job_location', '_application', '_company_name', '_company_website', '_company_tagline', '_company_twitter', '_company_video', '_filled', '_featured', '_remote_position', '_job_salary', '_job_salary_max', '_job_salary_currency', '_job_salary_unit' ]; $private_fields = [ '_job_expires' ]; $this->logout(); $post_id = $this->get_job_listing(); @@ -192,7 +192,7 @@ public function test_guest_can_read_only_public_fields() { } public function test_same_employer_read_access_to_private_meta_fields() { - $available_fields = [ '_job_location', '_application', '_company_name', '_company_website', '_company_tagline', '_company_twitter', '_company_video', '_filled', '_featured', '_job_expires', '_remote_position', '_job_salary', '_job_salary_currency', '_job_salary_unit' ]; + $available_fields = [ '_job_location', '_application', '_company_name', '_company_website', '_company_tagline', '_company_twitter', '_company_video', '_filled', '_featured', '_job_expires', '_remote_position', '_job_salary', '_job_salary_max', '_job_salary_currency', '_job_salary_unit' ]; $this->login_as_employer(); $post_id = $this->get_job_listing(); @@ -207,7 +207,7 @@ public function test_same_employer_read_access_to_private_meta_fields() { } public function test_different_employer_read_access_to_private_meta_fields() { - $public_fields = [ '_job_location', '_application', '_company_name', '_company_website', '_company_tagline', '_company_twitter', '_company_video', '_filled', '_featured', '_remote_position', '_job_salary', '_job_salary_currency', '_job_salary_unit' ]; + $public_fields = [ '_job_location', '_application', '_company_name', '_company_website', '_company_tagline', '_company_twitter', '_company_video', '_filled', '_featured', '_remote_position', '_job_salary', '_job_salary_max', '_job_salary_currency', '_job_salary_unit' ]; $private_fields = [ '_job_expires' ]; $this->login_as_employer(); $post_id = $this->get_job_listing(); diff --git a/wp-job-manager-template.php b/wp-job-manager-template.php index 0c7665e5a..3572c81d9 100644 --- a/wp-job-manager-template.php +++ b/wp-job-manager-template.php @@ -418,10 +418,19 @@ function wpjm_get_job_listing_structured_data( $post = null ) { } } - $salary = get_the_job_salary( $post ); - $currency = get_the_job_salary_currency( $post ); - $unit = get_the_job_salary_unit( $post ); - if ( ! empty( $salary ) ) { + $salary = get_the_job_salary( $post ); + $salary_max = get_the_job_salary_max( $post ); + $currency = get_the_job_salary_currency( $post ); + $unit = get_the_job_salary_unit( $post ); + if ( ! empty( $salary_max ) ) { + $data['baseSalary'] = []; + $data['baseSalary']['@type'] = 'MonetaryAmount'; + $data['baseSalary']['currency'] = $currency; + $data['baseSalary']['value']['@type'] = 'QuantitativeValue'; + $data['baseSalary']['value']['minValue'] = $salary; + $data['baseSalary']['value']['maxValue'] = $salary_max; + $data['baseSalary']['value']['unitText'] = $unit; + } elseif ( ! empty( $salary ) ) { $data['baseSalary'] = []; $data['baseSalary']['@type'] = 'MonetaryAmount'; $data['baseSalary']['currency'] = $currency; @@ -1298,6 +1307,33 @@ function get_the_job_salary( $post = null ) { return apply_filters( 'the_job_salary', $job_salary, $post ); } +/** + * Gets the max job salary. + * + * @since 1.37.0 + * @param int|WP_Post|null $post (default: null). + * @return string|null + */ +function get_the_job_salary_max( $post = null ) { + $post = get_post( $post ); + if ( ! $post || 'job_listing' !== $post->post_type ) { + return; + } + + $job_salary_max = $post->_job_salary_max; + + /** + * Filter the returned max job salary. + * + * @since 1.36.0 + * + * @param string $job_salary_max + * @param WP_Post $post + */ + return apply_filters( 'the_job_salary_max', $job_salary_max, $post ); +} + + /** * Displays or retrieves the job salary with optional content. * @@ -1309,16 +1345,20 @@ function get_the_job_salary( $post = null ) { * @return string|void */ function the_job_salary( $before = '', $after = '', $echo = true, $post = null ) { - $post = get_post( $post ); - $salary = get_the_job_salary( $post ); - $currency = get_the_job_salary_currency( $post ); - $unit = get_the_job_salary_unit_display_text( $post ); + $post = get_post( $post ); + $salary = get_the_job_salary( $post ); + $salarymax = get_the_job_salary_max( $post ); + $currency = get_the_job_salary_currency( $post ); + $unit = get_the_job_salary_unit_display_text( $post ); if ( strlen( $salary ) === 0 ) { return; } $job_salary = $before . $salary . ' ' . $currency; + if ( ! empty( $salarymax ) ) { + $job_salary .= ' - ' . $salarymax . ' ' . $currency; + } if ( ! empty( $unit ) ) { $job_salary .= ' / ' . $unit; } @@ -1332,11 +1372,12 @@ function the_job_salary( $before = '', $after = '', $echo = true, $post = null ) * @param WP_Post $post * @param string $before * @param string $salary + * @param string $salarymax * @param string $currency * @param string $unit * @param string $after */ - $job_salary = apply_filters( 'the_job_salary_message', $job_salary, $post, $before, $salary, $currency, $unit, $after ); + $job_salary = apply_filters( 'the_job_salary_message', $job_salary, $post, $before, $salary, $currency, $unit, $after, $salarymax ); if ( $echo ) { echo esc_html( $job_salary );