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-elementor.php +351 -9 1.4.622.3.0 View file →
@@ -8,10 +8,40 @@
8 8
9 9 public function __construct()
10 10 {
11 11 add_action( 'plugins_loaded', array( $this, 'setup_propertyhive_elementor_functionality' ) );
12 + add_action( 'elementor/query/onmarketpropertyquery', array( $this, 'elementor_query_on_market_only' ) );
13 + add_action( 'elementor/query/onmarketsalespropertyquery', array( $this, 'elementor_query_on_market_sales_only' ) );
14 + add_action( 'elementor/query/onmarketlettingspropertyquery', array( $this, 'elementor_query_on_market_lettings_only' ) );
15 + add_action( 'elementor/query/onmarketcommercialpropertyquery', array( $this, 'elementor_query_on_market_commercial_only' ) );
16 + add_action( 'elementor/query/featuredpropertyquery', array( $this, 'elementor_query_featured_only' ) );
17 + add_filter( 'elementor/query/query_args', array( $this, 'elementor_query_args' ), 10, 2 );
18 +
19 + add_action( 'propertyhive_elementor_widget_property_image_controls', array( $this, 'elementor_widget_property_image_controls' ), 10 );
20 + add_action( 'propertyhive_elementor_widget_property_image_render_after', array( $this, 'elementor_widget_property_image_render_after' ), 10, 2 );
12 21 }
13 22
23 + public function elementor_query_args( $query_vars, $widget )
24 + {
25 + // Check to see if this is the right Widget.
26 + $settings = $widget->get_data( 'settings' );
27 +
28 + if ( isset($settings['post_query_query_id']) && $settings['post_query_query_id'] == 'onmarketpropertyquery' )
29 + {
30 + $ordering = PH()->query->get_search_results_ordering_args();
31 +
32 + $query_vars['orderby'] = $ordering['orderby'] . ' post_title';
33 + $query_vars['order'] = $ordering['order'];
34 + if ( isset( $ordering['meta_key'] ) )
35 + {
36 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Elementor integration copies the ordering meta_key produced by PH_Query, whose supported order cases map to fixed Property Hive keys. The surrounding hook applies only to named Property Hive query IDs; Elementor supplies its own paginated widget query.
37 + $query_vars['meta_key'] = $ordering['meta_key'];
38 + }
39 + }
40 +
41 + return $query_vars;
42 + }
43 +
14 44 public function setup_propertyhive_elementor_functionality()
15 45 {
16 46 add_filter( 'elementor_pro/utils/get_public_post_types', array( $this, 'register_public_post_type' ) );
17 47
@@ -16,8 +46,10 @@
16 46 add_filter( 'elementor_pro/utils/get_public_post_types', array( $this, 'register_public_post_type' ) );
17 47
18 48 add_action( 'elementor/elements/categories_registered', array( $this, 'add_elementor_widget_category' ) );
19 49
50 + add_filter( 'elementor/image_size/get_attachment_image_html', array( $this, 'portfolio_use_property_image_url'), 10, 4 );
51 +
20 52 add_action( 'elementor/preview/enqueue_scripts', array( 'PH_Frontend_Scripts', 'load_scripts' ) );
21 53 add_action( 'elementor/preview/enqueue_scripts', array( $this, 'load_elementor_scripts' ) );
22 54
23 55 if ( did_action( 'elementor/loaded' ) )
@@ -26,8 +58,164 @@
26 58 add_action( 'init', array( $this, 'register_widgets' ) );
27 59 }
28 60 }
29 61
62 + public function elementor_query_on_market_only( $query )
63 + {
64 + PH()->query->property_query( $query );
65 +
66 + // Set the custom post type
67 + $query->set( 'post_type', [ 'property' ] );
68 +
69 + // ensure a department is set as not set by default from property_query
70 + $meta_query = $query->get('meta_query');
71 +
72 + $new_meta_query = $meta_query;
73 + $department_found = false;
74 + foreach ( $meta_query as $key => $value )
75 + {
76 + if ( isset($value['key']) && $value['key'] == '_department' )
77 + {
78 + $department_found = true;
79 + break;
80 + }
81 + }
82 +
83 + if ( !$department_found )
84 + {
85 + $new_meta_query[] = array(
86 + 'key' => '_department',
87 + 'value' => get_option( 'propertyhive_primary_department', 'residential-sales' )
88 + );
89 + }
90 +
91 + $query->set( 'meta_query', $new_meta_query );
92 + }
93 +
94 + public function elementor_query_on_market_sales_only( $query )
95 + {
96 + $this->query_department( $query, 'residential-sales' );
97 +
98 + // Set the custom post type
99 + $query->set( 'post_type', [ 'property' ] );
100 +
101 + // ensure a department is set as not set by default from property_query
102 + $new_meta_query = $this->remove_department_from_query( $query );
103 +
104 + $new_meta_query[] = array(
105 + 'key' => '_department',
106 + 'value' => 'residential-sales'
107 + );
108 +
109 + $query->set( 'meta_query', $new_meta_query );
110 + }
111 +
112 + public function elementor_query_on_market_lettings_only( $query )
113 + {
114 + $this->query_department( $query, 'residential-lettings' );
115 +
116 + // Set the custom post type
117 + $query->set( 'post_type', [ 'property' ] );
118 +
119 + // ensure a department is set as not set by default from property_query
120 + $new_meta_query = $this->remove_department_from_query( $query );
121 +
122 + $new_meta_query[] = array(
123 + 'key' => '_department',
124 + 'value' => 'residential-lettings'
125 + );
126 +
127 + $query->set( 'meta_query', $new_meta_query );
128 + }
129 +
130 + public function elementor_query_on_market_commercial_only( $query )
131 + {
132 + $this->query_department( $query, 'commercial' );
133 +
134 + // Set the custom post type
135 + $query->set( 'post_type', [ 'property' ] );
136 +
137 + // ensure a department is set as not set by default from property_query
138 + $new_meta_query = $this->remove_department_from_query( $query );
139 +
140 + $new_meta_query[] = array(
141 + 'key' => '_department',
142 + 'value' => 'commercial'
143 + );
144 +
145 + $query->set( 'meta_query', $new_meta_query );
146 + }
147 +
148 + public function elementor_query_featured_only( $query )
149 + {
150 + $original_orderby = $query->get( 'orderby' );
151 + $original_order = $query->get( 'order' );
152 +
153 + PH()->query->property_query( $query );
154 +
155 + // Set the custom post type
156 + $query->set( 'post_type', [ 'property' ] );
157 +
158 + $meta_query = $this->remove_department_from_query( $query );
159 +
160 + $new_meta_query = $meta_query;
161 +
162 + $new_meta_query[] = array(
163 + 'key' => '_featured',
164 + 'value' => 'yes'
165 + );
166 +
167 + $query->set( 'meta_query', $new_meta_query );
168 +
169 + $query->set( 'orderby', $original_orderby );
170 + $query->set( 'order', $original_order );
171 + }
172 +
173 + /** Temporarily scope the public query while preserving the exact surrounding request. */
174 + private function query_department( $query, $department ) {
175 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Snapshot only: this raw value is restored unchanged, never used in the scoped query. PH_Query separately validates request inputs.
176 + $original_request = array_key_exists( 'department', $_REQUEST ) ? array( $_REQUEST['department'] ) : array();
177 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Snapshot only: preserve GET independently from REQUEST, including absence and the original slashing contract.
178 + $original_get = array_key_exists( 'department', $_GET ) ? array( $_GET['department'] ) : array();
179 + $_GET['department'] = $department;
180 + $_REQUEST['department'] = $department;
181 + try {
182 + PH()->query->property_query( $query );
183 + } finally {
184 + if ( $original_request ) {
185 + $_REQUEST['department'] = $original_request[0];
186 + } else {
187 + unset( $_REQUEST['department'] );
188 + }
189 + if ( $original_get ) {
190 + $_GET['department'] = $original_get[0];
191 + } else {
192 + unset( $_GET['department'] );
193 + }
194 + }
195 + }
196 +
197 + private function remove_department_from_query( $query )
198 + {
199 + $new_meta_query = array();
200 +
201 + $meta_query = $query->get('meta_query');
202 +
203 + foreach ( $meta_query as $key => $value )
204 + {
205 + if ( isset($value['key']) && $value['key'] == '_department' )
206 + {
207 + // remove department
208 + }
209 + else
210 + {
211 + $new_meta_query[$key] = $value;
212 + }
213 + }
214 +
215 + return $new_meta_query;
216 + }
217 +
30 218 public function load_elementor_scripts()
31 219 {
32 220 $suffix = '';
33 221 $assets_path = str_replace( array( 'http:', 'https:' ), '', PH()->plugin_url() ) . '/assets/';
@@ -36,15 +224,15 @@
36 224 wp_enqueue_style( 'propertyhive_fancybox_css' );
37 225
38 226 wp_enqueue_script( 'flexslider', $assets_path . 'js/flexslider/jquery.flexslider' . $suffix . '.js', array( 'jquery' ), '2.2.2', true );
39 227 wp_enqueue_script( 'flexslider-init', $assets_path . 'js/flexslider/jquery.flexslider.init' . $suffix . '.js', array( 'jquery','flexslider' ), PH_VERSION, true );
40 - wp_enqueue_style( 'flexslider_css', $assets_path . 'css/flexslider.css' );
228 + wp_enqueue_style( 'flexslider_css', $assets_path . 'css/flexslider.css', array(), PH_VERSION );
41 229
42 230 $api_key = get_option('propertyhive_google_maps_api_key');
43 - wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3');
231 + wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3', true );
44 232 wp_enqueue_script('googlemaps');
45 233
46 - wp_enqueue_script( 'propertyhive_elementor', $assets_path . 'js/elementor/elementor.js', array( 'jquery','flexslider' ), PH_VERSION, true );
234 + wp_enqueue_script( 'propertyhive_elementor', $assets_path . 'js/elementor/elementor.js', array( 'jquery','flexslider', 'googlemaps' ), PH_VERSION, true );
47 235 }
48 236
49 237 public function add_elementor_widget_category( $elements_manager )
50 238 {
@@ -59,10 +247,42 @@
59 247
60 248 public function register_widgets()
61 249 {
62 250 $widgets = array(
251 + 'Property Search Form',
252 + 'Property Tabbed Details',
253 + 'Property Images',
254 + 'Property Image',
255 + 'Property Gallery',
256 + 'Property Address Name Number',
257 + 'Property Address Street',
258 + 'Property Address Line 2',
259 + 'Property Address Town City',
260 + 'Property Address County',
261 + 'Property Address Postcode',
262 + 'Property Address Full',
263 + );
264 +
265 + if ( taxonomy_exists('location') )
266 + {
267 + $args = array(
268 + 'taxonomy' => 'location',
269 + 'hide_empty' => false,
270 + 'parent' => 0,
271 + 'number' => 1,
272 + 'fields' => 'ids',
273 + );
274 + $terms = get_terms( $args );
275 +
276 + if ( !empty( $terms ) && !is_wp_error( $terms ) )
277 + {
278 + $widgets[] = 'Property Location';
279 + }
280 + }
281 +
282 + $widgets = array_merge( $widgets, array(
63 283 'Property Price',
64 - 'Property Images',
284 + 'Property Price Qualifier',
65 285 'Property Features',
66 286 'Property Summary Description',
67 287 'Property Full Description',
68 288 'Property Actions',
@@ -71,21 +291,66 @@
71 291 'Property Type',
72 292 'Property Bedrooms',
73 293 'Property Bathrooms',
74 294 'Property Reception Rooms',
295 + 'Property Reference Number',
296 + 'Property Floor Area',
297 + 'Property Tenure',
298 + 'Property Council Tax Band',
299 + 'Property Let Available Date',
300 + 'Property Deposit',
301 + 'Property Furnished',
302 + 'Property Marketing Flag',
75 303 'Property Map',
304 + 'Property Map Link',
76 305 'Property Street View',
77 - );
306 + 'Property Floorplans',
307 + 'Property Floorplans Link',
308 + 'Property EPCs',
309 + 'Property EPCs Link',
310 + 'Property Enquiry Form',
311 + 'Property Enquiry Form Link',
312 + 'Property Brochures Link',
313 + 'Property Embedded Virtual Tours',
314 + 'Property Virtual Tours Link',
315 + 'Property Office Name',
316 + 'Property Office Telephone Number',
317 + 'Property Office Email Address',
318 + 'Property Office Address',
319 + 'Property Negotiator Name',
320 + 'Property Negotiator Telephone Number',
321 + 'Property Negotiator Email Address',
322 + 'Property Negotiator Photo',
323 + 'Property Not On Market Message',
324 + 'Back To Search',
325 + 'Property Search Result Count',
326 + 'Property Search Order',
327 + ) );
78 328
329 + $current_settings = get_option( 'propertyhive_template_assistant', array() );
330 +
331 + $custom_fields = ( (isset($current_settings['custom_fields'])) ? $current_settings['custom_fields'] : array() );
332 +
333 + foreach ( $custom_fields as $custom_field )
334 + {
335 + if ( substr($custom_field['meta_box'], 0, 9) == 'property_' || substr($custom_field['meta_box'], 0, 7) == 'office_' )
336 + {
337 + $widgets[] = 'Property Additional Field';
338 + break;
339 + }
340 + }
341 +
79 342 $widgets = apply_filters( 'propertyhive_elementor_widgets', $widgets );
80 343
81 344 foreach ( $widgets as $widget )
82 345 {
83 - if ( file_exists( dirname(__FILE__) . "/elementor-widgets/" . sanitize_title($widget) . ".php" ) )
346 + $widget_dir = 'elementor-widgets';
347 + $widget_dir = apply_filters( 'propertyhive_elementor_widget_directory', dirname(__FILE__) . "/" . $widget_dir, $widget );
348 + if ( file_exists( $widget_dir . "/" . sanitize_title($widget) . ".php" ) )
84 349 {
85 - require_once( dirname(__FILE__) . "/elementor-widgets/" . sanitize_title($widget) . ".php" );
350 + require_once( $widget_dir . "/" . sanitize_title($widget) . ".php" );
86 351 $class_name = '\Elementor_' . str_replace(" ", "_", $widget) . '_Widget';
87 - \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new $class_name() );
352 + \Elementor\Plugin::instance()->widgets_manager->register( new $class_name() );
88 353 }
89 354 }
90 355 }
91 356
@@ -100,7 +365,84 @@
100 365
101 366 return $post_types;
102 367 }
103 368
369 + public function portfolio_use_property_image_url( $html, $settings, $image_size_key, $image_key )
370 + {
371 + global $post;
372 +
373 + if ( !isset($settings['posts_post_type']) || ( isset($settings['posts_post_type']) && $settings['posts_post_type'] != 'property' ) )
374 + {
375 + return $html;
376 + }
377 +
378 + // We're viewing a property
379 +
380 + if ( get_option('propertyhive_images_stored_as', '') != 'urls' )
381 + {
382 + return $html;
383 + }
384 +
385 + // Images are stored as URLs
386 +
387 + $images = get_post_meta( $post->ID, '_photo_urls', TRUE );
388 +
389 + if ( empty($images) )
390 + {
391 + return $html;
392 + }
393 +
394 + $image_src = $images[0]['url'];
395 +
396 + $image_class = ! empty( $settings['hover_animation'] ) ? 'elementor-animation-' . $settings['hover_animation'] : '';
397 + $image_class_html = ! empty( $image_class ) ? ' class="' . esc_attr( $image_class ) . '"' : '';
398 +
399 + $html = sprintf( '<img src="%s" title="" alt=""%s />', esc_url( $image_src ), $image_class_html );
400 + return $html;
401 + }
402 +
403 + public function elementor_widget_property_image_controls( $widget )
404 + {
405 + $widget->add_control(
406 + 'show_flag',
407 + [
408 + 'label' => __( 'Show Availability Flag', 'propertyhive' ),
409 + 'type' => \Elementor\Controls_Manager::SWITCHER,
410 + 'label_on' => __( 'Yes', 'propertyhive' ),
411 + 'label_off' => __( 'No', 'propertyhive' ),
412 + 'return_value' => 'yes',
413 + 'default' => '',
414 + ]
415 + );
416 +
417 + $widget->add_control(
418 + 'flag_note',
419 + [
420 + 'label' => '',
421 + 'type' => \Elementor\Controls_Manager::RAW_HTML,
422 + 'raw' => /* translators: %s: Template Assistant flags settings URL. */ sprintf( __( 'The flag shown will take its colour and position settings from the <a href="%s" target="_blank">Template Assistant Flags</a> settings area', 'propertyhive' ), esc_url( admin_url( 'admin.php?page=ph-settings&tab=frontend&section=flags' ) ) ),
423 + 'condition' => [
424 + 'show_flag' => 'yes',
425 + ],
426 + ]
427 + );
428 + }
429 +
430 + public function elementor_widget_property_image_render_after( $settings, $property )
431 + {
432 + global $property;
433 +
434 + if ( isset($settings['show_flag']) && $settings['show_flag'] == 'yes' )
435 + {
436 + $flag = propertyhive_get_flag();
437 +
438 + if ( $flag != '' )
439 + {
440 + $current_settings = get_option( 'propertyhive_template_assistant', array() );
441 +
442 + echo '<div class="flag flag-' . esc_attr( sanitize_title( $flag ) ) . '" style="' . esc_attr( 'position:absolute; text-transform:uppercase; font-size:13px; box-sizing:border-box; padding:7px 20px; ' . propertyhive_get_flag_custom_style( $current_settings ) ) . '">' . esc_html( $flag ) . '</div>';
443 + }
444 + }
445 + }
104 446 }
105 447
106 -new PH_Elementor();
448 +new PH_Elementor();