From 9a0dd1cd2455e76b27108787fa9f739bec1b19ae Mon Sep 17 00:00:00 2001 From: Chuck Hagenbuch Date: Sat, 10 Jan 2009 12:38:25 -0500 Subject: [PATCH] super-crude adaptation of Rdo helper code. Needs lots of work. --- framework/Rdo/www/Form_Helper.php | 474 +++++++++++++++++++++++++++++ framework/Rdo/www/Form_Renderer_Helper.php | 26 ++ framework/Rdo/www/Lens.php | 23 ++ framework/Rdo/www/Table_Helper.php | 308 +++++++++++++++++++ framework/Rdo/www/Table_Helper_Lens.php | 44 +++ framework/Rdo/www/crud.php | 133 ++++++++ framework/Rdo/www/index.php | 49 +++ 7 files changed, 1057 insertions(+) create mode 100644 framework/Rdo/www/Form_Helper.php create mode 100644 framework/Rdo/www/Form_Renderer_Helper.php create mode 100644 framework/Rdo/www/Lens.php create mode 100644 framework/Rdo/www/Table_Helper.php create mode 100644 framework/Rdo/www/Table_Helper_Lens.php create mode 100644 framework/Rdo/www/crud.php create mode 100644 framework/Rdo/www/index.php diff --git a/framework/Rdo/www/Form_Helper.php b/framework/Rdo/www/Form_Helper.php new file mode 100644 index 000000000..e65213e57 --- /dev/null +++ b/framework/Rdo/www/Form_Helper.php @@ -0,0 +1,474 @@ + + * @since Horde 4.0 + * @package Horde_Rdo + */ +class Horde_Rdo_Form_Helper extends Horde_Form +{ + /** + * The primary key(s) of the resource. + * + * @var string + */ + protected $primaryKey; + + /** + * Rdo_Mapper object that we display. + * + * @var Horde_Rdo_Mapper $mapper + */ + protected $mapper; + + /** + * Extends Horde_Form for general purposes and prepare initial form. + */ + public function __construct($vars, $title = '', $name = null, $params = null) + { + parent::__construct($vars, $title, $name); + + if (is_array($params)) { + $this->mapper = $params['mapper']; + unset($params['mapper']); + } else { + $this->mapper = $params; + $params = array(); + } + + if ($vars->exists('action')) { + $this->addHidden('', 'action', 'text', true); + } + if ($vars->exists('table')) { + $this->addHidden('', 'table', 'text', true); + } + if ($vars->exists('what2process')) { + $this->addHidden('', 'what2process', 'text', true); + } + + /* Determinate action */ + if ($vars->get('submitbutton') == _("Advanced search")) { + $vars->set('action', 'search_active'); + $this->_submitted = false; + } elseif ($vars->get('submitbutton') == _("Basic search")) { + $vars->set('action', 'search'); + $this->_submitted = false; + } elseif (isset($params['action'])) { + $vars->set('action', $params['action']); + } + + $i = 0; + $this->getPrimaryKey(); + $allFields = $this->getFields($vars->get('action')); + + /* Determine what to display */ + if ($vars->get('action') == 'search_active') { + if ($vars->get('fields')) { + $fields = explode('|', $vars->get('fields')); + } else { + $fields = $this->primaryKey; + } + if ($vars->get('horde_helper_add')) { + $fields[] = $vars->get('horde_helper_add'); + $vars->set('horde_helper_add', null); + } + } else { + $fields = $allFields; + } + + /* Loop to add fields */ + foreach ($fields as $key) { + if ($key == 'created' || $key == 'updated') { + continue; + } + + $params = $this->formMeta($vars->get('action'), $key); + if (is_object($params)) { + return $params; + } + + $this->_currentSection = $params['section']; + + switch ($vars->get('action')) { + case 'create': + if ($params['readonly']) { + continue 2; + } + break; + + case 'update': + if (in_array($key, $this->primaryKey)) { + $this->addHidden('', $key, $params['type'], true); + $params['readonly'] = true; + } + break; + + case 'search': + case 'search_active': + $key .= '_' . $i++; + $params['readonly'] = false; + $params['required'] = false; + if (!$params['hidden']) { + $this->addCase($params['humanName'], $key); + } + break; + } + + if ($params['hidden']) { + $this->addHidden('', $key, $params['type'], $params['required']); + continue; + } + + $v = $this->addVariable($params['humanName'], $key, $params['type'], + $params['required'], $params['readonly'], + $params['description'], $params['params']); + + if (!empty($params['help'])) { + $v->setHelp($params['help']); + } + if (!empty($params['default'])) { + $v->setDefault($params['default']); + } + } + + switch ($vars->get('action')) { + case 'search': + $this->_submit = array(_("Search"), _("Advanced search")); + break; + + case 'search_active': + require_once 'Horde/Array.php'; + $params = array(Horde_Array::valuesToKeys($allFields), true); + $this->addVariable(_("Add"), 'horde_helper_add', 'enum', false, false, null, $params); + $this->_submit = array(_("Search"), _("Add"), _("Basic search")); + $this->addHidden('', 'fields', 'text', true); + $vars->set('fields', implode('|', $fields)); + break; + + case 'create': + $this->_submit = _("Create"); + break; + + case 'update': + $this->_submit = _("Update"); + $this->_reset = _("Reset"); + } + } + + /** + * Add a comparison operator selection + */ + protected function addCase($humanName, $key) + { + $this->addVariable($humanName, 'cases_' . $key, 'enum', false, false, 'cases', + array(array('=' => '=', '>' => '>', '<' => '<', + '>=' => '>=', '<=' => '<=', '<>' => '<>', + 'LIKE' => 'LIKE', 'NOT LIKE' => 'NOT LIKE', + 'IS' => 'IS', 'IS NOT' => 'IS NOT'))); + } + + /** + * Map from columns to Horde_Form types and attributes: + * Create values like Horde_Form::addVariable parameters + * - humanName + * - type + * - required + * - readonly + * - description + * - params + */ + protected function formMeta($action, $column, $key = false) + { + static $map; + + if ($map === null) { + $map = $this->formMetaData($action); + if ($map instanceof PEAR_Error) { + return $map; + } + if (isset($map['__sections']) && $this->_vars->action != 'search_active') { + foreach ($map['__sections'] as $section => $value) { + $this->setSection($section, $value['desc'], $value['image'], $value['expanded']); + } + unset($map['__sections']); + } + + foreach ($this->getFields($action) as $id) { + if (!isset($map[$id])) { + $map[$id] = array(); + } + if (!isset($map[$id]['hidden'])) { + $map[$id]['hidden'] = false; + } + if (!isset($map[$id]['humanName'])) { + $map[$id]['humanName'] = $id; + } + if (!isset($map[$id]['section'])) { + $map[$id]['section'] = '__base'; + } + if (!isset($map[$id]['readonly'])) { + $map[$id]['readonly'] = false; + } + if (!isset($map[$id]['params'])) { + $map[$id]['params'] = array(); + } + if (!isset($map[$id]['description'])) { + $map[$id]['description'] = ''; + } + if (!isset($map[$id]['required'])) { + $map[$id]['required'] = in_array($id, $this->primaryKey); + } + if ($action == 'update' && in_array($id, $this->primaryKey)) { + $map[$id]['readonly'] = true; + } + + if (!isset($map[$id]['type'])) { + $map[$id]['type'] = 'text'; + } else { + + /* trim aditonal parameters like decimal(10,2)*/ + if (strpos($map[$id]['type'], '(')) { + $map[$id]['type'] = substr($map[$id]['type'], 0, strpos($map[$id]['type'], '(')); + } + + switch ($map[$id]['type']) { + case 'date': + $map[$id]['type'] = 'monthdayyear'; + $map[$id]['params'] = array('', '', true, '%Y-%m-%d'); + break; + + case 'number': + case 'decimal': + case 'real': + $map[$id]['type'] = 'number'; + break; + + case 'text': + $map[$id]['type'] = 'longtext'; + break; + + default: + if (!class_exists('Horde_Form_Type_' . $map[$id]['type'], false)) { + $map[$id]['type'] = 'text'; + } + break; + } + } + } + } + + + if ($key) { + return $map[$column][$key]; + } else { + return $map[$column]; + } + } + + /** + * Return the form values of primary keys. + */ + public function getSelected() + { + static $params; + + if (is_null($params)) { + foreach ($this->primaryKey as $key) { + if ($this->_vars->$key) { + $params[$key] = $this->_vars->$key; + } + } + } + + return $params; + } + + function getRenderer($params = array()) + { + if ($this->_vars->action == 'search' || $this->_vars->action == 'search_active') { + $renderer = new Horde_Form_Renderer_Form_Helper($params); + } else { + $renderer = new Horde_Form_Renderer($params); + } + + return $renderer; + } + + /** + * Fetch the field values of the submitted form. + * + * @param Variables $vars The Variables object. + * @param array $info Array to be filled with the submitted field + * values. + */ + function getInfo($vars, &$info) + { + if (!$this->isSubmitted()) { + $info = array(); + return; + } + + parent::getInfo($vars, $info); + + /* Add test cases and filter not existing filters */ + if ($this->_vars->action == 'search' || $this->_vars->action == 'search_active') { + $fields = $this->getFields('search'); + foreach ($info as $key => $value) { + $name = substr($key, 0, strrpos($key, '_')); + if (empty($value) || !in_array($name, $fields)) { + if (substr($key, 0, 6) != 'cases_') { + unset($info[$key], + $info['cases_' . $key]); + } + continue; + } + switch ($info['cases_' . $key]) { + case 'IS': + case 'IS NOT': + if (!defined($value)) { + unset($info[$key], + $info['cases_' . $key]); + continue 2; + } + $value = constant($value); + break; + + case 'LIKE': + case 'NOT LIKE': + if (strpos($value, '%') === false) { + $value = "%$value%"; + } + break; + } + + $info[$key] = array('field' => $name, + 'test' => $info['cases_' . $key], + 'value' => $value); + unset($info['cases_' . $key]); + } + } + } + + /** + * Return the selected object or false if none. + */ + public function getSelected() + { + return $this->mapper->find(Horde_Rdo::FIND_FIRST, + parent::getSelected()); + } + + /** + * Return the form meta data + */ + public function formMetaData($action) + { + if (method_exists($this->mapper, 'formMeta')) { + return $this->mapper->formMeta($action); + } else { + return $this->mapper->model->getFields(); + } + } + + /** + * Array of field name. + */ + protected function getFields($action) + { + static $fields; + + if ($fields !== null) { + return $fields; + } + + if (method_exists($this->mapper, 'formFields')) { + $fields = $this->mapper->formFields($action); + } else { + $fields = $this->mapper->model->listFields(); + } + + return $fields; + } + + /** + * Get primary key. + */ + protected function getPrimaryKey() + { + if ($this->primaryKey !== null) { + return $this->primaryKey; + } + + if (method_exists($this->mapper, 'getPrimaryKey')) { + $this->primaryKey = $this->mapper->getPrimaryKey(); + } else { + $this->primaryKey = array($this->mapper->model->key); + } + } + + /** + * Delect selected record. + */ + public function delete() + { + try { + $this->getSelected()->delete(); + } catch (Exception $e) { + return PEAR::raiseError($e->getMessage()); + } + } + + /** + * Create a new record. + */ + public function create($params) + { + foreach ($params as $key => $value) { + $meta = $this->formMeta('update', $key); + if ($meta['type'] == 'set') { + $params[$key] = implode('|', $value); + } + } + + try { + $this->mapper->create($params); + } catch (Exception $e) { + return PEAR::raiseError($e->getMessage()); + } + } + + /** + * Update selected record. + */ + public function update($params) + { + foreach ($params as $key => $value) { + $meta = $this->formMeta('update', $key); + if ($meta['type'] == 'set' && is_array($value)) { + $params[$key] = implode('|', $value); + } + } + + $selected = $this->getSelected(); + foreach ($params as $key => $value) { + $selected->$key = $value; + } + + try { + $selected->save(); + } catch (Exception $e) { + return PEAR::raiseError($e->getMessage()); + } + } + +} diff --git a/framework/Rdo/www/Form_Renderer_Helper.php b/framework/Rdo/www/Form_Renderer_Helper.php new file mode 100644 index 000000000..347668622 --- /dev/null +++ b/framework/Rdo/www/Form_Renderer_Helper.php @@ -0,0 +1,26 @@ +description != 'cases' && $var->varName != 'horde_helper_add') { + return; + } + + parent::_renderVarInputBegin($form, $var, $vars); + } + + function _renderVarInputEnd($form, $var, $vars) + { + if ($var->description == 'cases' && $var->varName != 'horde_helper_add') { + echo ' '; + return; + } + + parent::_renderVarInputEnd($form, $var, $vars); + } + +} diff --git a/framework/Rdo/www/Lens.php b/framework/Rdo/www/Lens.php new file mode 100644 index 000000000..07c62a658 --- /dev/null +++ b/framework/Rdo/www/Lens.php @@ -0,0 +1,23 @@ + + * @since Horde 4.0 + * @package Horde_Rdo + */ +class Horde_Rdo_Table_Helper extends Horde_Template +{ + /** + * Parameters for this Template instance. + * + * @var array + */ + protected $params = array(); + + /** + * Mapper object that we display. + * + * @var Horde_Rdo_Mapper $object + */ + protected $object; + + /** + * Constructor + * + * @param Horde_Rdo_Mapper $object Mapper instance. + * @param array $params Template defaults. + */ + public function __construct($params = array(), $object) + { + $this->object = $object; + $params['name'] = $object->model->table; + $params['id'] = $object->model->table; + + $defaults = array( + 'delete' => true, + 'update' => true, + 'columns' => null, + 'name' => '', + 'id' => '', + 'page' => 0, + 'url' => Horde::selfUrl(), + 'img_dir' => $GLOBALS['registry']->getImageDir('horde'), + 'sort' => array(), + 'filter' => array(), + ); + + $this->params = array_merge($defaults, $params); + + parent::Horde_Template(); + $this->setOption('gettext', true); + } + + /** + * Get Rdo members. + */ + public function getRows() + { + $query = $this->prepareQuery(); + if (!empty($this->params['perpage'])) { + $limit = $this->params['perpage']; + $offset = $this->params['page'] * $this->params['perpage']; + $query->limit($limit, $offset); + } + + $rows = new Horde_Rdo_List($query); + + if (!empty($this->params['decorator'])) { + $decorator = $this->params['decorator']; + $rows = new Horde_Lens_Iterator($rows, new $decorator()); + } + + return $rows; + } + + /** + * Count Rdo members. + * + * @param array $filter filter/search rows + */ + public function count() + { + return $this->object->count($this->prepareQuery()); + } + + /** + * Prepares Rdo query. + */ + private function prepareQuery() + { + $query = new Horde_Rdo_Query($this->object); + + if (!empty($this->params['filter'])) { + foreach ($this->params['filter'] as $key => $val) { + if (is_array($val)) { + $query->addTest($val['field'], $val['test'], $val['value']); + } else { + $query->addTest($key, '=', $val); + } + } + } + + if (!empty($this->params['sort'])) { + if (!is_array($this->params['sort'])) { + $this->params['sort'] = array($this->params['sort']); + } + foreach ($this->params['sort'] as $sort) { + if (is_array($sort)) { + $query->sortBy($sort[0], $sort[1]); + } else { + $query->sortBy($sort); + } + } + } + + return $query; + } + + /** + * Return field information. + */ + protected function getFields() + { + if ($this->params['columns']) { + return $this->params['columns']; + } elseif (!empty($this->params['relationships'])) { + $fields = $this->object->model->listFields(); + foreach ($this->object->relationships as $r) { + $mapper_name = $r['mapper']; + $mapper = new $mapper_name(); + $fields = array_merge($fields, $mapper->model->listFields()); + } + return $fields; + } else { + return $this->object->model->listFields(); + } + } + + /** + * Return field names. + */ + protected function listFields() + { + $meta = array(); + if (method_exists($this->object, 'formMeta')) { + $meta = $this->object->formMeta('table'); + if ($meta instanceof PEAR_Error) { + return $meta; + } + } + + $columns = array(); + + $keys = $this->getFields(); + foreach ($keys as $key) { + if (isset($meta[$key]['humanName'])) { + $columns[$key] = $meta[$key]['humanName']; + } elseif ($key == 'created') { + $columns[$key] = 'Created'; + } elseif ($key == 'updated') { + $columns[$key] = 'Updated'; + } else { + $columns[$key] = $key; + } + } + + return $columns; + } + + /** + * Get primary key. + */ + protected function getPrimaryKey() + { + if (method_exists($this->object, 'getPrimaryKey')) { + $keys = $this->object->getPrimaryKey(); + } else { + $keys = array($this->object->model->key); + } + + if (!$keys) { + $keys = $this->getFields(); + } + + return $keys; + } + + /** + * Fetch template. + * + * @param string $template Template path. + */ + public function fetch($template = null) + { + if ($template === null) { + $template = $this->getTemplateFile(); + } + if ($template) { + return parent::fetch($template); + } + return parent::parse($this->getTemplate()); + } + + public function __toString() + { + return $this->fetch(); + } + + /** + * Fill up table data. + */ + public function fill() + { + $this->set('rows', $this->getRows()); + + if (empty($this->_scalars['img_dir'])) { + $this->set('img_dir', $this->params['img_dir']); + } + + if (empty($this->_scalars['url'])) { + $this->set('url', $this->params['url']); + } + } + + /** + * Get template path if it exists. + * + * @return string Template filename. + */ + protected function getTemplateFile() + { + $filename = $GLOBALS['registry']->get('templates') . DIRECTORY_SEPARATOR . $this->params['name'] . '.html'; + if (file_exists($filename)) { + return $filename; + } + + $filename = $GLOBALS['registry']->get('templates', 'horde') . DIRECTORY_SEPARATOR . $this->params['name'] . '.html'; + if (file_exists($filename)) { + return $filename; + } + + return false; + } + + /** + * Create template content. + * + * @return string $content + */ + public function getTemplate() + { + $url = ''; + $columns = $this->listFields(); + + $keys = array(); + $primaryKeys = $this->getPrimaryKey(); + foreach ($primaryKeys as $key) { + $keys[] = $key . '='; + } + $keys = implode('&', $keys); + + $content = '' . "\n" . + '' . "\n" . '' . "\n"; + if ($this->params['update'] || $this->params['delete']) { + $content .= '' . "\n"; + } + foreach ($columns as $key => $name) { + if (in_array($key, $this->params['sort'])) { + $content .= '' . "\n"; + } else { + $content .= '' . "\n"; + } + } + $content .= '' . "\n" . '' . "\n" . '' . + '' . "\n"; + + /* Actions. */ + if ($this->params['update'] || $this->params['delete']) { + $content .= '' . "\n"; + } + + foreach ($columns as $key => $name) { + $content .= ''; + } + + return $content . '' . "\n" . '' . "\n" . '
Actions' . htmlspecialchars($name) . '' . htmlspecialchars($name) . '
' . "\n"; + if ($this->params['update']) { + $content .= '' . + '<gettext>Edit</gettext> ' . "\n"; + } + if ($this->params['delete']) { + $content .= '' . + '<gettext>Delete</gettext> ' . "\n"; + } + $content .= '
'; + } + +} diff --git a/framework/Rdo/www/Table_Helper_Lens.php b/framework/Rdo/www/Table_Helper_Lens.php new file mode 100644 index 000000000..3e2cf8894 --- /dev/null +++ b/framework/Rdo/www/Table_Helper_Lens.php @@ -0,0 +1,44 @@ +date_format = $GLOBALS['prefs']->getValue('date_format'); + $this->time_format = $GLOBALS['prefs']->getValue('twentyFour') ? 'G:i' : 'g:ia'; + } + + /** + */ + public function decorate($target) + { + if (!is_object($target)) { + $target = (object)$target; + } + return parent::decorate($target); + } + + /** + */ + public function __get($key) + { + $value = parent::__get($key); + if ($key == 'updated' || $key == 'created') { + return strftime($this->date_format, $value) . ' ' . date($this->time_format , $value); + } + return htmlspecialchars($value); + } + +} diff --git a/framework/Rdo/www/crud.php b/framework/Rdo/www/crud.php new file mode 100644 index 000000000..b48fe0521 --- /dev/null +++ b/framework/Rdo/www/crud.php @@ -0,0 +1,133 @@ + + * + * $Horde: incubator/Horde_Rdo/crud.php,v 1.8 2008/09/02 17:25:04 chuck Exp $ + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @author Duck + * @since Horde 4.0 + * @package Horde_Rdo + */ + +@define('HORDE_BASE', dirname(__FILE__) . '/../../'); +require_once HORDE_BASE . '/lib/base.php'; + +if (!Auth::isAdmin()) { + die('Permission denied'); +} + +require_once 'Horde/Variables.php'; +require_once 'Horde/Autoloader.php'; +require_once dirname(__FILE__) . '/Form.php'; +require_once dirname(__FILE__) . '/Table.php'; + +$what2process = Util::getFormData('what2process', 'Rdo'); +$table = Util::getFormData('table', 'horde_user'); +$self_url = Util::addParameter(Horde::selfUrl(false), array('table' => $table, 'what2process' => $what2process), null, false); + +if ($what2process == 'Rdo') { + + /** + */ + class Test extends Horde_Rdo_Base { + } + + /** + */ + class TestMapper extends Horde_Rdo_Mapper { + + /** + * TestMapper constructor. Sets table name. + */ + public function __construct($table) + { + $this->_table = $table; + } + + public function getAdapter() + { + return Horde_Rdo_Adapter::factory('pdo', $GLOBALS['conf']['sql']); + } + + } + + $mapper = new TestMapper($table); +} else { + /** + */ + $mapper = $table; +} + +$action = Util::getFormData('action'); + +$filter = Util::getFormData('filter', array()); +$title = sprintf('%s: %s', $action, $table); + +$vars = Variables::getDefaultVariables(); +$form = Horde_Form_Helper::factory($what2process, $vars, $title, null, $mapper); + +switch ($action) { +case 'delete': + $form->delete(); + $notification->push(_("Deleted"), 'horde.success'); + header('Location: ' . $self_url); + exit; + +case 'create': + if (!$form->validate()) { + break; + } + $form->getInfo($vars, $info); + unset($info['action']); + $form->create($info); + $notification->push(_("Created"), 'horde.success'); + header('Location: ' . $self_url); + exit; + +case 'update': + $test = $form->getSelected(); + if (!$form->isSubmitted()) { + foreach ($test as $key => $value) { + $vars->set($key, $value); + } + } elseif ($form->validate()) { + $form->getInfo($vars, $info); + unset($info['action']); + $form->update($info); + $notification->push(_("Updated"), 'horde.success'); + header('Location: ' . $self_url); + exit; + } + break; + +case 'search': +case 'search_active': + $form->getInfo($vars, $filter); + $self_url = Util::addParameter($self_url, 'action', 'search'); + break; +} + +Horde::addScriptFile('stripe.js', 'horde', true); +require HORDE_TEMPLATES . '/common-header.inc'; + +echo "

$what2process

"; + +if (!in_array($action, array('create', 'update'))) { + $template = Horde_Table_Helper::factory($what2process, + array('filter' => $filter, + 'url' => $self_url), + $mapper); + $template->fill(); + echo $template->fetch(); +} + +if (in_array($action, array('create', 'update', 'search', 'search_active'))) { + $form->renderActive(null, null, $self_url, 'post'); +} + +require HORDE_TEMPLATES . '/common-footer.inc'; diff --git a/framework/Rdo/www/index.php b/framework/Rdo/www/index.php new file mode 100644 index 000000000..259fc8b6e --- /dev/null +++ b/framework/Rdo/www/index.php @@ -0,0 +1,49 @@ + + * + * $Horde: incubator/Horde_Rdo/index.php,v 1.2 2007/06/27 17:23:28 jan Exp $ + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @author Duck + * @since Horde 4.0 + * @package Horde_Rdo + */ + +@define('HORDE_BASE', dirname(__FILE__) . '/../../'); +require_once HORDE_BASE . '/lib/base.php'; + +if (!Auth::isAdmin()) { + die('Permission denied'); +} + +require_once 'Horde/Form.php'; +require_once 'Horde/Form/Renderer.php'; +require_once 'Horde/Variables.php'; +require_once 'Horde/Array.php'; + +$vars = Variables::getDefaultVariables(); + +$dbh = DB::connect($conf['sql']); +$tables = $dbh->getListOf('tables'); +$tables = Horde_Array::valuesToKeys($tables); + +$actions = array('create' => _("Create"), + 'search' => _("Search"), + 'search_active' => _("Search Active")); + +$form = new Horde_Form($vars, _("Select table"), 'select_table'); +$form->addVariable(_("Table"), 'table', 'enum', true, false, false, array($tables)); +$form->addVariable(_("Action"), 'action', 'enum', true, false, false, array($actions)); +$form->addVariable(_("Process type"), 'what2process', 'enum', true, false, false, array(array('Rdo' => 'Rdo', + 'DB' => 'DB'))); + +require HORDE_TEMPLATES . '/common-header.inc'; + +$form->renderActive(null, null, 'crud.php', 'post'); + +require HORDE_TEMPLATES . '/common-footer.inc'; -- 2.11.0