File: /var/www/Gosurya/WP2/wp-content/themes/my-listing/includes/src/admin/single-listing-screen.php
<?php
namespace MyListing\Src\Admin;
if ( ! defined('ABSPATH') ) {
exit;
}
class Single_Listing_Screen {
use \MyListing\Src\Traits\Instantiatable;
public function __construct() {
if ( ! is_admin() ) {
return;
}
add_action( 'save_post', [ $this, 'save_post' ], 1, 2 );
add_action( 'add_meta_boxes', [ $this, 'display_listing_fields' ] );
add_action( 'mylisting/admin/save-listing-data', [ $this, 'save_listing_fields' ], 20, 2 );
add_action( 'admin_init', [ $this, 'remove_taxonomy_metaboxes' ] );
add_action( 'add_meta_boxes', [ $this, 'display_package_metabox' ], 40 );
add_action( 'add_meta_boxes', [ $this, 'display_priority_settings' ], 60 );
add_action( 'add_meta_boxes', [ $this, 'display_verification_metabox' ], 70 );
add_action( 'add_meta_boxes', [ $this, 'display_author_metabox' ], 80 );
// expiry date
add_action( 'add_meta_boxes', [ $this, 'display_expiry_metabox' ], 35 );
add_action( 'transition_post_status', [ $this, 'set_expiry_on_publish' ], 35, 3 );
// listing settings
add_action( 'mylisting/admin/save-listing-data', [ $this, 'save_listing_settings' ], 100, 2 );
// display custom post statuses
foreach ( [ 'post', 'post-new' ] as $hook ) {
add_action( "admin_footer-{$hook}.php", [ $this, 'display_custom_post_statuses' ] );
}
}
/**
* Handles `save_post` action.
*
* @since 2.1
*/
public function save_post( $post_id, $post ) {
if ( empty( $post_id ) || empty( $post ) || empty( $_POST ) || $post->post_type !== 'job_listing' ) {
return;
}
if ( is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) || empty( $_POST['mylisting_save_fields_nonce'] ) || ! wp_verify_nonce( $_POST['mylisting_save_fields_nonce'], 'save_meta_data' ) ) {
return;
}
do_action( 'mylisting/admin/save-listing-data', $post_id, \MyListing\Src\Listing::get( $post ) );
do_action( 'job_manager_save_job_listing', $post_id, $post ); // legacy
}
/**
* Get the list of fields to be shown in
* the backend edit listing form.
*
* @since 2.1
*/
public function get_listing_fields() {
global $post;
$listing = \MyListing\Src\Listing::get( $post );
if ( ! ( $listing && $listing->type ) ) {
return [];
}
// get fields for this listing type
$fields = $listing->get_fields();
// Filter out fields set to be hidden from the backend submission form.
$fields = array_filter( $fields, function( $field ) {
return $field->props['show_in_admin'];
} );
// allow modifiying fields through filters
$fields = apply_filters( 'mylisting/admin/submission/fields', $fields, $listing );
// unset the title field on backend, to make use of the post title input in wp backend
if ( isset( $fields['job_title'] ) ) {
unset( $fields['job_title'] );
}
// in backend form, description field must be shown with high priority,
// regardless of the order in the listing type editor
if ( isset( $fields['job_description'] ) ) {
$fields['job_description']->props['priority'] = 0.2;
}
// order by priority
uasort( $fields, function( $a, $b ) {
$first = isset( $a->props['priority'] ) ? $a->props['priority'] : 0;
$second = isset( $b->props['priority'] ) ? $b->props['priority'] : 0;
return $first - $second;
} );
return $fields;
}
/**
* Handles the saving of listing data fields.
*
* @since 2.1
*/
public function save_listing_fields( $post_id, $listing ) {
foreach ( $this->get_listing_fields() as $key => $field ) {
// description requires special handling to avoid triggering an
// infinite loop of 'save_post' hook calls
if ( $field->get_key() === 'job_description' ) {
remove_action( 'save_post', [ $this, 'save_post' ], 1 );
wp_update_post( [
'ID' => $post_id,
'post_content' => $field->get_posted_value(),
] );
add_action( 'save_post', [ $this, 'save_post' ], 1, 2 );
} else {
try {
$field->admin_validate();
$field->update();
} catch ( \Exception $e ) {
// $e->getMessage();
}
}
}
}
/**
* Handle changing the listing type, author, expiry date...
* in backend edit listing page.
*
* @since 2.0
*/
public function save_listing_settings( $post_id, $listing ) {
remove_action( 'save_post', [ $this, 'save_post' ], 1 );
// post statuses
$current_status = isset( $_POST['post_status'] ) ? $_POST['post_status'] : false;
$previous_status = isset( $_POST['original_post_status'] ) ? $_POST['original_post_status'] : false;
// update listing type
if ( isset( $_POST['_case27_listing_type'] ) ) {
update_post_meta( $post_id, '_case27_listing_type', $_POST['_case27_listing_type'] );
}
// update expiry date
if ( isset( $_POST['mylisting_modify_expiry'] ) && $_POST['mylisting_modify_expiry'] === 'yes' ) {
$expiry_date = ! empty( $_POST['mylisting_expiry_date'] ) ? strtotime( $_POST['mylisting_expiry_date'] ) : false;
if ( $expiry_date ) {
mlog( 'Applying custom expiry date set in metabox.' );
update_post_meta( $post_id, '_job_expires', date( 'Y-m-d', $expiry_date ) );
}
}
// expire listing if past expiry date
$expiry_date = get_post_meta( $post_id, '_job_expires', true );
$has_expired = $expiry_date && strtotime( $expiry_date ) && ( strtotime( $expiry_date ) < current_time( 'timestamp' ) );
if ( $has_expired && ! in_array( $current_status, [ 'draft', 'expired' ], true ) ) {
mlog( 'Listing has reached expiration date, setting post status to "expired".' );
wp_update_post( [
'ID' => $post_id,
'post_status' => 'expired',
] );
}
// update priority
if ( isset( $_POST['cts-listing-priority'] ) ) {
$priority = $_POST['cts-listing-priority'];
// Save custom priority value.
if ( $priority === 'custom' ) {
$custom_priority = ! empty( $_POST['cts-listing-custom-priority'] ) ? absint( $_POST['cts-listing-custom-priority'] ) : false;
if ( $custom_priority >= 0 ) {
update_post_meta( $post_id, '_featured', $custom_priority );
}
} elseif ( absint( $priority ) >= 0 ) {
update_post_meta( $post_id, '_featured', absint( $priority ) );
}
}
// update verification status
if ( isset( $_POST['mylisting_modify_verified_status'] ) && $_POST['mylisting_modify_verified_status'] === 'yes' ) {
$is_verified = isset( $_POST['mylisting_verification_status'] ) && $_POST['mylisting_verification_status'] === 'verified';
update_post_meta( $post_id, '_claimed', $is_verified ? 1 : 0 );
}
// update author
if ( ! empty( $_POST['mylisting_author'] ) && isset( $_POST['mylisting_change_author'] ) && $_POST['mylisting_change_author'] === 'yes' ) {
wp_update_post( [
'ID' => $post_id,
'post_author' => $_POST['mylisting_author'] > 0 ? absint( $_POST['mylisting_author'] ) : 0,
] );
}
// update payment package
if ( isset( $_POST['mylisting_switch_package'] ) && $_POST['mylisting_switch_package'] === 'yes' ) {
$switch_package_id = ! empty( $_POST['mylisting_payment_package'] ) ? absint( $_POST['mylisting_payment_package'] ) : false;
$switch_package = \MyListing\Src\Package::get( $switch_package_id );
// if no package is selected, remove the payment package and associated data
if ( ! $switch_package ) {
delete_post_meta( $post_id, '_job_duration' );
delete_post_meta( $post_id, '_package_id' );
delete_post_meta( $post_id, '_user_package_id' );
// make sure any listing promotions aren't made inactive when disabling package
$priority = (int) get_post_meta( $post_id, '_featured', true );
if ( $priority <= 1 ) {
delete_post_meta( $post_id, '_featured' );
}
// recalculate expiry
$expires = \MyListing\Src\Listing::calculate_expiry( $post_id );
update_post_meta( $post_id, '_job_expires', $expires );
mlog()->note( 'Deleted payment package for listing #'.$post_id );
} else {
// otherwise, apply the selected package
// if the listing already has this package, and it is published, ignore request
if ( $listing->get_data('post_status') !== 'publish' || absint( $listing->get_package_id() ) !== absint( $switch_package->get_id() ) ) {
wp_update_post( [
'ID' => $listing->get_id(),
'post_status' => 'publish',
] );
$switch_package->assign_to_listing( $listing->get_id() );
mlog()->note( 'Switched to package #'.$switch_package_id.' for listing #'.$post_id );
}
}
} elseif ( ! empty( $_POST['mylisting_sync_package'] ) ) {
mlog()->note( 'Syncing product id with the package product id for listing #'.$post_id );
update_post_meta( $post_id, '_package_id', absint( $_POST['mylisting_sync_package'] ) );
}
add_action( 'save_post', [ $this, 'save_post' ], 1, 2 );
}
/**
* Calculate the expiry date when listing gets published.
*
* @since 2.1.6
*/
public function set_expiry_on_publish( $new_status, $old_status, $post ) {
// run this only when the new status is publish and the old one anything but publish
if ( $post->post_type !== 'job_listing' || $new_status !== 'publish' || $old_status === 'publish' ) {
return;
}
$listing = \MyListing\Src\Listing::get( $post );
// if the expiry date meta field isn't set at all, this is likely the initial
// listing publish, so calculate the expiry date and set it
if ( ! metadata_exists( 'post', $listing->get_id(), '_job_expires' ) ) {
mlog( '"Expiry Date" meta key not set, calculating default expiry.' );
$expiry_date = \MyListing\Src\Listing::calculate_expiry( $listing->get_id() );
update_post_meta( $listing->get_id(), '_job_expires', $expiry_date );
}
// if the listing already has an expiry date, make sure it's valid and is a
// date in the future; otherwise, calculate a fresh expiry date and set it
$expiry = $listing->get_expiry_date();
if ( ! $expiry || ( $expiry->getTimestamp() < current_time( 'timestamp' ) ) ) {
mlog( 'Current expiry date has passed, setting a new one on listing publish.' );
$expiry_date = \MyListing\Src\Listing::calculate_expiry( $listing->get_id() );
update_post_meta( $listing->get_id(), '_job_expires', $expiry_date );
}
}
/**
* Add custom meta boxes to single listing screen.
*
* @since 1.7.0
*/
public function display_listing_fields() {
add_meta_box(
'job_listing_data',
_x( 'Listing data', 'Listing fields metabox title', 'my-listing' ),
[ $this, 'fields_metabox_content' ],
'job_listing',
'normal',
'high'
);
}
/**
* Display current author information, and ability
* to switch author.
*
* @since 2.1.6
*/
public function display_author_metabox() {
add_meta_box(
'mylisting_author_metabox',
_x( 'Author', 'Listing author metabox title', 'my-listing' ),
function( $listing ) {
$listing = \MyListing\Src\Listing::get( $listing );
require locate_template( 'templates/admin/single-listing-screen/author-metabox.php' );
},
'job_listing',
'side',
'default'
);
}
/**
* Insert basic settings for listing priority in listing
* edit page in wp-admin.
*
* @since 1.7.0
*/
public function display_priority_settings() {
add_meta_box(
'cts_listing_promotion_settings',
_x( 'Priority', 'Listing priority settings metabox in wp-admin', 'my-listing' ),
function( $listing ) {
$listing = \MyListing\Src\Listing::get( $listing );
require locate_template( 'templates/dashboard/promotions/admin/priority-settings.php' );
},
'job_listing',
'side',
'default'
);
}
/**
* Display verification status and ability to modify it.
*
* @since 2.1.6
*/
public function display_verification_metabox() {
add_meta_box(
'mylisting_verification_metabox',
_x( 'Verification Status', 'Listing verification status metabox title', 'my-listing' ),
function( $listing ) {
$listing = \MyListing\Src\Listing::get( $listing );
require locate_template( 'templates/admin/single-listing-screen/verification-metabox.php' );
},
'job_listing',
'side',
'default'
);
}
/**
* Display current package information, and ability
* to switch package / change details.
*
* @since 2.1.6
*/
public function display_package_metabox() {
add_meta_box(
'mylisting_package_metabox',
_x( 'Package', 'Listing package metabox title', 'my-listing' ),
function( $listing ) {
$listing = \MyListing\Src\Listing::get( $listing );
require locate_template( 'templates/admin/single-listing-screen/package-metabox.php' );
},
'job_listing',
'side',
'default'
);
}
/**
* Display the listing expiry date and ability
* to modify it.
*
* @since 2.1.6
*/
public function display_expiry_metabox() {
add_meta_box(
'mylisting_expiry_metabox',
_x( 'Expiry Date', 'Listing package metabox title', 'my-listing' ),
function( $listing ) {
$listing = \MyListing\Src\Listing::get( $listing );
require locate_template( 'templates/admin/single-listing-screen/expiry-metabox.php' );
},
'job_listing',
'side',
'default'
);
}
/**
* The fields metabox contents.
*
* @since 2.1
*/
public function fields_metabox_content( $post ) {
global $thepostid;
$thepostid = $post->ID;
$listing = \MyListing\Src\Listing::get( $post );
echo '<div class="wp_job_manager_meta_data">';
wp_nonce_field( 'save_meta_data', 'mylisting_save_fields_nonce' );
require locate_template( 'templates/add-listing/form-fields/admin/select-listing-type.php' );
echo '</div></div></div><div class="ml-admin-listing-form">';
wp_enqueue_style( 'mylisting-admin-form' );
wp_enqueue_script( 'mylisting-admin-form' );
foreach ( $this->get_listing_fields() as $key => $field ) {
$field['value'] = $field->get_value();
require locate_template( 'templates/add-listing/form-fields/admin/default.php' );
}
// @todo test this
$user_edited_date = get_post_meta( $post->ID, '_job_edited', true );
if ( $user_edited_date ) {
echo '<p class="form-field">';
echo '<em>' . sprintf( esc_html__( 'Listing was last modified by the user on %s.', 'my-listing' ), esc_html( date_i18n( get_option( 'date_format' ), $user_edited_date ) ) ) . '</em>';
echo '</p>';
}
echo '</div><div><div><div>';
echo '</div>';
}
/**
* Workaround to show custom post statuses in the
* status dropdown in admin edit listing page.
*
* @since 2.1
*/
public function display_custom_post_statuses() {
global $post, $post_type;
// Abort if we're on the wrong post type, but only if we got a restriction.
if ( 'job_listing' !== $post_type ) {
return;
}
// Get all non-builtin post status and add them as <option>.
$options = '';
$display = '';
foreach ( \MyListing\Src\Listing::get_post_statuses() as $status => $name ) {
$selected = selected( $post->post_status, $status, false );
// If we one of our custom post status is selected, remember it.
if ( $selected ) {
$display = $name;
}
// Build the options.
$options .= "<option{$selected} value='{$status}'>" . esc_html( $name ) . '</option>';
}
?>
<script type="text/javascript">
jQuery( document ).ready( function($) {
<?php if ( ! empty( $display ) ) : ?>
jQuery( '#post-status-display' ).html( <?php echo wp_json_encode( $display ); ?> );
<?php endif; ?>
var select = jQuery( '#post-status-select' ).find( 'select' );
jQuery( select ).html( <?php echo wp_json_encode( $options ); ?> );
} );
</script>
<?php
}
/**
* Remove taxonomy metaboxes in edit listing screen, since taxonomies
* can be edited through the listing form fields.
*
* @since 2.1
*/
public function remove_taxonomy_metaboxes() {
remove_meta_box( 'job_listing_categorydiv', 'job_listing', 'normal' );
remove_meta_box( 'regiondiv', 'job_listing', 'normal' );
remove_meta_box( 'tagsdiv-case27_job_listing_tags', 'job_listing', 'normal' );
foreach ( mylisting_custom_taxonomies() as $slug => $label ) {
remove_meta_box( $slug.'div', 'job_listing', 'normal' );
}
}
}