PluginProbe
Search & Replace Everything – Quick and Easy Way to Find and Replace Text, Links / trunk
Search & Replace Everything – Quick and Easy Way to Find and Replace Text, Links vtrunk
1.5.2 1.5.0 1.5.1 1.4.7 1.4.6 1.4.4 1.4.5 1.4.3 trunk 1.0.2 1.0.3 1.0.4 1.0.4.1 1.1 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.2 1.2.3 1.2.4 1.2.5 All 34 releases
update-urls / lite / includes / Install.php

Install.php in Search & Replace Everything – Quick and Easy Way to Find and Replace Text, Links trunk, at lite/includes/Install.php

608 lines 13.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace KaizenCoders\UpdateURLS;
4
5 class Install {
6
7 /**
8 * DB updates and callbacks that need to be run per version.
9 *
10 * @since 1.2
11 * @var array
12 *
13 */
14 private static $db_updates = array(
15
16 '1.2.3' => array(
17 'kc_uu_update_123_add_installed_on_option',
18 ),
19
20 '1.4.2' => array(
21 'kc_uu_update_142_set_email_digest_defaults',
22 ),
23
24 '1.5.0' => array(
25 'kc_uu_update_150_create_custom_tables',
26 'kc_uu_update_150_migrate_data',
27 ),
28
29 // A schema revision inside 1.5.0. Installs that ran a 1.5.0 build before
30 // the undo journal existed are already stamped 1.5.0, and the updater
31 // only queues callbacks for versions above the stored one — filed under
32 // 1.5.0 these would never run on the installs that need them most.
33 '1.5.0.1' => array(
34 'kc_uu_update_1501_create_undo_journal',
35 ),
36
37 '1.5.0.2' => array(
38 'kc_uu_update_1502_record_undo_outcomes',
39 ),
40
41 );
42
43 /**
44 * Init Install/ Update Process
45 *
46 * @since 1.2
47 */
48 public static function init() {
49
50 if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
51
52 add_action( 'admin_init', array( __CLASS__, 'check_version' ), 5 );
53 add_action( 'admin_init', array( __CLASS__, 'install_actions' ) );
54 }
55 }
56
57 /**
58 * Install if required
59 *
60 * @since 1.2
61 */
62 public static function check_version() {
63
64 $current_db_version = Option::get( 'db_version', '0.0.1' );
65
66 // Get latest available DB update version
67 $latest_db_version_to_update = self::get_latest_db_version_to_update();
68
69 if ( version_compare( $current_db_version, $latest_db_version_to_update, '<' ) ) {
70 self::install();
71 }
72
73 }
74
75 /**
76 * Update
77 *
78 * @since 1.2
79 */
80 public static function install_actions() {
81 if ( ! empty( $_GET['do_update_kc_uu'] ) ) {
82 check_admin_referer( 'kc_uu_db_update', 'kc_uu_db_update_nonce' );
83 $from_db_version = ! empty( $_GET['from_db_version'] ) ? $_GET['from_db_version'] : '';
84
85 self::delete_update_transient();
86
87 if ( ! empty( $from_db_version ) ) {
88 self::update_db_version( $from_db_version );
89 }
90
91 self::update( true );
92
93 }
94
95 if ( ! empty( $_GET['force_update_kc_uu'] ) ) {
96 check_admin_referer( 'kc_uu_force_db_update', 'kc_uu_force_db_update_nonce' );
97 self::update();
98 wp_safe_redirect( admin_url( 'tools.php?page=update-urls' ) );
99 exit;
100 }
101 }
102
103 /**
104 * Begin Installation
105 *
106 * @since 1.2
107 */
108 public static function install() {
109
110 if ( ! is_blog_installed() ) {
111 return;
112 }
113
114 // Check if we are not already running this routine.
115 if ( 'yes' === Cache::get_transient( 'installing' ) ) {
116 return;
117 }
118
119 if ( self::is_new_install() ) {
120 // If we made it till here nothing is running yet, lets set the transient now.
121 Cache::set_transient( 'installing', 'yes', MINUTE_IN_SECONDS * 10 );
122
123 Helper::maybe_define_constant( 'KC_UU_INSTALLING', true );
124
125 // Create Tables
126 self::create_tables();
127
128 // Create Default Option
129 self::create_options();
130
131 self::update_db_version( KC_UU_PLUGIN_VERSION );
132
133 Option::add( 'installed_on', time(), true );
134 }
135
136 self::maybe_update_db_version();
137
138 Cache::delete_transient( 'installing' );
139 }
140
141 /**
142 * Delete Update Transient
143 *
144 * @since 1.2
145 */
146 public static function delete_update_transient() {
147 global $wpdb;
148
149 Option::delete( 'update_processed_tasks' );
150 Option::delete( 'update_tasks_to_process' );
151
152 $transient_like = $wpdb->esc_like( '_transient_kc_uu_update_' ) . '%';
153 $updating_like = $wpdb->esc_like( '_transient_kc_uu_updating' ) . '%';
154 $last_sent_queue_like = '%' . $wpdb->esc_like( '_last_sending_queue_batch_run' ) . '%';
155 $running_migration_queue_like = '%' . $wpdb->esc_like( '_running_migration_for_' ) . '%';
156 $db_migration_queue_like = '%' . $wpdb->esc_like( 'kc_uu_updater_batch_' ) . '%';
157
158 $query = "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '{$transient_like}' OR option_name LIKE '{$updating_like}' OR option_name LIKE '{$last_sent_queue_like}' OR option_name LIKE '{$running_migration_queue_like}' OR option_name LIKE '{$db_migration_queue_like}'";
159
160 $wpdb->query( $query );
161
162 }
163
164 /**
165 * Is this new Installation?
166 *
167 * @return bool
168 *
169 * @since 1.2
170 */
171 public static function is_new_install() {
172 /**
173 * We are storing us_db_version if it's new installation.
174 *
175 */
176 return is_null( Option::get( 'db_version', null ) );
177 }
178
179 /**
180 * Get latest db version based on available updates.
181 *
182 * @return mixed
183 *
184 * @since 1.2
185 */
186 public static function get_latest_db_version_to_update() {
187
188 $updates = self::get_db_update_callbacks();
189 $update_versions = array_keys( $updates );
190 usort( $update_versions, 'version_compare' );
191
192 return end( $update_versions );
193 }
194
195 /**
196 * Require DB updates?
197 *
198 * @return bool
199 *
200 * @since 1.2
201 */
202 private static function needs_db_update() {
203
204 $current_db_version = Helper::get_db_version();
205
206 $latest_db_version_to_update = self::get_latest_db_version_to_update();
207
208 return ! is_null( $current_db_version ) && version_compare( $current_db_version, $latest_db_version_to_update, '<' );
209 }
210
211 /**
212 * Check whether database update require? If require do update.
213 *
214 * @since 1.2
215 */
216 private static function maybe_update_db_version() {
217 if ( self::needs_db_update() ) {
218 if ( apply_filters( 'kc_uu_enable_auto_update_db', true ) ) {
219 self::update();
220 }
221 }
222 }
223
224 /**
225 * Get all database updates
226 *
227 * @return array
228 *
229 * @since 1.2
230 */
231 public static function get_db_update_callbacks() {
232 return self::$db_updates;
233 }
234
235 /**
236 * Do database update.
237 *
238 * @param bool $force
239 *
240 * @since 1.2
241 */
242 private static function update( $force = false ) {
243
244 // Check if we are not already running this routine.
245 if ( ! $force && 'yes' === Cache::get_transient( 'updating' ) ) {
246 return;
247 }
248
249 Cache::set_transient( 'updating', 'yes', MINUTE_IN_SECONDS * 5 );
250
251 $current_db_version = Helper::get_db_version();
252
253 $tasks_to_process = Option::get( 'update_tasks_to_process', array() );
254
255 // Get all tasks processed
256 $processed_tasks = Option::get( 'update_processed_tasks', array() );
257
258 // Get al tasks to process
259 $tasks = self::get_db_update_callbacks();
260
261 if ( count( $tasks ) > 0 ) {
262
263 foreach ( $tasks as $version => $update_callbacks ) {
264
265 if ( version_compare( $current_db_version, $version, '<' ) ) {
266 foreach ( $update_callbacks as $update_callback ) {
267 if ( ! in_array( $update_callback, $tasks_to_process ) && ! in_array( $update_callback, $processed_tasks ) ) {
268 $tasks_to_process[] = $update_callback;
269 } else {
270 }
271 }
272
273 // Update db version on every update run
274 self::update_db_version( $version );
275 }
276 }
277 }
278
279 if ( count( $tasks_to_process ) > 0 ) {
280
281 Option::set( 'update_tasks_to_process', $tasks_to_process );
282
283 self::dispatch();
284
285 } else {
286 Cache::delete_transient( 'updating' );
287 }
288
289 }
290
291 /**
292 * Dispatch database updates.
293 *
294 * @since 1.2
295 */
296 public static function dispatch() {
297
298 $batch = Option::get( 'update_tasks_to_process', array() );
299
300 if ( count( $batch ) > 0 ) {
301
302 $current_memory_limit = @ini_get( 'memory_limit' );
303
304 // We may require lots of memory
305 @ini_set( 'memory_limit', '-1' );
306
307 // It may take long time to process database update.
308 // So, increase execution time
309 @set_time_limit( 360 );
310 @ini_set( 'max_execution_time', 360 );
311
312 foreach ( $batch as $key => $value ) {
313
314 $is_value_exists = true;
315
316 $processed_tasks = Option::get( 'update_processed_tasks', array() );
317
318 $task = false; // By default it's set to false
319
320 // Check whether the tasks is already processed? If not, process it.
321 if ( ! in_array( $value, $processed_tasks ) ) {
322 $is_value_exists = false;
323 $task = (bool) self::task( $value );
324 } else {
325 unset( $batch[ $key ] );
326 }
327
328 if ( false === $task ) {
329
330 if ( ! $is_value_exists ) {
331 $processed_tasks[] = $value;
332 Option::set( 'update_processed_tasks', $processed_tasks );
333 }
334
335 unset( $batch[ $key ] );
336 }
337
338 }
339
340 Option::set( 'update_tasks_to_process', $batch );
341
342 @ini_set( 'memory_limit', $current_memory_limit );
343 }
344
345 //Delete update transient
346 Cache::delete_transient( 'updating' );
347 }
348
349 /**
350 * Run individual database update.
351 *
352 * @param $callback
353 *
354 * @return bool|callable
355 *
356 * @since 1.2
357 */
358 public static function task( $callback ) {
359
360 include_once dirname( __FILE__ ) . '/Upgrade/update-functions.php';
361
362 $result = false;
363
364 if ( is_callable( $callback ) ) {
365
366 $result = (bool) call_user_func( $callback );
367
368 if ( $result ) {
369 //$logger->info( sprintf( '%s callback needs to run again', $callback ), self::$logger_context );
370 } else {
371 //$logger->info( sprintf( '--- Finished Task - %s ', $callback ), self::$logger_context );
372 }
373 } else {
374 //$logger->notice( sprintf( '--- Could not find %s callback', $callback ), self::$logger_context );
375 }
376
377 return $result ? $callback : false;
378 }
379
380 /**
381 * Update DB Version & DB Update history
382 *
383 * @param null $version
384 *
385 * @since 1.2
386 */
387 public static function update_db_version( $version = null ) {
388
389 $latest_db_version_to_update = self::get_latest_db_version_to_update();
390
391 Option::set( 'db_version', is_null( $version ) ? $latest_db_version_to_update : $version );
392
393 if ( ! is_null( $version ) ) {
394
395 $db_update_history_option = 'db_update_history';
396
397 $db_update_history_data = Option::get( $db_update_history_option, array() );
398
399 $db_update_history_data[ $version ] = Helper::get_current_date_time();
400
401 Option::set( $db_update_history_option, $db_update_history_data );
402 }
403 }
404
405 /**
406 * Create default options while installing
407 *
408 * @since 1.2
409 */
410 private static function create_options() {
411
412 $options = self::get_options();
413
414 if ( Helper::is_forechable( $options ) ) {
415
416 foreach ( $options as $option => $values ) {
417 Option::add( $option, $values['default'], false );
418 }
419 }
420
421 self::set_email_digest_defaults();
422 }
423
424 /**
425 * Get default options
426 *
427 * @return array
428 *
429 * @since 1.2
430 */
431 public static function get_options() {
432 return array();
433 }
434
435 /**
436 * Set email digest defaults without overwriting existing values.
437 *
438 * @since 1.4.2
439 */
440 public static function set_email_digest_defaults() {
441 $settings = get_option( 'kc_uu_settings', array() );
442
443 $defaults = array(
444 'email_digest_enabled' => 1,
445 'email_digest_frequency' => 'daily',
446 'email_digest_time' => '09:00',
447 'email_digest_day' => 1,
448 'email_digest_recipients' => '',
449 );
450
451 foreach ( $defaults as $key => $value ) {
452 if ( ! isset( $settings['email_digest']['settings'][ $key ] ) ) {
453 $settings['email_digest']['settings'][ $key ] = $value;
454 }
455 }
456
457 update_option( 'kc_uu_settings', $settings );
458 }
459
460 /**
461 * Create Tables
462 *
463 * @param null $version
464 *
465 * @since 1.2
466 */
467 public static function create_tables( $version = null ) {
468
469 global $wpdb;
470
471 $collate = '';
472
473 if ( $wpdb->has_cap( 'collation' ) ) {
474 $collate = $wpdb->get_charset_collate();
475 }
476
477 if ( is_null( $version ) ) {
478 $schema_fn = 'get_schema';
479 } else {
480 $v = str_replace( '.', '', $version );
481 $schema_fn = 'get_' . $v . '_schema';
482 }
483
484 $wpdb->hide_errors();
485 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
486 dbDelta( self::$schema_fn( $collate ) );
487 }
488
489 /**
490 * @param string $collate
491 *
492 * @return string
493 *
494 * @since 1.2
495 */
496 private static function get_schema( $collate = '' ) {
497
498 $tables = self::get_100_schema( $collate );
499
500 return $tables;
501 }
502
503 /**
504 * Get 1.0.0 schema.
505 *
506 * @param string $collate
507 *
508 * @return string
509 *
510 * @since 1.5.0
511 */
512 private static function get_100_schema( $collate = '' ) {
513
514 global $wpdb;
515
516 $tables = "
517 CREATE TABLE {$wpdb->prefix}kc_uu_history (
518 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
519 entry_id VARCHAR(50) NOT NULL,
520 date DATETIME NOT NULL,
521 search_for TEXT NOT NULL,
522 replace_with TEXT NOT NULL,
523 tables TEXT NOT NULL,
524 case_insensitive TINYINT(1) NOT NULL DEFAULT 0,
525 replace_guids TINYINT(1) NOT NULL DEFAULT 0,
526 total_changes INT UNSIGNED NOT NULL DEFAULT 0,
527 total_updates INT UNSIGNED NOT NULL DEFAULT 0,
528 undone TINYINT(1) NOT NULL DEFAULT 0,
529 undo_recorded INT UNSIGNED NOT NULL DEFAULT 0,
530 undo_restored INT UNSIGNED NOT NULL DEFAULT 0,
531 undo_skipped INT UNSIGNED NOT NULL DEFAULT 0,
532 undo_status VARCHAR(20) NOT NULL DEFAULT '',
533 details LONGTEXT,
534 PRIMARY KEY (id),
535 UNIQUE KEY entry_id (entry_id),
536 KEY date (date)
537 ) $collate;
538 CREATE TABLE {$wpdb->prefix}kc_uu_undo (
539 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
540 entry_id VARCHAR(50) NOT NULL,
541 table_name VARCHAR(191) NOT NULL,
542 column_name VARCHAR(191) NOT NULL,
543 row_pk VARCHAR(191) NOT NULL,
544 old_value LONGTEXT NOT NULL,
545 old_hash CHAR(40) NOT NULL DEFAULT '',
546 new_hash CHAR(40) NOT NULL,
547 restored TINYINT(1) NOT NULL DEFAULT 0,
548 outcome VARCHAR(16) NOT NULL DEFAULT '',
549 skip_reason VARCHAR(24) NOT NULL DEFAULT '',
550 PRIMARY KEY (id),
551 KEY entry_pending (entry_id, restored),
552 KEY entry_outcome (entry_id, outcome)
553 ) $collate;
554 CREATE TABLE {$wpdb->prefix}kc_uu_profiles (
555 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
556 name VARCHAR(255) NOT NULL,
557 search_for TEXT NOT NULL,
558 replace_with TEXT NOT NULL,
559 select_tables TEXT NOT NULL,
560 case_insensitive VARCHAR(5) NOT NULL DEFAULT 'off',
561 replace_guids VARCHAR(5) NOT NULL DEFAULT 'off',
562 PRIMARY KEY (id),
563 UNIQUE KEY name (name)
564 ) $collate;
565 ";
566
567 return $tables;
568 }
569
570 /**
571 * Create files/ directory
572 *
573 * @since 1.2
574 */
575 public static function create_files() {
576
577 // Want to bypass creation of files?
578 if ( apply_filters( 'kc_uu_install_skip_create_files', false ) ) {
579 return;
580 }
581
582 $files = array(
583 array(
584 'base' => KC_UU_LOG_DIR,
585 'file' => '.htaccess',
586 'content' => 'deny from all',
587 ),
588 array(
589 'base' => KC_UU_LOG_DIR,
590 'file' => 'index.html',
591 'content' => '',
592 ),
593 );
594
595 foreach ( $files as $file ) {
596 if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
597 $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' );
598 if ( $file_handle ) {
599 fwrite( $file_handle, $file['content'] );
600 fclose( $file_handle );
601 }
602 }
603 }
604 }
605
606 }
607
608 Install::init();