PluginProbe
Property Hive / 1.4.61
Property Hive v1.4.61
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
propertyhive / propertyhive.php

propertyhive.php in Property Hive 1.4.61, at propertyhive.php

503 lines 17.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Property Hive
4 * Plugin URI: https://wordpress.org/plugins/propertyhive/
5 * Description: Estate Agency Property Software Plugin for WordPress
6 * Version: 1.4.61
7 * Author: PropertyHive
8 * Author URI: https://wp-property-hive.com
9 * Requires at least: 3.8
10 * Tested up to: 5.4.1
11 *
12 * Text Domain: propertyhive
13 * Domain Path: /i18n/languages/
14 *
15 * @package PropertyHive
16 * @category Core
17 * @author PropertyHive
18 */
19
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit; // Exit if accessed directly
22 }
23
24 if ( ! class_exists( 'PropertyHive' ) )
25 {
26 /**
27 * Main PropertyHive Class
28 *
29 * @class PropertyHive
30 * @version 1.4.61
31 */
32 final class PropertyHive {
33
34 /**
35 * @var string
36 */
37 public $version = '1.4.61';
38
39 /**
40 * @var PropertyHive The single instance of the class
41 */
42 protected static $_instance = null;
43
44 /**
45 * Query instance.
46 *
47 * @var PH_Query
48 */
49 public $query = null;
50
51 /**
52 * Email instance.
53 *
54 * @var PH_Emails
55 */
56 public $email = null;
57
58 /**
59 * Main PropertyHive Instance
60 *
61 * Ensures only one instance of PropertyHive is loaded or can be loaded.
62 *
63 * @static
64 * @return PropertyHive - Main instance
65 */
66 public static function instance()
67 {
68 if ( is_null( self::$_instance ) )
69 {
70 self::$_instance = new self();
71 }
72 return self::$_instance;
73 }
74
75 /**
76 * Cloning is forbidden.
77 *
78 * @since 1.0.0
79 */
80 public function __clone() {
81 _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'propertyhive' ), '1.0.0' );
82 }
83
84 /**
85 * Unserializing instances of this class is forbidden.
86 *
87 * @since 1.0.0
88 */
89 public function __wakeup() {
90 _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'propertyhive' ), '1.0.0' );
91 }
92
93 /**
94 * PropertyHive Constructor.
95 * @access public
96 * @return PropertyHive
97 */
98 public function __construct()
99 {
100 // Auto-load classes on demand
101 if ( function_exists( "__autoload" ) ) {
102 spl_autoload_register( "__autoload" );
103 }
104
105 spl_autoload_register( array( $this, 'autoload' ) );
106
107 // Define constants
108 $this->define_constants();
109
110 // Include required files
111 $this->includes();
112
113 // Init API
114 //$this->api = new PH_API();
115
116 // Hooks
117 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'action_links' ) );
118 //add_action( 'widgets_init', array( $this, 'include_widgets' ) );
119 add_action( 'init', array( $this, 'init' ), 0 );
120 add_action( 'init', array( $this, 'include_template_functions' ) );
121 add_action( 'init', array( $this, 'unsubscribe_contact' ), 0 );
122 add_action( 'init', array( 'PH_Shortcodes', 'init' ) );
123 add_action( 'rest_api_init', array( $this, 'rest_api_includes' ) );
124 add_action( 'after_setup_theme', array( $this, 'setup_environment' ) );
125
126 // Loaded action
127 do_action( 'propertyhive_loaded' );
128 }
129
130 /**
131 * Show action links on the plugin screen
132 *
133 * @param mixed $links
134 * @return array
135 */
136 public function action_links( $links )
137 {
138 return array_merge( array(
139 '<a href="' . admin_url( 'admin.php?page=ph-settings' ) . '">' . __( 'Settings', 'propertyhive' ) . '</a>',
140 '<a href="' . esc_url( apply_filters( 'propertyhive_url', 'https://wp-property-hive.com/', 'propertyhive' ) ) . '" target="_blank">' . __( 'Website', 'propertyhive' ) . '</a>',
141 '<a href="' . esc_url( apply_filters( 'propertyhive_addons_url', 'https://wp-property-hive.com/add-ons' ) ) . '" target="_blank">' . __( 'Add Ons', 'propertyhive' ) . '</a>',
142 ), $links );
143 }
144
145 /**
146 * Auto-load PH classes on demand to reduce memory consumption.
147 *
148 * @param mixed $class
149 * @return void
150 */
151 public function autoload( $class )
152 {
153 $path = null;
154 $class = strtolower( $class );
155 $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
156
157 if ( strpos( $class, 'ph_shortcode_' ) === 0 ) {
158 $path = $this->plugin_path() . '/includes/shortcodes/';
159 } elseif ( strpos( $class, 'ph_meta_box' ) === 0 ) {
160 $path = $this->plugin_path() . '/includes/admin/post-types/meta-boxes/';
161 } elseif ( strpos( $class, 'ph_admin' ) === 0 ) {
162 $path = $this->plugin_path() . '/includes/admin/';
163 }
164
165 if ( $path && is_readable( $path . $file ) ) {
166 include_once( $path . $file );
167 return;
168 }
169
170 // Fallback
171 if ( strpos( $class, 'ph_' ) === 0 ) {
172 $path = $this->plugin_path() . '/includes/';
173 }
174
175 if ( $path && is_readable( $path . $file ) ) {
176 include_once( $path . $file );
177 return;
178 }
179 }
180
181 /**
182 * Define PH Constants
183 */
184 private function define_constants()
185 {
186 define( 'PH_PLUGIN_FILE', __FILE__ );
187 define( 'PH_VERSION', $this->version );
188
189 if ( ! defined( 'PH_TEMPLATE_PATH' ) ) {
190 define( 'PH_TEMPLATE_PATH', $this->template_path() );
191 }
192 }
193
194 /**
195 * Include required core files used in admin and on the frontend.
196 */
197 private function includes() {
198 include_once( 'includes/ph-core-functions.php' );
199 include_once( 'includes/class-ph-install.php' );
200 include_once( 'includes/class-ph-comments.php' );
201 include_once( 'includes/class-ph-emails.php' );
202 include_once( 'includes/class-ph-licenses.php' );
203
204 if ( is_admin() ) {
205 include_once( 'includes/admin/class-ph-admin.php' );
206 include_once( 'includes/class-ph-third-party-contacts.php' );
207 }
208
209 if ( defined( 'DOING_AJAX' ) ) {
210 $this->ajax_includes();
211 }
212
213 if ( ! is_admin() || defined( 'DOING_AJAX' ) || (isset($_GET['action']) && $_GET['action'] == 'elementor') ) {
214 $this->frontend_includes();
215 }
216
217 include_once( 'includes/ph-form-functions.php' ); // Form Renderers
218 include_once( 'includes/class-ph-form-handler.php' ); // Form Handlers
219 include_once( 'includes/class-ph-shortcodes.php' ); // Shortcodes class
220
221 include( 'includes/class-ph-query.php' ); // The main query class
222
223 include_once( 'includes/class-ph-post-types.php' ); // Registers post types
224 include_once( 'includes/class-ph-countries.php' ); // Manages interaction with countries and currency
225
226 include_once( 'includes/class-ph-user-contacts.php' ); // Handles keeping contacts and users in sync
227
228 include_once( 'includes/class-ph-elementor.php' ); // Elementor
229 include_once( 'includes/class-ph-yoast-seo.php' ); // Yoast SEO
230
231 $this->query = new PH_Query();
232 $this->email = new PH_Emails();
233 $this->license = new PH_Licenses();
234 }
235
236 public function rest_api_includes()
237 {
238 include_once( 'includes/class-ph-rest-api.php' );
239 $this->rest_api = new PH_Rest_Api();
240 }
241
242 /**
243 * Include required ajax files.
244 */
245 public function ajax_includes() {
246 include_once( 'includes/class-ph-ajax.php' ); // Ajax functions for admin and the front-end
247 }
248
249 /**
250 * Include required frontend files.
251 */
252 public function frontend_includes() {
253 include_once( 'includes/ph-template-hooks.php' );
254 include_once( 'includes/class-ph-template-loader.php' ); // Template Loader
255 include_once( 'includes/class-ph-frontend-scripts.php' ); // Frontend Scripts
256 }
257
258 /**
259 * Function used to Init PropertyHive Template Functions - This makes them pluggable by plugins and themes.
260 */
261 public function include_template_functions() {
262 include_once( 'includes/ph-template-functions.php' );
263 }
264
265 /**
266 * Include core widgets
267 */
268 public function include_widgets() {
269 /*include_once( 'includes/abstracts/abstract-ph-widget.php' );
270 include_once( 'includes/widgets/class-ph-widget-properties.php' );*/
271 }
272
273 /**
274 * Unsubscribe contact if ph_unsubscribe param set in query string. Might be a better place for this
275 */
276 public function unsubscribe_contact() {
277 if ( isset($_GET['ph_unsubscribe']) && !empty($_GET['ph_unsubscribe']) )
278 {
279 $ph_unsubscribe = sanitize_text_field(base64_decode($_GET['ph_unsubscribe']));
280 if ( $ph_unsubscribe === FALSE )
281 {
282 die("Invalid token passed 1");
283 return false;
284 }
285
286 $explode_ph_unsubscribe = explode("|", $ph_unsubscribe);
287 if ( count($explode_ph_unsubscribe) != 2 )
288 {
289 die("Invalid token passed 2");
290 return false;
291 }
292
293 $contact_id = $explode_ph_unsubscribe[0];
294 if ( FALSE === get_post_status( $contact_id ) )
295 {
296 die("Invalid token passed 3");
297 return false;
298 }
299 $contact_email = get_post_meta( $contact_id, '_email_address', TRUE );
300
301 if (md5($contact_email) != $explode_ph_unsubscribe[1])
302 {
303 die("Invalid token passed 4");
304 return false;
305 }
306
307 // TODO: Make sure not already unsubscribed
308
309 // We've got this far. We received a valid token and email address
310 $forbidden_contact_methods = get_post_meta( $contact_id, '_forbidden_contact_methods', TRUE );
311 if (!is_array($forbidden_contact_methods))
312 {
313 $forbidden_contact_methods = array();
314 }
315 $forbidden_contact_methods[] = 'email';
316 update_post_meta( $contact_id, '_forbidden_contact_methods', array_unique($forbidden_contact_methods) );
317
318 // Write note to applicant
319 $comment = array(
320 'note_type' => 'unsubscribe'
321 );
322
323 $data = array(
324 'comment_post_ID' => $contact_id,
325 'comment_author' => 'Property Hive',
326 'comment_author_email' => 'propertyhive@noreply.com',
327 'comment_author_url' => '',
328 'comment_date' => date("Y-m-d H:i:s"),
329 'comment_content' => serialize($comment),
330 'comment_approved' => 1,
331 'comment_type' => 'propertyhive_note',
332 );
333 wp_insert_comment( $data );
334
335 die("You have been unsubscribed successfully. Please allow up to 24 hours for this to take effect.");
336 }
337 }
338
339 /**
340 * Init PropertyHive when WordPress Initialises.
341 */
342 public function init() {
343 // Before init action
344 do_action( 'before_propertyhive_init' );
345
346 // Set up localisation
347 $this->load_plugin_textdomain();
348
349 // Session class, handles session data for users - can be overwritten if custom handler is needed
350 //$session_class = apply_filters( 'propertyhive_session_handler', 'PH_Session_Handler' );
351
352 // Load class instances
353 //$this->product_factory = new PH_Product_Factory(); // Product Factory to create new product instances
354 $this->countries = new PH_Countries(); // Countries class
355 //$this->integrations = new PH_Integrations(); // Integrations class
356 // $this->session = new $session_class();
357
358 // Email Actions
359 /*$email_actions = array(
360 'propertyhive_low_stock',
361 'propertyhive_no_stock',
362 'propertyhive_product_on_backorder',
363 'propertyhive_order_status_pending_to_processing',
364 'propertyhive_order_status_pending_to_completed',
365 'propertyhive_order_status_pending_to_on-hold',
366 'propertyhive_order_status_failed_to_processing',
367 'propertyhive_order_status_failed_to_completed',
368 'propertyhive_order_status_completed',
369 'propertyhive_new_customer_note',
370 'propertyhive_created_customer'
371 );
372
373 foreach ( $email_actions as $action )
374 add_action( $action, array( $this, 'send_transactional_email' ), 10, 10 );*/
375
376 // Init action
377 do_action( 'propertyhive_init' );
378 }
379
380 /**
381 * Load Localisation files.
382 *
383 * Note: the first-loaded translation file overrides any following ones if the same translation is present
384 */
385 public function load_plugin_textdomain() {
386 $locale = apply_filters( 'plugin_locale', get_locale(), 'propertyhive' );
387
388 // Admin Locale
389 if ( is_admin() ) {
390 load_textdomain( 'propertyhive', WP_LANG_DIR . "/propertyhive/propertyhive-admin-$locale.mo" );
391 load_textdomain( 'propertyhive', dirname( __FILE__ ) . "/i18n/languages/propertyhive-admin-$locale.mo" );
392 }
393
394 // Global + Frontend Locale
395 load_textdomain( 'propertyhive', WP_LANG_DIR . "/propertyhive/propertyhive-$locale.mo" );
396 load_plugin_textdomain( 'propertyhive', false, plugin_basename( dirname( __FILE__ ) ) . "/i18n/languages" );
397 }
398
399 /**
400 * Ensure theme and server variable compatibility and setup image sizes..
401 */
402 public function setup_environment() {
403
404 // IIS
405 if ( ! isset($_SERVER['REQUEST_URI'] ) ) {
406 $_SERVER['REQUEST_URI'] = substr( $_SERVER['PHP_SELF'], 1 );
407 if ( isset( $_SERVER['QUERY_STRING'] ) ) {
408 $_SERVER['REQUEST_URI'].='?'.$_SERVER['QUERY_STRING'];
409 }
410 }
411
412 // NGINX Proxy
413 if ( ! isset( $_SERVER['REMOTE_ADDR'] ) && isset( $_SERVER['HTTP_REMOTE_ADDR'] ) ) {
414 $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_REMOTE_ADDR'];
415 }
416
417 if ( ! isset( $_SERVER['HTTPS'] ) && ! empty( $_SERVER['HTTP_HTTPS'] ) ) {
418 $_SERVER['HTTPS'] = $_SERVER['HTTP_HTTPS'];
419 }
420
421 // Support for hosts which don't use HTTPS, and use HTTP_X_FORWARDED_PROTO
422 if ( ! isset( $_SERVER['HTTPS'] ) && ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
423 $_SERVER['HTTPS'] = '1';
424 }
425 }
426
427 /** Helper functions ******************************************************/
428
429 /**
430 * Get the plugin url.
431 *
432 * @return string
433 */
434 public function plugin_url() {
435 return untrailingslashit( plugins_url( '/', __FILE__ ) );
436 }
437
438 /**
439 * Get the plugin path.
440 *
441 * @return string
442 */
443 public function plugin_path() {
444 return untrailingslashit( plugin_dir_path( __FILE__ ) );
445 }
446
447 /**
448 * Get the template path.
449 *
450 * @return string
451 */
452 public function template_path() {
453 return apply_filters( 'PH_TEMPLATE_PATH', 'propertyhive/' );
454 }
455
456 /**
457 * Get Ajax URL.
458 *
459 * @return string
460 */
461 public function ajax_url() {
462 return admin_url( 'admin-ajax.php', 'relative' );
463 }
464
465 /**
466 * Return the WC API URL for a given request
467 *
468 * @param mixed $request
469 * @param mixed $ssl (default: null)
470 * @return string
471 */
472 public function api_request_url( $request, $ssl = null ) {
473 if ( is_null( $ssl ) ) {
474 $scheme = parse_url( get_option( 'home' ), PHP_URL_SCHEME );
475 } elseif ( $ssl ) {
476 $scheme = 'https';
477 } else {
478 $scheme = 'http';
479 }
480
481 if ( get_option('permalink_structure') ) {
482 return esc_url_raw( trailingslashit( home_url( '/ph-api/' . $request, $scheme ) ) );
483 } else {
484 return esc_url_raw( add_query_arg( 'ph-api', $request, trailingslashit( home_url( '', $scheme ) ) ) );
485 }
486 }
487
488 }
489
490 }
491
492 /**
493 * Returns the main instance of PH to prevent the need to use globals.
494 *
495 * @since 1.0.0
496 * @return PropertyHive
497 */
498 function PH() {
499 return PropertyHive::instance();
500 }
501
502 // Global for backwards compatibility.
503 $GLOBALS['propertyhive'] = PH();