// ------------------------------------------------------------- //********************** 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_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 = '
' . fInput('submit', 'submit', smd_vars_gTxt('table_install_label'), 'smallerbox') . '
'; $btnRemoveTbl = '
' . fInput('submit', 'submit', smd_vars_gTxt('table_remove_label'), 'smallerbox') . '
'; $btnPurgeExpired = '
' . fInput('submit', 'submit', smd_vars_gTxt('purge_expired_label'), 'smallerbox') . '
'; $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 startTable('list'); echo tr(tda(strong(smd_vars_gTxt('list_title')), ' colspan="5"')); echo tr( column_head('id', 'id', 'smd_vars', true, $switch_dir, $crit, $search_method, ('id' == $sort) ? $dir : ''). column_head('name', 'name', 'smd_vars', true, $switch_dir, $crit, $search_method, ('name' == $sort) ? $dir : ''). column_head('value', 'value', 'smd_vars', true, $switch_dir, $crit, $search_method, ('value' == $sort) ? $dir : ''). column_head('expires', 'expires', 'smd_vars', true, $switch_dir, $crit, $search_method, ('expires' == $sort) ? $dir : ''). column_head('expired', 'expired', 'smd_vars', false) ); if ($step != "smd_vars_edit") { $out = td(' '); $out .= fInputCell('new_name', $theName); $out .= fInputCell('new_value', $theValue, '', 42); $out .= fInputCell('new_expiry', $theExpires); $out .= td(' '); $out .= tda($btnAdd, $btnStyle); echo tr($out); } // Note the negative logic in the 'expired' column (since smd_var_status returns 1 if 'valid') $rs = safe_rows_start('*', 'smd_vars', "$criteria order by $sort_sql limit $offset, $limit"); while ($a = nextRow($rs)) { $expiry = ($a['expires']=="0000-00-00 00:00:00") ? smd_vars_gTxt('empty_expiry') : $a['expires']; $expireLabel = smd_var_status(array("name" => $a['name'])) ? (($expiry == smd_vars_gTxt('empty_expiry')) ? smd_vars_gTxt('empty_expiry') : gTxt('no')) : gTxt('yes'); if ($step == "smd_vars_edit" && $id == $a['id']) { $out = td($a['id']); $out .= fInputCell('new_name', $a['name']); $out .= fInputCell('new_value', $a['value'], '', 42); $out .= fInputCell('new_expiry', $expiry); $out .= td($expireLabel); $out .= tda(fInput('submit', 'smd_vars_update', gTxt('save'), 'smallerbox', '', 'smd_var_step=this.name;smd_var_id=\''.$a['id'].'\'')); $out .= tda(fInput('submit', 'smd_vars_cancel', smd_vars_gTxt('cancel_label'), 'smallerbox', '', 'smd_var_step=this.name;smd_var_id=\'\'')); } else { $out = tag($a['id'], 'td'); $out .= tag($a['name'], 'td'); $out .= tag(($a['value'] ? $a['value'] : ' '), 'td'); $out .= tag($expiry, 'td'); $out .= tag($expireLabel, 'td'); $out .= tda(fInput('submit', 'smd_vars_edit', gTxt('edit'), 'smallerbox', '', 'smd_var_step=this.name;smd_var_id=\''.$a['id'].'\'')); $out .= td(dLink('smd_vars', 'smd_vars_delete', 'id', $a['id'], '', '', '', false, array($page, $sort, $dir, $crit, $search_method)), 10); $out .= td(fInput('checkbox', 'selected[]', $a['id'])); } echo tr($out, ' class="smd_vars_row" id="'.$a['id'].'"'); } echo tda(select_buttons() . event_multiedit_form('smd_vars', NULL, $page, $sort, $dir, $crit, $search_method), ' colspan="5" style="text-align: right; border: none;"'); echo endTable(); 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); }