function asb_admin_custom_boxes()
{
    global $lang, $mybb, $db, $page, $html, $min;
    if ($mybb->input['mode'] == 'export') {
        if ((int) $mybb->input['id'] == 0) {
            flash_message($lang->asb_custom_export_error, 'error');
            admin_redirect($html->url(array("action" => 'custom_boxes')));
        }
        $this_custom = new Custom_type($mybb->input['id']);
        if (!$this_custom->is_valid()) {
            flash_message($lang->asb_custom_export_error, 'error');
            admin_redirect($html->url(array("action" => 'custom_boxes')));
        }
        $this_custom->export();
        exit;
    }
    if ($mybb->input['mode'] == 'delete') {
        // info good?
        if ((int) $mybb->input['id'] == 0) {
            flash_message($lang->asb_add_custom_box_delete_failure, 'error');
            admin_redirect($html->url(array("action" => 'custom_boxes')));
        }
        // nuke it
        $this_custom = new Custom_type($mybb->input['id']);
        // success?
        if (!$this_custom->remove()) {
            flash_message($lang->asb_add_custom_box_delete_failure, 'error');
            admin_redirect($html->url(array("action" => 'custom_boxes')));
        }
        // :)
        flash_message($lang->asb_add_custom_box_delete_success, 'success');
        asb_cache_has_changed();
        admin_redirect($html->url(array("action" => 'custom_boxes')));
    }
    // POSTing?
    if ($mybb->request_method == 'post') {
        if ($mybb->input['mode'] == 'import') {
            if (!$_FILES['file'] || $_FILES['file']['error'] == 4) {
                flash_message($lang->asb_custom_import_no_file, 'error');
                admin_redirect($html->url(array("action" => 'custom_boxes')));
            }
            if ($_FILES['file']['error']) {
                flash_message($lang->sprintf($lang->asb_custom_import_file_error, $_FILES['file']['error']), 'error');
                admin_redirect($html->url(array("action" => 'custom_boxes')));
            }
            if (!is_uploaded_file($_FILES['file']['tmp_name'])) {
                flash_message($lang->asb_custom_import_file_upload_error, 'error');
                admin_redirect($html->url(array("action" => 'custom_boxes')));
            }
            $contents = @file_get_contents($_FILES['file']['tmp_name']);
            @unlink($_FILES['file']['tmp_name']);
            if (!trim($contents)) {
                flash_message($lang->asb_custom_import_file_empty, 'error');
                admin_redirect($html->url(array("action" => 'custom_boxes')));
            }
            require_once MYBB_ROOT . 'inc/class_xml.php';
            $parser = new XMLParser($contents);
            $tree = $parser->get_tree();
            if (!is_array($tree) || empty($tree)) {
                flash_message($lang->asb_custom_import_file_empty, 'error');
                admin_redirect($html->url(array("action" => 'custom_boxes')));
            }
            if (!is_array($tree['asb_custom_sideboxes']) || empty($tree['asb_custom_sideboxes'])) {
                if (!is_array($tree['adv_sidebox']) || !is_array($tree['adv_sidebox']['custom_sidebox'])) {
                    flash_message($lang->asb_custom_import_file_empty, 'error');
                    admin_redirect($html->url(array("action" => 'custom_boxes')));
                }
                $results = asb_legacy_custom_import($tree);
                if (!is_array($results)) {
                    flash_message($results, 'error');
                    admin_redirect($html->url(array("action" => 'custom_boxes')));
                }
                $custom = new Custom_type($results);
            } else {
                $custom = new Custom_type();
                if (!$custom->import($contents)) {
                    flash_message($lang->asb_custom_import_fail_generic, 'error');
                    admin_redirect($html->url(array("action" => 'custom_boxes')));
                }
            }
            if (!$custom->save()) {
                flash_message($lang->asb_custom_box_save_failure, 'error');
                admin_redirect($html->url(array("action" => 'custom_boxes')));
            }
            flash_message($lang->asb_custom_import_save_success, 'success');
            admin_redirect($html->url(array("action" => 'custom_boxes', "id" => $custom->get('id'))));
        } else {
            // saving?
            if ($mybb->input['save_box_submit'] == 'Save') {
                if (!$mybb->input['box_name'] || !$mybb->input['box_content']) {
                    flash_message($lang->asb_custom_box_save_failure_no_content, 'error');
                    admin_redirect($html->url(array("action" => 'custom_boxes')));
                }
                $this_custom = new Custom_type((int) $mybb->input['id']);
                // get the info
                $this_custom->set('title', $mybb->input['box_name']);
                $this_custom->set('description', $mybb->input['box_description']);
                $this_custom->set('content', $mybb->input['box_content']);
                $this_custom->set('wrap_content', $mybb->input['wrap_content'] == 'yes');
                // success?
                if (!$this_custom->save()) {
                    flash_message($lang->asb_custom_box_save_failure, 'error');
                    admin_redirect($html->url(array("action" => 'custom_boxes', "id" => $this_custom->get('id'))));
                }
                flash_message($lang->asb_custom_box_save_success, 'success');
                asb_cache_has_changed();
                admin_redirect($html->url(array("action" => 'custom_boxes', "id" => $this_custom->get('id'))));
            }
        }
    }
    $page->add_breadcrumb_item($lang->asb, $html->url());
    if ($mybb->input['mode'] == 'edit') {
        $queryadmin = $db->simple_select('adminoptions', '*', "uid='{$mybb->user['uid']}'");
        $admin_options = $db->fetch_array($queryadmin);
        if ($admin_options['codepress'] != 0) {
            $page->extra_header .= <<<EOF
\t<link type="text/css" href="./jscripts/codepress/languages/codepress-mybb.css" rel="stylesheet" id="cp-lang-style"/>
\t<script type="text/javascript" src="./jscripts/codepress/codepress.js"></script>
\t<script type="text/javascript">
\t<!--
\t\tCodePress.language = 'mybb';
\t// -->
\t</script>
EOF;
        }
        $this_box = new Custom_type((int) $mybb->input['id']);
        $action = $lang->asb_add_custom;
        if ($this_box->get('id')) {
            $specify_box = '&amp;id=' . $this_box->get('id');
            $currently_editing = $lang->asb_editing . ': <strong>' . $this_box->get('title') . '</strong>';
            $action = $lang->asb_edit . ' ' . $this_box->get('title');
        } else {
            // new box
            $specify_box = '';
            $sample_content = <<<EOF
<tr>
\t\t<td class="trow1">{$lang->asb_sample_content_line1} (HTML)</td>
\t</tr>
\t<tr>
\t\t<td class="trow2">{$lang->asb_sample_content_line2}</td>
\t</tr>
\t<tr>
\t\t<td class="trow1"><strong>{$lang->asb_sample_content_line3}</td>
\t</tr>
EOF;
            $this_box->set('content', $sample_content);
            $this_box->set('wrap_content', true);
        }
        $page->extra_header .= <<<EOF
\t<link rel="stylesheet" type="text/css" href="styles/asb_acp.css" media="screen" />
\t<script src="jscripts/asb/asb{$min}.js" type="text/javascript"></script>
EOF;
        $page->add_breadcrumb_item($lang->asb_custom_boxes, $html->url(array("action" => 'custom_boxes')));
        $page->add_breadcrumb_item($lang->asb_add_custom);
        $page->output_header("{$lang->asb} - {$action}");
        asb_output_tabs('asb_add_custom');
        $form = new Form($html->url(array("action" => 'custom_boxes')) . $specify_box, 'post', 'edit_box');
        $form_container = new FormContainer($currently_editing);
        $form_container->output_cell($lang->asb_name);
        $form_container->output_cell($lang->asb_description);
        $form_container->output_cell($lang->asb_custom_box_wrap_content);
        $form_container->output_row('');
        // name
        $form_container->output_cell($form->generate_text_box('box_name', $this_box->get('title'), array("id" => 'box_name')));
        // description
        $form_container->output_cell($form->generate_text_box('box_description', $this_box->get('description')));
        // wrap content?
        $form_container->output_cell($form->generate_check_box('wrap_content', 'yes', $lang->asb_custom_box_wrap_content_desc, array("checked" => $this_box->get('wrap_content'))));
        $form_container->output_row('');
        $form_container->output_cell('Content:', array("colspan" => 3));
        $form_container->output_row('');
        // content
        $form_container->output_cell($form->generate_text_area('box_content', $this_box->get('content'), array("id" => 'box_content', 'class' => 'codepress mybb', 'style' => 'width: 100%; height: 240px;')), array("colspan" => 3));
        $form_container->output_row('');
        // finish form
        $form_container->end();
        $buttons[] = $form->generate_submit_button('Save', array('name' => 'save_box_submit'));
        $form->output_submit_wrapper($buttons);
        $form->end();
        if ($admin_options['codepress'] != 0) {
            echo <<<EOF
\t\t<script type="text/javascript">
\t\t<!--
\t\t\tEvent.observe('edit_box', 'submit', function() {
\t\t\t\tif (\$('box_content_cp')) {
\t\t\t\t\tvar area = \$('box_content_cp');
\t\t\t\t\tarea.id = 'box_content';
\t\t\t\t\tarea.value = box_content.getCode();
\t\t\t\t\tarea.disabled = false;
\t\t\t\t}
\t\t\t});
\t\t// -->
\t\t</script>
EOF;
            // build link bar and ACP footer
            asb_output_footer('edit_custom');
        }
    }
    $page->extra_header .= <<<EOF
\t<link rel="stylesheet" type="text/css" href="styles/asb_acp.css" media="screen" />
\t<script src="jscripts/asb/asb{$min}.js" type="text/javascript"></script>
EOF;
    $page->add_breadcrumb_item($lang->asb_custom_boxes);
    $page->output_header("{$lang->asb} - {$lang->asb_custom_boxes}");
    asb_output_tabs('asb_custom');
    $new_box_url = $html->url(array("action" => 'custom_boxes', "mode" => 'edit'));
    $new_box_link = $html->link($new_box_url, $lang->asb_add_custom_box_types, array("style" => 'font-weight: bold;', "title" => $lang->asb_add_custom_box_types, "icon" => "{$mybb->settings['bburl']}/inc/plugins/asb/images/add.png"), array("alt" => '+', "style" => 'margin-bottom: -3px;', "title" => $lang->asb_add_custom_box_types));
    echo $new_box_link . '<br /><br />';
    $table = new Table();
    $table->construct_header($lang->asb_name);
    $table->construct_header($lang->asb_custom_box_desc);
    $table->construct_header($lang->asb_controls, array("colspan" => 2));
    $custom = asb_get_all_custom();
    // if there are saved types . . .
    if (is_array($custom) && !empty($custom)) {
        // display them
        foreach ($custom as $this_custom) {
            $data = $this_custom->get('data');
            // name (edit link)
            $edit_url = $html->url(array("action" => 'custom_boxes', "mode" => 'edit', "id" => $data['id']));
            $edit_link = $html->link($edit_url, $data['title'], array("title" => $lang->asb_edit, "style" => 'font-weight: bold;'));
            $table->construct_cell($edit_link, array("width" => '30%'));
            // description
            if ($data['description']) {
                $description = $data['description'];
            } else {
                $description = "<em>{$lang->asb_no_description}</em>";
            }
            $table->construct_cell($description, array("width" => '60%'));
            // options popup
            $popup = new PopupMenu('box_' . $data['id'], $lang->asb_options);
            // edit
            $popup->add_item($lang->asb_edit, $edit_url);
            // delete
            $popup->add_item($lang->asb_delete, $html->url(array("action" => 'custom_boxes', "mode" => 'delete', "id" => $data['id'])), "return confirm('{$lang->asb_custom_del_warning}');");
            // export
            $popup->add_item($lang->asb_custom_export, $html->url(array("action" => 'custom_boxes', "mode" => 'export', "id" => $data['id'])));
            // popup cell
            $table->construct_cell($popup->fetch(), array("width" => '10%'));
            // finish the table
            $table->construct_row();
        }
    } else {
        // no saved types
        $table->construct_cell($lang->asb_no_custom_boxes, array("colspan" => 4));
        $table->construct_row();
    }
    $table->output($lang->asb_custom_box_types);
    echo '<br /><br />';
    $import_form = new Form($html->url(array("action" => 'custom_boxes', "mode" => 'import')), 'post', '', 1);
    $import_form_container = new FormContainer($lang->asb_custom_import);
    $import_form_container->output_row($lang->asb_custom_import_select_file, '', $import_form->generate_file_upload_box('file'));
    $import_form_container->end();
    $import_buttons[] = $import_form->generate_submit_button($lang->asb_custom_import, array('name' => 'import'));
    $import_form->output_submit_wrapper($import_buttons);
    $import_form->end();
    // build link bar and ACP footer
    asb_output_footer('custom');
}
function asb_start()
{
    global $mybb, $theme;
    // side box, add-on and custom box classes
    require_once MYBB_ROOT . 'inc/plugins/asb/classes/forum.php';
    // don't waste execution if unnecessary
    if (!asb_do_checks()) {
        return;
    }
    $asb = asb_get_cache();
    $this_script = asb_get_this_script($asb, true);
    // no boxes, get out
    if (!is_array($this_script['sideboxes']) || empty($this_script['sideboxes']) || empty($this_script['sideboxes'][0]) && empty($this_script['sideboxes'][1]) || strlen($this_script['find_top']) == 0 || strlen($this_script['find_bottom']) == 0) {
        return;
    }
    $width = $boxes = array(0 => '', 1 => '');
    // make sure this script's width is within range 120-800 (120 because the templates
    // aren't made to work any smaller and tbh 800 is kind of arbitrary :s
    foreach (array("left" => 0, "right" => 1) as $key => $pos) {
        $width[$pos] = (int) max(120, min(800, $this_script["width_{$key}"]));
    }
    // does this column have boxes?
    if (!is_array($this_script['sideboxes']) || empty($this_script['sideboxes'])) {
        return;
    }
    // functions for add-on modules
    require_once MYBB_ROOT . 'inc/plugins/asb/functions_addon.php';
    // loop through all the boxes for the script
    foreach ($this_script['sideboxes'] as $pos => $sideboxes) {
        // does this column have boxes?
        if (!is_array($sideboxes) || empty($sideboxes)) {
            continue;
        }
        // loop through them
        foreach ($sideboxes as $id => $module_name) {
            // verify that the box ID exists
            if (!isset($asb['sideboxes'][$id])) {
                continue;
            }
            // then load the object
            $sidebox = new Sidebox($asb['sideboxes'][$id]);
            // can the user view this side box?
            if (!asb_check_user_permissions($sidebox->get('groups'))) {
                continue;
            }
            // is this theme available for this side box?
            $good_themes = $sidebox->get('themes');
            if ($good_themes && !in_array($theme['tid'], $good_themes)) {
                continue;
            }
            $result = false;
            // get the template variable
            $template_var = "{$module_name}_{$id}";
            // attempt to load the box as an add-on module
            $module = new Addon_type($module_name);
            // if it is valid, then the side box was created using an
            // add-on module, so we can proceed
            if ($module->is_valid()) {
                // build the template. pass settings, template variable
                // name and column width
                $result = $module->build_template($sidebox->get('settings'), $template_var, $width[$pos], get_current_location());
            } elseif (isset($asb['custom'][$module_name]) && is_array($asb['custom'][$module_name])) {
                $custom = new Custom_type($asb['custom'][$module_name]);
                // if it validates, then build it, otherwise there was an error
                if ($custom->is_valid()) {
                    // build the custom box template
                    $result = $custom->build_template($template_var);
                }
            } else {
                continue;
            }
            /*
             * all box types return true or false based upon whether they have
             * content to show. in the case of custom boxes, false is returned
             * when the custom content is empty; in reference to add-on modules
             * many factors are involved, but basically, if the side box depends on
             * an element (threads for example) and there are none, it will return
             * false-- IF asb_show_empty_boxes is true then it will return a side
             * box with a 'no content' message, if not, it will be skipped
             */
            if ($result || $mybb->settings['asb_show_empty_boxes']) {
                $boxes[$pos] .= asb_build_sidebox_content($sidebox->get('data'));
            }
        }
    }
    // load the template handler class definition and make the edits
    require_once MYBB_ROOT . 'inc/plugins/asb/classes/template_handler.php';
    ASBTemplateHandler::edit($boxes, $width, $this_script);
}