public function add_sub_items($settings = false)
 {
     if (false === $settings) {
         $settings = edd_get_registered_settings();
     }
     $header = '';
     $headers = array();
     $to_add = array();
     foreach ($settings as $key => $setting) {
         $type = isset($setting['type']) ? $setting['type'] : false;
         // This item isn't a setting but a parent array, check it's sub arrays
         if (false === $type) {
             $this->add_sub_items($setting);
         }
         $allowed_types = array('checkbox', 'header');
         if (false === $type || !in_array($type, $allowed_types)) {
             continue;
         }
         if ($type === 'header') {
             $headers[] = $setting;
             $header = $setting['id'];
         } else {
             if (empty($header)) {
                 $header = $key;
                 $name = str_replace('_', ' ', $header);
                 $name = str_replace('-', ' ', $name);
                 $headers[] = array('id' => $header, 'name' => ucwords($name));
             }
             $to_add[$header][] = $setting;
         }
     }
     if (!empty($headers)) {
         // Itterate through the headers we found
         foreach ($headers as $key => $header) {
             // If this header has subitems, add it and it's settings
             if (!empty($to_add[$header['id']])) {
                 $location = !empty($this->header_locations[$header['id']]) ? $this->header_locations[$header['id']] : false;
                 $this->add_heading($header, $location);
                 foreach ($to_add[$header['id']] as $item) {
                     $this->add_sub_item($item);
                 }
             }
         }
     }
 }
/**
 * Retrieve settings tabs
 *
 * @since 1.8
 * @return array $tabs
 */
function edd_get_settings_tabs()
{
    $settings = edd_get_registered_settings();
    $tabs = array();
    $tabs['general'] = __('General', 'easy-digital-downloads');
    $tabs['gateways'] = __('Payment Gateways', 'easy-digital-downloads');
    $tabs['emails'] = __('Emails', 'easy-digital-downloads');
    $tabs['styles'] = __('Styles', 'easy-digital-downloads');
    $tabs['taxes'] = __('Taxes', 'easy-digital-downloads');
    if (!empty($settings['extensions'])) {
        $tabs['extensions'] = __('Extensions', 'easy-digital-downloads');
    }
    if (!empty($settings['licenses'])) {
        $tabs['licenses'] = __('Licenses', 'easy-digital-downloads');
    }
    $tabs['misc'] = __('Misc', 'easy-digital-downloads');
    return apply_filters('edd_settings_tabs', $tabs);
}
/**
 * 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. After successful install, the user is redirected to the EDD Welcome
 * screen.
 *
 * @since 1.0
 * @global $wpdb
 * @global $edd_options
 * @global $wp_version
 * @return void
 */
function edd_install()
{
    global $wpdb, $edd_options, $wp_version;
    if (!function_exists('edd_create_protection_files')) {
        require_once EDD_PLUGIN_DIR . 'includes/admin/upload-functions.php';
    }
    // 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);
    // Add Upgraded From Option
    $current_version = get_option('edd_version');
    if ($current_version) {
        update_option('edd_version_upgraded_from', $current_version);
    }
    // Setup some default options
    $options = array();
    // Checks if the purchase page option exists
    if (!edd_get_option('purchase_page', false)) {
        // Checkout Page
        $checkout = wp_insert_post(array('post_title' => __('Checkout', 'easy-digital-downloads'), 'post_content' => '[download_checkout]', 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'page', 'comment_status' => 'closed'));
        // Purchase Confirmation (Success) Page
        $success = wp_insert_post(array('post_title' => __('Purchase Confirmation', 'easy-digital-downloads'), 'post_content' => __('Thank you for your purchase! [edd_receipt]', 'easy-digital-downloads'), 'post_status' => 'publish', 'post_author' => 1, 'post_parent' => $checkout, 'post_type' => 'page', 'comment_status' => 'closed'));
        // Failed Purchase Page
        $failed = wp_insert_post(array('post_title' => __('Transaction Failed', 'easy-digital-downloads'), 'post_content' => __('Your transaction failed, please try again or contact site support.', 'easy-digital-downloads'), 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'page', 'post_parent' => $checkout, 'comment_status' => 'closed'));
        // Purchase History (History) Page
        $history = wp_insert_post(array('post_title' => __('Purchase History', 'easy-digital-downloads'), 'post_content' => '[purchase_history]', 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'page', 'post_parent' => $checkout, 'comment_status' => 'closed'));
        // Store our page IDs
        $options['purchase_page'] = $checkout;
        $options['success_page'] = $success;
        $options['failure_page'] = $failed;
        $options['purchase_history_page'] = $history;
    }
    // Populate some default values
    foreach (edd_get_registered_settings() as $tab => $settings) {
        foreach ($settings as $option) {
            if ('checkbox' == $option['type'] && !empty($option['std'])) {
                $options[$option['id']] = '1';
            }
        }
    }
    update_option('edd_settings', array_merge($edd_options, $options));
    update_option('edd_version', EDD_VERSION);
    // Create wp-content/uploads/edd/ folder and the .htaccess file
    edd_create_protection_files(true);
    // Create EDD shop roles
    $roles = new EDD_Roles();
    $roles->add_roles();
    $roles->add_caps();
    $api = new EDD_API();
    update_option('edd_default_api_version', 'v' . $api->get_version());
    // Create the customers database
    @EDD()->customers->create_table();
    // Check for PHP Session support, and enable if available
    EDD()->session->use_php_sessions();
    // Add a temporary option to note that EDD pages have been created
    set_transient('_edd_installed', $options, 30);
    // Bail if activating from network, or bulk
    if (is_network_admin() || isset($_GET['activate-multi'])) {
        return;
    }
    if (!$current_version) {
        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');
        foreach ($upgrade_routines as $upgrade) {
            edd_set_upgrade_complete($upgrade);
        }
    }
    // Add the transient to redirect
    set_transient('_edd_activation_redirect', true, 30);
}
 public static function check_edd_settings($old_value, $new_value)
 {
     $options = array();
     if (!is_array($old_value) || !is_array($new_value)) {
         return;
     }
     foreach (self::get_changed_keys($old_value, $new_value, 0) as $field_key => $field_value) {
         $options[$field_key] = $field_value;
     }
     $settings = edd_get_registered_settings();
     foreach ($options as $option => $option_value) {
         $field = null;
         if ('banned_email' === $option) {
             $field = array('name' => _x('Banned emails', 'edd', 'stream'));
             $page = 'edd-tools';
             $tab = 'general';
         } else {
             $page = 'edd-settings';
             foreach ($settings as $tab => $fields) {
                 if (isset($fields[$option])) {
                     $field = $fields[$option];
                     break;
                 }
             }
         }
         if (empty($field)) {
             continue;
         }
         self::log(__('"%s" setting updated', 'stream'), array('option_title' => $field['name'], 'option' => $option, 'old_value' => maybe_serialize($old_value), 'value' => maybe_serialize($new_value), 'tab' => $tab), null, 'settings', 'updated');
     }
 }
/**
 * Options Page
 *
 * Renders the options page contents.
 *
 * @since 1.0
 * @return void
 */
function edd_options_page()
{
    $settings_tabs = edd_get_settings_tabs();
    $settings_tabs = empty($settings_tabs) ? array() : $settings_tabs;
    $active_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'general';
    $active_tab = array_key_exists($active_tab, $settings_tabs) ? $active_tab : 'general';
    $sections = edd_get_settings_tab_sections($active_tab);
    $key = 'main';
    if (is_array($sections)) {
        $key = key($sections);
    }
    $registered_sections = edd_get_settings_tab_sections($active_tab);
    $section = isset($_GET['section']) && !empty($registered_sections) && array_key_exists($_GET['section'], $registered_sections) ? sanitize_text_field($_GET['section']) : $key;
    // Unset 'main' if it's empty and default to the first non-empty if it's the chosen section
    $all_settings = edd_get_registered_settings();
    // Let's verify we have a 'main' section to show
    $has_main_settings = true;
    if (empty($all_settings[$active_tab]['main'])) {
        $has_main_settings = false;
    }
    // Check for old non-sectioned settings (see #4211 and #5171)
    if (!$has_main_settings) {
        foreach ($all_settings[$active_tab] as $sid => $stitle) {
            if (is_string($sid) && is_array($sections) && array_key_exists($sid, $sections)) {
                continue;
            } else {
                $has_main_settings = true;
                break;
            }
        }
    }
    $override = false;
    if (false === $has_main_settings) {
        unset($sections['main']);
        if ('main' === $section) {
            foreach ($sections as $section_key => $section_title) {
                if (!empty($all_settings[$active_tab][$section_key])) {
                    $section = $section_key;
                    $override = true;
                    break;
                }
            }
        }
    }
    ob_start();
    ?>
	<div class="wrap <?php 
    echo 'wrap-' . $active_tab;
    ?>
">
		<h1 class="nav-tab-wrapper">
			<?php 
    foreach (edd_get_settings_tabs() as $tab_id => $tab_name) {
        $tab_url = add_query_arg(array('settings-updated' => false, 'tab' => $tab_id));
        // Remove the section from the tabs so we always end up at the main section
        $tab_url = remove_query_arg('section', $tab_url);
        $active = $active_tab == $tab_id ? ' nav-tab-active' : '';
        echo '<a href="' . esc_url($tab_url) . '" class="nav-tab' . $active . '">';
        echo esc_html($tab_name);
        echo '</a>';
    }
    ?>
		</h1>
		<?php 
    $number_of_sections = count($sections);
    $number = 0;
    if ($number_of_sections > 1) {
        echo '<div><ul class="subsubsub">';
        foreach ($sections as $section_id => $section_name) {
            echo '<li>';
            $number++;
            $tab_url = add_query_arg(array('settings-updated' => false, 'tab' => $active_tab, 'section' => $section_id));
            $class = '';
            if ($section == $section_id) {
                $class = 'current';
            }
            echo '<a class="' . $class . '" href="' . esc_url($tab_url) . '">' . $section_name . '</a>';
            if ($number != $number_of_sections) {
                echo ' | ';
            }
            echo '</li>';
        }
        echo '</ul></div>';
    }
    ?>
		<div id="tab_container">
			<form method="post" action="options.php">
				<table class="form-table">
				<?php 
    settings_fields('edd_settings');
    if ('main' === $section) {
        do_action('edd_settings_tab_top', $active_tab);
    }
    do_action('edd_settings_tab_top_' . $active_tab . '_' . $section);
    do_settings_sections('edd_settings_' . $active_tab . '_' . $section);
    do_action('edd_settings_tab_bottom_' . $active_tab . '_' . $section);
    // For backwards compatibility
    if ('main' === $section) {
        do_action('edd_settings_tab_bottom', $active_tab);
    }
    // If the main section was empty and we overrode the view with the next subsection, prepare the section for saving
    if (true === $override) {
        ?>
<input type="hidden" name="edd_section_override" value="<?php 
        echo $section;
        ?>
" /><?php 
    }
    ?>
				</table>
				<?php 
    submit_button();
    ?>
			</form>
		</div><!-- #tab_container-->
	</div><!-- .wrap -->
	<?php 
    echo ob_get_clean();
}
/**
 * Options Page
 *
 * Renders the options page contents.
 *
 * @since 1.0
 * @return void
 */
function edd_options_page()
{
    $settings_tabs = edd_get_settings_tabs();
    $settings_tabs = empty($settings_tabs) ? array() : $settings_tabs;
    $active_tab = isset($_GET['tab']) && array_key_exists($_GET['tab'], $settings_tabs) ? $_GET['tab'] : 'general';
    $sections = edd_get_settings_tab_sections($active_tab);
    $key = 'main';
    if (is_array($sections)) {
        $key = key($sections);
    }
    $registered_sections = edd_get_settings_tab_sections($active_tab);
    $section = isset($_GET['section']) && !empty($registered_sections) && array_key_exists($_GET['section'], $registered_sections) ? $_GET['section'] : $key;
    // Unset 'main' if it's empty and default to the first non-empty if it's the chosen section
    $all_settings = edd_get_registered_settings();
    // Let's verify we have a 'main' section to show
    ob_start();
    do_settings_sections('edd_settings_' . $active_tab . '_main');
    $has_main_settings = strlen(ob_get_contents()) > 0;
    ob_end_clean();
    if (false === $has_main_settings) {
        unset($sections['main']);
        if ('main' === $section) {
            foreach ($sections as $section_key => $section_title) {
                if (!empty($all_settings[$active_tab][$section_key])) {
                    $section = $section_key;
                    break;
                }
            }
        }
    }
    ob_start();
    ?>
	<div class="wrap">
		<h1 class="nav-tab-wrapper">
			<?php 
    foreach (edd_get_settings_tabs() as $tab_id => $tab_name) {
        $tab_url = add_query_arg(array('settings-updated' => false, 'tab' => $tab_id));
        // Remove the section from the tabs so we always end up at the main section
        $tab_url = remove_query_arg('section', $tab_url);
        $active = $active_tab == $tab_id ? ' nav-tab-active' : '';
        echo '<a href="' . esc_url($tab_url) . '" title="' . esc_attr($tab_name) . '" class="nav-tab' . $active . '">';
        echo esc_html($tab_name);
        echo '</a>';
    }
    ?>
		</h1>
		<?php 
    $number_of_sections = count($sections);
    $number = 0;
    if ($number_of_sections > 1) {
        echo '<div><ul class="subsubsub">';
        foreach ($sections as $section_id => $section_name) {
            echo '<li>';
            $number++;
            $tab_url = add_query_arg(array('settings-updated' => false, 'tab' => $active_tab, 'section' => $section_id));
            $class = '';
            if ($section == $section_id) {
                $class = 'current';
            }
            echo '<a class="' . $class . '" href="' . esc_url($tab_url) . '">' . $section_name . '</a>';
            if ($number != $number_of_sections) {
                echo ' | ';
            }
            echo '</li>';
        }
        echo '</ul></div>';
    }
    ?>
		<div id="tab_container">
			<form method="post" action="options.php">
				<table class="form-table">
				<?php 
    settings_fields('edd_settings');
    if ('main' === $section) {
        do_action('edd_settings_tab_top', $active_tab);
    }
    do_action('edd_settings_tab_top_' . $active_tab . '_' . $section);
    do_settings_sections('edd_settings_' . $active_tab . '_' . $section);
    do_action('edd_settings_tab_bottom_' . $active_tab . '_' . $section);
    // For backwards compatibility
    if ('main' === $section) {
        do_action('edd_settings_tab_bottom', $active_tab);
    }
    ?>
				</table>
				<?php 
    submit_button();
    ?>
			</form>
		</div><!-- #tab_container-->
	</div><!-- .wrap -->
	<?php 
    echo ob_get_clean();
}