<?php /*

 Composr
 Copyright (c) ocProducts, 2004-2016

 See text/EN/licence.txt for full licencing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright  ocProducts Ltd
 * @package    setupwizard
 */

/**
 * Module page class.
 */
class Module_admin_setupwizard
{
    /**
     * Find details of the module.
     *
     * @return ?array Map of module info (null: module is disabled).
     */
    public function info()
    {
        $info = array();
        $info['author'] = 'Chris Graham';
        $info['organisation'] = 'ocProducts';
        $info['hacked_by'] = null;
        $info['hack_version'] = null;
        $info['version'] = 2;
        $info['locked'] = false;
        return $info;
    }

    /**
     * Find entry-points available within this module.
     *
     * @param  boolean $check_perms Whether to check permissions.
     * @param  ?MEMBER $member_id The member to check permissions as (null: current user).
     * @param  boolean $support_crosslinks Whether to allow cross links to other modules (identifiable via a full-page-link rather than a screen-name).
     * @param  boolean $be_deferential Whether to avoid any entry-point (or even return null to disable the page in the Sitemap) if we know another module, or page_group, is going to link to that entry-point. Note that "!" and "browse" entry points are automatically merged with container page nodes (likely called by page-groupings) as appropriate.
     * @return ?array A map of entry points (screen-name=>language-code/string or screen-name=>[language-code/string, icon-theme-image]) (null: disabled).
     */
    public function get_entry_points($check_perms = true, $member_id = null, $support_crosslinks = true, $be_deferential = false)
    {
        return array(
            'browse' => array('SETUPWIZARD', 'menu/adminzone/setup/setupwizard'),
        );
    }

    public $title;

    /**
     * Module pre-run function. Allows us to know metadata for <head> before we start streaming output.
     *
     * @return ?Tempcode Tempcode indicating some kind of exceptional output (null: none).
     */
    public function pre_run()
    {
        $type = get_param_string('type', 'browse');

        require_lang('config');

        set_helper_panel_tutorial('tut_configuration');

        breadcrumb_set_self(do_lang_tempcode('SETUPWIZARD'));

        if ($type == 'browse') {
            $step = 1;
        }

        if ($type != 'browse') {
            //breadcrumb_set_parents(array(array('_SELF:_SELF:browse', do_lang_tempcode('START'))));

            $step = min(10, intval(substr($type, 4)));
        }

        $this->title = get_screen_title('SETUPWIZARD');

        return null;
    }

    /**
     * Execute the module.
     *
     * @return Tempcode The result of execution.
     */
    public function run()
    {
        appengine_live_guard();

        require_css('setupwizard');

        $type = get_param_string('type', 'browse');

        if (($type != 'browse') && ($type != 'step11')) {
            if ((count($_POST) == 0) && (cms_srv('REQUEST_METHOD') != 'POST')) {
                warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
            }
        }

        if ($type == 'browse') {
            return $this->step1();
        }
        if ($type == 'step2') {
            return $this->step2();
        }
        if ($type == 'step3') {
            return $this->step3();
        }
        if ($type == 'step4') {
            return $this->step4();
        }
        if ($type == 'step5') {
            return $this->step5();
        }
        if ($type == 'step6') {
            return $this->step6();
        }
        if ($type == 'step7') {
            return $this->step7();
        }
        if ($type == 'step8') {
            return $this->step8();
        }
        if ($type == 'step9') {
            return $this->step9();
        }
        if ($type == 'step10') {
            return $this->step10();
        }
        if ($type == 'step11') {
            return $this->step11();
        }

        return new Tempcode();
    }

    /**
     * UI for a setup wizard step (welcome).
     *
     * @return Tempcode The UI
     */
    public function step1()
    {
        require_code('form_templates');

        $dh = @opendir(get_custom_file_base() . '/imports/addons/');
        $addons_available = array();
        if ($dh !== false) {
            while (($file = readdir($dh)) !== false) {
                if (substr($file, -4) == '.tar') {
                    $addons_available[] = basename($file, '.tar');
                }
            }
            closedir($dh);
        }
        foreach ($addons_available as $aa) {
            if (!addon_installed($aa)) {
                $addon_management = build_url(array('page' => 'admin_addons'), get_module_zone('admin_addons'));
                attach_message(do_lang_tempcode('ADDONS_NOT_INSTALLED_IN_SETUPWIZARD', escape_html($addon_management->evaluate())), 'notice');
                break;
            }
        }

        $_done_once = get_value('setupwizard_completed');
        $done_once = !is_null($_done_once);

        $post_url = build_url(array('page' => '_SELF', 'type' => 'step2'), '_SELF', array('keep_theme_seed', 'keep_theme_dark', 'keep_theme_source', 'keep_theme_algorithm'));
        $text = new Tempcode();
        $addons_url = build_url(array('page' => 'admin_addons'), get_module_zone('admin_addons'));
        $text->attach(paragraph(do_lang_tempcode($done_once ? 'SETUPWIZARD_1_DESCRIBE_ALT' : 'SETUPWIZARD_1_DESCRIBE', escape_html($addons_url->evaluate()))));
        $rescue_url = build_url(array('page' => '', 'keep_safe_mode' => '1'), '');
        $text->attach(paragraph(do_lang_tempcode('SETUPWIZARD_SAFE_MODE', escape_html($rescue_url->evaluate()), escape_html(find_theme_image('icons/24x24/tool_buttons/software_chat')), escape_html(find_theme_image('icons/48x48/tool_buttons/software_chat')))));
        $submit_name = do_lang_tempcode('PROCEED');

        $fields = new Tempcode();

        $inner = do_template('FORM', array('_GUID' => '71316d91703e3549301f57182405c997', 'SKIP_WEBSTANDARDS' => true, 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => $text, 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => $submit_name, 'HIDDEN' => ''));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => '38a02343903542f8bbe1fb49a7b21eb7', 'TITLE' => $this->title, 'STEP' => '1', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (information).
     *
     * @return Tempcode The UI
     */
    public function step2()
    {
        require_code('form_templates');

        $post_url = build_url(array('page' => '_SELF', 'type' => 'step3'), '_SELF');
        $submit_name = do_lang_tempcode('PROCEED');

        $inner = do_template('SETUPWIZARD_2', array('_GUID' => '2042f3786d10c7c5be5d38ea28942b47', 'SKIP_WEBSTANDARDS' => true, 'URL' => $post_url, 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => $submit_name));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => 'e04bc40dfc4047b62b586711d15ad875', 'TITLE' => $this->title, 'STEP' => '2', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (config).
     *
     * @return Tempcode The UI
     */
    public function step3()
    {
        $post_url = build_url(array('page' => '_SELF', 'type' => 'step4'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_3_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        require_code('form_templates');
        $fields = new Tempcode();
        require_lang('zones');

        $site_name = get_option('site_name');
        $description = get_option('description');
        $site_scope = get_option('site_scope');
        $_header_text = $GLOBALS['SITE_DB']->query_select_value('zones', 'zone_header_text', array('zone_name' => ''));
        $header_text = get_translated_text($_header_text);
        $copyright = get_option('copyright');
        $staff_address = get_option('staff_address');
        $keywords = get_option('keywords');
        $google_analytics = get_option('google_analytics');

        if ($site_name == '???') {
            $site_name = do_lang('EXAMPLE_SITE_NAME');
        }
        if ($description == '???') {
            $description = do_lang('EXAMPLE_DESCRIPTION');
        }
        if ($site_scope == '???') {
            $site_scope = do_lang('EXAMPLE_SITE_SCOPE');
        }
        if ($header_text == 'A site about ???') {
            $header_text = do_lang('EXAMPLE_HEADER_TEXT');
        }
        if ($copyright == 'Copyright &copy;, ???, 2006') {
            $copyright = do_lang('EXAMPLE_COPYRIGHT');
        }
        if ($keywords == '') {
            $keywords = do_lang('EXAMPLE_KEYWORDS');
        }

        $installprofiles = new Tempcode();
        $hooks = find_all_hooks('modules', 'admin_setupwizard_installprofiles');
        $installprofiles->attach(form_input_list_entry('', true, do_lang_tempcode('NA_EM')));
        require_code('zones2');
        foreach (array_keys($hooks) as $hook) {
            $path = get_file_base() . '/sources_custom/hooks/modules/admin_setupwizard_installprofiles/' . filter_naughty_harsh($hook) . '.php';
            if (!file_exists($path)) {
                $path = get_file_base() . '/sources/hooks/modules/admin_setupwizard_installprofiles/' . filter_naughty_harsh($hook) . '.php';
            }
            $_hook_bits = extract_module_functions($path, array('info'));
            $installprofile = is_array($_hook_bits[0]) ? call_user_func_array($_hook_bits[0][0], $_hook_bits[0][1]) : @eval($_hook_bits[0]);
            $installprofiles->attach(form_input_list_entry($hook, false, $installprofile['title']));
        }
        $fields->attach(form_input_list(do_lang_tempcode('INSTALLPROFILE'), do_lang_tempcode('DESCRIPTION_INSTALLPROFILE'), 'installprofile', $installprofiles, null, true, false));
        $fields->attach(form_input_line(do_lang_tempcode('SITE_NAME'), do_lang_tempcode('CONFIG_OPTION_site_name'), 'site_name', $site_name, true));
        $fields->attach(form_input_line(do_lang_tempcode('DESCRIPTION'), do_lang_tempcode('CONFIG_OPTION_description'), 'description', $description, false));
        $fields->attach(form_input_line(do_lang_tempcode('SITE_SCOPE'), do_lang_tempcode('CONFIG_OPTION_site_scope'), 'site_scope', $site_scope, true));
        $fields->attach(form_input_line(do_lang_tempcode('HEADER_TEXT'), do_lang_tempcode('DESCRIPTION_HEADER_TEXT'), 'header_text', $header_text, false));
        $fields->attach(form_input_line(do_lang_tempcode('COPYRIGHT'), do_lang_tempcode('CONFIG_OPTION_copyright'), 'copyright', $copyright, false));
        $fields->attach(form_input_line(do_lang_tempcode('STAFF_EMAIL'), do_lang_tempcode('CONFIG_OPTION_staff_address'), 'staff_address', $staff_address, true));
        $fields->attach(form_input_line(do_lang_tempcode('KEYWORDS'), do_lang_tempcode('CONFIG_OPTION_keywords'), 'keywords', $keywords, false));
        $fields->attach(form_input_line(do_lang_tempcode('GOOGLE_ANALYTICS'), do_lang_tempcode('CONFIG_OPTION_google_analytics'), 'google_analytics', $google_analytics, false));
        $fields->attach(form_input_tick(do_lang_tempcode('FIXED_WIDTH'), do_lang_tempcode('CONFIG_OPTION_fixed_width'), 'fixed_width', get_option('fixed_width') == '1'));
        $panel_path = get_custom_file_base() . '/pages/comcode_custom/' . get_site_default_lang() . '/panel_left.txt';
        if (file_exists($panel_path)) {
            $include_cms_advert = strpos(file_get_contents($panel_path), 'logos/') !== false;
        } else {
            $include_cms_advert = false;
        }
        $fields->attach(form_input_tick(do_lang_tempcode('INCLUDE_CMS_ADVERT'), do_lang_tempcode('DESCRIPTION_INCLUDE_CMS_ADVERT'), 'include_cms_advert', $include_cms_advert));

        $inner = do_template('FORM', array('_GUID' => '3126441524b51cba6a1e0de336c8a9d5', 'SKIP_WEBSTANDARDS' => true, 'SKIPPABLE' => 'skip_3', 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => $text, 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => $submit_name, 'HIDDEN' => ''));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => '6bdae2f0aa24b5dbe81fd0fc72e87feb', 'TITLE' => $this->title, 'STEP' => '3', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (addons).
     *
     * @return Tempcode The UI
     */
    public function step4()
    {
        $post_url = build_url(array('page' => '_SELF', 'type' => 'step5'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_4_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        require_code('form_templates');
        require_code('addons2');
        require_lang('addons');

        $addons_installed = find_installed_addons();
        $addons_not_installed = list_to_map('name', find_available_addons(false, false));

        $fields = '';
        $fields_advanced = '';
        $hidden = static_evaluate_tempcode(build_keep_post_fields());

        $installprofile = post_param_string('installprofile', '');
        $addon_list_override_to_off_by_default = array();
        $addon_list_force_on = array();
        if ($installprofile != '') {
            require_code('hooks/modules/admin_setupwizard_installprofiles/' . $installprofile);
            $object = object_factory('Hook_admin_setupwizard_installprofiles_' . $installprofile);
            $profile_addons = $object->get_addon_list();
            list($addon_list_on_by_default, $addon_list_advanced_on_by_default) = $profile_addons;
            if (array_key_exists(2, $profile_addons)) {
                $addon_list_override_to_off_by_default = $profile_addons[2];
            }
            if (array_key_exists(3, $profile_addons)) {
                $addon_list_force_on = $profile_addons[3];
            }
        } else {
            $addon_list_on_by_default = mixed();
            $addon_list_advanced_on_by_default = array();
            $addon_list_force_on = array();
        }

        /*$addon_list_on_by_default = array(   These will be put on in individual Setup Wizard profiles; we list them here just so our addon_setupwizard unit test can ensure we haven't forgotten to consider their status
            'aggregate_types',
            'authors',
            'calendar',
            'chat',
            'content_privacy',
            'content_reviews',
            'debrand',
            'downloads',
            'forum_blocks',
            'galleries',
            'match_key_permissions',
            'news',
            'newsletter',
            'cns_clubs',
            'cns_contact_member',
            'cns_forum',
            'cns_member_photos',
            'cns_member_titles',
            'cns_multi_moderations',
            'cns_post_templates',
            'cns_reported_posts',
            'cns_signatures',
            'cns_warnings',
            'points',
            'pointstore',
            'polls',
            'quizzes',
            'random_quotes',
            'realtime_rain',
            'recommend',
            'shopping',
            'ssl',
            'tickets',
            'welcome_emails',
            'wiki',
            'zone_logos',
        );*/

        // These are on by default regardless of install profile. It's useful, because we don't want install profiles to have to be too prescriptive, and we want old ones to keep working well even if new addons have been introduced.
        if (!is_null($addon_list_on_by_default)) {
            $addon_list_on_by_default = array_merge($addon_list_on_by_default, array(
                'banners',
                'ecommerce',
                'cns_avatars',
                'cns_cartoon_avatars',
                'cns_member_avatars',
                'cns_thematic_avatars',
                'wordfilter',
            ));
        }
        $addon_list_advanced_on_by_default = array_merge($addon_list_advanced_on_by_default, array(
            'actionlog',
            'awards',
            'breadcrumbs',
            'captcha',
            'catalogues',
            'counting_blocks',
            'custom_comcode',
            'errorlog',
            'help_page',
            'import',
            'language_block',
            'commandr',
            'cns_cpfs',
            'page_management',
            'redirects_editor',
            'search',
            'securitylogging',
            'setupwizard',
            'staff_messaging',
            'stats',
            'stats_block',
            'syndication',
            'syndication_blocks',
            'themewizard',
            'uninstaller',
            'unvalidated',
            'phpinfo',
            'hphp_buildkit',
            'apache_config_files',
            'code_editor',
            'linux_helper_scripts',
            'windows_helper_scripts',
            'weather',
            'xml_fields',
            'users_online_block',
            'news_shared',
            'filedump',
            'textbased_persistent_caching',
            'getid3', // this will be downloaded as it is not bundled, for licencing reasons
        ));
        // ... unless the install profile really is shunning them
        foreach ($addon_list_override_to_off_by_default as $_to_find) {
            if (!is_null($addon_list_on_by_default)) {
                $_found = array_search($_to_find, $addon_list_on_by_default);
                if ($_found !== false) {
                    unset($addon_list_on_by_default[$_found]);
                }
            }
            $_found = array_search($_to_find, $addon_list_advanced_on_by_default);
            if ($_found !== false) {
                unset($addon_list_advanced_on_by_default[$_found]);
            }
        }

        $addon_list_advanced_off_by_default = array( // Hint that these must go under advanced (as they default as visible). Note that presence of an addon in an 'on' list gives it precedence.
                                                     'installer',
                                                     'rootkit_detector',
                                                     'failover',
                                                     'msn',
                                                     'staff',
                                                     'backup',
                                                     'bookmarks',
                                                     'supermember_directory',
                                                     'ldap',
                                                     'sms',
                                                     'printer_friendly_block',
                                                     'data_mappr', // this will be downloaded as it is not bundled
                                                     'user_mappr', // this will be downloaded as it is not bundled
                                                     'facebook_support', // this will be downloaded as it is not bundled
                                                     'twitter_support', // this will be downloaded as it is not bundled
        );
        if (GOOGLE_APPENGINE) {
            $addon_list_advanced_off_by_default[] = 'google_appengine';
        }

        // Do we need to download any from compo.sr?
        $GLOBALS['DEV_MODE'] = false;
        foreach (array_merge(is_null($addon_list_on_by_default) ? array() : $addon_list_on_by_default, $addon_list_advanced_on_by_default, $addon_list_advanced_off_by_default) as $mentioned_addon) {
            if ((!array_key_exists($mentioned_addon, $addons_installed)) && (!array_key_exists($mentioned_addon, $addons_not_installed))) {
                $remote_addons = find_remote_addons();
                $_mentioned_addon = titleify($mentioned_addon);
                if (array_key_exists($_mentioned_addon, $remote_addons)) {
                    $id = $remote_addons[$_mentioned_addon];
                    require_code('uploads');
                    $_POST['url'] = 'http://compo.sr/site/dload.php?id=' . strval($id);
                    get_url('url', 'file', 'imports/addons', 0, CMS_UPLOAD_ANYTHING, false, '', '', true); // Download it
                }
            }
        }
        $addons_not_installed = list_to_map('name', find_available_addons(false, false, list_to_map('file', $addons_not_installed))); // Re-search for these, as more may have been downloaded above

        $all_addons = $addons_installed + $addons_not_installed;
        foreach ($all_addons as $addon_name => $row) {
            if (!isset($all_addons[$addon_name]['name'])) {
                $all_addons[$addon_name]['name'] = titleify($addon_name);
            }
        }
        sort_maps_by($all_addons, 'name');
        require_code('addons');
        foreach ($all_addons as $addon_name => $row) {
            $is_core = ($addon_name == 'core') || (substr($addon_name, 0, 5) == 'core_');
            if ((!$is_core) && (substr($addon_name, -7) != '_shared') && ($addon_name != 'setupwizard') && (!in_array($addon_name, $addon_list_force_on))) {
                $is_advanced_on_by_default = in_array($addon_name, $addon_list_advanced_on_by_default);
                $is_advanced_off_by_default = in_array($addon_name, $addon_list_advanced_off_by_default);
                $install_by_default = ((!is_null($addon_list_on_by_default)) && (in_array($addon_name, $addon_list_on_by_default)) || ($is_advanced_on_by_default) || ((is_null($addon_list_on_by_default)) && (!$is_advanced_off_by_default)));

                $addon_description = $row['description'];
                if ((substr($addon_description, -1) != '.') && ($addon_description != '')) {
                    $addon_description .= '.';
                }
                $_addon_description = protect_from_escaping(symbol_truncator(array(static_evaluate_tempcode(comcode_to_tempcode($addon_description)), '1000', '0', '1'), 'left'));

                $addon_icon = find_addon_icon($addon_name, false, array_key_exists('tar_path', $row) ? $row['tar_path'] : null);
                $addon_name_pretty = protect_from_escaping(do_template('ADDON_NAME', array('_GUID' => 'c036db4d27417f79e1f395d1edb44020', 'IMAGE_URL' => $addon_icon, 'NAME' => $row['name'])));

                $field = form_input_tick($addon_name_pretty, $_addon_description, 'addon_' . $addon_name, $install_by_default);

                $advanced = ($is_advanced_on_by_default) || ($is_advanced_off_by_default);
                if ($advanced) {
                    $fields_advanced .= $field->evaluate();
                } else {
                    $fields .= $field->evaluate();
                }
            } elseif (!$is_core) {
                $hidden .= static_evaluate_tempcode(form_input_hidden('addon_' . $addon_name, '1'));
            }
        }

        $fields .= static_evaluate_tempcode(do_template('FORM_SCREEN_FIELD_SPACER', array('_GUID' => '00948cc876d0ecb8b511800eabd8cae2', 'SECTION_HIDDEN' => true, 'TITLE' => do_lang_tempcode('ADVANCED'))));
        $fields .= $fields_advanced;

        $inner = do_template('FORM', array('_GUID' => '0f361a3ac0e020ba71f3a7a900eca0e4', 'NO_SIZING' => true, 'SKIP_WEBSTANDARDS' => true, 'SKIPPABLE' => 'skip_4', 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => $text, 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => $submit_name, 'HIDDEN' => $hidden));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => 'ca91a76aa418d5c9ae956247ebc70652', 'TITLE' => $this->title, 'STEP' => '4', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (the zone/feature configuration).
     *
     * @return Tempcode The UI
     */
    public function step5()
    {
        require_lang('menus');

        $post_url = build_url(array('page' => '_SELF', 'type' => 'step6'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_5_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        require_code('form_templates');
        $fields = '';

        $installprofile = post_param_string('installprofile', '');
        if ($installprofile != '') {
            $path = get_file_base() . '/sources_custom/hooks/modules/admin_setupwizard_installprofiles/' . filter_naughty_harsh($installprofile) . '.php';
            if (!file_exists($path)) {
                $path = get_file_base() . '/sources/hooks/modules/admin_setupwizard_installprofiles/' . filter_naughty_harsh($installprofile) . '.php';
            }
            $_hook_bits = extract_module_functions($path, array('field_defaults'));
            $field_defaults = is_array($_hook_bits[0]) ? call_user_func_array($_hook_bits[0][0], $_hook_bits[0][1]) : @eval($_hook_bits[0]);
        } else {
            $field_defaults = array();
        }

        $fields .= static_evaluate_tempcode(do_template('FORM_SCREEN_FIELD_SPACER', array('_GUID' => '9f81456d95f2ff66a46e2a5b9901aaf3', 'TITLE' => do_lang_tempcode('FEATURES'))));

        $hooks = find_all_hooks('modules', 'admin_setupwizard');
        foreach (array_keys($hooks) as $hook) {
            if ((post_param_integer('addon_' . $hook, 0) == 1) && ($hook != 'core')) {
                $path = get_file_base() . '/sources_custom/hooks/modules/admin_setupwizard/' . filter_naughty_harsh($hook) . '.php';
                if (!file_exists($path)) {
                    $path = get_file_base() . '/sources/hooks/modules/admin_setupwizard/' . filter_naughty_harsh($hook) . '.php';
                }
                if (strpos(file_get_contents($path), 'get_fields') !== false) { // Memory optimisation
                    require_code('hooks/modules/admin_setupwizard/' . filter_naughty_harsh($hook));
                    $hook = object_factory('Hook_sw_' . filter_naughty_harsh($hook), true);
                    if (is_null($hook)) {
                        continue;
                    }
                    if (method_exists($hook, 'get_fields')) {
                        $hook_fields = $hook->get_fields($field_defaults);
                        $fields .= static_evaluate_tempcode($hook_fields);
                    }
                }
            }
        }
        require_code('hooks/modules/admin_setupwizard/core'); // Core one explicitly goes last
        $hook = object_factory('Hook_sw_core', true);
        if (method_exists($hook, 'get_fields')) {
            $hook_fields = $hook->get_fields($field_defaults);
            $fields .= static_evaluate_tempcode($hook_fields);
        }

        $js = 'var cuz=document.getElementById("collapse_user_zones"); var cuz_func=function() { var gza=document.getElementById("guest_zone_access"); gza.disabled=cuz.checked; if (cuz.checked) gza.checked=true; }; cuz.onchange=cuz_func; cuz_func();';

        $inner = do_template('FORM', array(
            '_GUID' => 'f1e9a4d271c7d68ff9da6dc0438f6e3f',
            'SKIP_WEBSTANDARDS' => true,
            'JAVASCRIPT' => $js,
            'SKIPPABLE' => 'skip_5',
            'FIELDS' => $fields,
            'URL' => $post_url,
            'TEXT' => $text,
            'SUBMIT_ICON' => 'buttons__proceed',
            'SUBMIT_NAME' => $submit_name,
            'HIDDEN' => static_evaluate_tempcode(build_keep_post_fields()),
        ));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => '8dfd885199d3d1416c044fad7a97d953', 'TITLE' => $this->title, 'STEP' => '5', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (block choice).
     *
     * @return Tempcode The UI
     */
    public function step6()
    {
        require_all_lang();

        $installprofile = post_param_string('installprofile', '');
        if ($installprofile != '') {
            require_code('hooks/modules/admin_setupwizard_installprofiles/' . $installprofile);
            $object = object_factory('Hook_admin_setupwizard_installprofiles_' . $installprofile);
            $default_blocks = $object->default_blocks();
        } else {
            $default_blocks = null;
        }

        $main_blocks = array();
        $side_blocks = array();
        $hooks = find_all_hooks('modules', 'admin_setupwizard');
        foreach (array_keys($hooks) as $hook) {
            if ((post_param_integer('addon_' . $hook, 0) == 1) || (substr($hook, 0, 5) == 'core_') || ($hook == 'core')) {
                require_code('hooks/modules/admin_setupwizard/' . filter_naughty_harsh($hook));
                $ob = object_factory('Hook_sw_' . filter_naughty_harsh($hook), true);
                if (is_null($ob)) {
                    continue;
                }
                if (method_exists($ob, 'get_blocks')) {
                    $ret = $ob->get_blocks();
                    if (count($ret) != 0) {
                        list($a, $b) = $ret;
                        $main_blocks = array_merge($main_blocks, $a);
                        $side_blocks = array_merge($side_blocks, $b);
                    }
                }
            }
        }
        ksort($main_blocks);
        ksort($side_blocks);

        if (count($main_blocks) == 0 && count($side_blocks) == 0) {
            return $this->step7();
        }

        $post_url = build_url(array('page' => '_SELF', 'type' => 'step7'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_6_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        require_code('form_templates');
        $fields = '';
        require_lang('blocks');
        require_lang('zones');
        require_code('zones2');

        if (count($main_blocks) > 0) {
            $tmp = do_template('FORM_SCREEN_FIELD_SPACER', array('_GUID' => 'dfc20251e4f6b37ec1e046d0903250aa', 'TITLE' => do_lang_tempcode('HOME')));
            $fields .= $tmp->evaluate(); /*XHTMLXHTML*/
            foreach ($main_blocks as $block => $position_bits) {
                if (!file_exists(get_file_base() . '/sources/blocks/' . $block . '.php')) {
                    continue;
                }

                $description = paragraph(do_lang_tempcode('BLOCK_' . $block . '_DESCRIPTION'));
                $description->attach(paragraph(do_lang_tempcode('BLOCK_' . $block . '_USE')));
                $block_nice = cleanup_block_name($block);
                if (is_null($default_blocks)) {
                    $position = $position_bits[1];
                } else {
                    $position = 'NO';
                    foreach (array('YES', 'YES_CELL', 'PANEL_LEFT', 'PANEL_RIGHT') as $p) {
                        if (in_array($block, $default_blocks[$p])) {
                            $position = $p;
                        }
                    }
                }
                $main_list = new Tempcode();
                $main_list->attach(form_input_list_entry('NO', $position == 'NO', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_NO')));
                $main_list->attach(form_input_list_entry('YES', $position == 'YES', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_YES')));
                $main_list->attach(form_input_list_entry('YES_CELL', $position == 'YES_CELL', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_YES_CELL')));
                $main_list->attach(form_input_list_entry('PANEL_LEFT', $position == 'PANEL_LEFT', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_LEFT')));
                $main_list->attach(form_input_list_entry('PANEL_RIGHT', $position == 'PANEL_RIGHT', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_RIGHT')));
                $tmp = form_input_list($block_nice, $description, 'block_SITE_' . $block, $main_list);
                $fields .= $tmp->evaluate(); /*XHTMLXHTML*/
            }
        }

        if (count($side_blocks) > 0) {
            $tmp = do_template('FORM_SCREEN_FIELD_SPACER', array('_GUID' => '13e0d3002669654d9b45b4739ecbf28c', 'TITLE' => do_lang_tempcode('PANELS')));
            $fields .= $tmp->evaluate(); /*XHTMLXHTML*/
            foreach ($side_blocks as $block => $position_bits) {
                if (!file_exists(get_file_base() . '/sources/blocks/' . $block . '.php')) {
                    continue;
                }

                $description = paragraph(do_lang_tempcode('BLOCK_' . $block . '_DESCRIPTION'));
                $description->attach(paragraph(do_lang_tempcode('BLOCK_' . $block . '_USE')));
                $block_nice = cleanup_block_name($block);
                if (is_null($default_blocks)) {
                    $position = $position_bits[1];
                } else {
                    $position = 'NO';
                    foreach (array('YES', 'YES_CELL', 'PANEL_LEFT', 'PANEL_RIGHT') as $p) {
                        if (in_array($block, $default_blocks[$p])) {
                            $position = $p;
                        }
                    }
                }
                $side_list = new Tempcode();
                $side_list->attach(form_input_list_entry('PANEL_NONE', $position == 'PANEL_NONE', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_NONE')));
                $side_list->attach(form_input_list_entry('PANEL_LEFT', $position == 'PANEL_LEFT', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_LEFT')));
                $side_list->attach(form_input_list_entry('PANEL_RIGHT', $position == 'PANEL_RIGHT', do_lang_tempcode('BLOCK_CONFIGURATION__PANEL_RIGHT')));
                $tmp = form_input_list($block_nice, $description, 'block_SITE_' . $block, $side_list);
                $fields .= $tmp->evaluate(); /*XHTMLXHTML*/
            }
        }

        $inner = do_template('FORM', array(
            '_GUID' => 'd463906b9e2cd8c37577d64783aa844c',
            'SKIP_WEBSTANDARDS' => true,
            'SKIPPABLE' => 'skip_6',
            'FIELDS' => $fields,
            'URL' => $post_url,
            'TEXT' => $text,
            'PREVIEW' => true,
            'SUBMIT_ICON' => 'buttons__proceed',
            'SUBMIT_NAME' => $submit_name,
            'HIDDEN' => static_evaluate_tempcode(build_keep_post_fields()),
        ));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => '7c2cbc9577974b210e196b92158b4bb8', 'TITLE' => $this->title, 'STEP' => '6', 'INNER' => $inner));
    }

    /**
     * Get Comcode to save as the rules.
     *
     * @param  ID_TEXT $code A code relating to which rules set to get
     * @return string The Comcode
     */
    public function get_rules_file($code)
    {
        require_code('zones3');
        return get_template_contents('rules_' . $code);
    }

    /**
     * UI for a setup wizard step (rules).
     *
     * @return Tempcode The UI
     */
    public function step7()
    {
        $post_url = build_url(array('page' => '_SELF', 'type' => (addon_installed('themewizard') && (function_exists('imagepng'))) ? 'step8' : 'step9'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_7_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        $installprofile = post_param_string('installprofile', '');
        if ($installprofile != '') {
            require_code('hooks/modules/admin_setupwizard_installprofiles/' . $installprofile);
            $object = object_factory('Hook_admin_setupwizard_installprofiles_' . $installprofile);
            $field_defaults = $object->field_defaults();
        } else {
            $field_defaults = array();
        }

        require_code('form_templates');
        $list = new Tempcode();
        $list->attach(form_input_list_entry('balanced', array_key_exists('rules', $field_defaults) ? ($field_defaults['rules'] == 'balanced') : true, do_lang_tempcode('SETUPWIZARD_RULES_balanced')));
        $list->attach(form_input_list_entry('liberal', array_key_exists('rules', $field_defaults) ? ($field_defaults['rules'] == 'liberal') : false, do_lang_tempcode('SETUPWIZARD_RULES_liberal')));
        $list->attach(form_input_list_entry('corporate', array_key_exists('rules', $field_defaults) ? ($field_defaults['rules'] == 'corporate') : false, do_lang_tempcode('SETUPWIZARD_RULES_corporate')));
        $fields = form_input_list(do_lang_tempcode('RULES'), do_lang_tempcode('DESCRIPTION_RULES'), 'rules', $list, null, true);
        $javascript = "document.getElementById('rules').onchange=function() { var items=['preview_box_balanced','preview_box_liberal','preview_box_corporate']; var i; for (i=0;i<items.length;i++) document.getElementById(items[i]).style.display=(this.selectedIndex!=i)?'none':'block'; }";
        $form = do_template('FORM', array('_GUID' => 'bf01a2b90967e86213ae0672c36a4b4e', 'SKIPPABLE' => 'skip_7', 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => $text, 'SUBMIT_ICON' => 'buttons__proceed', 'SUBMIT_NAME' => $submit_name, 'HIDDEN' => static_evaluate_tempcode(build_keep_post_fields()), 'JAVASCRIPT' => $javascript));

        $balanced = comcode_to_tempcode($this->get_rules_file('balanced'), null, true);
        $liberal = comcode_to_tempcode($this->get_rules_file('liberal'), null, true);
        $corporate = comcode_to_tempcode($this->get_rules_file('corporate'), null, true);

        $inner = do_template('SETUPWIZARD_7', array('_GUID' => '5e46c3a989e42fa6eec5a017e8c644c2', 'FORM' => $form, 'BALANCED' => $balanced, 'LIBERAL' => $liberal, 'CORPORATE' => $corporate));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => '04f24f8c44267d2ad315aa34243e9712', 'TITLE' => $this->title, 'STEP' => '7', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (theme).
     *
     * @return Tempcode The UI
     */
    public function step8()
    {
        require_lang('themes');
        require_code('themewizard');

        $post_url = build_url(array('page' => '_SELF', 'type' => 'step9'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_8_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        require_code('form_templates');
        $fields = new Tempcode();
        $fields->attach(form_input_colour(do_lang_tempcode('SEED_COLOUR'), do_lang_tempcode('DESCRIPTION_SEED_COLOUR'), 'seed_hex', '#' . find_theme_seed('default'), true));
        $fields->attach(form_input_tick(do_lang_tempcode('DARK_THEME'), do_lang_tempcode('DESCRIPTION_DARK_THEME'), 'dark', get_param_integer('dark', 0) == 1));

        $inner = do_template('FORM', array(
            '_GUID' => '7ef31eb9712cff98da57a92fc173f7af',
            'PREVIEW' => true,
            'SKIP_WEBSTANDARDS' => true,
            'SKIPPABLE' => 'skip_8',
            'FIELDS' => $fields,
            'URL' => $post_url,
            'TEXT' => $text,
            'SUBMIT_ICON' => 'buttons__proceed',
            'SUBMIT_NAME' => $submit_name,
            'HIDDEN' => static_evaluate_tempcode(build_keep_post_fields()),
        ));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => 'e67abf478cea7aed5cda64189549677a', 'TITLE' => $this->title, 'STEP' => '8', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (close-status).
     *
     * @return Tempcode The UI
     */
    public function step9()
    {
        $post_url = build_url(array('page' => '_SELF', 'type' => 'step10'), '_SELF');
        $text = do_lang_tempcode('SETUPWIZARD_9_DESCRIBE');
        $submit_name = do_lang_tempcode('PROCEED');

        require_code('form_templates');
        $fields = new Tempcode();
        $fields->attach(form_input_tick(do_lang_tempcode('CLOSED_SITE'), do_lang_tempcode('CONFIG_OPTION_site_closed'), 'site_closed', true));
        $fields->attach(form_input_text(do_lang_tempcode('MESSAGE'), do_lang_tempcode('CONFIG_OPTION_closed'), 'closed', get_option('closed'), false));

        $javascript = "document.getElementById('site_closed').onchange=function() { document.getElementById('closed').disabled=!this.checked; }";

        $inner = do_template('FORM', array(
            '_GUID' => 'c405a64a08328f78ac0e3f22a8365411',
            'SKIP_WEBSTANDARDS' => true,
            'SKIPPABLE' => 'skip_9',
            'FIELDS' => $fields,
            'URL' => $post_url,
            'TEXT' => $text,
            'SUBMIT_ICON' => 'buttons__proceed',
            'SUBMIT_NAME' => $submit_name,
            'HIDDEN' => static_evaluate_tempcode(build_keep_post_fields()),
            'JAVASCRIPT' => $javascript,
        ));
        return do_template('SETUPWIZARD_SCREEN', array('_GUID' => 'de13f131460e7f342c8beb6ba5ae3f42', 'TITLE' => $this->title, 'STEP' => '9', 'INNER' => $inner));
    }

    /**
     * UI for a setup wizard step (done).
     *
     * @return Tempcode The UI
     */
    public function step10()
    {
        $GLOBALS['NO_QUERY_LIMIT'] = true;

        require_code('abstract_file_manager');
        force_have_afm_details();

        if (php_function_allowed('set_time_limit')) {
            @set_time_limit(600);
        }
        send_http_output_ping();

        disable_php_memory_limit();

        // Proceed...

        set_mass_import_mode();

        require_code('config2');
        require_code('themes2');
        require_lang('zones');
        require_code('files');
        require_code('images');

        $header_text = post_param_string('header_text');
        $name = post_param_string('site_name');
        require_code('fonts');
        $font = post_param_string('font', find_default_font());
        $theme = substr(preg_replace('#[^' . URL_CONTENT_REGEXP . ']#', '_', $name), 0, 40);
        $installprofile = post_param_string('installprofile', '');

        $default_logos = get_all_image_ids_type('logo/default_logos');
        shuffle($default_logos);
        $default_backgrounds = get_all_image_ids_type('logo/default_backgrounds');
        shuffle($default_backgrounds);
        $logo_theme_image = post_param_string('logo_theme_image', array_shift($default_logos));
        $background_theme_image = post_param_string('background_theme_image', array_shift($default_backgrounds));

        if ($installprofile != '') {
            // Run any specific code for the profile
            $object = mixed();
            if ((is_file(get_file_base() . '/sources/hooks/modules/admin_setupwizard_installprofiles/' . $installprofile . '.php')) || (is_file(get_file_base() . '/sources_custom/hooks/modules/admin_setupwizard_installprofiles/' . $installprofile . '.php'))) {
                require_code('hooks/modules/admin_setupwizard_installprofiles/' . $installprofile);
                $object = object_factory('Hook_admin_setupwizard_installprofiles_' . $installprofile, true);
            }
            if (!is_null($object)) {
                $object->install_code();
                $installprofileblocks = $object->default_blocks();
            } else { // Hmm, we probably just uninstalled the install-profile hook as its addon was not chosen! Whoopsie, but do our best.
                $installprofileblocks = array();
            }
        } else {
            $installprofileblocks = array();
        }

        if ((post_param_integer('skip_8', 0) == 0) && (function_exists('imagepng')) && (addon_installed('themewizard'))) {
            require_code('themewizard');

            // Make theme
            global $THEME_IMAGES_CACHE;
            $old_img_codes_site = $GLOBALS['SITE_DB']->query_select('theme_images', array('id', 'path'), array('theme' => $GLOBALS['FORUM_DRIVER']->get_theme(), 'lang' => user_lang()));
            if (!file_exists(get_custom_file_base() . '/themes/' . $theme)) {
                make_theme($theme, 'default', 'equations', post_param_string('seed_hex'), true, post_param_integer('dark', 0) == 1);
            }
            foreach (array($theme, 'default') as $logo_save_theme) {
                $logo = generate_logo($name, $font, $logo_theme_image, $background_theme_image, false, $logo_save_theme);
                $path = 'themes/' . $logo_save_theme . '/images_custom/-logo.png';
                if (!file_exists(get_custom_file_base() . '/' . dirname($path))) {
                    require_code('files2');
                    make_missing_directory(get_custom_file_base() . '/' . dirname($path));
                }
                cms_imagesave($logo, get_custom_file_base() . '/' . $path) or intelligent_write_error($path);
                actual_edit_theme_image('logo/-logo', $logo_save_theme, get_site_default_lang(), 'logo/-logo', $path, true);
                if (addon_installed('collaboration_zone')) {
                    actual_edit_theme_image('logo/collaboration-logo', $logo_save_theme, get_site_default_lang(), 'logo/collaboration-logo', $path, true);
                }
                imagedestroy($logo);
                $logo = generate_logo($name, $font, $logo_theme_image, $background_theme_image, false, $logo_save_theme, true);
                $path = 'themes/' . $logo_save_theme . '/images_custom/standalone_logo.png';
                cms_imagesave($logo, get_custom_file_base() . '/' . $path) or intelligent_write_error($path);
                actual_edit_theme_image('logo/standalone_logo', $logo_save_theme, get_site_default_lang(), 'logo/standalone_logo', $path, true);
                imagedestroy($logo);
            }
            $contents = '';
            $contents .= 'title=' . $name . "\n";
            $contents .= 'description=' . do_lang('NA') . "\n";
            $contents .= 'seed=' . post_param_string('seed_hex') . "\n";
            $contents .= 'author=Composr' . "\n";
            cms_file_put_contents_safe(get_custom_file_base() . '/themes/' . filter_naughty($theme) . '/theme.ini', $contents, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);
            $THEME_IMAGES_CACHE['site'] = $old_img_codes_site; // Just so it renders with the old theme
        }

        // Set options
        if (post_param_integer('skip_3', 0) == 0) {
            set_option('site_name', $name);
            set_option('copyright', 'Copyright &copy; ' . $name . ' ' . date('Y'));
            set_option('description', post_param_string('description'));
            set_option('site_scope', post_param_string('site_scope'));
            set_option('copyright', post_param_string('copyright'));
            set_option('staff_address', post_param_string('staff_address'));
            set_option('keywords', post_param_string('keywords'));
            set_option('google_analytics', post_param_string('google_analytics'));
            set_option('fixed_width', post_param_string('fixed_width', '0'));

            $a = $GLOBALS['SITE_DB']->query_select_value('zones', 'zone_header_text', array('zone_name' => ''));
            $GLOBALS['SITE_DB']->query_update('zones', lang_remap('zone_header_text', $a, $header_text), array('zone_name' => ''), '', 1);

            $b = $GLOBALS['SITE_DB']->query_select_value_if_there('zones', 'zone_header_text', array('zone_name' => 'site'));
            if (!is_null($b)) {
                $GLOBALS['SITE_DB']->query_update('zones', lang_remap('zone_header_text', $b, $header_text), array('zone_name' => 'site'), '', 1);
            }
        }

        if (post_param_integer('skip_9', 0) == 0) {
            set_option('site_closed', strval(post_param_integer('site_closed', 0)));
            set_option('closed', post_param_string('closed', ''));
        }

        // Set addons
        if ((post_param_integer('skip_4', 0) == 0) && (is_null($GLOBALS['CURRENT_SHARE_USER']))) {
            require_lang('addons');
            require_code('addons2');
            preload_all_ocproducts_addons_info();
            $addons_installed = find_installed_addons(false, true, true);
            $uninstalling = array();
            foreach ($addons_installed as $i => $addon_info) {
                if (post_param_integer('addon_' . $addon_info['name'], 0) == 0 && $addon_info['name'] != 'core' && substr($addon_info['name'], 0, 5) != 'core_') {
                    $uninstalling[$addon_info['name']] = $addon_info;
                }
            }
            $addons_not_installed = find_available_addons(false);
            $installing = array();
            foreach ($addons_not_installed as $addon_info) {
                if (post_param_integer('addon_' . $addon_info['name'], 0) == 1) {
                    $installing[] = $addon_info['name'];
                }
            }
            do {
                $cnt = count($uninstalling);
                foreach ($addons_installed as $addon_info) {
                    if (array_key_exists($addon_info['name'], $uninstalling)) {
                        $addon_info['author'] = ''; // Fudge, to stop it dying on warnings for official addons

                        // Check dependencies
                        $dependencies = isset($addon_info['dependencies_on_this']) ? $addon_info['dependencies_on_this'] : array();
                        foreach (array_keys($uninstalling) as $d) {
                            if (in_array($d, $dependencies)) {// Can mark this dependency as irrelevant, as we are uninstalling the addon for it anyway
                                unset($dependencies[array_search($d, $dependencies)]);
                            }
                        }

                        if (count($dependencies) != 0) { // Can't uninstall, has dependencies
                            unset($uninstalling[$addon_info['name']]);
                        }
                    }
                }
            } while ($cnt != count($uninstalling)); // Dependency chains can be complex, so loop until we're stopped finding anything changing

            if (!file_exists(get_file_base() . '/.git')) { // Only uninstall if we're not working from a git repository
                foreach ($uninstalling as $addon_info) {
                    // Archive it off to exports/addons
                    if ($addon_info['files'] != array()) {
                        $file = preg_replace('#^[\_\.\-]#', 'x', preg_replace('#[^\w\.\-]#', '_', $addon_info['name'])) . '.tar';
                        create_addon(
                            $file,
                            $addon_info['files'],
                            $addon_info['name'],
                            implode(',', $addon_info['incompatibilities']),
                            implode(',', $addon_info['dependencies']),
                            $addon_info['author'],
                            $addon_info['organisation'],
                            $addon_info['version'],
                            $addon_info['category'],
                            implode("\n", $addon_info['copyright_attribution']),
                            $addon_info['licence'],
                            $addon_info['description'],
                            'imports/addons'
                        );
                    }

                    uninstall_addon($addon_info['name']);
                }
            }
            foreach ($addons_not_installed as $addon_file => $addon_info) {
                if (post_param_integer('addon_' . $addon_info['name'], 0) == 1) {
                    // Check dependencies
                    $dependencies = explode(',', $addon_info['dependencies']);
                    foreach (array_keys($uninstalling) as $d) {
                        if ((addon_installed($d, true)) || (in_array($d, $installing))) {
                            unset($dependencies[array_search($d, $dependencies)]);
                        }
                    }

                    if (count($dependencies) == 0) { // If all dependencies installed / will be installed
                        install_addon($addon_file);
                    }
                }
            }
        }

        // Set features
        if (post_param_integer('skip_5', 0) == 0) {
            $hooks = find_all_hooks('modules', 'admin_setupwizard');
            foreach (array_keys($hooks) as $hook) {
                if ((post_param_integer('addon_' . $hook, 0) == 1) || ($hook == 'core')) {
                    $path = get_file_base() . '/sources_custom/hooks/modules/admin_setupwizard/' . filter_naughty_harsh($hook) . '.php';
                    if (!file_exists($path)) {
                        $path = get_file_base() . '/sources/hooks/modules/admin_setupwizard/' . filter_naughty_harsh($hook) . '.php';
                    }
                    $_hook_bits = extract_module_functions($path, array('set_fields'));
                    if (is_array($_hook_bits[0])) {
                        call_user_func_array($_hook_bits[0][0], $_hook_bits[0][1]);
                    } else {
                        @eval($_hook_bits[0]);
                    }
                }
            }
        }

        $collapse_zones = post_param_integer('collapse_user_zones', 0) == 1;

        // Rules
        if (post_param_integer('skip_7', 0) == 0) {
            $full_path = get_custom_file_base() . '/pages/comcode_custom/' . get_site_default_lang() . '/_rules.txt';
            if (file_exists($full_path)) {
                @copy($full_path, $full_path . '.' . strval(time()));
                fix_permissions($full_path . '.' . strval(time()));
                sync_file($full_path . '.' . strval(time()));
            }
            $rf = $this->get_rules_file(post_param_string('rules'));
            cms_file_put_contents_safe($full_path, $rf, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);
        }

        $block_options = mixed();
        if (($installprofile != '') && (!is_null($object))) {
            $block_options = $object->block_options();
        }

        // Blocks
        if (post_param_integer('skip_6', 0) == 0) {
            require_code('setupwizard');
            $page_structure = _get_zone_pages($installprofileblocks, $block_options, $collapse_zones, $installprofile);

            foreach ($page_structure as $zone => $zone_pages) {
                // Start
                $full_path = get_custom_file_base() . (($zone == '') ? '' : '/') . $zone . '/pages/comcode_custom/' . get_site_default_lang() . '/start.txt';
                if (file_exists($full_path)) {
                    @copy($full_path, $full_path . '.' . strval(time()));
                    fix_permissions($full_path . '.' . strval(time()));
                    sync_file($full_path . '.' . strval(time()));
                }
                cms_file_put_contents_safe($full_path, $zone_pages['start'], FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);

                // Left
                $full_path = get_custom_file_base() . (($zone == '') ? '' : '/') . $zone . '/pages/comcode_custom/' . get_site_default_lang() . '/panel_left.txt';
                if (file_exists($full_path)) {
                    @copy($full_path, $full_path . '.' . strval(time()));
                    fix_permissions($full_path . '.' . strval(time()));
                    sync_file($full_path . '.' . strval(time()));
                }
                cms_file_put_contents_safe($full_path, $zone_pages['left'], FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);

                // Right
                $full_path = get_custom_file_base() . (($zone == '') ? '' : '/') . $zone . '/pages/comcode_custom/' . get_site_default_lang() . '/panel_right.txt';
                if (file_exists($full_path)) {
                    @copy($full_path, $full_path . '.' . strval(time()));
                    fix_permissions($full_path . '.' . strval(time()));
                    sync_file($full_path . '.' . strval(time()));
                }
                cms_file_put_contents_safe($full_path, $zone_pages['right'], FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);
            }
        }

        decache('menu');

        // We're done
        set_value('setupwizard_completed', '1');

        $url = build_url(array('page' => '_SELF', 'type' => 'step11'), '_SELF');
        return redirect_screen($this->title, $url, do_lang_tempcode('SUCCESS'));
    }

    /**
     * Clear caches we want to clear to clean up.
     */
    private function clear_caching()
    {
        require_code('caches3');
        erase_comcode_page_cache();
        erase_block_cache(true);
        //persistent_cache_delete('OPTIONS');  Done by set_option
        erase_persistent_cache();
        erase_cached_templates(false, null, TEMPLATE_DECACHE_WITH_ANYTHING_INTERESTING);
    }

    /**
     * UI for a setup wizard step (done, message after cache emptied - need lower memory usage to rebuild them).
     *
     * @return Tempcode The UI
     */
    public function step11()
    {
        // Clear some caching
        $this->clear_caching();

        require_code('templates_donext');

        require_lang('zones');

        // Show nice interface to start adding pages
        return do_next_manager($this->title, do_lang_tempcode('SUCCESS'),
            array(
                array('menu/cms/comcode_page_edit', array('cms_comcode_pages', array('type' => 'edit'), get_module_zone('cms_comcode_pages')), do_lang('COMCODE_PAGE_ADD')),
                array('menu/start', array(null, array(), '')),
                array('menu/cms/cms', array(null, array(), 'cms')),
                array('menu/adminzone/adminzone', array(null, array(), 'adminzone')),
            ),
            do_lang('PAGES'),
            null, null, null, null, null, null, null, null, null, null, null, null, null, null,
            paragraph(do_lang_tempcode('SETUPWIZARD_10_DESCRIBE'))
        );
    }
}
