PluginProbe
Property Hive / 2.3.1
Property Hive v2.3.1
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/admin/class-ph-admin-menus.php +427 -93 1.4.612.3.1 View file →
@@ -1,5 +1,8 @@
1 1 <?php
2 +// phpcs:set WordPress.Security.ValidatedSanitizedInput customSanitizingFunctions[] ph_clean
3 +// ph_clean() recursively sanitizes text; presence, shape and unslashing checks remain separate.
4 +
2 5 /**
3 6 * Setup menus in WP admin.
4 7 *
5 8 * @author PropertyHive
@@ -14,8 +17,9 @@
14 17
15 18 /**
16 19 * PH_Admin_Menus Class
17 20 */
21 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Admin_Menus; preserving the existing PH_* class name is required for plugin and extension compatibility.
18 22 class PH_Admin_Menus {
19 23
20 24 /**
21 25 * Hook in tabs.
@@ -22,17 +26,162 @@
22 26 */
23 27 public function __construct() {
24 28 // Add menus
25 29 add_action( 'admin_menu', array( $this, 'admin_menu' ), 9 );
30 + add_action( 'admin_menu', array( $this, 'import_properties_dummy_menu' ), 20 );
26 31 add_action( 'admin_menu', array( $this, 'reports_menu' ), 20 );
27 32 add_action( 'admin_menu', array( $this, 'settings_menu' ), 50 );
28 - add_action( 'admin_menu', array( $this, 'add_ons_menu' ), 60 );
33 + add_action( 'admin_menu', array( $this, 'crm_only_mode_menu' ), 99 );
29 34
30 35 add_action( 'admin_head', array( $this, 'menu_highlight' ) );
31 - //add_filter( 'menu_order', array( $this, 'menu_order' ) );
32 - //add_filter( 'custom_menu_order', array( $this, 'custom_menu_order' ) );
36 +
37 + add_action( 'admin_bar_menu', array( $this, 'remove_from_admin_bar' ), 999);
38 +
39 + // Handle saving settings earlier than load-{page} hook to avoid race conditions in conditional menus.
40 + add_action( 'wp_loaded', array( $this, 'save_settings' ) );
33 41 }
34 42
43 + public function save_settings() {
44 + global $current_tab, $current_section;
45 +
46 + // We should only save on the settings page.
47 + if ( ! is_admin() || ! isset( $_GET['page'] ) || 'ph-settings' !== $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
48 + return;
49 + }
50 +
51 + // Include settings pages.
52 + PH_Admin_Settings::get_settings_pages();
53 +
54 + // Get current tab/section.
55 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound, WordPress.Security.NonceVerification.Recommended -- Read-only settings routing; saved data is separately nonce/capability checked by PH_Admin_Settings::save(). Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global.
56 + $current_tab = empty( $_GET['tab'] ) || ! is_string( $_GET['tab'] ) ? 'general' : sanitize_title( wp_unslash( $_GET['tab'] ) ); // WPCS: input var okay, CSRF ok.
57 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound, WordPress.Security.NonceVerification.Recommended -- Read-only settings routing; saved data is separately nonce/capability checked by PH_Admin_Settings::save(). Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global.
58 + $current_section = empty( $_REQUEST['section'] ) || ! is_string( $_REQUEST['section'] ) ? '' : sanitize_title( wp_unslash( $_REQUEST['section'] ) ); // WPCS: input var okay, CSRF ok.
59 +
60 + // Save settings if data has been posted. The called save method verifies nonce and capabilities.
61 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only save intent; PH_Admin_Settings::save() validates before changing any settings.
62 + $save_requested = ! empty( $_POST['save'] );
63 + if ( '' !== $current_section && apply_filters( "propertyhive_save_settings_{$current_tab}_{$current_section}", $save_requested ) ) { // WPCS: input var okay, CSRF ok.
64 + PH_Admin_Settings::save();
65 + } elseif ( '' === $current_section && apply_filters( "propertyhive_save_settings_{$current_tab}", $save_requested ) ) { // WPCS: input var okay, CSRF ok.
66 + PH_Admin_Settings::save();
67 + }
68 +
69 + $redirect_after_save = '';
70 + if ( current_user_can( 'manage_options' ) && isset( $_REQUEST['_wpnonce'] ) && is_string( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'propertyhive-settings' ) ) {
71 + $redirect_after_save = isset( $_POST['redirect'] ) && is_string( $_POST['redirect'] ) ? sanitize_url( wp_unslash( $_POST['redirect'] ) ) : '';
72 + }
73 + if ( !empty($redirect_after_save) )
74 + {
75 + wp_safe_redirect($redirect_after_save . '&ph_message=' . __( 'Your settings have been saved.', 'propertyhive' ) );
76 + die();
77 + }
78 + }
79 +
80 + public function remove_from_admin_bar( $wp_admin_bar )
81 + {
82 + $current_user = wp_get_current_user();
83 +
84 + $user_id = $current_user->ID;
85 +
86 + $crm_only_mode = get_user_meta( $user_id, 'crm_only_mode', TRUE );
87 +
88 + if ( $crm_only_mode == '1' )
89 + {
90 + $wp_admin_bar->remove_node('new-content');
91 + }
92 + }
93 +
94 + public function crm_only_mode_menu()
95 + {
96 + $current_user = wp_get_current_user();
97 +
98 + $user_id = $current_user->ID;
99 +
100 + $crm_only_mode = get_user_meta( $user_id, 'crm_only_mode', TRUE );
101 +
102 + if ( $crm_only_mode == '1' )
103 + {
104 + global $menu, $submenu, $wp_filter;
105 +
106 + // remove all top-level menu items that isn't the Dashboard
107 + foreach ( $menu as $i => $menuitem )
108 + {
109 + if (
110 + ( !isset($menuitem[2]) || ( isset($menuitem[2]) && $menuitem[2] != 'index.php' ) )
111 + &&
112 + apply_filters( 'propertyhive_remove_menu_item_in_crm_only_mode', true, $menuitem ) === true
113 + )
114 + {
115 + unset($menu[$i]);
116 + }
117 + }
118 + if ( isset($submenu['propertyhive']) )
119 + {
120 + unset($submenu['propertyhive'][0]);
121 + $position = 5;
122 + foreach ( $submenu['propertyhive'] as $submenuitem )
123 + {
124 + $callback = '';
125 + if ( substr($submenuitem[2], 0, 3) == 'ph-' )
126 + {
127 + $callback = array( $this, substr($submenuitem[2], 3) . '_page' );
128 + }
129 + elseif ( isset($wp_filter[sanitize_title(__( 'Property Hive', 'propertyhive' )) . '_page_' . $submenuitem[2]]) )
130 + {
131 + // get class name from callbacks then convert it to class name
132 + // i.e. convert PH_Property_Import to PHPI()
133 + $class_name = '';
134 + $function_name = '';
135 + if ( isset($wp_filter[sanitize_title(__( 'Property Hive', 'propertyhive' )) . '_page_' . $submenuitem[2]]->callbacks) )
136 + {
137 + foreach ( $wp_filter[sanitize_title(__( 'Property Hive', 'propertyhive' )) . '_page_' . $submenuitem[2]]->callbacks as $priority => $filter_callbacks )
138 + {
139 + foreach ( $filter_callbacks as $oddkey => $filter_callback )
140 + {
141 + if ( isset($filter_callback['function']) && count($filter_callback['function']) >= 2 )
142 + {
143 + $class_name = get_class($filter_callback['function'][0]);
144 + $explode_class_name = explode("_", $class_name);
145 +
146 + $class_name_bits = array();
147 + foreach ( $explode_class_name as $exploded_class_name_bit )
148 + {
149 + if ( $exploded_class_name_bit == 'PH' )
150 + {
151 + $class_name_bits[] = $exploded_class_name_bit;
152 + }
153 + else
154 + {
155 + $class_name_bits[] = strtoupper(substr($exploded_class_name_bit, 0, 1));
156 + }
157 + }
158 +
159 + $class_name = implode("", $class_name_bits);
160 + $function_name = $filter_callback['function'][1];
161 + }
162 + }
163 + }
164 + }
165 +
166 + if ( class_exists($class_name) && $class_name != '' && $function_name != '' )
167 + {
168 + $callback = array( $class_name(), $function_name );
169 + }
170 + elseif ( function_exists($class_name) && $class_name != '' && $function_name != '' )
171 + {
172 + $callback = array( $class_name(), $function_name );
173 + }
174 + }
175 +
176 + add_menu_page( $submenuitem[3], $submenuitem[0], $submenuitem[1], $submenuitem[2], $callback, $this->get_menu_icon($submenuitem[2]), $position );
177 + $position += 5;
178 + }
179 + unset($submenu['propertyhive']);
180 + }
181 + }
182 + }
183 +
35 184 /**
36 185 * Add menu items
37 186 */
38 187 public function admin_menu() {
@@ -40,9 +189,9 @@
40 189
41 190 //if ( current_user_can( 'manage_propertyhive' ) )
42 191 $menu[] = array( '', 'read', 'separator-propertyhive', '', 'wp-menu-separator propertyhive' );
43 192
44 - add_menu_page( __( 'Property Hive', 'propertyhive' ), __( 'Property Hive', 'propertyhive' ), 'manage_propertyhive', 'propertyhive' , array( $this, 'settings_page' ), PH()->plugin_url() . '/assets/images/menu-icon.png', '54.5' );
193 + add_menu_page( __( 'Property Hive', 'propertyhive' ), __( 'Property Hive', 'propertyhive' ), 'manage_propertyhive', 'propertyhive' , array( $this, 'settings_page' ), $this->get_menu_icon(), '54.5' );
45 194
46 195 add_submenu_page( 'propertyhive', __( 'Properties', 'propertyhive' ), __( 'Properties', 'propertyhive' ), 'manage_propertyhive', 'edit.php?post_type=property'/*, array( $this, 'attributes_page' )*/ );
47 196
48 197 if ( get_option('propertyhive_module_disabled_contacts', '') != 'yes' )
@@ -54,28 +203,34 @@
54 203
55 204 if ( get_option('propertyhive_module_disabled_enquiries', '') != 'yes' )
56 205 {
57 206 $count = '';
58 - $args = array(
59 - 'post_type' => 'enquiry',
60 - 'nopaging' => true,
61 - 'fields' => 'ids',
62 - 'meta_query' => array(
63 - array(
64 - 'key' => '_status',
65 - 'value' => 'open'
66 - ),
67 - array(
68 - 'key' => '_negotiator_id',
69 - 'value' => ''
70 - ),
71 - ),
72 - );
73 - $enquiry_query = new WP_Query( $args );
74 - if ( $enquiry_query->have_posts() )
207 + if ( apply_filters( 'propertyhive_show_admin_menu_enquiry_count', TRUE ) === TRUE )
75 208 {
76 - $count = ' <span class="update-plugins count-' . $enquiry_query->found_posts . '"><span class="plugin-count">' . $enquiry_query->found_posts . '</span></span>';
77 - }
209 + $args = array(
210 + 'post_type' => 'enquiry',
211 + 'posts_per_page' => 1,
212 + 'no_found_rows' => false,
213 + 'fields' => 'ids',
214 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Count-only menu query fetches one ID while retaining found_rows for the complete total.
215 + 'meta_query' => array(
216 + array(
217 + 'key' => '_status',
218 + 'value' => 'open'
219 + ),
220 + array(
221 + 'key' => '_negotiator_id',
222 + 'value' => ''
223 + ),
224 + ),
225 + );
226 + $args = apply_filters( 'propertyhive_admin_menu_enquiry_count_args', $args );
227 + $enquiry_query = new WP_Query( $args );
228 + if ( $enquiry_query->have_posts() )
229 + {
230 + $count = ' <span class="update-plugins count-' . $enquiry_query->found_posts . '"><span class="plugin-count">' . $enquiry_query->found_posts . '</span></span>';
231 + }
232 + }
78 233 add_submenu_page( 'propertyhive', __( 'Enquiries', 'propertyhive' ), __( 'Enquiries', 'propertyhive' ) . $count, 'manage_propertyhive', 'edit.php?post_type=enquiry'/*, array( $this, 'attributes_page' )*/ );
79 234 }
80 235
81 236 if ( get_option('propertyhive_module_disabled_appraisals', '') != 'yes' )
@@ -93,16 +248,143 @@
93 248 add_submenu_page( 'propertyhive', __( 'Offers', 'propertyhive' ), __( 'Offers', 'propertyhive' ), 'manage_propertyhive', 'edit.php?post_type=offer'/*, array( $this, 'attributes_page' )*/ );
94 249 add_submenu_page( 'propertyhive', __( 'Sales', 'propertyhive' ), __( 'Sales', 'propertyhive' ), 'manage_propertyhive', 'edit.php?post_type=sale'/*, array( $this, 'attributes_page' )*/ );
95 250 }
96 251
252 + if ( get_option( 'propertyhive_active_departments_lettings' ) == 'yes' && get_option('propertyhive_module_disabled_tenancies', '') != 'yes' )
253 + {
254 + add_submenu_page( 'propertyhive', __( 'Tenancies', 'propertyhive' ), __( 'Tenancies', 'propertyhive' ), 'manage_propertyhive', 'edit.php?post_type=tenancy'/*, array( $this, 'attributes_page' )*/ );
255 +
256 + $count = '';
257 + if ( apply_filters( 'propertyhive_show_admin_menu_key_date_count', TRUE ) === TRUE )
258 + {
259 + $args = array(
260 + 'post_type' => 'key_date',
261 + 'posts_per_page' => 1,
262 + 'no_found_rows' => false,
263 + 'fields' => 'ids',
264 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Count-only menu query fetches one ID while retaining found_rows for the complete total.
265 + 'meta_query' => array(
266 + array(
267 + 'key' => '_key_date_status',
268 + 'value' => 'pending'
269 + ),
270 + array(
271 + 'key' => '_date_due',
272 + 'value' => gmdate('Y-m-d'),
273 + 'type' => 'date',
274 + 'compare' => '<=',
275 + ),
276 + ),
277 + );
278 + $args = apply_filters( 'propertyhive_admin_menu_key_date_count_args', $args );
279 + $key_date_query = new WP_Query( $args );
280 + if ( $key_date_query->have_posts() )
281 + {
282 + $count = ' <span class="update-plugins count-' . $key_date_query->found_posts . '"><span class="plugin-count">' . $key_date_query->found_posts . '</span></span>';
283 + }
284 + }
285 + add_submenu_page( 'propertyhive', __( 'Management', 'propertyhive' ), __( 'Management', 'propertyhive' ) . $count, 'manage_propertyhive', 'edit.php?post_type=key_date&orderby=date_due&order=asc&status=upcoming_and_overdue&filter_action=Filter' );
286 + }
287 +
97 288 if ( get_option('propertyhive_module_disabled_contacts', '') != 'yes' )
98 289 {
99 - add_submenu_page( null, __( 'Applicant Matching Properties', 'propertyhive'), __( 'Applicant Matching Properties', 'propertyhive' ), 'manage_propertyhive', 'ph-matching-properties', array($this, 'matching_properties_page'));
100 - add_submenu_page( null, __( 'Generate Applicant List', 'propertyhive'), __( 'Generate Applicant List', 'propertyhive' ), 'manage_propertyhive', 'ph-generate-applicant-list', array($this, 'generate_applicant_list_page'));
101 - add_submenu_page( null, __( 'Applicant Matching Applicants', 'propertyhive'), __( 'Applicant Matching Properties', 'propertyhive' ), 'manage_propertyhive', 'ph-matching-applicants', array($this, 'matching_applicants_page'));
290 + add_submenu_page( '', __( 'Applicant Matching Properties', 'propertyhive'), __( 'Applicant Matching Properties', 'propertyhive' ), 'manage_propertyhive', 'ph-matching-properties', array($this, 'matching_properties_page'));
291 + add_submenu_page( '', __( 'Generate Applicant List', 'propertyhive'), __( 'Generate Applicant List', 'propertyhive' ), 'manage_propertyhive', 'ph-generate-applicant-list', array($this, 'generate_applicant_list_page'));
292 + add_submenu_page( '', __( 'Applicant Matching Applicants', 'propertyhive'), __( 'Applicant Matching Properties', 'propertyhive' ), 'manage_propertyhive', 'ph-matching-applicants', array($this, 'matching_applicants_page'));
293 + add_submenu_page( '', __( 'Merge Duplicate Contacts', 'propertyhive'), __( 'Merge Duplicate Contacts', 'propertyhive' ), 'manage_propertyhive', 'ph-merge-duplicate-contacts', array($this, 'generate_merge_duplicate_contacts_page'));
102 294 }
103 295 }
104 296
297 + /**
298 + * Add menu item
299 + */
300 + public function import_properties_dummy_menu()
301 + {
302 + // check clauses
303 + if ( !current_user_can( 'manage_options' ) )
304 + {
305 + // Not an administrator
306 + return;
307 + }
308 +
309 + if ( apply_filters( 'propertyhive_admin_menu_property_import_button', true ) !== true )
310 + {
311 + // Manually turned off by filter
312 + return;
313 + }
314 +
315 + if ( class_exists('PH_Property_Import') )
316 + {
317 + // Already activated. Check can be used
318 + if ( apply_filters( 'propertyhive_add_on_can_be_used', true, 'propertyhive-property-import' ) === true )
319 + {
320 + // Yes. Import add on is fine to use
321 + return;
322 + }
323 + }
324 +
325 + // check date installed more than when PRO went live
326 + $propertyhive_install_timestamp = get_option( 'propertyhive_install_timestamp', '' );
327 + if ( !empty($propertyhive_install_timestamp) )
328 + {
329 + $november_first_2023 = strtotime('2023-11-01 00:00:00');
330 + if ( $propertyhive_install_timestamp < $november_first_2023 )
331 + {
332 + // Installed before 1st Nov 2023. Don't show anything
333 + return;
334 + }
335 + }
336 +
337 + $show_dummy_link = false;
338 +
339 + $license_type = get_option( 'propertyhive_license_type', '' );
340 + if ( $license_type == '' )
341 + {
342 + $show_dummy_link = true;
343 + }
344 +
345 + if ( !$show_dummy_link )
346 + {
347 + if ( $license_type == 'old' )
348 + {
349 + // Old user. Don't do anything
350 + return;
351 + }
352 +
353 + if ( $license_type == 'pro' )
354 + {
355 + $license_key = get_option( 'propertyhive_pro_license_key', '' );
356 + if ( empty($license_key) )
357 + {
358 + // No license key entered
359 + $show_dummy_link = true;
360 + }
361 + else
362 + {
363 + if ( PH()->license->is_valid_pro_license_key() )
364 + {
365 + // valid license key.
366 + return;
367 + }
368 + else
369 + {
370 + $show_dummy_link = true;
371 + }
372 + }
373 + }
374 + }
375 +
376 + if ( $show_dummy_link === true )
377 + {
378 + add_submenu_page( 'propertyhive', __( 'Import Properties', 'propertyhive' ), __( 'Import Properties', 'propertyhive' ) . '<span class="update-plugins" style="padding:0 3px;"><span class="plugin-count">PRO</span></span>', 'manage_options', 'ph-import_properties_dummy', array( $this, 'import_properties_dummy_page' ) );
379 + }
380 + }
381 +
382 + public function import_properties_dummy_page()
383 + {
384 + include_once( 'views/html-import-properties-dummy.php' );
385 + }
386 +
105 387 /**
106 388 * Add menu item
107 389 */
108 390 public function reports_menu() {
@@ -118,15 +400,8 @@
118 400 //add_action( 'load-' . $settings_page, array( $this, 'settings_page_init' ) );
119 401 }
120 402
121 403 /**
122 - * Add menu item
123 - */
124 - public function add_ons_menu() {
125 - $settings_page = add_submenu_page( 'propertyhive', __( 'Add Ons', 'propertyhive' ), __( 'Add Ons', 'propertyhive' ) , 'manage_options', 'admin.php?page=ph-settings&tab=addons'/*, array( $this, 'settings_page' )*/ );
126 - }
127 -
128 - /**
129 404 * Loads gateways and shipping methods into memory for use within settings.
130 405 */
131 406 public function settings_page_init() {
132 407
@@ -141,71 +416,42 @@
141 416 public function menu_highlight() {
142 417
143 418 global $menu, $submenu, $parent_file, $submenu_file, $self, $post_type, $taxonomy;
144 419
145 - $to_highlight_types = array( 'property', 'contact', 'enquiry', 'appraisal', 'viewing', 'offer', 'sale' );
420 + $current_user = wp_get_current_user();
146 421
147 - if ( isset( $post_type ) ) {
148 - if ( in_array( $post_type, $to_highlight_types ) ) {
149 - $submenu_file = 'edit.php?post_type=' . esc_attr( $post_type );
150 - $parent_file = 'propertyhive';
422 + $user_id = $current_user->ID;
423 +
424 + $crm_only_mode = get_user_meta( $user_id, 'crm_only_mode', TRUE );
425 +
426 + if ( $crm_only_mode == '1' )
427 + {
428 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only CRM navigation highlighting, not a data mutation.
429 + $contact_type = isset( $_GET['_contact_type'] ) && is_string( $_GET['_contact_type'] ) ? sanitize_text_field( wp_unslash( $_GET['_contact_type'] ) ) : '';
430 + if ( $post_type == 'contact' && '' !== $contact_type )
431 + {
432 + $parent_file = 'edit.php?post_type=contact&_contact_type=' . rawurlencode( $contact_type );
151 433 }
152 434 }
435 + else
436 + {
437 + $to_highlight_types = array( 'property', 'contact', 'enquiry', 'appraisal', 'viewing', 'offer', 'sale', 'tenancy', 'key_date' );
153 438
154 - if ( isset( $submenu['propertyhive'] ) && isset( $submenu['propertyhive'][1] ) ) {
155 - $submenu['propertyhive'][0] = $submenu['propertyhive'][1];
156 - unset( $submenu['propertyhive'][1] );
439 + if ( isset( $post_type ) ) {
440 + if ( in_array( $post_type, $to_highlight_types ) ) {
441 + $submenu_file = 'edit.php?post_type=' . esc_attr( $post_type );
442 + $parent_file = 'propertyhive';
443 + }
444 + }
445 +
446 + if ( isset( $submenu['propertyhive'] ) && isset( $submenu['propertyhive'][1] ) ) {
447 + $submenu['propertyhive'][0] = $submenu['propertyhive'][1];
448 + unset( $submenu['propertyhive'][1] );
449 + }
157 450 }
158 451 }
159 452
160 453 /**
161 - * Reorder the PH menu items in admin.
162 - *
163 - * @param mixed $menu_order
164 - * @return array
165 - */
166 - public function menu_order( $menu_order ) {
167 -
168 -
169 - // Initialize our custom order array
170 - $propertyhive_menu_order = array();
171 -
172 - // Get the index of our custom separator
173 - $propertyhive_separator = array_search( 'separator-propertyhive', $menu_order );
174 -
175 - // Get index of product menu
176 - $propertyhive_property = array_search( 'edit.php?post_type=property', $menu_order );
177 -
178 - // Loop through menu order and do some rearranging
179 - foreach ( $menu_order as $index => $item ) :
180 -
181 - if ( ( ( 'propertyhive' ) == $item ) ) :
182 - $propertyhive_menu_order[] = 'separator-propertyhive';
183 - $propertyhive_menu_order[] = $item;
184 - $propertyhive_menu_order[] = 'edit.php?post_type=property';
185 - unset( $menu_order[$propertyhive_separator] );
186 - unset( $menu_order[$propertyhive_property] );
187 - elseif ( !in_array( $item, array( 'separator-propertyhive' ) ) ) :
188 - $propertyhive_menu_order[] = $item;
189 - endif;
190 -
191 - endforeach;
192 -
193 - // Return order
194 - return $propertyhive_menu_order;
195 - }
196 -
197 - /**
198 - * custom_menu_order
199 - * @return bool
200 - */
201 - public function custom_menu_order() {
202 - if ( ! current_user_can( 'manage_propertyhive' ) )
203 - return false;
204 - return true;
205 - }
206 -
207 - /**
208 454 * Init the reports page
209 455 */
210 456 public function reports_page() {
211 457 include_once( 'class-ph-admin-reports.php' );
@@ -233,9 +479,10 @@
233 479 * Init the applicant list page
234 480 */
235 481 public function generate_applicant_list_page() {
236 482 include_once( 'class-ph-admin-applicant-list.php' );
237 - PH_Admin_Applicant_List::output();
483 + $ph_admin_applicant_list = new PH_Admin_Applicant_List();
484 + $ph_admin_applicant_list->output();
238 485 }
239 486
240 487 /**
241 488 * Init the property matching applicants page
@@ -246,13 +493,100 @@
246 493 $ph_admin_matching_applicants->output();
247 494 }
248 495
249 496 /**
250 - * Init the status page
497 + * Init the merge contacts page
251 498 */
252 - public function status_page() {
253 - $page = include( 'class-ph-admin-status.php' );
254 - $page->output();
499 + public function generate_merge_duplicate_contacts_page() {
500 + include_once( 'class-ph-admin-merge-contacts.php' );
501 + $ph_admin_merge_contacts = new PH_Admin_Merge_Contacts();
502 + $ph_admin_merge_contacts->output();
503 + }
504 +
505 + private function get_menu_icon( $section = '' )
506 + {
507 + // extract post type
508 + $explode_section = explode("?", $section, 2);
509 + $tab = '';
510 + if ( count($explode_section) == 2 )
511 + {
512 + parse_str( $explode_section[1], $array );
513 +
514 + if ( isset($array['post_type']) )
515 + {
516 + $section = $array['post_type'];
517 + }
518 + elseif ( isset($array['page']) )
519 + {
520 + $section = $array['page'];
521 + if ( isset($array['tab']) )
522 + {
523 + $tab = $array['tab'];
524 + }
525 + }
526 + }
527 +
528 + $icon = PH()->plugin_url() . '/assets/images/menu-icon.png';
529 + switch ( $section )
530 + {
531 + case "contact":
532 + {
533 + $icon = "dashicons-admin-users";
534 + break;
535 + }
536 + case "property":
537 + {
538 + $icon = "dashicons-admin-home";
539 + break;
540 + }
541 + case "appraisal":
542 + {
543 + $icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzgwIiBoZWlnaHQ9IjM5MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDxnPgogIDx0aXRsZT5MYXllciAxPC90aXRsZT4KICA8cGF0aCBmaWxsPSIjZjBmMGYxIiBpZD0ic3ZnXzEiIGQ9Im0xOTAuMjA5MDU3LDYuMjExNDA4Yy0xMDMuNzU0LDAgLTE4OC4xNjEsODQuNDEzIC0xODguMTYxLDE4OC4xNjdzODQuNDA3LDE4OC4xNTUgMTg4LjE2MSwxODguMTU1YzEwMy43NiwwIDE4OC4xNjcsLTg0LjQwMSAxODguMTY3LC0xODguMTU1cy04NC40MDcsLTE4OC4xNjcgLTE4OC4xNjcsLTE4OC4xNjd6bTAsMzQ2LjY0MmMtODcuMzgzLDAgLTE1OC40NzYsLTcxLjA5MyAtMTU4LjQ3NiwtMTU4LjQ3NmMwLC04Ny4zOTUgNzEuMDkyLC0xNTguNDg3IDE1OC40NzYsLTE1OC40ODdjODcuMzg5LDAgMTU4LjQ4Nyw3MS4wOTMgMTU4LjQ4NywxNTguNDg3YzAuMDAxLDg3LjM4MyAtNzEuMDk4LDE1OC40NzYgLTE1OC40ODcsMTU4LjQ3NnoiLz4KICA8cGF0aCBmaWxsPSIjZjBmMGYxIiBpZD0ic3ZnXzIiIGQ9Im0yMTcuMjIxMDYsMTE1LjY4MjRjMTQuODA2LDAgMTguODY3LDEwLjczOSAyMi45MjksMjMuNTIybDEzLjkzOCwtMTcuNzA3Yy00LjY0NSwtMTguNTg3IC0xNy40MjIsLTI5LjYxMSAtNDIuOTY3LC0yOS42MTFjLTQzLjg0NSwwIC00OS4wNjYsMzEuOTMxIC00OS4wNjYsNTkuNzk0bDAsMzAuMjA1bC0yMS40OSwwbC01LjgwMywyNC4zOTFsMjUuODM1LDBjLTMuMTkzLDMyLjgxMSAtMTEuNjEyLDYzLjU3NSAtMzQuMjYxLDkwLjU4MmwxMjUuMTQ2LDBsMCwtMzAuMTk1bC03MC41NjcsMGM5LjAwMiwtMjAuNjIxIDEyLjQ5OCwtMzguNjE0IDEzLjk0OCwtNjAuMzg5bDQ4LjQ3OSwwbDUuODEsLTI0LjM5MWwtNTMuMTM0LDBsMCwtMjQuMzkxYzAsLTIyLjY0MSAxLjE2NiwtNDEuODEgMjEuMjAzLC00MS44MXoiLz4KIDwvZz4KPC9zdmc+";
544 + break;
545 + }
546 + case "viewing":
547 + {
548 + $icon = "dashicons-visibility";
549 + break;
550 + }
551 + case "enquiry":
552 + {
553 + $icon = "dashicons-admin-comments";
554 + break;
555 + }
556 + case "offer":
557 + case "sale":
558 + {
559 + $icon = "dashicons-tag";
560 + break;
561 + }
562 + case "tenancy":
563 + {
564 + $icon = "dashicons-admin-network";
565 + break;
566 + }
567 + case "key_date":
568 + {
569 + $icon = "dashicons-admin-network";
570 + break;
571 + }
572 + case "ph-reports":
573 + {
574 + $icon = "dashicons-chart-bar";
575 + break;
576 + }
577 + case "ph-settings":
578 + {
579 + $icon = "dashicons-admin-settings";
580 + if ( $tab == 'addons' )
581 + {
582 + $icon = "dashicons-insert";
583 + }
584 + break;
585 + }
586 + }
587 + $icon = apply_filters( 'propertyhive_menu_icon', $icon, $section );
588 + return $icon;
255 589 }
256 590
257 591 }
258 592