From 7f15da0b74db80b8fab4e02228fb1462acfc82cb Mon Sep 17 00:00:00 2001 From: secretr Date: Fri, 30 Oct 2009 17:59:32 +0000 Subject: [PATCH] Admin tools - more work --- e107_admin/newspost.php | 12 +- e107_handlers/admin_handler.php | 762 +++++++++++++++------- e107_handlers/calendar/calendar_class.php | 63 +- e107_handlers/date_handler.php | 37 +- e107_handlers/e107_class.php | 8 +- e107_handlers/form_handler.php | 270 +++++--- e107_handlers/js_manager.php | 20 +- e107_handlers/message_handler.php | 17 +- e107_handlers/model_class.php | 380 +++++++---- e107_handlers/validator_class.php | 6 +- e107_plugins/release/admin_config.php | 80 ++- e107_plugins/release/release_sql.php | 2 +- 12 files changed, 1120 insertions(+), 537 deletions(-) diff --git a/e107_admin/newspost.php b/e107_admin/newspost.php index b58685dcd..9695b3433 100644 --- a/e107_admin/newspost.php +++ b/e107_admin/newspost.php @@ -9,9 +9,9 @@ * News Administration * * $Source: /cvs_backup/e107_0.8/e107_admin/newspost.php,v $ - * $Revision: 1.61 $ - * $Date: 2009-10-26 07:26:47 $ - * $Author: e107coders $ + * $Revision: 1.62 $ + * $Date: 2009-10-30 17:59:32 $ + * $Author: secretr $ */ require_once("../class2.php"); @@ -265,7 +265,7 @@ class admin_newspost 'news_title' => array('title' => NWSLAN_40, 'type' => 'text', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false), 'news_rewrite_string' => array('title' => 'SEF URL', 'type' => 'text', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false), 'user_name' => array('title' => LAN_NEWS_50, 'type' => 'text', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false), - 'news_datestamp' => array('title' => LAN_NEWS_32, 'type' => 'datestamp', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false, 'colparms' => 'mask=%A %d %B %Y'), + 'news_datestamp' => array('title' => LAN_NEWS_32, 'type' => 'datestamp', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false, 'parms' => 'mask=%A %d %B %Y'), 'category_name' => array('title' => NWSLAN_6, 'type' => 'text', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false), 'news_class' => array('title' => NWSLAN_22, 'type' => 'userclass', 'width' => 'auto', 'thclass' => '', 'class' => null, 'nosort' => false), 'news_render_type' => array('title' => LAN_NEWS_49, 'type' => 'dropdown', 'width' => 'auto', 'thclass' => 'center', 'class' => null, 'nosort' => false), @@ -1143,7 +1143,7 @@ class admin_newspost } // AUTO RENDER - $text .= $frm->trow($this, $row); + $text .= $frm->trow($this->fields, $this->fieldpref, $row, 'news_id'); } $text .= " @@ -1207,7 +1207,7 @@ class admin_newspost 'comments' => array('Modify Comments', $comments_array), '__check_class' => array('category' => $news_manage) ), - array( + array( 'userclass' => array('Assign Visibility...',$classes), ) ); diff --git a/e107_handlers/admin_handler.php b/e107_handlers/admin_handler.php index 246e97dd3..583fd4986 100644 --- a/e107_handlers/admin_handler.php +++ b/e107_handlers/admin_handler.php @@ -102,7 +102,7 @@ class e_admin_request * Current action * @var string */ - protected $_action = 'default'; + protected $_action = 'index'; /** * Key name for action search @@ -482,7 +482,7 @@ class e_admin_response */ public function __construct() { - $this->__render_mod['default'] = 'admin_page'; + $this->_render_mod['default'] = 'admin_page'; } /** @@ -575,7 +575,7 @@ class e_admin_response * @return e_admin_response */ function appendTitle($title, $namespace = 'default') - { + { if(empty($title)) { return $this; @@ -584,7 +584,7 @@ class e_admin_response { $this->_title[$namespace] = array(); } - $this->_title[$namespace][] = $title; + $this->_title[$namespace][] = $title; return $this; } @@ -620,10 +620,9 @@ class e_admin_response function getTitle($namespace = 'default', $reset = false, $glue = ' - ') { $content = array(); - if(!isset($this->_title[$namespace]) && is_array($this->_title[$namespace])) + if(isset($this->_title[$namespace]) && is_array($this->_title[$namespace])) { $content = $this->_title[$namespace]; - } if($reset) { @@ -811,7 +810,7 @@ class e_admin_response ), $options); $content = $this->getBody($name, true); - $title = $this->getTitle($name, true); + $title = $this->getTitle($name, true); $return = $options['return']; if($options['ajax'] || e_AJAX_REQUEST) @@ -841,7 +840,7 @@ class e_admin_response { $options['render'] = false; } - + if($options['render']) { return e107::getRender()->tablerender($title, $content, $this->getRenderMod($name), $return); @@ -1138,6 +1137,20 @@ class e_admin_dispatcher $request->setMode($this->getDefaultControllerName())->setAction('e404'); $this->_current_controller->setRequest($request)->init(); } + + if(vartrue($this->controllerList[$request->getModeName()]['ui'])) + { + $class_name = $this->controllerList[$request->getModeName()]['ui']; + $class_path = vartrue($this->controllerList[$request->getModeName()]['uipath']); + if($class_path) + { + require_once(e107::getParser()->replaceConstants($class_path)); + } + if(class_exists($class_name))//NOTE: autoload in the play + { + $this->_current_controller->setParam('ui', new $class_name($this->_current_controller)); + } + } } return $this; @@ -1185,7 +1198,7 @@ class e_admin_dispatcher case 'url': $k2 = 'link'; - $v = $tp->replaceConstants($v, 'abs').'?mode='.$tmp[0].'&action='.$tmp[1]; + $v = $tp->replaceConstants($v, 'abs').'?mode='.$tmp[0].'&action='.$tmp[1]; break; default: @@ -1194,9 +1207,9 @@ class e_admin_dispatcher } $var[$key][$k2] = $v; } - if(vartrue($var[$key]['link'])) + if(!vartrue($var[$key]['link'])) { - $var[$key]['link'] = e_SELF.'?mode='.$tmp[0].'&action='.$tmp[1]; + $var[$key]['link'] = e_SELF.'?mode='.$tmp[0].'&action='.$tmp[1]; } /*$var[$key]['text'] = $val['caption']; @@ -1225,13 +1238,18 @@ class e_admin_controller */ protected $_params = array(); + /** + * @var string default action name + */ + protected $_default_action = 'index'; + /** * Constructor * @param e_admin_request $request [optional] */ public function __construct($request, $response, $params = array()) { - $this->_params = array('enable_triggers'); + $this->_params = array_merge(array('enable_triggers' => false), $params); $this->setRequest($request) ->setResponse($response) ->setParams($params); @@ -1437,16 +1455,28 @@ class e_admin_controller return $this->getResponse()->getHeaderContent(); } + /** + * Get current mode, response proxy method + * @return string + */ public function getMode() { return $this->getRequest()->getMode(); } + /** + * Get current actin, response proxy method + * @return string + */ public function getAction() { return $this->getRequest()->getAction(); } + /** + * Get current ID, response proxy method + * @return string + */ public function getId() { return $this->getRequest()->getId(); @@ -1462,6 +1492,24 @@ class e_admin_controller return $this->getResponse()->getJsHelper(); } + protected function _preDispatch($action = '') + { + if(!$action) $action = $this->getAction(); + $method = $this->toMethodName($action, 'page'); + if(!method_exists($this, $method)) + { + $this->getRequest()->setAction($this->getDefaultAction()); + } + + // switch to 404 if needed + $method = $this->toMethodName($this->getRequest()->getActionName(), 'page'); + if(!method_exists($this, $method)) + { + $this->getRequest()->setAction('e404'); + e107::getMessage()->add('Action '.$method.' not found!', E_MESSAGE_ERROR); + } + } + /** * Dispatch observer, check for triggers * @@ -1477,13 +1525,14 @@ class e_admin_controller $this->setRequest($request); } + $this->_preDispatch($action); if(null === $action) { $action = $request->getActionName(); } // check for observer - $actionObserverName = $action.(e_AJAX_REQUEST ? 'Ajax' : '').'Observer'; + $actionObserverName = $this->toMethodName($action, 'observer', e_AJAX_REQUEST); if(method_exists($this, $actionObserverName)) { $this->$actionObserverName(); @@ -1497,10 +1546,10 @@ class e_admin_controller { if(strpos($key, 'etrigger_') === 0) { - $actionTriggerName = $action.$request->camelize(substr($key, 9)).'Trigger'; + $actionTriggerName = $this->toMethodName($action.$request->camelize(substr($key, 9)), 'trigger', false); if(method_exists($this, $actionTriggerName)) { - $this->$actionTriggerName(); + $this->$actionTriggerName($value); } //Check if triggers are still enabled if(!$this->triggersEnabled()) @@ -1526,6 +1575,7 @@ class e_admin_controller { return $this; } + $request = $this->getRequest(); if(null === $request) { @@ -1533,13 +1583,14 @@ class e_admin_controller $this->setRequest($request); } + $this->_preDispatch($action); if(null === $action) { $action = $request->getActionName(); } // check for observer - $actionHeaderName = $action.'Header'; + $actionHeaderName = $this->toMethodName($action, 'header', false); if(method_exists($this, $actionHeaderName)) { $this->$actionHeaderName(); @@ -1559,19 +1610,26 @@ class e_admin_controller public function dispatchPage($action = null) { $request = $this->getRequest(); + if(null === $request) + { + $request = new e_admin_request(); + $this->setRequest($request); + } $response = $this->getResponse(); + $this->_preDispatch($action); if(null === $action) { $action = $request->getActionName(); } // check for observer - $actionName = $action.(e_AJAX_REQUEST ? 'Ajax' : '').'Page'; + $actionName = $this->toMethodName($action, 'page'); $ret = ''; - if(!method_exists($this, $actionName)) + if(!method_exists($this, $actionName)) // pre dispatch already switched to default action/not found page if needed { e107::getMessage()->add('Action '.$actionName.' no found!', E_MESSAGE_ERROR); + return $response; } ob_start(); //catch any output @@ -1606,6 +1664,50 @@ class e_admin_controller return $response; } + public function E404Observer() + { + $this->getResponse()->setTitle('Page Not Found'); + } + + public function E404Page() + { + return '
Requested page was not found!
'; // TODO - lan + } + + /** + * Convert action name to method name + * + * @param string $action_name formatted (e.g. request method getActionName()) action name + * @param string $type page|observer|header|trigger + * @param boolean $ajax force with true/false, if null will be auto-resolved + * @return + */ + public function toMethodName($action_name, $type= 'page', $ajax = null) + { + if(null === $ajax) $ajax = e_AJAX_REQUEST; //auto-resolving + return $action_name.($ajax ? 'Ajax' : '').ucfirst(strtolower($type)); + } + + /** + * Get default action + * @return string action + */ + public function getDefaultAction() + { + return $this->_default_action; + } + + /** + * Set default action + * @param string $action_name + * @return e_admin_controller + */ + public function setDefaultAction($action_name) + { + $this->_default_action = $action_name; + return $this; + } + /** * @return boolean */ @@ -1626,12 +1728,12 @@ class e_admin_controller } //FIXME - move everything from e_admin_controller_main except model auto-create related code -class e_admin_controller_base extends e_admin_controller +class e_admin_controller_ui extends e_admin_controller { } -class e_admin_controller_main extends e_admin_controller_base +class e_admin_controller_main extends e_admin_controller_ui { protected $fields = array(); protected $fieldpref = array(); @@ -1646,8 +1748,8 @@ class e_admin_controller_main extends e_admin_controller_base protected $pid; protected $pluginTitle; protected $perPage = 20; - - + protected $batchDelete = true; + /** * @var e_admin_model */ @@ -1676,7 +1778,11 @@ class e_admin_controller_main extends e_admin_controller_base */ public function __construct($request, $response, $params = array()) { + $this->setDefaultAction('list'); + $params['enable_triggers'] = true; // override + parent::__construct($request, $response, $params); + if(!$this->pluginName) { $this->pluginName = 'core'; @@ -1689,16 +1795,7 @@ class e_admin_controller_main extends e_admin_controller_base $this->fieldpref = $ufieldpref; } - $this->addTitle($this->pluginTitle); - } - - /** - * Default is List action page - * @return string - */ - public function DefaultPage() - { - return $this->getUI()->getList(); + $this->addTitle($this->pluginTitle); } /** @@ -1708,20 +1805,55 @@ class e_admin_controller_main extends e_admin_controller_base public function ListObserver() { $this->getTreeModel()->load(); + $this->addTitle('List'); + //var_dump($_POST, $this->getParam('enable_triggers')); + } + + /** + * Catch batch submit + * @param string $batch_trigger + * @return + */ + public function ListBatchTrigger($batch_trigger) + { + $multi_name = vartrue($this->fields['checkboxes']['toggle'], 'multiselect'); + $data = $this->getPosted($multi_name, array()); + $this->triggersEnabled(false); //disable further triggering + if(!$this->getBatchDelete()) + { + e107::getMessage()->add('Batch delete not allowed!', E_MESSAGE_WARNING); + return; + } + $this->_handleListBatch($batch_trigger, array_values($data)); + } + + public function _handleListBatch($trigger, $data) + { + switch($trigger) + { + case 'delete': //FIXME - confirmation screen + $this->getTreeModel()->delete($data); + $this->getTreeModel()->setMessages(); + break; + + default: + //TODO - batch handling; + break; + } } /** * List action header * @return void */ - public function ListHead() + public function ListHeader() { e107::getJs()->headerCore('core/tabs.js') ->headerCore('core/admin.js'); } /** - * List action page + * Generic List action page * @return string */ public function ListPage() @@ -1729,6 +1861,92 @@ class e_admin_controller_main extends e_admin_controller_base return $this->getUI()->getList(); } + /** + * Generic Edit observer + */ + public function EditObserver() + { + $this->getModel()->load($this->getId()); + } + + /** + * Generic Edit submit trigger + */ + public function EditSubmitTrigger() + { + $this->CreateSubmitTrigger(); + } + + /** + * Generic Edit page + * @return string + */ + public function EditPage() + { + return $this->CreatePage(); + } + + /** + * Generic Create observer + * @return string + */ + public function CreateObserver() + { + $this->triggersEnabled(true); + } + + /** + * Generic Create submit trigger + */ + public function CreateSubmitTrigger() + { + // Scenario I - use request owned POST data - toForm already exeuted + $posted = $this->getPosted(); + $this->convertData($posted); + $this->getModel()->setPostedData($posted, null, false, false) + ->save(true); + // Scenario II - inner model sanitize + //$this->getModel()->setPosted($this->convertData($_POST(, null, false, true); + + // Copy model messages to the default message stack + $this->getModel()->setMessages(); + } + + /** + * + * @return + */ + public function CreatePage() + { + return $this->getUI()->getCreate(); + } + + /** + * Convert posted values when needed (based on field type) + * @param array $data + * @return void + */ + public function convertData(&$data) + { + foreach ($this->getFields() as $key => $attributes) + { + if(!isset($data[$key])) + { + continue; + } + switch($attributes['type']) + { + case 'datestamp': + if(!is_numeric($data[$key])) + { + $data[$key] = e107::getDateConvert()->toDate($data[$key], 'input'); + } + break; + //more to come + } + } + } + public function getPerPage() { return $this->perPage; @@ -1754,16 +1972,39 @@ class e_admin_controller_main extends e_admin_controller_base return $this->table; } + public function getBatchDelete() + { + return $this->batchDelete; + } + public function getFields() { return $this->fields; } + public function getFieldAttr($key) + { + if(isset($this->fields[$key])) + { + return $this->fields[$key]; + } + return array(); + } + public function getFieldPref() { return $this->fieldpref; } + public function getFieldPrefAttr($key) + { + if(isset($this->fieldpref[$key])) + { + return $this->fieldpref[$key]; + } + return array(); + } + /** * Get Config object * @return e_plugin_pref|e_core_pref @@ -1787,6 +2028,40 @@ class e_admin_controller_main extends e_admin_controller_base { if(null === $this->_model) { + // try to create dataFields array if missing + if(!$this->dataFields) + { + $this->dataFields = array(); + foreach ($this->fields as $key => $att) + { + if(null === $att['type'] || vartrue($att['noedit']) || !vartrue($att['data'])) + { + continue; + } + $this->dataFields[$key] = $att['data']; + } + } + // TODO - do it in one loop, or better - separate method(s) -> convertFields(validate), convertFields(data),... + if(!$this->validationRules) + { + $this->validationRules = array(); + foreach ($this->fields as $key => $att) + { + if(null === $att['type'] || vartrue($att['noedit'])) + { + continue; + } + if(vartrue($att['validate'])) + { + $this->validationRules[$key] = array((true === $att['validate'] ? 'required' : $att['validate']), varset($att['rule']), $att['title'], varset($att['error'], $att['help'])); + } + elseif(vartrue($att['check'])) + { + $this->checkRules[$key] = array($att['check'], varset($att['rule']), $att['title'], varset($att['error'], $att['help'])); + } + } + } + // default model $this->_model = new e_admin_model(); $this->_model->setModelTable($this->table) @@ -1794,7 +2069,7 @@ class e_admin_controller_main extends e_admin_controller_base ->setValidationRules($this->validationRules) ->setFieldTypes($this->fieldTypes) ->setDataFields($this->dataFields) - ->load($this->getId()); + ->setParam($this->editQry); } return $this->_model; } @@ -1811,8 +2086,10 @@ class e_admin_controller_main extends e_admin_controller_base // default tree model $this->_tree_model = new e_admin_tree_model(); $this->_tree_model->setModelTable($this->table) + ->setFieldIdName($this->pid) ->setParams(array('model_class' => 'e_admin_model', 'db_query' => $this->listQry)); } + return $this->_tree_model; } @@ -1826,8 +2103,15 @@ class e_admin_controller_main extends e_admin_controller_base { if(null === $this->_ui) { - // default ui - $this->_ui = new e_admin_ui($this); + if($this->getParam('ui')) + { + $this->_ui = $this->getParam('ui'); + $this->setParam('ui', null); + } + else// default ui + { + $this->_ui = new e_admin_ui($this); + } } return $this->_ui; } @@ -1848,7 +2132,7 @@ class e_admin_ui extends e_form /** * Constructor * @param e_admin_controller_main $controller - * @return + * @param boolean $tabindex [optional] enable form element auto tab-indexing */ function __construct($controller, $tabindex = false) { @@ -1863,6 +2147,80 @@ class e_admin_ui extends e_form { } + /** + * Generic DB Record Creation Form. + * @return string + */ + function getCreate() + { + $controller = $this->getController(); + $model = $controller->getModel(); + $request = $controller->getRequest(); + $elid = ($controller->getPluginName() == 'core' ? 'core-' : '').str_replace('_', '-', $controller->getTableName()); //TODO - method getElId() + + $text = " +
+
+ ".$controller->getPluginTitle()." + + + + + + + "; + + foreach($controller->getFields() as $key => $att) + { + $parms = vartrue($att['parms'], array()); + if(!is_array($parms)) parse_str($parms, $parms); + $label = vartrue($att['note']) ? '
'.deftrue($att['note'], $att['note']).'
' : ''; + $help = vartrue($att['help']) ? '
'.deftrue($att['help'], $att['help']).'
' : ''; + + // type null - system (special) fields + if($att['type'] !== null && !vartrue($att['noedit']) && $key != $controller->getPrimaryName()) + { + $text .= " + + + + + "; + } + + } + + $text .= " + +
+ ".defset($att['title'], $att['title']).$label." + + ".$this->renderElement($key, $model->getIfPosted($key), $att)." + {$help} +
+
+ "; + + if($controller->getId()) + { + $text .= $this->admin_button('etrigger_submit', LAN_UPDATE, 'update'); + $text .= ""; + } + else + { + $text .= $this->admin_button('etrigger_submit', LAN_CREATE, 'create'); + $text .= ""; + } + + $text .= " +
+
+
+ "; + + return $text; + } + /** * Create list view * Search for the following GET variables: @@ -1872,6 +2230,7 @@ class e_admin_ui extends e_form */ public function getList() { + $tp = e107::getParser(); $controller = $this->getController(); $request = $controller->getRequest(); $tree = $controller->getTreeModel()->getTree(); @@ -1883,9 +2242,9 @@ class e_admin_ui extends e_form $asc = strtoupper($controller->getQuery('asc', 'desc')); $elid = ($controller->getPluginName() == 'core' ? 'core-' : '').str_replace('_', '-', $controller->getTableName()); - $text = $tree ? $this->renderFilter() : ''; + $text = $tree ? $this->renderFilter($tp->post_toForm(array($controller->getQuery('searchquery'), $controller->getQuery('filter_options')))) : ''; $text .= " -
+
".$controller->getPluginTitle()." @@ -1894,7 +2253,6 @@ class e_admin_ui extends e_form "; - if(!$tree) { $text .= " @@ -1907,7 +2265,7 @@ class e_admin_ui extends e_form { foreach($tree as $model) { - $text .= $this->trow($controller->getFields(), $controller->getFieldPref(), $field->getData(), $controller->getPrimaryName()); + $text .= $this->trow($controller->getFields(), $controller->getFieldPref(), $model->getData(), $controller->getPrimaryName()); } } @@ -1917,7 +2275,7 @@ class e_admin_ui extends e_form
"; - $text .= $tree ? $this->renderBatch() : ''; + $text .= $tree ? $this->renderBatch($controller->getBatchDelete()) : ''; $text .= "
@@ -1930,30 +2288,35 @@ class e_admin_ui extends e_form $text .= e107::getParser()->parseTemplate("{NEXTPREV={$parms}}"); } - //e107::getRender()->tablerender($this->pluginTitle." :: ".$this->adminMenu['list']['caption'], $mes->render().$text); return $text; } - function renderFilter($current_query, $input_options = array()) + function renderFilter($current_query = array(), $input_options = array()) { if(!$input_options) $input_options = array('size' => 20); $text = " -
- ".$this->text('searchquery', $current_query, 50, $input_options)." - ".$this->select_open('filter_options', array('class' => 'tbox select e-filter-options', 'id' => false))." - ".$this->option('Display All', '')." - ".$this->renderBatchFilter('filter')." - ".$this->select_close()." - ".$this->admin_button('etrigger_filter', LAN_FILTER)." -
+
+ Filter +
+ ".$this->text('searchquery', $current_query[0], 50, $input_options)." + ".$this->select_open('filter_options', array('class' => 'tbox select e-filter-options', 'id' => false))." + ".$this->option('Display All', '')." + ".$this->renderBatchFilter('filter', $current_query[1])." + ".$this->select_close()." + ".$this->hidden('mode', $this->getController()->getMode())." + ".$this->hidden('action', $this->getController()->getAction())." + ".$this->admin_button('etrigger_filter', LAN_FILTER)." +
+
"; //TODO assign CSS return $text; } - function renderBatch() + // FIXME - use e_form::batchoptions(), nice way of buildig batch dropdown - news administration show_batch_options() + function renderBatch($allow_delete = false) { $fields = $this->getController()->getFields(); if(!varset($fields['checkboxes'])) @@ -1961,20 +2324,21 @@ class e_admin_ui extends e_form return ''; } - $text = "
- "; - $text .= $frm->select_open('etrigger_batch', array('class' => 'tbox select e-execute-batch', 'id' => false)). - $this->option('With selected...', ''). - $this->option(LAN_DELETE, 'batch__delete'); - $text .= $this->renderBatchFilter('batch'); - $text .= "
"; - + $text = " +
+ + ".$this->select_open('etrigger_batch', array('class' => 'tbox select e-execute-batch', 'id' => false))." + ".$this->option('With selected...', '')." + ".($allow_delete ? $this->option('    '.LAN_DELETE, 'delete') : '')." + ".$this->renderBatchFilter('batch')." + ".$this->select_close()." +
+ "; return $text; - } // TODO - do more - function renderBatchFilter($type='batch') // Common function used for both batches and filters. + function renderBatchFilter($type='batch', $selected = '') // Common function used for both batches and filters. { $optdiz = array('batch' => 'Modify ', 'filter'=> 'Filter by '); $table = $this->getController()->getTableName(); @@ -1991,18 +2355,18 @@ class e_admin_ui extends e_form switch($val['type']) { case 'boolean': //TODO modify description based on $val['parm] - $option[$type.'__'.$key."__1"] = LAN_YES; - $option[$type.'__'.$key."__0"] = LAN_NO; + $option[$key."_1"] = LAN_YES; + $option[$key."_0"] = LAN_NO; break; case 'dropdown': // use the array $parm; foreach($val['parm'] as $k=>$name) { - $option[$type.'__'.$key."__".$k] = $name; + $option[$key."_".$k] = $name; } break; - case 'date': // use $parm to determine unix-style or YYYY-MM-DD + case 'datestamp': // use $parm to determine unix-style or YYYY-MM-DD //TODO last hour, today, yesterday, this-month, last-month etc. /* foreach($val['parm'] as $k=>$name) { @@ -2011,41 +2375,132 @@ class e_admin_ui extends e_form break; case 'userclass': - $classes = e107::getUserClass()->uc_required_class_list($val['parm']); + case 'userclasses': + $classes = e107::getUserClass()->uc_required_class_list($val['parms']); foreach($classes as $k=>$name) { - $option[$type. '__'.$key."__".$k] = $name; + $option[$key."_".$k] = $name; } break; case 'method': $method = $key; - $list = $this->$method('', $type); - foreach($list as $k=>$name) + $list = call_user_func_array(array($this, $method), array('', $type)); + if(is_array($list)) { - $option[$type.'__'.$key."__".$k] = $name; + foreach($list as $k=>$name) + { + $option[$key."_".$k] = $name; + } } break; } - if(count($option)>0) + if(count($option) > 0) + { + $text .= "\t".$this->optgroup_open($optdiz[$type].$val['title'], $disabled)."\n"; + foreach($option as $okey=>$oval) { - $text .= "\t".$this->optgroup_open($optdiz[$type].$val['title'], $disabled)."\n"; - foreach($option as $okey=>$oval) - { - $sel = ($_SESSION[$table."_".$type] == $okey) ? TRUE : FALSE; //FIXME - GET - $text .= $this->option($oval, $okey, $sel)."\n"; - } - $text .= "\t".$this->optgroup_close()."\n"; + $text .= $this->option($oval, $okey, $selected == $okey)."\n"; } - - + $text .= "\t".$this->optgroup_close()."\n"; + } } return $text; } + /** + * Render Form Element + * @param string $key + * @param mixed $value + * @param array $attributes field attributes including render parameters, element options + * @return string + */ + function renderElement($key, $value, $attributes) + { + $parms = vartrue($attributes['parms'], array()); + if(is_string($parms)) parse_str($parms, $parms); + + //FIXME - this block is present in trow(), so make it separate method, use it in both methods + switch($attributes['type']) + { + case 'number': + $maxlength = vartrue($parms['maxlength'], 255); + unset($parms['maxlength']); + if(!vartrue($parms['size'])) $parms['size'] = 15; + if(!vartrue($parms['class'])) $parms['class'] = 'tbox number'; + return $this->text($key, $value, $maxlength, $parms); + break; + + case 'url': + case 'text': + $maxlength = vartrue($parms['maxlength'], 255); + unset($parms['maxlength']); + return $this->text($key, $value, $maxlength, $parms); + break; + + case 'image': //TODO - thumb, image list shortcode, js tooltip... + $label = varset($parms['label']); + unset($parms['label']); + return $this->imagepicker($key, $value, $label, $parms); + break; + + case 'icon': + $label = varset($parms['label']); + $ajax = varset($parms['ajax']) ? true : false; + unset($parms['label'], $parms['ajax']); + return $this->iconpicker($key, $value, $label, $parms, $ajax); + break; + + case 'datestamp': + return $this->datepicker($key, $value, $parms); + break; + + case 'dropdown': + $eloptions = vartrue($parms['dropdown'], array()); + if(is_string($eloptions)) parse_str($eloptions); + unset($parms['dropdown']); + return $this->selectbox($name, $eloptions, $value, $parms); + break; + + case 'userclass': + case 'userclasses': + $uc_options = vartrue($parms['userclass'], ''); + unset($parms['userclass']); + $method = $attributes['type'] == 'userclass' ? 'uc_select' : 'uc_checkbox'; + return $this->$method($key, $value, $uc_options, $parms); + break; + + case 'user_name': + case 'user_loginname': + case 'user_login': + case 'user_customtitle': + case 'user_email': + //user_id expected + //$value = get_user_data($value); + return $this->user($key, $value, $parms); + break; + + case 'boolean': + $lenabled = vartrue($parms['enabled'], 'LAN_ENABLED'); + $ldisabled = vartrue($parms['disabled'], 'LAN_DISABLED'); + unset($parms['enabled'], $parms['disabled']); + return $this->radio_switch($key, $value, defset($lenabled, $lenabled), defset($ldisabled, $ldisabled)); + break; + + case 'method': // Custom Function + return call_user_func_array(array($this, $key), array($value, 'form')); + break; + + default: + //unknown type + break; + } + + } + /** * @return e_admin_controller_main */ @@ -2207,81 +2662,8 @@ class e_admin_ui_dummy extends e_form - /** - * Generic DB Record Creation Form. - * @param object $id [optional] - * @return - */ - function createPage() - { - global $e_userclass, $e_event; - - $id = varset($_POST['edit']) ? key($_POST['edit']) : ""; - $tp = e107::getParser(); - $ns = e107::getRender(); - $sql = e107::getDb(); - $frm = e107::getForm(); - - if($id) - { - $query = str_replace("{ID}",$id,$this->editQry); - $sql->db_Select_gen($query); - $row = $sql->db_Fetch(MYSQL_ASSOC); - } - else - { - $row = array(); - } - - $text = " -
-
- ".$this->pluginTitle." - - - - - - "; - - foreach($this->fields as $key=>$att) - { - if($att['forced']!==TRUE) - { - $text .= " - - - - "; - } - - } - - $text .= " - -
".$att['title']."".$this->renderElement($key,$row)."
-
"; - - if($id) - { - $text .= $frm->admin_button('update', LAN_UPDATE, 'update'); - $text .= ""; - } - else - { - $text .= $frm->admin_button('create', LAN_CREATE, 'create'); - } - - $text .= " -
-
-
"; - - $ns->tablerender($this->pluginTitle." :: ".$this->adminMenu['create']['caption'], $text); - } - /** * Generic Save DB Record Function. @@ -2348,77 +2730,9 @@ class e_admin_ui_dummy extends e_form - /** - * Render Form Element (edit page) - * @param object $key - * @param object $row - * @return - */ - function renderElement($key,$row) - { - $frm = e107::getForm(); - - $att = ($this->mode == 'options') ? $this->prefs[$key] : $this->fields[$key]; - $value = $row[$key]; - - if($att['type']=='method') - { - $meth = $key; - return $this->$meth($value); - } - - if($att['type']=='boolean') - { - return $frm->radio_switch($key, $row[$key]); - } - - return $frm->text($key, $row[$key], 50); - - } - - /** - * Render Field value (listing page) - * @param object $key - * @param object $row - * @return - */ - function renderValue($key,$row) // NO LONGER REQUIRED. use $frm->trow(); - { - $att = $this->fields[$key]; - //TODO add checkbox. - - if($att['type']=='method') - { - $meth = $key; - return $this->$meth($row[$key]); - } - - - if($key == "options") - { - $id = $this->primary; - // $text = ""; - // $text .= ""; - // return $text; - } - - switch($att['type']) - { - case 'url': - return "".$row[$key].""; - break; - - default: - return $row[$key]; - break; - } - return $row[$key] .$att['type']; - } - - /** * Generic Options/Preferences Form. * @return diff --git a/e107_handlers/calendar/calendar_class.php b/e107_handlers/calendar/calendar_class.php index 6e15888e6..b3a1f7414 100755 --- a/e107_handlers/calendar/calendar_class.php +++ b/e107_handlers/calendar/calendar_class.php @@ -1,4 +1,18 @@ calendar_file = e_HANDLER.'calendar/calendar_stripped.js'; - $this->calendar_setup_file = e_HANDLER.'calendar/calendar-setup_stripped.js'; + $this->calendar_file = e_HANDLER_ABS.'calendar/calendar_stripped.js'; + $this->calendar_setup_file = e_HANDLER_ABS.'calendar/calendar-setup_stripped.js'; } else { - $this->calendar_file = e_HANDLER.'calendar/calendar.js'; - $this->calendar_setup_file = e_HANDLER.'calendar/calendar-setup.js'; + $this->calendar_file = e_HANDLER_ABS.'calendar/calendar.js'; + $this->calendar_setup_file = e_HANDLER_ABS.'calendar/calendar-setup.js'; } if(file_exists(e_HANDLER.'calendar/language/'.e_LANGUAGE.'.js')) { - $this->calendar_lang_file = e_HANDLER.'calendar/language/'.e_LANGUAGE.'.js'; + $this->calendar_lang_file = e_HANDLER_ABS.'calendar/language/'.e_LANGUAGE.'.js'; } else { - $this->calendar_lang_file = e_HANDLER.'calendar/language/English.js'; + $this->calendar_lang_file = e_HANDLER_ABS.'calendar/language/English.js'; } if(defined('CALENDAR_IMG')) @@ -49,16 +62,16 @@ class DHTML_Calendar } else { - $this->calendar_img = ""; + $this->calendar_img = ""; } if(file_exists(THEME."calendar.css")) { - $this->calendar_theme_file = THEME."calendar.css"; + $this->calendar_theme_file = THEME_ABS."calendar.css"; } else { - $this->calendar_theme_file = e_HANDLER."calendar/calendar.css"; + $this->calendar_theme_file = e_HANDLER_ABS."calendar/calendar.css"; } $this->calendar_options = array('ifFormat' => '%Y/%m/%d', 'daFormat' => '%Y/%m/%d'); @@ -73,16 +86,16 @@ class DHTML_Calendar } function get_load_files_code() { - $code = ( '' . NEWLINE ); - $code .= ( '' . NEWLINE ); - $code .= ( '' . NEWLINE ); - $code .= ( '' . NEWLINE ); + $code = ( '' . self::$NEWLINE ); + $code .= ( '' . self::$NEWLINE ); + $code .= ( '' . self::$NEWLINE ); + $code .= ( '' . self::$NEWLINE ); return $code; } - function _make_calendar($other_options = array()) { + function _make_calendar($other_options = array(), $script_tag = true) { $js_options = $this->_make_js_hash(array_merge($this->calendar_options, $other_options)); - $code = ( '' ); + $code = $script_tag ? ( '' ) : 'Calendar.setup({' . $js_options . '});'; return $code; } @@ -90,11 +103,11 @@ class DHTML_Calendar { $ret = ""; $id = $this->_gen_id(); - $attrstr = $this->_make_html_attr(array_merge($field_attributes, array('id' => $this->_field_id($id), 'type' => 'text'))); + $attrstr = $this->_make_html_attr(array_merge($field_attributes, array('id' => $this->_field_id($id), 'type' => 'text'))); $ret .= ' '; $ret .= "".$this->calendar_img.""; $options = array_merge($cal_options, array('inputField' => $this->_field_id($id), 'button' => $this->_trigger_id($id))); - $ret .= $this->_make_calendar($options); + e107::getJs()->footerInline($this->_make_calendar($options, false)); //FIXME - get_load_files_code() to use JS Manager return $ret; } diff --git a/e107_handlers/date_handler.php b/e107_handlers/date_handler.php index 07579ad9b..10115112e 100644 --- a/e107_handlers/date_handler.php +++ b/e107_handlers/date_handler.php @@ -1,21 +1,16 @@ '{e_HANDLER}news_class.php', 'news' => '{e_HANDLER}news_class.php', 'e_form' => '{e_HANDLER}form_handler.php', - //'e_fieldset' => '{e_HANDLER}form_handler.php', 'e_upgrade' => '{e_HANDLER}e_upgrade_class.php', 'e_jshelper' => '{e_HANDLER}js_helper.php', 'e_menu' => '{e_HANDLER}menu_class.php', @@ -126,6 +125,7 @@ class e107 'themeHandler' => '{e_HANDLER}theme_handler.php', 'e_model' => '{e_HANDLER}model_class.php', 'e_admin_model' => '{e_HANDLER}model_class.php', + 'DHTML_Calendar'=> '{e_HANDLER}calendar/calendar_class.php', ); /** diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 52adeefa3..14ccc5fa8 100644 --- a/e107_handlers/form_handler.php +++ b/e107_handlers/form_handler.php @@ -9,8 +9,8 @@ * Form Handler * * $Source: /cvs_backup/e107_0.8/e107_handlers/form_handler.php,v $ - * $Revision: 1.60 $ - * $Date: 2009-10-28 17:05:34 $ + * $Revision: 1.61 $ + * $Date: 2009-10-30 17:59:30 $ * $Author: secretr $ * */ @@ -99,7 +99,7 @@ class e_form // The button itself could be replaced with an icon just for this purpose. - $e107 = &e107::getInstance(); + $e107 = e107::getInstance(); $id = $this->name2id($name); $sc_parameters .= '&id='.$id; $jsfunc = $ajax ? "e107Ajax.toggleUpdate('{$id}-iconpicker', '{$id}-iconpicker-cn', 'sc:iconpicker=".urlencode($sc_parameters)."', '{$id}-iconpicker-ajax', { overlayElement: '{$id}-iconpicker-button' })" : "e107Helper.toggle('{$id}-iconpicker')"; @@ -116,35 +116,64 @@ class e_form return $ret; } + + // FIXME - better GUI, {IMAGESELECTOR} rewrite, flexibility, thumbnails, tooltip image preivew, etc. + function imagepicker($name, $default, $label = '', $sc_parameters = '') + { + if(is_string($sc_parameters)) parse_str($sc_parameters, $sc_parameters); + if(!$label) $label = LAN_SELECT; + $parms = "name={$name}"; + $parms .= "&path=".urlencode(e107::getParser()->replaceConstants(vartue($sc_parameters['path'], '{e_FILE}images/'))); + $parms .= "&filter=0"; + $parms .= "&fullpath=1"; + $parms .= "&default=".$default; + $parms .= "&multiple=FALSE"; + $parms .= "&label=-- ".$label." --"; + $parms .= "&subdirs=0"; + //$parms .= "&tabindex=".$this->getNext(); + //$parms .= "&click_target=data"; + //$parms .= "&click_prefix=[img][[e_IMAGE]]newspost_images/"; + //$parms .= "&click_postfix=[/img]"; - /** - * Date field with popup calendar - * @param name => string - the name of the field - * @param datestamp => UNIX timestamp - default value of the field - **/ - function datepicker($name, $datestamp=false) - { - global $pref; - //TODO can some of these values be set in an admin section somewhere so they are set per site? - //TODO allow time option ? - $cal = new DHTML_Calendar(true); - $cal_options['showsTime'] = false; - $cal_options['showOthers'] = false; - $cal_options['weekNumbers'] = false; - //TODO use $prefs values for format? - $cal_options['ifFormat'] = $pref['inputdate']; + $ret = "
".$tp->parseTemplate("{IMAGESELECTOR={$parms}&scaction=select}")."
"; + $ret = "
".$tp->parseTemplate("{IMAGESELECTOR={$parms}&scaction=preview}")."
"; + return $text; + } + + /** + * Date field with popup calendar + * @param string $name the name of the field + * @param integer $datestamp UNIX timestamp - default value of the field + * @param array $options calendar options + */ + function datepicker($name, $datestamp = false, $options = array()) + { + $cal = new DHTML_Calendar(true); + $cal_options['showsTime'] = varset($options['time'], true); + $cal_options['showOthers'] = varset($options['others'], false); + $cal_options['weekNumbers'] = varset($options['weeks'], false); + $cal_options['ifFormat'] = e107::getPref('inputdate', '%d/%m/%Y %H:%M:%S'); $cal_options['timeFormat'] = "24"; - $cal_attrib['class'] = "tbox"; - $cal_attrib['size'] = "12"; + $cal_attrib['class'] = "tbox date"; + $cal_attrib['size'] = varset($options['size'], 25); $cal_attrib['name'] = $name; if ($datestamp) { - //TODO use $prefs values for format? - $cal_attrib['value'] = date("d/m/Y H:i:s", $datestamp); - $cal_attrib['value'] = date("d/m/Y", $datestamp); + $cal_attrib['value'] = e107::getDateConvert()->convert_date($datestamp, 'input'); //date("d/m/Y H:i:s", $datestamp); } + //JS manager to send JS/CSS to header if possible, if not - footer + e107::getJs()// FIXME - no CSS support yet!!! ->tryHeaderFile($cal->calendar_theme_file) + ->tryHeaderFile($cal->calendar_file) + ->tryHeaderFile($cal->calendar_setup_file) + ->tryHeaderFile($cal->calendar_lang_file); + return $cal->make_input_field($cal_options, $cal_attrib); - } + } + + function user($name, $default_id, $options = array()) + { + return 'User auto-complete search - under development'; + } function file($name, $options = array()) { @@ -833,38 +862,59 @@ class e_form } $tdclass = vartrue($data['class']); - if($tdclass) - { - $tdclass = ' class="'.$tdclass.'"'; - } - $value = $fieldvalues[$field]; - + $parms = array(); - if(isset($data['colparms'])) //TODO rename to 'parms'. + if(isset($data['parms'])) { - if(!is_array($data['colparms'])) parse_str($data['colparms'], $data['colparms']); - $parms = $data['colparms']; + if(!is_array($data['parms'])) parse_str($data['parms'], $data['parms']); + $parms = $data['parms']; } switch($field) // special fields { case 'options': - $value = ""; - $value .= ""; + if(!$value) + { + parse_str(str_replace('&', '&', e_QUERY), $query); + // keep other vars in tact + $query['action'] = 'edit'; + $query['id'] = $fieldvalues[$pid]; + + //$edit_query = array('mode' => varset($query['mode']), 'action' => varset($query['action']), 'id' => $fieldvalues[$pid]); + $query = http_build_query($query); + + $value = "".LAN_EDIT." "; + $value .= $this->submit_image('delete['.$fieldvalues[$pid].']', $fieldvalues[$pid], 'delete', LAN_DELETE.' [ ID: '.$fieldvalues[$pid].' ]'); + } $data['type'] = 'text'; break; case 'checkboxes': $value = $this->checkbox(vartrue($data['toggle'], 'multiselect').'['.$fieldvalues[$pid].']', $fieldvalues[$pid]); $data['type'] = 'text'; + $tdclass = $tdclass ? $tdclass.' autocheck e-pointer' : 'autocheck e-pointer'; break; } switch($data['type']) { - case 'text': case 'number': + // same + break; + + case 'text': + if(vartrue($parms['truncate'])) + { + $value = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + } + elseif(vartrue($parms['htmltruncate'])) + { + $value = e107::getParser()->html_truncate($value, $parms['htmltruncate'], '...'); + } + break; + + case 'icon': case 'image': //TODO - thumb, js tooltip... //same break; @@ -891,6 +941,10 @@ class e_form { $value = 'not found'; } + if(vartrue($parms['truncate'])) + { + $value = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + } break; case 'boolean': @@ -898,12 +952,17 @@ class e_form break; case 'url': - $value = "".$value.""; + $ttl = $data['title']; + if(vartrue($parms['truncate'])) + { + $ttl = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + } + $value = "".$ttl.""; break; case 'method': // Custom Function - $meth = $field; - $value = $obj->$meth($value,$obj->mode); + $method = $field; + $value = call_user_func_array(array($this, $method), array($value, 'list')); break; //TODO - form_userclass, order,... and maybe more types @@ -912,17 +971,11 @@ class e_form continue; //unknown type break; } - - //TODO - this should be done per type! - if(vartrue($parms['truncate'])) + + if($tdclass) { - $value = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + $tdclass = ' class="'.$tdclass.'"'; } - elseif(vartrue($parms['htmltruncate'])) - { - $value = e107::getParser()->html_truncate($value, $parms['htmltruncate'], '...'); - } - $ret .= ' '.$value.' @@ -940,74 +993,75 @@ class e_form '.$ret.' '; - } - return ''; } - // The 2 functions below are for demonstration purposes only, and may be moved/modified before release. - function filterType($fieldarray) + return ''; + } + + // The 2 functions below are for demonstration purposes only, and may be moved/modified before release. + function filterType($fieldarray) + { + return " frm-> filterType() is Deprecated    "; + define("e_AJAX_REQUEST", TRUE); + $text = ""; - foreach ($fieldarray as $key=>$val) + $text .= varset($val['type']) ? "\n" : ""; + + } + $text .= ""; + return $text; + } + + function filterValue($type = '', $fields = '') + { + return " frm-> filterValue() is Deprecated.   "; + + if($type) + { + + switch($fields[$type]['type']) { - $text .= varset($val['type']) ? "\n" : ""; + case "datestamp": + return "[date field]"; + break; - } - $text .= ""; - return $text; - } - - function filterValue($type = '', $fields = '') - { - return " frm-> filterValue() is Deprecated.   "; - - if($type) - { - - switch($fields[$type]['type']) - { - case "datestamp": - return "[date field]"; - break; - - case "boolean": - - return ""; - break; - - case "user": - return ""; - break; + case "boolean": + + return ""; + break; + + case "user": + return ""; + break; + + default: + + return $this->text('searchquery', '', 50); - default: - - return $this->text('searchquery', '', 50); - - } } - else - { - return $this->text('searchquery', '', 50); - } - // This needs to be dynamic for the various form types, and be loaded via ajax. } - - /** - * Generates a batch options select component - * This component is generally associated with a table of items where one or more rows in the table can be selected (using checkboxes). - * The list options determine some processing that wil lbe applied to all checked rows when the form is submitted. - * - * @param array $options associative array of option elements, keyed on the option value - * @param array ucOptions [optional] associative array of userclass option groups to display, keyed on the option value prefix - * @return string the HTML for the form component - */ - function batchoptions($options, $ucOptions = null) + else { + return $this->text('searchquery', '', 50); + } + // This needs to be dynamic for the various form types, and be loaded via ajax. + } + + /** + * Generates a batch options select component + * This component is generally associated with a table of items where one or more rows in the table can be selected (using checkboxes). + * The list options determine some processing that wil lbe applied to all checked rows when the form is submitted. + * + * @param array $options associative array of option elements, keyed on the option value + * @param array ucOptions [optional] associative array of userclass option groups to display, keyed on the option value prefix + * @return string the HTML for the form component + */ + function batchoptions($options, $ucOptions = null) + { $text = "
@@ -1076,7 +1130,7 @@ class e_form $text .= " ".$this->select_close()." ".$this->admin_button('trigger_execute_batch', 'trigger_execute_batch', 'submit multi e-hide-if-js', 'Go')." -
+
"; return $text; diff --git a/e107_handlers/js_manager.php b/e107_handlers/js_manager.php index 7d49d943b..017dbb06d 100644 --- a/e107_handlers/js_manager.php +++ b/e107_handlers/js_manager.php @@ -7,8 +7,8 @@ * GNU General Public License (http://gnu.org). * * $Source: /cvs_backup/e107_0.8/e107_handlers/js_manager.php,v $ - * $Revision: 1.5 $ - * $Date: 2009-10-07 11:05:55 $ + * $Revision: 1.6 $ + * $Date: 2009-10-30 17:59:32 $ * $Author: secretr $ * */ @@ -52,6 +52,20 @@ class e_jsmanager */ protected $_runtime_header_src = array(); + /** + * Current Header zone (under development) + * + * @var array + */ + protected $_zone_header = 0; + + /** + * Current Footer zone (under development) + * + * @var array + */ + protected $_zone_footer = 0; + /** * JS files array - loaded in page footer * @@ -292,7 +306,7 @@ class e_jsmanager * @param integer $zone 1-5 (see header.php) * @return e_jsmanager */ - public function headerCore($file_path, $zone = 1) + public function headerCore($file_path, $zone = 2) { $this->headerFile('{e_FILE}jslib/'.trim($file_path, '/'), $zone); return $this; diff --git a/e107_handlers/message_handler.php b/e107_handlers/message_handler.php index 04fbe8313..59b795077 100644 --- a/e107_handlers/message_handler.php +++ b/e107_handlers/message_handler.php @@ -9,8 +9,8 @@ * Message Handler * * $Source: /cvs_backup/e107_0.8/e107_handlers/message_handler.php,v $ - * $Revision: 1.22 $ - * $Date: 2009-10-22 14:18:18 $ + * $Revision: 1.23 $ + * $Date: 2009-10-30 17:59:32 $ * $Author: secretr $ * */ @@ -511,20 +511,22 @@ class eMessage */ public function moveStack($from_stack, $to_stack = 'default', $type = false, $session = true) { + if($from_stack == $to_stack) return $this; foreach ($this->_sysmsg as $_type => $stacks) { if($type && $type !== $_type) { continue; } + if(isset($stacks[$from_stack])) { if(!isset($this->_sysmsg[$_type][$to_stack])) { $this->_sysmsg[$_type][$to_stack] = array(); } - array_merge($this->_sysmsg[$_type][$from_stack], $this->_sysmsg[$_type][$to_stack]); - unset($this->_sysmsg[$_type][$to_stack]); + $this->_sysmsg[$_type][$to_stack] = array_merge($this->_sysmsg[$_type][$to_stack], $this->_sysmsg[$_type][$from_stack]); + unset($this->_sysmsg[$_type][$from_stack]); } } @@ -544,6 +546,7 @@ class eMessage */ public function moveSessionStack($from_stack, $to_stack = 'default', $type = false) { + if($from_stack == $to_stack) return $this; foreach ($_SESSION[$this->_session_id] as $_type => $stacks) { if($type && $type !== $_type) @@ -554,10 +557,10 @@ class eMessage { if(!isset($_SESSION[$this->_session_id][$_type][$to_stack])) { - $this->_sysmsg[$_type][$to_stack] = array(); + $_SESSION[$this->_session_id][$_type][$to_stack] = array(); } - array_merge($_SESSION[$this->_session_id][$_type][$from_stack], $this->_sysmsg[$_type][$to_stack]); - unset($_SESSION[$this->_session_id][$_type][$to_stack]); + $_SESSION[$this->_session_id][$_type][$to_stack] = array_merge($_SESSION[$this->_session_id][$_type][$to_stack], $this->_sysmsg[$_type][$from_stack]); + unset($_SESSION[$this->_session_id][$_type][$from_stack]); } } diff --git a/e107_handlers/model_class.php b/e107_handlers/model_class.php index b253027d2..78de0331f 100644 --- a/e107_handlers/model_class.php +++ b/e107_handlers/model_class.php @@ -9,8 +9,8 @@ * e107 Base Model * * $Source: /cvs_backup/e107_0.8/e107_handlers/model_class.php,v $ - * $Revision: 1.26 $ - * $Date: 2009-10-28 17:05:34 $ + * $Revision: 1.27 $ + * $Date: 2009-10-30 17:59:31 $ * $Author: secretr $ */ @@ -44,6 +44,15 @@ class e_model * @var array */ protected $_data_fields = array(); + + /** + * Current model DB table, used in all db calls + * + * This can/should be overwritten/set by extending the class + * + * @var string + */ + protected $_db_table; /** * Runtime cache of parsed from {@link _getData()} keys @@ -74,8 +83,14 @@ class e_model * @var string */ protected $_message_stack = 'default'; - - + + /** + * Model parameters passed mostly from external sources + * + * @var array + */ + protected $_params = array(); + /** * Constructor - set data on initialization * @@ -86,6 +101,27 @@ class e_model $this->setData($data); } + /** + * Optional DB table - used for auto-load data from the DB + * @param string $table + * @return e_model + */ + public function getModelTable() + { + return $this->_db_table; + } + + /** + * Set model DB table + * @param string $table + * @return e_model + */ + public function setModelTable($table) + { + $this->_db_table = $table; + return $this; + } + /** * Get data fields array * @return array @@ -427,7 +463,7 @@ class e_model return $this; } - $this->$data_src = $key; + $this->${data_src} = $key; return $this; } @@ -765,13 +801,33 @@ class e_model } /** - * Load data from DB - * Awaiting for child class implementation - * + * Generic load data from DB + * @param boolean $force + * @return e_admin */ - public function load() - { - } + public function load($id, $force = false) + { + if($this->hasData() && !$force) + { + return $this; + } + $id = intval($id); + + $qry = str_replace('{ID}', $id, $this->getParam('db_query')); + if(!$qry) + { + $qry = ' + SELECT * FROM #'.$this->getModelTable().' WHERE '.$this->getFieldIdName().'='.$id.' + '; + } + //TODO - error reporting + $sql = e107::getDb(); + if($sql->db_Select_gen($qry)) + { + $this->setData($sql->db_Fetch()); + } + return $this; + } /** * Save data to DB @@ -800,6 +856,73 @@ class e_model { } + /** + * Replace DB record + * Awaiting for child class implementation + * @see e_model_admin + */ + public function dbReplace() + { + } + + /** + * Delete DB data + * Awaiting for child class implementation + * @see e_model_admin + */ + public function dbDelete() + { + } + + /** + * Set parameter array + * Core parameters: + * - db_query: string db query to be passed to load() ($sql->db_Select_gen()) + * - model_class: e_tree_model class - string class name for creating nodes inside default load() method + * + * @param array $params + * @return e_model + */ + public function setParams(array $params) + { + $this->_params = $params; + return $this; + } + + /** + * Get parameter array + * + * @return array parameters + */ + public function getParams() + { + return $this->_params; + } + + /** + * Set parameter + * + * @param string $key + * @param mixed $value + * @return e_model + */ + public function setParam($key, $value) + { + $this->_params[$key] = $value; + return $this; + } + + /** + * Get parameter + * + * @param string $key + * @param mixed $default + */ + public function getParam($key, $default = null) + { + return (isset($this->_params[$key]) ? $this->_params[$key] : $default); + } + /** * Try to convert string to a number * Shoud fix locale related troubles @@ -863,6 +986,16 @@ class e_model { return $this->toString((@func_get_arg(0) === true)); } + + public function destroy() + { + $this->_data = array(); + $this->_params = array(); + $this->_data_fields = array(); + $this->_parsed_keys = array(); + $this->_db_table = $this->_field_id = ''; + $this->data_has_changed = false; + } } //FIXME - move e_model_admin to e_model_admin.php @@ -895,15 +1028,6 @@ class e_model */ class e_admin_model extends e_model { - /** - * Current model DB table, used in all db calls - * - * This can/should be overwritten by extending the class - * - * @var string - */ - protected $_db_table; - /** * Posted data * Back-end related @@ -926,7 +1050,7 @@ class e_admin_model extends e_model * Validation structure - see {@link e_validator::$_required_rules} for * more information about the array format. * Used in {@link validate()} method. - * + * TODO - check_rules (see e_validator::$_optional_rules) * This can/should be overwritten by extending the class. * * @var array @@ -945,17 +1069,6 @@ class e_admin_model extends e_model */ protected $_validator = null; - public function setModelTable($table) - { - $this->_db_table = $table; - return $this; - } - - public function getModelTable() - { - return $this->_db_table; - } - /** * @return array */ @@ -1449,12 +1562,30 @@ class e_admin_model extends e_model return ($this->hasValidationError() || $this->hasSqlError()); } + /** + * Generic load data from DB + * @param boolean $force + * @return e_admin_model + */ + public function load($id, $force = false) + { + parent::load($id, $force); + + $this->_db_errno = e107::getDb()->getLastErrorNumber(); + if($this->_db_errno) + { + $this->addMessageError('SQL Update Error', $session_messages); //TODO - Lan + $this->addMessageDebug('SQL Error #'.$this->_db_errno.': '.e107::getDb()->getLastErrorText()); + } + return $this; + } + /** * Save data to DB * * @param boolen $from_post */ - public function save($from_post = true) + public function save($from_post = true, $force = false, $session_messages = false) { if(!$this->getFieldIdName()) { @@ -1469,11 +1600,24 @@ class e_admin_model extends e_model if($this->getId()) { - return $this->dbUpdate(); + return $this->dbUpdate($force, $session_messages); } - return $this->dbInsert(); + return $this->dbInsert($force, $session_messages); } + + public function delete($destroy = true, $session_messages = false) + { + $ret = $this->dbDelete(); + if($ret) + { + if($destroy) + { + $this->setMessages(true, $session_messages)->destroy(); + } + } + return $ret; + } /** * Insert data to DB @@ -1484,7 +1628,7 @@ class e_admin_model extends e_model public function dbInsert($force = false, $session_messages = false) { $this->_db_errno = 0; - if(!$this->data_has_changed && !$force) + if($this->hasError() || (!$this->data_has_changed && !$force)) { return 0; } @@ -1509,7 +1653,7 @@ class e_admin_model extends e_model public function dbReplace($force = false, $session_messages = false) { $this->_db_errno = 0; - if(!$this->data_has_changed && !$force) + if($this->hasError() || (!$this->data_has_changed && !$force)) { return 0; } @@ -1537,6 +1681,10 @@ class e_admin_model extends e_model public function dbUpdate($force = false, $session_messages = false) { $this->_db_errno = 0; + if($this->hasError() || (!$this->data_has_changed && !$force)) + { + return 0; + } $res = e107::getDb()->db_Update($this->getModelTable(), $this->toSqlQuery('update')); if(!$res) { @@ -1560,6 +1708,11 @@ class e_admin_model extends e_model public function dbDelete($session_messages = false) { $this->_db_errno = 0; + if($this->hasError()) + { + return 0; + } + if(!$this->getId()) { $this->addMessageError('Record not found', $session_messages); //TODO - Lan @@ -1587,20 +1740,33 @@ class e_admin_model extends e_model */ public function toSqlQuery($force = '') { - $fields = array_keys($this->_data_fields); $qry = array(); - $action = $this->getId() ? 'update' : 'create'; if($force) { $action = $force; } - - foreach ($fields as $key => $value) + else { + $action = $this->getId() ? 'update' : 'create'; + } + + $qry['_FIELD_TYPES'] = $this->_FIELD_TYPES; //DB field types are optional + $qry['data'][$this->getFieldIdName()] = $this->getId(); + $qry['_FIELD_TYPES'][$this->getFieldIdName()] = 'int'; + + foreach ($this->_data_fields as $key => $type) + { + if($key == $this->getFieldIdName()) + { + continue; + } + if(!isset($qry['_FIELD_TYPES'][$key])) + { + $qry['_FIELD_TYPES'][$key] = $type; //_FIELD_TYPES much more optional now... + } $qry['data'][$key] = $this->getData($key); } - $qry['_FIELD_TYPES'] = $this->_FIELD_TYPES; switch($action) { @@ -1690,6 +1856,17 @@ class e_admin_model extends e_model return null; } + + public function destroy() + { + parent::destroy(); + $this->_validator = null; + $this->_validation_rules = array(); + $this->_db_errno = null; + $this->_posted_data = array(); + $this->data_has_changed = array(); + $this->_FIELD_TYPES = array(); + } } /** @@ -1697,11 +1874,6 @@ class e_admin_model extends e_model */ class e_tree_model extends e_model { - /** - * @var array - */ - protected $_params = array(); - /** * Current model DB table, used in all db calls * This can/should be overwritten by extending the class @@ -1717,9 +1889,21 @@ class e_tree_model extends e_model */ protected $_total = 0; + /** + * Constructor + * + */ + function __construct($tree_data = array()) + { + if($tree_data) + { + $this->setTree($tree_data); + } + } + public function getTotal() { - return $this->_total; + return $this->_total; } public function setTotal($num) @@ -1748,18 +1932,6 @@ class e_tree_model extends e_model return $this->_db_table; } - /** - * Constructor - * - */ - function __construct($tree_data = array()) - { - if($tree_data) - { - $this->setTree($tree_data); - } - } - /** * Set array of models * @return array @@ -1788,8 +1960,14 @@ class e_tree_model extends e_model * * @return e_tree_model */ - public function load() + public function load($force = false) { + + if(!$this->isEmpty() && !$force) + { + return $this; + } + if($this->getParam('db_query') && $this->getParam('model_class') && class_exists($this->getParam('model_class'))) { $sql = e107::getDb(); @@ -1797,11 +1975,18 @@ class e_tree_model extends e_model if($sql->db_Select_gen($this->getParam('db_query'))) { $this->_total = $sql->total_results; //requires SQL_CALC_FOUND_ROWS in query - see db handler + while($tmp = $sql->db_Fetch()) { $tmp = new $class_name($tmp); - $this->setNode($tmp->getId(), $tmp); + $this->setNode($tmp->get($this->getFieldIdName()), $tmp); } + if(!$this->_total && $this->getModelTable()) + { + //SQL_CALC_FOUND_ROWS not found in the query, do one more query + $this->_total = e107::getDb()->db_Count($this->getModelTable()); + } + unset($tmp); } } @@ -1866,57 +2051,7 @@ class e_tree_model extends e_model */ function isEmpty() { - return $this->has('__tree'); - } - - /** - * Set parameter array - * Core parameters: - * - db_query: string db query to be passed to $sql->db_Select_gen(); - * - model_class: string class name for creating nodes inside default load() method - * - * @param array $params - * @return e_tree_model - */ - public function setParams(array $params) - { - $this->_params = $params; - return $this; - } - - - /** - * Get parameter array - * - * @return array parameters - */ - public function getParams() - { - return $this->_params; - } - - /** - * Set parameter - * - * @param string $key - * @param mixed $value - * @return e_tree_model - */ - public function setParam($key, $value) - { - $this->_params[$key] = $value; - return $this; - } - - /** - * Get parameter - * - * @param string $key - * @param mixed $default - */ - public function getParam($key, $default = null) - { - return (isset($this->_params[$key]) ? $this->_params[$key] : $default); + return (!$this->has('__tree')); } } @@ -1931,11 +2066,11 @@ class e_admin_tree_model extends e_tree_model */ public function delete($ids, $destroy = true, $session_messages = false) { - if(is_string($ids)) + if(!$ids) return $this; + if(is_array($ids)) { - $ids = explode(',', $ids); + $ids = implode(',', $ids); } - $ids = e107::getParser()->toDB($ids); $sql = e107::getDb(); $res = $sql->db_Delete($this->getModelTable(), $this->getFieldIdName().' IN ('.$ids.')'); @@ -1949,10 +2084,19 @@ class e_admin_tree_model extends e_tree_model } elseif($destroy) { + if(is_string($ids)) + { + $ids = explode(',', $ids); + } + foreach ($ids as $id) { - call_user_func(array($this->getNode($id), 'destroy')); // first call model destroy method if any - $this->setNode($id, null); + if($this->getNode($id)) + { + $this->getNode($id)->setMessages(true, $session_messages); + call_user_func(array($this->getNode(trim($id)), 'destroy')); // first call model destroy method if any + $this->setNode($id, null); + } } } diff --git a/e107_handlers/validator_class.php b/e107_handlers/validator_class.php index e8e292809..10e1e3d4d 100644 --- a/e107_handlers/validator_class.php +++ b/e107_handlers/validator_class.php @@ -9,8 +9,8 @@ * Handler - general purpose validation functions * * $Source: /cvs_backup/e107_0.8/e107_handlers/validator_class.php,v $ - * $Revision: 1.12 $ - * $Date: 2009-10-20 16:05:02 $ + * $Revision: 1.13 $ + * $Date: 2009-10-30 17:59:31 $ * $Author: secretr $ * */ @@ -218,7 +218,7 @@ class e_validator */ public function setMessageStack($mstack) { - if($mstack) $mstack = 'validator'; + if(!$mstack) $mstack = 'validator'; $this->_message_stack = $mstack; return $this; } diff --git a/e107_plugins/release/admin_config.php b/e107_plugins/release/admin_config.php index ca3b9b73f..b6ed6d2af 100644 --- a/e107_plugins/release/admin_config.php +++ b/e107_plugins/release/admin_config.php @@ -9,8 +9,8 @@ * e107 Release Plugin * * $Source: /cvs_backup/e107_0.8/e107_plugins/release/admin_config.php,v $ - * $Revision: 1.10 $ - * $Date: 2009-10-28 17:05:35 $ + * $Revision: 1.11 $ + * $Date: 2009-10-30 17:59:32 $ * $Author: secretr $ * */ @@ -64,29 +64,32 @@ class plugin_release_admin_controller_main extends e_admin_controller_main // optional protected $perPage = 20; + + // default - true + protected $batchDelete = true; //TODO change the release_url type back to URL before release. // required protected $fields = array( - 'checkboxes' => array('title'=> '', 'type' => '', 'width'=>'5%', 'thclass' =>'center', 'forced'=> TRUE, 'class'=>'center'), - 'release_id' => array('title'=> ID, 'type' => '', 'width'=>'5%', 'thclass' => '', 'forced'=> TRUE, 'primary'=>TRUE), - 'release_type' => array('title'=> 'Type', 'type' => 'method', 'width'=>'auto', 'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE), - 'release_folder' => array('title'=> 'Folder', 'type' => 'text', 'width' => 'auto', 'thclass' => ''), - 'release_name' => array('title'=> 'Name', 'type' => 'text', 'width' => 'auto', 'thclass' => ''), - 'release_version' => array('title'=> 'Version', 'type' => 'text', 'width' => 'auto', 'thclass' => ''), - 'release_author' => array('title'=> LAN_AUTHOR, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left'), - 'release_authorURL' => array('title'=> LAN_AUTHOR_URL, 'type' => 'url', 'width' => 'auto', 'thclass' => 'left'), - 'release_date' => array('title'=> LAN_DATE, 'type' => 'text', 'width' => 'auto', 'thclass' => ''), - 'release_compatibility' => array('title'=> 'compatib', 'type' => 'text', 'width' => '10%', 'thclass' => 'center' ), - 'release_url' => array('title'=> 'Userclass', 'type' => 'userclass', 'width' => '10%', 'thclass' => 'center', 'batch' => TRUE, 'filter'=>TRUE), - 'options' => array('title'=> LAN_OPTIONS, 'type' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced'=>TRUE) + 'checkboxes' => array('title'=> '', 'type' => null, 'data' => null, 'width'=>'5%', 'thclass' =>'center', 'forced'=> TRUE, 'class'=>'center', 'toggle' => 'e-multiselect'), + 'release_id' => array('title'=> ID, 'type' => 'int', 'data' => 'int', 'width'=>'5%', 'thclass' => '', 'forced'=> TRUE, 'primary'=>TRUE/*, 'noedit'=>TRUE*/), //Primary ID is note editable + 'release_type' => array('title'=> 'Type', 'type' => 'method', 'data' => 'str', 'width'=>'auto', 'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE), + 'release_folder' => array('title'=> 'Folder', 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'thclass' => ''), + 'release_name' => array('title'=> 'Name', 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'thclass' => ''), + 'release_version' => array('title'=> 'Version', 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'thclass' => ''), + 'release_author' => array('title'=> LAN_AUTHOR, 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'thclass' => 'left'), + 'release_authorURL' => array('title'=> LAN_AUTHOR_URL, 'type' => 'url', 'data' => 'str', 'width' => 'auto', 'thclass' => 'left'), + 'release_date' => array('title'=> LAN_DATE, 'type' => 'datestamp', 'data' => 'int', 'width' => 'auto', 'thclass' => ''), + 'release_compatibility' => array('title'=> 'compatib', 'type' => 'text', 'data' => 'str', 'width' => '10%', 'thclass' => 'center' ), + 'release_url' => array('title'=> 'release_url', 'type' => 'url', 'data' => 'str', 'width' => '20%', 'thclass' => 'center', 'batch' => TRUE, 'filter'=>TRUE, 'parms' => 'truncate=30', 'validate' => true, 'help' => 'Enter release URL here', 'error' => 'please, ener valid URL'), + 'options' => array('title'=> LAN_OPTIONS, 'type' => null, 'data' => null, 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced'=>TRUE) ); //required - default column user prefs - protected $fieldpref = array('checkboxes', 'release_id', 'release_type', 'release_compatibility', 'options'); + protected $fieldpref = array('checkboxes', 'release_id', 'release_type', 'release_url', 'release_compatibility', 'options'); - // required if no custom model is set in init() - protected $dataFields = array( + // optional if fields 'data' attribute is set or if custom model is set in init() + /*protected $dataFields = array( 'release_id' => 'int', 'release_type' => 'str', 'release_folder' => 'str', @@ -97,10 +100,12 @@ class plugin_release_admin_controller_main extends e_admin_controller_main 'release_date' => 'int', 'release_compatibility' => 'str', 'release_url' => 'str', - ); + );*/ - // optional - protected $validationRules = array(); + // optional, could be also set directly from $fields array with attributes 'validate' => true|'rule_name', 'rule' => 'condition_name', 'error' => 'Validation Error message' + /*protected $validationRules = array( + 'release_url' => array('required', '', 'Release URL', 'Help text', 'not valid error message') + );*/ // optional protected $prefs = array( //TODO add option for core or plugin pref. @@ -110,10 +115,10 @@ class plugin_release_admin_controller_main extends e_admin_controller_main 'pref_name' => array('title'=> 'name', 'type' => 'text') ); - // required if no custom model is set in init() + // required if no custom tree model is set in init() protected $listQry = "SELECT * FROM #release"; // without any Order or Limit. - // required if no custom model is set in init() + // optional - required only in case of e.g. tables JOIN. This also could be done with custom model (set it in init()) protected $editQry = "SELECT * FROM #release WHERE release_id = {ID}"; // optional @@ -122,6 +127,37 @@ class plugin_release_admin_controller_main extends e_admin_controller_main } } +class plugin_release_admin_ui_main extends e_admin_ui +{ + function release_type($curVal,$mode) // not really necessary since we can use 'dropdown' - but just an example of a custom function. + { + if($mode == 'list') + { + return $curVal.' (custom!)'; + } + + if($mode == 'batch') // Custom Batch List for release_type + { + return array('theme'=>"Theme","plugin"=>'Plugin'); + } + + if($mode == 'filter') // Custom Filter List for release_type + { + return array('theme'=>"Theme","plugin"=>'Plugin'); + } + + $types = array("theme","plugin"); + $text = ""; + return $text; + } +} + $dispatcher = new plugin_release_admin_dispatcher(); $dispatcher->runObservers(true); e107::setRegistry('admin/release_dispatcher', $dispatcher); diff --git a/e107_plugins/release/release_sql.php b/e107_plugins/release/release_sql.php index 80f06f5c2..929d699e5 100644 --- a/e107_plugins/release/release_sql.php +++ b/e107_plugins/release/release_sql.php @@ -6,7 +6,7 @@ CREATE TABLE release ( `release_version` varchar(5) NOT NULL, `release_author` varchar(50) NOT NULL, `release_authorURL` varchar(255) NOT NULL, - `release_date` date NOT NULL, + `release_date` int(10) NOT NULL, `release_compatibility` varchar(5) NOT NULL, `release_url` varchar(255) NOT NULL, PRIMARY KEY (`release_id`)