PluginProbe
Property Hive / 2.3.0
Property Hive v2.3.0
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
propertyhive / includes / class-ph-elementor.php

class-ph-elementor.php in Property Hive 2.3.0, at includes/class-ph-elementor.php

449 lines 15.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 class PH_Elementor {
8
9 public function __construct()
10 {
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 );
21 }
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
44 public function setup_propertyhive_elementor_functionality()
45 {
46 add_filter( 'elementor_pro/utils/get_public_post_types', array( $this, 'register_public_post_type' ) );
47
48 add_action( 'elementor/elements/categories_registered', array( $this, 'add_elementor_widget_category' ) );
49
50 add_filter( 'elementor/image_size/get_attachment_image_html', array( $this, 'portfolio_use_property_image_url'), 10, 4 );
51
52 add_action( 'elementor/preview/enqueue_scripts', array( 'PH_Frontend_Scripts', 'load_scripts' ) );
53 add_action( 'elementor/preview/enqueue_scripts', array( $this, 'load_elementor_scripts' ) );
54
55 if ( did_action( 'elementor/loaded' ) )
56 {
57 // Widgets
58 add_action( 'init', array( $this, 'register_widgets' ) );
59 }
60 }
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
218 public function load_elementor_scripts()
219 {
220 $suffix = '';
221 $assets_path = str_replace( array( 'http:', 'https:' ), '', PH()->plugin_url() ) . '/assets/';
222
223 wp_enqueue_script( 'propertyhive_fancybox' );
224 wp_enqueue_style( 'propertyhive_fancybox_css' );
225
226 wp_enqueue_script( 'flexslider', $assets_path . 'js/flexslider/jquery.flexslider' . $suffix . '.js', array( 'jquery' ), '2.2.2', true );
227 wp_enqueue_script( 'flexslider-init', $assets_path . 'js/flexslider/jquery.flexslider.init' . $suffix . '.js', array( 'jquery','flexslider' ), PH_VERSION, true );
228 wp_enqueue_style( 'flexslider_css', $assets_path . 'css/flexslider.css', array(), PH_VERSION );
229
230 $api_key = get_option('propertyhive_google_maps_api_key');
231 wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3', true );
232 wp_enqueue_script('googlemaps');
233
234 wp_enqueue_script( 'propertyhive_elementor', $assets_path . 'js/elementor/elementor.js', array( 'jquery','flexslider', 'googlemaps' ), PH_VERSION, true );
235 }
236
237 public function add_elementor_widget_category( $elements_manager )
238 {
239 $elements_manager->add_category(
240 'property-hive',
241 [
242 'title' => __( 'Property Hive', 'propertyhive' ),
243 'icon' => 'fa fa-home',
244 ]
245 );
246 }
247
248 public function register_widgets()
249 {
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(
283 'Property Price',
284 'Property Price Qualifier',
285 'Property Features',
286 'Property Summary Description',
287 'Property Full Description',
288 'Property Actions',
289 'Property Meta',
290 'Property Availability',
291 'Property Type',
292 'Property Bedrooms',
293 'Property Bathrooms',
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',
303 'Property Map',
304 'Property Map Link',
305 'Property Street View',
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 ) );
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
342 $widgets = apply_filters( 'propertyhive_elementor_widgets', $widgets );
343
344 foreach ( $widgets as $widget )
345 {
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" ) )
349 {
350 require_once( $widget_dir . "/" . sanitize_title($widget) . ".php" );
351 $class_name = '\Elementor_' . str_replace(" ", "_", $widget) . '_Widget';
352 \Elementor\Plugin::instance()->widgets_manager->register( new $class_name() );
353 }
354 }
355 }
356
357 public function register_public_post_type( $post_types ) {
358
359 if ( isset($post_types['property']) )
360 {
361 return $post_types;
362 }
363
364 $post_types['property'] = __( 'Property', 'propertyhive' );
365
366 return $post_types;
367 }
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 }
446 }
447
448 new PH_Elementor();
449