function ign_useCustomDbForm()
{
    global $ign_user_db, $prefs;
    extract(lAtts(array('ign_use_custom' => '', 'ign_fallback' => ''), $prefs, 0));
    if (isset($_POST['ign_use_custom'])) {
        $ign_use_custom = $_POST['ign_use_custom'];
    } else {
        $ign_use_custom = empty($ign_use_custom) ? '0' : $ign_use_custom;
    }
    return n . '<div style="margin: 3em auto auto auto; width: 40em; text-align: center;">' . n . n . form(n . eInput('ign_user_mgmt') . n . sInput('ign_update_prefs') . ign_gTxt('user_db') . br . yesnoRadio('ign_use_custom', $ign_use_custom) . br . ign_gTxt('fallback') . ign_checkbox(array('name' => 'fallback', 'checked' => 'true')) . br . n . fInput('submit', 'ign_update_prefs', 'Update', 'smallerbox')) . n . '</div>';
}
Exemple #2
0
/**
 * Renders a HTML choice for whether Daylight Savings Time is in effect.
 *
 * Can be altered by plugins via the 'prefs_ui > is_dst'
 * pluggable UI callback event.
 *
 * @param  string $name HTML name of the widget
 * @param  string $val  Initial (or current) selected item
 * @return string HTML
 */
function is_dst($name, $val)
{
    $ui = yesnoRadio($name, $val) . script_js(<<<EOS
        \$(document).ready(function ()
        {
            var radio = \$("#prefs-is_dst input");
            if (radio) {
                if (\$("#auto_dst-1").prop("checked")) {
                    radio.prop("disabled", "disabled");
                }

                \$("#auto_dst-0").click(function () {
                    radio.removeProp("disabled");
                });

                \$("#auto_dst-1").click(function () {
                    radio.prop("disabled", "disabled");
                });
            }
        });
EOS
);
    return pluggable_ui('prefs_ui', 'is_dst', $ui, $name, $val);
}
Exemple #3
0
function section_multiedit_form($page, $sort, $dir, $crit, $search_method)
{
    global $all_pages, $all_styles;
    $methods = array('changepage' => array('label' => gTxt('uses_page'), 'html' => selectInput('uses_page', $all_pages, '', false)), 'changecss' => array('label' => gTxt('uses_style'), 'html' => selectInput('css', $all_styles, '', false)), 'changeonfrontpage' => array('label' => gTxt('on_front_page'), 'html' => yesnoRadio('on_frontpage', 1)), 'changesyndicate' => array('label' => gTxt('syndicate'), 'html' => yesnoRadio('in_rss', 1)), 'changesearchable' => array('label' => gTxt('include_in_search'), 'html' => yesnoRadio('searchable', 1)), 'delete' => gTxt('delete'));
    return multi_edit($methods, 'section', 'section_multi_edit', $page, $sort, $dir, $crit, $search_method);
}
Exemple #4
0
 function prefs($event, $step)
 {
     pagetop('hak_tinymce ' . gTxt('preferences'), $step == 'update' ? gTxt('preferences_saved') : '');
     if ($step == 'install') {
         // Install the preferences table.
         hak_tinymce::install();
     }
     if ($step == 'uninstall') {
         //remove table
         safe_query("DROP TABLE " . PFX . "txp_hak_tinymce");
     }
     if ($step == 'update') {
         extract(doSlash(gpsa(array('hak_show_toggle', 'hak_hide_on_textile_edit', 'hak_tinymce_path', 'hak_tinymce_body_init', 'hak_tinymce_excerpt_init', 'hak_tinymce_callbacks', 'hak_hide_textile_select', 'hak_enable_body', 'hak_enable_excerpt', 'hak_use_compressor', 'hak_tinymce_compressor_init'))));
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_show_toggle}'", "pref_name = 'show_toggle'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_hide_on_textile_edit}'", "pref_name = 'hide_on_textile_edit'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_tinymce_path}'", "pref_name = 'tinymce_path'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_tinymce_body_init}'", "pref_name = 'body_init'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_tinymce_excerpt_init}'", "pref_name = 'excerpt_init'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_tinymce_callbacks}'", "pref_name = 'callbacks'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_hide_textile_select}'", "pref_name = 'hide_textile_select'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_enable_body}'", "pref_name = 'enable_body'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_enable_excerpt}'", "pref_name = 'enable_excerpt'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_use_compressor}'", "pref_name = 'use_compressor'");
         safe_update('txp_hak_tinymce', "pref_value = '{$hak_tinymce_compressor_init}'", "pref_name = 'compressor_init'");
     }
     if (hak_tinymce::check_install()) {
         extract(hak_tinymce::getPrefs());
         echo n . t . '<div style="margin: auto; width:40%;">' . n . t . t . hed('hak_tinymce ' . gTxt('Preferences'), '1') . n . n . form(n . eInput('hak_tinymce_prefs') . n . sInput('update') . n . fInput('submit', 'update', 'Update', 'smallerbox') . n . graf(hak_tinymce::mce_gTxt('hak_show_toggle') . br . n . yesnoRadio('hak_show_toggle', $show_toggle) . br . n . tag(tag(hak_tinymce::mce_gTxt('auto_disable'), "em"), "small")) . n . graf(hak_tinymce::mce_gTxt('hak_hide_on_textile_edit') . br . n . yesnoRadio('hak_hide_on_textile_edit', $hide_on_textile_edit)) . n . graf(hak_tinymce::mce_gTxt('hak_hide_textile_select') . br . n . yesnoRadio('hak_hide_textile_select', $hide_textile_select)) . n . graf(hak_tinymce::mce_gTxt('hak_tinymce_path') . br . n . finput('text', 'hak_tinymce_path', $tinymce_path, '', '', '', 60, '', 'hak_tinymce_path') . hak_tinymce::file_exists($tinymce_path)) . n . graf(hak_tinymce::mce_gTxt('enable_body') . br . n . yesnoRadio('hak_enable_body', $enable_body)) . n . graf(hak_tinymce::mce_gTxt('hak_tinymce_body_init') . br . tag(tag("(" . hak_tinymce::mce_gTxt('line_end') . ")", "em"), "small") . n . href(hak_tinymce::mce_gTxt('documentation'), "http://tinymce.moxiecode.com/documentation.php") . br . n . text_area('hak_tinymce_body_init', 200, 400, $body_init)) . n . graf(hak_tinymce::mce_gTxt('enable_excerpt') . br . n . yesnoRadio('hak_enable_excerpt', $enable_excerpt)) . n . graf(hak_tinymce::mce_gTxt('hak_tinymce_excerpt_init') . br . tag(tag("(" . hak_tinymce::mce_gTxt('line_end') . ")", "em"), "small") . n . href(hak_tinymce::mce_gTxt('documentation'), "http://tinymce.moxiecode.com/documentation.php") . br . n . text_area('hak_tinymce_excerpt_init', 200, 400, $excerpt_init)) . n . graf(hak_tinymce::mce_gTxt('hak_tinymce_callbacks') . br . n . text_area('hak_tinymce_callbacks', 200, 400, $callbacks)) . n . graf(hak_tinymce::mce_gTxt('use_compressor') . br . n . yesnoRadio('hak_use_compressor', $use_compressor) . hak_tinymce::file_exists(hak_compressor_path($tinymce_path), "compressor_not_found")) . n . graf(hak_tinymce::mce_gTxt('hak_tinymce_compressor_init') . br . tag(tag("(" . hak_tinymce::mce_gTxt('compressor_line_end') . ")", "em"), "small") . n . href(hak_tinymce::mce_gTxt('documentation'), "http://wiki.moxiecode.com/index.php/TinyMCE:Compressor/PHP") . br . n . text_area('hak_tinymce_compressor_init', 200, 400, $compressor_init)) . n . n . fInput('submit', 'update', 'Update', 'smallerbox')) . '</div>';
         echo n . t . '<div style="margin: 60px auto 0; width:40%;">' . n . hed(hak_tinymce::mce_gTxt('uninstall'), '1') . n . t . t . graf(hak_tinymce::mce_gTxt('uninstall_message')) . n . n . form(n . eInput('hak_tinymce_prefs') . n . sInput('uninstall') . n . n . fInput('submit', 'uninstall', 'Uninstall ', 'smallerbox'), "", "confirm('" . hak_tinymce::mce_gTxt('uninstall_confirm') . "')") . '</div>';
     } else {
         echo n . t . '<div style="margin: auto; width:40%;">' . n . t . t . hed('hak_tinymce ' . gTxt('Preferences'), '1') . n . graf(hak_tinymce::mce_gTxt('install_message')) . n . n . form(n . eInput('hak_tinymce_prefs') . n . sInput('install') . n . n . fInput('submit', 'install', 'Install ', 'smallerbox')) . '</div>';
     }
 }
Exemple #5
0
function is_dst($name, $val)
{
    $ui = yesnoRadio($name, $val) . n . script_js("textpattern.timezone_is_supported = " . (int) timezone::is_supported() . ";") . script_js(<<<EOS
\t\t\t\$(document).ready(function(){
\t\t\t\tvar radio = \$("#prefs-is_dst input");
\t\t\t\tif (radio) {
\t\t\t\t\tif (\$("#auto_dst-1").attr("checked") && textpattern.timezone_is_supported) {
\t\t\t\t\t\tradio.attr("disabled","disabled");
\t\t\t\t\t}
\t\t\t\t\t\$("#auto_dst-0").click(
\t\t\t\t\t\tfunction(){
\t\t\t\t\t\t\tradio.removeAttr("disabled");
\t\t\t\t\t\t});
\t\t\t\t   \t\$("#auto_dst-1").click(
\t\t\t\t\t\tfunction(){
\t\t\t\t\t\t\tradio.attr("disabled","disabled");
\t\t\t\t\t  \t});
\t\t\t   \t}
\t\t\t\tif (!textpattern.timezone_is_supported) {
\t\t\t\t\t\$("#prefs-auto_dst input").attr("disabled","disabled");
\t\t\t\t}
\t});
EOS
);
    return pluggable_ui('prefs_ui', 'is_dst', $ui, $name, $val);
}
 /**
  * Render single preference row
  * @param  array $pref preference array
  * @return string      <tr> containing the preference
  */
 private function render_pref($id, $pref)
 {
     $value = $this->get_pref($id);
     $id = $this->prefix($id);
     // render label
     $out = fLabelCell(gTxt($pref['label']), '', $id);
     // render field
     switch ($pref['type']) {
         case 2:
             $out .= td(selectInput($id, array(gTxt('None') => '', 'EXIF' => 'exif', 'IPTC' => 'iptc'), $value));
             break;
         case 1:
             $out .= td(yesnoRadio($id, $value));
             break;
         default:
             $out .= fInputCell($id, $value, '', 20, '', $id);
             break;
     }
     // render help
     $out .= td(gTxt($pref['descr']));
     // render save
     return tr($out);
 }
 function option_has_options($step)
 {
     return graf(gTxt('gbp_adlib_wiz-step_complex_txt', array('{step}' => $step))) . yesnoRadio('wizard_has_options_test', 1);
 }
function rss_db_bk($event, $step)
{
    global $prefs, $rss_dbbk_path, $rss_dbbk_dump, $rss_dbbk_mysql, $rss_dbbk_lock, $rss_dbbk_txplog, $rss_dbbk_debug, $DB, $file_base_path;
    if (!isset($rss_dbbk_lock)) {
        $rss_dbbk_lock = "1";
        $rs = safe_insert('txp_prefs', "name='rss_dbbk_lock', val='{$rss_dbbk_lock}', prefs_id='1'");
    }
    if (!isset($rss_dbbk_txplog)) {
        $rss_dbbk_txplog = "1";
        $rs = safe_insert('txp_prefs', "name='rss_dbbk_txplog', val='{$rss_dbbk_txplog}', prefs_id='1'");
    }
    if (!isset($rss_dbbk_debug)) {
        $rss_dbbk_debug = "0";
        $rs = safe_insert('txp_prefs', "name='rss_dbbk_debug', val='{$rss_dbbk_debug}', prefs_id='1'");
    }
    if (!isset($rss_dbbk_path)) {
        $rss_dbbk_path = $file_base_path;
        $rs = safe_insert('txp_prefs', "name='rss_dbbk_path', val='" . addslashes($rss_dbbk_path) . "', prefs_id='1'");
    }
    if (!isset($rss_dbbk_dump)) {
        $rss_dbbk_dump = "mysqldump";
        $rs = safe_insert('txp_prefs', "name='rss_dbbk_dump', val='" . addslashes($rss_dbbk_dump) . "', prefs_id='1'");
    }
    if (!isset($rss_dbbk_mysql)) {
        $rss_dbbk_mysql = "mysql";
        $rs = safe_insert('txp_prefs', "name='rss_dbbk_mysql', val='" . addslashes($rss_dbbk_mysql) . "', prefs_id='1'");
    }
    include txpath . '/include/txp_prefs.php';
    $bkpath = $rss_dbbk_path;
    $iswin = preg_match('/Win/', php_uname());
    $mysql_hup = ' -h' . $DB->host . ' -u' . $DB->user . ' -p' . escapeshellcmd($DB->pass);
    $txplogps = ps('rss_dbbk_txplog');
    if (ps("save")) {
        pagetop("DB Manager", "Preferences Saved");
        safe_update("txp_prefs", "val = '" . addslashes(ps('rss_dbbk_path')) . "'", "name = 'rss_dbbk_path' and prefs_id ='1'");
        safe_update("txp_prefs", "val = '" . addslashes(ps('rss_dbbk_dump')) . "'", "name = 'rss_dbbk_dump' and prefs_id ='1'");
        safe_update("txp_prefs", "val = '" . addslashes(ps('rss_dbbk_mysql')) . "'", "name = 'rss_dbbk_mysql' and prefs_id ='1'");
        safe_update("txp_prefs", "val = '" . ps('rss_dbbk_lock') . "'", "name = 'rss_dbbk_lock' and prefs_id ='1'");
        if (isset($txplogps)) {
            safe_update("txp_prefs", "val = '" . ps('rss_dbbk_txplog') . "'", "name = 'rss_dbbk_txplog' and prefs_id ='1'");
        }
        safe_update("txp_prefs", "val = '" . ps('rss_dbbk_debug') . "'", "name = 'rss_dbbk_debug' and prefs_id ='1'");
        header("Location: index.php?event=rss_db_bk");
    } else {
        if (gps("bk")) {
            $bk_table = gps("bk_table") ? " --tables " . gps("bk_table") . " " : "";
            $tabpath = gps("bk_table") ? "-" . gps("bk_table") : "";
            $gzip = gps("gzip");
            $filename = time() . '-' . $DB->db . $tabpath;
            $backup_path = $bkpath . '/' . $filename . '.sql';
            $lock = $rss_dbbk_lock ? "" : " --skip-lock-tables --skip-add-locks ";
            echo $txplogps;
            $nolog = $rss_dbbk_txplog ? "" : " --ignore-table=" . $DB->db . ".txp_log ";
            $nolog = isset($bk_table) && gps("bk_table") == "txp_log" ? "" : $nolog;
            if ($gzip) {
                $backup_path .= '.gz';
                $backup_cmd = $rss_dbbk_dump . $mysql_hup . ' -Q --add-drop-table ' . $lock . $nolog . $DB->db . $bk_table . ' | gzip > ' . $backup_path;
            } else {
                $backup_cmd = $rss_dbbk_dump . $mysql_hup . ' -Q --add-drop-table ' . $lock . $nolog . $DB->db . $bk_table . ' > ' . $backup_path;
            }
            $bkdebug = $rss_dbbk_debug ? $backup_cmd : '';
            $error = "";
            if (function_exists('passthru')) {
                passthru($backup_cmd, $error);
            } else {
                $dumpIt = popen($backup_cmd, 'r');
                pclose($dumpIt);
            }
            if (!is_writable($bkpath)) {
                pagetop("DB Manager", "BACKUP FAILED: folder is not writable");
            } elseif ($error) {
                unlink($backup_path);
                pagetop("DB Manager", "BACKUP FAILED.  ERROR NO: " . $error);
            } else {
                if (!is_file($backup_path)) {
                    pagetop("DB Manager", "BACKUP FAILED.  ERROR NO: " . $error);
                } else {
                    if (filesize($backup_path) == 0) {
                        unlink($backup_path);
                        pagetop("DB Manager", "BACKUP FAILED.  ERROR NO: " . $error);
                    } else {
                        pagetop("DB Manager", "Backed Up: " . $DB->db . " to " . $filename);
                    }
                }
            }
        } else {
            if (gps("download")) {
                $fn = gps("download");
                $file_path = $bkpath . '/' . $fn;
                header("Pragma: public");
                header("Expires: 0");
                header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                header("Content-Type: application/force-download");
                header("Content-Type: application/octet-stream");
                header("Content-Type: application/download");
                if (substr($fn, -2) == "gz") {
                    header("Content-Type: application/zip");
                }
                header("Content-Disposition: attachment; filename=" . basename($file_path) . ";");
                header("Content-Transfer-Encoding: binary");
                header("Content-Length: " . filesize($file_path));
                @readfile($file_path);
            } else {
                if (gps("restore")) {
                    if (stristr(gps("restore"), '.gz')) {
                        $backup_cmd = 'gunzip < ' . $bkpath . '/' . gps("restore") . ' | ' . $rss_dbbk_mysql . $mysql_hup . ' ' . $DB->db;
                    } else {
                        $backup_cmd = $rss_dbbk_mysql . $mysql_hup . ' ' . $DB->db . ' < ' . $bkpath . '/' . gps("restore");
                    }
                    $bkdebug = $rss_dbbk_debug ? $backup_cmd : '';
                    $error = "";
                    if (function_exists('passthru')) {
                        passthru($backup_cmd, $error);
                    } else {
                        $dumpIt = popen($backup_cmd, 'r');
                        pclose($dumpIt);
                    }
                    if ($error) {
                        pagetop("DB Manager", "FAILED TO RESTORE: " . $error);
                    } else {
                        pagetop("DB Manager", "Restored: " . gps("restore") . " to " . $DB->db);
                    }
                } else {
                    if (gps("delete")) {
                        if (is_file($bkpath . '/' . gps("delete"))) {
                            if (!unlink($bkpath . '/' . gps("delete"))) {
                                pagetop("DB Manager", "Unable to Delete: " . gps("delete"));
                            } else {
                                pagetop("DB Manager", "Deleted: " . gps("delete"));
                            }
                        } else {
                            pagetop("DB Manager", "Unable to Delete: " . gps("delete"));
                        }
                    } else {
                        pagetop("DB Backup");
                    }
                }
            }
        }
    }
    $gzp = !$iswin ? " | " . href('gzipped file', "index.php?event=rss_db_bk&amp;bk={$DB->db}&amp;gzip=1") : "";
    $sqlversion = getRow("SELECT VERSION() AS version");
    $sqlv = explode("-", $sqlversion['version']);
    $allownologs = (double) $sqlv[0] >= (double) "4.1.9" ? tda(gTxt('Include txp_log:'), ' style="text-align:right;vertical-align:middle"') . tda(yesnoRadio("rss_dbbk_txplog", $rss_dbbk_txplog), ' style="text-align:left;vertical-align:middle"') : '';
    if (isset($bkdebug) && $bkdebug) {
        echo '<p align="center">' . $bkdebug . '</p>';
    }
    echo startTable('list') . form(tr(tda(gTxt('Lock Tables:'), ' style="text-align:right;vertical-align:middle"') . tda(yesnoRadio("rss_dbbk_lock", $rss_dbbk_lock), ' style="text-align:left;vertical-align:middle"') . $allownologs . tda(gTxt('Debug Mode:'), ' style="text-align:right;vertical-align:middle"') . tda(yesnoRadio("rss_dbbk_debug", $rss_dbbk_debug), ' style="text-align:left;vertical-align:middle"') . tda(fInput("submit", "save", gTxt("save_button"), "publish") . eInput("rss_db_bk") . sInput('saveprefs'), " colspan=\"2\" class=\"noline\"")) . tr(tda(gTxt('Backup Path:'), ' style="text-align:right;vertical-align:middle"') . tda(text_input("rss_dbbk_path", $rss_dbbk_path, '50'), ' colspan="15"')) . tr(tda(gTxt('mysqldump Path:'), ' style="text-align:right;vertical-align:middle"') . tda(text_input("rss_dbbk_dump", $rss_dbbk_dump, '50'), ' colspan="15"')) . tr(tda(gTxt('mysql Path:'), ' style="text-align:right;vertical-align:middle"') . tda(text_input("rss_dbbk_mysql", $rss_dbbk_mysql, '50'), ' colspan="15"'))) . endTable() . startTable("list") . tr(tda(hed('Create a new backup of the ' . $DB->db . ' database' . br . href('.sql file', "index.php?event=rss_db_bk&amp;bk={$DB->db}") . $gzp, 3), ' colspan="7" style="text-align:center;"')) . tr(tdcs(hed("Previous Backup Files", 1), 7)) . tr(hcell("No.") . hcell("Backup File Name") . hcell("Backup Date/Time") . hcell("Backup File Size") . hcell("") . hcell("") . hcell(""));
    $totalsize = 0;
    $no = 0;
    if (!is_folder_empty($bkpath)) {
        if ($handle = opendir($bkpath)) {
            $database_files = array();
            while (false !== ($file = readdir($handle))) {
                if ($file != '.' && $file != '..' && (substr($file, -4) == ".sql" || substr($file, -7) == ".sql.gz")) {
                    $database_files[] = $file;
                }
            }
            closedir($handle);
            for ($i = sizeof($database_files) - 1; $i > -1; $i--) {
                $no++;
                $style = $no % 2 == 0 ? ' style="background-color: #eee;"' : '';
                $database_text = substr($database_files[$i], 11);
                $date_text = strftime("%A, %B %d, %Y [%H:%M:%S]", substr($database_files[$i], 0, 10));
                $size_text = filesize($bkpath . '/' . $database_files[$i]);
                $totalsize += $size_text;
                echo tr(td($no) . td($database_text) . td($date_text) . td(prettyFileSize($size_text)) . '<td><a href="index.php?event=rss_db_bk&amp;download=' . $database_files[$i] . '">Download</a></td>' . '<td><a href="index.php?event=rss_db_bk&amp;restore=' . $database_files[$i] . '"  onclick="return verify(\'' . gTxt('are_you_sure') . '\')">Restore</a></td>' . '<td><a href="index.php?event=rss_db_bk&amp;delete=' . $database_files[$i] . '"  onclick="return verify(\'' . gTxt('are_you_sure') . '\')">Delete</a></td>', $style);
            }
            echo tr(tag($no . " Backup File(s)", "th", ' colspan="3"') . tag(prettyFileSize($totalsize), "th", ' colspan="4"'));
        } else {
            echo tr(tda(hed('You have no database backups' . br . 'Create a new backup of the ' . $DB->db . ' database' . br . href('.sql file', "index.php?event=rss_db_bk&amp;bk={$DB->db}") . $gzp, 3), ' colspan="7" style="text-align:center;"'));
        }
    } else {
        echo tr(tda(hed('You have no database backups' . br . 'Create a new backup of the ' . $DB->db . ' database' . br . href('.sql file', "index.php?event=rss_db_bk&amp;bk={$DB->db}") . $gzp, 3), ' colspan="7" style="text-align:center;"'));
    }
    echo endTable();
}
Exemple #9
0
function is_dst($name, $val)
{
    return pluggable_ui('prefs_ui', 'is_dst', yesnoRadio($name, $val), $name, $val);
}
Exemple #10
0
function smd_ebook_prefs($msg = '')
{
    global $smd_ebook_event, $smd_ebook_prefs, $step;
    require_privs('plugin_prefs.' . $smd_ebook_event);
    if (ps('smd_ebook_pref_save')) {
        foreach ($smd_ebook_prefs as $idx => $prefobj) {
            $val = ps($idx);
            $val = is_array($val) ? join(', ', $val) : $val;
            set_pref($idx, doSlash($val), 'smd_ebook', $prefobj['type'], $prefobj['html'], $prefobj['position']);
        }
        $msg = gTxt('preferences_saved');
    }
    pagetop(gTxt('smd_ebook_tab_name'), $msg);
    extract(smd_ebook_buttons('prf'));
    $btnbar = has_privs('plugin_prefs.' . $smd_ebook_event) ? '<span class="smd_ebook_buttons">' . $btnMgr . n . $btnPrf . n . $btnCln . '</span>' : '';
    echo n . <<<EOJS
<script type="text/javascript">
jQuery(function() {
    jQuery("select[name='smd_ebook_fld_uid'], select[name='smd_ebook_fld_title'], select[name='smd_ebook_fld_chaptitle'], select[name='smd_ebook_fld_author'], select[name='smd_ebook_fld_description'], select[name='smd_ebook_fld_authornote'], select[name='smd_ebook_fld_subject'], select[name='smd_ebook_fld_publisher'], select[name='smd_ebook_fld_srp']").change(function() {
        var xtra = jQuery(this).attr('name') + '_fixed';
        if (jQuery('option:selected', this).val() === 'SMD_FIXED') {
            jQuery("input[name='"+xtra+"']").parent().parent().show('normal');
        } else {
            jQuery("input[name='"+xtra+"']").parent().parent().hide('fast');
        }
    }).change();
});
</script>
EOJS;
    echo n . '<div id="' . $smd_ebook_event . '_control" class="txp-control-panel">' . $btnbar . '</div>';
    $out = array();
    $out[] = n . '<div class="plugin-column">';
    $out[] = '<form name="smd_ebook_prefs" id="smd_ebook_prefs" class="prefs-form" action="index.php" method="post">';
    $out[] = '<div class="txp-layout-textbox">';
    $out[] = eInput($smd_ebook_event);
    $out[] = sInput('smd_ebook_prefs');
    $grpout = array();
    foreach ($smd_ebook_prefs as $idx => $prefobj) {
        $val = get_pref($idx, $prefobj['default'], 1);
        $vis = isset($prefobj['visible']) && !$prefobj['visible'] ? 'smd_hidden' : '';
        switch ($prefobj['html']) {
            case 'text_input':
                $grpout[$prefobj['group']][] = inputLabel($idx, fInput('text', $idx, $val, '', '', '', '', '', $idx), $idx, '', $vis);
                break;
            case 'yesnoradio':
                $grpout[$prefobj['group']][] = inputLabel($idx, yesnoRadio($idx, $val), '', '', $vis);
                break;
            case 'radioset':
                $grpout[$prefobj['group']][] = inputLabel($idx, radioSet($prefobj['content'], $idx, $val), '', '', $vis);
                break;
            case 'checkboxset':
                $vals = do_list($val);
                $lclout = array();
                foreach ($prefobj['content'] as $cb => $val) {
                    $checked = in_array($cb, $vals);
                    $lclout[] = checkbox($idx . '[]', $cb, $checked) . gTxt($val);
                }
                $grpout[$prefobj['group']][] = inputLabel($idx, join(n, $lclout), '', '', $vis);
                break;
            case 'selectlist':
                $grpout[$prefobj['group']][] = inputLabel($idx, selectInput($idx, $prefobj['content'][0], $val, $prefobj['content'][1], '', $idx), $idx, '', $vis);
                break;
            default:
                if (strpos($prefobj['html'], 'smd_ebook_') !== false && is_callable($prefobj['html'])) {
                    $grpout[$prefobj['group']][] = inputLabel($idx, $prefobj['html']($idx, $val), $idx, '', $vis);
                }
                break;
        }
    }
    foreach ($grpout as $grp => $content) {
        $out[] = '<div role="region" id="smd_ebook_group_' . $grp . '" class="txp-details" aria-labelledby="smd_ebook_group_' . $grp . '-label">' . n . '<h3 id="smd_ebook_group_' . $grp . '-label" class="lever txp-summary' . (get_pref('pane_' . $grp . '_visible') ? ' expanded' : '') . '">' . n . '<a href="#' . $grp . '" role="button">' . gTxt($grp) . '</a>' . n . '</h3>' . n . '<div id="' . $grp . '" class="toggle" role="group" style="display:' . (get_pref('pane_' . $grp . '_visible') ? 'block' : 'none') . '">';
        foreach ($content as $row) {
            $out[] = $row;
        }
        $out[] = '</div>';
        $out[] = '</div>';
    }
    if (smd_ebook_kindlegen_available()) {
        $out[] = graf($btnTst);
    }
    if ($step === 'smd_ebook_test') {
        $out[] = graf(text_area('smd_ebook_test_results', 150, 200, ps('smd_ebook_test_output')));
    }
    $out[] = graf(fInput('submit', 'smd_ebook_pref_save', gTxt('save'), 'publish'));
    $out[] = tInput();
    $out[] = '</div></form></div>';
    echo join(n, $out);
}