// -------------------------------------------------------------
//********************** ADMIN SIDE CODE ***********************
// -------------------------------------------------------------
if (@txpinterface == 'admin') {
add_privs('smd_vars','1,2');
// Extensions tab
register_tab('extensions', 'smd_vars', smd_vars_gTxt('smd_vars'));
register_callback('smd_vars', 'smd_vars');
}
// -------------------------------------------------------------
function smd_vars($event, $step) {
if(!$step or !in_array($step, array(
'smd_vars_table_install',
'smd_vars_table_remove',
'smd_vars_purge_expired',
'smd_vars_add',
'smd_vars_delete',
'smd_vars_update',
'smd_vars_multi_edit',
'smd_vars_change_pageby',
))) {
smd_vars_show('');
} else $step();
}
// -------------------------------------------------------------
function smd_vars_add() {
extract(doSlash(gpsa(array('new_name','new_value','new_expiry'))));
$ret = false;
$msg = '';
$new_expiry = smd_vars_calc_expiry($new_expiry);
$new_expiry = ($new_expiry) ? $new_expiry : '0000-00-00 00:00:00';
if (smd_vars_table_exists() && $new_name && $new_value && $new_expiry) {
$dup = safe_count("smd_vars", "name='$new_name'");
if ($dup) {
$msg = smd_vars_gTxt('duplicate');
} else {
$ret = safe_insert("smd_vars",
"name='$new_name',
value='$new_value',
expires='$new_expiry'"
);
}
}
if ($ret === false) {
smd_vars_show(smd_vars_gTxt('insert_failed').$msg, $new_name, $new_value, $new_expiry);
} else {
smd_vars_show(smd_vars_gTxt('inserted'));
}
}
// -------------------------------------------------------------
function smd_vars_update() {
extract(doSlash(gpsa(array('id', 'new_name','new_value','new_expiry'))));
$new_expiry = smd_vars_calc_expiry($new_expiry);
$ret = false;
$msg = '';
if (smd_vars_table_exists()) {
$dup = safe_row("*", "smd_vars", "name='$new_name'");
if ($dup && (intval($dup['id']) != intval($id))) {
$msg = smd_vars_gTxt('duplicate');
} else {
$ret = safe_update("smd_vars",
"name='$new_name',
value='$new_value',
expires='$new_expiry'",
"id='$id'");
}
}
if ($ret === false) {
smd_vars_show(smd_vars_gTxt('update_failed').$msg);
} else {
smd_vars_show(smd_vars_gTxt('updated'));
}
}
// -------------------------------------------------------------
function smd_vars_delete() {
$id = assert_int(ps('id'));
$ret = false;
if (smd_vars_table_exists()) {
$rs = safe_row('*', 'smd_vars', "id = $id");
if ($rs) {
extract($rs);
$ret = safe_delete('smd_vars', "id = $id");
}
}
if ($ret === false) {
smd_vars_show(smd_vars_gTxt('delete_failed'));
} else {
smd_vars_show(smd_vars_gTxt('deleted', array("{id}" => $id)));
}
}
// -------------------------------------------------------------
function smd_vars_multi_edit() {
// extract(doSlash(gpsa(array('id','new_name','new_value','new_expiry'))));
$selected = ps('selected');
$ret = false;
$ids = '';
if (smd_vars_table_exists() && $selected) {
$method = ps('edit_method');
switch($method) {
case "delete":
$ids = array();
foreach ($selected as $id) {
$id = assert_int($id);
if (safe_delete('smd_vars', "id = $id")) {
$ids[] = $id;
}
}
$ids = join(', ', $ids);
break;
}
}
smd_vars_show(smd_vars_gTxt('deleted', array("{id}" => $ids)));
}
// -------------------------------------------------------------
function smd_vars_purge_expired() {
$blatted = 0;
if (smd_vars_table_exists()) {
$where = "expires <> '0000-00-00 00:00:00' AND expires < NOW()";
$blatted = safe_count("smd_vars", $where);
$res = safe_delete("smd_vars", $where);
}
smd_vars_show(smd_vars_gTxt('deleted_num', array("{num}" => $blatted)));
}
// -------------------------------------------------------------
function smd_vars_table_exists() {
return(@safe_show('columns', 'smd_vars'));
}
// -------------------------------------------------------------
// Add the vars table if not already installed
function smd_vars_table_install() {
$version = mysql_get_server_info();
$GLOBALS['txp_err_count'] = 0;
if ($version < "4.1.2") {
$GLOBALS['txp_err_count']++;
trigger_error("smd_vars requires MySQL v4.1.2 or greater.");
} else {
$ret = '';
$sql = array();
if (!smd_vars_table_exists()) {
$sql[] = "CREATE TABLE `".safe_pfx('smd_vars')."` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(64) NOT NULL default '',
`value` text NOT NULL default '',
`expires` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=MyISAM PACK_KEYS=1 AUTO_INCREMENT=1";
foreach ($sql as $qry) {
$ret = safe_query($qry);
if (!$ret) {
$GLOBALS['txp_err_count']++;
echo "".$GLOBALS['txp_err_count'].". ".mysql_error()."
\n";
echo "\n";
}
}
}
}
if ($GLOBALS['txp_err_count'] == 0) {
$message = smd_vars_gTxt('table_installed');
} else {
$message = smd_vars_gTxt('table_not_installed');
}
smd_vars_show($message);
}
// -------------------------------------------------------------
// Drop the vars table if it's in the database
function smd_vars_table_remove() {
$ret = '';
$sql = array();
$GLOBALS['txp_err_count'] = 0;
if (smd_vars_table_exists()) {
$sql[] = "DROP TABLE IF EXISTS " .safe_pfx('smd_vars'). "; ";
foreach ($sql as $qry) {
$ret = safe_query($qry);
if (!$ret) {
$GLOBALS['txp_err_count']++;
echo "".$GLOBALS['txp_err_count'].". ".mysql_error()."
\n";
echo "\n";
}
}
}
if ($GLOBALS['txp_err_count'] == 0) {
$message = smd_vars_gTxt('table_removed');
} else {
$message = smd_vars_gTxt('table_not_removed');
}
smd_vars_show($message);
}
// -------------------------------------------------------------
// Display the variables already defined and other buttons like add/remove/edit vars/tables
function smd_vars_show($message, $theName='', $theValue='', $theExpires='') {
require_plugin('smd_lib');
// Process the sort order, limit and filtering stuff from the query string
extract(gpsa(array('step', 'page', 'sort', 'dir', 'crit', 'search_method', 'id')));
$pageby = (gps('qty')) ? gps('qty') : ((cs('smd_vars_pageby')) ? cs('smd_vars_pageby') : 15);
$dir = ($dir == 'desc') ? 'desc' : 'asc';
switch ($sort) {
case 'id':
$sort_sql = 'id '.$dir.', name asc';
break;
case 'value':
$sort_sql = 'value '.$dir.', name asc';
break;
case 'expires':
$sort_sql = 'expires '.$dir.', name asc';
break;
case 'name':
default:
$sort = 'name';
$sort_sql = 'name '.$dir;
break;
}
$switch_dir = ($dir == 'desc') ? 'asc' : 'desc';
$criteria = 1;
if ($search_method && $crit) {
$crit_escaped = doSlash($crit);
$now = date("Y-m-d H:i:s");
// Make up criteria for the fake 'expired' column
switch(strtolower($crit_escaped)) {
case strtolower(gTxt('yes')):
$expyre = "(expires < '$now' AND expires <> '0000-00-00 00:00:00')";
break;
case smd_vars_gTxt('empty_expiry'):
$expyre = "expires = '0000-00-00 00:00:00'";
break;
case strtolower(gTxt('no')).smd_vars_gTxt('empty_expiry'):
$expyre = "(expires >= '$now' OR expires = '0000-00-00 00:00:00')";
break;
default:
$expyre = "(expires >= '$now' AND expires <> '0000-00-00 00:00:00')";
break;
}
$critsql = array(
'id' => "id = '$crit_escaped'",
'name' => "name like '%$crit_escaped%'",
'value' => "value like '%$crit_escaped%'",
'expires' => "expires like '%$crit_escaped%'",
'expired' => $expyre,
);
if (array_key_exists($search_method, $critsql)) {
$criteria = $critsql[$search_method];
$limit = 500;
} else {
$search_method = '';
$crit = '';
}
} else {
$search_method = '';
$crit = '';
}
$total = (smd_vars_table_exists()) ? safe_count('smd_vars', "$criteria") : 0;
$limit = max(@$pageby, 15);
list($page, $offset, $numPages) = pager($total, $limit, $page);
$qs = array(
"event" => "smd_vars",
"page" => $page,
"sort" => $sort,
"dir" => $dir,
"crit" => $crit,
"search_method" => $search_method,
);
$qsVars = "index.php".htmlspecialchars_decode(join_qs($qs));
// Render the variable list
pagetop(smd_vars_gTxt('edit'),$message);
$btnAdd = fInput('submit', 'smd_vars_add', smd_vars_gTxt('add_label'), 'smallerbox', '', 'smd_var_step=this.name;smd_var_id=\'\'');
$btnInstallTbl = '
';
$btnRemoveTbl = '';
$btnPurgeExpired = '';
$btnStyle = ' style="border:0;height:25px"';
// Non-default cases return false because the original form action has been overriden
echo <<
var smd_var_step = '';
var smd_var_id = '';
function presub() {
var smd_var_URL = "{$qsVars}";
switch(smd_var_step) {
case "smd_vars_add":
case "smd_vars_update":
var new_name = jQuery("input[name='new_name']").val();
var new_value = jQuery("input[name='new_value']").val();
var new_expiry = jQuery("input[name='new_expiry']").val();
location.href = smd_var_URL + "&step=" + smd_var_step + "&new_name=" + new_name+ "&new_value=" + new_value+ "&new_expiry=" + new_expiry + "&id=" + smd_var_id;
return false;
break;
case "smd_vars_edit":
location.href = smd_var_URL + "&step=" + smd_var_step + "&id=" + smd_var_id;
return false;
break;
case "smd_vars_cancel":
location.href = smd_var_URL;
return false;
break;
default:
return true;
}
}
EOJS;
echo startTable('control','','',5);
if (smd_vars_table_exists()) {
// Tables installed
echo tr(fLabelCell(smd_vars_gTxt('control').':') . tda($btnRemoveTbl, $btnStyle) . tda($btnPurgeExpired, $btnStyle));
echo endTable();
echo smd_vars_search_form($crit, $search_method);
echo '';
echo n.nav_form('smd_vars', $page, $numPages, $sort, $dir, $crit, $search_method);
echo n.pageby_form('smd_vars', $pageby);
} else {
// Tables not installed
echo tr(tda($btnInstallTbl, $btnStyle));
echo endTable();
}
}
// -------------------------------------------------------------
function smd_vars_search_form($crit, $method) {
$methods = array(
'id' => gTxt('id'),
'name' => gTxt('name'),
'value' => gTxt('value'),
'expires' => gTxt('expires'),
'expired' => gTxt('expired')
);
return search_form('smd_vars', 'smd_vars_show', $crit, $methods, $method, 'name');
}
// -------------------------------------------------------------
function smd_vars_change_pageby() {
setcookie('smd_vars_pageby', gps('qty'));
smd_vars_show('');
}
// -------------------------------------------------------------
// Calculate any time offset relative to now, e.g. +1d, +4w, +30s, +10m etc
function smd_vars_calc_expiry($expires, $debug=false) {
$offsetRE = '/(\+|\@)([0-9]+)([A-Za-z])/';
$numOffsets = preg_match_all($offsetRE, $expires, $offsets);
if ($numOffsets > 0) {
$validPeriods = array(
's' => 1,
'm' => 60,
'h' => 3600,
'd' => 86400,
'w' => 604800,
'y' => 31449600,
);
$offNum = $offsets[2][0];
$offPeriod = (array_key_exists($offsets[3][0], $validPeriods)) ? $offsets[3][0] : "s";
$expires = date("Y-m-d H:i:s", time() + ($offNum * $validPeriods[$offPeriod]));
if ($debug) {
echo "++ TIME NOW AND TIME IN $offNum $offPeriod ++";
dmp(date("Y-m-d H:i:s"));
dmp($expires);
}
}
return $expires;
}
// -------------------------------------------------------------
//********************** PUBLIC SIDE TAGS **********************
// -------------------------------------------------------------
// -------------------------------------------------------------
function smd_var_get($atts) {
require_plugin('smd_lib');
extract(lAtts(array(
'name' => '',
'inject' => '',
'allow_spaces' => '0',
'valid' => '1',
'delim' => ',',
'paramdelim' => ':',
'debug' => '0',
), $atts));
if ($name) {$name = doSlash($name);}
list($nget, $ignore) = smd_doList($name, false, '', false, $delim, $allow_spaces);
$ret = false;
$useValid = ($valid) ? (smd_var_status(array('name' => $nget[0], 'type' => 'available, valid')) == "1|1") : 1;
if (smd_vars_table_exists() && $useValid) {
$rs = safe_row('*', 'smd_vars', 'name="'.$nget[0].'"', $debug);
if ($debug) {
echo "++ RAW / REPLACED VAR ++";
dmp($name .' / '. $nget[0]);
echo "++ RECORD ++";
dmp($rs);
}
if ($rs) {
list($vget, $ignore) = smd_doList($rs['value'], false, '', false, $delim, $allow_spaces);
$replacements = array();
if ($inject) {
list($inject, $ignore) = smd_doList($inject, false, '', false, $delim, $allow_spaces);
foreach ($inject as $squirt) {
$nv = do_list($squirt, $paramdelim);
if (count($nv) == 2) {
$replacements[$nv[0]] = $nv[1];
}
}
}
}
$ret = strtr($vget[0], $replacements);
}
return $ret;
}
// -------------------------------------------------------------
function smd_var_put($atts) {
require_plugin('smd_lib');
extract(lAtts(array(
'name' => '',
'value' => '',
'expires' => '',
'get_vals_now' => '1',
'action' => 'replace',
'allow_spaces' => '0',
'return' => 'silent',
'delim' => ',',
'debug' => '0',
), $atts));
$ret = false;
// Validate/process the attributes
if ($name) {$name = doSlash($name);}
if ($value) {$value = doSlash($value);}
if ($expires) {$expires = doSlash($expires);}
$actionOpts = array('replace', 'append', 'prepend', 'delete');
$action = (in_array($action,$actionOpts)) ? $action : $actionOpts[0];
if (smd_vars_table_exists() && $name) {
if ($action == "delete") {
$ret = smd_var_delete(array("name" => $name, "allow_spaces" => $allow_spaces, "debug" => $debug));
} else {
$expires = smd_vars_calc_expiry($expires, $debug);
$expiry = ($expires) ? ", expires='$expires'" : '';
// Decide whether to replace any ? variables with their real value counterparts before insertion. Placeholders are always stored intact
$names = do_list($name, $delim);
$numnames = count($names);
$values = do_list($value, $delim);
for ($idx = 0; $idx < $numnames; $idx++) {
// Hard-code a comma as the delimiter since we're already dealing with individual items after the do_list().
// Since the comma now cannot appear in any entry in $names or $values, this guarantees only one entry in the returned array
list($ninject, $ignore) = smd_doList($names[$idx], false, '', false, ',', $allow_spaces);
if ($get_vals_now) {
list($vinject, $ignore) = smd_doList($values[$idx], false, '', false, ',', $allow_spaces);
} else {
$vinject = array();
$vinject[0] = $values[$idx];
}
if ($debug) {
echo "++ RAW VAR ++";
dmp($names[$idx] .' : '. $values[$idx]);
echo "++ " .(($action=="append") ? "APPENDING TO" : (($action=="prepend") ? "PREPENDING TO" : "REPLACING")). " VAR '$ninject[0]' ++";
dmp($vinject[0]);
}
if ($action == "append") {
$ret = safe_upsert("smd_vars", "value=CONCAT(COALESCE(value, ''), '$vinject[0]')$expiry", "name='$ninject[0]'", $debug);
} else if ($action == "prepend") {
$ret = safe_upsert("smd_vars", "value=CONCAT('$vinject[0]', COALESCE(value, ''))$expiry", "name='$ninject[0]'", $debug);
} else {
$ret = safe_upsert("smd_vars", "value='$vinject[0]'$expiry", "name='$ninject[0]'", $debug);
}
}
}
}
return ($return == "silent") ? '' : $ret;
}
// -------------------------------------------------------------
// Available separately and also called if smd_var_put delete="1" is used
function smd_var_delete($atts) {
require_plugin('smd_lib');
extract(lAtts(array(
'name' => '',
'allow_spaces' => '0',
'debug' => '0',
), $atts));
if ($name) {$name = doSlash($name);}
list($ndel, $ignore) = smd_doList($name, false, '', false, $delim, $allow_spaces);
$ret = false;
if (smd_vars_table_exists()) {
if ($name) {
$ret = safe_delete("smd_vars", "name='$ndel[0]'");
}
}
return;
}
// -------------------------------------------------------------
function smd_var_status($atts) {
require_plugin('smd_lib');
extract(lAtts(array(
'name' => '',
'type' => 'valid',
'allow_spaces' => '0',
'return' => 'number',
'delim' => ',',
'outdelim' => '|',
'debug' => '0',
), $atts));
// Lookup tables
$typeOpts = array('valid', 'available', 'use');
$returnOpts = array('name', 'number');
$stati = array(
'available' => array(smd_vars_gTxt('var_unavailable'), smd_vars_gTxt('var_available')),
'valid' => array(smd_vars_gTxt('var_invalid'), smd_vars_gTxt('var_valid')),
'use' => array(smd_vars_gTxt('var_unused'), smd_vars_gTxt('var_used')),
);
// Validate the options
if ($name) {$name = doSlash($name);}
list($nstat, $ignore) = smd_doList($name, false, '', false, $delim, $allow_spaces);
$return = (in_array($return,$returnOpts)) ? $return : $returnOpts[0];
$types = array();
$type = do_list($type, $delim);
foreach ($type as $thistype) {
$types[] = (in_array($thistype, $typeOpts)) ? $thistype : $typeOpts[0];
}
$types = array_unique($types);
$out = array();
// Get the relevant row and check various parts of it
if (smd_vars_table_exists()) {
$rs = safe_row('*', 'smd_vars', 'name="'.$nstat[0].'"');
if ($debug) {
dmp($rs);
}
foreach ($types as $thistype) {
$ret = 0;
if ($thistype == "available") {
$ret = (count($rs) == 0) ? 0 : 1;
} else if ($thistype == "valid") {
$ret = (count($rs) > 0 && (strtotime($rs['expires']) > time() || $rs['expires'] == "0000-00-00 00:00:00")) ? 1 : 0;
} else if ($thistype == "use") {
$ret = (count($rs) > 0 && $rs['value']!="") ? 1 : 0;
}
$out[] = ($return=="name") ? $stati[$thistype][$ret] : $ret;
}
}
return join($outdelim, $out);
}
// -------------------------------------------------------------
function smd_var_if_status($atts, $thing='') {
extract(lAtts(array(
'name' => '',
'type' => 'valid',
), $atts));
$ret = smd_var_status(array(
'name' => $name,
'type' => $type,
));
return parse(EvalElse($thing, $ret));
}
// -------------------------------------------------------------
// Convenience shortcut functions for smd_var_if_status
function smd_var_if_valid($atts, $thing='') {
extract(lAtts(array('name' => ''), $atts));
return smd_var_if_status(array('name' => $name, 'type' => 'valid'), $thing);
}
function smd_var_if_used($atts, $thing='') {
extract(lAtts(array('name' => ''), $atts));
return smd_var_if_status(array('name' => $name, 'type' => 'use'), $thing);
}
function smd_var_if_available($atts, $thing='') {
extract(lAtts(array('name' => ''), $atts));
return smd_var_if_status(array('name' => $name, 'type' => 'available'), $thing);
}
// -------------------------------------------------------------
// Plugin-specific replacement strings - localise as required
// -------------------------------------------------------------
function smd_vars_gTxt($what, $atts = array()) {
$lang = array(
'smd_vars' => 'Variables',
'add_label' => 'Add',
'cancel_label' => 'cancel',
'clear' => 'clr',
'control' => 'Plugin control',
'delete_failed' => 'Variable NOT deleted.',
'deleted' => 'Variable IDs deleted: {id}',
'deleted_num' => 'Variables deleted: {num}',
'duplicate' => ': already exists.',
'edit' => 'Edit variables',
'empty_expiry' => '-',
'insert_failed' => 'Cannot add var',
'inserted' => 'Var inserted. ',
'list_title' => 'Defined Variables',
'not_available' => 'smd_vars table not installed',
'per_page' => 'Show {pageby} per page',
'purge_expired' => 'Delete all expired variables: are you sure?',
'purge_expired_label' => 'Purge expired',
'table_install_label' => 'Install table',
'table_installed' => 'Vars table installed. ',
'table_not_installed' => 'Vars table NOT installed. ',
'table_not_removed' => 'Vars table NOT removed. ',
'table_remove_check' => 'Delete entire smd_vars table: are you sure?',
'table_remove_label' => 'Remove table',
'table_removed' => 'Vars table removed. ',
'toggle' => 'tog',
'update_failed' => 'Var not updated',
'updated' => 'Var updated. ',
'var_available' => 'available',
'var_invalid' => 'expired',
'var_unavailable' => 'unavailable',
'var_unused' => 'empty',
'var_used' => 'used',
'var_valid' => 'current',
);
return strtr($lang[$what], $atts);
}