| 1 |
<?php |
| 2 |
|
| 3 |
namespace Code_Snippets; |
| 4 |
|
| 5 |
use WP_User; |
| 6 |
|
| 7 |
/** |
| 8 |
* Manages upgrade tasks such as deleting and updating options |
| 9 |
*/ |
| 10 |
class Upgrade { |
| 11 |
|
| 12 |
/** |
| 13 |
* Instance of database class |
| 14 |
* |
| 15 |
* @var DB |
| 16 |
*/ |
| 17 |
private DB $db; |
| 18 |
|
| 19 |
/** |
| 20 |
* The current plugin version number |
| 21 |
* |
| 22 |
* @var string |
| 23 |
*/ |
| 24 |
private string $current_version; |
| 25 |
|
| 26 |
/** |
| 27 |
* Class constructor |
| 28 |
* |
| 29 |
* @param string $version Current plugin version. |
| 30 |
* @param DB $db Instance of database class. |
| 31 |
*/ |
| 32 |
public function __construct( string $version, DB $db ) { |
| 33 |
$this->db = $db; |
| 34 |
$this->current_version = $version; |
| 35 |
} |
| 36 |
|
| 37 |
/** |
| 38 |
* Run the upgrade functions |
| 39 |
*/ |
| 40 |
public function run() { |
| 41 |
|
| 42 |
// Always run multisite upgrades, even if not on the main site, as sub-sites depend on the network snippet table. |
| 43 |
if ( is_multisite() ) { |
| 44 |
$this->do_multisite_upgrades(); |
| 45 |
} |
| 46 |
|
| 47 |
$this->do_site_upgrades(); |
| 48 |
} |
| 49 |
|
| 50 |
/** |
| 51 |
* Perform upgrades for the current site |
| 52 |
*/ |
| 53 |
private function do_site_upgrades() { |
| 54 |
$table_name = $this->db->table; |
| 55 |
$prev_version = get_option( 'code_snippets_version' ); |
| 56 |
|
| 57 |
// Do nothing if the plugin has not just been updated or installed. |
| 58 |
if ( ! version_compare( $prev_version, $this->current_version, '<' ) ) { |
| 59 |
return; |
| 60 |
} |
| 61 |
|
| 62 |
// Update the plugin version stored in the database. |
| 63 |
$updated = update_option( 'code_snippets_version', $this->current_version ); |
| 64 |
|
| 65 |
if ( ! $updated ) { |
| 66 |
return; // Bail if the data was not successfully saved to prevent this process from repeating. |
| 67 |
} |
| 68 |
|
| 69 |
$this->db->create_table( $table_name ); |
| 70 |
|
| 71 |
// Remove outdated user meta. |
| 72 |
if ( version_compare( $prev_version, '2.14.1', '<' ) ) { |
| 73 |
global $wpdb; |
| 74 |
|
| 75 |
$prefix = $wpdb->get_blog_prefix(); |
| 76 |
$menu_slug = code_snippets()->get_menu_slug(); |
| 77 |
$option_name = "{$prefix}managetoplevel_page_{$menu_slug}columnshidden"; |
| 78 |
|
| 79 |
// Loop through each user ID and remove all matching user meta. |
| 80 |
foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) { |
| 81 |
delete_metadata( 'user', $user_id, $option_name, '', true ); |
| 82 |
} |
| 83 |
} |
| 84 |
|
| 85 |
// Update the scope column of the database. |
| 86 |
if ( version_compare( $prev_version, '2.10.0', '<' ) ) { |
| 87 |
$this->migrate_scope_data( $table_name ); |
| 88 |
} |
| 89 |
|
| 90 |
// Custom capabilities were removed after version 2.9.5. |
| 91 |
if ( version_compare( $prev_version, '2.9.5', '<=' ) ) { |
| 92 |
$role = get_role( apply_filters( 'code_snippets_role', 'administrator' ) ); |
| 93 |
$role->remove_cap( apply_filters( 'code_snippets_cap', 'manage_snippets' ) ); |
| 94 |
} |
| 95 |
|
| 96 |
if ( false === $prev_version ) { |
| 97 |
add_action( 'init', [ $this, 'create_sample_content' ] ); |
| 98 |
} |
| 99 |
|
| 100 |
clean_snippets_cache( $table_name ); |
| 101 |
Welcome_API::clear_cache(); |
| 102 |
} |
| 103 |
|
| 104 |
/** |
| 105 |
* Create example snippets. |
| 106 |
* |
| 107 |
* As this uses translation functions, this should not be called earlier than 'init'. |
| 108 |
* |
| 109 |
* @return void |
| 110 |
*/ |
| 111 |
public function create_sample_content() { |
| 112 |
if ( apply_filters( 'code_snippets/create_sample_content', true ) ) { |
| 113 |
$sample_snippets = $this->get_sample_content(); |
| 114 |
foreach ( $sample_snippets as $sample_snippet ) { |
| 115 |
save_snippet( $sample_snippet ); |
| 116 |
} |
| 117 |
} |
| 118 |
} |
| 119 |
|
| 120 |
/** |
| 121 |
* Perform multisite-only upgrades |
| 122 |
*/ |
| 123 |
private function do_multisite_upgrades() { |
| 124 |
$table_name = $this->db->ms_table; |
| 125 |
$prev_version = get_site_option( 'code_snippets_version' ); |
| 126 |
|
| 127 |
// Do nothing if the plugin has not been updated or installed. |
| 128 |
if ( ! version_compare( $prev_version, $this->current_version, '<' ) ) { |
| 129 |
return; |
| 130 |
} |
| 131 |
|
| 132 |
// Always attempt to create or upgrade the database tables. |
| 133 |
$this->db->create_table( $table_name ); |
| 134 |
|
| 135 |
// Update the plugin version stored in the database. |
| 136 |
update_site_option( 'code_snippets_version', $this->current_version ); |
| 137 |
|
| 138 |
// Update the scope column of the database. |
| 139 |
if ( version_compare( $prev_version, '2.10.0', '<' ) ) { |
| 140 |
$this->migrate_scope_data( $table_name ); |
| 141 |
} |
| 142 |
|
| 143 |
// Custom capabilities were removed after version 2.9.5. |
| 144 |
if ( version_compare( $prev_version, '2.9.5', '<=' ) ) { |
| 145 |
$network_cap = apply_filters( 'code_snippets_network_cap', 'manage_network_snippets' ); |
| 146 |
|
| 147 |
foreach ( get_super_admins() as $admin ) { |
| 148 |
$user = new WP_User( 0, $admin ); |
| 149 |
$user->remove_cap( $network_cap ); |
| 150 |
} |
| 151 |
} |
| 152 |
|
| 153 |
clean_snippets_cache( $table_name ); |
| 154 |
} |
| 155 |
|
| 156 |
/** |
| 157 |
* Migrate data from the old integer method of storing scopes to the new string method |
| 158 |
* |
| 159 |
* @param string $table_name Name of database table. |
| 160 |
*/ |
| 161 |
private function migrate_scope_data( string $table_name ) { |
| 162 |
global $wpdb; |
| 163 |
|
| 164 |
$scopes = array( |
| 165 |
0 => 'global', |
| 166 |
1 => 'admin', |
| 167 |
2 => 'front-end', |
| 168 |
); |
| 169 |
|
| 170 |
foreach ( $scopes as $scope_number => $scope_name ) { |
| 171 |
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching, will flush at end of process. |
| 172 |
$wpdb->query( |
| 173 |
$wpdb->prepare( |
| 174 |
"UPDATE $table_name SET scope = %s WHERE scope = %d", |
| 175 |
$scope_name, |
| 176 |
$scope_number |
| 177 |
) |
| 178 |
); |
| 179 |
} |
| 180 |
} |
| 181 |
|
| 182 |
/** |
| 183 |
* Build a collection of sample snippets for new users to try out. |
| 184 |
* |
| 185 |
* @return array<string, Snippet> List of Snippet objects. |
| 186 |
*/ |
| 187 |
private function get_sample_content(): array { |
| 188 |
$tag = "\n\n" . esc_html__( 'This is a sample snippet. Feel free to use it, edit it, or remove it.', 'code-snippets' ); |
| 189 |
|
| 190 |
$snippets_data = array( |
| 191 |
array( |
| 192 |
'name' => esc_html__( 'Make upload filenames lowercase', 'code-snippets' ), |
| 193 |
'code' => "add_filter( 'sanitize_file_name', 'mb_strtolower' );", |
| 194 |
'desc' => esc_html__( 'Makes sure that image and file uploads have lowercase filenames.', 'code-snippets' ) . $tag, |
| 195 |
'tags' => array( 'sample', 'media' ), |
| 196 |
), |
| 197 |
array( |
| 198 |
'name' => esc_html__( 'Disable admin bar', 'code-snippets' ), |
| 199 |
'code' => "add_action( 'wp', function () {\n\tif ( ! current_user_can( 'manage_options' ) ) {\n\t\tshow_admin_bar( false );\n\t}\n} );", |
| 200 |
'desc' => esc_html__( 'Turns off the WordPress admin bar for everyone except administrators.', 'code-snippets' ) . $tag, |
| 201 |
'tags' => array( 'sample', 'admin-bar' ), |
| 202 |
'scope' => 'front-end', |
| 203 |
), |
| 204 |
array( |
| 205 |
'name' => esc_html__( 'Allow smilies', 'code-snippets' ), |
| 206 |
'code' => "add_filter( 'widget_text', 'convert_smilies' );\nadd_filter( 'the_title', 'convert_smilies' );\nadd_filter( 'wp_title', 'convert_smilies' );\nadd_filter( 'get_bloginfo', 'convert_smilies' );", |
| 207 |
'desc' => esc_html__( 'Allows smiley conversion in obscure places.', 'code-snippets' ) . $tag, |
| 208 |
'tags' => array( 'sample' ), |
| 209 |
), |
| 210 |
array( |
| 211 |
'name' => esc_html__( 'Current year', 'code-snippets' ), |
| 212 |
'code' => "<?php echo date( 'Y' ); ?>", |
| 213 |
'desc' => esc_html__( 'Shortcode for inserting the current year into a post or page..', 'code-snippets' ) . $tag, |
| 214 |
'tags' => array( 'sample', 'dates' ), |
| 215 |
'scope' => 'content', |
| 216 |
), |
| 217 |
); |
| 218 |
|
| 219 |
return array_map( |
| 220 |
function ( $snippet_data ) { |
| 221 |
return new Snippet( $snippet_data ); |
| 222 |
}, |
| 223 |
$snippets_data |
| 224 |
); |
| 225 |
} |
| 226 |
} |
| 227 |
|