PluginProbe
Property Hive / 2.3.1
Property Hive v2.3.1
2.3.1 2.3.0 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 1.4.46 1.4.47 1.4.48 1.4.49 1.4.5 1.4.50 1.4.51 1.4.52 1.4.53 1.4.54 1.4.55 1.4.56 1.4.57 1.4.58 1.4.59 1.4.6 1.4.60 1.4.61 All 261 releases
propertyhive / includes / admin / post-types / class-ph-admin-cpt-key-date.php

class-ph-admin-cpt-key-date.php in Property Hive 2.3.1, at includes/admin/post-types/class-ph-admin-cpt-key-date.php

317 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly
4 }
5
6 if ( ! class_exists( 'PH_Admin_CPT' ) ) {
7 include( 'class-ph-admin-cpt.php' );
8 }
9
10 if ( ! class_exists( 'PH_Admin_CPT_Key_Date' ) )
11 {
12 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Admin_CPT_Key_Date; preserving the existing PH_* class name is required for plugin and extension compatibility.
13 class PH_Admin_CPT_Key_Date extends PH_Admin_CPT {
14
15 public function __construct() {
16 $this->type = 'key_date';
17
18 add_filter( 'manage_edit-key_date_columns', array( $this, 'edit_columns' ) );
19 add_action( 'manage_key_date_posts_custom_column', array( $this, 'custom_columns' ) );
20 add_filter( 'list_table_primary_column', array( $this, 'set_primary_column' ), 10, 2 );
21 add_filter( 'post_row_actions', array( $this, 'remove_actions' ), 10, 2 );
22 add_filter( 'manage_edit-key_date_sortable_columns', array( $this, 'sortable_columns' ) );
23 add_filter( 'request', array( $this, 'custom_sorts' ) );
24 add_action( 'quick_edit_custom_box', array( $this, 'key_date_custom_quick_edit_box' ), 10, 3 );
25 add_action( 'save_post', array( $this, 'save_key_date' ) );
26
27 add_filter( 'bulk_actions-edit-key_date', array( $this, 'remove_bulk_actions') );
28
29 parent::__construct();
30 }
31
32 function key_date_custom_quick_edit_box( $column_name, $post_type, $taxonomy ) {
33 global $post;
34
35 if ($post_type == 'key_date' && $column_name == 'description')
36 {
37 wp_nonce_field( 'propertyhive-save-key-date', 'propertyhive_key_date_nonce' );
38 ?>
39 <fieldset class="inline-edit-col-left inline-edit-ph inline-edit-key_date">
40 <legend class="inline-edit-legend">Quick Edit</legend>
41 <div class="inline-edit-col">
42 <label>
43 <span class="title">Description</span>
44 <span class="input-text-wrap">
45 <input type="text" name="_key_date_description" class="short" style="width:200px;" value="">
46 </span>
47 </label>
48 <label>
49 <span class="title">Property</span>
50 <span class="key_date-property"></span>
51 </label>
52 <label>
53 <span class="title">Status</span>
54 <span class="input-text-wrap">
55 <?php
56 $selected_value = get_post_meta( $post->ID, '_key_date_status', true );
57
58 $output = '<select name="_key_date_status">';
59
60 foreach ( array( 'pending', 'booked', 'complete', 'on_hold', 'cancelled' ) as $status )
61 {
62 $output .= '<option value="' . esc_attr($status) . '"';
63 $output .= selected($status, $selected_value, false );
64 $output .= '>' . esc_html(ucwords(str_replace("_", " ", $status))) . '</option>';
65 }
66
67 $output .= '</select>';
68
69 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Select markup is assembled above with fixed status values, escaped labels/values and core selected().
70 echo $output;
71 ?>
72 </span>
73 </label>
74 <label id="book_next_key_date_label" style="display: none;">
75 Book next key date?&nbsp;&nbsp;<input type="checkbox" id="book_next_key_date_checkbox" name="book_next_key_date" >
76 </label>
77 <label id="next_date_due_label" style="display: none;">
78 <span class="title">Next Date</span>
79 <span class="input-text-wrap">
80 <input type="text" id="next_date_due" name="next_date_due" class="short" placeholder="yyyy-mm-dd" style="width:120px;" value="">
81 </span>
82 </label>
83 </div>
84 </fieldset>
85 <?php
86 }
87 }
88
89 /**
90 * Change the columns shown in admin.
91 */
92 public function edit_columns( $existing_columns ) {
93
94 if ( empty( $existing_columns ) && ! is_array( $existing_columns ) )
95 {
96 $existing_columns = array();
97 }
98
99 unset( $existing_columns['title'], $existing_columns['comments'], $existing_columns['date'] );
100
101 $columns = array();
102 $columns['cb'] = '<input type="checkbox" />';
103 $columns['description'] = __( 'Description', 'propertyhive' );
104 $columns['notes'] = __( 'Notes', 'propertyhive' );
105 $columns['property'] = __( 'Property', 'propertyhive' );
106 $columns['tenants'] = __( 'Tenants', 'propertyhive' );
107 $columns['date_due'] = __( 'Date Due', 'propertyhive' );
108 $columns['status'] = __( 'Status', 'propertyhive' );
109
110 return array_merge( $columns, $existing_columns );
111 }
112
113 /**
114 * Define our custom columns shown in admin.
115 *
116 * @param string $column
117 */
118 public function custom_columns( $column ) {
119 global $post;
120
121 $key_date = new PH_Key_Date( $post );
122 $property = $key_date->property();
123 $tenancy = $key_date->tenancy();
124
125 switch ( $column ) {
126
127 case 'description' :
128
129 $post_type_object = get_post_type_object( $post->post_type );
130
131 echo '<div class="cell-main-content">';
132 $opening_link_tag = false;
133 if ( !empty($key_date->tenancy_id) )
134 {
135 echo '<a href="' . esc_url(get_edit_post_link((int)$key_date->tenancy_id)) . '#propertyhive-tenancy-management%7Cpropertyhive-management-dates">';
136 $opening_link_tag = true;
137 }
138 else
139 {
140 if ( !empty($key_date->property_id) )
141 {
142 echo '<a href="' . esc_url(get_edit_post_link((int)$key_date->property_id)) . '#propertyhive-property-tenancies%7Cpropertyhive-management-dates">';
143 $opening_link_tag = true;
144 }
145 }
146 echo esc_html( $key_date->description() ) . ( $opening_link_tag ? '</a>' : '' ) . '</div>';
147 echo '<div class="row-actions">';
148 break;
149
150 case 'notes' :
151 echo '<div class="cell-main-content">' . ( !empty($key_date->notes()) ? nl2br( esc_html( $key_date->notes() ) ) : '-' ) . '</div>';
152 break;
153
154 case 'property' :
155 echo '<div class="cell-main-content">' . esc_html($property->get_formatted_full_address()) . '</div>';
156 break;
157
158 case 'tenants' :
159 if ( $tenancy->id )
160 {
161 echo wp_kses_post( $tenancy->get_tenants(false, true) );
162 }
163 else
164 {
165 echo '-';
166 }
167 break;
168
169 case 'date_due' :
170 echo '<div class="cell-main-content">' . esc_html($key_date->date_due()->format( 'jS F Y' )) . '</div>';
171 break;
172
173 case 'status' :
174 echo '<div class="cell-main-content">' . esc_html(ucwords( $key_date->status() )) . '</div>';
175 break;
176
177 default :
178 break;
179 }
180 }
181
182 public function set_primary_column( $default, $screen ) {
183
184 if ( 'edit-key_date' === $screen )
185 {
186 $default = 'description';
187 }
188
189 return $default;
190 }
191
192 public function remove_actions($actions, $post) {
193
194 if ( $post->post_type !== 'key_date' )
195 {
196 return $actions;
197 }
198
199 if ( isset($actions['edit']) )
200 {
201 unset($actions['edit']);
202 }
203
204 return $actions;
205 }
206
207 public function sortable_columns( $columns ) {
208 $custom = array(
209 'date_due' => 'date_due',
210 );
211
212 return wp_parse_args( $custom, $columns );
213 }
214
215 function custom_sorts( $vars ) {
216
217 if ( ! isset( $vars['orderby'] ) )
218 {
219 return $vars;
220 }
221
222 switch ( $vars['orderby'] )
223 {
224 case 'date_due':
225 $vars['orderby'] = 'meta_value';
226 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- All these meta_key values are literal, supported CPT date/status/price keys used by paginated WordPress admin list ordering. Core admin post queries provide pagination; no arbitrary request key is copied into these lines.
227 $vars['meta_key'] = '_date_due';
228 break;
229 }
230
231 return $vars;
232 }
233
234 /**
235 * Remove bulk edit actions
236 * @param array $actions
237 */
238 public function remove_bulk_actions( $actions ) {
239 return array();
240 }
241
242 function save_key_date( $post_id ) {
243 if ( 'key_date' !== get_post_type( $post_id ) || wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
244 return;
245 }
246 if ( ! current_user_can( 'manage_propertyhive' ) || ! current_user_can( 'edit_post', $post_id ) ) {
247 return;
248 }
249 if ( empty( $_POST['propertyhive_key_date_nonce'] ) || ! is_string( $_POST['propertyhive_key_date_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['propertyhive_key_date_nonce'] ) ), 'propertyhive-save-key-date' ) ) {
250 return;
251 }
252 if ( ! isset( $_POST['post_ID'] ) || ! is_scalar( $_POST['post_ID'] ) || absint( $_POST['post_ID'] ) !== (int) $post_id ) {
253 return;
254 }
255 $status = isset( $_POST['_key_date_status'] ) && is_string( $_POST['_key_date_status'] ) ? sanitize_key( wp_unslash( $_POST['_key_date_status'] ) ) : '';
256 if ( ! in_array( $status, array( 'pending', 'booked', 'complete', 'on_hold', 'cancelled' ), true ) ) {
257 return;
258 }
259 $description = isset( $_POST['_key_date_description'] ) && is_string( $_POST['_key_date_description'] ) ? sanitize_text_field( wp_unslash( $_POST['_key_date_description'] ) ) : get_post_field( 'post_title', $post_id, 'raw' );
260 $next_date = isset( $_POST['next_date_due'] ) && is_string( $_POST['next_date_due'] ) ? sanitize_text_field( wp_unslash( $_POST['next_date_due'] ) ) : '';
261 $parsed_date = DateTimeImmutable::createFromFormat( '!Y-m-d', $next_date );
262
263 update_post_meta( $post_id, '_key_date_status', $status );
264
265 $existing_description = get_post_field( 'post_title', $post_id, 'raw' );
266
267 if ( '' !== $description && $description !== $existing_description )
268 {
269 $post_update = array(
270 'ID' => $post_id,
271 'post_title' => wp_slash( $description ),
272 );
273
274 remove_action( 'save_post', array( $this, 'save_key_date' ) );
275 wp_update_post( $post_update );
276 add_action( 'save_post', array( $this, 'save_key_date' ) );
277 }
278
279 if ( isset( $_POST['book_next_key_date'] ) && 'on' === $_POST['book_next_key_date'] && $parsed_date && $parsed_date->format( 'Y-m-d' ) === $next_date )
280 {
281 // Insert next key date record
282 $next_key_date_post = array(
283 'post_title' => wp_slash( $description ),
284 'post_content' => '',
285 'post_type' => 'key_date',
286 'post_status' => 'publish',
287 'comment_status' => 'closed',
288 'ping_status' => 'closed',
289 );
290
291 // Insert the post into the database
292 // Remove save_post hook temporarily to prevent it running again on wp_insert_post
293 remove_action( 'save_post', array( $this, 'save_key_date' ) );
294 $next_key_date_post_id = wp_insert_post( $next_key_date_post );
295 add_action( 'save_post', array( $this, 'save_key_date' ) );
296
297 if ( !is_wp_error($next_key_date_post_id) && $next_key_date_post_id != 0 )
298 {
299 add_post_meta( $next_key_date_post_id, '_date_due', $next_date );
300 add_post_meta( $next_key_date_post_id, '_key_date_status', 'pending' );
301 add_post_meta( $next_key_date_post_id, '_key_date_type_id', get_post_meta($post_id, '_key_date_type_id', true) );
302
303 if( metadata_exists('post', $post_id, '_property_id') ) {
304 add_post_meta( $next_key_date_post_id, '_property_id', get_post_meta($post_id, '_property_id', true) );
305 }
306
307 if( metadata_exists('post', $post_id, '_tenancy_id') ) {
308 add_post_meta( $next_key_date_post_id, '_tenancy_id', get_post_meta($post_id, '_tenancy_id', true) );
309 }
310 }
311 }
312 }
313 }
314 }
315
316 return new PH_Admin_CPT_Key_Date();
317