diff --git a/e107_handlers/admin_handler.php b/e107_handlers/admin_handler.php index 513d26e55..dd4714f83 100644 --- a/e107_handlers/admin_handler.php +++ b/e107_handlers/admin_handler.php @@ -428,10 +428,15 @@ class e_admin_request if($encode) { $separator = '&'; - $ret = array_map('rawurlencode', $ret); + //$ret = array_map('rawurlencode', $ret); } - return http_build_query($ret, 'numeric_', $separator); + $ret = http_build_query($ret, 'numeric_', $separator); + if(!$encode) + { + return rawurldecode($ret); + } + return $ret; } /** @@ -1818,6 +1823,23 @@ class e_admin_controller return $action_name.($ajax ? 'Ajax' : '').ucfirst(strtolower($type)); } + /** + * Check if there is a trigger available in the posted data + * @return boolean + */ + public function hasTrigger() + { + $posted = array_keys($this->getPosted()); + foreach ($posted as $key) + { + if(strpos($key, 'etrigger_') === 0) + { + return true; + } + } + return false; + } + /** * Get default action * @return string action @@ -1917,7 +1939,6 @@ class e_admin_ui extends e_admin_controller_ui { $this->pluginName = 'core'; } - $this->_pref = $this->pluginName == 'core' ? e107::getConfig() : e107::getPlugConfig($this->pluginName); $ufieldpref = $this->getUserPref(); if($ufieldpref) @@ -1946,7 +1967,47 @@ class e_admin_ui extends e_admin_controller_ui */ public function ListBatchTrigger($batch_trigger) { - $this->_handleListBatch($batch_trigger); + $this->setPosted('etrigger_batch', null); + // proceed ONLY if there is no other trigger + if($batch_trigger && !$this->hasTrigger()) $this->_handleListBatch($batch_trigger); + } + + /** + * Catch fieldpref submit + * @param string $batch_trigger + * @return + */ + public function ListEcolumnsTrigger() + { + $this->triggersEnabled(false); //disable further triggering + $cols = array(); + $posted = $this->getPosted('e-columns', array()); + foreach ($this->getFields() as $field => $attr) + { + if((vartrue($attr['forced']) || in_array($field, $posted)) && !vartrue($attr['nolist'])) + { + $cols[] = $field; + continue; + } + } + + if($cols) + { + $this->setUserPref($cols); + } + } + + /** + * Catch delete submit + * @param string $batch_trigger + * @return + */ + public function ListDeleteTrigger($posted) + { + $this->triggersEnabled(false); + $id = intval(array_shift($posted)); + $this->getTreeModel()->delete($id); + $this->getTreeModel()->setMessages(); } /** @@ -2053,6 +2114,23 @@ class e_admin_ui extends e_admin_controller_ui return $this->getUI()->getCreate(); } + public function SettingsSaveTrigger() + { + + $this->getConfig() + ->setPostedData($this->getPosted(), null, false, false) + //->setPosted('not_existing_pref_test', 1) + ->save(true); + + $this->getConfig()->setMessages(); + + } + + public function SettingsPage() + { + return $this->getUI()->getSettings(); + } + /** * Handle posted batch options * @param string $batch_trigger @@ -2063,6 +2141,9 @@ class e_admin_ui extends e_admin_controller_ui $tp = e107::getParser(); $multi_name = vartrue($this->fields['checkboxes']['toggle'], 'multiselect'); $selected = $tp->toDB(array_values($this->getPosted($multi_name, array()))); + + if(empty($selected)) return; + $trigger = $tp->toDB(explode('__', $batch_trigger)); $this->triggersEnabled(false); //disable further triggering @@ -2079,24 +2160,26 @@ class e_admin_ui extends e_admin_controller_ui $this->getTreeModel()->setMessages(); break; - case 'bool': + case 'bool': // FIXME - tree method update // direct query $field = $trigger[1]; $value = $trigger[2]; - if($cnt = e107::getDb()->db_Update($this->getTableName(), "{$field}={$value} WHERE {$field} IN (".implode(', ', $selected).")")) + if($cnt = e107::getDb()->db_Update($this->getTableName(), "{$field}={$value} WHERE ".$this->getPrimaryName()." IN (".implode(', ', $selected).")")) { - $this->getTreeModel()->addMessageSuccess($cnt.' records successfully updated.'); + $this->getTreeModel()->addMessageSuccess($cnt.' records successfully updated.', true); } $this->getTreeModel()->setMessages(); + $this->redirectAction(); break; - case 'boolreverse': + case 'boolreverse': // FIXME - tree method update // direct query $field = $trigger[1]; //TODO - errors - if($cnt = e107::getDb()->db_Update($this->getTableName(), "{$field}=1-{$field} WHERE {$field} IN (".implode(', ', $selected).")")) + if($cnt = e107::getDb()->db_Update($this->getTableName(), "{$field}=1-{$field} WHERE ".$this->getPrimaryName()." IN (".implode(', ', $selected).")")) { - e107::getMessage()->add($cnt.' records successfully reversed.', E_MESSAGE_SUCCESS); + e107::getMessage()->add($cnt.' records successfully reversed.', E_MESSAGE_SUCCESS, true); } + $this->redirectAction(); break; default: @@ -2108,12 +2191,14 @@ class e_admin_ui extends e_admin_controller_ui } else // default handling { + // FIXME - tree method update $field = $trigger[0]; $value = $trigger[1]; //TODO - errors - if($cnt = e107::getDb()->db_Update($this->getTableName(), "{$field}={$value} WHERE {$field} IN (".implode(', ', $selected).")")) + if($cnt = e107::getDb()->db_Update($this->getTableName(), "{$field}='{$value}' WHERE ".$this->getPrimaryName()." IN (".implode(', ', $selected).")")) { - e107::getMessage()->add(''.$value.' set for '.$cnt.' records.', E_MESSAGE_SUCCESS); + e107::getMessage()->add(''.$value.' set for '.$cnt.' records.', E_MESSAGE_SUCCESS, true); } + $this->redirectAction(); } break; } @@ -2143,11 +2228,12 @@ class e_admin_ui extends e_admin_controller_ui break; case 'list': // list - $this->redirectAction('list'); + $this->redirectAction('list', 'id'); break; default: - $this->redirectAction(preg_replace('/[^\w\-]/', '', $choice), 'id'); + $choice = explode('|', str_replace('{ID}', $id, $choice), 3); + $this->redirectAction(preg_replace('/[^\w\-]/', '', $choice[0]), vartrue($choice[1]), vartrue($choice[2])); break; } return; @@ -2171,7 +2257,7 @@ class e_admin_ui extends e_admin_controller_ui case 'datestamp': if(!is_numeric($data[$key])) { - $data[$key] = e107::getDateConvert()->toDate($data[$key], 'input'); + $data[$key] = e107::getDateConvert()->toTime($data[$key], 'input'); } break; //more to come @@ -2288,10 +2374,48 @@ class e_admin_ui extends e_admin_controller_ui * @return e_plugin_pref|e_core_pref */ public function getConfig() - { + { + if(null === $this->_pref) + { + $this->_pref = $this->pluginName == 'core' ? e107::getConfig() : e107::getPlugConfig($this->pluginName); + + $dataFields = $validateRules = array(); + foreach ($this->prefs as $key => $att) + { + // create dataFields array + if(vartrue($att['data'])) + { + $dataFields[$key] = $att['data']; + } + + // create validation array + if(vartrue($att['validate'])) + { + $validateRules[$key] = array((true === $att['validate'] ? 'required' : $att['validate']), varset($att['rule']), $att['title'], varset($att['error'], $att['help'])); + } + + + $this->_pref->setDataFields($dataFields)->setValidationRules($validateRules); + /* Not implemented in e_model yet + elseif(vartrue($att['check'])) + { + $validateRules[$key] = array($att['check'], varset($att['rule']), $att['title'], varset($att['error'], $att['help'])); + }*/ + } + + } return $this->_pref; } + /** + * Get Config object + * @return e_plugin_pref|e_core_pref + */ + public function getPrefs() + { + return $this->prefs; + } + /** * Get column preference array * @return array @@ -2302,6 +2426,18 @@ class e_admin_ui extends e_admin_controller_ui return vartrue($user_pref['admin_cols_'.$this->getTableName()], array()); } + /** + * Get column preference array + * @return array + */ + public function setUserPref($new) + { + global $user_pref; + $user_pref['admin_cols_'.$this->getTableName()] = $new; + $this->fieldpref = $new; + save_prefs('user'); + } + /** * Get current model * @@ -2435,7 +2571,6 @@ class e_admin_form_ui extends e_form } /** - * This will use the above (after it's done) * TODO - lans * Generic DB Record Creation Form. * @return string @@ -2473,6 +2608,37 @@ class e_admin_form_ui extends e_form return $this->createForm($forms, $models); } + /** + * TODO - lans + * Generic Settings Form. + * @return string + */ + function getSettings() + { + $controller = $this->getController(); + $request = $controller->getRequest(); + $legend = 'Settings'; + $forms = $models = array(); + $forms[] = array( + 'id' => $this->getElementId(), + //'url' => e_SELF, + //'query' => 'self', or custom GET query, self is default + 'tabs' => false, // TODO - NOT IMPLEMENTED YET - enable tabs (only if fieldset count is > 1) + 'fieldsets' => array( + 'settings' => array( + 'legend' => $legend, + 'fields' => $controller->getPrefs(), //see e_admin_ui::$prefs + 'after_submit_options' => false, + 'after_submit_default' => false, // or true for default redirect options + 'triggers' => array('save' => array(LAN_SAVE, 'update')), // standard create/update-cancel triggers + ) + ) + ); + $models[] = $controller->getConfig(); + + return $this->createForm($forms, $models); + } + /** * Create list view * Search for the following GET variables: @@ -2485,14 +2651,14 @@ class e_admin_form_ui extends e_form $tp = e107::getParser(); $controller = $this->getController(); $request = $controller->getRequest(); - $tree = $controller->getTreeModel(); + $tree = $controller->getTreeModel(); $options = array( 'id' => $this->getElementId(), // unique string used for building element ids, REQUIRED 'pid' => $controller->getPrimaryName(), // primary field name, REQUIRED //'url' => e_SELF, default //'query' => e_QUERY, default - 'head_query' => $request->buildQueryString(array(), true, 'field,asc,from'), // without field, asc and from vars, REQUIRED - 'np_query' => $request->buildQueryString(array(), true, 'from'), // without from var, REQUIRED for next/prev functionality + 'head_query' => $request->buildQueryString('field=[FIELD]&asc=[ASC]&from=[FROM]', false), // without field, asc and from vars, REQUIRED + 'np_query' => $request->buildQueryString(array(), false, 'from'), // without from var, REQUIRED for next/prev functionality 'legend' => $controller->getPluginTitle(), // hidden by default 'form_pre' => !$tree->isEmpty() ? $this->renderFilter($tp->post_toForm(array($controller->getQuery('searchquery'), $controller->getQuery('filter_options')), $controller->getModel().'/'.$controller->getAction())) : '', 'form_post' => '', // markup to be added after closing form element @@ -2566,6 +2732,8 @@ class e_admin_form_ui extends e_form { $optdiz = array('batch' => 'Modify ', 'filter'=> 'Filter by '); $table = $this->getController()->getTableName(); + $text = ''; + $textsingle = ''; foreach($this->getController()->getFields() as $key=>$val) { @@ -2575,6 +2743,8 @@ class e_admin_form_ui extends e_form } $option = array(); + $parms = vartrue($val['writeParms'], array()); + if(is_string($parms)) parse_str($parms, $parms); switch($val['type']) { @@ -2588,7 +2758,8 @@ class e_admin_form_ui extends e_form break; case 'dropdown': // use the array $parm; - foreach($val['parm'] as $k => $name) + unset($parms['__options']); //remove element options if any + foreach($parms as $k => $name) { $option[$key.'__'.$k] = $name; } @@ -2603,8 +2774,8 @@ class e_admin_form_ui extends e_form break; case 'userclass': - case 'userclasses': - $classes = e107::getUserClass()->uc_required_class_list($val['parms']); + //case 'userclasses': + $classes = e107::getUserClass()->uc_required_class_list(vartrue($parms['classlist'], '')); foreach($classes as $k => $name) { $option[$key.'__'.$k] = $name; @@ -2616,17 +2787,29 @@ class e_admin_form_ui extends e_form $list = call_user_func_array(array($this, $method), array('', $type)); if(is_array($list)) { + //check for single option + if(isset($list['singleOption'])) + { + $textsingle .= $list['singleOption']; + continue; + } + // non rendered options array foreach($list as $k => $name) { $option[$key.'__'.$k] = $name; } } + elseif(!empty($list)) //optgroup, continue + { + $text .= $list; + continue; + } break; } if(count($option) > 0) { - $text .= "\t".$this->optgroup_open($optdiz[$type].$val['title'], $disabled)."\n"; + $text .= "\t".$this->optgroup_open($optdiz[$type].defset($val['title'], $val['title']), $disabled)."\n"; foreach($option as $okey=>$oval) { $text .= $this->option($oval, $okey, $selected == $okey)."\n"; @@ -2635,7 +2818,7 @@ class e_admin_form_ui extends e_form } } - return $text; + return $textsingle.$text; } @@ -2832,9 +3015,9 @@ class e_admin_ui_dummy extends e_form { $text .= " - ".$var['title']." + ".defset($var['title'], $var['title'])." - ".$this->renderElement($key,$pref)." + ".$this->renderElement($key, $pref)." \n"; } diff --git a/e107_handlers/date_handler.php b/e107_handlers/date_handler.php index 10115112e..4ffaf93ee 100644 --- a/e107_handlers/date_handler.php +++ b/e107_handlers/date_handler.php @@ -7,8 +7,8 @@ * GNU General Public License (http://gnu.org). * * $Source: /cvs_backup/e107_0.8/e107_handlers/date_handler.php,v $ - * $Revision: 1.9 $ - * $Date: 2009-10-30 17:59:32 $ + * $Revision: 1.10 $ + * $Date: 2009-11-04 17:29:26 $ * $Author: secretr $ * */ @@ -61,9 +61,9 @@ class convert return strftime($mask, $datestamp); } - function toDate($date_string, $maks = '') + function toTime($date_string, $mask = '') { - //TODO - convert string to datestamp + //TODO - convert string to datestamp, coming soon return time(); } diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 558ad1902..1a4518b10 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.63 $ - * $Date: 2009-11-02 17:45:28 $ + * $Revision: 1.64 $ + * $Date: 2009-11-04 17:29:26 $ * $Author: secretr $ * */ @@ -142,6 +142,12 @@ class e_form /** * Date field with popup calendar + * $options allowed keys: + * - time: show time, default is true + * - others: ???, default is false + * - weeks: show weeks, default is false + * - size: input field size attribute, default 25 + * * @param string $name the name of the field * @param integer $datestamp UNIX timestamp - default value of the field * @param array $options calendar options @@ -219,6 +225,7 @@ class e_form } $options = array('class' => 'tbox'.($size ? ' '.$size : '').' e-wysiwyg'); $bbbar = ''; + // FIXME - see ren_help.php if(!deftrue('e_WYSIWYG')) { require_once(e_HANDLER."ren_help.php"); @@ -721,7 +728,7 @@ class e_form // has issues with the checkboxes. $text .= "
- ".$this->admin_button('submit-e-columns', LAN_SAVE, 'update')." + ".$this->admin_button('etrigger_ecolumns', LAN_SAVE, 'update')."
@@ -754,21 +761,21 @@ class e_form '; } - function thead($fieldarray, $columnPref=array(), $querypattern = '', $requeststr = '') + function thead($fieldarray, $columnPref = array(), $querypattern = '', $requeststr = '') { $text = ""; - // Recommended pattern: ?mode=list&fld=[FIELD]&asc=[ASC]&frm=[FROM] + // Recommended pattern: mode=list&field=[FIELD]&asc=[ASC]&from=[FROM] if(strpos($querypattern,'&')!==FALSE) { // we can assume it's always $_GET since that's what it will generate // more flexible (e.g. pass default values for order/field when they can't be found in e_QUERY) & secure - $tmp = $requeststr ? $requeststr : str_replace('&', '&', e_QUERY); + $tmp = str_replace('&', '&', $requeststr ? $requeststr : e_QUERY); parse_str($tmp, $tmp); $etmp = array(); - parse_str($querypattern,$etmp); + parse_str(str_replace('&', '&', $querypattern), $etmp); } else // Legacy Queries. eg. main.[FIELD].[ASC].[FROM] { @@ -798,7 +805,7 @@ class e_form $ascdesc = (varset($ascdesc) == 'desc') ? 'asc' : 'desc'; foreach($fieldarray as $key=>$val) { - if(in_array($key,$columnPref) || $key == 'options' || (vartrue($val['forced']))) + if(in_array($key, $columnPref) || $key == 'options' || (vartrue($val['forced']))) { $cl = (vartrue($val['thclass'])) ? " class='".$val['thclass']."'" : ""; $text .= " @@ -812,11 +819,11 @@ class e_form $repl = array($key,$ascdesc,$from); $val['url'] = e_SELF."?".str_replace($srch,$repl,$querypattern); } - + $text .= (vartrue($val['url'])) ? "" : ""; // Really this column-sorting link should be auto-generated, or be autocreated via unobtrusive js. $text .= vartrue($val['title'], ''); $text .= ($val['url']) ? "" : ""; - $text .= ($key == "options") ? $this->columnSelector($fieldarray,$columnPref) : ""; + $text .= ($key == "options") ? $this->columnSelector($fieldarray, $columnPref) : ""; $text .= ($key == "checkboxes") ? $this->checkbox_toggle('e-column-toggle', vartrue($val['toggle'], 'multiselect')) : ""; @@ -834,7 +841,6 @@ class e_form } - // FIXME - newspost.php function trow($fieldarray, $currentlist, $fieldvalues, $pid) { $cnt = 0; @@ -849,7 +855,7 @@ class e_form { //Not found - if(!$data['forced'] && !in_array($field, $currentlist)) + if((!$data['forced'] && !in_array($field, $currentlist)) || $data['nolist']) { continue; } @@ -866,12 +872,13 @@ class e_form $tdclass = vartrue($data['class']); $value = $fieldvalues[$field]; + $tp = e107::getParser(); $parms = array(); - if(isset($data['parms'])) + if(isset($data['readParms'])) { - if(!is_array($data['parms'])) parse_str($data['parms'], $data['parms']); - $parms = $data['parms']; + if(is_string($data['readParms'])) parse_str($data['readParms'], $data['readParms']); + $parms = $data['readParms']; } switch($field) // special fields @@ -879,7 +886,7 @@ class e_form case 'options': if(!$value) { - parse_str(str_replace('&', '&', e_QUERY), $query); + parse_str(str_replace('&', '&', e_QUERY), $query); //FIXME - FIX THIS // keep other vars in tact $query['action'] = 'edit'; $query['id'] = $fieldvalues[$pid]; @@ -888,7 +895,7 @@ class e_form $query = http_build_query($query); $value = "".LAN_EDIT." "; - $value .= $this->submit_image('delete['.$fieldvalues[$pid].']', $fieldvalues[$pid], 'delete', LAN_DELETE.' [ ID: '.$fieldvalues[$pid].' ]'); + $value .= $this->submit_image('etrigger_delete['.$fieldvalues[$pid].']', $fieldvalues[$pid], 'delete', LAN_DELETE.' [ ID: '.$fieldvalues[$pid].' ]'); } $data['type'] = 'text'; break; @@ -899,27 +906,70 @@ class e_form $tdclass = $tdclass ? $tdclass.' autocheck e-pointer' : 'autocheck e-pointer'; break; } - + //FIXME - move this block to separate method renderValue(), similar to renderElement() switch($data['type']) { case 'number': - // same + if($parms) + { + if(!isset($parms['sep'])) $value = number_format($number, $parms['decimals']); + else $value = number_format($number, $parms['decimals'], vartrue($parms['point'], '.'), vartrue($parms['sep'], ' ')); + } + $value = vartrue($parms['pre']).$value.vartrue($parms['post']); + // else same break; + case 'dropdown': case 'text': if(vartrue($parms['truncate'])) { - $value = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + $value = $tp->text_truncate($value, $parms['truncate'], '...'); } elseif(vartrue($parms['htmltruncate'])) { - $value = e107::getParser()->html_truncate($value, $parms['htmltruncate'], '...'); + $value = $tp->html_truncate($value, $parms['htmltruncate'], '...'); + } + $value = vartrue($parms['pre']).$value.vartrue($parms['post']); + break; + + case 'bbarea': + case 'textarea': + $expand = '...'; + $toexpand = false; + if($data['type'] == 'bbarea' && !isset($parms['bb'])) $parms['bb'] = true; //force bb parsing for bbareas + $id = trim(str_replace('_', '-', $field)); + if(!vartrue($parms['noparse'])) $value = $tp->toHTML($value, (vartrue($parms['bb']) ? true : false), vartrue($parms['parse'])); + if(vartrue($parms['expand'])) + { + $expand = ''.defset($parms['expand'], $parms['expand']).""; + } + + $oldval = $value; + if(vartrue($parms['truncate'])) + { + $value = $oldval = strip_tags($value); + $value = $tp->text_truncate($value, $parms['truncate'], $expand); + $toexpand = $value != $oldval; + } + elseif(vartrue($parms['htmltruncate'])) + { + $value = $tp->html_truncate($value, $parms['htmltruncate'], $expand); + $toexpand = $value != $oldval; + } + if($toexpand) + { + // force hide! TODO - core style .expand-c (expand container) + $value .= ''; } break; case 'icon': + $value = ''.basename($value).''; + break; + case 'image': //TODO - thumb, js tooltip... - //same + $ttl = vartrue($parms['title'], 'LAN_PREVIEW'); + $value = ''.defset($ttl, $ttl).''; break; case 'datestamp': @@ -930,6 +980,16 @@ class e_form $value = $this->_uc->uc_get_classname($value); break; + case 'userclasses': + $classes = explode(',', $value); + $value = array(); + foreach ($classes as $cid) + { + $value[] = $this->_uc->uc_get_classname($cid); + } + $value = implode(vartrue($parms['separator']), $pieces); + break; + case 'user_name': case 'user_loginname': case 'user_login': @@ -946,7 +1006,7 @@ class e_form } if(vartrue($parms['truncate'])) { - $value = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + $value = $tp->text_truncate($value, $parms['truncate'], '...'); } break; @@ -955,17 +1015,17 @@ class e_form break; case 'url': - $ttl = $data['title']; + $ttl = $value; if(vartrue($parms['truncate'])) { - $ttl = e107::getParser()->text_truncate($value, $parms['truncate'], '...'); + $ttl = $tp->text_truncate($value, $parms['truncate'], '...'); } - $value = "".$ttl.""; + $value = "".$ttl.""; break; case 'method': // Custom Function $method = $field; - $value = call_user_func_array(array($this, $method), array($value, 'list')); + $value = call_user_func_array(array($this, $method), array($value, 'read', $parms)); break; //TODO - form_userclass, order,... and maybe more types @@ -1002,8 +1062,103 @@ class e_form } /** - * Generic List Form - * Search for the following GET variables: + * Auto-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['writeParms'], array()); + if(is_string($parms)) parse_str($parms, $parms); + + 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 vartrue($parms['pre']).$this->text($key, $value, $maxlength, $parms).vartrue($parms['post']); + break; + + case 'url': + case 'text': + $maxlength = vartrue($parms['maxlength'], 255); + unset($parms['maxlength']); + return vartrue($parms['pre']).$this->text($key, $value, $maxlength, vartrue($parms['__options'])).vartrue($parms['post']); + break; + + case 'textarea': + return $this->textarea($key, $value, vartrue($parms['rows'], 15), vartrue($parms['cols'], 40), vartrue($parms['__options'])); + break; + + case 'bbarea': + return $this->bbarea($key, $value, vartrue($parms['help']), vartrue($parms['helptag']), vartrue($parms['size'])); + break; + + case 'image': //TODO - thumb, image list shortcode, js tooltip... + $label = varset($parms['label']); + unset($parms['label']); + return $this->imagepicker($key, $value, $label, vartrue($parms['__options'])); + 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['__options'], array()); + if(is_string($eloptions)) parse_str($eloptions); + unset($parms['dropdown']); + return $this->selectbox($name, $parms, $value, $eloptions); + break; + + case 'userclass': + case 'userclasses': + $uc_options = vartrue($parms['classlist'], ''); // defaults to 'public,guest,nobody,member,classes' (userclass handler) + unset($parms['classlist']); + $method = $attributes['type'] == 'userclass' ? 'uc_select' : 'uc_checkbox'; + return $this->$method($key, $value, $uc_options, vartrue($parms['__options'], array())); + 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, 'write', $parms)); + break; + + default: + //unknown type + break; + } + } + + /** + * Generic List Form, used internal by admin UI * Expected options array format: * * array(...), //see e_admin_ui::$fields * 'after_submit_options' => array('__default' => 'action_name' 'action' => 'Label'[,...]), // or true for default redirect options * 'triggers' => 'auto', // standard create/update-cancel triggers - * //or custom trigger array in format array('sibmit' => array('Title', 'create', '1'), 'cancel') - trigger name - title, action, optional hidden value (in this case named sibmit_value) + * //or custom trigger array in format array('submit' => array('Title', 'create', '1'), 'cancel' => array('cancel', 'cancel')) - trigger name - title, action, optional hidden value (in this case named sibmit_value) * ) * ) * ); @@ -1256,147 +1411,15 @@ class e_form return $text; } - /** - * Auto-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; - } - - } - // 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 = ""; - 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; - - - 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. } /** diff --git a/e107_handlers/model_class.php b/e107_handlers/model_class.php index 145299c76..003bc5a9b 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.29 $ - * $Date: 2009-11-02 17:45:29 $ + * $Revision: 1.30 $ + * $Date: 2009-11-04 17:29:26 $ * $Author: secretr $ */ @@ -1448,13 +1448,13 @@ class e_admin_model extends e_model * @param array $data optional - data for validation, defaults to posted data * @return boolean */ - public function validate(array $data = array()) + public function validate($data = null) { if(!$this->getValidationRules()) { return true; } - if(!$data) + if(null === $data) { $data = $this->getPostedData(); } @@ -1867,7 +1867,7 @@ class e_admin_model extends e_model break; case 'model': - return $value->mergePostedData()->toArray(); //XXX - ??? + return $value-mergePostedData(false, true, true)->sanitize(); //XXX - ??? break; case 'null': @@ -2107,7 +2107,7 @@ class e_admin_tree_model extends e_tree_model } elseif($destroy) { - if(is_string($ids)) + if(!is_array($ids)) { $ids = explode(',', $ids); } diff --git a/e107_handlers/pref_class.php b/e107_handlers/pref_class.php index 6c6fe2e06..610774bf8 100644 --- a/e107_handlers/pref_class.php +++ b/e107_handlers/pref_class.php @@ -9,8 +9,8 @@ * e107 Preference Handler * * $Source: /cvs_backup/e107_0.8/e107_handlers/pref_class.php,v $ - * $Revision: 1.28 $ - * $Date: 2009-11-03 10:57:15 $ + * $Revision: 1.29 $ + * $Date: 2009-11-04 17:29:26 $ * $Author: secretr $ */ @@ -491,7 +491,12 @@ class e_pref extends e_admin_model if($from_post) { - $this->mergePostedData(); //all posted data is sanitized and filtered vs preferences array + $this->mergePostedData(); //all posted data is sanitized and filtered vs preferences/_data_fields array + } + + if($this->hasValidationError()) + { + return false; } //FIXME - switch to new model system messages (separate eMessage namespaces) @@ -627,12 +632,13 @@ class e_pref extends e_admin_model } /** - * Validation override + * Validation + * @param array $data [optional] null to use Posted data * @return */ - public function validate() + public function validate($data = null) { - return true; + return parent::validate($data); } /** @@ -661,6 +667,34 @@ class e_pref extends e_admin_model return $this; } + /** + * Override + */ + public function dbInsert() + { + } + + /** + * Override + */ + public function dbUpdate() + { + } + + /** + * Override + */ + public function dbReplace() + { + } + + /** + * Override + */ + public function dbDelete() + { + } + } /** diff --git a/e107_handlers/ren_help.php b/e107_handlers/ren_help.php index 40357e04c..2310ad786 100644 --- a/e107_handlers/ren_help.php +++ b/e107_handlers/ren_help.php @@ -11,9 +11,9 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_handlers/ren_help.php,v $ -| $Revision: 1.11 $ -| $Date: 2009-10-23 19:54:48 $ -| $Author: e107steved $ +| $Revision: 1.12 $ +| $Date: 2009-11-04 17:29:26 $ +| $Author: secretr $ +----------------------------------------------------------------------------+ */ @@ -30,7 +30,7 @@ function ren_help($mode = 1, $addtextfunc = "addtext", $helpfunc = "help") - +// FIXME - full rewrite, EVERYTHING - bbcode class (php + JS), core callbacks, tooltip help, optimize function display_help($tagid="helpb", $mode = 1, $addtextfunc = "addtext", $helpfunc = "help", $helpsize = '') { if(defsettrue('e_WYSIWYG')) { return; } diff --git a/e107_handlers/userclass_class.php b/e107_handlers/userclass_class.php index 2b2503bd2..bc4a848d9 100644 --- a/e107_handlers/userclass_class.php +++ b/e107_handlers/userclass_class.php @@ -11,9 +11,9 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_handlers/userclass_class.php,v $ -| $Revision: 1.43 $ -| $Date: 2009-11-01 17:19:27 $ -| $Author: e107steved $ +| $Revision: 1.44 $ +| $Date: 2009-11-04 17:29:26 $ +| $Author: secretr $ +----------------------------------------------------------------------------+ */ @@ -375,7 +375,7 @@ class user_class } return $temp; } - + //TODO - $optlist == all $opt_arr = explode(',',$optlist); foreach ($opt_arr as $k => $v) { diff --git a/e107_plugins/release/includes/admin.php b/e107_plugins/release/includes/admin.php index 8fa807986..5f8901e34 100644 --- a/e107_plugins/release/includes/admin.php +++ b/e107_plugins/release/includes/admin.php @@ -9,8 +9,8 @@ * Release Plugin Administration UI * * $Source: /cvs_backup/e107_0.8/e107_plugins/release/includes/admin.php,v $ - * $Revision: 1.3 $ - * $Date: 2009-11-02 17:45:28 $ + * $Revision: 1.4 $ + * $Date: 2009-11-04 17:29:26 $ * $Author: secretr $ */ @@ -31,15 +31,16 @@ class plugin_release_admin extends e_admin_dispatcher * @var array */ protected $adminMenu = array( - 'main/list' => array('caption'=> 'Manage', 'perm' => '0'), - 'main/create' => array('caption'=> LAN_CREATE, 'perm' => '0'), - 'main/options' => array('caption'=> 'Settings', 'perm' => '0'), - 'main/custom' => array('caption'=> 'Custom Page', 'perm' => '0') + 'main/list' => array('caption'=> 'Manage', 'perm' => '0'), + 'main/create' => array('caption'=> LAN_CREATE, 'perm' => '0'), + 'main/settings' => array('caption'=> 'Settings', 'perm' => '0'), + 'main/custom' => array('caption'=> 'Custom Page', 'perm' => '0') ); /** - * Optional, map mode/action t + * Optional, mode/action aliases, related with 'selected' menu CSS class * Format: 'MODE/ACTION' => 'MODE ALIAS/ACTION ALIAS'; + * This will mark active main/list menu item, when current page is main/edit * @var array */ protected $adminMenuAliases = array( @@ -68,23 +69,109 @@ class plugin_release_admin_ui extends e_admin_ui protected $pid = "release_id"; // optional - protected $perPage = 2; + protected $perPage = 20; // default - true protected $batchDelete = true; //TODO change the release_url type back to URL before release. // required + /** + * (use this as starting point for wiki documentation) + * $fields format (string) $field_name => (array) $attributes + * + * $attributes format: + * - title (string) Human readable field title, constant name will be accpeted as well (multi-language support + * + * - type (string) null (means system), number, text, dropdown, url, image, icon, datestamp, userclass, userclasses, user[_name|_loginname|_login|_customtitle|_email], + * boolean, method + * full/most recent reference list - e_form::trow(), e_form::renderElement(), e_admin_form_ui::renderBatchFilter() + * + * - data (string) Data type, one of the following: int, integer, string, str, float, bool, boolean, model, null + * Used only if $dataFields is not set + * full/most recent reference list - e_admin_model::sanitize(), db::_getFieldValue() + * - primary (boolean) primary field (obsolete, $pid is now used) + * + * - help (string) edit/create table - inline help, constant name will be accpeted as well, optional + * - note (string) edit/create table - text shown below the field title (left column), constant name will be accpeted as well, optional + * + * - validate (boolean|string) any of accepted validation types (see e_validator::$_required_rules), true == 'required' + * - rule (string) condition for chosen above validation type (see e_validator::$_required_rules), not required for all types + * - error (string) Human readable error message (validation failure), constant name will be accpeted as well, optional + * + * - batch (boolean) list table - add current field to batch actions, in use only for boolean, dropdown, datestamp, userclass, method field types + * NOTE: batch may accept string values in the future... + * full/most recent reference type list - e_admin_form_ui::renderBatchFilter() + * + * - filter (boolean) list table - add current field to filter actions, rest is same as batch + * + * - forced (boolean) list table - forced fields are always shown in list table + * - nolist (boolean) list table - don't show in column choice list + * - noedit (boolean) edit table - don't show in edit mode + * + * - width (string) list table - width e.g '10%', 'auto' + * - thclass (string) list table header - th element class + * - class (string) list table body - td element additional class + * + * - readParms (mixed) parameters used by core routine for showing values of current field. Structure on this attribute + * depends on the current field type (see below). readParams are used mainly by list page + * + * - writeParms (mixed) parameters used by core routine for showing control element(s) of current field. + * Structure on this attribute depends on the current field type (see below). + * writeParams are used mainly by edit page, filter (list page), batch (list page) + * + * $attributes['type']->$attributes['read/writeParams'] pairs: + * - null -> read: n/a + * -> write: n/a + * + * - number -> read: (array) [optional] 'point' => '.', [optional] 'sep' => ' ', [optional] 'decimals' => 2, [optional] 'pre' => '€ ', [optional] 'post' => 'LAN_CURRENCY' + * -> write: (array) [optional] 'pre' => '€ ', [optional] 'post' => 'LAN_CURRENCY', [optional] 'maxlength' => 50, [optional] '__options' => array(...) see e_form class description for __options format + * + * - text -> read: (array) [optional] 'htmltruncate' => 100, [optional] 'truncate' => 100, [optional] 'pre' => '', [optional] 'post' => ' px' + * -> write: (array) [optional] 'pre' => '', [optional] 'post' => ' px', [optional] 'maxlength' => 50 (default - 255), [optional] '__options' => array(...) see e_form class description for __options format + * + * - textarea -> read: (array) 'noparse' => '1' default 0 (disable toHTML text parsing), [optional] 'bb' => '1' (parse bbcode) default 0, [optional] 'parse' => '' modifiers passed to e_parse::toHTML() e.g. 'BODY', [optional] 'htmltruncate' => 100, [optional] 'truncate' => 100, [optional] 'expand' => '[more]' title for expand link, empty - no expand + * -> write: (array) [optional] 'rows' => '' default 15, [optional] 'cols' => '' default 40, [optional] '__options' => array(...) see e_form class description for __options format + * + * - bbarea -> read: same as textarea type + * -> write: (array) [optional] 'pre' => '', [optional] 'post' => ' px', [optional] 'maxlength' => 50 (default - 255), [optional] '__options' => array(...) see e_form class description for __options format + * + * - image -> read: [optional] 'title' => 'SOME_LAN' (default - LAN_PREVIEW), [optional] 'pre' => '{e_PLUGIN}myplug/images/' + * -> write: (array) [optional] 'label' => '', [optional] '__options' => array(...) see e_form::imagepicker() for allowed options + * + * - icon -> read: [optional] 'class' => 'S16', [optional] 'pre' => '{e_PLUGIN}myplug/images/' + * -> write: (array) [optional] 'label' => '', [optional] 'ajax' => true/false , [optional] '__options' => array(...) see e_form::iconpicker() for allowed options + * + * - datestamp -> read: [optional] 'mask' => 'long'|'short'|strftime() string, default is 'short' + * -> write: (array) [optional] 'label' => '', [optional] 'ajax' => true/false , [optional] '__options' => array(...) see e_form::iconpicker() for allowed options + * + * - url -> read: [optional] 'pre' => '{ePLUGIN}myplug/'|'http://somedomain.com/', 'truncate' => 50 default - no truncate, NOTE: + * -> write: + * + * - method -> read: optional, passed to given method (the field name) + * -> write: optional, passed to given method (the field name) + * + * Special attribute types: + * - method (string) field name should be method from the current e_admin_form_ui class (or its extension). + * Example call: field_name($value, $render_action, $parms) where $value is current value, + * $render_action is on of the following: read|write|batch|filter, parms are currently used paramateres ( value of read/writeParms attribute). + * Return type expected (by render action): + * - read: list table - formatted value only + * - write: edit table - form element (control) + * - batch: either array('title1' => 'value1', 'title2' => 'value2', ..) or array('singleOption' => '') or rendered option group (string '' + * - filter: same as batch + * @var array + */ protected $fields = array( '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_id' => array('title'=> ID, 'type' => 'number', 'data' => 'int', 'width'=>'5%', 'thclass' => '', 'forced'=> TRUE, 'primary'=>TRUE/*, 'noedit'=>TRUE*/), //Primary ID is not 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_date' => array('title'=> LAN_DATE, 'type' => 'datestamp', 'data' => 'int', 'width' => 'auto', 'thclass' => '', 'readParms' => 'long', 'writeParms' => ''), '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'), 'test_list_1' => array('title'=> 'test 1', 'type' => 'boolean', 'data' => 'int', 'width' => '5%', 'thclass' => 'center', 'batch' => TRUE, 'filter'=>TRUE, 'noedit' => true), @@ -104,9 +191,9 @@ class plugin_release_admin_ui extends e_admin_ui // optional, if $pluginName == 'core', core prefs will be used, else e107::getPluginConfig($pluginName); protected $prefs = array( - 'pref_type' => array('title'=> 'type', 'type'=>'text'), - 'pref_folder' => array('title'=> 'folder', 'type' => 'boolean'), - 'pref_name' => array('title'=> 'name', 'type' => 'text') + 'pref_type' => array('title'=> 'type', 'type'=>'text', 'data' => 'string', 'validate' => true), + 'pref_folder' => array('title'=> 'folder', 'type' => 'boolean', 'data' => 'integer'), + 'pref_name' => array('title'=> 'name', 'type' => 'text', 'data' => 'string', 'validate' => 'regex', 'rule' => '#^[\w]+$#i', 'help' => 'allowed characters are a-zA-Z and underscore') ); // required if no custom tree model is set in init() @@ -125,7 +212,7 @@ class plugin_release_admin_form_ui extends e_admin_form_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') + if($mode == 'read') { return $curVal.' (custom!)'; }