First attempt at admin settings page with writeable database backend.

Currently broken due to PHP's transparent conversion of "." to "_" in
POST variable names!
This commit is contained in:
2011-08-24 02:40:16 +01:00
parent 807514daa8
commit 3497eb8e1e
10 changed files with 462 additions and 3 deletions

View File

@@ -25,6 +25,7 @@ class RippingCluster_Main extends SihnonFramework_Main {
$this->smarty->compile_dir = static::makeAbsolutePath($smarty_tmp . '/tmp/templates');
$this->smarty->cache_dir = static::makeAbsolutePath($smarty_tmp . '/tmp/cache');
$this->smarty->config_dir = static::makeAbsolutePath($smarty_tmp . '/config');
$this->smarty->plugins_dir = static::makeAbsolutePath('./source/smarty/plugins');
$this->smarty->registerPlugin('modifier', 'formatDuration', array('RippingCluster_Main', 'formatDuration'));
$this->smarty->registerPlugin('modifier', 'formatFilesize', array('RippingCluster_Main', 'formatFilesize'));

View File

@@ -23,7 +23,8 @@ var rc = {
},
post: function(url, data) {
$.ajax(url, {
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: data,
@@ -134,6 +135,68 @@ var rc = {
} else {
console.log("Action not supported: " +action);
}
},
settings: {
init: function() {
$("#settings_save").click(
function() {
rc.settings.save();
}
);
},
add_stringlist_field: function(id) {
var container = $('#container_'+id);
var next = $('#settings_'+id+'_next');
var next_value = next.val();
var line = $('<div>');
line.attr('id', 'settings_'+id+'_line'+next.val());
line.append($('<input type="text" class="settings_field_string" />'));
line.append(' ');
var button = $('<input type="button" value="-" class="settings_field_remove"/>');
button.click(function() {
rc.settings.remove_field(id, next_value);
});
line.append(button);
// Add the new item
container.append(line);
// Increment the next counter
next.val(parseInt(next_value)+1);
},
remove_field: function(id, line) {
$("#settings_"+id+"_line"+line).remove();
},
save: function() {
var settings = {};
var fields = $("input.setting").get();
for (var i in fields) {
var setting = fields[i];
var name = setting.name;
if (/\[\]$/.test(name)) {
if (! settings[name]) {
settings[name] = [];
}
settings[name].push(setting.value);
} else {
settings[name] = setting.value;
}
}
rc.ajax.post(base_url + "ajax/update-settings/", settings);
}
}
};

View File

@@ -0,0 +1,10 @@
<?php
$main = RippingCluster_Main::instance();
$config = $main->config();
$settings = $config->enumerateAll();
$this->smarty->assign('settings', $settings);
$this->smarty->assign('config', $config);
?>

View File

@@ -0,0 +1,15 @@
<?php
$main = RippingCluster_Main::instance();
$config = $main->config();
// Iterate over the settings and store each one back to the backend
foreach($_POST as $key => $value) {
if ($config->exists($key)) {
$config->set($key, $value);
}
}
$this->smarty->assign('messages', $messages);
?>

View File

@@ -0,0 +1,292 @@
<?php
/**
* Switch statement plugin for smarty.
* This smarty plugin provides php switch statement functionality in smarty tags.
* To install this plugin drop it into your smarty plugins folder. You will also need to manually
* load the plugin sot hat all the hooks are registered properly. Add the following line after
* you load smarty and create an instance of it in your source code.
*
* <code>
* $this->smartyObj->loadPlugin('smarty_compiler_switch');
* </code>
*
* @author Jeremy Pyne <jeremy.pyne@gmail.com>
* - Donations: Accepted via PayPal at the above address.
* - Updated: 02/10/2010 - Version 3.2
* - File: smarty/plugins/compiler.switch.php
* - Licence: CC:BY/NC/SA http://creativecommons.org/licenses/by-nc-sa/3.0/
*
* - Updates
* Version 2:
* Changed the break attribute to cause a break to be printed before the next case, instead of before this
* case. This way makes more sense and simplifies the code. This change in incompatible with code in
* from version one. This is written to support nested switches and will work as expected.
* Version 2.1:
* Added {/case} tag, this is identical to {break}.
* Version 3:
* Updated switch statment to support Smarty 3. This update is NOT backwards compatible but the old version is still maintained.
* Version 3.1:
* Added a prefilter to re-enable the shorthand {switch $myvar} support. To use the shorthand form you will need to add the following line to your code.
* $smarty->loadPlugin('smarty_compiler_switch');
* Version 3.2:
* Fixed a bug when chaining multiple {case} statements without a {break}.
* Version 3.5:
* Updated to work with Smarty 3.0 release. (Tested and working with 3.0.5, no longer compatible with 3.0rcx releases.)
*
* - Bugs/Notes:
*
* @package Smarty
* @subpackage plugins
*
* Sample usage:
* <code>
* {foreach item=$debugItem from=$debugData}
* // Switch on $debugItem.type
* {switch $debugItem.type}
* {case 1}
* {case "invalid_field"}
* // Case checks for string and numbers.
* {/case}
* {case $postError}
* {case $getError|cat:"_ajax"|lower}
* // Case checks can also use variables and modifiers.
* {break}
* {default}
* // Default case is supported.
* {/switch}
* {/foreach}
* </code>
*
* Note in the above example that the break statements work exactly as expected. Also the switch and default
* tags can take the break attribute. If set they will break automatically before the next case is printed.
*
* Both blocks produce the same switch logic:
* <code>
* {case 1 break}
* Code 1
* {case 2}
* Code 2
* {default break}
* Code 3
* </code>
*
* <code>
* {case 1}
* Code 1
* {break}
* {case 2}
* Code 2
* {default}
* Code 3
* {break}
* </code>
*
* Finally, there is an alternate long hand style for the switch statments that you may need to use in some cases.
*
* <code>
* {switch var=$type}
* {case value="box" break}
* {case value="line"}
* {break}
* {default}
* {/switch}
* </code>
*/
//Register the post and pre filters as they are not auto-registered.
$this->registerFilter('post', 'smarty_postfilter_switch');
class Smarty_Compiler_Switch extends Smarty_Internal_CompileBase {
public $required_attributes = array('var');
public $optional_attributes = array();
public $shorttag_order = array('var');
/**
* Start a new switch statement.
* A variable must be passed to switch on.
* Also, the switch can only directly contain {case} and {default} tags.
*
* @param string $tag_arg
* @param Smarty_Compiler $smarty
* @return string
*/
public function compile($args, $compiler){
$this->compiler = $compiler;
$attr = $this->_get_attributes($args);
$_output = '';
$this->_open_tag('switch',array($compiler->tag_nocache));
if (is_array($attr['var'])) {
$_output .= "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$attr['var']['var']."])) \$_smarty_tpl->tpl_vars[".$attr['var']['var']."] = new Smarty_Variable;";
$_output .= "switch (\$_smarty_tpl->tpl_vars[".$attr['var']['var']."]->value = ".$attr['var']['value']."){?>";
} else {
$_output .= '<?php switch (' . $attr['var'] . '){?>';
}
return $_output;
}
}
class Smarty_Compiler_Case extends Smarty_Internal_CompileBase {
public $required_attributes = array('value');
public $optional_attributes = array('break');
public $shorttag_order = array('value', 'break');
/**
* Print out a case line for this switch.
* A condition must be passed to match on.
* This can only go in {switch} tags.
* If break is passed, a {break} will be rendered before the next case.
*
* @param string $tag_arg
* @param Smarty_Compiler $smarty
* @return string
*/
public function compile($args, $compiler){
$this->compiler = $compiler;
$attr = $this->_get_attributes($args);
$_output = '';
list($last_tag, $last_attr) = $this->compiler->_tag_stack[count($this->compiler->_tag_stack) - 1];
if($last_tag == 'case')
{
list($break, $compiler->tag_nocache) = $this->_close_tag(array('case'));
if($last_attr[0])
$_output .= '<?php break;?>';
}
$this->_open_tag('case', array(isset($attr['break']) ? $attr['break'] : false, $compiler->tag_nocache));
if (is_array($attr['value'])) {
$_output .= "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$attr['value']['var']."])) \$_smarty_tpl->tpl_vars[".$attr['value']['var']."] = new Smarty_Variable;";
$_output .= "case \$_smarty_tpl->tpl_vars[".$attr['value']['var']."]->value = ".$attr['value']['value'].":?>";
} else {
$_output .= '<?php case ' . $attr['value'] . ':?>';
}
return $_output;
}
}
class Smarty_Compiler_Default extends Smarty_Internal_CompileBase {
public $required_attributes = array();
public $optional_attributes = array('break');
public $shorttag_order = array('break');
/**
* Print out a default line for this switch.
* This can only go in {switch} tags.
* If break is passed, a {break} will be rendered before the next case.
*
* @param string $tag_arg
* @param Smarty_Compiler $smarty
* @return string
*/
public function compile($args, $compiler){
$this->compiler = $compiler;
$attr = $this->_get_attributes($args);
$_output = '';
list($last_tag, $last_attr) = $this->compiler->_tag_stack[count($this->compiler->_tag_stack) - 1];
if($last_tag == 'case')
{
list($break, $compiler->tag_nocache) = $this->_close_tag(array('case'));
if($last_attr[0])
$_output .= '<?php break;?>';
}
$this->_open_tag('case', array(isset($attr['break']) ? $attr['break'] : false, $compiler->tag_nocache));
$_output .= '<?php default:?>';
return $_output;
}
}
class Smarty_Compiler_Break extends Smarty_Internal_CompileBase {
public $required_attributes = array();
public $optional_attributes = array();
public $shorttag_order = array();
/**
* Print out a break command for the switch.
* This can only go inside of {case} tags.
*
* @param string $tag_arg
* @param Smarty_Compiler $smarty
* @return string
*/
public function compile($args, $compiler){
$this->compiler = $compiler;
$attr = $this->_get_attributes($args);
list($break, $compiler->tag_nocache) = $this->_close_tag(array('case'));
return '<?php break;?>';
}
}
class Smarty_Compiler_Caseclose extends Smarty_Internal_CompileBase {
public $required_attributes = array();
public $optional_attributes = array();
public $shorttag_order = array();
/**
* Print out a break command for the switch.
* This can only go inside of {case} tags.
*
* @param string $tag_arg
* @param Smarty_Compiler $smarty
* @return string
*/
public function compile($args, $compiler){
$this->compiler = $compiler;
$attr = $this->_get_attributes($args);
list($break, $compiler->tag_nocache) = $this->_close_tag(array('case'));
return '<?php break;?>';
}
}
class Smarty_Compiler_Switchclose extends Smarty_Internal_CompileBase {
public $required_attributes = array();
public $optional_attributes = array();
public $shorttag_order = array();
/**
* End a switch statement.
*
* @param string $tag_arg
* @param Smarty_Compiler $smarty
* @return string
*/
public function compile($args, $compiler){
$this->compiler = $compiler;
$attr = $this->_get_attributes($args);
list($last_tag, $last_attr) = $this->compiler->_tag_stack[count($this->compiler->_tag_stack) - 1];
if(($last_tag == 'case' || $last_tag == 'default'))
list($break, $compiler->tag_nocache) = $this->_close_tag(array('case'));
list($compiler->tag_nocache) = $this->_close_tag(array('switch'));
return '<?php }?>';
}
}
/**
* Filter the template after it is generated to fix switch bugs.
* Remove any spaces after the 'switch () {' code and before the first case. Any tabs or spaces
* for layout would cause php errors witch this reged will fix.
*
* @param string $compiled
* @param Smarty_Compiler $smarty
* @return string
*/
function smarty_postfilter_switch($compiled, &$smarty) {
// Remove the extra spaces after the start of the switch tag and before the first case statement.
return preg_replace('/({ ?\?>)\s+(<\?php case)/', "$1\n$2", $compiled);
}
?>

View File

@@ -1 +1,56 @@
Not yet implemented.
<h2>Settings</h2>
<table id="settings">
<thead>
<th>Name</th>
<th>Value</th>
</thead>
<tbody>
{foreach from=$settings item=name}
{assign var='value' value=$config->get($name)}
{assign var='type' value=$config->type($name)}
{assign var='id' value=str_replace('.', '-',$name)}
<tr>
<td>{$name}</td>
<td>
{switch $type}
{case Sihnon_Config::TYPE_BOOL}
<input type="checkbox" id="setting_{$id}" name="{$name}" value="1" {if $value}checked="checked" {/if} class="setting" />
{/case}
{case Sihnon_Config::TYPE_INT}
<input type="text" id="setting_{$id}" name="{$name}" value="{$value}" class="setting settings_field_numeric" />
{/case}
{case Sihnon_Config::TYPE_STRING}
<input type="text" id="setting_{$id}" name="{$name}" value="{$value}" class="setting settings_field_string" />
{/case}
{case Sihnon_Config::TYPE_STRING_LIST}
<div id="container_{$id}">
{foreach from=$value item=line name=settings}
<div id="settings_{$id}_line{$smarty.foreach.settings.iteration}">
<input type="text" name="{$name}[]" value="{$line}" class="setting settings_field_string" />
<input type="button" value="-" class="settings_field_remove" onclick="rc.settings.remove_field('{$id}', '{$smarty.foreach.settings.iteration}')" />
</div>
{/foreach}
</div>
<div class="settings_addfieldcontainer">
<input type="hidden" id="settings_{$id}_next" value="{$smarty.foreach.settings.iteration+1}" />
<input type="button" value="+" class="settings_field_add" onclick="rc.settings.add_stringlist_field('{$id}')" />
</div>
{/case}
{/switch}
</td>
</tr>
{/foreach}
</tbody>
<tfoot>
<tr>
<td colspan="2">
<input type="button" id="settings_save" name="save" value="Save" />
</td>
</tr>
</tfoot>
</table>
<script type="text/javascript">
rc.settings.init();
</script>

View File

@@ -2,7 +2,7 @@
{if $messages}
messages: [
{foreach from=$messages item=message}
'{$message}',
'{$message|json_encode}',
{/foreach}
],
{/if}

View File

@@ -8,4 +8,10 @@
<li><a href="{$base_uri}sources/list" title="Browse Sources">Sources</a></li>
</ul>
</li>
<li>Admin
<ul>
<li><a href="{$base_uri}admin/settings" title="Edit Settings">Settings</a></li>
</ul>
</li>
</ul>

View File

@@ -142,6 +142,23 @@ label {
text-align: right;
}
table#settings {
}
table#settings td {
padding: 1.0em;
border: 1px solid;
border-collapse: collapse;
}
table#settings input[type=text] {
width: 40em;
}
.settings_addfieldcontainer {
text-align: right;
}
.default {
background: beige;
color: darkgray;