_x( 'Listings', 'Post Type General Name', 'advanced-classifieds-and-directory-pro' ), 'singular_name' => _x( 'Listing', 'Post Type Singular Name', 'advanced-classifieds-and-directory-pro' ), 'menu_name' => __( 'Classifieds & Directory', 'advanced-classifieds-and-directory-pro' ), 'name_admin_bar' => __( 'Listing', 'advanced-classifieds-and-directory-pro' ), 'all_items' => __( 'All Listings', 'advanced-classifieds-and-directory-pro' ), 'add_new_item' => __( 'Add New Listing', 'advanced-classifieds-and-directory-pro' ), 'add_new' => __( 'Add New', 'advanced-classifieds-and-directory-pro' ), 'new_item' => __( 'New Listing', 'advanced-classifieds-and-directory-pro' ), 'edit_item' => __( 'Edit Listing', 'advanced-classifieds-and-directory-pro' ), 'update_item' => __( 'Update Listing', 'advanced-classifieds-and-directory-pro' ), 'view_item' => __( 'View Listing', 'advanced-classifieds-and-directory-pro' ), 'search_items' => __( 'Search Listing', 'advanced-classifieds-and-directory-pro' ), 'not_found' => __( 'Not found', 'advanced-classifieds-and-directory-pro' ), 'not_found_in_trash' => __( 'Not found in Trash', 'advanced-classifieds-and-directory-pro' ), ); $supports = array( 'title', 'editor', 'author' ); $general_settings = get_option( 'acadp_general_settings' ); if( ! empty( $general_settings['has_comment_form'] ) ) { array_push( $supports, 'comments' ); } $args = array( 'label' => __( 'acadp_listings', 'advanced-classifieds-and-directory-pro' ), 'description' => __( 'Post Type Description', 'advanced-classifieds-and-directory-pro' ), 'labels' => $labels, 'supports' => $supports, 'taxonomies' => array( '' ), 'hierarchical' => false, 'public' => true, 'show_ui' => current_user_can( 'administrator' ) ? true : false, 'show_in_menu' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-welcome-widgets-menus', 'show_in_admin_bar' => true, 'show_in_nav_menus' => true, 'can_export' => true, 'has_archive' => true, 'exclude_from_search' => false, 'publicly_queryable' => true, 'capability_type' => 'acadp_listing', 'map_meta_cap' => true, ); $permalink_settings = get_option( 'acadp_permalink_settings' ); if( isset( $permalink_settings['listing'] ) ) { $args['rewrite'] = array( 'slug' => $permalink_settings['listing'] ); } register_post_type( 'acadp_listings', $args ); } /** * Remove meta boxes. * * @since 1.0.0 * @access public */ public function remove_meta_boxes() { remove_meta_box( 'acadp_categoriesdiv', 'acadp_listings', 'side' ); remove_meta_box( 'acadp_locationsdiv', 'acadp_listings', 'side' ); } /** * Adds custom meta fields in Publish meta box. * * @since 1.0.0 * @access public */ public function post_submitbox_misc_actions() { global $post, $post_type; if( 'acadp_listings' == $post_type ) { $featured_settings = get_option( 'acadp_featured_listing_settings' ); $has_featured = apply_filters( 'acadp_has_featured', isset( $featured_settings['enabled'] ) ); $post_meta = get_post_meta( $post->ID ); $never_expires = ! empty( $post_meta['never_expires'][0] ) ? 1 : 0; if( isset( $post_meta['expiry_date'] ) ) { $expiry_date = acadp_parse_mysql_date_format( $post_meta['expiry_date'][0] ); } // Add a nonce field so we can check for it later wp_nonce_field( 'acadp_save_listing_submitbox', 'acadp_listing_submitbox_nonce' ); require_once ACADP_PLUGIN_DIR . 'admin/partials/listings/acadp-admin-listing-submitbox-display.php'; } } /** * Register meta boxes. * * @since 1.0.0 * @access public */ public function add_meta_boxes() { $general_settings = get_option( 'acadp_general_settings' ); add_meta_box( 'acadp-listing-details', __( 'Listing Details', 'advanced-classifieds-and-directory-pro' ), array( $this, 'display_meta_box_listing_details' ), 'acadp_listings', 'normal', 'high' ); if( ! empty( $general_settings['has_location'] ) ) { add_meta_box( 'acadp-contact-details', __( 'Contact Details', 'advanced-classifieds-and-directory-pro' ), array( $this, 'display_meta_box_contact_details' ), 'acadp_listings', 'normal', 'high' ); } if( ! empty( $general_settings['has_images'] ) ) { add_meta_box( 'acadp-listing-images', __( 'Images', 'advanced-classifieds-and-directory-pro' ), array( $this, 'display_meta_box_listing_images' ), 'acadp_listings', 'normal', 'high' ); } if( ! empty( $general_settings['has_video'] ) ) { add_meta_box( 'acadp-listing-video', __( 'Video', 'advanced-classifieds-and-directory-pro' ), array( $this, 'display_meta_box_listing_video' ), 'acadp_listings', 'normal', 'high' ); } } /** * Display a listing details meta box. * * @since 1.0.0 * @access public * * @param WP_Post $post WordPress Post object */ public function display_meta_box_listing_details( $post ) { $general_settings = get_option( 'acadp_general_settings' ); $disable_parent_categories = empty( $general_settings['disable_parent_categories'] ) ? false : true; $has_price = empty( $general_settings['has_price'] ) ? false : true; $post_meta = get_post_meta( $post->ID ); $category = wp_get_object_terms( $post->ID, 'acadp_categories', array( 'fields' => 'ids' ) ); // Add a nonce field so we can check for it later wp_nonce_field( 'acadp_save_listing_details', 'acadp_listing_details_nonce' ); require_once ACADP_PLUGIN_DIR . 'admin/partials/listings/acadp-admin-listing-details-display.php'; } /** * Display a contact details meta box. * * @since 1.0.0 * @access public * * @param WP_Post $post WordPress Post object */ public function display_meta_box_contact_details( $post ) { $post_meta = get_post_meta( $post->ID ); $general_settings = get_option( 'acadp_general_settings' ); $location = wp_get_object_terms( $post->ID, 'acadp_locations', array( 'fields' => 'ids' ) ); $location = count( $location ) ? $location[0] : $general_settings['default_location']; // Add a nonce field so we can check for it later wp_nonce_field( 'acadp_save_contact_details', 'acadp_contact_details_nonce' ); require_once ACADP_PLUGIN_DIR . 'admin/partials/listings/acadp-admin-contact-details-display.php'; } /** * Display a meta box to add images. * * @since 1.0.0 * @access public * * @param WP_Post $post WordPress Post object */ public function display_meta_box_listing_images( $post ) { $general_settings = get_option( 'acadp_general_settings' ); $post_meta = get_post_meta( $post->ID ); // Add a nonce field so we can check for it later wp_nonce_field( 'acadp_save_listing_images', 'acadp_listing_images_nonce' ); require_once ACADP_PLUGIN_DIR . 'admin/partials/listings/acadp-admin-listing-images-display.php'; } /** * Display a meta box to add video. * * @since 1.0.0 * @access public * * @param WP_Post $post WordPress Post object */ public function display_meta_box_listing_video( $post ) { $general_settings = get_option( 'acadp_general_settings' ); $post_meta = get_post_meta( $post->ID ); // Add a nonce field so we can check for it later wp_nonce_field( 'acadp_save_listing_video', 'acadp_listing_video_nonce' ); require_once ACADP_PLUGIN_DIR . 'admin/partials/listings/acadp-admin-listing-video-display.php'; } /** * Display custom fields. * * @since 1.0.0 * @access public * * @param int $post_id Post ID. */ public function ajax_callback_custom_fields( $post_id = 0 ) { $ajax = false; $terms = array(); if ( isset( $_POST['terms'] ) ) { check_ajax_referer( 'acadp_ajax_nonce', 'security' ); $ajax = true; $post_id = (int) $_POST['post_id']; $terms = is_array( $_POST['terms'] ) ? array_map( 'intval', $_POST['terms'] ) : (int) $_POST['terms']; } else { $post_id = (int) $post_id; if ( $post_id > 0 ) { $terms = wp_get_object_terms( $post_id, 'acadp_categories', array( 'fields' => 'ids' ) ); } } // Get post meta for the given post_id $post_meta = get_post_meta( $post_id ); // Get custom fields $custom_field_ids = acadp_get_custom_field_ids( $terms ); if ( ! empty( $custom_field_ids ) ) { $args = array( 'post_type' => 'acadp_fields', 'posts_per_page' => 500, 'post__in' => $custom_field_ids, 'no_found_rows' => true, 'update_post_term_cache' => false, 'meta_key' => 'order', 'orderby' => 'meta_value_num', 'order' => 'ASC', ); $acadp_query = new WP_Query( $args ); // Start the Loop global $post; // Process output ob_start(); include( ACADP_PLUGIN_DIR . 'admin/partials/listings/acadp-admin-custom-fields-display.php' ); wp_reset_postdata(); // Restore global post data stomped by the_post() $output = ob_get_clean(); print $output; } if ( $ajax ) { wp_die(); } } /** * Delete attachments. * * @since 1.0.0 * @access public */ public function before_delete_post( $post_id ) { global $post_type; if ( 'acadp_listings' != $post_type ) { return; } $images = get_post_meta( $post_id, 'images', true ); if( ! empty( $images ) ) { foreach( $images as $image ) { wp_delete_attachment( $image, true ); } } } /** * Save meta data. * * @since 1.0.0 * @access public * * @param int $post_id Post ID. * @param post $post The post object. * @return int $post_id If the save was successful or not. */ public function save_meta_data( $post_id, $post ) { if( ! isset( $_POST['post_type'] ) ) { return $post_id; } // Check this is the "acadp_listings" custom post type if( 'acadp_listings' != $post->post_type ) { return $post_id; } // If this is an autosave, our form has not been submitted, so we don't want to do anything if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) { return $post_id; } // Check the logged in user has permission to edit this post if( ! acadp_current_user_can( 'edit_acadp_listing', $post_id ) ) { return $post_id; } // Check if "acadp_listing_submitbox_nonce" nonce is set if( isset( $_POST['acadp_listing_submitbox_nonce'] ) ) { // Verify that the nonce is valid if( wp_verify_nonce( $_POST['acadp_listing_submitbox_nonce'], 'acadp_save_listing_submitbox' ) ) { // OK to save meta data if( isset( $_POST['acadp_aa'] ) ) { $date = array( 'year' => $_POST['acadp_aa'], 'month' => $_POST['acadp_mm'], 'day' => $_POST['acadp_jj'], 'hour' => $_POST['acadp_hh'], 'min' => $_POST['acadp_mn'] ); $expiry_date = acadp_mysql_date_format( $date ); update_post_meta( $post_id, 'expiry_date', $expiry_date ); } else if( 'publish' == $post->post_status ) { $expiry_date = acadp_listing_expiry_date( $post_id ); update_post_meta( $post->ID, 'expiry_date', $expiry_date ); } if( isset( $_POST['never_expires'] ) ) { update_post_meta( $post_id, 'never_expires', 1 ); } else { delete_post_meta( $post_id, 'never_expires' ); } $featured = isset( $_POST['featured'] ) ? 1 : 0; update_post_meta( $post_id, 'featured', $featured ); if( isset( $_POST['listing_status'] ) ) { $listing_status = sanitize_text_field( $_POST['listing_status'] ); update_post_meta( $post_id, 'listing_status', $listing_status ); } } } // Check if "acadp_listing_details_nonce" nonce is set if( isset( $_POST['acadp_listing_details_nonce'] ) ) { // Verify that the nonce is valid if( wp_verify_nonce( $_POST['acadp_listing_details_nonce'], 'acadp_save_listing_details' ) ) { // OK to save meta data $cat_ids = array_map( 'intval', (array) $_POST['acadp_category'] ); $cat_ids = array_unique( $cat_ids ); wp_set_object_terms( $post_id, null, 'acadp_categories' ); wp_set_object_terms( $post_id, $cat_ids, 'acadp_categories', true ); if( isset( $_POST['price'] ) ) { $price = acadp_sanitize_amount( $_POST['price'] ); update_post_meta( $post_id, 'price', $price ); } if( isset( $_POST['acadp_fields'] ) ) { foreach( $_POST['acadp_fields'] as $key => $value ) { $type = get_post_meta( $key, 'type', true ); switch( $type ) { case 'text' : $value = sanitize_text_field( $value ); break; case 'textarea' : $value = esc_textarea( $value ); break; case 'select' : case 'radio' : $value = sanitize_text_field( $value ); break; case 'checkbox' : $value = array_map( 'esc_attr', $value ); $value = implode( "\n", array_filter( $value ) ); break; case 'url' : $value = esc_url_raw( $value ); break; default : $value = sanitize_text_field( $value ); } update_post_meta( $post_id, $key, $value ); } } $views = (int) $_POST['views']; update_post_meta( $post_id, 'views', $views ); } } // Check if "acadp_contact_details_nonce" nonce is set if( isset( $_POST['acadp_contact_details_nonce'] ) ) { // Verify that the nonce is valid if( wp_verify_nonce( $_POST['acadp_contact_details_nonce'], 'acadp_save_contact_details' ) ) { // OK to save meta data $address = esc_textarea( $_POST['address'] ); update_post_meta( $post_id, 'address', $address ); wp_set_object_terms( $post_id, (int) $_POST['acadp_location'], 'acadp_locations' ); $zipcode = sanitize_text_field( $_POST['zipcode'] ); update_post_meta( $post_id, 'zipcode', $zipcode ); $phone = sanitize_text_field( $_POST['phone'] ); update_post_meta( $post_id, 'phone', $phone ); $email = sanitize_email( $_POST['email'] ); update_post_meta( $post_id, 'email', $email ); $website = esc_url_raw( $_POST['website'] ); update_post_meta( $post_id, 'website', $website ); $latitude = isset( $_POST['latitude'] ) ? sanitize_text_field( $_POST['latitude'] ) : ''; update_post_meta( $post_id, 'latitude', $latitude ); $longitude = isset( $_POST['longitude'] ) ? sanitize_text_field( $_POST['longitude'] ) : ''; update_post_meta( $post_id, 'longitude', $longitude ); $hide_map = isset( $_POST['hide_map'] ) ? (int) $_POST['hide_map'] : 0; update_post_meta( $post_id, 'hide_map', $hide_map ); } } // Check if "acadp_listing_images_nonce" nonce is set if( isset( $_POST['acadp_listing_images_nonce'] ) ) { // Verify that the nonce is valid if( wp_verify_nonce( $_POST['acadp_listing_images_nonce'], 'acadp_save_listing_images' ) ) { if( isset( $_POST['images'] ) ) { // OK to save meta data $images = array_filter( $_POST['images'] ); $images = array_map( 'intval', $images ); if( count( $images ) ) { update_post_meta( $post_id, 'images', $images ); set_post_thumbnail( $post_id, $images[0] ); } else { delete_post_meta( $post_id, 'images' ); delete_post_thumbnail( $post_id ); } } else { // Nothing received, all fields are empty, delete option delete_post_meta( $post_id, 'images' ); delete_post_thumbnail( $post_id ); } } } // Check if "acadp_listing_video_nonce" nonce is set if( isset( $_POST['acadp_listing_video_nonce'] ) ) { // Verify that the nonce is valid if( wp_verify_nonce( $_POST['acadp_listing_video_nonce'], 'acadp_save_listing_video' ) ) { if( isset( $_POST['video'] ) ) { $video = esc_url_raw( $_POST['video'] ); update_post_meta( $post_id, 'video', $video ); } } } return $post_id; } /** * Notify listing owner when his listing approved/published. * * @since 1.0.0 * @access public * * @param string $new_status Transition to this post status. * @param string $old_status Previous post status. * @param WP_Post $post Post data. */ public function transition_post_status( $new_status, $old_status, $post ) { if( 'acadp_listings' !== $post->post_type ) { return; } // Check if we are transitioning from pending to publish if( 'pending' == $old_status && 'publish' == $new_status ) { acadp_email_listing_owner_listing_approved( $post->ID ); } // Check if we are transitioning from private to publish if( 'private' == $old_status && 'publish' == $new_status ) { $listing_status = get_post_meta( $post->ID, 'listing_status', true ); if( 'expired' == $listing_status ) { update_post_meta( $post->ID, 'listing_status', 'post_status' ); unset( $_POST['acadp_aa'] ); unset( $_POST['listing_status'] ); } } } /** * Add custom filter options. * * @since 1.0.0 * @access public */ public function restrict_manage_posts() { global $typenow, $wp_query; if( 'acadp_listings' == $typenow ) { $general_settings = get_option( 'acadp_general_settings' ); $featured_settings = get_option( 'acadp_featured_listing_settings' ); // Restrict by location if( ! empty( $general_settings['has_location'] ) ) { $base_location = max( 0, $general_settings['base_location'] ); wp_dropdown_categories(array( 'show_option_none' => __( "All Locations", 'advanced-classifieds-and-directory-pro' ), 'option_none_value' => $base_location, 'child_of' => $base_location, 'taxonomy' => 'acadp_locations', 'name' => 'acadp_locations', 'orderby' => 'name', 'selected' => isset( $wp_query->query['acadp_locations'] ) ? $wp_query->query['acadp_locations'] : '', 'hierarchical' => true, 'depth' => 3, 'show_count' => false, 'hide_empty' => false, )); } // Restrict by category wp_dropdown_categories(array( 'show_option_none' => __( "All Categories", 'advanced-classifieds-and-directory-pro' ), 'option_none_value' => 0, 'taxonomy' => 'acadp_categories', 'name' => 'acadp_categories', 'orderby' => 'name', 'selected' => isset( $wp_query->query['acadp_categories'] ) ? $wp_query->query['acadp_categories'] : '', 'hierarchical' => true, 'depth' => 3, 'show_count' => false, 'hide_empty' => false, )); // Restrict by featured $has_featured = apply_filters( 'acadp_has_featured', isset( $featured_settings['enabled'] ) ); if( $has_featured ) { $featured = isset( $_GET['featured'] ) ? $_GET['featured'] : 0; echo ''; } } } /** * Parse a query string and filter listings accordingly. * * @since 1.0.0 * @access public * * @param WP_Query $query WordPress Query object */ public function parse_query( $query ) { global $pagenow, $post_type; if( 'edit.php' == $pagenow && 'acadp_listings' == $post_type ) { // Convert location id to taxonomy term in query if( isset( $query->query_vars['acadp_locations'] ) && ctype_digit( $query->query_vars['acadp_locations'] ) && $query->query_vars['acadp_locations'] != 0 ) { $term = get_term_by( 'id', $query->query_vars['acadp_locations'], 'acadp_locations' ); $query->query_vars['acadp_locations'] = $term->slug; } // Convert category id to taxonomy term in query if( isset( $query->query_vars['acadp_categories'] ) && ctype_digit( $query->query_vars['acadp_categories'] ) && $query->query_vars['acadp_categories'] != 0 ) { $term = get_term_by( 'id', $query->query_vars['acadp_categories'], 'acadp_categories' ); $query->query_vars['acadp_categories'] = $term->slug; } // Set featured meta in query if( isset( $_GET['featured'] ) && 1 == $_GET['featured'] ) { $query->query_vars['meta_key'] = 'featured'; $query->query_vars['meta_value'] = 1; } } } /** * Retrieve the table columns. * * @since 1.0.0 * @access public * * @param array $columns Array of default table columns. * @return array $columns Updated list of table columns. */ public function get_columns( $columns ) { $general_settings = get_option( 'acadp_general_settings' ); $featured_settings = get_option( 'acadp_featured_listing_settings' ); $new_columns = array( 'views' => __( 'Views', 'advanced-classifieds-and-directory-pro' ) ); $has_featured = apply_filters( 'acadp_has_featured', isset( $featured_settings['enabled'] ) ); if( $has_featured ) { $new_columns['featured'] = __( 'Featured', 'advanced-classifieds-and-directory-pro' ); } $new_columns['posted_date'] = __( 'Posted Date', 'advanced-classifieds-and-directory-pro' ); $new_columns['expiry_date'] = __( 'Expires on', 'advanced-classifieds-and-directory-pro' ); $new_columns['status'] = __( 'Status', 'advanced-classifieds-and-directory-pro' ); unset( $columns['date'] ); $taxonomy_column = 'taxonomy-acadp_categories'; return acadp_array_insert_after( $taxonomy_column, $columns, $new_columns ); } /** * This function renders the custom columns in the list table. * * @since 1.0.0 * @access public * * @param string $column The name of the column. * @param string $post_id Post ID. */ public function custom_column_content( $column, $post_id ) { switch ( $column ) { case 'views' : echo get_post_meta( $post_id, 'views', true ); break; case 'featured' : $value = get_post_meta( $post_id, 'featured', true ); echo ''.($value == 1 ? '✓' : '✗').''; break; case 'posted_date' : printf( _x( '%s ago', '%s = human-readable time difference', 'advanced-classifieds-and-directory-pro' ), human_time_diff( get_the_time( 'U', $post_id ), current_time( 'timestamp' ) ) ); break; case 'expiry_date' : $never_expires = get_post_meta( $post_id, 'never_expires', true ); if( ! empty( $never_expires ) ) { _e( 'Never Expires', 'advanced-classifieds-and-directory-pro' ); } else { $expiry_date = get_post_meta( $post_id, 'expiry_date', true ); if( ! empty( $expiry_date ) ) { echo date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $expiry_date ) ); } else { echo '-'; } } break; case 'status' : $listing_status = get_post_meta( $post_id, 'listing_status', true ); echo ( empty( $listing_status ) || 'post_status' == $listing_status ) ? get_post_status( $post_id ) : $listing_status; break; } } /** * Remove quick edit. * * @since 1.0.0 * @access public * * @param array $actions An array of row action links. * @param WP_Post $post The post object. * @return array $actions Updated array of row action links. */ public function remove_row_actions( $actions, $post ) { global $current_screen; if( $current_screen->post_type != 'acadp_listings' ) return $actions; unset( $actions['view'] ); unset( $actions['inline hide-if-no-js'] ); return $actions; } }