PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 5.8.1
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v5.8.1
7.2 7.1.2 7.1.1 7.1 7.0.4 7.0.6 7.0.7 6.3.8 6.3.7 6.3.6 6.3.5 6.3.4 6.3.3 6.3.1 trunk 5.7.3 5.7.5 5.8.1 5.8.2 5.8.3 5.8.4 5.8.6 6.0.4 6.0.5 6.0.7 All 35 releases
mlsimport / mlsimport.php

mlsimport.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 5.8.1, at mlsimport.php

435 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: MlsImport
4 * Plugin URI: https://mlsimport.com/
5 * Description: "MLS Import - The MLSImport plugin facilitates the connection to your real estate MLS database, allowing you to download and synchronize real estate property data from the MLS.
6 * Version: 5.8.1
7 * Requires at least: 5.2
8 * Requires PHP: 7.2
9 * License: GPLv3
10 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
11 * Author: MlsImport
12 * Text Domain: mlsimport
13 * Domain Path: /languages
14 */
15
16 // If this file is called directly, abort.
17
18 if ( ! defined( 'WPINC' ) ) {
19 die;
20 }
21
22
23 define( 'MLSIMPORT_VERSION', '5.8.1' );
24 define( 'MLSIMPORT_CLUBLINK', 'mlsimport.com' );
25 define( 'MLSIMPORT_CLUBLINKSSL', 'https' );
26 define( 'MLSIMPORT_CRON_STEP', 20 );
27 define( 'MLSIMPORT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
28 define( 'MLSIMPORT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
29 define( 'MLSIMPORT_API_URL', 'https://requests.mlsimport.com/' );
30
31
32
33 /**
34 * The code that runs during plugin activation.
35 * This action is documented in includes/class-mlsimport-activator.php
36 */
37 function mlsimport_activate() {
38 require_once plugin_dir_path( __FILE__ ) . 'includes/class-mlsimport-activator.php';
39 Mlsimport_Activator::activate();
40 }
41
42
43
44 /**
45 * The code that runs during plugin deactivation.
46 * This action is documented in includes/class-mlsimport-deactivator.php
47 */
48 function mlsimport_deactivate() {
49 require_once plugin_dir_path( __FILE__ ) . 'includes/class-mlsimport-deactivator.php';
50 wp_clear_scheduled_hook( 'event_mls_import_auto' );
51 wp_clear_scheduled_hook( 'mlsimport_reconciliation_event' );
52 Mlsimport_Deactivator::deactivate();
53 }
54
55
56
57 register_activation_hook( __FILE__, 'mlsimport_activate' );
58 register_deactivation_hook( __FILE__, 'mlsimport_deactivate' );
59
60
61
62 /**
63 * The core plugin class that is used to define internationalization,
64 * admin-specific hooks, and public-facing site hooks.
65 */
66
67 require 'vendor/autoload.php';
68 require_once plugin_dir_path( __FILE__ ) . 'includes/help_functions.php';
69 require_once plugin_dir_path( __FILE__ ) . 'includes/class-mlsimport.php';
70 require_once plugin_dir_path( __FILE__ ) . 'includes/ThemeImport.php';
71 require_once plugin_dir_path( __FILE__ ) . 'enviroment/ResidenceClass.php';
72 require_once plugin_dir_path( __FILE__ ) . 'enviroment/EstateClass.php';
73 require_once plugin_dir_path( __FILE__ ) . 'enviroment/HouzezClass.php';
74 require_once plugin_dir_path( __FILE__ ) . 'enviroment/RealHomesClass.php';
75 require_once plugin_dir_path( __FILE__ ) . 'enviroment/ResoBase.php';
76 require_once plugin_dir_path( __FILE__ ) . 'enviroment/SparkResoClass.php';
77 require_once plugin_dir_path( __FILE__ ) . 'enviroment/BridgeResoClass.php';
78 require_once plugin_dir_path( __FILE__ ) . 'enviroment/TresleResoClass.php';
79 require_once plugin_dir_path( __FILE__ ) . 'enviroment/MlsgridResoClass.php';
80 require_once plugin_dir_path( __FILE__ ) . 'enviroment/MlsgridResoClass.php';
81
82
83
84 if ( ! wp_next_scheduled( 'event_mls_import_auto' ) ) {
85 wp_schedule_event( time(), 'hourly', 'event_mls_import_auto' );
86 }
87
88
89
90
91
92
93
94 add_action( 'event_mls_import_auto', 'mlsimport_saas_event_mls_import_auto_function' );
95 function mlsimport_saas_event_mls_import_auto_function() {
96 global $mlsimport;
97 $token = $mlsimport->admin->mlsimport_saas_get_mls_api_token_from_transient();
98 if ( trim( $token ) === '' ) {
99 return;
100 }
101
102 $is_mls_connected = get_option( 'mlsimport_connection_test', '' );
103 if ( 'yes' !== $is_mls_connected ) {
104 return;
105 }
106
107 $logs ='';
108 mlsimport_debuglogs_per_plugin( $logs );
109 $args = array(
110 'post_type' => 'mlsimport_item',
111 'post_status' => 'any',
112 'posts_per_page' => -1,
113 'meta_query' => array(
114 array(
115 'key' => 'mlsimport_item_stat_cron',
116 'value' => 1,
117 'compare' => '=',
118 ),
119
120 ),
121
122 );
123
124 $prop_selection = new WP_Query( $args );
125 if ( $prop_selection->have_posts() ) {
126 while ( $prop_selection->have_posts() ) :
127 $prop_selection->the_post();
128 $prop_id = get_the_ID();
129 $logs = ' Loop custom post : ' . $prop_id . PHP_EOL;
130 mlsimport_debuglogs_per_plugin( $logs );
131 $mlsimport->admin->mlsimport_saas_start_cron_links_per_item( $prop_id );
132 endwhile;
133 }
134 }
135
136
137
138 /*
139 * Reconciliation Mechanism
140 *
141 *
142 *
143 **/
144
145 if ( ! wp_next_scheduled( 'mlsimport_reconciliation_event' ) ) {
146 wp_schedule_event( time(), 'daily', 'mlsimport_reconciliation_event' );
147 }
148
149 add_action( 'mlsimport_reconciliation_event', 'mlsimport_saas_reconciliation_event_function' );
150
151
152 /*
153 * Force use of transient
154 *
155 *
156 *
157 **/
158
159 function mlsimport_force_use_transient( $value ) {
160 return $value;
161 // return false;
162 }
163
164
165
166
167 global $mlsimport;
168 $mlsimport = new Mlsimport();
169 $mlsimport->run();
170
171
172
173
174
175 $supported_theme = array(
176 991 => 'WpResidence',
177 992 => 'Houzez',
178 993 => 'Real Homes',
179 994 => 'Wpestate',
180
181 );
182
183 define( 'MLSIMPORT_THEME', $supported_theme );
184
185 add_filter( 'action_scheduler_failure_period', 'mlsimport_saas_filter_timelimit' );
186 function mlsimport_saas_filter_timelimit( $time_limit ) {
187 return 3000;
188 }
189
190
191
192 /*
193 *
194 * Write logs
195 *
196 **/
197
198 function mlsimport_saas_single_write_import_custom_logs( $message, $tip_import = 'normal' ) {
199 // Check if logging is enabled
200 $enable_logs = intval( get_option( 'mlsimport_disable_logs' ) );
201 if ( 1 !== $enable_logs) {
202 return;
203 }
204
205 if ( is_array( $message ) ) {
206 $message = wp_json_encode( $message );
207 }
208
209 $formatted_message = gmdate( 'F j, Y, g:i a' ) . ' -> ' . $message;
210
211 // Determine the log file path based on the import type
212 $log_file_name = 'cron' === $tip_import ? 'cron_logs' :
213 ( 'delete' === $tip_import ? 'delete_logs' :
214 ( 'server_cron' === $tip_import ? 'server_cron_logs' : 'import_logs' ) );
215
216 // Construct the full path with a date suffix
217 $log_file_path = WP_PLUGIN_DIR . "/mlsimport/logs/{$log_file_name}-" . gmdate( 'Y-m-d' ) . '.log';
218
219 // Error handling for file operations
220 try {
221 // Check and create the directory for logs if it does not exist
222 $log_dir = dirname( $log_file_path );
223 if ( ! file_exists( $log_dir ) ) {
224 mkdir( $log_dir, 0755, true );
225 }
226
227 // Append the formatted message to the log file
228 file_put_contents( $log_file_path, $formatted_message, FILE_APPEND | LOCK_EX );
229 } catch ( Exception $e ) {
230 // Handle the exception, such as logging the error elsewhere or sending a notification
231 }
232 }
233
234
235
236 /*
237 *
238 *
239 * Write Status logs
240 *
241 *
242 **/
243
244
245
246 function mlsimport_debuglogs_per_plugin_old( $message ) {
247
248 if ( is_array( $message ) ) {
249 $message = wp_json_encode( $message );
250 }
251
252 global $wp_filesystem;
253 if ( empty( $wp_filesystem ) ) {
254 require_once ABSPATH . '/wp-admin/includes/file.php';
255 WP_Filesystem();
256 }
257
258 $path_status = WP_PLUGIN_DIR . '/mlsimport/logs/status_logs.log';
259 file_put_contents( $path_status, $message, LOCK_EX );
260 }
261 function mlsimport_debuglogs_per_plugin( $message ) {
262
263 if ( is_array( $message ) ) {
264 $message = wp_json_encode( $message );
265 }
266
267 if ( empty( $message ) ) {
268 return; // Exit the function if there's nothing to log
269 }
270
271 $log_file_path = WP_PLUGIN_DIR . '/mlsimport/logs/status_logs.log';
272
273 // Check and create the directory for logs if it does not exist
274 $log_dir = dirname( $log_file_path );
275 if ( ! file_exists( $log_dir ) ) {
276 mkdir( $log_dir, 0755, true );
277 }
278
279 // Error handling for file operations
280 try {
281 // Append the message to the log file with a newline and acquire an exclusive lock during writing
282 file_put_contents( $log_file_path, $message . PHP_EOL, LOCK_EX );
283 } catch ( Exception $e ) {
284 // Handle the exception, such as logging the error elsewhere or sending a notification
285 }
286 }
287
288
289
290
291
292 /*
293 * Cron job trigger
294 *
295 *
296 *
297 **/
298
299
300 // */5 * * * * wget http://example.com/check */2
301 add_action( 'init', 'mlsimport_trigger_cron_job' );
302 function mlsimport_trigger_cron_job() {
303 // ?mlsimport_cron=yes
304 if ( isset( $_REQUEST['mlsimport_cron'] ) && 'yes' === sanitize_text_field( wp_unslash( $_REQUEST['mlsimport_cron'] ) ) ) {
305 $last_run = intval( get_option( 'mlsimport_last_server_cron' ) );
306 $now = time();
307 if ( 0 === intval($last_run) ) {
308 update_option( 'mlsimport_last_server_cron', $now );
309 }
310
311 if ( $last_run < $now - ( 60 * 60 * 2 ) ) {
312 $log = 'Server Cron Job triggered on ' . date( 'l jS \of F Y h:i:s A', $last_run ) . ' vs ' . gmdate( 'l jS \of F Y h:i:s A', $now ) . PHP_EOL;
313 // mlsimport_saas_event_mls_import_auto_function();
314 update_option( 'mlsimport_last_server_cron', $now );
315 } else {
316 $log = 'Server Cron Job Called but not triggered. Last run on ' . gmdate( 'l jS \of F Y h:i:s A', $last_run ) . ' vs ' . gmdate( 'l jS \of F Y h:i:s A', $now ) . PHP_EOL;
317 }
318
319 mlsimport_saas_single_write_import_custom_logs( $log, 'server_cron' );
320 }
321 }
322
323
324
325 function mlsimport_show_signup() {
326 $affiliate_url = 'https://mlsimport.com';
327 if ( function_exists( 'wp_estate_init' ) ) {
328 $affiliate_url = 'https://mlsimport.com/ref/1/?campaign=wpresidence';
329 }
330 ?>
331 <div class="mlsimport_signup">
332 <h3><?php esc_html_e('Import MLS Listings into your Real Estate website', 'mlsimport'); ?></h3>
333 <p><?php esc_html_e('Signup now and get 30-Days Free trial, no setup fee & cancel anytime at ', 'mlsimport'); ?><a href="<?php echo esc_url($affiliate_url); ?>" target="_blank">MlsImport.com</a></p>
334 <a href="<?php echo esc_url($affiliate_url); ?>" class="button mlsimport_button mlsimport_signup_button" target="_blank"><?php esc_html_e('Create My Account', 'mlsimport'); ?></a>
335 </div>
336 <?php
337 }
338
339 /*
340
341 // Register the hook before calling the scheduling function
342 add_action('mlsimport_delete_empty_terms_batch_event', 'mlsimport_delete_empty_terms_batch', 10, 3);
343
344 // Call this function with your taxonomy to start the deletion process
345 mlsimport_schedule_empty_terms_deletion('property_area');
346
347 function mlsimport_schedule_empty_terms_deletion($taxonomy) {
348 // Clear any existing scheduled events
349 wp_clear_scheduled_hook('mlsimport_delete_empty_terms_batch_event');
350
351 // Schedule the first batch
352 if (!wp_next_scheduled('mlsimport_delete_empty_terms_batch_event', array($taxonomy, 100, 0))) {
353 wp_schedule_single_event(time() + 30, 'mlsimport_delete_empty_terms_batch_event', array($taxonomy, 100, 0));
354 echo 'Scheduled first batch event.<br>';
355 } else {
356 echo 'First batch event already scheduled.<br>';
357 }
358 }
359
360 function mlsimport_delete_empty_terms_batch($taxonomy, $batch_size = 100, $offset = 0) {
361 // Debugging output to confirm function execution
362 echo 'Processing batch starting from offset: ' . $offset . '<br>';
363
364 // Get terms in batches
365 $terms = get_terms(array(
366 'taxonomy' => $taxonomy,
367 'hide_empty' => false, // Include empty terms
368 'orderby' => 'count',
369 'order' => 'ASC',
370 'number' => $batch_size,
371 'offset' => $offset,
372 ));
373
374 if (!is_wp_error($terms) && !empty($terms)) {
375 foreach ($terms as $term) {
376 // Check if term count is zero
377 if ($term->count == 0) {
378 // Delete the term if it has no posts associated
379 wp_delete_term($term->term_id, $taxonomy);
380 echo 'Deleted term ID: ' . $term->term_id . '<br>';
381 }
382 }
383
384 // Schedule the next batch if more terms are found
385 if (count($terms) == $batch_size) {
386 $next_offset = $offset + $batch_size;
387 wp_schedule_single_event(time() + 30, 'mlsimport_delete_empty_terms_batch_event', array($taxonomy, $batch_size, $next_offset));
388 echo 'Scheduled next batch event from offset: ' . $next_offset . '<br>';
389 } else {
390 echo 'No more terms to process.<br>';
391 }
392 } else {
393 // Debugging output for error or completion
394 if (is_wp_error($terms)) {
395 echo 'Error fetching terms: ' . $terms->get_error_message() . '<br>';
396 } else {
397 echo 'No more terms to process.<br>';
398 }
399 }
400 }
401
402
403 */
404
405
406 //add_action('admin_init', 'force_recount_all_terms');
407 function force_recount_all_terms() {
408 global $wpdb;
409
410 // Get all taxonomies
411 $taxonomies = get_taxonomies([], 'names');
412
413 foreach ($taxonomies as $taxonomy) {
414 // Get all terms for the taxonomy
415 $terms = get_terms([
416 'taxonomy' => $taxonomy,
417 'hide_empty' => false, // Include terms with 0 count
418 'fields' => 'ids', // Get only the term IDs
419 ]);
420
421 if (!is_wp_error($terms) && !empty($terms)) {
422 // Get term_taxonomy_ids for these terms
423 $term_taxonomy_ids = $wpdb->get_col($wpdb->prepare(
424 "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE term_id IN (" . implode(',', array_map('intval', $terms)) . ")"
425 ));
426
427 // Update term counts
428 if (!empty($term_taxonomy_ids)) {
429 wp_update_term_count_now($term_taxonomy_ids, $taxonomy);
430 }
431 }
432 }
433
434 echo "Term counts have been recalculated for all taxonomies.";
435 }