has_cap( 'edit_others_job_listings' ) ) { $fields['_job_author'] = [ 'label' => __( 'Posted by', 'wp-job-manager' ), 'type' => 'author', 'priority' => 0, ]; } foreach ( $fields_raw as $meta_key => $field ) { $show_in_admin = $field['show_in_admin']; if ( is_callable( $show_in_admin ) ) { $show_in_admin = (bool) call_user_func( $show_in_admin, true, $meta_key, $post_id, $current_user->ID ); } if ( ! $show_in_admin ) { continue; } /** * Check auth callback. Mirrors first 4 params of WordPress core's `auth_{$object_type}_meta_{$meta_key}` filter. * * @param bool $allowed Whether the user can edit the job listing meta. Default false. * @param string $meta_key The meta key. * @param int $object_id Object ID. * @param int $user_id User ID. */ if ( ! call_user_func( $field['auth_edit_callback'], false, $meta_key, $post_id, $current_user->ID ) ) { continue; } $fields[ $meta_key ] = $field; } if ( isset( $fields['_job_expires'] ) && ! isset( $fields['_job_expires']['value'] ) ) { $job_expires = get_post_meta( $post_id, '_job_expires', true ); if ( ! empty( $job_expires ) ) { $fields['_job_expires']['placeholder'] = null; $fields['_job_expires']['value'] = date( 'Y-m-d', strtotime( $job_expires ) ); } else { $fields['_job_expires']['placeholder'] = date_i18n( get_option( 'date_format' ), strtotime( calculate_job_expiry( $post_id ) ) ); $fields['_job_expires']['value'] = ''; } } if ( isset( $fields['_application'] ) && ! isset( $fields['_application']['default'] ) && 'url' !== get_option( 'job_manager_allowed_application_method' ) ) { $fields['_application']['default'] = $current_user->user_email; } /** * Filters job listing data fields shown in WP admin. * * To add job listing data fields, use the `job_manager_job_listing_data_fields` found in `includes/class-wp-job-manager-post-types.php`. * * @since 1.33.0 * * @param array $fields Job listing fields for WP admin. See `job_manager_job_listing_data_fields` filter for more information. * @param int|null $post_id Post ID to get fields for. May be null. */ $fields = apply_filters( 'job_manager_job_listing_wp_admin_fields', $fields, $post_id ); uasort( $fields, [ __CLASS__, 'sort_by_priority' ] ); return $fields; } /** * Sorts array of custom fields by priority value. * * @param array $a * @param array $b * @return int */ protected static function sort_by_priority( $a, $b ) { if ( ! isset( $a['priority'] ) || ! isset( $b['priority'] ) || $a['priority'] === $b['priority'] ) { return 0; } return ( $a['priority'] < $b['priority'] ) ? -1 : 1; } /** * Handles the hooks to add custom field meta boxes. */ public function add_meta_boxes() { global $wp_post_types; // translators: Placeholder %s is the singular name for a job listing post type. add_meta_box( 'job_listing_data', sprintf( __( '%s Data', 'wp-job-manager' ), $wp_post_types['job_listing']->labels->singular_name ), [ $this, 'job_listing_data' ], 'job_listing', 'normal', 'high' ); if ( ! get_option( 'job_manager_enable_types' ) || 0 === intval( wp_count_terms( 'job_listing_type' ) ) ) { remove_meta_box( 'job_listing_typediv', 'job_listing', 'side' ); } elseif ( false === job_manager_multi_job_type() ) { remove_meta_box( 'job_listing_typediv', 'job_listing', 'side' ); $job_listing_type = get_taxonomy( 'job_listing_type' ); add_meta_box( 'job_listing_type', $job_listing_type->labels->menu_name, [ $this, 'job_type_single_meta_box' ], 'job_listing', 'side', 'core' ); } } /** * Displays job listing metabox. * * @param int|WP_Post $post */ public function job_type_single_meta_box( $post ) { // Set up the taxonomy object and get terms. $taxonomy_name = 'job_listing_type'; // Get all the terms for this taxonomy. $terms = get_terms( [ 'taxonomy' => $taxonomy_name, 'hide_empty' => 0, ] ); $postterms = get_the_terms( $post->ID, $taxonomy_name ); $current = $postterms ? array_pop( $postterms ) : false; $current = $current ? $current->term_id : 0; $field_name = 'tax_input[' . $taxonomy_name . ']'; ?>
placeholder="" value="" />

$value ) { $download = null; if ( isset( $field['download'] ) && isset( $field['download'][ $k ] ) ) { $download = $field['download'][ $k ]; } self::file_url_field( $key, $name, $field['placeholder'], $value, true, $download ); } } else { $download = null; if ( isset( $field['download'] ) ) { $download = $field['download']; } self::file_url_field( $key, $name, $field['placeholder'], $field['value'], false, $download ); } if ( ! empty( $field['multiple'] ) ) { ?>

'; return; } } ?>

[ 'href' => [] ] ] ); ?> '; ?>

/>

ID ) { $the_post = get_post( $thepostid ); $author_id = $the_post->post_author; } else { $author_id = $post->post_author; } $posted_by = get_user_by( 'id', $author_id ); $name = ! empty( $field['name'] ) ? $field['name'] : $key; ?>

display_name ), absint( $posted_by->ID ), $posted_by->user_email ); echo '#' . absint( $author_id ) . ' – ' . esc_html( $posted_by->user_login ) . ''; } else { $user_string = __( 'Guest User', 'wp-job-manager' ); echo esc_html( $user_string ); } ?>

$value ) : ?>

ID; echo '
'; wp_nonce_field( 'save_meta_data', 'job_manager_nonce' ); do_action( 'job_manager_job_listing_data_start', $thepostid ); foreach ( $this->job_listing_fields() as $key => $field ) { $type = ! empty( $field['type'] ) ? $field['type'] : 'text'; if ( ! isset( $field['value'] ) && metadata_exists( 'post', $thepostid, $key ) ) { $field['value'] = get_post_meta( $thepostid, $key, true ); } if ( ! isset( $field['value'] ) && isset( $field['default'] ) ) { $field['value'] = $field['default']; } if ( has_action( 'job_manager_input_' . $type ) ) { do_action( 'job_manager_input_' . $type, $key, $field ); } elseif ( method_exists( $this, 'input_' . $type ) ) { call_user_func( [ $this, 'input_' . $type ], $key, $field ); } } $user_edited_date = get_post_meta( $post->ID, '_job_edited', true ); if ( $user_edited_date ) { echo '

'; // translators: %1$s is placeholder for singular name of the job listing post type; %2$s is the intl formatted date the listing was last modified. echo '' . sprintf( esc_html__( '%1$s was last modified by the user on %2$s.', 'wp-job-manager' ), esc_html( $wp_post_types['job_listing']->labels->singular_name ), esc_html( date_i18n( get_option( 'date_format' ), $user_edited_date ) ) ) . ''; echo '

'; } do_action( 'job_manager_job_listing_data_end', $thepostid ); echo '
'; } /** * Handles `save_post` action. * * @param int $post_id * @param WP_Post $post */ public function save_post( $post_id, $post ) { if ( empty( $post_id ) || empty( $post ) || empty( $_POST ) ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( is_int( wp_is_post_revision( $post ) ) ) { return; } if ( is_int( wp_is_post_autosave( $post ) ) ) { return; } if ( empty( $_POST['job_manager_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['job_manager_nonce'] ), 'save_meta_data' ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce should not be modified. ) { return; } if ( ! current_user_can( 'edit_post', $post_id ) ) { return; } if ( 'job_listing' !== $post->post_type ) { return; } do_action( 'job_manager_save_job_listing', $post_id, $post ); } /** * Handles the actual saving of job listing data fields. * * @param int $post_id * @param WP_Post $post (Unused). */ public function save_job_listing_data( $post_id, $post ) { global $wpdb; // These need to exist. add_post_meta( $post_id, '_filled', 0, true ); add_post_meta( $post_id, '_featured', 0, true ); // Save fields. foreach ( $this->job_listing_fields() as $key => $field ) { if ( isset( $field['type'] ) && 'info' === $field['type'] ) { continue; } // Checkboxes that aren't sent are unchecked. if ( 'checkbox' === $field['type'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. if ( ! empty( $_POST[ $key ] ) ) { $_POST[ $key ] = 1; } else { $_POST[ $key ] = 0; } } // Expirey date. if ( '_job_expires' === $key ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. if ( empty( $_POST[ $key ] ) ) { if ( get_option( 'job_manager_submission_duration' ) ) { update_post_meta( $post_id, $key, calculate_job_expiry( $post_id ) ); } else { delete_post_meta( $post_id, $key ); } } else { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. update_post_meta( $post_id, $key, date( 'Y-m-d', strtotime( sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) ) ) ); } } elseif ( '_job_author' === $key ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. if ( empty( $_POST[ $key ] ) ) { $_POST[ $key ] = 0; } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. $input_post_author = $_POST[ $key ] > 0 ? intval( $_POST[ $key ] ) : 0; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Avoid update post within `save_post` action. $wpdb->update( $wpdb->posts, [ 'post_author' => $input_post_author ], [ 'ID' => $post_id ] ); } elseif ( isset( $_POST[ $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- Input sanitized in registered post meta config; see WP_Job_Manager_Post_Types::register_meta_fields() and WP_Job_Manager_Post_Types::get_job_listing_fields() methods. update_post_meta( $post_id, $key, wp_unslash( $_POST[ $key ] ) ); } } /* Set Post Status To Expired If Already Expired */ $expiry_date = get_post_meta( $post_id, '_job_expires', true ); $today_date = date( 'Y-m-d', current_time( 'timestamp' ) ); $is_job_listing_expired = $expiry_date && $today_date > $expiry_date; if ( $is_job_listing_expired && ! $this->is_job_listing_status_changing( null, 'draft' ) ) { remove_action( 'job_manager_save_job_listing', [ $this, 'save_job_listing_data' ], 20 ); if ( $this->is_job_listing_status_changing( 'expired', 'publish' ) ) { update_post_meta( $post_id, '_job_expires', calculate_job_expiry( $post_id ) ); } else { $job_data = [ 'ID' => $post_id, 'post_status' => 'expired', ]; wp_update_post( $job_data ); } add_action( 'job_manager_save_job_listing', [ $this, 'save_job_listing_data' ], 20, 2 ); } } /** * Checks if the job listing status is being changed from $from_status to $to_status. * * @param string|null $from_status Status to test if it is changing from. NULL if anything. * @param string $to_status Status to test if it is changing to. * * @return bool True if status is changing from $from_status to $to_status. */ private function is_job_listing_status_changing( $from_status, $to_status ) { // phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce check handled by WP core. return isset( $_POST['post_status'] ) && isset( $_POST['original_post_status'] ) && $_POST['original_post_status'] !== $_POST['post_status'] && ( null === $from_status || $from_status === $_POST['original_post_status'] ) && $to_status === $_POST['post_status']; // phpcs:enable WordPress.Security.NonceVerification.Missing } } WP_Job_Manager_Writepanels::instance();