1
1
<?php
2
2
/**
3
- * Database Class
3
+ * Upgrade Class
4
4
*
5
5
* @package Webmention
6
6
*/
7
7
namespace Webmention ;
8
8
9
9
/**
10
- * Database Class
10
+ * Upgrade Class
11
11
*
12
12
* @package Webmention
13
13
*/
14
- class DB {
14
+ class Upgrade {
15
15
/**
16
- * Which internal datastructure version we are running on.
17
- *
18
- * @var int
16
+ * Initialize the upgrade class.
19
17
*/
20
- private static $ target_version = '1.0.1 ' ;
21
-
22
- public static function get_target_version () {
23
- return self ::$ target_version ;
18
+ public static function init () {
19
+ add_action ( 'init ' , array ( self ::class, 'maybe_upgrade ' ) );
24
20
}
25
21
22
+ /**
23
+ * Get the current version.
24
+ *
25
+ * @return int
26
+ */
26
27
public static function get_version () {
27
28
return get_option ( 'webmention_db_version ' , 0 );
28
29
}
29
30
30
31
/**
31
32
* Whether the database structure is up to date.
32
33
*
33
- * @return bool
34
+ * @return bool True if the database structure is up to date, false otherwise.
34
35
*/
35
36
public static function is_latest_version () {
36
- return (bool ) version_compare (
37
+ return (bool ) \ version_compare (
37
38
self ::get_version (),
38
- self :: get_target_version () ,
39
+ WEBMENTION_VERSION ,
39
40
'== '
40
41
);
41
42
}
42
43
44
+ /**
45
+ * Locks the database migration process to prevent simultaneous migrations.
46
+ *
47
+ * @return bool|int True if the lock was successful, timestamp of existing lock otherwise.
48
+ */
49
+ public static function lock () {
50
+ global $ wpdb ;
51
+
52
+ // Try to lock.
53
+ $ lock_result = (bool ) $ wpdb ->query ( $ wpdb ->prepare ( "INSERT IGNORE INTO ` $ wpdb ->options ` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */ " , 'webmention_migration_lock ' , \time () ) ); // phpcs:ignore WordPress.DB
54
+
55
+ if ( ! $ lock_result ) {
56
+ $ lock_result = \get_option ( 'webmention_migration_lock ' );
57
+ }
58
+
59
+ return $ lock_result ;
60
+ }
61
+
62
+ /**
63
+ * Unlocks the database migration process.
64
+ */
65
+ public static function unlock () {
66
+ \delete_option ( 'webmention_migration_lock ' );
67
+ }
68
+
69
+ /**
70
+ * Whether the database migration process is locked.
71
+ *
72
+ * @return boolean
73
+ */
74
+ public static function is_locked () {
75
+ $ lock = \get_option ( 'webmention_migration_lock ' );
76
+
77
+ if ( ! $ lock ) {
78
+ return false ;
79
+ }
80
+
81
+ $ lock = (int ) $ lock ;
82
+
83
+ if ( $ lock < \time () - 1800 ) {
84
+ self ::unlock ();
85
+ return false ;
86
+ }
87
+
88
+ return true ;
89
+ }
90
+
43
91
/**
44
92
* Updates the database structure if necessary.
45
93
*/
46
- public static function update_database () {
94
+ public static function maybe_upgrade () {
47
95
if ( self ::is_latest_version () ) {
48
96
return ;
49
97
}
50
98
99
+ if ( self ::is_locked () ) {
100
+ return ;
101
+ }
102
+
103
+ self ::lock ();
104
+
51
105
$ version_from_db = self ::get_version ();
52
106
53
107
if ( version_compare ( $ version_from_db , '1.0.0 ' , '< ' ) ) {
@@ -57,7 +111,17 @@ public static function update_database() {
57
111
self ::migrate_to_1_0_1 ();
58
112
}
59
113
60
- update_option ( 'webmention_db_version ' , self ::$ target_version );
114
+ /**
115
+ * Fires when the system has to be migrated.
116
+ *
117
+ * @param string $version_from_db The version from which to migrate.
118
+ * @param string $target_version The target version to migrate to.
119
+ */
120
+ \do_action ( 'webmention_migrate ' , $ version_from_db , WEBMENTION_VERSION );
121
+
122
+ \update_option ( 'webmention_db_version ' , WEBMENTION_VERSION );
123
+
124
+ self ::unlock ();
61
125
}
62
126
63
127
/**
0 commit comments