Completed
Push — master ( 013b86...e987a3 )
by Mike
08:27
created

WC_Install::plugin_action_links()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 18 and the first side effect is on line 12.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Installation related functions and actions
4
 *
5
 * @author   WooThemes
6
 * @category Admin
7
 * @package  WooCommerce/Classes
8
 * @version  2.4.1
9
 */
10
11
if ( ! defined( 'ABSPATH' ) ) {
12
	exit;
13
}
14
15
/**
16
 * WC_Install Class.
17
 */
18
class WC_Install {
19
20
	/** @var array DB updates that need to be run */
21
	private static $db_updates = array(
22
		'2.0.0' => 'updates/woocommerce-update-2.0.php',
23
		'2.0.9' => 'updates/woocommerce-update-2.0.9.php',
24
		'2.1.0' => 'updates/woocommerce-update-2.1.php',
25
		'2.2.0' => 'updates/woocommerce-update-2.2.php',
26
		'2.3.0' => 'updates/woocommerce-update-2.3.php',
27
		'2.4.0' => 'updates/woocommerce-update-2.4.php',
28
		'2.4.1' => 'updates/woocommerce-update-2.4.1.php',
29
		'2.5.0' => 'updates/woocommerce-update-2.5.php',
30
		'2.6.0' => 'updates/woocommerce-update-2.6.php'
31
	);
32
33
	/**
34
	 * Hook in tabs.
35
	 */
36
	public static function init() {
37
		add_action( 'init', array( __CLASS__, 'check_version' ), 5 );
38
		add_action( 'admin_init', array( __CLASS__, 'install_actions' ) );
39
		add_action( 'in_plugin_update_message-woocommerce/woocommerce.php', array( __CLASS__, 'in_plugin_update_message' ) );
40
		add_filter( 'plugin_action_links_' . WC_PLUGIN_BASENAME, array( __CLASS__, 'plugin_action_links' ) );
41
		add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 );
42
		add_filter( 'wpmu_drop_tables', array( __CLASS__, 'wpmu_drop_tables' ) );
43
		add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) );
44
	}
45
46
	/**
47
	 * Check WooCommerce version and run the updater is required.
48
	 *
49
	 * This check is done on all requests and runs if he versions do not match.
50
	 */
51
	public static function check_version() {
52
		if ( ! defined( 'IFRAME_REQUEST' ) && get_option( 'woocommerce_version' ) !== WC()->version ) {
53
			self::install();
54
			do_action( 'woocommerce_updated' );
55
		}
56
	}
57
58
	/**
59
	 * Install actions when a update button is clicked within the admin area.
60
	 *
61
	 * This function is hooked into admin_init to affect admin only.
62
	 */
63
	public static function install_actions() {
64
		if ( ! empty( $_GET['do_update_woocommerce'] ) ) {
65
			self::update();
66
			WC_Admin_Notices::remove_notice( 'update' );
67
			add_action( 'admin_notices', array( __CLASS__, 'updated_notice' ) );
68
		}
69
	}
70
71
	/**
72
	 * Show notice stating update was successful.
73
	 */
74
	public static function updated_notice() {
75
		?>
76
		<div id="message" class="updated woocommerce-message wc-connect">
77
			<p><?php _e( 'WooCommerce data update complete. Thank you for updating to the latest version!', 'woocommerce' ); ?></p>
78
		</div>
79
		<?php
80
	}
81
82
	/**
83
	 * Install WC.
84
	 */
85
	public static function install() {
86
		global $wpdb;
87
88
		if ( ! defined( 'WC_INSTALLING' ) ) {
89
			define( 'WC_INSTALLING', true );
90
		}
91
92
		// Ensure needed classes are loaded
93
		include_once( 'admin/class-wc-admin-notices.php' );
94
95
		self::create_options();
96
		self::create_tables();
97
		self::create_roles();
98
99
		// Register post types
100
		WC_Post_types::register_post_types();
101
		WC_Post_types::register_taxonomies();
102
103
		// Also register endpoints - this needs to be done prior to rewrite rule flush
104
		WC()->query->init_query_vars();
105
		WC()->query->add_endpoints();
106
		WC_API::add_endpoint();
107
		WC_Auth::add_endpoint();
108
109
		self::create_terms();
110
		self::create_cron_jobs();
111
		self::create_files();
112
113
		// Queue upgrades/setup wizard
114
		$current_wc_version    = get_option( 'woocommerce_version', null );
115
		$current_db_version    = get_option( 'woocommerce_db_version', null );
116
		$major_wc_version      = substr( WC()->version, 0, strrpos( WC()->version, '.' ) );
0 ignored issues
show
Unused Code introduced by
$major_wc_version is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
117
118
		WC_Admin_Notices::remove_all_notices();
119
120
		// No versions? This is a new install :)
121
		if ( is_null( $current_wc_version ) && is_null( $current_db_version ) && apply_filters( 'woocommerce_enable_setup_wizard', true ) ) {
122
			WC_Admin_Notices::add_notice( 'install' );
123
			set_transient( '_wc_activation_redirect', 1, 30 );
124
125
		// No page? Let user run wizard again..
126
		} elseif ( ! get_option( 'woocommerce_cart_page_id' ) ) {
127
			WC_Admin_Notices::add_notice( 'install' );
128
		}
129
130
		if ( ! is_null( $current_db_version ) && version_compare( $current_db_version, max( array_keys( self::$db_updates ) ), '<' ) ) {
131
			WC_Admin_Notices::add_notice( 'update' );
132
		} else {
133
			self::update_db_version();
134
		}
135
136
		self::update_wc_version();
137
138
		// Flush rules after install
139
		flush_rewrite_rules();
140
		delete_transient( 'wc_attribute_taxonomies' );
141
142
		/*
143
		 * Deletes all expired transients. The multi-table delete syntax is used.
144
		 * to delete the transient record from table a, and the corresponding.
145
		 * transient_timeout record from table b.
146
		 *
147
		 * Based on code inside core's upgrade_network() function.
148
		 */
149
		$sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
150
			WHERE a.option_name LIKE %s
151
			AND a.option_name NOT LIKE %s
152
			AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
153
			AND b.option_value < %d";
154
		$wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', time() ) );
155
156
		// Trigger action
157
		do_action( 'woocommerce_installed' );
158
	}
159
160
	/**
161
	 * Update WC version to current.
162
	 */
163
	private static function update_wc_version() {
164
		delete_option( 'woocommerce_version' );
165
		add_option( 'woocommerce_version', WC()->version );
166
	}
167
168
	/**
169
	 * Update DB version to current.
170
	 */
171
	private static function update_db_version( $version = null ) {
172
		delete_option( 'woocommerce_db_version' );
173
		add_option( 'woocommerce_db_version', is_null( $version ) ? WC()->version : $version );
174
	}
175
176
	/**
177
	 * Handle updates.
178
	 */
179
	private static function update() {
180
		if ( ! defined( 'WC_UPDATING' ) ) {
181
			define( 'WC_UPDATING', true );
182
		}
183
184
		$current_db_version = get_option( 'woocommerce_db_version' );
185
186
		foreach ( self::$db_updates as $version => $updater ) {
187
			if ( version_compare( $current_db_version, $version, '<' ) ) {
188
				include( $updater );
189
				self::update_db_version( $version );
190
			}
191
		}
192
193
		self::update_db_version();
194
	}
195
196
	/**
197
	 * Add more cron schedules.
198
	 * @param  array $schedules
199
	 * @return array
200
	 */
201
	public static function cron_schedules( $schedules ) {
202
		$schedules['monthly'] = array(
203
			'interval' => 2635200,
204
			'display'  => __( 'Monthly', 'woocommerce' )
205
		);
206
		return $schedules;
207
	}
208
209
	/**
210
	 * Create cron jobs (clear them first).
211
	 */
212
	private static function create_cron_jobs() {
213
		wp_clear_scheduled_hook( 'woocommerce_scheduled_sales' );
214
		wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
215
		wp_clear_scheduled_hook( 'woocommerce_cleanup_sessions' );
216
		wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
217
		wp_clear_scheduled_hook( 'woocommerce_tracker_send_event' );
218
219
		$ve = get_option( 'gmt_offset' ) > 0 ? '+' : '-';
220
221
		wp_schedule_event( strtotime( '00:00 tomorrow ' . $ve . get_option( 'gmt_offset' ) . ' HOURS' ), 'daily', 'woocommerce_scheduled_sales' );
222
223
		$held_duration = get_option( 'woocommerce_hold_stock_minutes', '60' );
224
225
		if ( $held_duration != '' ) {
226
			wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
227
		}
228
229
		wp_schedule_event( time(), 'twicedaily', 'woocommerce_cleanup_sessions' );
230
		wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' );
231
		wp_schedule_event( time(), apply_filters( 'woocommerce_tracker_event_recurrence', 'daily' ), 'woocommerce_tracker_send_event' );
232
	}
233
234
	/**
235
	 * Create pages that the plugin relies on, storing page id's in variables.
236
	 */
237
	public static function create_pages() {
238
		include_once( 'admin/wc-admin-functions.php' );
239
240
		$pages = apply_filters( 'woocommerce_create_pages', array(
241
			'shop' => array(
242
				'name'    => _x( 'shop', 'Page slug', 'woocommerce' ),
243
				'title'   => _x( 'Shop', 'Page title', 'woocommerce' ),
244
				'content' => ''
245
			),
246
			'cart' => array(
247
				'name'    => _x( 'cart', 'Page slug', 'woocommerce' ),
248
				'title'   => _x( 'Cart', 'Page title', 'woocommerce' ),
249
				'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']'
250
			),
251
			'checkout' => array(
252
				'name'    => _x( 'checkout', 'Page slug', 'woocommerce' ),
253
				'title'   => _x( 'Checkout', 'Page title', 'woocommerce' ),
254
				'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']'
255
			),
256
			'myaccount' => array(
257
				'name'    => _x( 'my-account', 'Page slug', 'woocommerce' ),
258
				'title'   => _x( 'My Account', 'Page title', 'woocommerce' ),
259
				'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']'
260
			)
261
		) );
262
263
		foreach ( $pages as $key => $page ) {
264
			wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' );
265
		}
266
267
		delete_transient( 'woocommerce_cache_excluded_uris' );
268
	}
269
270
	/**
271
	 * Default options.
272
	 *
273
	 * Sets up the default options used on the settings page.
274
	 */
275
	private static function create_options() {
276
		// Include settings so that we can run through defaults
277
		include_once( 'admin/class-wc-admin-settings.php' );
278
279
		$settings = WC_Admin_Settings::get_settings_pages();
280
281
		foreach ( $settings as $section ) {
282
			if ( ! method_exists( $section, 'get_settings' ) ) {
283
				continue;
284
			}
285
			$subsections = array_unique( array_merge( array( '' ), array_keys( $section->get_sections() ) ) );
286
287
			foreach ( $subsections as $subsection ) {
288
				foreach ( $section->get_settings( $subsection ) as $value ) {
289
					if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
290
						$autoload = isset( $value['autoload'] ) ? (bool) $value['autoload'] : true;
291
						add_option( $value['id'], $value['default'], '', ( $autoload ? 'yes' : 'no' ) );
292
					}
293
				}
294
			}
295
		}
296
	}
297
298
	/**
299
	 * Add the default terms for WC taxonomies - product types and order statuses. Modify this at your own risk.
300
	 */
301
	private static function create_terms() {
302
		$taxonomies = array(
303
			'product_type' => array(
304
				'simple',
305
				'grouped',
306
				'variable',
307
				'external'
308
			)
309
		);
310
311
		foreach ( $taxonomies as $taxonomy => $terms ) {
312
			foreach ( $terms as $term ) {
313
				if ( ! get_term_by( 'slug', sanitize_title( $term ), $taxonomy ) ) {
314
					wp_insert_term( $term, $taxonomy );
315
				}
316
			}
317
		}
318
	}
319
320
	/**
321
	 * Set up the database tables which the plugin needs to function.
322
	 *
323
	 * Tables:
324
	 *		woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined
325
	 *		woocommerce_termmeta - Term meta table - sadly WordPress does not have termmeta so we need our own
326
	 *		woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions.
327
	 *			KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page
328
	 *		woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports
329
	 *		woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data.
330
	 *		woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient.
331
	 *		woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table.
332
	 */
333
	private static function create_tables() {
334
		global $wpdb;
335
336
		$wpdb->hide_errors();
337
338
		require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
339
340
		/**
341
		 * Before updating with DBDELTA, remove any primary keys which could be modified due to schema updates.
342
		 */
343
		if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_downloadable_product_permissions';" ) ) {
344
			if ( ! $wpdb->get_var( "SHOW COLUMNS FROM `{$wpdb->prefix}woocommerce_downloadable_product_permissions` LIKE 'permission_id';" ) ) {
345
				$wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions DROP PRIMARY KEY, ADD `permission_id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT;" );
346
			}
347
		}
348
349
		dbDelta( self::get_schema() );
350
	}
351
352
	/**
353
	 * Get Table schema.
354
	 * @return string
355
	 */
356
	private static function get_schema() {
357
		global $wpdb;
358
359
		$collate = '';
360
361
		if ( $wpdb->has_cap( 'collation' ) ) {
362
			$collate = $wpdb->get_charset_collate();
363
		}
364
365
		return "
366
CREATE TABLE {$wpdb->prefix}woocommerce_sessions (
367
  session_id bigint(20) NOT NULL AUTO_INCREMENT,
368
  session_key char(32) NOT NULL,
369
  session_value longtext NOT NULL,
370
  session_expiry bigint(20) NOT NULL,
371
  UNIQUE KEY session_id (session_id),
372
  PRIMARY KEY  (session_key)
373
) $collate;
374
CREATE TABLE {$wpdb->prefix}woocommerce_api_keys (
375
  key_id bigint(20) NOT NULL auto_increment,
376
  user_id bigint(20) NOT NULL,
377
  description longtext NULL,
378
  permissions varchar(10) NOT NULL,
379
  consumer_key char(64) NOT NULL,
380
  consumer_secret char(43) NOT NULL,
381
  nonces longtext NULL,
382
  truncated_key char(7) NOT NULL,
383
  last_access datetime NULL default null,
384
  PRIMARY KEY  (key_id),
385
  KEY consumer_key (consumer_key),
386
  KEY consumer_secret (consumer_secret)
387
) $collate;
388
CREATE TABLE {$wpdb->prefix}woocommerce_attribute_taxonomies (
389
  attribute_id bigint(20) NOT NULL auto_increment,
390
  attribute_name varchar(200) NOT NULL,
391
  attribute_label longtext NULL,
392
  attribute_type varchar(200) NOT NULL,
393
  attribute_orderby varchar(200) NOT NULL,
394
  attribute_public int(1) NOT NULL DEFAULT 1,
395
  PRIMARY KEY  (attribute_id),
396
  KEY attribute_name (attribute_name)
397
) $collate;
398
CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
399
  meta_id bigint(20) NOT NULL auto_increment,
400
  woocommerce_term_id bigint(20) NOT NULL,
401
  meta_key varchar(255) NULL,
402
  meta_value longtext NULL,
403
  PRIMARY KEY  (meta_id),
404
  KEY woocommerce_term_id (woocommerce_term_id),
405
  KEY meta_key (meta_key)
406
) $collate;
407
CREATE TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions (
408
  permission_id bigint(20) NOT NULL auto_increment,
409
  download_id varchar(32) NOT NULL,
410
  product_id bigint(20) NOT NULL,
411
  order_id bigint(20) NOT NULL DEFAULT 0,
412
  order_key varchar(200) NOT NULL,
413
  user_email varchar(200) NOT NULL,
414
  user_id bigint(20) NULL,
415
  downloads_remaining varchar(9) NULL,
416
  access_granted datetime NOT NULL default '0000-00-00 00:00:00',
417
  access_expires datetime NULL default null,
418
  download_count bigint(20) NOT NULL DEFAULT 0,
419
  PRIMARY KEY  (permission_id),
420
  KEY download_order_key_product (product_id,order_id,order_key,download_id),
421
  KEY download_order_product (download_id,order_id,product_id)
422
) $collate;
423
CREATE TABLE {$wpdb->prefix}woocommerce_order_items (
424
  order_item_id bigint(20) NOT NULL auto_increment,
425
  order_item_name longtext NOT NULL,
426
  order_item_type varchar(200) NOT NULL DEFAULT '',
427
  order_id bigint(20) NOT NULL,
428
  PRIMARY KEY  (order_item_id),
429
  KEY order_id (order_id)
430
) $collate;
431
CREATE TABLE {$wpdb->prefix}woocommerce_order_itemmeta (
432
  meta_id bigint(20) NOT NULL auto_increment,
433
  order_item_id bigint(20) NOT NULL,
434
  meta_key varchar(255) NULL,
435
  meta_value longtext NULL,
436
  PRIMARY KEY  (meta_id),
437
  KEY order_item_id (order_item_id),
438
  KEY meta_key (meta_key)
439
) $collate;
440
CREATE TABLE {$wpdb->prefix}woocommerce_tax_rates (
441
  tax_rate_id bigint(20) NOT NULL auto_increment,
442
  tax_rate_country varchar(200) NOT NULL DEFAULT '',
443
  tax_rate_state varchar(200) NOT NULL DEFAULT '',
444
  tax_rate varchar(200) NOT NULL DEFAULT '',
445
  tax_rate_name varchar(200) NOT NULL DEFAULT '',
446
  tax_rate_priority bigint(20) NOT NULL,
447
  tax_rate_compound int(1) NOT NULL DEFAULT 0,
448
  tax_rate_shipping int(1) NOT NULL DEFAULT 1,
449
  tax_rate_order bigint(20) NOT NULL,
450
  tax_rate_class varchar(200) NOT NULL DEFAULT '',
451
  PRIMARY KEY  (tax_rate_id),
452
  KEY tax_rate_country (tax_rate_country),
453
  KEY tax_rate_state (tax_rate_state),
454
  KEY tax_rate_class (tax_rate_class),
455
  KEY tax_rate_priority (tax_rate_priority)
456
) $collate;
457
CREATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations (
458
  location_id bigint(20) NOT NULL auto_increment,
459
  location_code varchar(255) NOT NULL,
460
  tax_rate_id bigint(20) NOT NULL,
461
  location_type varchar(40) NOT NULL,
462
  PRIMARY KEY  (location_id),
463
  KEY tax_rate_id (tax_rate_id),
464
  KEY location_type (location_type),
465
  KEY location_type_code (location_type(40),location_code(90))
466
) $collate;
467
CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zones (
468
  zone_id bigint(20) NOT NULL auto_increment,
469
  zone_name varchar(255) NOT NULL,
470
  zone_order bigint(20) NOT NULL,
471
  PRIMARY KEY  (zone_id)
472
) $collate;
473
CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_locations (
474
  location_id bigint(20) NOT NULL auto_increment,
475
  zone_id bigint(20) NOT NULL,
476
  location_code varchar(255) NOT NULL,
477
  location_type varchar(40) NOT NULL,
478
  PRIMARY KEY  (location_id),
479
  KEY location_id (location_id),
480
  KEY location_type (location_type),
481
  KEY location_type_code (location_type(40),location_code(90))
482
) $collate;
483
CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_methods (
484
  zone_id bigint(20) NOT NULL,
485
  instance_id bigint(20) NOT NULL auto_increment,
486
  method_id varchar(255) NOT NULL,
487
  method_order bigint(20) NOT NULL,
488
  PRIMARY KEY  (instance_id)
489
) $collate;
490
		";
491
	}
492
493
	/**
494
	 * Create roles and capabilities.
495
	 */
496
	public static function create_roles() {
497
		global $wp_roles;
498
499
		if ( ! class_exists( 'WP_Roles' ) ) {
500
			return;
501
		}
502
503
		if ( ! isset( $wp_roles ) ) {
504
			$wp_roles = new WP_Roles();
505
		}
506
507
		// Customer role
508
		add_role( 'customer', __( 'Customer', 'woocommerce' ), array(
509
			'read' 					=> true
510
		) );
511
512
		// Shop manager role
513
		add_role( 'shop_manager', __( 'Shop Manager', 'woocommerce' ), array(
514
			'level_9'                => true,
515
			'level_8'                => true,
516
			'level_7'                => true,
517
			'level_6'                => true,
518
			'level_5'                => true,
519
			'level_4'                => true,
520
			'level_3'                => true,
521
			'level_2'                => true,
522
			'level_1'                => true,
523
			'level_0'                => true,
524
			'read'                   => true,
525
			'read_private_pages'     => true,
526
			'read_private_posts'     => true,
527
			'edit_users'             => true,
528
			'edit_posts'             => true,
529
			'edit_pages'             => true,
530
			'edit_published_posts'   => true,
531
			'edit_published_pages'   => true,
532
			'edit_private_pages'     => true,
533
			'edit_private_posts'     => true,
534
			'edit_others_posts'      => true,
535
			'edit_others_pages'      => true,
536
			'publish_posts'          => true,
537
			'publish_pages'          => true,
538
			'delete_posts'           => true,
539
			'delete_pages'           => true,
540
			'delete_private_pages'   => true,
541
			'delete_private_posts'   => true,
542
			'delete_published_pages' => true,
543
			'delete_published_posts' => true,
544
			'delete_others_posts'    => true,
545
			'delete_others_pages'    => true,
546
			'manage_categories'      => true,
547
			'manage_links'           => true,
548
			'moderate_comments'      => true,
549
			'unfiltered_html'        => true,
550
			'upload_files'           => true,
551
			'export'                 => true,
552
			'import'                 => true,
553
			'list_users'             => true
554
		) );
555
556
		$capabilities = self::get_core_capabilities();
557
558
		foreach ( $capabilities as $cap_group ) {
559
			foreach ( $cap_group as $cap ) {
560
				$wp_roles->add_cap( 'shop_manager', $cap );
561
				$wp_roles->add_cap( 'administrator', $cap );
562
			}
563
		}
564
	}
565
566
	/**
567
	 * Get capabilities for WooCommerce - these are assigned to admin/shop manager during installation or reset.
568
	 *
569
	 * @return array
570
	 */
571
	 private static function get_core_capabilities() {
572
		$capabilities = array();
573
574
		$capabilities['core'] = array(
575
			'manage_woocommerce',
576
			'view_woocommerce_reports'
577
		);
578
579
		$capability_types = array( 'product', 'shop_order', 'shop_coupon', 'shop_webhook' );
580
581
		foreach ( $capability_types as $capability_type ) {
582
583
			$capabilities[ $capability_type ] = array(
584
				// Post type
585
				"edit_{$capability_type}",
586
				"read_{$capability_type}",
587
				"delete_{$capability_type}",
588
				"edit_{$capability_type}s",
589
				"edit_others_{$capability_type}s",
590
				"publish_{$capability_type}s",
591
				"read_private_{$capability_type}s",
592
				"delete_{$capability_type}s",
593
				"delete_private_{$capability_type}s",
594
				"delete_published_{$capability_type}s",
595
				"delete_others_{$capability_type}s",
596
				"edit_private_{$capability_type}s",
597
				"edit_published_{$capability_type}s",
598
599
				// Terms
600
				"manage_{$capability_type}_terms",
601
				"edit_{$capability_type}_terms",
602
				"delete_{$capability_type}_terms",
603
				"assign_{$capability_type}_terms"
604
			);
605
		}
606
607
		return $capabilities;
608
	}
609
610
	/**
611
	 * woocommerce_remove_roles function.
612
	 */
613
	public static function remove_roles() {
614
		global $wp_roles;
615
616
		if ( ! class_exists( 'WP_Roles' ) ) {
617
			return;
618
		}
619
620
		if ( ! isset( $wp_roles ) ) {
621
			$wp_roles = new WP_Roles();
622
		}
623
624
		$capabilities = self::get_core_capabilities();
625
626
		foreach ( $capabilities as $cap_group ) {
627
			foreach ( $cap_group as $cap ) {
628
				$wp_roles->remove_cap( 'shop_manager', $cap );
629
				$wp_roles->remove_cap( 'administrator', $cap );
630
			}
631
		}
632
633
		remove_role( 'customer' );
634
		remove_role( 'shop_manager' );
635
	}
636
637
	/**
638
	 * Create files/directories.
639
	 */
640
	private static function create_files() {
641
		// Install files and folders for uploading files and prevent hotlinking
642
		$upload_dir      = wp_upload_dir();
643
		$download_method = get_option( 'woocommerce_file_download_method', 'force' );
644
645
		$files = array(
646
			array(
647
				'base' 		=> $upload_dir['basedir'] . '/woocommerce_uploads',
648
				'file' 		=> 'index.html',
649
				'content' 	=> ''
650
			),
651
			array(
652
				'base' 		=> WC_LOG_DIR,
653
				'file' 		=> '.htaccess',
654
				'content' 	=> 'deny from all'
655
			),
656
			array(
657
				'base' 		=> WC_LOG_DIR,
658
				'file' 		=> 'index.html',
659
				'content' 	=> ''
660
			)
661
		);
662
663
		if ( 'redirect' !== $download_method ) {
664
			$files[] = array(
665
				'base' 		=> $upload_dir['basedir'] . '/woocommerce_uploads',
666
				'file' 		=> '.htaccess',
667
				'content' 	=> 'deny from all'
668
			);
669
		}
670
671
		foreach ( $files as $file ) {
672
			if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
673
				if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
674
					fwrite( $file_handle, $file['content'] );
675
					fclose( $file_handle );
676
				}
677
			}
678
		}
679
	}
680
681
	/**
682
	 * Show plugin changes. Code adapted from W3 Total Cache.
683
	 */
684
	public static function in_plugin_update_message( $args ) {
685
		$transient_name = 'wc_upgrade_notice_' . $args['Version'];
686
687
		if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
688
			$response = wp_safe_remote_get( 'https://plugins.svn.wordpress.org/woocommerce/trunk/readme.txt' );
689
690
			if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
691
				$upgrade_notice = self::parse_update_notice( $response['body'] );
692
				set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
693
			}
694
		}
695
696
		echo wp_kses_post( $upgrade_notice );
697
	}
698
699
	/**
700
	 * Parse update notice from readme file.
701
	 * @param  string $content
702
	 * @return string
703
	 */
704
	private static function parse_update_notice( $content ) {
705
		// Output Upgrade Notice
706
		$matches        = null;
707
		$regexp         = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( WC_VERSION ) . '\s*=|$)~Uis';
708
		$upgrade_notice = '';
709
710
		if ( preg_match( $regexp, $content, $matches ) ) {
711
			$version = trim( $matches[1] );
712
			$notices = (array) preg_split('~[\r\n]+~', trim( $matches[2] ) );
713
714
			if ( version_compare( WC_VERSION, $version, '<' ) ) {
715
716
				$upgrade_notice .= '<div class="wc_plugin_upgrade_notice">';
717
718
				foreach ( $notices as $index => $line ) {
719
					$upgrade_notice .= wp_kses_post( preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line ) );
720
				}
721
722
				$upgrade_notice .= '</div> ';
723
			}
724
		}
725
726
		return wp_kses_post( $upgrade_notice );
727
	}
728
729
	/**
730
	 * Show action links on the plugin screen.
731
	 *
732
	 * @param	mixed $links Plugin Action links
733
	 * @return	array
734
	 */
735
	public static function plugin_action_links( $links ) {
736
		$action_links = array(
737
			'settings' => '<a href="' . admin_url( 'admin.php?page=wc-settings' ) . '" title="' . esc_attr( __( 'View WooCommerce Settings', 'woocommerce' ) ) . '">' . __( 'Settings', 'woocommerce' ) . '</a>',
738
		);
739
740
		return array_merge( $action_links, $links );
741
	}
742
743
	/**
744
	 * Show row meta on the plugin screen.
745
	 *
746
	 * @param	mixed $links Plugin Row Meta
747
	 * @param	mixed $file  Plugin Base file
748
	 * @return	array
749
	 */
750
	public static function plugin_row_meta( $links, $file ) {
751
		if ( $file == WC_PLUGIN_BASENAME ) {
752
			$row_meta = array(
753
				'docs'    => '<a href="' . esc_url( apply_filters( 'woocommerce_docs_url', 'http://docs.woothemes.com/documentation/plugins/woocommerce/' ) ) . '" title="' . esc_attr( __( 'View WooCommerce Documentation', 'woocommerce' ) ) . '">' . __( 'Docs', 'woocommerce' ) . '</a>',
754
				'apidocs' => '<a href="' . esc_url( apply_filters( 'woocommerce_apidocs_url', 'http://docs.woothemes.com/wc-apidocs/' ) ) . '" title="' . esc_attr( __( 'View WooCommerce API Docs', 'woocommerce' ) ) . '">' . __( 'API Docs', 'woocommerce' ) . '</a>',
755
				'support' => '<a href="' . esc_url( apply_filters( 'woocommerce_support_url', 'http://support.woothemes.com/' ) ) . '" title="' . esc_attr( __( 'Visit Premium Customer Support Forum', 'woocommerce' ) ) . '">' . __( 'Premium Support', 'woocommerce' ) . '</a>',
756
			);
757
758
			return array_merge( $links, $row_meta );
759
		}
760
761
		return (array) $links;
762
	}
763
764
	/**
765
	 * Uninstall tables when MU blog is deleted.
766
	 * @param  array $tables
767
	 * @return string[]
768
	 */
769
	public static function wpmu_drop_tables( $tables ) {
770
		global $wpdb;
771
772
		$tables[] = $wpdb->prefix . 'woocommerce_sessions';
773
		$tables[] = $wpdb->prefix . 'woocommerce_api_keys';
774
		$tables[] = $wpdb->prefix . 'woocommerce_attribute_taxonomies';
775
		$tables[] = $wpdb->prefix . 'woocommerce_downloadable_product_permissions';
776
		$tables[] = $wpdb->prefix . 'woocommerce_termmeta';
777
		$tables[] = $wpdb->prefix . 'woocommerce_tax_rates';
778
		$tables[] = $wpdb->prefix . 'woocommerce_tax_rate_locations';
779
		$tables[] = $wpdb->prefix . 'woocommerce_order_items';
780
		$tables[] = $wpdb->prefix . 'woocommerce_order_itemmeta';
781
782
		return $tables;
783
	}
784
}
785
786
WC_Install::init();
787