2013-07-25 15:29:25 +00:00
< ? php
/**
2016-06-06 17:20:10 +00:00
* Installation related functions and actions .
2013-07-25 15:29:25 +00:00
*
2020-08-05 16:36:24 +00:00
* @ package WooCommerce\Classes
2018-03-21 03:06:47 +00:00
* @ version 3.0 . 0
2013-07-25 15:29:25 +00:00
*/
2020-01-29 05:21:29 +00:00
use Automattic\Jetpack\Constants ;
2020-07-15 09:50:18 +00:00
use Automattic\WooCommerce\Internal\WCCom\ConnectionHelper as WCConnectionHelper ;
2020-01-29 05:21:29 +00:00
2018-03-21 03:06:47 +00:00
defined ( 'ABSPATH' ) || exit ;
2013-07-25 15:29:25 +00:00
/**
2015-11-03 13:31:20 +00:00
* WC_Install Class .
2013-07-25 15:29:25 +00:00
*/
class WC_Install {
2017-09-05 10:54:17 +00:00
/**
* DB updates and callbacks that need to be run per version .
*
* @ var array
*/
2015-04-29 09:47:57 +00:00
private static $db_updates = array (
2016-05-11 11:44:23 +00:00
'2.0.0' => array (
'wc_update_200_file_paths' ,
'wc_update_200_permalinks' ,
'wc_update_200_subcat_display' ,
'wc_update_200_taxrates' ,
'wc_update_200_line_items' ,
'wc_update_200_images' ,
'wc_update_200_db_version' ,
),
'2.0.9' => array (
'wc_update_209_brazillian_state' ,
'wc_update_209_db_version' ,
),
'2.1.0' => array (
'wc_update_210_remove_pages' ,
'wc_update_210_file_paths' ,
'wc_update_210_db_version' ,
),
'2.2.0' => array (
'wc_update_220_shipping' ,
'wc_update_220_order_status' ,
'wc_update_220_variations' ,
'wc_update_220_attributes' ,
'wc_update_220_db_version' ,
),
'2.3.0' => array (
'wc_update_230_options' ,
'wc_update_230_db_version' ,
),
'2.4.0' => array (
'wc_update_240_options' ,
'wc_update_240_shipping_methods' ,
'wc_update_240_api_keys' ,
'wc_update_240_refunds' ,
'wc_update_240_db_version' ,
),
'2.4.1' => array (
'wc_update_241_variations' ,
'wc_update_241_db_version' ,
),
'2.5.0' => array (
'wc_update_250_currency' ,
'wc_update_250_db_version' ,
),
'2.6.0' => array (
'wc_update_260_options' ,
'wc_update_260_termmeta' ,
'wc_update_260_zones' ,
'wc_update_260_zone_methods' ,
'wc_update_260_refunds' ,
'wc_update_260_db_version' ,
),
2017-03-15 16:55:07 +00:00
'3.0.0' => array (
'wc_update_300_grouped_products' ,
'wc_update_300_settings' ,
'wc_update_300_product_visibility' ,
'wc_update_300_db_version' ,
2016-08-03 20:32:02 +00:00
),
2017-06-01 18:26:35 +00:00
'3.1.0' => array (
'wc_update_310_downloadable_products' ,
2017-06-08 11:18:07 +00:00
'wc_update_310_old_comments' ,
2017-06-01 18:26:35 +00:00
'wc_update_310_db_version' ,
),
2017-08-15 16:01:28 +00:00
'3.1.2' => array (
'wc_update_312_shop_manager_capabilities' ,
'wc_update_312_db_version' ,
),
2017-06-28 11:57:37 +00:00
'3.2.0' => array (
'wc_update_320_mexican_states' ,
'wc_update_320_db_version' ,
2017-08-11 16:49:49 +00:00
),
2017-11-07 19:16:44 +00:00
'3.3.0' => array (
'wc_update_330_image_options' ,
2017-11-16 15:44:01 +00:00
'wc_update_330_webhooks' ,
2017-11-20 22:21:08 +00:00
'wc_update_330_product_stock_status' ,
2017-11-23 15:44:17 +00:00
'wc_update_330_set_default_product_cat' ,
2017-12-05 17:23:29 +00:00
'wc_update_330_clear_transients' ,
2018-01-23 02:51:01 +00:00
'wc_update_330_set_paypal_sandbox_credentials' ,
2017-11-07 19:16:44 +00:00
'wc_update_330_db_version' ,
),
2018-01-09 17:23:58 +00:00
'3.4.0' => array (
2018-04-17 15:13:44 +00:00
'wc_update_340_states' ,
2018-05-25 13:18:19 +00:00
'wc_update_340_state' ,
2018-05-01 13:13:38 +00:00
'wc_update_340_last_active' ,
2018-04-09 21:24:26 +00:00
'wc_update_340_db_version' ,
2018-01-09 17:23:58 +00:00
),
2018-06-18 14:47:47 +00:00
'3.4.3' => array (
'wc_update_343_cleanup_foreign_keys' ,
'wc_update_343_db_version' ,
),
2018-07-10 08:30:11 +00:00
'3.4.4' => array (
'wc_update_344_recreate_roles' ,
'wc_update_344_db_version' ,
),
2018-04-16 18:04:57 +00:00
'3.5.0' => array (
2018-09-20 16:28:39 +00:00
'wc_update_350_reviews_comment_type' ,
2018-06-11 13:54:02 +00:00
'wc_update_350_db_version' ,
2018-04-16 18:04:57 +00:00
),
2018-11-16 06:27:06 +00:00
'3.5.2' => array (
'wc_update_352_drop_download_log_fk' ,
2018-12-04 18:04:24 +00:00
),
2019-01-21 16:02:28 +00:00
'3.5.4' => array (
'wc_update_354_modify_shop_manager_caps' ,
'wc_update_354_db_version' ,
),
2019-02-12 13:27:30 +00:00
'3.6.0' => array (
'wc_update_360_product_lookup_tables' ,
2019-01-25 13:56:15 +00:00
'wc_update_360_term_meta' ,
2019-02-28 13:36:55 +00:00
'wc_update_360_downloadable_product_permissions_index' ,
2019-02-12 13:27:30 +00:00
'wc_update_360_db_version' ,
),
2019-03-20 15:27:43 +00:00
'3.7.0' => array (
'wc_update_370_tax_rate_classes' ,
2019-06-25 09:47:16 +00:00
'wc_update_370_mro_std_currency' ,
2019-03-20 15:27:43 +00:00
'wc_update_370_db_version' ,
),
2020-01-13 19:18:14 +00:00
'3.9.0' => array (
2020-01-15 18:24:13 +00:00
'wc_update_390_move_maxmind_database' ,
2020-01-14 01:00:39 +00:00
'wc_update_390_change_geolocation_database_update_cron' ,
2020-01-14 21:39:47 +00:00
'wc_update_390_db_version' ,
2020-01-13 19:18:14 +00:00
),
2020-02-03 22:36:52 +00:00
'4.0.0' => array (
2020-01-20 14:21:42 +00:00
'wc_update_product_lookup_tables' ,
2020-02-04 14:06:26 +00:00
'wc_update_400_increase_size_of_column' ,
2020-03-10 12:27:30 +00:00
'wc_update_400_reset_action_scheduler_migration_status' ,
2020-02-03 22:36:52 +00:00
'wc_update_400_db_version' ,
2019-12-18 07:28:27 +00:00
),
2020-07-09 14:47:14 +00:00
'4.4.0' => array (
'wc_update_440_insert_attribute_terms_for_variable_products' ,
'wc_update_440_db_version' ,
2020-04-29 15:35:56 +00:00
),
2020-07-27 19:50:23 +00:00
'4.5.0' => array (
'wc_update_450_sanitize_coupons_code' ,
'wc_update_450_db_version' ,
),
2015-04-29 09:47:57 +00:00
);
2013-07-25 15:29:25 +00:00
/**
* Hook in tabs .
*/
2014-11-25 17:09:19 +00:00
public static function init () {
2016-01-19 10:05:44 +00:00
add_action ( 'init' , array ( __CLASS__ , 'check_version' ), 5 );
2019-06-19 20:19:13 +00:00
add_action ( 'init' , array ( __CLASS__ , 'manual_database_update' ), 20 );
2020-03-13 18:20:41 +00:00
add_action ( 'admin_init' , array ( __CLASS__ , 'wc_admin_db_update_notice' ) );
2019-02-28 11:11:08 +00:00
add_action ( 'woocommerce_run_update_callback' , array ( __CLASS__ , 'run_update_callback' ) );
2014-11-25 17:09:19 +00:00
add_action ( 'admin_init' , array ( __CLASS__ , 'install_actions' ) );
add_filter ( 'plugin_action_links_' . WC_PLUGIN_BASENAME , array ( __CLASS__ , 'plugin_action_links' ) );
add_filter ( 'plugin_row_meta' , array ( __CLASS__ , 'plugin_row_meta' ), 10 , 2 );
add_filter ( 'wpmu_drop_tables' , array ( __CLASS__ , 'wpmu_drop_tables' ) );
2015-09-03 15:21:53 +00:00
add_filter ( 'cron_schedules' , array ( __CLASS__ , 'cron_schedules' ) );
2016-06-15 15:11:04 +00:00
}
2016-05-11 11:44:23 +00:00
2013-07-25 15:29:25 +00:00
/**
2016-01-19 10:05:44 +00:00
* Check WooCommerce version and run the updater is required .
*
2017-04-29 06:52:14 +00:00
* This check is done on all requests and runs if the versions do not match .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function check_version () {
2020-01-29 05:21:29 +00:00
if ( ! Constants :: is_defined ( 'IFRAME_REQUEST' ) && version_compare ( get_option ( 'woocommerce_version' ), WC () -> version , '<' ) ) {
2014-11-25 17:09:19 +00:00
self :: install ();
2014-02-11 13:33:56 +00:00
do_action ( 'woocommerce_updated' );
2014-01-12 00:05:14 +00:00
}
2013-07-25 15:29:25 +00:00
}
2019-06-19 20:19:13 +00:00
/**
* Performan manual database update when triggered by WooCommerce System Tools .
*
* @ since 3.6 . 5
*/
public static function manual_database_update () {
$blog_id = get_current_blog_id ();
add_action ( 'wp_' . $blog_id . '_wc_updater_cron' , array ( __CLASS__ , 'run_manual_database_update' ) );
}
2020-02-23 20:59:03 +00:00
/**
* Add WC Admin based db update notice .
*
* @ since 4.0 . 0
*/
public static function wc_admin_db_update_notice () {
2020-03-13 18:20:41 +00:00
if (
WC () -> is_wc_admin_active () &&
false !== get_option ( 'woocommerce_admin_install_timestamp' )
) {
2020-02-23 20:59:03 +00:00
new WC_Notes_Run_Db_Update ();
}
}
2019-06-19 20:19:13 +00:00
/**
* Run manual database update .
*/
public static function run_manual_database_update () {
self :: update ();
}
2019-02-28 11:11:08 +00:00
/**
* Run an update callback when triggered by ActionScheduler .
*
* @ since 3.6 . 0
* @ param string $callback Callback name .
*/
2019-02-28 11:52:56 +00:00
public static function run_update_callback ( $callback ) {
2019-02-28 11:11:08 +00:00
include_once dirname ( __FILE__ ) . '/wc-update-functions.php' ;
if ( is_callable ( $callback ) ) {
2019-02-28 11:52:56 +00:00
self :: run_update_callback_start ( $callback );
2019-02-28 11:11:08 +00:00
$result = ( bool ) call_user_func ( $callback );
2019-02-28 11:52:56 +00:00
self :: run_update_callback_end ( $callback , $result );
2019-02-28 11:11:08 +00:00
}
}
/**
* Triggered when a callback will run .
*
* @ since 3.6 . 0
* @ param string $callback Callback name .
*/
2019-02-28 11:52:56 +00:00
protected static function run_update_callback_start ( $callback ) {
2019-02-28 11:11:08 +00:00
wc_maybe_define_constant ( 'WC_UPDATING' , true );
}
/**
* Triggered when a callback has ran .
*
* @ since 3.6 . 0
* @ param string $callback Callback name .
* @ param bool $result Return value from callback . Non - false need to run again .
*/
2019-02-28 11:52:56 +00:00
protected static function run_update_callback_end ( $callback , $result ) {
2019-02-28 11:11:08 +00:00
if ( $result ) {
WC () -> queue () -> add (
'woocommerce_run_update_callback' ,
array (
'update_callback' => $callback ,
),
'woocommerce-db-updates'
);
}
}
2013-07-25 15:29:25 +00:00
/**
2016-01-19 10:05:44 +00:00
* Install actions when a update button is clicked within the admin area .
*
* This function is hooked into admin_init to affect admin only .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function install_actions () {
2018-06-07 12:05:46 +00:00
if ( ! empty ( $_GET [ 'do_update_woocommerce' ] ) ) { // WPCS: input var ok.
check_admin_referer ( 'wc_db_update' , 'wc_db_update_nonce' );
2014-11-25 17:09:19 +00:00
self :: update ();
2020-02-25 13:58:02 +00:00
WC_Admin_Notices :: add_notice ( 'update' , true );
2013-07-25 15:29:25 +00:00
}
}
/**
2015-11-03 13:31:20 +00:00
* Install WC .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function install () {
2016-11-09 11:53:39 +00:00
if ( ! is_blog_installed () ) {
return ;
}
2017-09-27 15:41:26 +00:00
// Check if we are not already running this routine.
if ( 'yes' === get_transient ( 'wc_installing' ) ) {
return ;
2015-01-23 13:29:23 +00:00
}
2015-01-23 13:05:35 +00:00
2017-09-27 15:41:26 +00:00
// If we made it till here nothing is running yet, lets set the transient now.
set_transient ( 'wc_installing' , 'yes' , MINUTE_IN_SECONDS * 10 );
2017-09-05 10:54:17 +00:00
wc_maybe_define_constant ( 'WC_INSTALLING' , true );
2015-01-28 17:50:58 +00:00
2019-03-20 15:27:43 +00:00
WC () -> wpdb_table_fix ();
2017-09-05 10:54:17 +00:00
self :: remove_admin_notices ();
2014-11-25 17:09:19 +00:00
self :: create_tables ();
2020-05-11 18:04:51 +00:00
self :: verify_base_tables ();
2019-07-09 18:12:34 +00:00
self :: create_options ();
2014-11-25 17:09:19 +00:00
self :: create_roles ();
2017-09-05 10:54:17 +00:00
self :: setup_environment ();
self :: create_terms ();
self :: create_cron_jobs ();
self :: create_files ();
self :: maybe_enable_setup_wizard ();
self :: update_wc_version ();
self :: maybe_update_db_version ();
2020-05-28 02:11:06 +00:00
self :: maybe_enable_homescreen ();
2017-09-05 10:54:17 +00:00
2017-09-27 15:41:26 +00:00
delete_transient ( 'wc_installing' );
2013-07-25 15:29:25 +00:00
2017-09-05 10:54:17 +00:00
do_action ( 'woocommerce_flush_rewrite_rules' );
do_action ( 'woocommerce_installed' );
}
2013-07-25 15:29:25 +00:00
2020-05-11 18:04:51 +00:00
/**
* Check if all the base tables are present .
*
* @ param bool $modify_notice Whether to modify notice based on if all tables are present .
2020-05-26 17:56:45 +00:00
* @ param bool $execute Whether to execute get_schema queries as well .
2020-05-11 18:04:51 +00:00
*
* @ return array List of querues .
*/
2020-05-26 17:56:45 +00:00
public static function verify_base_tables ( $modify_notice = true , $execute = false ) {
2020-05-11 18:04:51 +00:00
require_once ABSPATH . 'wp-admin/includes/upgrade.php' ;
2020-05-26 17:56:45 +00:00
if ( $execute ) {
self :: create_tables ();
}
2020-06-02 02:55:17 +00:00
$queries = dbDelta ( self :: get_schema (), false );
2020-05-11 18:04:51 +00:00
$missing_tables = array ();
foreach ( $queries as $table_name => $result ) {
if ( " Created table $table_name " === $result ) {
$missing_tables [] = $table_name ;
}
}
if ( 0 < count ( $missing_tables ) ) {
if ( $modify_notice ) {
WC_Admin_Notices :: add_notice ( 'base_tables_missing' );
}
2020-06-04 15:03:38 +00:00
update_option ( 'woocommerce_schema_missing_tables' , $missing_tables );
2020-05-11 18:04:51 +00:00
} else {
if ( $modify_notice ) {
WC_Admin_Notices :: remove_notice ( 'base_tables_missing' );
}
2020-06-04 17:08:13 +00:00
update_option ( 'woocommerce_schema_version' , WC () -> db_version );
2020-06-04 15:03:38 +00:00
delete_option ( 'woocommerce_schema_missing_tables' );
2020-05-11 18:04:51 +00:00
}
return $missing_tables ;
}
2020-05-28 02:11:06 +00:00
/**
* Check if the homepage should be enabled and set the appropriate option if thats the case .
*
* @ since 4.3 . 0
*/
private static function maybe_enable_homescreen () {
if ( self :: is_new_install () && ! get_option ( 'woocommerce_homescreen_enabled' ) ) {
add_option ( 'woocommerce_homescreen_enabled' , 'yes' );
}
}
2017-09-05 10:54:17 +00:00
/**
* Reset any notices added to admin .
*
* @ since 3.2 . 0
*/
private static function remove_admin_notices () {
2017-11-23 12:41:31 +00:00
include_once dirname ( __FILE__ ) . '/admin/class-wc-admin-notices.php' ;
2017-09-05 10:54:17 +00:00
WC_Admin_Notices :: remove_all_notices ();
}
/**
* Setup WC environment - post types , taxonomies , endpoints .
*
* @ since 3.2 . 0
*/
private static function setup_environment () {
2014-02-11 00:29:29 +00:00
WC_Post_types :: register_post_types ();
2014-02-05 15:01:30 +00:00
WC_Post_types :: register_taxonomies ();
2014-02-11 00:29:29 +00:00
WC () -> query -> init_query_vars ();
WC () -> query -> add_endpoints ();
2015-03-20 14:20:12 +00:00
WC_API :: add_endpoint ();
2015-04-17 20:41:25 +00:00
WC_Auth :: add_endpoint ();
2017-09-05 10:54:17 +00:00
}
2014-02-11 00:29:29 +00:00
2017-09-05 10:54:17 +00:00
/**
* Is this a brand new WC install ?
*
2019-03-08 15:11:23 +00:00
* A brand new install has no version yet . Also treat empty installs as 'new' .
*
2018-11-16 06:29:13 +00:00
* @ since 3.2 . 0
2017-09-05 10:54:17 +00:00
* @ return boolean
*/
2020-02-07 10:06:35 +00:00
public static function is_new_install () {
2019-03-08 15:11:23 +00:00
$product_count = array_sum ( ( array ) wp_count_posts ( 'product' ) );
return is_null ( get_option ( 'woocommerce_version' , null ) ) || ( 0 === $product_count && - 1 === wc_get_page_id ( 'shop' ) );
2017-09-05 10:54:17 +00:00
}
2013-07-25 15:29:25 +00:00
2017-09-05 10:54:17 +00:00
/**
* Is a DB update needed ?
*
2018-11-16 06:29:13 +00:00
* @ since 3.2 . 0
2017-09-05 10:54:17 +00:00
* @ return boolean
*/
2019-02-28 11:52:56 +00:00
public static function needs_db_update () {
2017-09-05 10:54:17 +00:00
$current_db_version = get_option ( 'woocommerce_db_version' , null );
$updates = self :: get_db_update_callbacks ();
2019-03-20 12:05:12 +00:00
$update_versions = array_keys ( $updates );
2019-03-20 12:06:13 +00:00
usort ( $update_versions , 'version_compare' );
2013-07-25 15:29:25 +00:00
2019-03-20 12:05:12 +00:00
return ! is_null ( $current_db_version ) && version_compare ( $current_db_version , end ( $update_versions ), '<' );
2017-09-05 10:54:17 +00:00
}
2013-07-25 15:29:25 +00:00
2017-09-05 10:54:17 +00:00
/**
* See if we need the wizard or not .
*
* @ since 3.2 . 0
*/
private static function maybe_enable_setup_wizard () {
2019-03-08 15:11:23 +00:00
if ( apply_filters ( 'woocommerce_enable_setup_wizard' , true ) && self :: is_new_install () ) {
2020-02-25 14:00:37 +00:00
WC_Admin_Notices :: add_notice ( 'install' , true );
2015-04-29 10:24:29 +00:00
set_transient ( '_wc_activation_redirect' , 1 , 30 );
2014-01-12 00:05:14 +00:00
}
2017-09-05 10:54:17 +00:00
}
2013-07-25 15:29:25 +00:00
2017-09-05 10:54:17 +00:00
/**
* See if we need to show or run database updates during install .
*
* @ since 3.2 . 0
*/
private static function maybe_update_db_version () {
if ( self :: needs_db_update () ) {
2017-09-06 09:49:03 +00:00
if ( apply_filters ( 'woocommerce_enable_auto_update_db' , false ) ) {
2017-09-05 10:54:17 +00:00
self :: update ();
} else {
2020-02-25 13:58:02 +00:00
WC_Admin_Notices :: add_notice ( 'update' , true );
2017-09-05 10:54:17 +00:00
}
2013-07-25 15:29:25 +00:00
} else {
2015-04-29 09:47:57 +00:00
self :: update_db_version ();
2013-07-25 15:29:25 +00:00
}
}
2015-04-29 09:47:57 +00:00
/**
2015-11-03 13:31:20 +00:00
* Update WC version to current .
2015-04-29 09:47:57 +00:00
*/
private static function update_wc_version () {
delete_option ( 'woocommerce_version' );
add_option ( 'woocommerce_version' , WC () -> version );
}
2016-12-13 13:38:20 +00:00
/**
* Get list of DB update callbacks .
*
2017-03-15 16:36:53 +00:00
* @ since 3.0 . 0
2016-12-13 13:38:20 +00:00
* @ return array
*/
public static function get_db_update_callbacks () {
return self :: $db_updates ;
}
2015-04-29 09:47:57 +00:00
/**
2016-05-11 11:44:23 +00:00
* Push all needed DB updates to the queue for processing .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
private static function update () {
2013-07-25 15:29:25 +00:00
$current_db_version = get_option ( 'woocommerce_db_version' );
2019-02-28 11:52:56 +00:00
$loop = 0 ;
2015-04-29 09:47:57 +00:00
2016-12-13 13:38:20 +00:00
foreach ( self :: get_db_update_callbacks () as $version => $update_callbacks ) {
2014-11-25 17:09:19 +00:00
if ( version_compare ( $current_db_version , $version , '<' ) ) {
2016-05-11 11:44:23 +00:00
foreach ( $update_callbacks as $update_callback ) {
2019-02-28 11:52:56 +00:00
WC () -> queue () -> schedule_single (
time () + $loop ,
2019-02-28 11:11:08 +00:00
'woocommerce_run_update_callback' ,
array (
'update_callback' => $update_callback ,
),
'woocommerce-db-updates'
2016-11-22 18:52:16 +00:00
);
2019-02-28 11:52:56 +00:00
$loop ++ ;
2016-05-11 11:44:23 +00:00
}
2014-01-12 00:05:14 +00:00
}
2014-05-30 17:27:41 +00:00
}
2016-05-11 11:44:23 +00:00
}
/**
* Update DB version to current .
2017-11-23 12:41:31 +00:00
*
2017-11-23 13:55:25 +00:00
* @ param string | null $version New WooCommerce DB version or null .
2016-05-11 11:44:23 +00:00
*/
public static function update_db_version ( $version = null ) {
delete_option ( 'woocommerce_db_version' );
add_option ( 'woocommerce_db_version' , is_null ( $version ) ? WC () -> version : $version );
2013-07-25 15:29:25 +00:00
}
2015-09-03 15:21:53 +00:00
/**
2015-11-03 13:31:20 +00:00
* Add more cron schedules .
2017-11-23 12:41:31 +00:00
*
2018-11-16 06:29:13 +00:00
* @ param array $schedules List of WP scheduled cron jobs .
*
2015-09-03 15:21:53 +00:00
* @ return array
*/
public static function cron_schedules ( $schedules ) {
2020-01-20 14:21:42 +00:00
$schedules [ 'monthly' ] = array (
2015-09-03 15:21:53 +00:00
'interval' => 2635200 ,
2016-08-27 01:46:45 +00:00
'display' => __ ( 'Monthly' , 'woocommerce' ),
2015-09-03 15:21:53 +00:00
);
2020-01-14 01:00:39 +00:00
$schedules [ 'fifteendays' ] = array (
'interval' => 1296000 ,
'display' => __ ( 'Every 15 Days' , 'woocommerce' ),
);
2015-09-03 15:21:53 +00:00
return $schedules ;
}
2013-07-25 15:29:25 +00:00
/**
2015-11-03 13:31:20 +00:00
* Create cron jobs ( clear them first ) .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
private static function create_cron_jobs () {
2013-07-25 15:29:25 +00:00
wp_clear_scheduled_hook ( 'woocommerce_scheduled_sales' );
wp_clear_scheduled_hook ( 'woocommerce_cancel_unpaid_orders' );
wp_clear_scheduled_hook ( 'woocommerce_cleanup_sessions' );
2018-04-30 14:38:45 +00:00
wp_clear_scheduled_hook ( 'woocommerce_cleanup_personal_data' );
2018-05-01 15:37:14 +00:00
wp_clear_scheduled_hook ( 'woocommerce_cleanup_logs' );
2014-12-23 18:49:43 +00:00
wp_clear_scheduled_hook ( 'woocommerce_geoip_updater' );
2015-01-23 16:36:52 +00:00
wp_clear_scheduled_hook ( 'woocommerce_tracker_send_event' );
2013-07-25 15:29:25 +00:00
2017-02-08 12:08:49 +00:00
$ve = get_option ( 'gmt_offset' ) > 0 ? '-' : '+' ;
2013-07-25 15:29:25 +00:00
2017-08-28 19:35:11 +00:00
wp_schedule_event ( strtotime ( '00:00 tomorrow ' . $ve . absint ( get_option ( 'gmt_offset' ) ) . ' HOURS' ), 'daily' , 'woocommerce_scheduled_sales' );
2013-07-25 15:29:25 +00:00
2014-11-25 17:09:19 +00:00
$held_duration = get_option ( 'woocommerce_hold_stock_minutes' , '60' );
2013-07-25 15:29:25 +00:00
2018-03-21 03:06:47 +00:00
if ( '' !== $held_duration ) {
2013-07-25 15:29:25 +00:00
wp_schedule_single_event ( time () + ( absint ( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
2014-01-12 00:05:14 +00:00
}
2013-07-25 15:29:25 +00:00
2020-01-15 17:22:49 +00:00
// Delay the first run of `woocommerce_cleanup_personal_data` by 10 seconds
// so it doesn't occur in the same request. WooCommerce Admin also schedules
// a daily cron that gets lost due to a race condition. WC_Privacy's background
// processing instance updates the cron schedule from within a cron job.
wp_schedule_event ( time () + 10 , 'daily' , 'woocommerce_cleanup_personal_data' );
2018-05-01 15:37:14 +00:00
wp_schedule_event ( time () + ( 3 * HOUR_IN_SECONDS ), 'daily' , 'woocommerce_cleanup_logs' );
wp_schedule_event ( time () + ( 6 * HOUR_IN_SECONDS ), 'twicedaily' , 'woocommerce_cleanup_sessions' );
2020-01-14 21:20:20 +00:00
wp_schedule_event ( time () + MINUTE_IN_SECONDS , 'fifteendays' , 'woocommerce_geoip_updater' );
2018-04-24 10:42:06 +00:00
wp_schedule_event ( time () + 10 , apply_filters ( 'woocommerce_tracker_event_recurrence' , 'daily' ), 'woocommerce_tracker_send_event' );
2013-07-25 15:29:25 +00:00
}
/**
2017-03-20 15:47:51 +00:00
* Create pages that the plugin relies on , storing page IDs in variables .
2013-07-25 15:29:25 +00:00
*/
2013-11-18 15:56:04 +00:00
public static function create_pages () {
2017-11-23 12:41:31 +00:00
include_once dirname ( __FILE__ ) . '/admin/wc-admin-functions.php' ;
$pages = apply_filters (
2018-11-23 14:57:51 +00:00
'woocommerce_create_pages' ,
array (
2017-11-23 12:41:31 +00:00
'shop' => array (
'name' => _x ( 'shop' , 'Page slug' , 'woocommerce' ),
'title' => _x ( 'Shop' , 'Page title' , 'woocommerce' ),
'content' => '' ,
),
'cart' => array (
'name' => _x ( 'cart' , 'Page slug' , 'woocommerce' ),
'title' => _x ( 'Cart' , 'Page title' , 'woocommerce' ),
2018-11-05 16:45:48 +00:00
'content' => '<!-- wp:shortcode -->[' . apply_filters ( 'woocommerce_cart_shortcode_tag' , 'woocommerce_cart' ) . ']<!-- /wp:shortcode -->' ,
2017-11-23 12:41:31 +00:00
),
'checkout' => array (
'name' => _x ( 'checkout' , 'Page slug' , 'woocommerce' ),
'title' => _x ( 'Checkout' , 'Page title' , 'woocommerce' ),
2018-11-05 16:45:48 +00:00
'content' => '<!-- wp:shortcode -->[' . apply_filters ( 'woocommerce_checkout_shortcode_tag' , 'woocommerce_checkout' ) . ']<!-- /wp:shortcode -->' ,
2017-11-23 12:41:31 +00:00
),
'myaccount' => array (
'name' => _x ( 'my-account' , 'Page slug' , 'woocommerce' ),
'title' => _x ( 'My account' , 'Page title' , 'woocommerce' ),
2018-11-05 16:45:48 +00:00
'content' => '<!-- wp:shortcode -->[' . apply_filters ( 'woocommerce_my_account_shortcode_tag' , 'woocommerce_my_account' ) . ']<!-- /wp:shortcode -->' ,
2017-11-23 12:41:31 +00:00
),
)
);
2013-07-25 15:29:25 +00:00
2014-01-12 00:05:14 +00:00
foreach ( $pages as $key => $page ) {
2013-11-25 14:07:22 +00:00
wc_create_page ( esc_sql ( $page [ 'name' ] ), 'woocommerce_' . $key . '_page_id' , $page [ 'title' ], $page [ 'content' ], ! empty ( $page [ 'parent' ] ) ? wc_get_page_id ( $page [ 'parent' ] ) : '' );
2014-01-12 00:05:14 +00:00
}
2013-07-25 15:29:25 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Default options .
2013-07-25 15:29:25 +00:00
*
2015-11-03 13:31:20 +00:00
* Sets up the default options used on the settings page .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
private static function create_options () {
2017-11-23 13:55:25 +00:00
// Include settings so that we can run through defaults.
2017-11-23 12:41:31 +00:00
include_once dirname ( __FILE__ ) . '/admin/class-wc-admin-settings.php' ;
2013-07-26 14:36:28 +00:00
$settings = WC_Admin_Settings :: get_settings_pages ();
2013-07-25 15:29:25 +00:00
2013-07-26 14:36:28 +00:00
foreach ( $settings as $section ) {
2014-09-10 16:35:46 +00:00
if ( ! method_exists ( $section , 'get_settings' ) ) {
continue ;
}
2015-01-23 12:36:22 +00:00
$subsections = array_unique ( array_merge ( array ( '' ), array_keys ( $section -> get_sections () ) ) );
2014-09-10 16:35:46 +00:00
2015-01-23 12:36:22 +00:00
foreach ( $subsections as $subsection ) {
foreach ( $section -> get_settings ( $subsection ) as $value ) {
2014-01-11 23:56:29 +00:00
if ( isset ( $value [ 'default' ] ) && isset ( $value [ 'id' ] ) ) {
$autoload = isset ( $value [ 'autoload' ] ) ? ( bool ) $value [ 'autoload' ] : true ;
add_option ( $value [ 'id' ], $value [ 'default' ], '' , ( $autoload ? 'yes' : 'no' ) );
}
}
}
}
2018-05-01 11:15:57 +00:00
// Define other defaults if not in setting screens.
add_option ( 'woocommerce_single_image_width' , '600' , '' , 'yes' );
add_option ( 'woocommerce_thumbnail_image_width' , '300' , '' , 'yes' );
2018-05-03 15:50:26 +00:00
add_option ( 'woocommerce_checkout_highlight_required_fields' , 'yes' , '' , 'yes' );
2018-05-01 11:15:57 +00:00
add_option ( 'woocommerce_demo_store' , 'no' , '' , 'no' );
2019-07-09 18:13:02 +00:00
// Define initial tax classes.
WC_Tax :: create_tax_class ( __ ( 'Reduced rate' , 'woocommerce' ) );
WC_Tax :: create_tax_class ( __ ( 'Zero rate' , 'woocommerce' ) );
2013-07-25 15:29:25 +00:00
}
2014-11-25 17:09:19 +00:00
/**
* Add the default terms for WC taxonomies - product types and order statuses . Modify this at your own risk .
*/
2017-03-27 10:55:36 +00:00
public static function create_terms () {
2014-11-25 17:09:19 +00:00
$taxonomies = array (
2017-11-23 12:41:31 +00:00
'product_type' => array (
2014-11-25 17:09:19 +00:00
'simple' ,
'grouped' ,
'variable' ,
2016-08-27 02:08:49 +00:00
'external' ,
2016-08-27 01:46:45 +00:00
),
2016-12-08 10:56:45 +00:00
'product_visibility' => array (
'exclude-from-search' ,
'exclude-from-catalog' ,
'featured' ,
'outofstock' ,
2016-12-09 15:43:25 +00:00
'rated-1' ,
'rated-2' ,
'rated-3' ,
'rated-4' ,
'rated-5' ,
2016-12-08 10:56:45 +00:00
),
2014-11-25 17:09:19 +00:00
);
foreach ( $taxonomies as $taxonomy => $terms ) {
foreach ( $terms as $term ) {
2017-11-23 14:26:34 +00:00
if ( ! get_term_by ( 'name' , $term , $taxonomy ) ) { // @codingStandardsIgnoreLine.
2014-11-25 17:09:19 +00:00
wp_insert_term ( $term , $taxonomy );
}
}
}
2017-11-23 14:26:34 +00:00
2018-03-13 13:12:01 +00:00
$woocommerce_default_category = ( int ) get_option ( 'default_product_cat' , 0 );
2017-11-23 14:26:34 +00:00
2017-11-23 14:38:40 +00:00
if ( ! $woocommerce_default_category || ! term_exists ( $woocommerce_default_category , 'product_cat' ) ) {
$default_product_cat_id = 0 ;
$default_product_cat_slug = sanitize_title ( _x ( 'Uncategorized' , 'Default category slug' , 'woocommerce' ) );
$default_product_cat = get_term_by ( 'slug' , $default_product_cat_slug , 'product_cat' ); // @codingStandardsIgnoreLine.
2017-11-23 14:26:34 +00:00
2017-11-23 14:38:40 +00:00
if ( $default_product_cat ) {
2017-11-23 15:44:17 +00:00
$default_product_cat_id = absint ( $default_product_cat -> term_taxonomy_id );
2017-11-23 14:38:40 +00:00
} else {
$result = wp_insert_term ( _x ( 'Uncategorized' , 'Default category slug' , 'woocommerce' ), 'product_cat' , array ( 'slug' => $default_product_cat_slug ) );
2018-03-13 14:02:55 +00:00
if ( ! is_wp_error ( $result ) && ! empty ( $result [ 'term_taxonomy_id' ] ) ) {
2017-11-23 15:44:17 +00:00
$default_product_cat_id = absint ( $result [ 'term_taxonomy_id' ] );
2017-11-23 14:38:40 +00:00
}
}
if ( $default_product_cat_id ) {
2017-11-23 14:41:17 +00:00
update_option ( 'default_product_cat' , $default_product_cat_id );
2017-11-23 14:26:34 +00:00
}
}
2014-11-25 17:09:19 +00:00
}
2013-07-25 15:29:25 +00:00
/**
* Set up the database tables which the plugin needs to function .
2020-05-26 17:56:45 +00:00
* WARNING : If you are modifying this method , make sure that its safe to call regardless of the state of database .
*
* This is called from `install` method and is executed in - sync when WC is installed or updated . This can also be called optionally from `verify_base_tables` .
*
* TODO : Add all crucial tables that we have created from workers in the past .
2013-07-25 15:29:25 +00:00
*
* Tables :
2017-11-23 12:41:31 +00:00
* woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined
* woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions .
* KEY ( order_id , product_id , download_id ) used for organizing downloads on the My Account page
* woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports
* woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data .
* woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient .
* woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode / city hence the second table .
2013-07-25 15:29:25 +00:00
*/
2020-05-26 18:29:28 +00:00
private static function create_tables () {
2014-06-08 20:33:11 +00:00
global $wpdb ;
2013-07-25 15:29:25 +00:00
$wpdb -> hide_errors ();
2017-11-23 12:41:31 +00:00
require_once ABSPATH . 'wp-admin/includes/upgrade.php' ;
2013-07-25 15:29:25 +00:00
2014-02-13 13:29:55 +00:00
/**
2016-03-11 12:32:43 +00:00
* Before updating with DBDELTA , remove any primary keys which could be
* modified due to schema updates .
2014-02-13 13:29:55 +00:00
*/
if ( $wpdb -> get_var ( " SHOW TABLES LIKE ' { $wpdb -> prefix } woocommerce_downloadable_product_permissions'; " ) ) {
if ( ! $wpdb -> get_var ( " SHOW COLUMNS FROM ` { $wpdb -> prefix } woocommerce_downloadable_product_permissions` LIKE 'permission_id'; " ) ) {
2017-02-13 11:49:30 +00:00
$wpdb -> query ( " ALTER TABLE { $wpdb -> prefix } woocommerce_downloadable_product_permissions DROP PRIMARY KEY, ADD `permission_id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT; " );
2014-02-13 13:29:55 +00:00
}
}
2018-10-17 15:11:01 +00:00
/**
* Change wp_woocommerce_sessions schema to use a bigint auto increment field instead of char ( 32 ) field as
* the primary key as it is not a good practice to use a char ( 32 ) field as the primary key of a table and as
* there were reports of issues with this table ( see https :// github . com / woocommerce / woocommerce / issues / 20912 ) .
*
* This query needs to run before dbDelta () as this WP function is not able to handle primary key changes
* ( see https :// github . com / woocommerce / woocommerce / issues / 21534 and https :// core . trac . wordpress . org / ticket / 40357 ) .
*/
if ( $wpdb -> get_var ( " SHOW TABLES LIKE ' { $wpdb -> prefix } woocommerce_sessions' " ) ) {
if ( ! $wpdb -> get_var ( " SHOW KEYS FROM { $wpdb -> prefix } woocommerce_sessions WHERE Key_name = 'PRIMARY' AND Column_name = 'session_id' " ) ) {
$wpdb -> query (
" ALTER TABLE ` { $wpdb -> prefix } woocommerce_sessions` DROP PRIMARY KEY, DROP KEY `session_id`, ADD PRIMARY KEY(`session_id`), ADD UNIQUE KEY(`session_key`) "
);
}
}
2014-11-25 17:09:19 +00:00
dbDelta ( self :: get_schema () );
2016-08-09 08:00:51 +00:00
2017-02-16 16:45:50 +00:00
$index_exists = $wpdb -> get_row ( " SHOW INDEX FROM { $wpdb -> comments } WHERE column_name = 'comment_type' and key_name = 'woo_idx_comment_type' " );
2016-08-09 12:28:41 +00:00
if ( is_null ( $index_exists ) ) {
// Add an index to the field comment_type to improve the response time of the query
// used by WC_Comments::wp_count_comments() to get the number of comments by type.
$wpdb -> query ( " ALTER TABLE { $wpdb -> comments } ADD INDEX woo_idx_comment_type (comment_type) " );
}
2018-04-13 17:03:02 +00:00
2018-06-04 11:21:01 +00:00
// Get tables data types and check it matches before adding constraint.
2018-06-04 11:31:03 +00:00
$download_log_columns = $wpdb -> get_results ( " SHOW COLUMNS FROM { $wpdb -> prefix } wc_download_log WHERE Field = 'permission_id' " , ARRAY_A );
2018-06-04 11:21:01 +00:00
$download_log_column_type = '' ;
if ( isset ( $download_log_columns [ 0 ][ 'Type' ] ) ) {
$download_log_column_type = $download_log_columns [ 0 ][ 'Type' ];
}
2018-06-04 11:10:05 +00:00
2018-06-04 11:31:03 +00:00
$download_permissions_columns = $wpdb -> get_results ( " SHOW COLUMNS FROM { $wpdb -> prefix } woocommerce_downloadable_product_permissions WHERE Field = 'permission_id' " , ARRAY_A );
2018-06-04 11:21:01 +00:00
$download_permissions_column_type = '' ;
if ( isset ( $download_permissions_columns [ 0 ][ 'Type' ] ) ) {
$download_permissions_column_type = $download_permissions_columns [ 0 ][ 'Type' ];
}
2018-06-04 11:10:05 +00:00
2018-06-04 11:21:01 +00:00
// Add constraint to download logs if the columns matches.
if ( ! empty ( $download_permissions_column_type ) && ! empty ( $download_log_column_type ) && $download_permissions_column_type === $download_log_column_type ) {
2018-12-04 17:39:19 +00:00
$fk_result = $wpdb -> get_row (
2018-11-23 14:57:51 +00:00
" SELECT COUNT(*) AS fk_count
2018-06-18 14:47:47 +00:00
FROM information_schema . TABLE_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = '{$wpdb->dbname}'
2018-11-27 19:08:47 +00:00
AND CONSTRAINT_NAME = 'fk_{$wpdb->prefix}wc_download_log_permission_id'
2018-06-18 14:47:47 +00:00
AND CONSTRAINT_TYPE = 'FOREIGN KEY'
2018-11-23 14:57:51 +00:00
AND TABLE_NAME = '{$wpdb->prefix}wc_download_log' "
2020-04-29 15:35:56 +00:00
);
2018-06-18 14:47:47 +00:00
if ( 0 === ( int ) $fk_result -> fk_count ) {
2018-11-23 14:57:51 +00:00
$wpdb -> query (
" ALTER TABLE ` { $wpdb -> prefix } wc_download_log`
2018-11-27 19:08:47 +00:00
ADD CONSTRAINT `fk_{$wpdb->prefix}wc_download_log_permission_id`
2018-06-18 14:47:47 +00:00
FOREIGN KEY ( `permission_id` )
2018-11-23 14:57:51 +00:00
REFERENCES `{$wpdb->prefix}woocommerce_downloadable_product_permissions` ( `permission_id` ) ON DELETE CASCADE ; "
2020-04-29 15:35:56 +00:00
);
2018-06-18 14:47:47 +00:00
}
2018-06-04 11:10:05 +00:00
}
2019-03-05 16:49:45 +00:00
// Clear table caches.
delete_transient ( 'wc_attribute_taxonomies' );
2014-11-25 17:09:19 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Get Table schema .
2017-02-15 11:36:41 +00:00
*
2017-11-23 13:55:25 +00:00
* See https :// github . com / woocommerce / woocommerce / wiki / Database - Description /
2017-02-15 11:36:41 +00:00
*
* A note on indexes ; Indexes have a maximum size of 767 bytes . Historically , we haven ' t need to be concerned about that .
* As of WordPress 4.2 , however , we moved to utf8mb4 , which uses 4 bytes per character . This means that an index which
* used to have room for floor ( 767 / 3 ) = 255 characters , now only has room for floor ( 767 / 4 ) = 191 characters .
*
* Changing indexes may cause duplicate index notices in logs due to https :// core . trac . wordpress . org / ticket / 34870 but dropping
* indexes first causes too much load on some servers / larger DB .
*
2018-02-06 13:19:40 +00:00
* When adding or removing a table , make sure to update the list of tables in WC_Install :: get_tables () .
*
2014-11-25 17:09:19 +00:00
* @ return string
*/
2020-05-26 18:29:28 +00:00
private static function get_schema () {
2014-11-25 17:09:19 +00:00
global $wpdb ;
$collate = '' ;
if ( $wpdb -> has_cap ( 'collation' ) ) {
2016-01-27 10:10:56 +00:00
$collate = $wpdb -> get_charset_collate ();
2014-11-25 17:09:19 +00:00
}
2019-07-09 20:59:16 +00:00
/*
* Indexes have a maximum size of 767 bytes . Historically , we haven ' t need to be concerned about that .
* As of WP 4.2 , however , they moved to utf8mb4 , which uses 4 bytes per character . This means that an index which
* used to have room for floor ( 767 / 3 ) = 255 characters , now only has room for floor ( 767 / 4 ) = 191 characters .
*/
$max_index_length = 191 ;
2015-11-06 15:33:12 +00:00
$tables = "
2015-10-07 13:47:29 +00:00
CREATE TABLE { $wpdb -> prefix } woocommerce_sessions (
2017-02-13 11:49:30 +00:00
session_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
2015-10-07 13:47:29 +00:00
session_key char ( 32 ) NOT NULL ,
session_value longtext NOT NULL ,
2017-02-13 11:49:30 +00:00
session_expiry BIGINT UNSIGNED NOT NULL ,
2018-08-31 19:40:15 +00:00
PRIMARY KEY ( session_id ),
UNIQUE KEY session_key ( session_key )
2015-10-07 13:47:29 +00:00
) $collate ;
2015-05-15 21:20:49 +00:00
CREATE TABLE { $wpdb -> prefix } woocommerce_api_keys (
2017-02-13 11:49:30 +00:00
key_id BIGINT UNSIGNED NOT NULL auto_increment ,
user_id BIGINT UNSIGNED NOT NULL ,
2017-02-13 14:04:33 +00:00
description varchar ( 200 ) NULL ,
2015-05-16 01:52:00 +00:00
permissions varchar ( 10 ) NOT NULL ,
2015-06-08 23:04:29 +00:00
consumer_key char ( 64 ) NOT NULL ,
consumer_secret char ( 43 ) NOT NULL ,
2015-05-15 21:25:41 +00:00
nonces longtext NULL ,
2015-07-16 18:42:00 +00:00
truncated_key char ( 7 ) NOT NULL ,
last_access datetime NULL default null ,
2015-05-28 13:36:25 +00:00
PRIMARY KEY ( key_id ),
2015-05-15 20:57:18 +00:00
KEY consumer_key ( consumer_key ),
KEY consumer_secret ( consumer_secret )
) $collate ;
2014-11-25 17:09:19 +00:00
CREATE TABLE { $wpdb -> prefix } woocommerce_attribute_taxonomies (
2017-02-13 11:49:30 +00:00
attribute_id BIGINT UNSIGNED NOT NULL auto_increment ,
2014-11-25 17:09:19 +00:00
attribute_name varchar ( 200 ) NOT NULL ,
2017-02-13 14:04:33 +00:00
attribute_label varchar ( 200 ) NULL ,
attribute_type varchar ( 20 ) NOT NULL ,
attribute_orderby varchar ( 20 ) NOT NULL ,
2014-12-19 17:58:49 +00:00
attribute_public int ( 1 ) NOT NULL DEFAULT 1 ,
2014-11-25 17:09:19 +00:00
PRIMARY KEY ( attribute_id ),
2017-02-15 11:36:41 +00:00
KEY attribute_name ( attribute_name ( 20 ))
2014-11-25 17:09:19 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_downloadable_product_permissions (
2017-02-13 11:49:30 +00:00
permission_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-08-05 04:42:31 +00:00
download_id varchar ( 36 ) NOT NULL ,
2017-02-13 11:49:30 +00:00
product_id BIGINT UNSIGNED NOT NULL ,
order_id BIGINT UNSIGNED NOT NULL DEFAULT 0 ,
2014-11-25 17:09:19 +00:00
order_key varchar ( 200 ) NOT NULL ,
user_email varchar ( 200 ) NOT NULL ,
2017-02-13 11:49:30 +00:00
user_id BIGINT UNSIGNED NULL ,
2014-11-25 17:09:19 +00:00
downloads_remaining varchar ( 9 ) NULL ,
access_granted datetime NOT NULL default '0000-00-00 00:00:00' ,
access_expires datetime NULL default null ,
2017-02-13 11:49:30 +00:00
download_count BIGINT UNSIGNED NOT NULL DEFAULT 0 ,
2014-11-25 17:09:19 +00:00
PRIMARY KEY ( permission_id ),
2017-02-15 11:36:41 +00:00
KEY download_order_key_product ( product_id , order_id , order_key ( 16 ), download_id ),
2017-06-01 18:26:35 +00:00
KEY download_order_product ( download_id , order_id , product_id ),
2019-02-28 13:30:17 +00:00
KEY order_id ( order_id ),
KEY user_order_remaining_expires ( user_id , order_id , downloads_remaining , access_expires )
2014-11-25 17:09:19 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_order_items (
2017-02-13 11:49:30 +00:00
order_item_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-02-13 14:04:33 +00:00
order_item_name TEXT NOT NULL ,
2017-03-22 17:09:37 +00:00
order_item_type varchar ( 200 ) NOT NULL DEFAULT '' ,
2017-02-13 11:49:30 +00:00
order_id BIGINT UNSIGNED NOT NULL ,
2014-11-25 17:09:19 +00:00
PRIMARY KEY ( order_item_id ),
KEY order_id ( order_id )
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_order_itemmeta (
2017-02-13 11:49:30 +00:00
meta_id BIGINT UNSIGNED NOT NULL auto_increment ,
order_item_id BIGINT UNSIGNED NOT NULL ,
2016-03-02 01:28:04 +00:00
meta_key varchar ( 255 ) default NULL ,
2014-11-25 17:09:19 +00:00
meta_value longtext NULL ,
PRIMARY KEY ( meta_id ),
KEY order_item_id ( order_item_id ),
2017-02-15 11:36:41 +00:00
KEY meta_key ( meta_key ( 32 ))
2014-11-25 17:09:19 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_tax_rates (
2017-02-13 11:49:30 +00:00
tax_rate_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-02-13 14:04:33 +00:00
tax_rate_country varchar ( 2 ) NOT NULL DEFAULT '' ,
2014-11-25 17:09:19 +00:00
tax_rate_state varchar ( 200 ) NOT NULL DEFAULT '' ,
2017-02-13 14:04:33 +00:00
tax_rate varchar ( 8 ) NOT NULL DEFAULT '' ,
2014-11-25 17:09:19 +00:00
tax_rate_name varchar ( 200 ) NOT NULL DEFAULT '' ,
2017-02-13 11:49:30 +00:00
tax_rate_priority BIGINT UNSIGNED NOT NULL ,
2014-11-25 17:09:19 +00:00
tax_rate_compound int ( 1 ) NOT NULL DEFAULT 0 ,
tax_rate_shipping int ( 1 ) NOT NULL DEFAULT 1 ,
2017-02-13 11:49:30 +00:00
tax_rate_order BIGINT UNSIGNED NOT NULL ,
2014-11-25 17:09:19 +00:00
tax_rate_class varchar ( 200 ) NOT NULL DEFAULT '' ,
PRIMARY KEY ( tax_rate_id ),
2017-02-15 11:17:33 +00:00
KEY tax_rate_country ( tax_rate_country ),
2017-02-15 11:36:41 +00:00
KEY tax_rate_state ( tax_rate_state ( 2 )),
KEY tax_rate_class ( tax_rate_class ( 10 )),
2014-11-25 17:09:19 +00:00
KEY tax_rate_priority ( tax_rate_priority )
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_tax_rate_locations (
2017-02-13 11:49:30 +00:00
location_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-02-13 14:04:33 +00:00
location_code varchar ( 200 ) NOT NULL ,
2017-02-13 11:49:30 +00:00
tax_rate_id BIGINT UNSIGNED NOT NULL ,
2014-11-25 17:09:19 +00:00
location_type varchar ( 40 ) NOT NULL ,
PRIMARY KEY ( location_id ),
KEY tax_rate_id ( tax_rate_id ),
2017-02-15 11:36:41 +00:00
KEY location_type_code ( location_type ( 10 ), location_code ( 20 ))
2015-12-10 11:55:03 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_shipping_zones (
2017-02-13 11:49:30 +00:00
zone_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-02-13 14:04:33 +00:00
zone_name varchar ( 200 ) NOT NULL ,
2017-02-13 11:49:30 +00:00
zone_order BIGINT UNSIGNED NOT NULL ,
2015-12-10 11:55:03 +00:00
PRIMARY KEY ( zone_id )
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_shipping_zone_locations (
2017-02-13 11:49:30 +00:00
location_id BIGINT UNSIGNED NOT NULL auto_increment ,
zone_id BIGINT UNSIGNED NOT NULL ,
2017-02-13 14:04:33 +00:00
location_code varchar ( 200 ) NOT NULL ,
2015-12-10 11:55:03 +00:00
location_type varchar ( 40 ) NOT NULL ,
2016-01-08 13:17:13 +00:00
PRIMARY KEY ( location_id ),
2015-12-11 14:11:12 +00:00
KEY location_id ( location_id ),
2017-02-15 11:36:41 +00:00
KEY location_type_code ( location_type ( 10 ), location_code ( 20 ))
2015-12-11 14:11:12 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_shipping_zone_methods (
2017-02-13 11:49:30 +00:00
zone_id BIGINT UNSIGNED NOT NULL ,
instance_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-02-13 14:04:33 +00:00
method_id varchar ( 200 ) NOT NULL ,
2017-02-13 11:49:30 +00:00
method_order BIGINT UNSIGNED NOT NULL ,
2016-03-15 17:23:06 +00:00
is_enabled tinyint ( 1 ) NOT NULL DEFAULT '1' ,
2016-01-08 13:17:13 +00:00
PRIMARY KEY ( instance_id )
2016-02-02 17:08:32 +00:00
) $collate ;
2016-02-04 20:11:38 +00:00
CREATE TABLE { $wpdb -> prefix } woocommerce_payment_tokens (
2017-02-13 11:49:30 +00:00
token_id BIGINT UNSIGNED NOT NULL auto_increment ,
2017-02-13 14:04:33 +00:00
gateway_id varchar ( 200 ) NOT NULL ,
2016-02-04 20:11:38 +00:00
token text NOT NULL ,
2017-02-13 11:49:30 +00:00
user_id BIGINT UNSIGNED NOT NULL DEFAULT '0' ,
2017-02-13 14:04:33 +00:00
type varchar ( 200 ) NOT NULL ,
2016-02-04 20:11:38 +00:00
is_default tinyint ( 1 ) NOT NULL DEFAULT '0' ,
PRIMARY KEY ( token_id ),
2016-02-04 20:56:29 +00:00
KEY user_id ( user_id )
2016-02-02 17:08:32 +00:00
) $collate ;
2016-02-04 20:11:38 +00:00
CREATE TABLE { $wpdb -> prefix } woocommerce_payment_tokenmeta (
2017-02-13 11:49:30 +00:00
meta_id BIGINT UNSIGNED NOT NULL auto_increment ,
payment_token_id BIGINT UNSIGNED NOT NULL ,
2016-02-04 20:11:38 +00:00
meta_key varchar ( 255 ) NULL ,
meta_value longtext NULL ,
PRIMARY KEY ( meta_id ),
KEY payment_token_id ( payment_token_id ),
2017-02-15 11:36:41 +00:00
KEY meta_key ( meta_key ( 32 ))
2016-11-20 13:32:46 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } woocommerce_log (
2017-02-13 11:49:30 +00:00
log_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
2016-11-20 13:32:46 +00:00
timestamp datetime NOT NULL ,
2016-12-11 17:59:12 +00:00
level smallint ( 4 ) NOT NULL ,
2017-02-13 14:04:33 +00:00
source varchar ( 200 ) NOT NULL ,
2016-11-20 13:32:46 +00:00
message longtext NOT NULL ,
context longtext NULL ,
PRIMARY KEY ( log_id ),
KEY level ( level )
2017-07-30 22:38:17 +00:00
) $collate ;
2017-08-18 16:41:02 +00:00
CREATE TABLE { $wpdb -> prefix } wc_webhooks (
2017-08-16 18:37:22 +00:00
webhook_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
status varchar ( 200 ) NOT NULL ,
name text NOT NULL ,
user_id BIGINT UNSIGNED NOT NULL ,
delivery_url text NOT NULL ,
secret text NOT NULL ,
topic varchar ( 200 ) NOT NULL ,
2017-08-17 00:48:09 +00:00
date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ,
date_created_gmt datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ,
date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ,
date_modified_gmt datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ,
2017-08-16 18:37:22 +00:00
api_version smallint ( 4 ) NOT NULL ,
2017-08-17 00:48:09 +00:00
failure_count smallint ( 10 ) NOT NULL DEFAULT '0' ,
2017-08-16 18:37:22 +00:00
pending_delivery tinyint ( 1 ) NOT NULL DEFAULT '0' ,
PRIMARY KEY ( webhook_id ),
KEY user_id ( user_id )
2017-11-15 12:28:14 +00:00
) $collate ;
2017-11-13 19:03:08 +00:00
CREATE TABLE { $wpdb -> prefix } wc_download_log (
2017-07-30 22:38:17 +00:00
download_log_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
timestamp datetime NOT NULL ,
permission_id BIGINT UNSIGNED NOT NULL ,
user_id BIGINT UNSIGNED NULL ,
user_ip_address VARCHAR ( 100 ) NULL DEFAULT '' ,
2019-02-11 15:05:12 +00:00
PRIMARY KEY ( download_log_id ),
2017-07-30 22:38:17 +00:00
KEY permission_id ( permission_id ),
KEY timestamp ( timestamp )
2014-11-25 17:09:19 +00:00
) $collate ;
2019-02-15 12:37:45 +00:00
CREATE TABLE { $wpdb -> prefix } wc_product_meta_lookup (
2019-02-11 14:41:24 +00:00
`product_id` bigint ( 20 ) NOT NULL ,
2019-03-07 13:34:28 +00:00
`sku` varchar ( 100 ) NULL default '' ,
2019-03-07 14:32:20 +00:00
`virtual` tinyint ( 1 ) NULL default 0 ,
`downloadable` tinyint ( 1 ) NULL default 0 ,
2019-12-18 07:19:32 +00:00
`min_price` decimal ( 19 , 4 ) NULL default NULL ,
`max_price` decimal ( 19 , 4 ) NULL default NULL ,
2019-03-13 17:14:20 +00:00
`onsale` tinyint ( 1 ) NULL default 0 ,
2019-03-07 14:32:20 +00:00
`stock_quantity` double NULL default NULL ,
`stock_status` varchar ( 100 ) NULL default 'instock' ,
2019-03-06 14:03:44 +00:00
`rating_count` bigint ( 20 ) NULL default 0 ,
2019-02-28 14:01:13 +00:00
`average_rating` decimal ( 3 , 2 ) NULL default 0.00 ,
2019-02-12 14:04:22 +00:00
`total_sales` bigint ( 20 ) NULL default 0 ,
2020-01-20 14:21:42 +00:00
`tax_status` varchar ( 100 ) NULL default 'taxable' ,
`tax_class` varchar ( 100 ) NULL default '' ,
2019-02-11 15:05:12 +00:00
PRIMARY KEY ( `product_id` ),
2019-03-07 14:47:46 +00:00
KEY `virtual` ( `virtual` ),
KEY `downloadable` ( `downloadable` ),
KEY `stock_status` ( `stock_status` ),
2019-03-07 15:08:22 +00:00
KEY `stock_quantity` ( `stock_quantity` ),
2019-03-13 17:14:20 +00:00
KEY `onsale` ( `onsale` ),
2019-02-28 13:12:12 +00:00
KEY min_max_price ( `min_price` , `max_price` )
2019-03-20 14:19:11 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } wc_tax_rate_classes (
tax_rate_class_id BIGINT UNSIGNED NOT NULL auto_increment ,
name varchar ( 200 ) NOT NULL DEFAULT '' ,
slug varchar ( 200 ) NOT NULL DEFAULT '' ,
PRIMARY KEY ( tax_rate_class_id ),
2019-07-09 20:59:16 +00:00
UNIQUE KEY slug ( slug ( $max_index_length ))
2020-05-06 16:14:53 +00:00
) $collate ;
CREATE TABLE { $wpdb -> prefix } wc_reserved_stock (
`order_id` bigint ( 20 ) NOT NULL ,
`product_id` bigint ( 20 ) NOT NULL ,
`stock_quantity` double NOT NULL DEFAULT 0 ,
2020-06-05 13:50:06 +00:00
`timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ,
`expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ,
2020-05-06 16:14:53 +00:00
PRIMARY KEY ( `order_id` , `product_id` )
2019-03-20 14:19:11 +00:00
) $collate ;
2014-11-25 17:09:19 +00:00
" ;
2015-11-06 15:33:12 +00:00
return $tables ;
2013-07-25 15:29:25 +00:00
}
2018-02-06 13:19:40 +00:00
/**
* Return a list of WooCommerce tables . Used to make sure all WC tables are dropped when uninstalling the plugin
* in a single site or multi site environment .
*
* @ return array WC tables .
*/
public static function get_tables () {
global $wpdb ;
$tables = array (
" { $wpdb -> prefix } wc_download_log " ,
2019-02-15 12:37:45 +00:00
" { $wpdb -> prefix } wc_product_meta_lookup " ,
2019-07-09 18:02:07 +00:00
" { $wpdb -> prefix } wc_tax_rate_classes " ,
2018-02-06 13:19:40 +00:00
" { $wpdb -> prefix } wc_webhooks " ,
" { $wpdb -> prefix } woocommerce_api_keys " ,
" { $wpdb -> prefix } woocommerce_attribute_taxonomies " ,
" { $wpdb -> prefix } woocommerce_downloadable_product_permissions " ,
" { $wpdb -> prefix } woocommerce_log " ,
" { $wpdb -> prefix } woocommerce_order_itemmeta " ,
" { $wpdb -> prefix } woocommerce_order_items " ,
" { $wpdb -> prefix } woocommerce_payment_tokenmeta " ,
" { $wpdb -> prefix } woocommerce_payment_tokens " ,
" { $wpdb -> prefix } woocommerce_sessions " ,
" { $wpdb -> prefix } woocommerce_shipping_zone_locations " ,
" { $wpdb -> prefix } woocommerce_shipping_zone_methods " ,
" { $wpdb -> prefix } woocommerce_shipping_zones " ,
" { $wpdb -> prefix } woocommerce_tax_rate_locations " ,
" { $wpdb -> prefix } woocommerce_tax_rates " ,
2020-05-06 16:14:53 +00:00
" { $wpdb -> prefix } wc_reserved_stock " ,
2018-02-06 13:19:40 +00:00
);
2018-03-16 18:54:17 +00:00
/**
* Filter the list of known WooCommerce tables .
*
* If WooCommerce plugins need to add new tables , they can inject them here .
*
* @ param array $tables An array of WooCommerce - specific database table names .
*/
$tables = apply_filters ( 'woocommerce_install_get_tables' , $tables );
2018-02-06 13:19:40 +00:00
return $tables ;
}
/**
* Drop WooCommerce tables .
*
* @ return void
*/
public static function drop_tables () {
global $wpdb ;
$tables = self :: get_tables ();
foreach ( $tables as $table ) {
2020-01-13 19:18:14 +00:00
$wpdb -> query ( " DROP TABLE IF EXISTS { $table } " ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
2018-02-06 13:19:40 +00:00
}
}
/**
* Uninstall tables when MU blog is deleted .
*
2018-11-16 06:29:13 +00:00
* @ param array $tables List of tables that will be deleted by WP .
*
2018-02-06 13:19:40 +00:00
* @ return string []
*/
public static function wpmu_drop_tables ( $tables ) {
return array_merge ( $tables , self :: get_tables () );
}
2013-07-25 15:29:25 +00:00
/**
2015-11-03 13:31:20 +00:00
* Create roles and capabilities .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function create_roles () {
2013-07-25 15:29:25 +00:00
global $wp_roles ;
2014-11-25 17:09:19 +00:00
if ( ! class_exists ( 'WP_Roles' ) ) {
return ;
2014-01-12 00:05:14 +00:00
}
2013-07-25 15:29:25 +00:00
2014-11-25 17:09:19 +00:00
if ( ! isset ( $wp_roles ) ) {
2017-11-23 13:55:25 +00:00
$wp_roles = new WP_Roles (); // @codingStandardsIgnoreLine
2014-11-25 17:09:19 +00:00
}
2018-04-30 14:38:45 +00:00
// Dummy gettext calls to get strings in the catalog.
/* translators: user role */
_x ( 'Customer' , 'User role' , 'woocommerce' );
/* translators: user role */
_x ( 'Shop manager' , 'User role' , 'woocommerce' );
2017-11-23 13:55:25 +00:00
// Customer role.
2017-11-23 12:41:31 +00:00
add_role (
'customer' ,
2018-04-30 14:38:45 +00:00
'Customer' ,
2017-11-23 12:41:31 +00:00
array (
'read' => true ,
)
);
2014-11-25 17:09:19 +00:00
2017-11-23 13:55:25 +00:00
// Shop manager role.
2017-11-23 12:41:31 +00:00
add_role (
'shop_manager' ,
2018-04-30 14:38:45 +00:00
'Shop manager' ,
2017-11-23 12:41:31 +00:00
array (
'level_9' => true ,
'level_8' => true ,
'level_7' => true ,
'level_6' => true ,
'level_5' => true ,
'level_4' => true ,
'level_3' => true ,
'level_2' => true ,
'level_1' => true ,
'level_0' => true ,
'read' => true ,
'read_private_pages' => true ,
'read_private_posts' => true ,
'edit_posts' => true ,
'edit_pages' => true ,
'edit_published_posts' => true ,
'edit_published_pages' => true ,
'edit_private_pages' => true ,
'edit_private_posts' => true ,
'edit_others_posts' => true ,
'edit_others_pages' => true ,
'publish_posts' => true ,
'publish_pages' => true ,
'delete_posts' => true ,
'delete_pages' => true ,
'delete_private_pages' => true ,
'delete_private_posts' => true ,
'delete_published_pages' => true ,
'delete_published_posts' => true ,
'delete_others_posts' => true ,
'delete_others_pages' => true ,
'manage_categories' => true ,
'manage_links' => true ,
'moderate_comments' => true ,
'upload_files' => true ,
'export' => true ,
'import' => true ,
'list_users' => true ,
2018-07-09 08:45:48 +00:00
'edit_theme_options' => true ,
2017-11-23 12:41:31 +00:00
)
);
2014-11-25 17:09:19 +00:00
$capabilities = self :: get_core_capabilities ();
foreach ( $capabilities as $cap_group ) {
foreach ( $cap_group as $cap ) {
$wp_roles -> add_cap ( 'shop_manager' , $cap );
$wp_roles -> add_cap ( 'administrator' , $cap );
2013-07-25 15:29:25 +00:00
}
}
}
2013-08-09 16:11:15 +00:00
/**
2015-11-03 13:31:20 +00:00
* Get capabilities for WooCommerce - these are assigned to admin / shop manager during installation or reset .
2013-08-09 16:11:15 +00:00
*
2013-11-27 09:03:47 +00:00
* @ return array
2013-08-09 16:11:15 +00:00
*/
2017-11-23 12:41:31 +00:00
private static function get_core_capabilities () {
2013-08-09 16:11:15 +00:00
$capabilities = array ();
$capabilities [ 'core' ] = array (
2014-01-12 00:05:14 +00:00
'manage_woocommerce' ,
2016-08-27 02:08:49 +00:00
'view_woocommerce_reports' ,
2013-08-09 16:11:15 +00:00
);
2017-08-17 14:37:57 +00:00
$capability_types = array ( 'product' , 'shop_order' , 'shop_coupon' );
2013-08-09 16:11:15 +00:00
2014-01-12 00:05:14 +00:00
foreach ( $capability_types as $capability_type ) {
2013-08-09 16:11:15 +00:00
$capabilities [ $capability_type ] = array (
2017-11-23 13:55:25 +00:00
// Post type.
2013-08-09 16:11:15 +00:00
" edit_ { $capability_type } " ,
" read_ { $capability_type } " ,
" delete_ { $capability_type } " ,
" edit_ { $capability_type } s " ,
" edit_others_ { $capability_type } s " ,
" publish_ { $capability_type } s " ,
" read_private_ { $capability_type } s " ,
" delete_ { $capability_type } s " ,
" delete_private_ { $capability_type } s " ,
" delete_published_ { $capability_type } s " ,
" delete_others_ { $capability_type } s " ,
" edit_private_ { $capability_type } s " ,
" edit_published_ { $capability_type } s " ,
2017-11-23 13:55:25 +00:00
// Terms.
2013-08-09 16:11:15 +00:00
" manage_ { $capability_type } _terms " ,
" edit_ { $capability_type } _terms " ,
" delete_ { $capability_type } _terms " ,
2016-08-27 02:08:49 +00:00
" assign_ { $capability_type } _terms " ,
2013-08-09 16:11:15 +00:00
);
}
return $capabilities ;
}
/**
2017-11-23 13:55:25 +00:00
* Remove WooCommerce roles .
2013-08-09 16:11:15 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function remove_roles () {
2013-08-09 16:11:15 +00:00
global $wp_roles ;
2014-11-25 17:09:19 +00:00
if ( ! class_exists ( 'WP_Roles' ) ) {
return ;
2014-01-12 00:05:14 +00:00
}
2013-08-09 16:11:15 +00:00
2014-11-25 17:09:19 +00:00
if ( ! isset ( $wp_roles ) ) {
2017-11-23 13:55:25 +00:00
$wp_roles = new WP_Roles (); // @codingStandardsIgnoreLine
2014-11-25 17:09:19 +00:00
}
2013-08-09 16:11:15 +00:00
2014-11-25 17:09:19 +00:00
$capabilities = self :: get_core_capabilities ();
2013-08-09 16:11:15 +00:00
2014-11-25 17:09:19 +00:00
foreach ( $capabilities as $cap_group ) {
foreach ( $cap_group as $cap ) {
$wp_roles -> remove_cap ( 'shop_manager' , $cap );
$wp_roles -> remove_cap ( 'administrator' , $cap );
2013-08-09 16:11:15 +00:00
}
}
2014-11-25 17:09:19 +00:00
remove_role ( 'customer' );
remove_role ( 'shop_manager' );
2013-08-09 16:11:15 +00:00
}
2013-07-25 15:29:25 +00:00
/**
2015-11-03 13:31:20 +00:00
* Create files / directories .
2013-07-25 15:29:25 +00:00
*/
2014-11-25 17:09:19 +00:00
private static function create_files () {
2017-11-23 13:55:25 +00:00
// Bypass if filesystem is read-only and/or non-standard upload system is used.
2017-08-25 04:16:32 +00:00
if ( apply_filters ( 'woocommerce_install_skip_create_files' , false ) ) {
return ;
}
2017-11-23 13:55:25 +00:00
// Install files and folders for uploading files and prevent hotlinking.
2020-05-07 02:21:31 +00:00
$upload_dir = wp_get_upload_dir ();
2015-08-24 12:50:14 +00:00
$download_method = get_option ( 'woocommerce_file_download_method' , 'force' );
2013-07-25 15:29:25 +00:00
$files = array (
array (
2017-11-23 12:41:31 +00:00
'base' => $upload_dir [ 'basedir' ] . '/woocommerce_uploads' ,
'file' => 'index.html' ,
'content' => '' ,
2013-07-25 15:29:25 +00:00
),
array (
2017-11-23 12:41:31 +00:00
'base' => WC_LOG_DIR ,
'file' => '.htaccess' ,
'content' => 'deny from all' ,
2013-07-25 15:29:25 +00:00
),
array (
2017-11-23 12:41:31 +00:00
'base' => WC_LOG_DIR ,
'file' => 'index.html' ,
'content' => '' ,
2016-08-27 02:08:49 +00:00
),
2020-05-07 02:20:56 +00:00
array (
2017-11-23 12:41:31 +00:00
'base' => $upload_dir [ 'basedir' ] . '/woocommerce_uploads' ,
'file' => '.htaccess' ,
2020-05-07 02:20:56 +00:00
'content' => 'redirect' === $download_method ? 'Options -Indexes' : 'deny from all' ,
),
);
2015-08-24 12:50:14 +00:00
2013-07-25 15:29:25 +00:00
foreach ( $files as $file ) {
if ( wp_mkdir_p ( $file [ 'base' ] ) && ! file_exists ( trailingslashit ( $file [ 'base' ] ) . $file [ 'file' ] ) ) {
2020-05-07 02:25:33 +00:00
$file_handle = @ fopen ( trailingslashit ( $file [ 'base' ] ) . $file [ 'file' ], 'wb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
2017-11-23 13:55:25 +00:00
if ( $file_handle ) {
2018-03-21 03:06:47 +00:00
fwrite ( $file_handle , $file [ 'content' ] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite
fclose ( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
2013-07-25 15:29:25 +00:00
}
}
}
2018-06-27 16:47:30 +00:00
// Create attachment for placeholders.
self :: create_placeholder_image ();
}
/**
* Create a placeholder image in the media library .
*
* @ since 3.5 . 0
*/
private static function create_placeholder_image () {
2018-06-27 17:38:36 +00:00
$placeholder_image = get_option ( 'woocommerce_placeholder_image' , 0 );
2018-06-27 16:47:30 +00:00
2019-01-14 11:32:57 +00:00
// Validate current setting if set. If set, return.
if ( ! empty ( $placeholder_image ) ) {
if ( ! is_numeric ( $placeholder_image ) ) {
return ;
} elseif ( $placeholder_image && wp_attachment_is_image ( $placeholder_image ) ) {
return ;
}
2018-06-27 16:47:30 +00:00
}
$upload_dir = wp_upload_dir ();
2019-01-14 13:54:01 +00:00
$source = WC () -> plugin_path () . '/assets/images/placeholder-attachment.png' ;
2018-06-27 16:47:30 +00:00
$filename = $upload_dir [ 'basedir' ] . '/woocommerce-placeholder.png' ;
if ( ! file_exists ( $filename ) ) {
copy ( $source , $filename ); // @codingStandardsIgnoreLine.
}
if ( ! file_exists ( $filename ) ) {
2018-06-27 17:38:36 +00:00
update_option ( 'woocommerce_placeholder_image' , 0 );
2018-06-27 16:47:30 +00:00
return ;
}
$filetype = wp_check_filetype ( basename ( $filename ), null );
$attachment = array (
'guid' => $upload_dir [ 'url' ] . '/' . basename ( $filename ),
'post_mime_type' => $filetype [ 'type' ],
'post_title' => preg_replace ( '/\.[^.]+$/' , '' , basename ( $filename ) ),
'post_content' => '' ,
'post_status' => 'inherit' ,
);
$attach_id = wp_insert_attachment ( $attachment , $filename );
2018-06-27 17:38:36 +00:00
update_option ( 'woocommerce_placeholder_image' , $attach_id );
2018-06-27 16:47:30 +00:00
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once ABSPATH . 'wp-admin/includes/image.php' ;
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata ( $attach_id , $filename );
wp_update_attachment_metadata ( $attach_id , $attach_data );
2013-07-25 15:29:25 +00:00
}
2014-08-29 17:34:01 +00:00
/**
2014-08-29 17:43:06 +00:00
* Show action links on the plugin screen .
2014-08-29 17:34:01 +00:00
*
2018-11-16 06:29:13 +00:00
* @ param mixed $links Plugin Action links .
*
* @ return array
2014-08-29 17:34:01 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function plugin_action_links ( $links ) {
2014-08-29 19:05:09 +00:00
$action_links = array (
2017-03-13 05:39:46 +00:00
'settings' => '<a href="' . admin_url ( 'admin.php?page=wc-settings' ) . '" aria-label="' . esc_attr__ ( 'View WooCommerce settings' , 'woocommerce' ) . '">' . esc_html__ ( 'Settings' , 'woocommerce' ) . '</a>' ,
2014-08-29 19:05:09 +00:00
);
2014-08-29 17:43:06 +00:00
return array_merge ( $action_links , $links );
2014-08-29 17:34:01 +00:00
}
2014-08-29 17:54:17 +00:00
/**
* Show row meta on the plugin screen .
*
2018-11-16 06:29:13 +00:00
* @ param mixed $links Plugin Row Meta .
* @ param mixed $file Plugin Base file .
*
* @ return array
2014-08-29 17:54:17 +00:00
*/
2014-11-25 17:09:19 +00:00
public static function plugin_row_meta ( $links , $file ) {
2020-07-01 19:50:19 +00:00
if ( WC_PLUGIN_BASENAME !== $file ) {
return $links ;
}
$row_meta = array (
'docs' => '<a href="' . esc_url ( apply_filters ( 'woocommerce_docs_url' , 'https://docs.woocommerce.com/documentation/plugins/woocommerce/' ) ) . '" aria-label="' . esc_attr__ ( 'View WooCommerce documentation' , 'woocommerce' ) . '">' . esc_html__ ( 'Docs' , 'woocommerce' ) . '</a>' ,
'apidocs' => '<a href="' . esc_url ( apply_filters ( 'woocommerce_apidocs_url' , 'https://docs.woocommerce.com/wc-apidocs/' ) ) . '" aria-label="' . esc_attr__ ( 'View WooCommerce API docs' , 'woocommerce' ) . '">' . esc_html__ ( 'API docs' , 'woocommerce' ) . '</a>' ,
'support' => '<a href="' . esc_url ( apply_filters ( 'woocommerce_community_support_url' , 'https://wordpress.org/support/plugin/woocommerce/' ) ) . '" aria-label="' . esc_attr__ ( 'Visit community forums' , 'woocommerce' ) . '">' . esc_html__ ( 'Community support' , 'woocommerce' ) . '</a>' ,
);
2014-08-29 17:54:17 +00:00
2020-07-15 09:50:18 +00:00
if ( WCConnectionHelper :: is_connected () ) {
2020-07-01 19:50:19 +00:00
$row_meta [ 'premium_support' ] = '<a href="' . esc_url ( apply_filters ( 'woocommerce_support_url' , 'https://woocommerce.com/my-account/tickets/' ) ) . '" aria-label="' . esc_attr__ ( 'Visit premium customer support' , 'woocommerce' ) . '">' . esc_html__ ( 'Premium support' , 'woocommerce' ) . '</a>' ;
2014-08-29 17:54:17 +00:00
}
2020-07-01 19:50:19 +00:00
return array_merge ( $links , $row_meta );
2014-08-29 17:54:17 +00:00
}
2014-10-10 13:48:08 +00:00
/**
2018-02-16 20:01:05 +00:00
* Get slug from path and associate it with the path .
2017-11-23 12:41:31 +00:00
*
2018-04-16 11:16:59 +00:00
* @ param array $plugins Associative array of plugin files to paths .
2018-02-16 20:01:05 +00:00
* @ param string $key Plugin relative path . Example : woocommerce / woocommerce . php .
2016-04-18 16:05:19 +00:00
*/
2018-04-16 11:16:59 +00:00
private static function associate_plugin_file ( $plugins , $key ) {
2018-05-07 12:27:22 +00:00
$path = explode ( '/' , $key );
2018-05-07 18:48:18 +00:00
$filename = end ( $path );
2018-05-07 12:27:22 +00:00
$plugins [ $filename ] = $key ;
2018-02-16 20:01:05 +00:00
return $plugins ;
2016-04-18 16:05:19 +00:00
}
/**
* Install a plugin from . org in the background via a cron job ( used by
* installer - opt in ) .
2017-11-23 12:41:31 +00:00
*
2017-11-23 13:55:25 +00:00
* @ param string $plugin_to_install_id Plugin ID .
* @ param array $plugin_to_install Plugin information .
2018-11-16 06:29:13 +00:00
*
2017-11-23 13:55:25 +00:00
* @ throws Exception If unable to proceed with plugin installation .
2018-11-16 06:29:13 +00:00
* @ since 2.6 . 0
2016-04-18 16:05:19 +00:00
*/
public static function background_installer ( $plugin_to_install_id , $plugin_to_install ) {
2016-12-12 12:02:03 +00:00
// Explicitly clear the event.
2018-11-23 18:49:08 +00:00
$args = func_get_args ();
2016-12-12 12:02:03 +00:00
2016-04-18 16:05:19 +00:00
if ( ! empty ( $plugin_to_install [ 'repo-slug' ] ) ) {
2017-11-23 12:41:31 +00:00
require_once ABSPATH . 'wp-admin/includes/file.php' ;
require_once ABSPATH . 'wp-admin/includes/plugin-install.php' ;
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ;
require_once ABSPATH . 'wp-admin/includes/plugin.php' ;
2016-04-18 16:05:19 +00:00
WP_Filesystem ();
2017-11-23 12:41:31 +00:00
$skin = new Automatic_Upgrader_Skin ();
2016-04-18 16:05:19 +00:00
$upgrader = new WP_Upgrader ( $skin );
2018-11-23 18:49:08 +00:00
$installed_plugins = array_reduce ( array_keys ( get_plugins () ), array ( __CLASS__ , 'associate_plugin_file' ) );
if ( empty ( $installed_plugins ) ) {
$installed_plugins = array ();
}
2019-07-08 21:12:23 +00:00
$plugin_slug = $plugin_to_install [ 'repo-slug' ];
$plugin_file = isset ( $plugin_to_install [ 'file' ] ) ? $plugin_to_install [ 'file' ] : $plugin_slug . '.php' ;
$installed = false ;
$activate = false ;
2016-04-18 16:05:19 +00:00
2017-11-23 13:55:25 +00:00
// See if the plugin is installed already.
2018-04-16 11:16:59 +00:00
if ( isset ( $installed_plugins [ $plugin_file ] ) ) {
2016-04-18 16:05:19 +00:00
$installed = true ;
2018-04-16 11:16:59 +00:00
$activate = ! is_plugin_active ( $installed_plugins [ $plugin_file ] );
2016-04-18 16:05:19 +00:00
}
// Install this thing!
if ( ! $installed ) {
2017-11-23 13:55:25 +00:00
// Suppress feedback.
2016-04-18 16:05:19 +00:00
ob_start ();
try {
2017-11-23 12:41:31 +00:00
$plugin_information = plugins_api (
'plugin_information' ,
array (
2018-04-16 11:16:59 +00:00
'slug' => $plugin_slug ,
2017-11-23 12:41:31 +00:00
'fields' => array (
'short_description' => false ,
'sections' => false ,
'requires' => false ,
'rating' => false ,
'ratings' => false ,
'downloaded' => false ,
'last_updated' => false ,
'added' => false ,
'tags' => false ,
'homepage' => false ,
'donate_link' => false ,
'author_profile' => false ,
'author' => false ,
),
)
);
2016-04-18 16:05:19 +00:00
if ( is_wp_error ( $plugin_information ) ) {
throw new Exception ( $plugin_information -> get_error_message () );
}
$package = $plugin_information -> download_link ;
$download = $upgrader -> download_package ( $package );
if ( is_wp_error ( $download ) ) {
throw new Exception ( $download -> get_error_message () );
}
$working_dir = $upgrader -> unpack_package ( $download , true );
if ( is_wp_error ( $working_dir ) ) {
throw new Exception ( $working_dir -> get_error_message () );
}
2017-11-23 12:41:31 +00:00
$result = $upgrader -> install_package (
array (
'source' => $working_dir ,
'destination' => WP_PLUGIN_DIR ,
'clear_destination' => false ,
'abort_if_destination_exists' => false ,
'clear_working' => true ,
'hook_extra' => array (
'type' => 'plugin' ,
'action' => 'install' ,
),
)
);
2016-04-18 16:05:19 +00:00
if ( is_wp_error ( $result ) ) {
throw new Exception ( $result -> get_error_message () );
}
$activate = true ;
} catch ( Exception $e ) {
WC_Admin_Notices :: add_custom_notice (
$plugin_to_install_id . '_install_error' ,
sprintf (
2017-11-23 13:55:25 +00:00
// translators: 1: plugin name, 2: error message, 3: URL to install plugin manually.
2016-10-27 17:36:24 +00:00
__ ( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>' , 'woocommerce' ),
2016-04-18 16:05:19 +00:00
$plugin_to_install [ 'name' ],
$e -> getMessage (),
2018-04-16 11:16:59 +00:00
esc_url ( admin_url ( 'index.php?wc-install-plugin-redirect=' . $plugin_slug ) )
2016-04-18 16:05:19 +00:00
)
);
}
2017-11-23 13:55:25 +00:00
// Discard feedback.
2016-04-18 16:05:19 +00:00
ob_end_clean ();
}
wp_clean_plugins_cache ();
2017-11-23 13:55:25 +00:00
// Activate this thing.
2016-04-18 16:05:19 +00:00
if ( $activate ) {
try {
2018-07-24 10:29:10 +00:00
add_action ( 'add_option_mailchimp_woocommerce_plugin_do_activation_redirect' , array ( __CLASS__ , 'remove_mailchimps_redirect' ), 10 , 2 );
2018-04-16 11:22:15 +00:00
$result = activate_plugin ( $installed ? $installed_plugins [ $plugin_file ] : $plugin_slug . '/' . $plugin_file );
2016-04-18 16:05:19 +00:00
if ( is_wp_error ( $result ) ) {
throw new Exception ( $result -> get_error_message () );
}
} catch ( Exception $e ) {
WC_Admin_Notices :: add_custom_notice (
$plugin_to_install_id . '_install_error' ,
sprintf (
2017-11-23 13:55:25 +00:00
// translators: 1: plugin name, 2: URL to WP plugin page.
2016-10-27 17:36:24 +00:00
__ ( '%1$s was installed but could not be activated. <a href="%2$s">Please activate it manually by clicking here.</a>' , 'woocommerce' ),
2016-04-18 16:05:19 +00:00
$plugin_to_install [ 'name' ],
2016-10-27 17:36:24 +00:00
admin_url ( 'plugins.php' )
2016-04-18 16:05:19 +00:00
)
);
}
}
}
}
2017-05-17 16:42:18 +00:00
2018-07-24 10:29:10 +00:00
/**
* Removes redirect added during MailChimp plugin ' s activation .
*
* @ param string $option Option name .
* @ param string $value Option value .
*/
public static function remove_mailchimps_redirect ( $option , $value ) {
// Remove this action to prevent infinite looping.
remove_action ( 'add_option_mailchimp_woocommerce_plugin_do_activation_redirect' , array ( __CLASS__ , 'remove_mailchimps_redirect' ) );
// Update redirect back to false.
update_option ( 'mailchimp_woocommerce_plugin_do_activation_redirect' , false );
}
2017-05-17 16:42:18 +00:00
/**
* Install a theme from . org in the background via a cron job ( used by installer - opt in ) .
*
2017-11-23 13:55:25 +00:00
* @ param string $theme_slug Theme slug .
2018-11-16 06:29:13 +00:00
*
2017-11-23 13:55:25 +00:00
* @ throws Exception If unable to proceed with theme installation .
2018-11-16 06:29:13 +00:00
* @ since 3.1 . 0
2017-05-17 16:42:18 +00:00
*/
public static function theme_background_installer ( $theme_slug ) {
// Explicitly clear the event.
2018-11-23 18:49:08 +00:00
$args = func_get_args ();
2017-05-17 16:42:18 +00:00
if ( ! empty ( $theme_slug ) ) {
2017-11-23 13:55:25 +00:00
// Suppress feedback.
2017-05-17 16:42:18 +00:00
ob_start ();
try {
$theme = wp_get_theme ( $theme_slug );
if ( ! $theme -> exists () ) {
2017-11-23 12:41:31 +00:00
require_once ABSPATH . 'wp-admin/includes/file.php' ;
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ;
include_once ABSPATH . 'wp-admin/includes/theme.php' ;
2017-05-17 16:42:18 +00:00
WP_Filesystem ();
2017-11-23 12:41:31 +00:00
$skin = new Automatic_Upgrader_Skin ();
2017-05-17 16:42:18 +00:00
$upgrader = new Theme_Upgrader ( $skin );
2017-11-23 12:41:31 +00:00
$api = themes_api (
2018-11-23 14:57:51 +00:00
'theme_information' ,
array (
2017-11-23 12:41:31 +00:00
'slug' => $theme_slug ,
'fields' => array ( 'sections' => false ),
)
);
2017-05-17 16:42:18 +00:00
$result = $upgrader -> install ( $api -> download_link );
if ( is_wp_error ( $result ) ) {
throw new Exception ( $result -> get_error_message () );
} elseif ( is_wp_error ( $skin -> result ) ) {
throw new Exception ( $skin -> result -> get_error_message () );
} elseif ( is_null ( $result ) ) {
throw new Exception ( 'Unable to connect to the filesystem. Please confirm your credentials.' );
}
}
switch_theme ( $theme_slug );
} catch ( Exception $e ) {
WC_Admin_Notices :: add_custom_notice (
$theme_slug . '_install_error' ,
sprintf (
2017-11-23 13:55:25 +00:00
// translators: 1: theme slug, 2: error message, 3: URL to install theme manually.
2017-05-17 16:42:18 +00:00
__ ( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>' , 'woocommerce' ),
$theme_slug ,
$e -> getMessage (),
2017-05-23 15:35:17 +00:00
esc_url ( admin_url ( 'update.php?action=install-theme&theme=' . $theme_slug . '&_wpnonce=' . wp_create_nonce ( 'install-theme_' . $theme_slug ) ) )
2017-05-17 16:42:18 +00:00
)
);
}
2017-11-23 13:55:25 +00:00
// Discard feedback.
2017-05-17 16:42:18 +00:00
ob_end_clean ();
}
}
2013-07-25 15:29:25 +00:00
}
2014-11-25 17:09:19 +00:00
WC_Install :: init ();