PluginProbe
Property Hive / trunk
Property Hive vtrunk
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 1.4.62 All 260 releases
← All changes | includes/ph-core-functions.php +319 -9 1.4.53trunk View file →
@@ -19,9 +19,9 @@
19 19 include( 'ph-page-functions.php' );
20 20 include( 'ph-property-functions.php' );
21 21
22 22 /**
23 - * Get template part (for templates like the single-product).
23 + * Get template part (for templates like the single-property).
24 24 *
25 25 * @access public
26 26 * @param mixed $slug
27 27 * @param string $name (default: '')
@@ -26,8 +26,9 @@
26 26 * @param mixed $slug
27 27 * @param string $name (default: '')
28 28 * @return void
29 29 */
30 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_template_part; the established callable name is part of the plugin/extension API and must remain stable.
30 31 function ph_get_template_part( $slug, $name = '' ) {
31 32 $template = '';
32 33
33 34 // Look in yourtheme/slug-name.php and yourtheme/propertyhive/slug-name.php
@@ -45,8 +46,9 @@
45 46 $template = locate_template( array( "{$slug}.php", PH()->template_path() . "{$slug}.php" ) );
46 47 }
47 48
48 49 // Allow 3rd party plugin filter template file from their plugin
50 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Existing public Property Hive extension hook ph_get_template_part; changing the established name would detach installed callbacks.
49 51 $template = apply_filters( 'ph_get_template_part', $template, $slug, $name );
50 52
51 53 if ( $template ) {
52 54 load_template( $template, false );
@@ -62,8 +64,9 @@
62 64 * @param string $template_path (default: '')
63 65 * @param string $default_path (default: '')
64 66 * @return void
65 67 */
68 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_template; the established callable name is part of the plugin/extension API and must remain stable.
66 69 function ph_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
67 70 if ( $args && is_array( $args ) ) {
68 71 extract( $args );
69 72 }
@@ -70,9 +73,9 @@
70 73
71 74 $located = ph_locate_template( $template_name, $template_path, $default_path );
72 75
73 76 if ( ! file_exists( $located ) ) {
74 - _doing_it_wrong( __FUNCTION__, sprintf( '<code>%s</code> does not exist.', $located ), '2.1' );
77 + _doing_it_wrong( __FUNCTION__, sprintf( '<code>%s</code> does not exist.', esc_html( $located ) ), '2.1' );
75 78 return;
76 79 }
77 80
78 81 do_action( 'propertyhive_before_template_part', $template_name, $template_path, $located, $args );
@@ -96,8 +99,9 @@
96 99 * @param string $template_path (default: '')
97 100 * @param string $default_path (default: '')
98 101 * @return string
99 102 */
103 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_locate_template; the established callable name is part of the plugin/extension API and must remain stable.
100 104 function ph_locate_template( $template_name, $template_path = '', $default_path = '' ) {
101 105 if ( ! $template_path ) {
102 106 $template_path = PH()->template_path();
103 107 }
@@ -130,12 +134,14 @@
130 134 * @param string $value Value of the cookie
131 135 * @param integer $expire Expiry of the cookie
132 136 * @param string $secure Whether the cookie should be served only over https
133 137 */
138 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_setcookie; the established callable name is part of the plugin/extension API and must remain stable.
134 139 function ph_setcookie( $name, $value, $expire = 0, $secure = false ) {
135 140 if ( ! headers_sent() ) {
136 141 return setcookie( $name, $value, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure );
137 142 } elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
143 + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Intentional developer notice, enabled only by WP_DEBUG, for a failed cookie API call; no request or private data is included.
138 144 trigger_error( "Cookie cannot be set - headers already sent", E_USER_NOTICE );
139 145 }
140 146 return false;
141 147 }
@@ -145,8 +151,9 @@
145 151 *
146 152 * @param mixed $image_size
147 153 * @return array
148 154 */
155 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_image_size; the established callable name is part of the plugin/extension API and must remain stable.
149 156 function ph_get_image_size( $image_size ) {
150 157 if ( is_array( $image_size ) ) {
151 158 $width = isset( $image_size[0] ) ? $image_size[0] : '300';
152 159 $height = isset( $image_size[1] ) ? $image_size[1] : '300';
@@ -169,10 +176,45 @@
169 176
170 177 return $size;
171 178 }
172 179
173 -function ph_get_departments()
180 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_custom_departments; the established callable name is part of the plugin/extension API and must remain stable.
181 +function ph_get_custom_departments( $active_only = true )
174 182 {
183 + $return = array();
184 +
185 + $custom_departments = get_option( 'propertyhive_custom_departments', array() );
186 +
187 + if ( is_array($custom_departments) && !empty($custom_departments) )
188 + {
189 + foreach ( $custom_departments as $key => $custom_department )
190 + {
191 + if ( !$active_only || ( $active_only && get_option('propertyhive_active_departments_' . $key) == 'yes' ) )
192 + {
193 + $return[$key] = $custom_department;
194 + }
195 + }
196 + }
197 +
198 + return $return;
199 +}
200 +
201 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_custom_department_based_on; the established callable name is part of the plugin/extension API and must remain stable.
202 +function ph_get_custom_department_based_on( $department )
203 +{
204 + $custom_departments = get_option( 'propertyhive_custom_departments', array() );
205 +
206 + if ( isset($custom_departments[$department]['based_on']) )
207 + {
208 + return $custom_departments[$department]['based_on'];
209 + }
210 +
211 + return false;
212 +}
213 +
214 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_departments; the established callable name is part of the plugin/extension API and must remain stable.
215 +function ph_get_departments( $raw = false )
216 +{
175 217 $departments = array(
176 218 'residential-sales' => __( 'Residential Sales', 'propertyhive' ),
177 219 'residential-lettings' => __( 'Residential Lettings', 'propertyhive' ),
178 220 'commercial' => __( 'Commercial', 'propertyhive' ),
@@ -177,11 +219,159 @@
177 219 'residential-lettings' => __( 'Residential Lettings', 'propertyhive' ),
178 220 'commercial' => __( 'Commercial', 'propertyhive' ),
179 221 );
180 222
181 - return apply_filters( 'propertyhive_departments', $departments );
223 + return $raw ? $departments : apply_filters( 'propertyhive_departments', $departments );
182 224 }
183 225
226 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_viewing_statuses; the established callable name is part of the plugin/extension API and must remain stable.
227 +function ph_get_viewing_statuses()
228 +{
229 + $viewing_statuses = array(
230 + 'pending' => __( 'Pending', 'propertyhive' ),
231 + 'confirmed' => '- ' . __( 'Confirmed', 'propertyhive' ),
232 + 'unconfirmed' => '- ' . __( 'Awaiting Confirmation', 'propertyhive' ),
233 + 'carried_out' => __( 'Carried Out', 'propertyhive' ),
234 + 'awaiting_feedback' => '- ' . __( 'Awaiting Feedback', 'propertyhive' ),
235 + 'feedback_passed_on' => '- ' . __( 'Feedback Passed On', 'propertyhive' ),
236 + 'feedback_not_passed_on' => '- ' . __( 'Feedback Not Passed On', 'propertyhive' ),
237 + 'cancelled' => __( 'Cancelled', 'propertyhive' ),
238 + 'no_show' => __( 'No Show', 'propertyhive' ),
239 + );
240 +
241 + return $viewing_statuses;
242 +}
243 +
244 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper add_viewing_status_meta_query; the established callable name is part of the plugin/extension API and must remain stable.
245 +function add_viewing_status_meta_query( $meta_query, $selected_status )
246 +{
247 + switch ( $selected_status )
248 + {
249 + case "confirmed":
250 + {
251 + $meta_query[] = array(
252 + 'key' => '_status',
253 + 'value' => 'pending',
254 + );
255 + $meta_query[] = array(
256 + 'key' => '_all_confirmed',
257 + 'value' => 'yes',
258 + );
259 + break;
260 + }
261 + case "unconfirmed":
262 + {
263 + $meta_query[] = array(
264 + 'key' => '_status',
265 + 'value' => 'pending',
266 + );
267 + $meta_query[] = array(
268 + 'relation' => 'OR',
269 + array(
270 + 'key' => '_all_confirmed',
271 + 'value' => '',
272 + ),
273 + array(
274 + 'key' => '_all_confirmed',
275 + 'compare' => 'NOT EXISTS',
276 + )
277 + );
278 + break;
279 + }
280 + case "awaiting_feedback":
281 + {
282 + $meta_query[] = array(
283 + 'key' => '_status',
284 + 'value' => 'carried_out',
285 + );
286 + $meta_query[] = array(
287 + 'key' => '_feedback_status',
288 + 'value' => '',
289 + );
290 + break;
291 + }
292 + case "feedback_passed_on":
293 + {
294 + $meta_query[] = array(
295 + 'key' => '_status',
296 + 'value' => 'carried_out',
297 + );
298 + $meta_query[] = array(
299 + 'key' => '_feedback_status',
300 + 'value' => array('interested', 'not_interested'),
301 + 'compare' => 'IN'
302 + );
303 + $meta_query[] = array(
304 + 'key' => '_feedback_passed_on',
305 + 'value' => 'yes',
306 + );
307 + break;
308 + }
309 + case "feedback_not_passed_on":
310 + {
311 + $meta_query[] = array(
312 + 'key' => '_status',
313 + 'value' => 'carried_out',
314 + );
315 + $meta_query[] = array(
316 + 'key' => '_feedback_status',
317 + 'value' => array('interested', 'not_interested'),
318 + 'compare' => 'IN'
319 + );
320 + $meta_query[] = array(
321 + 'key' => '_feedback_passed_on',
322 + 'value' => '',
323 + );
324 + break;
325 + }
326 + default:
327 + {
328 + $meta_query[] = array(
329 + 'key' => '_status',
330 + 'value' => sanitize_text_field( $selected_status ),
331 + );
332 + }
333 + }
334 + return $meta_query;
335 +}
336 +
337 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_offer_statuses; the established callable name is part of the plugin/extension API and must remain stable.
338 +function ph_get_offer_statuses()
339 +{
340 + $offer_statuses = array(
341 + 'pending' => __( 'Pending', 'propertyhive' ),
342 + 'accepted' => __( 'Accepted', 'propertyhive' ),
343 + 'declined' => __( 'Declined', 'propertyhive' ),
344 + );
345 +
346 + return $offer_statuses;
347 +}
348 +
349 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_sale_statuses; the established callable name is part of the plugin/extension API and must remain stable.
350 +function ph_get_sale_statuses()
351 +{
352 + $sale_statuses = array(
353 + 'current' => __( 'Current', 'propertyhive' ),
354 + 'exchanged' => __( 'Exchanged', 'propertyhive' ),
355 + 'completed' => __( 'Completed', 'propertyhive' ),
356 + 'fallen_through' => __( 'Fallen Through', 'propertyhive' ),
357 + );
358 +
359 + return $sale_statuses;
360 +}
361 +
362 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_get_enquiry_statuses; the established callable name is part of the plugin/extension API and must remain stable.
363 +function ph_get_enquiry_statuses()
364 +{
365 + $enquiry_statuses = array(
366 + 'open' => __( 'Open', 'propertyhive' ),
367 + 'closed' => __( 'Closed', 'propertyhive' ),
368 + );
369 +
370 + return $enquiry_statuses;
371 +}
372 +
373 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper get_area_units; the established callable name is part of the plugin/extension API and must remain stable.
184 374 function get_area_units()
185 375 {
186 376 $size_options = array(
187 377 'sqft' => __( 'Sq Ft', 'propertyhive' ),
@@ -196,20 +386,26 @@
196 386
197 387 return $size_options;
198 388 }
199 389
390 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper convert_size_to_sqft; the established callable name is part of the plugin/extension API and must remain stable.
200 391 function convert_size_to_sqft( $size, $unit = 'sqft' )
201 392 {
202 393 $size_sqft = $size;
203 - switch ( $unit )
394 +
395 + if ( $size_sqft != '' )
204 396 {
205 - case "sqm": { $size_sqft = $size * 1; break; }
206 - case "acre": { $size_sqft = $size * 43560; break; }
207 - case "hectare": { $size_sqft = $size * 107639; break; }
397 + switch ( $unit )
398 + {
399 + case "sqm": { $size_sqft = $size * 10.7639; break; }
400 + case "acre": { $size_sqft = $size * 43560; break; }
401 + case "hectare": { $size_sqft = $size * 107639; break; }
402 + }
208 403 }
209 404 return $size_sqft;
210 405 }
211 406
407 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper get_commercial_price_units; the established callable name is part of the plugin/extension API and must remain stable.
212 408 function get_commercial_price_units( )
213 409 {
214 410 $price_options = array(
215 411 'psqft' => __( 'Per Sq Ft', 'propertyhive' ),
@@ -218,5 +414,119 @@
218 414 'phectare' => __( 'Per Hectare', 'propertyhive' ),
219 415 );
220 416
221 417 return $price_options;
222 -}
418 +}
419 +
420 +/**
421 + * Get ordinal suffix (st, nd, rd etc) for any number
422 + *
423 + * @param int $number
424 + * @param bool $return_number Include $n in the string returned
425 + * @return string $number including its ordinal suffix
426 + */
427 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Legacy public global helper ph_ordinal_suffix; the established callable name is part of the plugin/extension API and must remain stable.
428 +function ph_ordinal_suffix( $number, $return_words = true, $return_number = true )
429 +{
430 + $n_last = $number % 100;
431 + if ( ($n_last > 10 && $n_last << 14) || $number == 0 )
432 + {
433 + $suffix = 'th';
434 + $number_in_words = substr($number, -1) . 'th';
435 + }
436 + else
437 + {
438 + switch( substr($number, -1) )
439 + {
440 + case '1':
441 + $suffix = 'st';
442 + $number_in_words = 'First';
443 + break;
444 + case '2':
445 + $suffix = 'nd';
446 + $number_in_words = 'Second';
447 + break;
448 + case '3':
449 + $suffix = 'rd';
450 + $number_in_words = 'Third';
451 + break;
452 + case '4':
453 + $suffix = 'th';
454 + $number_in_words = 'Fourth';
455 + break;
456 + case '5':
457 + $suffix = 'th';
458 + $number_in_words = 'Fifth';
459 + break;
460 + default:
461 + $suffix = 'th';
462 + $number_in_words = substr($number, -1) . 'th';
463 + break;
464 + }
465 + }
466 + return $return_words ? $number_in_words : ( $return_number ? $number . $suffix : $suffix );
467 +}
468 +
469 +/**
470 + * Save an ordered property media list without modifying unauthorized attachments.
471 + * The caller verifies the property form nonce before invoking this helper.
472 + *
473 + * @param int $post_id Property ID.
474 + * @param string $meta_key Media list key.
475 + * @param string $submitted_ids Comma-separated attachment IDs.
476 + * @return bool Whether the list was saved.
477 + */
478 +function propertyhive_save_media_attachment_list( $post_id, $meta_key, $submitted_ids ) {
479 + if ( ! current_user_can( 'manage_propertyhive' ) || ! current_user_can( 'edit_post', $post_id ) || 'property' !== get_post_type( $post_id ) ) {
480 + return false;
481 + }
482 + if ( ! in_array( $meta_key, array( '_photos', '_floorplans', '_brochures', '_epcs' ), true ) || ! is_string( $submitted_ids ) || ! preg_match( '/^[0-9,\s]*$/D', $submitted_ids ) ) {
483 + return false;
484 + }
485 + $ids = array_values( array_unique( array_filter( array_map( 'absint', explode( ',', $submitted_ids ) ) ) ) );
486 + $previous_ids = get_post_meta( $post_id, $meta_key, true );
487 + $previous_ids = is_array( $previous_ids ) ? array_map( 'absint', $previous_ids ) : array();
488 +
489 + foreach ( $ids as $index => $attachment_id ) {
490 + if ( 'attachment' !== get_post_type( $attachment_id ) ) {
491 + unset( $ids[$index] );
492 + continue;
493 + }
494 +
495 + if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
496 + return false;
497 + }
498 + }
499 +
500 + $ids = array_values( $ids );
501 +
502 + foreach ( $ids as $attachment_id ) {
503 + wp_update_post( array( 'ID' => $attachment_id, 'post_parent' => $post_id ) );
504 + clean_attachment_cache( $attachment_id );
505 + }
506 + update_post_meta( $post_id, $meta_key, $ids );
507 + foreach ( array_diff( $previous_ids, $ids ) as $attachment_id ) {
508 + if ( 'attachment' === get_post_type( $attachment_id ) && (int) get_post_field( 'post_parent', $attachment_id ) === (int) $post_id && current_user_can( 'edit_post', $attachment_id ) ) {
509 + wp_update_post( array( 'ID' => $attachment_id, 'post_parent' => 0 ) );
510 + clean_attachment_cache( $attachment_id );
511 + }
512 + }
513 + return true;
514 +}
515 +
516 +/**
517 + * Determine public visibility on all supported WordPress versions.
518 + *
519 + * @param int|WP_Post $post Post to inspect.
520 + * @return bool Whether anonymous visitors may view it.
521 + */
522 +function propertyhive_is_post_publicly_viewable( $post ) {
523 + if ( function_exists( 'is_post_publicly_viewable' ) ) {
524 + return is_post_publicly_viewable( $post );
525 + }
526 + $post = get_post( $post );
527 + if ( ! $post || ! is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) {
528 + return false;
529 + }
530 + $status = get_post_status_object( $post->post_status );
531 + return $status && ! empty( $status->public );
532 +}