$post_id, 'post_status' => 'archive', ); wp_update_post($updated_post); } $redirect_to = add_query_arg('bulk_archived_posts', count($post_ids), $redirect_to); } elseif ($doaction === 'unarchive') { foreach ($post_ids as $post_id) { // Check permissions if (!current_user_can('edit_post', $post_id)) { continue; } // Update the post status to 'publish' (or whatever the original status should be) $updated_post = array( 'ID' => $post_id, 'post_status' => 'publish', ); wp_update_post($updated_post); } $redirect_to = add_query_arg('bulk_unarchived_posts', count($post_ids), $redirect_to); } return $redirect_to; } public function register_bulk_action_move_to_archive( $bulk_actions ) { global $post_status; // Define our custom actions $custom_actions = array(); if ($post_status === 'archive') { $custom_actions['unarchive'] = __('Unarchive', 'propertyhive'); } else { $custom_actions['move_to_archive'] = __('Move to Archive', 'propertyhive'); } // Check if 'trash' exists and insert custom actions before it if (isset($bulk_actions['trash'])) { $new_actions = array(); foreach ($bulk_actions as $key => $value) { if ($key === 'trash') { $new_actions = array_merge($new_actions, $custom_actions); } $new_actions[$key] = $value; } return $new_actions; } elseif (isset($bulk_actions['untrash'])) { $new_actions = array(); foreach ($bulk_actions as $key => $value) { if ($key === 'untrash') { $new_actions = array_merge($new_actions, $custom_actions); } $new_actions[$key] = $value; } return $new_actions; } else { // If 'trash' doesn't exist, append custom actions at the end return array_merge($bulk_actions, $custom_actions); } } public function modify_post_row_actions_for_archived( $actions, $post ) { // Define the post types that can be archived $post_types = array('property', 'contact', 'appraisal', 'viewing', 'offer', 'sale', 'tenancy', 'key_date'); $post_types = apply_filters('propertyhive_post_types_with_archive', $post_types); // Check if the current post type is in the allowed post types and if the post is archived if ( in_array($post->post_type, $post_types) && $post->post_status == 'archive' ) { // Remove the "View" link if (isset($actions['view'])) { unset($actions['view']); } // Add the "Unarchive" link $unarchive_url = wp_nonce_url(admin_url('post.php?post=' . $post->ID . '&action=unarchive&return=archive'), 'unarchive-post_' . $post->ID); $actions['unarchive'] = '' . __('Unarchive', 'propertyhive') . ''; } return $actions; } public function adjust_post_status_views( $views ) { if (isset($views['archive'])) { $archive = $views['archive']; unset($views['archive']); $new_views = array(); $bin_exists = false; foreach ($views as $key => $view) { if ($key === 'trash') { $bin_exists = true; $new_views['archive'] = $archive; } $new_views[$key] = $view; } // Ensure 'archive' is added to the end if 'trash' is not present if (!$bin_exists) { $new_views['archive'] = $archive; } return $new_views; } return $views; } public function handle_archive_action() { // Check if the action and nonce are set and valid if ( !isset($_GET['action']) || $_GET['action'] !== 'archive_single' ) return; $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0; $post_type = get_post_type($post_id); if ( !wp_verify_nonce($_GET['_wpnonce'], 'archive-post_' . $post_id) ) { wp_die(esc_html(__('Security check failed.', 'propertyhive'))); } if ( !current_user_can('edit_post', $post_id) ) { wp_die(esc_html(__('You do not have permission to edit this post.', 'propertyhive'))); } // Update the post status to 'archive' $updated_post = array( 'ID' => $post_id, 'post_status' => 'archive', ); $result = wp_update_post($updated_post, true); if ( is_wp_error($result) ) { wp_die(esc_html(__('An error occurred while archiving the post.', 'propertyhive'))); } // Redirect to the main list of contacts wp_redirect(admin_url('edit.php?post_type=' . $post_type)); exit; } public function handle_unarchive_action() { // Check if the action and nonce are set and valid if ( !isset($_GET['action']) || $_GET['action'] !== 'unarchive_single' ) return; $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0; $post_type = get_post_type($post_id); if ( !wp_verify_nonce($_GET['_wpnonce'], 'unarchive-post_' . $post_id) ) { wp_die(esc_html(__('Security check failed.', 'propertyhive'))); } if ( !current_user_can('edit_post', $post_id) ) { wp_die(esc_html(__('You do not have permission to edit this post.', 'propertyhive'))); } // Update the post status to 'publish' $updated_post = array( 'ID' => $post_id, 'post_status' => 'publish', ); $result = wp_update_post($updated_post, true); if ( is_wp_error($result) ) { wp_die(esc_html(__('An error occurred while unarchiving the post.', 'propertyhive'))); } // Redirect to the main list of contacts if ( isset($_GET['return']) && $_GET['return'] === 'archive' ) { wp_redirect(admin_url('edit.php?post_status=archive&post_type=' . get_post_type($post_id))); } else { wp_redirect(admin_url('edit.php?post_type=' . get_post_type($post_id))); } exit; } /** * Conditonally load classes and functions only needed when viewing a post type. */ public function include_post_type_handlers() { include( 'post-types/class-ph-admin-header-stripes.php' ); include( 'post-types/class-ph-admin-meta-boxes.php' ); include( 'post-types/class-ph-admin-cpt-property.php' ); include( 'post-types/class-ph-admin-cpt-contact.php' ); include( 'post-types/class-ph-admin-cpt-enquiry.php' ); include( 'post-types/class-ph-admin-cpt-office.php' ); include( 'post-types/class-ph-admin-cpt-appraisal.php' ); include( 'post-types/class-ph-admin-cpt-viewing.php' ); include( 'post-types/class-ph-admin-cpt-offer.php' ); include( 'post-types/class-ph-admin-cpt-sale.php' ); include( 'post-types/class-ph-admin-cpt-tenancy.php' ); include( 'post-types/class-ph-admin-cpt-key-date.php' ); } /** * Change messages when a post type is updated. * * @param array $messages * @return array */ public function post_updated_messages( $messages ) { global $post, $post_ID; $messages['property'] = array( 0 => '', // Unused. Messages start at index 1. /* translators: %s: URL to view the property */ 1 => sprintf( __( 'Property updated. View property', 'propertyhive' ), esc_url( get_permalink($post_ID) ) ), 2 => __( 'Custom field updated.', 'propertyhive' ), 3 => __( 'Custom field deleted.', 'propertyhive' ), 4 => __( 'Property updated.', 'propertyhive' ), 5 => __( 'Revision restored.', 'propertyhive' ), /* translators: %s: URL to view the property */ 6 => sprintf( __( 'Property published. View property', 'propertyhive' ), esc_url( get_permalink($post_ID) ) ), 7 => __( 'Property saved.', 'propertyhive' ), /* translators: %s: URL to preview the property */ 8 => sprintf( __( 'Property submitted. Preview property', 'propertyhive' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), /* translators: 1: formatted date, 2: URL to preview the property */ 9 => sprintf( __( 'Property scheduled for: %1$s. Preview property', 'propertyhive' ), date_i18n( __( 'M j, Y @ G:i', 'propertyhive' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ), /* translators: %s: URL to preview the property */ 10 => sprintf( __( 'Property draft updated. Preview property', 'propertyhive' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), ); $messages['contact'] = array( 0 => '', // Unused. Messages start at index 1. 1 => __( 'Contact updated.', 'propertyhive' ), 2 => __( 'Custom field updated.', 'propertyhive' ), 3 => __( 'Custom field deleted.', 'propertyhive' ), 4 => __( 'Contact updated.', 'propertyhive' ), 5 => __( 'Revision restored.', 'propertyhive' ), 6 => __( 'Contact published.', 'propertyhive' ), 7 => __( 'Contact saved.', 'propertyhive' ), 8 => __( 'Contact submitted.', 'propertyhive' ), /* translators: 1: formatted date */ 9 => sprintf( __( 'Contact scheduled for: %1$s.', 'propertyhive' ), date_i18n( __( 'M j, Y @ G:i', 'propertyhive' ), strtotime( $post->post_date ) )), 10 => __( 'Contact draft updated.', 'propertyhive' ), ); $messages['office'] = array( 0 => '', // Unused. Messages start at index 1. 1 => __( 'Office updated.', 'propertyhive' ), 2 => __( 'Custom field updated.', 'propertyhive' ), 3 => __( 'Custom field deleted.', 'propertyhive' ), 4 => __( 'Office updated.', 'propertyhive' ), 5 => __( 'Revision restored.', 'propertyhive' ), 6 => sprintf( __( 'Office published.', 'propertyhive' ), esc_url( get_permalink($post_ID) ) ), 7 => __( 'Office saved.', 'propertyhive' ), 8 => sprintf( __( 'Office submitted.', 'propertyhive' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), /* translators: 1: formatted date */ 9 => sprintf( __( 'Office scheduled for: %1$s.', 'propertyhive' ), date_i18n( __( 'M j, Y @ G:i', 'propertyhive' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ), 10 => sprintf( __( 'Office draft updated. ', 'propertyhive' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), ); $messages['enquiry'] = array( 0 => '', // Unused. Messages start at index 1. 1 => sprintf( __( 'Enquiry updated.', 'propertyhive' ), esc_url( get_permalink($post_ID) ) ), 2 => __( 'Custom field updated.', 'propertyhive' ), 3 => __( 'Custom field deleted.', 'propertyhive' ), 4 => __( 'Enquiry updated.', 'propertyhive' ), 5 => __( 'Revision restored.', 'propertyhive' ), 6 => sprintf( __( 'Enquiry published.', 'propertyhive' ), esc_url( get_permalink($post_ID) ) ), 7 => __( 'Enquiry saved.', 'propertyhive' ), 8 => sprintf( __( 'Enquiry submitted.', 'propertyhive' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), /* translators: 1: formatted date */ 9 => sprintf( __( 'Enquiry scheduled for: %1$s.', 'propertyhive' ), date_i18n( __( 'M j, Y @ G:i', 'propertyhive' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ), 10 => sprintf( __( 'Enquiry draft updated.', 'propertyhive' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), ); return $messages; } /** * Remove month filter from some property hive pages */ public function remove_month_filter() { global $typenow; $post_types_to_hide_months_dropdown = array('property', 'contact', 'enquiry', 'appraisal', 'viewing', 'offer', 'sale', 'tenancy', 'key_date'); $post_types_to_hide_months_dropdown = apply_filters( 'propertyhive_post_types_to_hide_months_dropdown', $post_types_to_hide_months_dropdown ); if ( in_array($typenow, $post_types_to_hide_months_dropdown) ) { add_filter('months_dropdown_results', '__return_empty_array'); } } /** * Disable the auto-save functionality for certain CPT's. * * @access public * @return void */ public function disable_autosave(){ /*global $post; if ( $post && get_post_type( $post->ID ) === 'enquiry' ) { wp_dequeue_script( 'autosave' ); }*/ } /** * Filters for post types */ public function restrict_manage_posts() { global $typenow, $wp_query; switch ( $typenow ) { case 'property' : $this->property_filters(); break; case 'contact' : $this->contact_filters(); break; case 'enquiry' : $this->enquiry_filters(); break; case 'appraisal' : $this->appraisal_filters(); break; case 'viewing' : $this->viewing_filters(); break; case 'offer' : $this->offer_filters(); break; case 'sale' : $this->sale_filters(); break; case 'tenancy' : $this->tenancy_filters(); break; case 'key_date' : $this->key_date_filters(); break; default : break; } } /** * Show a property filter box */ public function property_filters() { global $wp_query; // Department filtering $output = ''; $output .= $this->property_department_filter(); $output .= $this->property_marketing_filter(); $output .= $this->property_availability_filter(); $output .= $this->property_location_filter(); $output .= $this->property_office_filter(); $output .= $this->negotiator_filter(); echo apply_filters( 'propertyhive_property_filters', $output ); } /** * Show a property department filter box */ public function property_department_filter() { global $wp_query; $departments = ph_get_departments(); $selected_department = isset( $_GET['_department'] ) && in_array( $_GET['_department'], array_keys($departments) ) ? $_GET['_department'] : ''; // Department filtering $output = ''; return $output; } /** * Show a property office filter box */ public function property_office_filter() { global $wp_query, $post; // Department filtering $output = ''; return $output; } /** * Show a negotiator filter box */ public function negotiator_filter() { return wp_dropdown_users(array( 'name' => '_negotiator_id', 'id' => 'dropdown_property_negotiator_id', 'show_option_all' => __( 'All Negotiators', 'propertyhive' ), 'selected' => empty( $_GET['_negotiator_id'] ) ? '' : (int)$_GET['_negotiator_id'], 'echo' => false, 'role__not_in' => apply_filters( 'property_negotiator_exclude_roles', array('property_hive_contact', 'subscriber') ) )); } /** * Show a date range selector */ public function date_range_filter() { $date_range_label = empty( $_GET['_date_range_label'] ) ? __( 'Any Time', 'propertyhive' ) : $_GET['_date_range_label']; // The date picker doesn't have a concept of 'Any Time', so valid dates must be used // I've used the last and first date of the month (reversed) as it's a range that is not selectable, but is within the current month // If I used an already labelled date range (e.g. 'Today'), it would show as 'Today' when selected // If I use a nearby date range (e.g. 'Yesterday'), if someone actually selected that range it would show as 'Any Time' // If I use a unlikely date range (e.g. 01-01-1970 - 31-12-2070), the custom date range picker would open showing Jan 1970. $date_range_from = empty( $_GET['_date_range_from'] ) ? date('Y-m-d', strtotime('last day of this month')) : $_GET['_date_range_from']; $date_range_to = empty( $_GET['_date_range_to'] ) ? date('Y-m-d', strtotime('first day of this month')) : $_GET['_date_range_to']; return " "; } /** * Show a property location filter box */ public function property_location_filter() { global $wp_query, $post; // Department filtering $output = ''; return $output; } /** * Show a property availability filter box */ public function property_availability_filter() { global $wp_query, $post; // Availability filtering $output = ''; return $output; } /** * Show a property marketing filter box */ public function property_marketing_filter() { global $wp_query, $post; // Availability filtering $output = ''; return $output; } /** * Show a contact filter box */ public function contact_filters() { global $wp_query; $selected_contact_type = isset( $_GET['_contact_type'] ) && in_array( $_GET['_contact_type'], array( 'owner', 'potentialowner', 'applicant', 'hotapplicant', 'thirdparty' ) ) ? ph_clean($_GET['_contact_type']) : ''; // Type filtering $options = array(); // Owners $option = '