laipower/wp-content/plugins/easy-digital-downloads/includes/install.php

556 lines
14 KiB
PHP
Raw Normal View History

<?php
/**
* Install Function
*
* @package EDD
* @subpackage Functions/Install
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Get the current database version
*
* @since 3.0
*
* @return string
*/
function edd_get_db_version() {
$db_version = get_option( 'edd_version' );
$retval = ! empty( $db_version )
? edd_format_db_version( $db_version )
: false;
return $retval;
}
/**
* Update the EDD version in the options table
*
* @since 3.0
*/
function edd_update_db_version() {
if ( defined( 'EDD_VERSION' ) ) {
update_option( 'edd_version', edd_format_db_version( EDD_VERSION ) );
}
}
/**
* Format the EDD version (going into or coming from the database.)
*
* @since 3.0
*
* @param string $version
* @return string
*/
function edd_format_db_version( $version = '' ) {
return preg_replace( '/[^0-9.].*/', '', $version );
}
/**
* Check if the upgrade routine has been run for a specific action
*
* @since 2.3
* @param string $upgrade_action The upgrade action to check completion for
* @return bool If the action has been added to the copmleted actions array
*/
function edd_has_upgrade_completed( $upgrade_action = '' ) {
// Bail if no upgrade action to check
if ( empty( $upgrade_action ) ) {
return false;
}
// Get completed upgrades
$completed_upgrades = edd_get_completed_upgrades();
// Return true if in array, false if not
return in_array( $upgrade_action, $completed_upgrades, true );
}
/**
* Get's the array of completed upgrade actions
*
* @since 2.3
* @return array The array of completed upgrades
*/
function edd_get_completed_upgrades() {
// Get the completed upgrades for this site
$completed_upgrades = get_option( 'edd_completed_upgrades', array() );
// Return array of completed upgrades
return (array) $completed_upgrades;
}
/**
* Install
*
* Runs on plugin install by setting up the post types, custom taxonomies,
* flushing rewrite rules to initiate the new 'downloads' slug and also
* creates the plugin and populates the settings fields for those plugin
* pages.
*
* @since 1.0
* @param bool $network_wide If the plugin is being network-activated
* @return void
*/
function edd_install( $network_wide = false ) {
// Multi-site install
if ( is_multisite() && ! empty( $network_wide ) ) {
edd_run_multisite_install();
// Single site install
} else {
edd_run_install();
}
}
/**
* Run the EDD installation on every site in the current network.
*
* @since 3.0
*/
function edd_run_multisite_install() {
global $wpdb;
// Get site count
$network_id = get_current_network_id();
$query = $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->blogs} WHERE site_id = %d", $network_id );
$count = $wpdb->get_var( $query );
// Bail if no sites (this is really strange and bad)
if ( empty( $count ) || is_wp_error( $count ) ) {
return;
}
// Setup the steps
$per_step = 100;
$total_steps = ceil( $count / $per_step );
$step = 1;
$offset = 0;
// Step through all sites in this network in groups of 100
do {
// Get next batch of site IDs
$query = $wpdb->prepare( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id = %d LIMIT %d, %d", $network_id, $offset, $per_step );
$site_ids = $wpdb->get_col( $query );
// Proceed if site IDs exist
if ( ! empty( $site_ids ) ) {
foreach ( $site_ids as $site_id ) {
edd_run_install( $site_id );
}
}
// Bump the limit for the next iteration
$offset = ( $step * $per_step ) - 1;
// Bump the step
++$step;
// Bail when steps are greater than or equal to total steps
} while ( $total_steps > $step );
}
/**
* Run the EDD Install process
*
* @since 2.5
* @since 3.0 Added $site_id parameter
*/
function edd_run_install( $site_id = false ) {
// Not switched
$switched = false;
// Maybe switch to a site
if ( ! empty( $site_id ) ) {
switch_to_blog( $site_id );
$switched = true;
}
// Get the current database version
$current_version = edd_get_db_version();
// Setup the components (customers, discounts, logs, etc...)
edd_setup_components();
// Setup the Downloads Custom Post Type
edd_setup_edd_post_types();
// Setup the Download Taxonomies
edd_setup_download_taxonomies();
// Clear the permalinks
flush_rewrite_rules( false );
// Install the default pages
edd_install_pages();
// Maybe save the previous version, only if different than current
if ( ! empty( $current_version ) && ( edd_format_db_version( EDD_VERSION ) !== $current_version ) ) {
if ( version_compare( $current_version, edd_format_db_version( EDD_VERSION ), '>' ) ) {
$downgraded = true;
update_option( 'edd_version_downgraded_from', $current_version );
}
update_option( 'edd_version_upgraded_from', $current_version );
}
// Install the default settings
edd_install_settings();
// Set the activation date.
edd_get_activation_date();
// Create wp-content/uploads/edd/ folder and the .htaccess file
if ( ! function_exists( 'edd_create_protection_files' ) ) {
require_once EDD_PLUGIN_DIR . 'includes/admin/upload-functions.php';
}
if ( function_exists( 'edd_create_protection_files' ) ) {
edd_create_protection_files( true );
}
// Create custom tables. (@todo move to BerlinDB)
EDD()->notifications->create_table();
// Create EDD shop roles
$roles = new EDD_Roles;
$roles->add_roles();
$roles->add_caps();
// API version
$api = new EDD_API;
update_option( 'edd_default_api_version', 'v' . $api->get_version() );
// Check for PHP Session support, and enable if available
EDD()->session->use_php_sessions();
// Maybe set all upgrades as complete (only on fresh installation)
edd_set_all_upgrades_complete();
// Update the database version (must be at end, but before site restore)
edd_update_db_version();
// Maybe switch back
if ( true === $switched ) {
restore_current_blog();
}
}
/**
* Maybe set upgrades as complete during a fresh
* @since 3.0
*/
function edd_set_all_upgrades_complete() {
// Bail if not a fresh installation
if ( edd_get_db_version() ) {
return;
}
// Maybe include an admin-area only file/function
if ( ! function_exists( 'edd_set_upgrade_complete' ) ) {
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/upgrade-functions.php';
}
// When new upgrade routines are added, mark them as complete on fresh install
$upgrade_routines = array(
'upgrade_payment_taxes',
'upgrade_customer_payments_association',
'upgrade_user_api_keys',
'remove_refunded_sale_logs',
'update_file_download_log_data',
);
$edd_30_upgrades = edd_get_v30_upgrades();
$upgrade_routines = array_merge( $upgrade_routines, array_keys( $edd_30_upgrades ) );
// Loop through upgrade routines and mark them as complete
foreach ( $upgrade_routines as $upgrade ) {
edd_set_upgrade_complete( $upgrade );
}
}
/**
* Install the required pages
*
* @since 3.0
*/
function edd_install_pages() {
// Get all of the EDD settings
$current_options = get_option( 'edd_settings', array() );
// Required store pages
$pages = edd_get_required_pages();
// Look for missing pages
$missing_pages = array_diff_key( $pages, $current_options );
$pages_to_check = array_intersect_key( $current_options, $pages );
// Query for any existing pages
$posts = new WP_Query(
array(
'include' => array_values( $pages_to_check ),
'post_type' => 'page',
'fields' => 'ids',
)
);
// Default value for checkout page
$checkout = 0;
// We'll only update settings on change
$changed = false;
// Use the current user as the page author.
$user_id = get_current_user_id();
// Loop through all pages, fix or create any missing ones
foreach ( $pages as $page => $page_attributes ) {
$page_attributes = wp_parse_args(
$page_attributes,
array(
'post_status' => 'publish',
'post_author' => $user_id,
'post_type' => 'page',
'comment_status' => 'closed',
)
);
$page_id = ! empty( $pages_to_check[ $page ] ) ? $pages_to_check[ $page ] : false;
// Checks if the page option exists
$page_object = ! array_key_exists( $page, $missing_pages ) && ! empty( $posts->posts ) && ! empty( $page_id )
? get_post( $page_id )
: array();
// Skip if page exists
if ( ! empty( $page_object ) ) {
// Set the checkout page
if ( 'purchase_page' === $page ) {
$checkout = $page_object->ID;
}
// Skip if page exists
continue;
}
if ( ! isset( $page_attributes['post_parent'] ) ) {
$page_attributes['post_parent'] = $checkout;
}
// Create the new page
$new_page = wp_insert_post( $page_attributes );
// Update the checkout page ID
if ( 'purchase_page' === $page ) {
$checkout = $new_page;
}
// Set the page option
$current_options[ $page ] = $new_page;
// Pages changed
$changed = true;
}
// Update the option
if ( true === $changed ) {
update_option( 'edd_settings', $current_options );
}
}
/**
* Gets the array of required pages with default attributes and content for EDD.
*
* @since 3.1
* @return array
*/
function edd_get_required_pages() {
return apply_filters(
'edd_required_pages',
array(
'purchase_page' => array(
'post_title' => __( 'Checkout', 'easy-digital-downloads' ),
'post_content' => '<!-- wp:shortcode -->[download_checkout]<!-- /wp:shortcode -->',
'post_parent' => 0,
),
'success_page' => array(
'post_title' => __( 'Purchase Confirmation', 'easy-digital-downloads' ),
'post_content' => '<!-- wp:paragraph --><p>' . __( 'Thank you for your purchase!', 'easy-digital-downloads' ) . '</p><!-- /wp:paragraph --><!-- wp:shortcode -->[edd_receipt]<!-- /wp:shortcode -->',
),
'failure_page' => array(
'post_title' => __( 'Transaction Failed', 'easy-digital-downloads' ),
'post_content' => '<!-- wp:paragraph --><p>' . __( 'Your transaction failed; please try again or contact site support.', 'easy-digital-downloads' ) .'</p><!-- /wp:paragraph -->',
),
'purchase_history_page' => array(
'post_title' => __( 'Purchase History', 'easy-digital-downloads' ),
'post_content' => '<!-- wp:shortcode -->[purchase_history]<!-- /wp:shortcode -->',
),
)
);
}
/**
* Install the default settings
*
* @since 3.0
*
* @global array $edd_options
*/
function edd_install_settings() {
global $edd_options;
// Setup some default options
$options = array();
// Populate some default values
$all_settings = edd_get_registered_settings();
if ( ! empty( $all_settings ) ) {
foreach ( $all_settings as $tab => $sections ) {
foreach ( $sections as $section => $settings) {
// Check for backwards compatibility
$tab_sections = edd_get_settings_tab_sections( $tab );
if ( ! is_array( $tab_sections ) || ! array_key_exists( $section, $tab_sections ) ) {
$section = 'main';
$settings = $sections;
}
foreach ( $settings as $option ) {
if ( ! empty( $option['type'] ) && 'checkbox' == $option['type'] && ! empty( $option['std'] ) ) {
$options[ $option['id'] ] = '1';
}
}
}
}
}
// Get the settings
$settings = get_option( 'edd_settings', array() );
$merged_options = array_merge( $settings, $options );
$edd_options = $merged_options;
// Update the settings
update_option( 'edd_settings', $merged_options );
}
/**
* When a new Blog is created in multisite, see if EDD is network activated, and run the installer
*
* @since 2.5
* @param int|WP_Site $blog WordPress 5.1 passes a WP_Site object.
* @return void
*/
function edd_new_blog_created( $blog ) {
// Bail if plugin is not activated for the network
if ( ! is_plugin_active_for_network( plugin_basename( EDD_PLUGIN_FILE ) ) ) {
return;
}
if ( ! is_int( $blog ) ) {
$blog = $blog->id;
}
switch_to_blog( $blog );
edd_install();
restore_current_blog();
}
if ( version_compare( get_bloginfo( 'version' ), '5.1', '>=' ) ) {
add_action( 'wp_initialize_site', 'edd_new_blog_created' );
} else {
add_action( 'wpmu_new_blog', 'edd_new_blog_created' );
}
/**
* Drop our custom tables when a mu site is deleted
*
* @deprecated 3.0 Handled by WP_DB_Table
* @since 2.5
* @param array $tables The tables to drop
* @param int $blog_id The Blog ID being deleted
* @return array The tables to drop
*/
function edd_wpmu_drop_tables( $tables, $blog_id ) {
switch_to_blog( $blog_id );
$customers_db = new EDD_DB_Customers();
$customer_meta_db = new EDD_DB_Customer_Meta();
if ( $customers_db->installed() ) {
$tables[] = $customers_db->table_name;
$tables[] = $customer_meta_db->table_name;
}
restore_current_blog();
return $tables;
}
/**
* Post-installation
*
* Runs just after plugin installation and exposes the
* edd_after_install hook.
*
* @since 1.7
* @return void
*/
function edd_after_install() {
if ( ! is_admin() ) {
return;
}
$edd_options = get_transient( '_edd_installed' );
do_action( 'edd_after_install', $edd_options );
if ( false !== $edd_options ) {
// Delete the transient
delete_transient( '_edd_installed' );
}
}
add_action( 'admin_init', 'edd_after_install' );
/**
* Install user roles on sub-sites of a network
*
* Roles do not get created when EDD is network activation so we need to create them during admin_init
*
* @since 1.9
* @return void
*/
function edd_install_roles_on_network() {
global $wp_roles;
if( ! is_object( $wp_roles ) ) {
return;
}
if( empty( $wp_roles->roles ) || ! array_key_exists( 'shop_manager', $wp_roles->roles ) ) {
// Create EDD shop roles
$roles = new EDD_Roles;
$roles->add_roles();
$roles->add_caps();
}
}
add_action( 'admin_init', 'edd_install_roles_on_network' );