<?php 
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * Displays the Quick Playground Blueprint Builder admin page and handles form output.
 */
function qckply_builder() {
    //if the request includes anything other than $_GET['page'] and $_GET['profile'], check nonce
    if(sizeof($_REQUEST) == 2 && isset($_REQUEST['page']) && isset($_REQUEST['profile'])) {
        //valid request
    }
    elseif(sizeof($_REQUEST) > 1 && (empty( $_REQUEST['playground']) || !wp_verify_nonce( sanitize_text_field( wp_unslash ( $_REQUEST['playground'])), 'quickplayground' ) )) 
    {
        echo '<h2>'.esc_html__('Security Error','quick-playground').'</h2>';
        return;
    }  

global $wpdb, $current_user;

    $qckply_directories = qckply_get_directories();
    $qckply_uploads = $qckply_directories['uploads'];
    $qckply_uploads_url = $qckply_directories['uploads_url'];

$profile = isset($_REQUEST['profile']) ? preg_replace('/[^a-z0-9\-]+/','_',strtolower(sanitize_text_field($_REQUEST['profile']))) : 'default';
$stylesheet = get_stylesheet();
printf('<h1>%s: %s</h1>', esc_html(get_bloginfo('name')), esc_html($profile));
$qckply_sync_code = qckply_blueprint_settings_init($profile);
$qckply_api_url = rest_url('quickplayground/v1/blueprint/'.$profile).'?x='.time().'&user_id='.$current_user->ID;
$qckply_clone_api_url = rest_url('quickplayground/v1/clone_posts/'.$profile);
$origin_url = site_url();
$blueprint = get_option('qckply_blueprint_'.$profile, array());
$settings = get_option('quickplay_clone_settings_'.$profile,array());
$stylesheet = $settings['qckply_clone_stylesheet'] ?? $stylesheet;
$display = get_option('qckply_display_'.$profile,[]);

do_action('qckply_form_top');
?>
<h2>Blueprint Builder</h2>
<p>This is where you define which themes and plugins you want each WordPress Playground to include. You can create several Playground profiles, associated with different themes, plugins, and options.</p>
<?php

printf('<form class="qckply-form" method="post" action="%s"> <input type="hidden" name="build_profile" value="1">',esc_attr(admin_url('admin.php?page=qckply_builder')));
wp_nonce_field('quickplayground','playground',true,true);
printf('<p><input type="checkbox" name="reset_cache[]" value="all" /> %s</p>',esc_html__('Reset All Cached Content','quick-playground'));
echo '<p><button>Refresh</button></p>';
echo '<h2>Customization Options</h2>';
printf('<p>Loading saved blueprint for profile %s with %d steps defined. You can add or modify themes, plugins, and settings below.</p>',esc_html($profile),intval(sizeof($blueprint['steps'])));

$saved_plugins = $saved_themes = [];
$saved_code = '';

qckply_theme_options($blueprint, $stylesheet, 10);
qckply_plugin_options($blueprint);

do_action('qckply_form_steps',$blueprint, $profile);

if(!empty($settings['page_on_front'])) {
    $page_on_front = $settings['page_on_front'];
}

$front = $page_options = $post_options = '';
$pages = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_status FROM %i WHERE post_type='page' AND (post_status='publish' OR post_status='draft') ORDER BY post_status, post_title ", $wpdb->posts));
foreach($pages as $page) {
    $status = ('draft' == $page->post_status) ? '(Draft)' : '';
    $opt = sprintf('<option value="%d" >%s %s</option>',intval($page->ID),esc_html($page->post_title),esc_html($status));
    if($settings['page_on_front'] == $page->ID)
        $front = $opt;
    $page_options .= $opt;
}
$demoposts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_status FROM %i WHERE post_type='post' AND (post_status='publish' OR post_status='draft') ORDER BY ID DESC ",$wpdb->posts));
foreach($demoposts as $p) {
    $status = ('draft' == $p->post_status) ? '(Draft)' : '';
    $opt = sprintf('<option value="%d" >%s %s</option>',intval($p->ID),esc_html($p->post_title),esc_html($status));
    $post_options .= $opt;
}

echo '<h2>'.esc_html__('Content to Include','quick-playground').'</h2>';
$front .= '<option value="">Blog Listing</option>';

printf('<p><label>%s</label> <select name="settings[page_on_front]">%s</select></p>',esc_html__('Front Page','quick-playground'),wp_kses($front.$page_options, qckply_kses_allowed()));

printf('<p><input type="checkbox" name="settings[qckply_key_pages]" value="1" %s > Include key pages and posts (linked to from the home page or menu)</p>',(!isset($settings['qckply_key_pages']) || $settings['qckply_key_pages']) ? ' checked="checked" ' : '');

printf('<p><label>Copy</label> <input type="checkbox" name="settings[copy_pages]" value="1" %s > all published pages <input style="width:5em" type="number" name="settings[copy_blogs]" value="%d" size="3" > latest blog posts</p>',!empty($settings['copy_pages']) ? ' checked="checked" ' : '',intval($settings['copy_blogs']));

if(!empty($settings['demo_pages']) && is_array($settings['demo_pages'])) {
    foreach($settings['demo_pages'] as $page_id) {
        if(!empty($page_id)) {
            printf('<p>%s <input type="checkbox" name="demo_pages[]" value="%d" checked="checked" /> %s</p>', esc_html__('Keep Demo Page', 'quick-playground'), intval($page_id), esc_html(get_the_title($page_id)));
        }
    }
}

for($i = 0; $i < 10; $i++) {
$classAndID = ($i > 0) ? ' class="hidden_item page" id="page_'.$i.'" ' : ' class="page" id="page_'.$i.'" ';
printf('<p%s><label>Demo Page</label> <select class="select_with_hidden" name="demo_pages[]">%s</select></p>'."\n",wp_kses($classAndID, qckply_kses_allowed()),'<option value="">Choose Page</option>'.wp_kses($page_options, qckply_kses_allowed()));
}
printf('<p><input type="checkbox" name="settings[make_menu]" value="1" %s > Make menu from selected pages</p>',empty($settings['make_menu']) ? '' : 'checked="checked"');

if(!empty($settings['demo_posts']) && is_array($settings['demo_posts'])) {
    foreach($settings['demo_posts'] as $id) {
        if(!empty($id)) {
            printf('<p>Keep Demo Post <input type="checkbox" name="demo_posts[]" value="%d" checked="checked" /> %s</p>'."\n",intval($id),esc_html(get_the_title($id)));
        }
    }
}
for($i = 0; $i < 10; $i++) {
    $classAndID = ($i > 0) ? ' class="hidden_item post" id="post_' . esc_attr($i) . '" ' : ' class="post" id="post_' . esc_attr($i) . '" ';
    printf(
        '<p%s><label>%s</label> <select class="select_with_hidden" name="demo_posts[]">%s</select></p>' . "\n",
        wp_kses($classAndID, qckply_kses_allowed()),
        esc_html__('Demo Blog Post', 'quick-playground'),
        '<option value="">' . esc_html__('Choose Blog Post', 'quick-playground') . '</option>' . wp_kses($post_options, qckply_kses_allowed())
    );
}
$att = get_option('qckply_profile_images_'.$profile,[]);
printf('<p><label>%s</label> <input type="text" name="attachments" value="%s" size="80" /><br /><em>%s</em></p>',esc_html__('Attachment IDs','quick-playground'),implode(',',$att),esc_html__('If you want to include specific media files in the Playground, enter a comma-separated list of attachment IDs. By default, Quick Playground downloads attachments needed for the correct functioning of post featured images and a few other features, such as site logo.','quick-playground'));

do_action('qckply_form_demo_content',$settings);

printf('<p><label>%s</label> <input name="settings[%s]" type="text" value="%s" /></p>','Site Name','blogname',esc_attr($settings['blogname']));
printf('<p><label>%s</label> <input name="settings[%s]" type="text" value="%s" /></p>','Site Description','blogdescription',esc_attr($settings['blogdescription']));


printf('<p><label>%s</label> <input type="text" name="settings[qckply_landing]" value="%s" /><br /><em>%s</em></p>',esc_html__('Landing Page (optional)','quick-playground'),empty($settings['qckply_landing']) ? '' : esc_attr($settings['qckply_landing']),esc_html__('If you want the user to start somewhere other than the home page, enter the path. Example "/wp-admin/" or "/demo-instructions/"','quick-playground'));
printf('<p><label>%s</label> <input type="radio" name="settings[show_playground_prompt_keys]" value="1" %s /> %s <input type="radio" name="settings[show_playground_prompt_keys]" value="0" %s /> %s<br /><em>%s</em></p>',esc_html__('Prompt for Prompts','quick-playground'),
!empty($settings['show_playground_prompt_keys']) ? ' checked="checked" ' : '',esc_html__('Yes','quick-playground'),empty($settings['show_playground_prompt_keys']) ? ' checked="checked" ' : '',esc_html__('No','quick-playground'),esc_html__('You can set up prompts/tips/help messages for each front end or admin page. Turning this on makes it easier to do that during preprateion of a demo (you can deactivate it later).','quick-playground'));

printf('<p>%s:<br /><input type="radio" name="qckply_display[iframe]" value="no_iframe" %s /> %s <input type="radio" name="qckply_display[iframe]" value="custom_sidebar" %s /> %s <input type="radio" name="qckply_display[iframe]" value="no_sidebar" %s /> %s <input type="radio" name="qckply_display[iframe]" value="no_iframe" %s /> %s </p>',esc_html__('Display Options','quick-playground'),(empty($display['iframe']) || 'no_iframe' == $display['iframe']) ? ' checked="checked" ' : '',esc_html__('No iframe, use playground.wordpress.net','quick-playground'),('iframe' == $display['iframe']) ? ' checked="checked" ' : '',esc_html__('iframe with sidebar','quick-playground'),(!empty($display['iframe']) && 'custom_sidebar' == $display['iframe']) ? ' checked="checked" ' : '',esc_html__('iframe with custom sidebar','quick-playground'),(!empty($display['iframe']) && 'no_sidebar' == $display['iframe']) ? ' checked="checked" ' : '',esc_html__('iframe, no sidebar','quick-playground'));
printf('<input type="hidden" name="qckply_display[iframe_sidebar]" value="%d" />%s',empty($display['iframe_sidebar']) ? '0' : intval($display['iframe_sidebar']),empty($display['iframe_sidebar']) ? '' : '<p><a target="_blank" href="'.esc_attr(admin_url('post.php?action=edit&post='.intval($display['iframe_sidebar']))).'">'.esc_html__('Edit Custom Sidebar','quick-playground').'</a></p>');
printf('<p><label>%s</label> <input type="number" class="number_input" name="qckply_display[sidebar_width]" value="%d" /> (pixels)</p>',esc_html__('Sidebar Width','quick-playground'),empty($display['sidebar_width']) ? 300 : intval($display['sidebar_width']));
printf('<p><label>%s</label> <input type="text" name="qckply_display[iframe_title]" value="%s" /> </p>',esc_html__('Page Title for iframe','quick-playground'),empty($display['iframe_title']) ? esc_attr(get_option('blogname')) : esc_attr($display['iframe_title']));
printf('<p><em>%s</em></p><ul></ul>',esc_html__('Enable the iframe to add more branding to your playground. One tradeoff to keep in mind: Links opened in a new tab do not display properly. If your purpose is to demonstrate editor functions, iframe display will tend to get in the way because the View Post link displayed after content is saved opens in a new tab by default.'));

echo '<p><input type="checkbox" name="show_details" value="1" /> Show Detailed Output</p>';
echo '<p><input type="checkbox" name="show_blueprint" value="1" /> Show Blueprint JSON</p>';
echo '<p><input type="checkbox" name="logerrors" value="1" /> Log Errors in Playground</p>';
printf('<input type="hidden" name="profile" value="%s" />', esc_attr($profile));
$sync_disable = get_option('qckply_disable_sync_'.$profile,false);
printf('<p><input type="radio" name="set_sync_code" value="1" %s /> Enable <input type="radio" name="set_sync_code" value="0" %s /> Disable Quick Playground Save and Sync</p>',!empty($qckply_sync_code) ? 'checked="checked"' : '',empty($qckply_sync_code) ? 'checked="checked"' : '');
printf('<p><input type="radio" name="settings[qckply_disable_image_upload]" value="0" %s /> Enable <input type="radio" name="settings[qckply_disable_image_upload]" value="1" %s /> Disable saving of Playground images</p>',!empty($settings['qckply_disable_image_upload']) ? '' : 'checked="checked"',empty($settings['qckply_disable_image_upload']) ? '' : 'checked="checked"');
do_action('qckply_additional_setup_form_fields',$settings);

echo '<h2>'.esc_html__('Content Saved from Past Sessions','quick-playground').'</h2>';
$caches = qckply_caches($profile);
if(empty($caches)) {
echo '<p>'.esc_html__('none','quick-playground').'</p>';
}
else {
    printf('<p><input type="checkbox" name="reset_cache[]" value="all" /> %s</p>',esc_html__('Reset All Cached Content','quick-playground'));
    foreach($caches as $cache) {
        printf('<p><input type="checkbox" name="reset_cache[]" value="%s" /> %s %s</p>',esc_attr($cache),esc_html__('Reset','quick-playground'),esc_html(ucfirst($cache)));
    }
    echo '<p>'.esc_html__('Resetting will force the playground to fetch fresh content.','quick-playground').'</p>';
}

echo '<p><button>Submit</button></p>';
echo '</form>';
$qckply_api_url = qckply_get_api_url(['profile'=>$profile]);
$qckply_json_url = qckply_get_api_url(['profile'=>$profile],true);

$taxurl = rest_url('quickplayground/v1/clone_taxonomy/'.$profile.'?t='.time());
$imgurl = rest_url('quickplayground/v1/clone_images/'.$profile.'?t='.time());
$customurl = rest_url('quickplayground/v1/clone_custom/'.$profile.'?t='.time());

echo '<p><a href="#qckply-builder-info" id="showtest">'.esc_html__('Show Test and Debugging Info','quick-playground').'</a></p><div id="qckply-builder-info" class="hidden_item">';
printf('<h3>For Testing</h3><p>Blueprint URL: <a href="%s" target="_blank">%s</a></p>',esc_url($qckply_api_url),esc_html($qckply_api_url));
printf('<p>Blueprint, No Cache: <a href="%s&nocache=1" target="_blank">%s&nocache=1</a></p>',esc_url($qckply_api_url),esc_html($qckply_api_url));
printf('<p>Blueprint API URL: <a href="%s&nocache=1" target="_blank">%s&nocache=1</a></p>',esc_url($qckply_json_url),esc_html($qckply_json_url));
printf('<p>Clone Posts API URL: <br /><a href="%s" target="_blank">%s</a></p>',esc_url($qckply_clone_api_url),esc_html($qckply_clone_api_url));
printf('<p>Clone Metadata/Taxonomy API URL: <br /><a href="%s" target="_blank">%s</a></p>',esc_url($taxurl),esc_html($taxurl));
printf('<p>Clone Images API URL: <br /><a href="%s" target="_blank">%s</a></p>',esc_url($imgurl),esc_html($imgurl));
printf('<p>Clone Custom API URL: <br /><a href="%s" target="_blank">%s</a></p>',esc_url($customurl),esc_html($customurl));
//variables are sanitized in qckply_get_button. output includes svg code not compatible with wp_kses_post. was not able to get it work with wp_kses and custom tags
printf('<p>Demo playground button code</p><p><textarea cols="100" rows="5">%s</textarea></p>',esc_html(qckply_get_button(['profile',$profile,'is_demo'=>1])));
qckply_get_blueprint_link(['profile'=>$profile,'is_demo'=>1]);
qckply_print_button_shortcode(['profile'=>$profile,'is_demo'=>1]);

qckply_key_pages_list();
qckply_show_hits();

$clone = qckply_get_clone_posts($profile, true);
echo '<h2>Zip Images Test</h2>';
$clone = qckply_zip_images($profile,$clone,true);

printf('<p>%s</p><pre>%s</pre><pre>%s</pre>',$clone['images_zip'],var_export($clone['added_images'],true),var_export($clone['not_found'],true));
foreach($clone['posts'] as $post) {
    if($post->post_type == 'attachment') {
    $parent = '';
    if(!empty($post->post_parent))
    {
        $parent_post = get_post($post->post_parent);
        if($parent_post)
            $parent = "(Parent: $parent_post->ID $parent_post->post_title )";
    }
    printf('<h3>Attachment ID %d: %s %s</h3><div>%s</div>',intval($post->ID),esc_html($post->post_title),esc_html($parent),wp_kses_post($post->guid));
    }
}

printf('<p>Quickplay Directories:</p><pre>%s</pre><p>WP Directories</p><pre>%s</pre>',var_export($qckply_directories,true),var_export(wp_get_upload_dir(),true));

echo '</div>';

}

/**
 * 
 * Outputs plugin selection options for the playground blueprint form.
 *
 * @param array $blueprint   The current blueprint array.
 * @param bool  $active_only Whether to show only active plugins (default true).
 */
function qckply_plugin_list($blueprint) {
    $saved_plugins = [];
    foreach($blueprint['steps'] as $step) {
        if(is_array($step)) {
            if('installPlugin' == $step['step']) {
                if($step['pluginData']['resource'] == 'wordpress.org/plugins')
                {
                    $slug = $step['pluginData']['slug'];
                }
                else {
                $slug = $step['pluginData']['url'];
                if(strpos($slug,'playground'))
                    continue; 
                preg_match('/\/([a-z0-9\-]+)\.zip/',$slug,$match);
                if(empty($match[1]))
                    continue;
                $slug = $match[1];
                }
            if(strpos($slug,'playground'))
                continue; 
            if(!empty($step['options']['activate']) )
                $slug .= ' (active)';
            $saved_plugins[] = $slug;
            }
        }
}
    return $saved_plugins;
}

/**
 * Outputs plugin selection options for the playground blueprint form.
 *
 * @param array $blueprint   The current blueprint array.
 * @param bool  $active_only Whether to show only active plugins (default true).
 */
function qckply_plugin_options($blueprint) {
    $plausible_plugins = qckply_plausible_plugins();
    $default_plugins = is_multisite() ? get_blog_option(1,'qckply_default_plugins',array()) : array();
    $pluginoptions = '<option value="">Select a plugin</option>';
    foreach($plausible_plugins['active'] as $index => $slug) {
        $name = $plausible_plugins['active_names'][$index];
        $pluginoptions .= sprintf('<option value="%s">%s (%s)</option>',esc_attr($slug), esc_html($name),esc_html__('Active','quick-playground'));
    }
    foreach($plausible_plugins['inactive'] as $slug => $name) {
        $pluginoptions .= sprintf('<option value="%s">%s</option>',esc_attr($slug), esc_html($name));
    }
    if(!empty($blueprint)) {
    foreach($blueprint['steps'] as $step) {
        if(is_array($step)) {
            if('installPlugin' == $step['step']) {
                if(isset($_GET['update']) && $step['pluginData']['resource'] == 'url')
                    {
                        preg_match('/([a-z0-9-_]+)\.zip/',$step['pluginData']['url'],$matches);
                        printf('<p>Zip update for %s</p>',esc_html($matches[1]));
                        qckply_zip_plugin($matches[1]);
                    }
                $saved_plugins[] = $step;
            }
        }
    }
}

echo '<h2>Choose Plugins for Your Playground</h2>';
if(!empty($default_plugins)) {
    echo '<p>The network administrator has specified that these will be included automatically: '.esc_html(implode(',',$default_plugins)).'</p>';
}
if(!empty($plausible_plugins['active'])) {
echo '<p><input type="checkbox" name="all_active_plugins" value="'.esc_attr(implode(',',$plausible_plugins['active'])).'"> Include these active plugins ('.esc_html(implode(', ',$plausible_plugins['active_names'])).')</p>';
}
for($i = 0; $i < 10 + sizeof($saved_plugins); $i++) {
if(!empty($saved_plugins[$i])) {
    if($saved_plugins[$i]['pluginData']['resource'] == 'wordpress.org/plugins') {
        $slug = $saved_plugins[$i]['pluginData']['slug'];
        $local = 0;
    }
    else {
        $slug = $saved_plugins[$i]['pluginData']['url'];
        preg_match('/\/([a-z0-9\-]+)\.zip/',$slug,$match);
        if(empty($match[1]))
            continue;
        $slug = $match[1];
        $local = 1;
    }
    if($slug == 'quick-playground')
        continue; // skip this plugin, it is already included in the playground
    if(!empty($slug)) {
    $opt = sprintf('<option value="%s">%s</option><option value="">Remove %s</option>',$slug,$slug,$slug);
    $activate = (!empty($saved_plugins[$i]['options']['activate']) ) ? '<input type="radio" name="activate_plugin['.intval($i).']" value="1" checked="checked" /> Activate <input type="radio" name="activate_plugin['.intval($i).']" value="0" /> Do Not Activate' : '<input type="radio" name="activate_plugin['.intval($i).']" value="1" /> Activate <input type="radio" name="activate_plugin['.intval($i).']" value="0" checked="checked" /> Do Not Activate';
    $zip = ($local) ? '<input type="radio" name="ziplocal_plugin['.intval($i).']" value="0" /> WordPress.org <input type="radio" name="ziplocal_plugin['.intval($i).']" value="1"  checked="checked" /> Local Zip ' : '<input type="radio" name="ziplocal_plugin['.intval($i).']" value="0" checked="checked" /> WordPress.org <input type="radio" name="ziplocal_plugin['.intval($i).']" value="1" /> Local Zip ';
    $classAndID = ' class="plugin" id="plugin_'.esc_attr($i).'" ';
    printf('<p%s><label>Plugin</label> <select class="select_with_hidden" name="add_plugin[]">%s</select> %s <br />%s  </p>',wp_kses($classAndID, qckply_kses_allowed()),wp_kses($opt.$pluginoptions, qckply_kses_allowed()),wp_kses($zip, qckply_kses_allowed()),wp_kses($activate, qckply_kses_allowed()));
    }
} 
else {
    $classAndID = ($i > 0 + sizeof($saved_plugins)) ? ' class="hidden_item plugin" id="plugin_'.esc_attr($i).'" ' : ' class="plugin" id="plugin_'.esc_attr($i).'" ';
    printf('<p%s><label>Plugin</label> <select class="select_with_hidden" name="add_plugin[]">%s</select>  <input type="radio" name="ziplocal_plugin[%d]" value="0" checked="checked" /> WordPress.org <input type="radio" name="ziplocal_plugin[%d]" value="1" /> Local Zip <br /><input type="radio" name="activate_plugin[%d]" value="1" checked="checked" /> Activate <input type="radio" name="activate_plugin[%d]" value="0" /> Do Not Activate  </p>',wp_kses($classAndID, qckply_kses_allowed()),wp_kses($pluginoptions, qckply_kses_allowed()),intval($i),intval($i),intval($i),intval($i));
    }
}
echo "<p class=\"fineprint\">Make a selection, and another will be revealed</p>\n";

}

/**
 * Outputs theme selection options for the playground blueprint form.
 *
 * @param array  $blueprint   The current blueprint array.
 * @param string $stylesheet  The current theme stylesheet.
 * @param int    $themeslots  Number of theme slots to display (default 1).
 */
function qckply_theme_options($blueprint, $stylesheet, $themeslots = 1) {
$excluded_themes = (is_multisite()) ? get_blog_option(1,'qckply_excluded_themes',array()) : array();
$saved_plugins = $saved_themes = [];
$saved_code = '';
    $themeoptions = '<option value="">Select a theme</option>';

    $themes = wp_get_themes(['allowed'=>true]);

    $all_themes = [];

    foreach($themes as $styleslug => $themeobj) {

        if(in_array($styleslug,$excluded_themes)) {
            continue; // skip excluded themes
        }

        if($stylesheet == $styleslug) {
            $current_theme_option = sprintf('<option value="%s">%s</option>',esc_attr($styleslug), esc_html($themeobj->__get('name')));
        }
        $themeoptions .= sprintf('<option value="%s">%s</option>',esc_attr($styleslug), esc_html($themeobj->__get('name')));
    }

if(!empty($blueprint)) {
    foreach($blueprint['steps'] as $step) {
        if(is_array($step)) {
            if('installTheme' == $step['step']) {
                if(isset($_GET['update']) && $step['themeData']['resource'] == 'url')
                    {
                        preg_match('/([a-z0-9-_]+)\.zip/',$step['themeData']['url'],$matches);
                        printf('<p>Zip update for %s</p>',esc_html($matches[1]));
                        qckply_zip_theme($matches[1]);
                    }
                $saved_themes[] = $step;
            }
            elseif('installPlugin' == $step['step']) {
                if(isset($_GET['update']) && $step['pluginData']['resource'] == 'url')
                    {
                        preg_match('/([a-z0-9-_]+)\.zip/',$step['pluginData']['url'],$matches);
                        printf('<p>Zip update for %s</p>',esc_html($matches[1]));
                        qckply_zip_plugin($matches[1]);
                    }
                $saved_plugins[] = $step;
            }
        }
    }
}

echo ($themeslots > 1) ? '<h2>Themes for Your Playground</h2>' : '<h2>Theme for Your Playground</h2>';

if($themeslots > 1)
    $themeslots += sizeof($saved_themes);

$themes_shown = [];

for($i = 0; $i < $themeslots; $i++) {
$label = ($i == 0) ? 'Active Theme' : 'Additional Theme';
$local = 0;

if(!empty($saved_themes[$i])) {
    if($saved_themes[$i]['themeData']['resource'] == 'wordpress.org/themes') {
        $slug = $saved_themes[$i]['themeData']['slug'];
        $local = 0;
    }
    else {
        $slug = $saved_themes[$i]['themeData']['url'];
        preg_match('/\/([a-z0-9\-]+)\.zip/',$slug,$match);
        $slug = $match[1];
        $local = 1;
    }
    if(in_array($slug,$themes_shown))
        continue;
    $themes_shown[] = $slug;
    if(!$local && !empty($slug))//verify that it's available in the repository
        $local = !qckply_repo_check($slug, 'theme');
} 
$default_option = ($i == 0) ? $current_theme_option : '';
$hideafter = (empty($saved_themes)) ? 1 : sizeof($saved_themes);
$classAndID = ($i > $hideafter ) ? ' class="hidden_item theme" id="theme_'.esc_attr($i).'" ' : ' class="theme" id="theme_'.esc_attr($i).'" ';
printf('<p%s><label>%s</label> <select class="select_with_hidden" name="add_theme[]">%s</select> <input type="radio" name="ziplocal_theme[%d]" value="0" %s /> WordPress.org <input type="radio" name="ziplocal_theme[%d]" value="1" %s /> Local Zip WordPress.org</p>',wp_kses($classAndID, qckply_kses_allowed()),esc_html($label),wp_kses($default_option.$themeoptions, qckply_kses_allowed()),intval($i),empty($local) ? ' checked="checked" ' : '',intval($i),!empty($local) ? ' checked="checked" ' : '' );

}
if($themeslots > 1)
    echo "<p class=\"fineprint\">Make a selection, and another will be revealed</p>\n";

if($themeslots == 1 && sizeof($saved_themes) > 1) {
    array_shift($saved_themes); // don't include active theme
    foreach($saved_themes as $si => $saved_theme) {
    $i = $si + 1;
    if($saved_theme['themeData']['resource'] == 'wordpress.org/themes') {
        $slug = $saved_theme['themeData']['slug'];
        $local = 0;
    }
    else {
        $slug = $saved_theme['themeData']['url'];
        preg_match('/\/([a-z0-9\-]+)\.zip/',$slug,$match);
        $slug = $match[1];
        $local = 1;
    }
    printf('<p>Keep %s: <input type="checkbox" name="add_theme[]" value="%s" checked="checked" /> %s <input type="checkbox" name="ziplocal_theme[%d]" value="1" %s /> Local Zip</p>',esc_html($label),esc_attr($slug), esc_attr($slug), intval($i), $local ? ' checked="checked" ' : '');
} 

}
}
