PluginProbe
Property Hive / 2.2.2
Property Hive v2.2.2
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 1.4.63 All 259 releases
propertyhive / includes / admin / class-ph-admin.php

class-ph-admin.php in Property Hive 2.2.2, at includes/admin/class-ph-admin.php

1,038 lines 43.5 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 /**
7 * PropertyHive Admin.
8 *
9 * @class PH_Admin
10 * @author PropertyHive
11 * @category Admin
12 * @package PropertyHive/Admin
13 * @version 1.0.0
14 */
15 class PH_Admin {
16
17 /**
18 * Constructor
19 */
20 public function __construct()
21 {
22 add_action( 'init', array( $this, 'includes' ) );
23 add_action( 'current_screen', array( $this, 'conditional_includes' ) );
24 add_action( 'current_screen', array( $this, 'disable_propertyhive_meta_box_dragging' ) );
25 add_action( 'current_screen', array( $this, 'remove_propertyhive_meta_boxes_from_screen_options' ) );
26 add_action( 'admin_notices', array( $this, 'review_admin_notices') );
27 add_action( 'admin_notices', array( $this, 'archive_admin_notices' ) );
28 //add_action( 'admin_notices', array( $this, 'retired_template_assistant_admin_notices' ) );
29 add_action( 'admin_menu', array( $this, 'admin_dashboard_pages' ) );
30 add_action( 'admin_head', array( $this, 'admin_head' ) );
31 add_action( 'admin_init', array( $this, 'admin_redirects' ) );
32 add_action( 'admin_init', array( $this, 'prevent_access_to_admin' ) );
33 add_action( 'admin_init', array( $this, 'view_email' ) );
34 add_action( 'admin_init', array( $this, 'preview_emails' ) );
35 add_action( 'admin_init', array( $this, 'record_recently_viewed' ) );
36 add_action( 'admin_init', array( $this, 'export_applicant_list' ) );
37 add_action( 'admin_init', array( $this, 'export_sub_grid' ) );
38 add_action( 'admin_init', array( $this, 'check_hide_demo_data_tab' ) );
39 add_action( 'admin_init', array( $this, 'check_install_add_on' ) );
40 add_filter( 'propertyhive_screen_ids', array( $this, 'crm_only_mode_screen_id' ) );
41 }
42
43 public function archive_admin_notices()
44 {
45 if ( isset($_GET['bulk_archived_posts']) && !empty($_GET['bulk_archived_posts']))
46 {
47 $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : '';
48 if ( $post_type )
49 {
50 $post_type_object = get_post_type_object($post_type);
51
52 $count = intval($_GET['bulk_archived_posts']);
53
54 printf(
55 '<div id="message" class="notice is-dismissible updated"><p>' . _n('%s ' . $post_type_object->labels->singular_name . ' moved to Archive.', '%s ' . $post_type_object->labels->name . ' moved to Archive.', $count, 'propertyhive') . '</p></div>',
56 $count
57 );
58 }
59 }
60
61 if ( isset($_GET['bulk_unarchived_posts']) && !empty($_GET['bulk_unarchived_posts']) )
62 {
63 $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : '';
64 if ( $post_type )
65 {
66 $post_type_object = get_post_type_object($post_type);
67
68 $count = intval($_GET['bulk_unarchived_posts']);
69
70 printf(
71 '<div id="message" class="notice is-dismissible updated"><p>' . _n('%s ' . $post_type_object->labels->singular_name . ' Removed from Archive.', '%s ' . $post_type_object->labels->name . ' removed from Archive.', $count, 'propertyhive') . '</p></div>',
72 $count
73 );
74 }
75 }
76 }
77
78 public function retired_template_assistant_admin_notices()
79 {
80 if ( is_multisite() )
81 {
82 $show = (bool)get_site_option( 'propertyhive_template_assistant_retired_notice', 0 );
83 if ( !$show ) return;
84 if ( !is_super_admin() ) return;
85 }
86 else
87 {
88 $show = (bool)get_option( 'propertyhive_template_assistant_retired_notice', 0 );
89 if ( !$show ) return;
90 if ( !current_user_can( 'activate_plugins' ) ) return;
91 }
92
93 echo '<div class="notice notice-info is-dismissible"><p>
94 <strong>' . __('The Template Assistant add-on has been retired.', 'propertyhive' ) . '</strong><br>
95 ' . __('Its functionality is now built into Property Hive under \'Property Hive &gt; Settings &gt; Frontend\'.', 'propertyhive' ) . '<br>
96 ' . __('The add-on has been deactivated to prevent conflicts. No settings were lost.' ) . '
97 </p>
98 <p>
99 <a href="https://wp-property-hive.com/template-assistant-is-now-part-of-property-hive-core-plugin" target="_blank" class="button button-primary">' . __('Read more', 'propertyhive' ) . '</a>
100 <a href="" class="button" id="ph_dismiss_notice_retired_template_assistant">' . __('Dismiss this notice', 'propertyhive' ) . '</a>
101 </p>
102 </div>';
103 }
104
105 public function crm_only_mode_screen_id( $screen_ids )
106 {
107 $current_user = wp_get_current_user();
108
109 $user_id = $current_user->ID;
110
111 $crm_only_mode = get_user_meta( $user_id, 'crm_only_mode', TRUE );
112
113 if ( $crm_only_mode == '1' )
114 {
115 $screen_ids[] = 'toplevel_page_ph-settings';
116 }
117
118 return $screen_ids;
119 }
120
121 public function check_install_add_on()
122 {
123 if (
124 isset($_GET['ph_action']) && $_GET['ph_action'] == 'install_add_on' &&
125 isset($_GET['ph_add_on_slug']) && !empty($_GET['ph_add_on_slug']) &&
126 isset($_GET['ph_add_on_plugin']) && !empty($_GET['ph_add_on_plugin'])
127 )
128 {
129 $installed_plugins = get_option( 'propertyhive_pre_pro_add_ons', array());
130
131 if ( empty($installed_plugins) )
132 {
133 $installed_plugins = array();
134 }
135
136 $installed_plugins[] = array(
137 'slug' => ph_clean(base64_decode($_GET['ph_add_on_slug'])),
138 'plugin' => ph_clean(base64_decode($_GET['ph_add_on_plugin']))
139 );
140
141 update_option( 'propertyhive_pre_pro_add_ons', $installed_plugins );
142
143 wp_redirect( admin_url('admin.php?page=ph-settings&tab=features') );
144 die();
145 }
146 }
147
148 public function check_hide_demo_data_tab()
149 {
150 if ( isset($_GET['tab']) && $_GET['tab'] == 'demo_data' && isset($_GET['hidetab']) )
151 {
152 update_option( 'propertyhive_hide_demo_data_tab', 'yes' );
153 wp_redirect( admin_url('admin.php?page=ph-settings') );
154 die();
155 }
156 }
157
158 public function export_sub_grid()
159 {
160 if (
161 isset($_GET['sub_grid']) && !empty(ph_clean($_GET['sub_grid']))
162 )
163 {
164 ob_start();
165
166 $df = fopen("php://output", 'w');
167
168 $columns = array( 'id' => __( 'ID', 'propertyhive' ) );
169
170 if ( strpos(ph_clean($_GET['sub_grid']), 'viewings') )
171 {
172 $columns['datetime'] = __( 'Date/Time', 'propertyhive' );
173 $columns['property'] = __( 'Property', 'propertyhive' );
174 //$columns['owner'] = __( 'Owner/Landlord', 'propertyhive' );
175 $columns['applicant'] = __( 'Applicant(s)', 'propertyhive' );
176 $columns['negotiator'] = __( 'Attending Negotiator(s)', 'propertyhive' );
177 $columns['status'] = __( 'Status', 'propertyhive' );
178 $columns['feedback'] = __( 'Feedback', 'propertyhive' );
179 }
180 elseif ( strpos(ph_clean($_GET['sub_grid']), 'offers') )
181 {
182 $columns['datetime'] = __( 'Date/Time', 'propertyhive' );
183 $columns['property'] = __( 'Property', 'propertyhive' );
184 //$columns['owner'] = __( 'Owner/Landlord', 'propertyhive' );
185 $columns['applicant'] = __( 'Applicant(s)', 'propertyhive' );
186 $columns['status'] = __( 'Status', 'propertyhive' );
187 $columns['amount'] = __( 'Offer Amount', 'propertyhive' );
188 }
189 elseif ( strpos(ph_clean($_GET['sub_grid']), 'sales') )
190 {
191 $columns['date'] = __( 'Date', 'propertyhive' );
192 $columns['property'] = __( 'Property', 'propertyhive' );
193 //$columns['owner'] = __( 'Owner/Landlord', 'propertyhive' );
194 $columns['applicant'] = __( 'Applicant(s)', 'propertyhive' );
195 $columns['status'] = __( 'Status', 'propertyhive' );
196 $columns['amount'] = __( 'Sale Amount', 'propertyhive' );
197 }
198
199 fputcsv($df, $columns);
200
201 if ( isset($_GET['record_ids']) && !empty(ph_clean($_GET['record_ids'])) )
202 {
203 $record_ids = explode("|", ph_clean($_GET['record_ids']));
204
205 if ( !empty($record_ids) )
206 {
207 if ( strpos(ph_clean($_GET['sub_grid']), 'viewings') )
208 {
209 $args = array(
210 'post_type' => 'viewing',
211 'nopaging' => TRUE,
212 'fields' => 'ids',
213 'post__in' => $record_ids,
214 'order' => 'ASC',
215 'orderby' => 'meta_value',
216 'meta_key' => '_start_date_time',
217 );
218
219 $records_query = new WP_Query( $args );
220
221 if ( $records_query->have_posts() )
222 {
223 while ( $records_query->have_posts() )
224 {
225 $records_query->the_post();
226
227 $viewing = new PH_Viewing( get_the_ID() );
228
229 $property_id = (int)$viewing->_property_id;
230 $property_address = '';
231 if ( !empty($property_id) )
232 {
233 $property = new PH_Property( $property_id );
234 $property_address = $property->get_formatted_full_address();
235 }
236
237 $columns = array(
238 get_the_ID(),
239 date("H:i jS F Y", strtotime($viewing->_start_date_time)),
240 $property_address,
241 str_replace("<br>", "\n", $viewing->get_applicants()),
242 $viewing->get_negotiators(),
243 str_replace("<br>", "\n", $viewing->get_status()),
244 $viewing->_feedback
245 );
246
247 fputcsv($df, $columns);
248 }
249 }
250 }
251 elseif ( strpos(ph_clean($_GET['sub_grid']), 'offers') )
252 {
253 $args = array(
254 'post_type' => 'offer',
255 'nopaging' => TRUE,
256 'fields' => 'ids',
257 'post__in' => $record_ids,
258 'order' => 'ASC',
259 'orderby' => 'meta_value',
260 'meta_key' => '_offer_date_time',
261 );
262
263 $records_query = new WP_Query( $args );
264
265 if ( $records_query->have_posts() )
266 {
267 while ( $records_query->have_posts() )
268 {
269 $records_query->the_post();
270
271 $offer = new PH_Offer( get_the_ID() );
272
273 $property_id = (int)$offer->_property_id;
274 $property_address = '';
275 if ( !empty($property_id) )
276 {
277 $property = new PH_Property( $property_id );
278 $property_address = $property->get_formatted_full_address();
279 }
280
281 $columns = array(
282 get_the_ID(),
283 date("H:i jS F Y", strtotime($offer->_offer_date_time)),
284 $property_address,
285 str_replace("<br>", "\n", $offer->get_applicants()),
286 $offer->_status,
287 html_entity_decode($offer->get_formatted_amount())
288 );
289
290 fputcsv($df, $columns);
291 }
292 }
293 }
294 elseif ( strpos(ph_clean($_GET['sub_grid']), 'sales') )
295 {
296 $args = array(
297 'post_type' => 'sale',
298 'nopaging' => TRUE,
299 'fields' => 'ids',
300 'post__in' => $record_ids,
301 'order' => 'ASC',
302 'orderby' => 'meta_value',
303 'meta_key' => '_sale_date_time',
304 );
305
306 $records_query = new WP_Query( $args );
307
308 if ( $records_query->have_posts() )
309 {
310 while ( $records_query->have_posts() )
311 {
312 $records_query->the_post();
313
314 $sale = new PH_Sale( get_the_ID() );
315
316 $property_id = (int)$sale->_property_id;
317 $property_address = '';
318 if ( !empty($property_id) )
319 {
320 $property = new PH_Property( $property_id );
321 $property_address = $property->get_formatted_full_address();
322 }
323
324 $columns = array(
325 get_the_ID(),
326 date("jS F Y", strtotime($sale->_sale_date_time)),
327 $property_address,
328 str_replace("<br>", "\n", $sale->get_applicants()),
329 $sale->_status,
330 html_entity_decode($sale->get_formatted_amount())
331 );
332
333 fputcsv($df, $columns);
334 }
335 }
336 }
337 }
338 }
339
340 fclose($df);
341
342 $output = ob_get_clean();
343
344 $filename = sanitize_title(ph_clean($_GET['sub_grid'])) . '-' . date("YmdHis") . '.csv';
345
346 // disable caching
347 $now = gmdate("D, d M Y H:i:s");
348 header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
349 header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
350 header("Last-Modified: {$now} GMT");
351
352 // force download
353 header("Content-Type: application/force-download");
354 header("Content-Type: application/octet-stream");
355 header("Content-Type: application/download");
356
357 // disposition / encoding on response body
358 header("Content-Disposition: attachment;filename={$filename}");
359 header("Content-Transfer-Encoding: binary");
360
361 echo $output;
362
363 die();
364 }
365 }
366
367 public function export_applicant_list()
368 {
369 if (
370 isset($_POST['submitted_applicant_list']) && $_POST['submitted_applicant_list'] == '1' &&
371 isset($_POST['export_applicant_list_results']) && $_POST['export_applicant_list_results'] == '1'
372 )
373 {
374 include_once( 'class-ph-admin-applicant-list.php' );
375 $ph_admin_applicant_list = new PH_Admin_Applicant_List();
376 $ph_admin_applicant_list->export();
377 }
378 }
379
380 public function record_recently_viewed()
381 {
382 global $pagenow;
383
384 if (
385 'post.php' === $pagenow &&
386 isset($_GET['post']) &&
387 in_array(
388 get_post_type((int)$_GET['post']),
389 apply_filters( 'propertyhive_post_types_with_tabs', array('property', 'contact', 'enquiry', 'appraisal', 'viewing', 'offer', 'sale') )
390 )
391 )
392 {
393 $recently_viewed = get_user_meta( get_current_user_id(), '_propertyhive_recently_viewed', TRUE );
394
395 if ( !is_array($recently_viewed) )
396 {
397 $recently_viewed = array();
398 }
399
400 foreach ( $recently_viewed as $time => $post )
401 {
402 if ( (int)$_GET['post'] == $post['id'] )
403 {
404 unset($recently_viewed[$time]);
405 }
406 }
407
408 $title = get_the_title((int)$_GET['post']);
409
410 switch ( get_post_type((int)$_GET['post']) )
411 {
412 case "appraisal":
413 {
414 $appraisal = new PH_Appraisal( (int)$_GET['post'] );
415 $title = $appraisal->get_formatted_summary_address();
416 break;
417 }
418 case "property":
419 {
420 $property = new PH_Property( (int)$_GET['post'] );
421 $title = $property->get_formatted_summary_address();
422 break;
423 }
424 case "enquiry":
425 case "viewing":
426 case "offer":
427 case "sale":
428 {
429 $property_id = get_post_meta( (int)$_GET['post'], '_property_id', TRUE );
430 if ( $property_id != '' )
431 {
432 $property = new PH_Property( (int)$property_id );
433 $title = $property->get_formatted_summary_address();
434 }
435 break;
436 }
437 }
438
439 $title = ucfirst(get_post_type((int)$_GET['post'])) . ' - ' . $title;
440
441 $recently_viewed = array(time() => array(
442 'id' => (int)$_GET['post'],
443 'title' => $title,
444 'post_type' => get_post_type((int)$_GET['post']),
445 'edit_link' => get_edit_post_link((int)$_GET['post']),
446 )) + $recently_viewed;
447
448 $recently_viewed = array_slice($recently_viewed, 0, 10, TRUE);
449
450 update_user_meta( get_current_user_id(), '_propertyhive_recently_viewed', $recently_viewed );
451 }
452 }
453
454 public function admin_dashboard_pages()
455 {
456 if ( ! empty( $_GET['page'] ) )
457 {
458 switch ( sanitize_title($_GET['page']) )
459 {
460 case 'ph-installed':
461 {
462 add_dashboard_page(
463 __( 'Welcome to Property Hive', 'propertyhive' ),
464 __( 'Welcome to Property Hive', 'propertyhive' ),
465 'manage_propertyhive',
466 sanitize_title($_GET['page']),
467 array( $this, 'installed_screen' )
468 );
469
470 break;
471 }
472 }
473 }
474 }
475
476 public function installed_screen()
477 {
478 ?>
479 <div class="wrap propertyhive-installed-screen">
480
481 <h1><?php echo esc_html(__( 'Welcome to Property Hive', 'propertyhive' )); ?></h1>
482
483 <div class="intro-text">
484 <p>Thank you choosing Property Hive to power your next property website. Below you'll find useful links, tips on getting started, and more.</p>
485 </div>
486
487 <div class="panels">
488
489 <div class="panel">
490
491 <h2>Getting Started</h2>
492
493 <p>Now that you've installed Property Hive you'll notice a new 'Property Hive' item in the left hand menu of WordPress.</p>
494
495 <img src="<?php echo esc_url(PH()->plugin_url()); ?>/assets/images/admin/installed-screen/wordpress-menu.png" style="margin:0 auto; display:block; max-width:100%;" alt="Property Hive menu in WordPress">
496
497 <p><strong>Configure Property Hive:</strong> We recommend that you start by navigating to the '<a href="<?php echo esc_url(admin_url( 'admin.php?page=ph-settings' )); ?>" target="_blank">Settings</a>' area of Property Hive and configuring the options available.</p>
498
499 <p><strong>Add Your First Property:</strong> See for yourself how easy it is to use Property Hive by <a href="<?php echo esc_url(admin_url( 'post-new.php?post_type=property' )); ?>" target="_blank">adding your first property</a>.</p>
500
501 </div>
502
503 <div class="panel">
504
505 <h2>Extending Property Hive</h2>
506
507 <p>We have a <a href="https://wp-property-hive.com/add-ons/" target="_blank">wide range of add ons</a> available to add extra functionality to your website.</p>
508
509 <a href="https://wp-property-hive.com/add-ons/" target="_blank"><img src="<?php echo esc_url(PH()->plugin_url()); ?>/assets/images/admin/installed-screen/add-ons.png" style="margin:0 auto; border:1px solid #CCC; display:block; max-width:100%;" alt="Property Hive Free Add Ons"></a>
510
511 <p><strong style="font-size:14px;"><a href="https://wp-property-hive.com/add-ons/?category=free" target="_blank">Free Add Ons</a></strong><br>
512 From our template assistant add on to a variety of calculators, these free add ons are great additions to any property website.</p>
513
514 <p><strong style="font-size:14px;"><a href="https://wp-property-hive.com/add-ons/?category=enhancements" target="_blank">Website Enhancements</a></strong><br>
515 Map View, Radial Search, Property Shortlist, Infinite Scroll, and lots more. Wow your users with the functionality provided with these add ons.</p>
516
517 <p><strong style="font-size:14px;"><a href="https://wp-property-hive.com/add-ons/?category=tools" target="_blank">Internal Tools</a></strong><br>
518 Add ons aimed to make your life easier and to save you time. Includes Digital Window Displays, Address Lookup and more.</p>
519
520 <p><strong style="font-size:14px;"><a href="https://wp-property-hive.com/add-ons/?category=import" target="_blank">Import and Export</a></strong><br>
521 Import properties from third party software or send your properties to portals like Rightmove, Zoopla and more. These add ons automate the import and export of property data.</p>
522
523 </div>
524
525 <div class="panel">
526
527 <h2>Support</h2>
528
529 We pride ourselves on great support at Property Hive and will always do what we can to help you make create the best site possible. Please find below some useful links relating to our support:
530
531 <p><strong style="font-size:14px;">Documentation</strong><br>
532 We have documentation <a href="https://docs.wp-property-hive.com" target="_blank">available on our website</a> covering setup advice, help with theming, and more.</p>
533
534 <p><strong style="font-size:14px;">Our Support Policy</strong><br>
535 Our <a href="https://wp-property-hive.com/support-policy/" target="_blank">Support Policy is available to view here</a> and outlines how you can get in touch, how we will (and won't) help, and how to report bugs.</p>
536
537 </div>
538
539 <div class="panel">
540
541 <h2>Additional Information</h2>
542
543 <p><strong style="font-size:14px;">Need a Theme?</strong><br>
544 Property Hive does <a href="https://wp-property-hive.com/which-wordpress-themes-work-with-property-hive/" target="_blank">integrate with any new or existing theme</a>. If however you need to get up and running quickly, or just want to have a play before committing, then our free <a href="https://wp-property-hive.com/honeycomb" target="_blank">Honeycomb theme</a> might be right for you.</p>
545
546 <a href="https://wp-property-hive.com/honeycomb" target="_blank"><img src="<?php echo esc_url(PH()->plugin_url()); ?>/assets/images/admin/installed-screen/honeycomb-screenshot.png" style="margin:0 auto; display:block; max-width:80%;" alt="Property Hive Free Honeycomb Theme"></a>
547
548 <p><strong style="font-size:14px;">Leave a Review</strong><br>
549 If you've found Property Hive useful we'd love it if you could spare a moment to tell others just how great we are by <a href="https://wordpress.org/support/plugin/propertyhive/reviews/?filter=5" target="_blank">leaving a review</a>.</p>
550
551 <p><strong style="font-size:14px;">Contribute</strong><br>
552 Property Hive is completely open-source meaning anyone can access and contribute to the code. Fixing bugs and adding functionality can be done by anyone with coding knowledge. <a href="https://github.com/propertyhive/WP-Property-Hive" target="_blank">Visit us on GitHub</a> to get started.</p>
553
554 <p><strong style="font-size:14px;">Our Feature Roadmap</strong><br>
555 View our <a href="https://trello.com/b/jb7bjB6j/property-hive-roadmap" target="_blank">feature roadmap</a> to see what's coming up, vote on feature, or submit your own ideas.</p>
556
557
558 </div>
559
560 </div>
561
562 </div>
563 <?php
564 }
565
566 /**
567 * Hide Individual Dashboard Pages
568 *
569 * @access public
570 * @since 1.0
571 * @return void
572 */
573 public function admin_head()
574 {
575 remove_submenu_page( 'index.php', 'ph-installed' );
576 }
577
578 /**
579 * Include any classes we need within admin.
580 */
581 public function includes() {
582 // Functions
583 include_once( 'ph-admin-functions.php' );
584 include_once( 'ph-meta-box-functions.php' );
585
586 // Classes
587 include_once( 'class-ph-admin-post-types.php' );
588 //include_once( 'class-ph-admin-taxonomies.php' );
589
590 // Classes we only need if the ajax is not-ajax
591 if ( ! is_ajax() ) {
592 include( 'class-ph-admin-menus.php' );
593 include( 'class-ph-admin-assets.php' );
594
595 // Help Tab
596 if ( apply_filters( 'propertyhive_enable_admin_help_tab', true ) )
597 {
598 include_once( 'class-ph-admin-help.php' );
599 }
600 }
601 }
602
603 /**
604 * Include admin files conditionally.
605 */
606 public function conditional_includes() {
607 if ( ! $screen = get_current_screen() ) {
608 return;
609 }
610
611 switch ( $screen->id ) {
612 case 'dashboard' :
613 include( 'class-ph-admin-dashboard.php' );
614 break;
615 case 'plugins' :
616 include( 'class-ph-admin-plugin-updates.php' );
617 break;
618 case 'users':
619 case 'user':
620 case 'profile':
621 case 'user-edit':
622 include( 'class-ph-admin-profile.php' );
623 break;
624 }
625 }
626
627 /**
628 * Include admin files conditionally
629 */
630 public function disable_propertyhive_meta_box_dragging()
631 {
632 $screen = get_current_screen();
633
634 if ( in_array( $screen->id, ph_get_screen_ids() ) )
635 {
636 //wp_deregister_script('postbox');
637 }
638 }
639
640 /**
641 * Remove PropertyHive meta boxes
642 */
643 public function remove_propertyhive_meta_boxes_from_screen_options()
644 {
645 global $wp_meta_boxes;
646
647 $screen = get_current_screen();
648
649 if ( in_array( $screen->id, array( 'property' ) ) )
650 {
651 //wp_deregister_script('postbox');
652 }
653 }
654
655 public function review_admin_notices()
656 {
657 global $wpdb;
658
659 if ( current_user_can( 'manage_options' ) )
660 {
661 $propertyhive_review_prompt_due_timestamp = get_option( 'propertyhive_review_prompt_due_timestamp', 0 );
662 if ( $propertyhive_review_prompt_due_timestamp != '' && $propertyhive_review_prompt_due_timestamp != 0 )
663 {
664 if ( $propertyhive_review_prompt_due_timestamp < time() )
665 {
666 echo "<div class=\"notice notice-info\" id=\"ph_notice_leave_review\">
667 <p>
668 " . __( '<strong>Finding Property Hive useful?</strong> Please take a minute to <a href="https://wordpress.org/support/plugin/propertyhive/reviews/?filter=5#new-post" target="_blank">leave us a �
669 �
670 �
671 �
672 �
673 review</a>', 'propertyhive' ) . "
674 </p>
675 <p>
676 <a href=\"https://wordpress.org/support/plugin/propertyhive/reviews/?filter=5#new-post\" target=\"_blank\" class=\"button-primary\">Leave a Review</a>
677 <a href=\"\" class=\"button\" id=\"ph_dismiss_notice_leave_review\">No Thanks</a>
678 </p>
679 </div>";
680 }
681 }
682
683 if (
684 class_exists('Easy_Property_Listings') &&
685 !isset($_GET['plugin_status']) &&
686 get_option( 'epl_notice_dismissed', '' ) != 'yes'
687 )
688 {
689 echo "<div class=\"notice notice-error\" id=\"ph_notice_epl\">
690 <p>
691 " . __( '<strong>It looks like you\'re also running Easy Property Listings.</strong> This will cause conflicts with Property Hive and should be deactivated.', 'propertyhive' ) . "
692 </p>
693 <p>
694 <a href=\"". esc_url(admin_url('plugins.php?s=easy%20property%20listings&plugin_status=all')) . "\" class=\"button-primary\">Deactivate Easy Property Listings</a>
695 <a href=\"\" class=\"button\" id=\"ph_dismiss_notice_epl\">Dismiss</a>
696 </p>
697
698 </div>";
699 }
700
701 if (
702 !class_exists('PH_Demo_Data') &&
703 get_option( 'propertyhive_install_timestamp', '' ) >= 1618268400 &&
704 get_option( 'propertyhive_hide_demo_data_tab', '' ) != 'yes' &&
705 (
706 !isset($_GET['page'])
707 ||
708 (
709 isset($_GET['page']) && sanitize_title($_GET['page']) != 'ph-installed' && sanitize_title($_GET['page']) != 'ph-settings'
710 )
711 )
712 )
713 {
714 echo "<div class=\"notice notice-info\" id=\"ph_notice_demo_data\">
715 <p>
716 " . __( '<strong>New To Property Hive?</strong> Did you know that you can quickly import demo data to get a feel for how Property Hive works?', 'propertyhive' ) . "
717 </p>
718 <p>
719 <a href=\"". esc_url(admin_url('admin.php?page=ph-settings&tab=demo_data')) . "\" class=\"button-primary\">Import Demo Data</a>
720 <a href=\"\" class=\"button\" id=\"ph_dismiss_notice_demo_data\">Dismiss</a>
721 </p>
722
723 </div>";
724 }
725
726 if (
727 get_option('propertyhive_search_results_page_id', '') == '' &&
728 (
729 !isset($_GET['page'])
730 ||
731 (
732 isset($_GET['page']) && sanitize_title($_GET['page']) != 'ph-installed' && sanitize_title($_GET['page']) != 'ph-settings'
733 )
734 ) &&
735 get_option( 'missing_search_results_notice_dismissed', '' ) != 'yes'
736 )
737 {
738 echo "<div class=\"notice notice-info\" id=\"ph_notice_missing_search_results\">
739 <p>
740 " . __( 'We noticed that you haven\'t assigned a page to be your \'Search Results\' page yet. We recommend that you do this in order to display properties on your site.', 'propertyhive' ) . "
741 </p>
742 <p>
743 <a href=\"". esc_url(admin_url('admin.php?page=ph-settings&tab=general')) . "\" class=\"button-primary\">" . esc_html(__( 'Go To Property Hive Settings', 'propertyhive' )) . "</a>
744 <a href=\"\" class=\"button\" id=\"ph_dismiss_notice_missing_search_results\">" . esc_html(__( 'Dismiss', 'propertyhive' )) . "</a>
745 </p>
746
747 </div>";
748 }
749
750 if (
751 get_option('propertyhive_maps_provider') !== 'osm' &&
752 get_option('propertyhive_google_maps_api_key', '') == '' &&
753 !isset($_POST['propertyhive_google_maps_api_key']) &&
754 (
755 !isset($_GET['page'])
756 ||
757 (
758 isset($_GET['page']) && sanitize_title($_GET['page']) != 'ph-installed'
759 )
760 ) &&
761 get_option( 'missing_google_maps_api_key_notice_dismissed', '' ) != 'yes'
762 )
763 {
764 echo "<div class=\"notice notice-info\" id=\"ph_notice_missing_google_maps_api_key\">
765 <p>
766 " . sprintf( __( 'We noticed that you haven\'t entered a Google Maps API key yet. If wishing to display a map on your website it\'s recommended that you <a href="https://developers.google.com/maps/documentation/javascript/get-api-key" target="_blank">create one</a> and <a href="%s">enter it</a>.', 'propertyhive' ), admin_url('admin.php?page=ph-settings&tab=general&section=map') ) . "
767 </p>
768 <p>
769 <a href=\"". esc_url(admin_url('admin.php?page=ph-settings&tab=general&section=map')) . "\" class=\"button-primary\">" . esc_html(__( 'Enter Google Maps API Key', 'propertyhive' )) . "</a>
770 <a href=\"\" class=\"button\" id=\"ph_dismiss_notice_missing_google_maps_api_key\">" . esc_html(__( 'Dismiss', 'propertyhive' )) . "</a>
771 </p>
772
773 </div>";
774 }
775
776 if (
777 get_option('propertyhive_license_key', '') != '' &&
778 get_option( 'missing_invalid_expired_license_key_notice_dismissed', '' ) != 'yes' &&
779 (
780 !isset($_GET['page'])
781 ||
782 (
783 isset($_GET['page']) && sanitize_title($_GET['page']) != 'ph-installed' && sanitize_title($_GET['page']) != 'ph-settings'
784 )
785 )
786 )
787 {
788 $license = PH()->license->get_current_license();
789 $output = '';
790
791 if ( isset($license['active']) && $license['active'] != '1' )
792 {
793 $output = __( 'Your Property Hive license key is inactive.', 'propertyhive' );
794 }
795 else
796 {
797
798 }
799
800 if ( $output != '' )
801 {
802 echo "<div class=\"notice notice-info\" id=\"ph_notice_invalid_expired_license_key\">
803 <p>
804 " . esc_html($output) . "
805 </p>
806 <p>
807 <a href=\"". esc_url(admin_url('admin.php?page=ph-settings&tab=licensekey')) . "\" class=\"button-primary\">" . esc_html(__( 'Go To License Key Settings', 'propertyhive' )) . "</a>
808 <a href=\"\" class=\"button\" id=\"ph_dismiss_notice_invalid_expired_license_key\">" . esc_html(__( 'Dismiss', 'propertyhive' )) . "</a>
809 </p>
810
811 </div>";
812 }
813 }
814
815 $screen = get_current_screen();
816 if ( in_array( $screen->id, array( 'dashboard' ) ) )
817 {
818 // Email Cron Warning
819 $queuedEmailsExist = (bool)$wpdb->get_var("SELECT 1 FROM " . $wpdb->prefix . "ph_email_log WHERE status = '' LIMIT 1");
820 $cronIsNextScheduled = wp_next_scheduled('propertyhive_process_email_log');
821 if ( $queuedEmailsExist && ( $cronIsNextScheduled === false || $cronIsNextScheduled < strtotime('24 hours ago') ) )
822 {
823 echo '
824 <div class="notice notice-error" id="ph_notice_email_cron_not_running">
825 <p>' . esc_html(__( 'The Property Hive email queue does not appear to be running', 'propertyhive' )) . '
826 </p>
827 <p>
828 <a href="'. esc_url(admin_url('admin.php?page=ph-settings&tab=email&section=log&status=queued')) . '" class="button-primary">' . esc_html(__( 'Go To Email Queue', 'propertyhive' )) . '</a>
829 </p>
830 </div>
831 ';
832 }
833 }
834 }
835
836 if ( isset($_GET['propertyhive_contacts_merged']) )
837 {
838 echo '
839 <div class="notice notice-info">
840 <p>' . esc_html(__( 'Contacts merged successfully', 'propertyhive' )) . '</p>
841 </div>
842 ';
843 }
844 }
845
846 /**
847 * Handle redirects to welcome page after install.
848 */
849 public function admin_redirects()
850 {
851 // Setup wizard redirect
852 if ( get_transient( '_ph_activation_redirect' ) )
853 {
854 delete_transient( '_ph_activation_redirect' );
855
856 // Don't do redirect if part of multisite, doing batch-activate, or if no permission
857 if ( is_network_admin() || isset( $_GET['activate-multi'] ) || ! current_user_can( 'manage_propertyhive' ) ) {
858 return;
859 }
860
861 wp_safe_redirect( admin_url( 'index.php?page=ph-installed' ) );
862 exit;
863 }
864 }
865
866 public function prevent_access_to_admin()
867 {
868 global $current_user;
869
870 $user_roles = $current_user->roles;
871 $user_role = array_shift($user_roles);
872
873 // Check role, but also AJAX as request to admin-ajax.php will still need to be made
874 if ( !defined( 'DOING_AJAX' ) && $user_role === 'property_hive_contact' )
875 {
876 exit( wp_redirect( home_url( '/' ) ) );
877 }
878 }
879
880 /**
881 * View previously sent email
882 *
883 * @return string
884 */
885 public function view_email() {
886
887 global $wpdb;
888
889 if ( isset( $_GET['view_propertyhive_email'] ) )
890 {
891 if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'view-email' ) )
892 {
893 die( 'Security check' );
894 }
895
896 if ( isset( $_GET['email_id'] ) )
897 {
898 $email_log = $wpdb->get_row( "SELECT * FROM " . $wpdb->prefix . "ph_email_log WHERE email_id = '" . esc_sql( (int)$_GET['email_id'] ) . "'" );
899 if ( null !== $email_log )
900 {
901 $body = $email_log->body;
902
903 if ( extension_loaded('zlib') && @gzuncompress($body) !== false )
904 {
905 $body = gzuncompress($body);
906 }
907
908 echo apply_filters( 'propertyhive_mail_content', PH()->email->style_inline( PH()->email->wrap_message( $body ) ) );
909
910 }
911 else
912 {
913 die("Email not found");
914 }
915 }
916
917 exit;
918 }
919 }
920
921 /**
922 * Preview email template.
923 *
924 * @return string
925 */
926 public function preview_emails() {
927 if ( isset( $_GET['preview_propertyhive_email'] ) )
928 {
929 if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'propertyhive-matching-properties' ) && ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'propertyhive-matching-applicants' ) )
930 {
931 die( 'Security check' );
932 }
933
934 $current_user = wp_get_current_user();
935
936 // get the preview email content
937 if ( isset($_GET['property_id']) )
938 {
939 $email_property_ids = array((int)$_GET['property_id']);
940 }
941 elseif ( isset($_POST['email_property_id']) )
942 {
943 $email_property_ids = explode(",", sanitize_text_field($_POST['email_property_id']));
944 }
945
946 $allowed_tags = array(
947 'strong' => array(),
948 'span' => array(),
949 'em' => array(),
950 'h1' => array(),
951 'h2' => array(),
952 'h3' => array(),
953 'h4' => array(),
954 'h5' => array(),
955 'h6' => array(),
956 'i' => array(),
957 'u' => array(),
958 'b' => array(),
959 'a' => array(
960 'href' => array(),
961 'target' => array(),
962 ),
963 );
964 $allowed_tags = apply_filters( 'propertyhive_match_email_allowed_tags', $allowed_tags );
965
966 $body = wp_kses(wp_unslash($_POST['body']), $allowedposttags);
967
968 if ( isset($_GET['contact_id']) )
969 {
970 $contact = new PH_Contact((int)$_GET['contact_id']);
971 $body = str_replace("[contact_name]", $contact->post_title, $body);
972 $body = str_replace("[contact_dear]", $contact->dear(), $body);
973 }
974 $body = str_replace("[property_count]", count($email_property_ids) . ' propert' . ( ( count($email_property_ids) != 1 ) ? 'ies' : 'y' ), $body);
975
976 $office_counts = array();
977
978 if ( strpos($body, '[properties]') !== FALSE )
979 {
980 ob_start();
981
982 if ( !empty($email_property_ids) )
983 {
984 foreach ( $email_property_ids as $email_property_id )
985 {
986 $property = new PH_Property((int)$email_property_id);
987
988 if ( $property->office_id != '' && $property->office_id != 0 )
989 {
990 if ( !isset($office_counts[$property->office_id]) ) { $office_counts[$property->office_id] = 0; }
991 ++$office_counts[$property->office_id];
992 }
993
994 ph_get_template( 'emails/applicant-match-property.php', array( 'property' => $property ) );
995 }
996 }
997 $body = str_replace("[properties]", ob_get_clean(), $body);
998 }
999
1000 $office_name = '';
1001 $office_email_address = '';
1002
1003 $office_id = get_user_meta($current_user->ID, 'office_id', TRUE);
1004 if ($office_id == '')
1005 {
1006 // No office against user. Use email address of office with most properties
1007 if ( !empty($office_counts) )
1008 {
1009 arsort($office_counts);
1010 reset($office_counts);
1011 $office_id = key($office_counts);
1012 }
1013 }
1014
1015 if ( !empty($office_id) )
1016 {
1017 $office_name = get_the_title($office_id);
1018 $office_email_address = get_post_meta( $office_id, '_office_email_address_sales', TRUE );
1019 }
1020
1021 $body = str_replace("[office_name]", $office_name, $body);
1022 $body = str_replace("[office_email_address]", $office_email_address, $body);
1023
1024 $body = str_replace("[negotiator_name]", $current_user->display_name, $body);
1025 $body = str_replace("[negotiator_email_address]", $current_user->user_email, $body);
1026
1027 // wrap the content with the email template and then add styles
1028 $message = apply_filters( 'propertyhive_mail_content', PH()->email->style_inline( PH()->email->wrap_message( $body ) ) );
1029
1030 // print the preview email
1031 echo $message;
1032 exit;
1033 }
1034 }
1035 }
1036
1037 return new PH_Admin();
1038