<?php

# PLUGIN PREVIEW BY TEXTPATTERN.INFO


/*
    adi_variables - Manage TXP variables

    Written by Adi Gilbert

    Released under the GNU General Public License

    Version history:
    0.7        - minor updates for TXP 4.6
    0.6        - TXP 4.5+ only
            - tested on TXP 4.6
            - plugin privileges in options
            - drag & drop reordering
            - minor UI improvements
    0.5        - TXP 4.5-ified
            - tooltips no more
            - Textpack
            - code tidy up
            - fix: update button now not shown for non privileged users when there're no public variables
            - enhancement: variable rename for Admin users
    0.4        - use update_lastmod() (thanks maniqui)
            - global variables tidy up
    0.3.1    - fix: unable to see variables in admin after manual edit (thanks woof)
    0.3        - adi_variables form converted from single to container <txp:variable> tags
    0.2        - enhancement: cope with TXP tags in variable values (for johnstephens)
    0.1        - initial release

*/

if (txpinterface === 'admin') {
    global 
$adi_variables_debug,$adi_variables_txp460;

    
$adi_variables_debug 0;

    if (!
version_compare(txp_version,'4.5','>=')) return;

    
$adi_variables_txp460 = (version_compare(txp_version,'4.6-dev','>='));

    
adi_variables_init();
}

function 
adi_variables_init() {
// initial set up
    
global $event,$prefs,$textarray,$adi_variables_boundary,$adi_variables_prefs,$adi_variables_outlawed_privs,$adi_variables_admin_privs,$adi_variables_debug,$adi_variables_url;

    
$adi_variables_boundary '<txp:hide>PUBLIC VARIABLES BELOW, ADMIN VARIABLES ABOVE</txp:hide>';

    
// default preferences
    
$adi_variables_prefs = array(
        
'adi_variables_privs' => array('value' => '1,2,3,4,5,6''input' => 'text_input'),
    );

    
// privs to be excluded
    
$adi_variables_outlawed_privs = array(0);

# --- BEGIN PLUGIN TEXTPACK ---
    
$adi_variables_gtxt = array(
        
'adi_install_fail' => 'Unable to install',
        
'adi_installed' => 'Installed',
        
'adi_textpack_fail' => 'Textpack installation failed',
        
'adi_textpack_feedback' => 'Textpack feedback',
        
'adi_textpack_online' => 'Textpack also available online',
        
'adi_plugin_privs' => 'Plugin privileges:',
        
'adi_variable' => 'Variable',
        
'adi_variables' => 'Variables',
        
'adi_variables_already_exists' => 'Variable already exists',
        
'adi_variables_copy_form' => 'Copy variables form',
        
'adi_variables_delete_fail' => 'Variable not deleted',
        
'adi_variables_deleted' => 'Variable deleted',
        
'adi_variables_form_copied' => 'Variables form copied',
        
'adi_variables_form_copy_fail' => 'Variables form not copied',
        
'adi_variables_form_empty' => 'Variables form empty',
        
'adi_variables_none_found' => 'No variables found',
        
'adi_variables_update_fail' => 'Variable update failed',
        
'adi_variables_updated' => 'Variables updated',
    );
# --- END PLUGIN TEXTPACK ---

    // update $textarray
    
$textarray += $adi_variables_gtxt;

    
// Textpack
    
$adi_variables_url = array(
        
'textpack' => 'http://www.greatoceanmedia.com.au/files/adi_textpack.txt',
        
'textpack_download' => 'http://www.greatoceanmedia.com.au/textpack/download',
        
'textpack_feedback' => 'http://www.greatoceanmedia.com.au/textpack/?plugin=adi_variables',
    );
    if (
strpos($prefs['plugin_cache_dir'],'adi') !== FALSE// use Adi's local version
        
$adi_variables_url['textpack'] = $prefs['plugin_cache_dir'].'/adi_textpack.txt';

    
/*    User privilege summary:
        0 - none            - can't even login
        1 - publisher        - full capability
        2 - manager            - full capability
        3 - copy editor        - full capability
        4 - staff writer    - public variable update only
        5 - freelancer        - public variable update only
        6 - designer        - full capability
    */

    // admin variable update, add/delete, admin buttons (i.e. anybody who can access Forms!)
    
$adi_variables_admin_privs 'form'// see lib/admin_config.php: '1,2,3,6' publisher, manager, copy writer, designer

    // register adi_variables tab
    
add_privs('adi_variables_admin',adi_variables_pref('adi_variables_privs'));
    
register_tab('content','adi_variables_admin',gTxt('adi_variables'));
    
register_callback('adi_variables_admin','adi_variables_admin');

    
// style
    
if ($event == 'adi_variables_admin')
        
register_callback('adi_variables_style','admin_side','head_end');

    
// script
    
if (strstr($event,'adi_variables_admin'))
        
register_callback('adi_variables_admin_script','admin_side','head_end');

    
// plugin options
    
$adi_variables_plugin_status fetch('status','txp_plugin','name','adi_variables',$adi_variables_debug);
    if (
$adi_variables_plugin_status) { // proper install - options under Plugins tab
        
add_privs('plugin_prefs.adi_variables'); // defaults to priv '1' only
        
register_callback('adi_variables_options','plugin_prefs.adi_variables');
    }
    else { 
// txpdev - options under Extensions tab
        
add_privs('adi_variables_options');
        
register_tab('extensions','adi_variables_options','adi_variables options');
        
register_callback('adi_variables_options','adi_variables_options');
    }
}

function 
adi_variables_style() {
// some style
    
echo '<style type="text/css">
        /* adi_variables */
         form h1 {text-align:center }
         .txp-list { width:auto; margin:0 auto }
         .txp-list th, .txp-list td { padding:0.5em }
         form div { margin-top:1.5em; text-align:center }
         .adi_td_center { text-align:center }
         td.adi_td_center { font-size:120%; line-height:1.4 }
         .adi_variables_prefs { margin-top:3em }
         .adi_variables_drag_drop { display:none } /* revealed by jQuery later */
    </style>'
;
}

function 
adi_variables_install($mode='') {
// create vanilla adi_variables form
    
$form = <<<EOF
<txp:variable name="example-admin" value="Only admin can change this" />
<txp:hide>PUBLIC VARIABLES BELOW, ADMIN VARIABLES ABOVE</txp:hide>
<txp:variable name="example-public1" value="Anybody can change this one" />
<txp:variable name="example-public2" value="Anybody can change this too" />
EOF;
    if (!
safe_field('name''txp_form'"name='adi_variables'")) // install default form
        
return safe_insert('txp_form',
            
"name='adi_variables',
            type='misc',
            Form='"
.doSlash($form)."'"
        
);
    else if (
$mode == 'copy') { // copy adi_variables form to adi_variables_copy CONSOLIDATE CODE
        
$raw adi_variables_read_form(); // read form
        
if (empty($raw))
            return 
FALSE;
        if (
safe_field('name''txp_form'"name='adi_variables_copy'")) // update existing form copy
            
return safe_update('txp_form',
                
"Form='".doSlash($raw['Form'])."'",
                
"name='adi_variables_copy'"
            
);
        else 
// add new form copy
            
return safe_insert('txp_form',
                
"name='adi_variables_copy',
                type='misc',
                Form='"
.doSlash($raw['Form'])."'"
            
);
    }
}

function 
adi_variables_read_form() {
// read in adi_variables form
    
$rs safe_query('SELECT Form FROM '.safe_pfx('txp_form')." WHERE name='adi_variables'");
    if (
$rs)
        return 
nextRow($rs); // $a = array("Form' => '<txp:variable name="example_admin" ..... )
    
else
        return array();
}

function 
adi_variables_validate($txp_var_tag) {
// v0.1 format: <txp:variable name="var" value="valuable" />
// v0.2 format: <txp:variable name="var" value='valuable' />
// v0.3+ format: <txp:variable name="var">valuable</txp:variable>
    
$txp_var_tag trim($txp_var_tag); // remove extraneous whitespace
    
$old_1_2_valid preg_match('@^<txp:variable\ @',$txp_var_tag); // line starts "<txp:variable "
    
$old_1_2_valid $old_1_2_valid && preg_match('@/>@',$txp_var_tag); // line ends "/>" (not a proper "ends with" match!)
    
$new_3_valid preg_match('@^<txp:variable\ @',$txp_var_tag); // line starts "<txp:variable "
    
$new_3_valid $new_3_valid && preg_match('@</txp:variable>$@',$txp_var_tag); // line ends "</txp:variable>" (not a proper "ends with" match!)
    
return $old_1_2_valid || $new_3_valid;
}

function 
adi_variables_get_vars($lines) {
// extract variables
    
$vars = array();
    
$public FALSE;
    foreach (
$lines as $index => $line) {
        
$ok adi_variables_validate($line);
        if (
preg_match('@^(<txp:hide>PUBLIC)@',$line)) $public TRUE// look for demarcation
        
if ($ok) {
            
$var adi_variables_extract($line);
            
$var['public'] = $public;
            
$vars[] = $var;
        }
    }
    return 
$vars;
}

function 
adi_variables_extract($line) {
// extract variables & values from adi_variables form
// v0.1 format: <txp:variable name="var" value="valuable" />
// v0.2 format: <txp:variable name="var" value='valuable' />
// v0.3+ format: <txp:variable name="var">valuable</txp:variable>
// check 0.3 format first then 0.1 then 0.2 format (copes with 0.1 -> 0.2 -> 0.3+ migration)
    
$var = array();
    
$line trim($line);  // strip whitespace - especially LF/CR at end
    
if (adi_variables_validate($line))
        if (
preg_match('@</txp:variable>$@',$line)) { // line ends "</txp:variable>" - 0.3 format
            
$diced explode('"',$line);
            
$var['name'] = $diced[1]; // var name will be second slice
            
$var['format'] = '0.3';
            
$value substr($line,22+strlen($var['name'])); // remove <txp:variable name="var"> from front
            
$var['value'] = substr($value,0,-15); // remove </txp:variable> from end
        
}
        else { 
// 0.1 or 0.2 format
            
$diced explode('"',$line); // use double quote delimiter first (v0.1)
            
if (!empty($diced)) { // check that there's something there
                
$var['name'] = $diced[1]; // var name will be second slice
                
if (count($diced) != 5) { // must be new format (v0.2)
                    
$diced explode("'",$line); // single quote delimiter
                    
$var['value'] = $diced[1]; // new format, value will be now be second slice
                    
$var['format'] = '0.2';
                }
                else { 
// old format, value will be fourth slice
                    
$var['value'] = $diced[3];
                    
$var['format'] = '0.1';
                }
            }
        }
    return 
$var;
}

function 
adi_variables_display_settings($vars) {
// display table for updating/adding variables
    
global $adi_variables_admin_privs;

    
$out '';

    foreach (
$vars as $index => $var) {
        
$out .= '<tr>';
        
$out .= tda(tag('&#x2195;','span',' class="adi_variables_drag_drop"'),' class="adi_td_center"'); // drag&drop symbol
        
if (has_privs($adi_variables_admin_privs)) // see everything, do anything
            
$out .=
                
tda(finput("text","adi_variables[$index][name]",$var['name'],'','','',20))
                .
tda(finput("text","adi_variables[$index][value]",$var['value'],'','','',80))
                .
tda(checkbox("adi_variables[$index][public]","1",$var['public']),' class="adi_td_center"')
                .
tda(adi_variables_delete_button($var['name']),' class="adi_td_center"');
        else 
// restricted capabilities: no rename, no delete, edit public variable values only
            
if ($var['public']) // display variable
                
$out .=
                    
tda(
                        
$var['name']
                        .
hinput("adi_variables[$index][name]",$var['name']) // hidden name
                    
)
                    .
tda(
                        
finput("text","adi_variables[$index][value]",$var['value'],'','','',80)
                        .
hinput("adi_variables[$index][public]",$var['public']) // hidden public setting
                    
);
            else 
// hide variable input but display variable name/value
                
$out .=
                    
tda(
                        
$var['name']
                        .
hinput("adi_variables[$index][name]",$var['name']) // hidden name
                    
)
                    .
tda(
                        (empty(
$var['value']) ? sp htmlspecialchars($var['value']))
                        .
hinput("adi_variables[$index][value]",$var['value']) // hidden value
                        
.hinput("adi_variables[$index][public]"$var['public']) // hidden public setting
                    
);
        
$out .= '</tr>';
    }

    if (
has_privs($adi_variables_admin_privs)) // restrict access to adding new variables
        
$out .=
            
tr(
                
tag('&#43;','td',' class="adi_variables_plus adi_td_center"'// plus
                
.tda(finput("text","adi_variables[new][name]",'','','','',20))
                .
tda(finput("text","adi_variables[new][value]",'','','','',80))
                .
tda(checkbox("adi_variables[new][public]""1"''),' class="adi_td_center"')
                .
tda(sp)
            );

    return 
$out;
}

function 
adi_variables_delete_button($var) {
// delete button
    
global $adi_variables_txp460;

    
$event 'adi_variables_admin';
    
$step 'delete';

    if (
$adi_variables_txp460)
        return
            
href(
                
span('Delete',' class="ui-icon ui-icon-trash"')
                ,array(
                    
'event' => $event,
                    
'step' => $step,
                    
'adi_variable_delete' => $var,
                    
'_txp_token'    => form_token(),
                )
                ,array(
                    
'class'       => 'dlink destroy',
                    
'title'       => gTxt('delete'),
                    
'data-verify' => gTxt('confirm_delete_popup'),
                )
            );
    else
        return
            
'<a href="?event='.$event.a.'step='.$step.a.'adi_variable_delete='.$var
            
.'" class="dlink" title="'.gTxt('delete').'" onclick="return verify(\''
            
.gTxt('confirm_delete_popup')
            .
'\')">'
            
.'&#215;'
            
.'</a>';
}

function 
adi_variables_update($form_contents) {
// update adi_variables form in db
    
global $adi_variables_debug;

    if (
safe_field('name''txp_form'"name='adi_variables'")) {
        
$res safe_update('txp_form',
                
"Form='".doSlash($form_contents)."'",
                
"name='adi_variables'"
                
);
    }
    else 
// Form not found
        
return FALSE;
    return 
$res;
}

function 
adi_variables_variable_tag($name,$value) {
// generate TXP variable tag
    
return '<txp:variable name="'.$name.'">'.$value.'</txp:variable>'// container tag - 0.3 format
}

function 
adi_variables_form_update($variables) {
// generate new adi_variables form
    
global $adi_variables_boundary;

    
$new_form = array();
    
$admin_vars $public_vars $ordered_vars = array();
    if (
$variables) {
        foreach (
$variables as $index => $variable) {
            if (
$index == 'new')
                if (
$variable['name']) {
                    
// remove nasties from new variable name
                    
$variable['name'] = strip_tags(trim($variable['name'])); // no tags
                    
$variable['name'] = str_replace(' ','',$variable['name']); // no embedded spaces
                    
$variable['name'] = str_replace('"','',$variable['name']); // no double quotes
                    
$variable['name'] = str_replace("'",'',$variable['name']); // no single quotes
                
}
                else
                    continue; 
// ignore new variable if name blank
            
if (isset($variable['public']))
                
$public_vars[] = $variable;
            else {
                
$variable['public'] = 0// coz checkbox don't set it
                
$admin_vars[] = $variable;
            }
        }
        
// reorder vars: admin first, public last
        
$ordered_vars array_merge($admin_vars,$public_vars);
        
// generate new form
        
$public FALSE;
        foreach (
$ordered_vars as $index => $variable) {
            if (!
$public && $variable['public']) { // start of public vars found
                
$public TRUE// toggle public
                
$new_form[] = $adi_variables_boundary// demarcation
            
}
            
$new_form[] = adi_variables_variable_tag($variable['name'],$variable['value']);
        }
    }
    return 
$new_form;
}

function 
adi_variables_form_delete($delete_me) {
// remove variable from form
    
global $adi_variables_boundary;

    
$new_form = array();
    
$raw adi_variables_read_form(); // raw data from form
    
$lines explode("\n",$raw['Form']); // break up into lines
    
$vars adi_variables_get_vars($lines); // extract variables
    // generate new form
    
$public FALSE;
    foreach (
$vars as $index => $var) {
        if (
$var['name'] == $delete_me)
            continue;
        if (!
$public && $var['public']) { // start of public vars found
            
$public TRUE// toggle public
            
$new_form[] = $adi_variables_boundary// demarcation
        
}
        
$new_form[] = adi_variables_variable_tag($var['name'],$var['value']);
    }
    return 
$new_form;
}

function 
adi_variables_pref($name,$value=NULL,$private=FALSE) {
// read or set pref
    
global $prefs,$adi_variables_prefs;

    if (
$value === NULL)
        return 
get_pref($name,$adi_variables_prefs[$name]['value']);
    else {
        if (
array_key_exists($name,$adi_variables_prefs))
            
$html $adi_variables_prefs[$name]['input'];
        else
            
$html 'text_input';
        
$res set_pref($name,$value,'adi_variables_admin',2,$html,0,$private);
        
$prefs get_prefs();
        return 
$res;
    }
}

function 
adi_variables_debug($event,$step,$something,$raw,$lines,$vars,$posted_vars,$new_form,$public_count) {
// debug info
    
global $adi_variables_debug;

    echo 
"event: ".$event.", step: ".$step.", something: ".$something.", adi_variable_delete: ".gps('adi_variable_delete').br.br;
    echo 
"POSTED DATA:";
    
dmp($posted_vars);
    echo 
"RAW FORM:";
    
dmp($raw);
    echo 
"LINE BY LINE:".br;
    foreach (
$lines as $index => $line) {
        
$line htmlspecialchars($line); // replace angle brackets so tags not parsed
        
echo "Line ".$index.". ".$line.br;
    }
    
$public FALSE;
    echo 
br."ANALYSIS:".br;
    foreach (
$lines as $index => $line) {
        
$this_line trim($line);
        if (empty(
$this_line))
            echo 
"BLANK LINE".br;
        else {
            
$ok adi_variables_validate($line);
            
$ok ? print "VAR " : print "IGNORE ";
            if (
preg_match('@^(<txp:hide>PUBLIC)@',$line)) $public TRUE// look for demarcation
            
if ($ok)
                
$public ? print '(PUBLIC): ' : print '(ADMIN): ';
            
$line htmlspecialchars($line); // replace angle brackets so tags not parsed
            
print $line.br;
        }
    }
    echo 
br."STORED DATA:";
    
dmp($vars);
    if (
$step == "update") {
        print 
"NEW FORM:";
        
dmp($new_form);
    }
    echo 
'Public variable count = '.$public_count.br;
}

function 
adi_variables_admin_script() {
// jQuery magic for admin tab
    
global $adi_variables_txp460;

    
$ui_script '';
    if (!
$adi_variables_txp460)
        
$ui_script '<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/jquery-ui.min.js"></script>';

    echo <<<END_SCRIPT
<!-- adi_variables - drag and drop -->
$ui_script
<script type="text/javascript">
    if (jQuery.ui) { // jQuery UI available
        $(function() {
            $('#list tbody tr').css('cursor','pointer'); // make like a pointer
            $('#list .adi_variables_drag_drop').show(); // reveal drag & drop icon
            $("#list tbody").sortable();
        });
    }
</script>
END_SCRIPT;
}

function 
adi_variables_admin($event,$step) {
// variables tab
    
global $adi_variables_debug,$adi_variables_admin_privs,$adi_variables_txp460;

    
$message '';
    
$something ps('something');
    
$installed TRUE;
    
$new_form = array();

    
$posted_vars gps('adi_variables');
    
$delete_variable gps('adi_variable_delete');

    
// install adi_variables form if required
    
if (!safe_field('name''txp_form'"name='adi_variables'")) // form not found
        
if (adi_variables_install())
            
$message gTxt('adi_installed');
        else {
            
$message = array(gTxt('adi_install_fail'),E_ERROR);
            
$installed FALSE;
        }

    if (
$installed) {
        if (
$step == 'update') {
            
// check for duplicates
            
$duplicates 0;
            if (isset(
$posted_vars['new'])) // non-privileged users can't post new variable
                
if ($posted_vars['new']['name']) {
                    
$duplicates = -1;
                    foreach (
$posted_vars as $var)
                        if (
$var['name'] == $posted_vars['new']['name'])
                            
$duplicates += 1;
                }
            if (
$duplicates)
                
$message = array(gTxt('adi_variables_already_exists'),E_ERROR);
            if (
$message == '') {
                
$new_form adi_variables_form_update($posted_vars);
                
$ok adi_variables_update(join("\n",$new_form));
                if (
$ok)
                    
$message gTxt('adi_variables_updated');
                else
                    
$message = array(gTxt('adi_variables_update_fail'),E_ERROR);
                if (
$ok)
                    
update_lastmod();
            }
        }
        if (
$step == 'delete') {
            if (
has_privs($adi_variables_admin_privs)) { // double check privileges because this operation uses GET VARS
                
$new_form adi_variables_form_delete($delete_variable);
                
$ok adi_variables_update(join("\n",$new_form));
                if (
$ok)
                    
$message gTxt('adi_variables_deleted');
                else
                    
$message = array(gTxt('adi_variables_delete_fail'),E_ERROR);
                if (
$ok)
                    
update_lastmod();
            }
            else
                
$message gTxt('adi_variables_delete_fail');
        }
        if (
$something == "copy") {
            
$ok adi_variables_install('copy');
            if (
$ok)
                
$message gTxt('adi_variables_form_copied');
            else
                
$message = array(gTxt('adi_variables_form_copy_fail'),E_ERROR);
        }

        
// read contents of form
        
$raw adi_variables_read_form();
        if (empty(
$raw)) // shouldn't ever happen coz adi_variables_install should've kicked in
            
gTxt('form_not_found');

        
// break up into individual lines
        
$lines explode("\n",$raw['Form']);

        
// extract variables & values from form
        
$vars adi_variables_get_vars($lines);
        if ((
trim($raw['Form']) == '') || empty($vars)) // form blank OR no vars (i.e. $adi_variables_boundary line only)
            
$message = array(gTxt('adi_variables_none_found'),E_WARNING);

        
// count public variables
        
$public_count 0;
        foreach (
$vars as $variable)
            if (
$variable['public'])
                
$public_count += 1;
    }

    
// generate page
    
pagetop('adi_variables admin',$message);
    if (
$adi_variables_debug)
        
adi_variables_debug($event,$step,$something,$raw,$lines,$vars,$posted_vars,$new_form,$public_count);

    if (
$installed) {
        
// only allowed update button if privileged or there're public variables present
        
if (has_privs($adi_variables_admin_privs) || $public_count)
            
$update_button =
                
tag(
                    (
$adi_variables_txp460 fInput("submit","update",gTxt('Save'),'publish') : fInput("submit","update",gTxt('Update'),"smallerbox")) // 4.6 has publish style
                    
.eInput("adi_variables_admin")
                    .
sInput("update")
                    ,
'div'
                
);
        else
            
$update_button '';
        
// output table & input form
        
echo
            
form(
                
hed(gTxt('adi_variables'),1,' class="txp-heading"')
                .
startTable('list','','txp-list')
                .
tag(
                    
tr(
                        
hcell(sp// spacer for plus/drag&drop
                        
.hcell(gTxt('name'))
                        .
hcell(gTxt('value'))
                        .(
has_privs($adi_variables_admin_privs) ? hcell(gTxt('public'),'',' class="adi_td_center"') : ''// hide Public heading if required
                        
.(has_privs($adi_variables_admin_privs) ? hcell(sp) : ''// filler for delete buttons
                    
)
                    ,
'thead'
                
)
                .
adi_variables_display_settings($vars)
                .
endTable()
                .
$update_button
            
);
        
// admin functions
        
if (has_privs($adi_variables_admin_privs)) { // restrict access to admin functions
            
echo form(
                
tag(
                    
hInput('something','copy')
                    .
fInput('submit','do_something',gTxt('adi_variables_copy_form'),'smallerbox')
                    .
eInput('adi_variables_admin')
                    .
sInput('admin')
                    ,
'div'
                    
,' class="adi_variables_prefs"'
                
)
            );
        }
        
// link to form
//         if ($adi_variables_txp460)
//             echo
//                 graf(
//                     href(
//                         gTxt('view')
//                         ,array(
//                             'event' => 'form',
//                             'step' => 'form_edit',
//                             'name' => 'adi_variables',
//                             '_txp_token' => form_token()
//                         )
//                     )
//                     ,' class="adi_td_center"'
//                 );
    
}
}

function 
adi_variables_options($event,$step) {
// plugin options page
    
global $txp_groups,$adi_variables_prefs,$adi_variables_outlawed_privs,$adi_variables_debug,$adi_variables_url,$textarray;

    
$message '';

    if (
$step == 'textpack') {
        if (
function_exists('install_textpack')) {
            
$adi_textpack file_get_contents($adi_variables_url['textpack']);
            if (
$adi_textpack) {
                
$result install_textpack($adi_textpack);
                
$message gTxt('textpack_strings_installed', array('{count}' => $result));
                
$textarray load_lang(LANG); // load in new strings
            
}
            else
                
$message = array(gTxt('adi_textpack_fail'),E_ERROR);
        }
    }
    else if (
$step == 'update_prefs') {
        
$result TRUE;
        
// run through all prefs
        
foreach ($adi_variables_prefs as $name => $data) {
            if (
array_key_exists($name,$_POST))
                
$value $_POST[$name];
            else if (
$data['input'] == 'yesnoradio')
                
$value '0';
            else
                
$value $data['value'];
            if (
is_array($value)) { // string-ify arrays
                
$value array_keys($value); // need index values not 1s
                
if ($name == 'adi_variables_privs') {
                    if (
array_search(1,$value) === FALSE// can't kill off Publisher
                        
array_unshift($value,1);
                }
                
$value implode(',',$value);
            }
            
// some values not allowed to be blank, reset to default
            
$non_blanks = array();
            foreach (
$non_blanks as $non_blank)
                if ((
$name == $non_blank) && (trim($value) == ''))
                    
$value $adi_variables_prefs[$non_blank]['value'];
            
$result &= adi_variables_pref($name,$value);
        }
        
$result $message gTxt('preferences_saved') : $message = array(gTxt('adi_pref_update_fail'),E_ERROR);
    }

    
// generate page
    
pagetop('adi_variables - '.gTxt('plugin_prefs'),$message);

    
// plugin priv checkboxes
    
$plugin_privs do_list(adi_variables_pref('adi_variables_privs'));
    
$priv_checkboxes '';
    foreach (
$txp_groups as $index => $group)
        if (
array_search($index,$adi_variables_outlawed_privs) === FALSE// ignore the outlaws
            
$priv_checkboxes .= tag(gTxt($group).checkbox2("adi_variables_privs[$index]",(array_search($index,$plugin_privs) !== FALSE),'','adi_variables_privs').sp.sp,'label');

    
// options
    
echo tag(
        
tag('adi_variables '.gTxt('plugin_prefs'),'h1')
        
// textpack links
        
.graf(href(gTxt('install_textpack'),'?event='.$event.'&amp;step=textpack'))
        .
graf(href(gTxt('adi_textpack_online'),$adi_variables_url['textpack_download']))
        .
graf(href(gTxt('adi_textpack_feedback'),$adi_variables_url['textpack_feedback']))
        
// plugin privs
        
.form(
            
graf(
                
gTxt('adi_plugin_privs')
                .
sp.sp.sp
                
.$priv_checkboxes
                
,' style="margin-top:2em"'
            
)
            .
fInput('submit','do_something',gTxt('update'),'smallerbox')
            .
eInput($event)
            .
sInput("update_prefs")
        )
        
// link to plugin admin tab
        
.graf(href(gTxt('adi_variables'),'?event=adi_variables_admin'))
        ,
'div'
        
,' style="text-align:center"'
    
);

    if (
$adi_variables_debug) {
        echo 
"<p>Event: ".$event.", Step: ".$step."</p>";
        echo 
'$adi_textpack ('.$adi_variables_url['textpack'].'):';
        
$adi_textpack file_get_contents($adi_variables_url['textpack']);
        
dmp($adi_textpack);
    }

}