PluginProbe
Property Hive / 2.3.0
Property Hive v2.3.0
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
← All changes | includes/class-ph-property.php +43 -46 2.2.62.3.0 View file →
@@ -12,8 +12,9 @@
12 12 * @package PropertyHive/Classes
13 13 * @category Class
14 14 * @author PropertyHive
15 15 */
16 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Property; preserving the existing PH_* class name is required for plugin and extension compatibility.
16 17 class PH_Property {
17 18
18 19 /** @public int Property (post) ID */
19 20 public $id;
@@ -103,8 +104,14 @@
103 104 if ($value == '')
104 105 {
105 106 $value = get_post_meta( $this->id, '_' . $key, true );
106 107 }
108 + // Sanitize stored description HTML before trusted extension callbacks run.
109 + // This also protects descriptions saved before the write-boundary checks.
110 + if ( preg_match( '/^_?(?:room_(?:name|dimensions|description)|description(?:_name)?)_[0-9]+$/', $key ) ) {
111 + $value = is_scalar( $value ) ? (string) $value : '';
112 + $value = preg_match( '/^_?(?:room_description|description)_[0-9]+$/', $key ) ? propertyhive_sanitize_description( $value ) : wp_kses_post( $value );
113 + }
107 114 }
108 115
109 116 $value = apply_filters( 'propertyhive_get_detail', $value, $key, $this );
110 117
@@ -314,9 +321,9 @@
314 321 $this->_for_sale == 'yes' && $this->_price_poa == 'yes' &&
315 322 $this->_to_rent == 'yes' && $this->_rent_poa == 'yes'
316 323 )
317 324 {
318 - $return = __( 'POA', 'propertyhive' );
325 + $return = esc_html__( 'POA', 'propertyhive' );
319 326 }
320 327 else
321 328 {
322 329 // Price Details
@@ -344,9 +351,9 @@
344 351 else
345 352 {
346 353 if ( !$is_admin && $this->_poa == 'yes')
347 354 {
348 - $return = __( 'POA', 'propertyhive' );
355 + $return = esc_html__( 'POA', 'propertyhive' );
349 356 }
350 357 else
351 358 {
352 359 $ph_countries = new PH_Countries();
@@ -352,21 +359,24 @@
352 359 $ph_countries = new PH_Countries();
353 360
354 361 if ( !$is_admin )
355 362 {
356 - if ( isset($_GET['currency']) )
363 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public currency choice only affects displayed prices.
364 + if ( isset($_GET['currency']) && is_string( $_GET['currency'] ) )
357 365 {
358 - if ( $_GET['currency'] != '' )
366 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public currency choice only affects displayed prices.
367 + $currency_code = sanitize_text_field( wp_unslash( $_GET['currency'] ) );
368 + if ( $currency_code != '' )
359 369 {
360 - $requested_currency = $ph_countries->get_currency( sanitize_text_field($_GET['currency']) );
370 + $requested_currency = $ph_countries->get_currency( $currency_code );
361 371 if ( $requested_currency !== FALSE )
362 372 {
363 373 $currency = $requested_currency;
364 374 $currency['exchange_rate'] = 1;
365 375 $exchange_rates = get_option( 'propertyhive_currency_exchange_rates', array() );
366 - if ( isset($exchange_rates[$_GET['currency']]) )
376 + if ( isset($exchange_rates[$currency_code]) )
367 377 {
368 - $currency['exchange_rate'] = $exchange_rates[sanitize_text_field($_GET['currency'])];
378 + $currency['exchange_rate'] = $exchange_rates[$currency_code];
369 379 }
370 380 }
371 381 }
372 382 else
@@ -387,11 +397,11 @@
387 397 }
388 398 }
389 399 }
390 400 }
391 - elseif ( isset($_COOKIE['propertyhive_currency']) && $_COOKIE['propertyhive_currency'] != '' )
401 + elseif ( false !== ( $cookie_currency = $ph_countries->get_currency_from_cookie() ) )
392 402 {
393 - $currency = @json_decode(html_entity_decode($_COOKIE['propertyhive_currency']), true);
403 + $currency = $cookie_currency;
394 404 }
395 405 else
396 406 {
397 407 $default_currency = apply_filters( 'propertyhive_default_display_currency', '' );
@@ -442,9 +452,9 @@
442 452 // Round this after calculation
443 453 $price = round($this->_price_actual * $currency['exchange_rate'], 0);
444 454 }
445 455
446 - $return = ( ( $price != '' ) ? $prefix . ph_display_price_field($price, !$is_admin) . $suffix : '-' );
456 + $return = ( ( $price != '' ) ? $prefix . esc_html( ph_display_price_field($price, !$is_admin) ) . $suffix : '-' );
447 457 break;
448 458 }
449 459 case "residential-lettings":
450 460 {
@@ -461,15 +471,17 @@
461 471 case "pa": { $price = ($price * 12); break; }
462 472 }
463 473 }
464 474
465 - $return = ( ( $price != '' ) ? $prefix . ph_display_price_field($price, !$is_admin) . $suffix . ' ' . __( $this->_rent_frequency, 'propertyhive' ) : '-' );
475 + $return = ( ( $price != '' ) ? $prefix . esc_html( ph_display_price_field($price, !$is_admin) ) . $suffix . ' ' . esc_html( propertyhive_get_rent_frequency_label( $this->_rent_frequency ) ) : '-' );
466 476 break;
467 477 }
468 478 }
469 479 }
480 +
470 481 }
471 482
483 + // Stored price/frequency text is escaped above; currency and commercial HTML filters remain trusted.
472 484 return apply_filters( 'propertyhive_price_output', $return, $this, $currency, $prefix, $suffix );
473 485 }
474 486
475 487 /**
@@ -487,9 +499,9 @@
487 499 $is_admin = ( !is_admin() || ( is_admin() && defined('DOING_AJAX') && DOING_AJAX ) ) ? false : true;
488 500
489 501 if ( !$is_admin && $this->_price_poa == 'yes' )
490 502 {
491 - $price .= __( 'POA', 'propertyhive' );
503 + $price .= esc_html__( 'POA', 'propertyhive' );
492 504 }
493 505 else
494 506 {
495 507 $ph_countries = new PH_Countries();
@@ -505,9 +517,9 @@
505 517 $suffix = ( (!$currency['currency_prefix']) ? $currency['currency_symbol'] : '' );
506 518
507 519 if ( $this->_price_from != '' )
508 520 {
509 - $price .= $prefix . ph_display_price_field($this->_price_from, !$is_admin) . $suffix;
521 + $price .= $prefix . esc_html( ph_display_price_field($this->_price_from, !$is_admin) ) . $suffix;
510 522 }
511 523 if ( $this->_price_to != '' && $this->_price_to != $this->_price_from )
512 524 {
513 525 if ( $price != '' )
@@ -513,18 +525,19 @@
513 525 if ( $price != '' )
514 526 {
515 527 $price .= ' - ';
516 528 }
517 - $price .= $prefix . ph_display_price_field($this->_price_to, !$is_admin) . $suffix;
529 + $price .= $prefix . esc_html( ph_display_price_field($this->_price_to, !$is_admin) ) . $suffix;
518 530 }
519 531 if ( $price != '' )
520 532 {
521 533 $price_units = get_commercial_price_units( );
522 - $price .= ( isset($price_units[$this->_price_units]) ) ? ' ' . $price_units[$this->_price_units] : '';
534 + $price .= ( isset($price_units[$this->_price_units]) ) ? ' ' . esc_html( $price_units[$this->_price_units] ) : '';
523 535 }
524 536 }
525 537 }
526 538
539 + // Stored price/unit text is escaped above; preserve trusted currency and price filter HTML.
527 540 return apply_filters( 'propertyhive_commercial_price_output', $price, $this );
528 541 }
529 542
530 543 /**
@@ -542,9 +555,9 @@
542 555 $is_admin = ( !is_admin() || ( is_admin() && defined('DOING_AJAX') && DOING_AJAX ) ) ? false : true;
543 556
544 557 if ( !$is_admin && $this->_rent_poa == 'yes' )
545 558 {
546 - $rent .= __( 'POA', 'propertyhive' );
559 + $rent .= esc_html__( 'POA', 'propertyhive' );
547 560 }
548 561 else
549 562 {
550 563 $ph_countries = new PH_Countries();
@@ -560,9 +573,9 @@
560 573 $suffix = ( (!$currency['currency_prefix']) ? $currency['currency_symbol'] : '' );
561 574
562 575 if ( $this->_rent_from != '' )
563 576 {
564 - $rent .= $prefix . ph_display_price_field($this->_rent_from, !$is_admin) . $suffix;
577 + $rent .= $prefix . esc_html( ph_display_price_field($this->_rent_from, !$is_admin) ) . $suffix;
565 578 }
566 579 if ( $this->_rent_to != '' && $this->_rent_to != $this->_rent_from )
567 580 {
568 581 if ( $rent != '' )
@@ -568,18 +581,19 @@
568 581 if ( $rent != '' )
569 582 {
570 583 $rent .= ' - ';
571 584 }
572 - $rent .= $prefix . ph_display_price_field($this->_rent_to, !$is_admin) . $suffix;
585 + $rent .= $prefix . esc_html( ph_display_price_field($this->_rent_to, !$is_admin) ) . $suffix;
573 586 }
574 587 if ( $rent != '' )
575 588 {
576 589 $price_units = get_commercial_price_units( );
577 - $rent .= ' ' . __( ( isset($price_units[$this->_rent_units]) ? $price_units[$this->_rent_units] : $this->_rent_units ), 'propertyhive' );
590 + $rent .= ' ' . esc_html( isset( $price_units[$this->_rent_units] ) ? $price_units[$this->_rent_units] : $this->_rent_units );
578 591 }
579 592 }
580 593 }
581 594
595 + // Stored rent/unit text is escaped above; preserve trusted currency and rent filter HTML.
582 596 return apply_filters( 'propertyhive_commercial_rent_output', $rent, $this );
583 597 }
584 598
585 599 public function get_formatted_floor_area( ) {
@@ -620,9 +634,9 @@
620 634 $area_units = get_area_units( );
621 635 $area .= ( isset($area_units[$this->_floor_area_units]) ) ? ' ' . $area_units[$this->_floor_area_units] : '';
622 636 }
623 637
624 - return apply_filters( 'propertyhive_floor_area_output', $area, $this );
638 + return apply_filters( 'propertyhive_floor_area_output', esc_html( $area ), $this );
625 639
626 640 }
627 641
628 642 public function get_formatted_site_area( ) {
@@ -663,9 +677,9 @@
663 677 $area_units = get_area_units( );
664 678 $area .= ( isset($area_units[$this->_site_area_units]) ) ? ' ' . $area_units[$this->_site_area_units] : '';
665 679 }
666 680
667 - return apply_filters( 'propertyhive_site_area_output', $area, $this );
681 + return apply_filters( 'propertyhive_site_area_output', esc_html( $area ), $this );
668 682
669 683 }
670 684
671 685 /**
@@ -712,9 +726,9 @@
712 726 }
713 727
714 728 if (strtotime($this->_available_date) > time())
715 729 {
716 - return date( get_option( 'date_format' ), strtotime($this->_available_date) );
730 + return gmdate( get_option( 'date_format' ), strtotime($this->_available_date) );
717 731 }
718 732 else
719 733 {
720 734 return __( 'Now', 'propertyhive' );
@@ -792,9 +806,9 @@
792 806 if ($this->{'_room_name_' . $i} != '' || $this->{'_room_dimensions_' . $i} != '')
793 807 {
794 808 $return .= "\n";
795 809 }
796 - $return .= strip_tags($this->{'_room_description_' . $i}) . "\n\n";
810 + $return .= wp_strip_all_tags($this->{'_room_description_' . $i}) . "\n\n";
797 811 }
798 812 }
799 813 }
800 814
@@ -836,9 +850,9 @@
836 850 if ($this->{'_description_name_' . $i} != '')
837 851 {
838 852 $return .= $this->{'_description_name_' . $i} . "\n";
839 853 }
840 - $return .= strip_tags($this->{'_description_' . $i}) . "\n\n";
854 + $return .= wp_strip_all_tags($this->{'_description_' . $i}) . "\n\n";
841 855 }
842 856 }
843 857 }
844 858
@@ -1032,31 +1046,14 @@
1032 1046 * @return string
1033 1047 */
1034 1048 public function get_imported_id()
1035 1049 {
1036 - global $wpdb;
1037 -
1038 - $row = $wpdb->get_row(
1039 - $wpdb->prepare(
1040 - "
1041 - SELECT meta_value
1042 - FROM {$wpdb->prefix}postmeta
1043 - WHERE
1044 - meta_key LIKE %s
1045 - AND post_id = %d
1046 - LIMIT 1
1047 - ",
1048 - '_imported_ref_%',
1049 - $this->id
1050 - ),
1051 - ARRAY_A
1052 - );
1053 -
1054 - if ( null !== $row )
1055 - {
1056 - return $row['meta_value'];
1050 + // Use WordPress's metadata cache and match the literal importer-key prefix.
1051 + foreach ( get_post_meta( $this->id ) as $key => $values ) {
1052 + if ( 0 === strpos( $key, '_imported_ref_' ) && isset( $values[0] ) ) {
1053 + return $values[0];
1054 + }
1057 1055 }
1058 -
1059 1056 return '';
1060 1057 }
1061 1058
1062 1059 /**