mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-08 09:04:53 +01:00
serverside validation for textbox and button
This commit is contained in:
parent
d095250d85
commit
a488b67f99
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
* @ToDo supported customized templates stored in DB, currently we only support xet files stored in filesystem
|
* @ToDo supported customized templates stored in DB, currently we only support xet files stored in filesystem
|
||||||
*/
|
*/
|
||||||
class etemplate_new
|
class etemplate_new extends etemplate_widget_template
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Are we running as sitemgr module or not
|
* Are we running as sitemgr module or not
|
||||||
@ -27,22 +27,6 @@ class etemplate_new
|
|||||||
*/
|
*/
|
||||||
public $sitemgr=false;
|
public $sitemgr=false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Request object of the currecntly created request
|
|
||||||
*
|
|
||||||
* It's a static variable as etemplates can contain further etemplates (rendered by a different object)
|
|
||||||
*
|
|
||||||
* @var etemplate_request
|
|
||||||
*/
|
|
||||||
static protected $request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON response object, if we run via a JSON request
|
|
||||||
*
|
|
||||||
* @var egw_json_response
|
|
||||||
*/
|
|
||||||
static protected $response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor of etemplate class, reads an eTemplate if $name is given
|
* constructor of etemplate class, reads an eTemplate if $name is given
|
||||||
*
|
*
|
||||||
@ -114,7 +98,7 @@ class etemplate_new
|
|||||||
self::$request->ignore_validation = $ignore_validation;
|
self::$request->ignore_validation = $ignore_validation;
|
||||||
self::$request->app_header = $GLOBALS['egw_info']['flags']['app_header'];
|
self::$request->app_header = $GLOBALS['egw_info']['flags']['app_header'];
|
||||||
if (self::$request->output_mode == -1) self::$request->output_mode = 0;
|
if (self::$request->output_mode == -1) self::$request->output_mode = 0;
|
||||||
self::$request->template = $this->rel_path;
|
self::$request->template = $this->as_array();
|
||||||
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'etemplate_exec_id' => self::$request->id(),
|
'etemplate_exec_id' => self::$request->id(),
|
||||||
@ -134,6 +118,8 @@ class etemplate_new
|
|||||||
}
|
}
|
||||||
else // first call
|
else // first call
|
||||||
{
|
{
|
||||||
|
// missing dependency, thought egw:uses jquery.jquery.tools does NOT work, maybe we should rename it to jquery-tools
|
||||||
|
egw_framework::validate_file('jquery','jquery.tools.min');
|
||||||
egw_framework::validate_file('.','etemplate2','etemplate');
|
egw_framework::validate_file('.','etemplate2','etemplate');
|
||||||
|
|
||||||
egw_framework::includeCSS('/etemplate/js/test/test.css');
|
egw_framework::includeCSS('/etemplate/js/test/test.css');
|
||||||
@ -165,26 +151,22 @@ class etemplate_new
|
|||||||
|
|
||||||
self::$response = egw_json_response::get();
|
self::$response = egw_json_response::get();
|
||||||
|
|
||||||
// todo: validate content
|
if (!($template = self::instance(self::$request->template['name'], self::$request->template['template_set'],
|
||||||
$content = self::validate($content);
|
self::$request->template['version'], self::$request->template['load_via'])))
|
||||||
|
{
|
||||||
|
throw new egw_exception_wrong_parameter('Can NOT read template '.array2string(self::$request->template));
|
||||||
|
}
|
||||||
|
$validated = array();
|
||||||
|
$template->validate($content, $validated);
|
||||||
|
if (self::validation_errors(self::$request->ignore_validation))
|
||||||
|
{
|
||||||
|
error_log(__METHOD__."(,".array2string($content).') validation_errors='.array2string(self::$validation_errors));
|
||||||
|
self::$response->generic('et2_validation_error', self::$validation_errors);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
error_log(__METHOD__."(,".array2string($content).') validated='.array2string($validated));
|
||||||
|
|
||||||
// merge with preserve and call our callback
|
return ExecMethod(self::$request->method, self::complete_array_merge(self::$request->preserv, $validated));
|
||||||
return ExecMethod(self::$request->method, self::complete_array_merge(self::$request->preserv, $content));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the content
|
|
||||||
*
|
|
||||||
* ** Test stub! ** First field always fails.
|
|
||||||
* @todo Fix this for proper server side validation
|
|
||||||
*/
|
|
||||||
static public function validate($content) {
|
|
||||||
self::$response->generic('et2_validation_error', array(
|
|
||||||
// Validation errors are field_name: message
|
|
||||||
key($content)=> "First field fails serverside. '".current($content)."'")
|
|
||||||
);
|
|
||||||
|
|
||||||
return $content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,11 +176,16 @@ class etemplate_new
|
|||||||
*/
|
*/
|
||||||
public $rel_path;
|
public $rel_path;
|
||||||
|
|
||||||
|
public $name;
|
||||||
|
public $template_set;
|
||||||
|
public $version;
|
||||||
|
public $laod_via;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an eTemplate from filesystem or DB (not yet supported)
|
* Reads an eTemplate from filesystem or DB (not yet supported)
|
||||||
*
|
*
|
||||||
* @param string $name name of the eTemplate or array with the values for all keys
|
* @param string $name name of the eTemplate or array with the values for all keys
|
||||||
* @param string $template template-set, '' loads the prefered template of the user, 'default' loads the default one '' in the db
|
* @param string $template_set template-set, '' loads the prefered template of the user, 'default' loads the default one '' in the db
|
||||||
* @param string $lang language, '' loads the pref. lang of the user, 'default' loads the default one '' in the db
|
* @param string $lang language, '' loads the pref. lang of the user, 'default' loads the default one '' in the db
|
||||||
* @param int $group id of the (primary) group of the user or 0 for none, not used at the moment !!!
|
* @param int $group id of the (primary) group of the user or 0 for none, not used at the moment !!!
|
||||||
* @param string $version version of the eTemplate
|
* @param string $version version of the eTemplate
|
||||||
@ -207,79 +194,27 @@ class etemplate_new
|
|||||||
*
|
*
|
||||||
* @ToDo supported customized templates stored in DB
|
* @ToDo supported customized templates stored in DB
|
||||||
*/
|
*/
|
||||||
public function read($name,$template='default',$lang='default',$group=0,$version='',$load_via='')
|
public function read($name,$template_set='default',$lang='default',$group=0,$version='',$load_via='')
|
||||||
{
|
{
|
||||||
list($app, $tpl_name) = explode('.', $name, 2);
|
$this->rel_path = self::relPath($this->name=$name, $this->template_set=$template_set,
|
||||||
|
$this->version=$version, $this->laod_via = $load_via);
|
||||||
|
|
||||||
$this->rel_path = '/'.$app.'/templates/'.$template.'/'.$tpl_name.'.xet';
|
return (boolean)$this->real_path;
|
||||||
if (!file_exists(EGW_SERVER_ROOT.$this->rel_path) && $template !== 'default')
|
|
||||||
{
|
|
||||||
$this->rel_path = '/'.$app.'/templates/default/'.$tpl_name.'.xet';
|
|
||||||
}
|
|
||||||
if (!file_exists(EGW_SERVER_ROOT.$this->rel_path))
|
|
||||||
{
|
|
||||||
$this->rel_path = null;
|
|
||||||
error_log(__METHOD__."('$name',...,'$load_via') returning FALSE");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//error_log(__METHOD__."('$name',...,'$load_via') this->rel_path=$this->rel_path returning TRUE");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation errors from process_show and the extensions, should be set via etemplate::set_validation_error
|
* Get template data as array
|
||||||
*
|
*
|
||||||
* @public array form_name => message pairs
|
* @return array
|
||||||
*/
|
*/
|
||||||
static protected $validation_errors = array();
|
public function as_array()
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a validation error, to be displayed in the next exec
|
|
||||||
*
|
|
||||||
* @param string $name (complete) name of the widget causing the error
|
|
||||||
* @param string $error error-message already translated
|
|
||||||
* @param string $cname=null set it to '', if the name is already a form-name, defaults to self::$name_vars
|
|
||||||
*/
|
|
||||||
public static function set_validation_error($name,$error,$cname=null)
|
|
||||||
{
|
{
|
||||||
if (is_null($cname)) $cname = self::$name_vars;
|
return array(
|
||||||
//echo "<p>etemplate::set_validation_error('$name','$error','$cname');</p>\n";
|
'name' => $this->name,
|
||||||
if ($cname) $name = self::form_name($cname,$name);
|
'template_set' => $this->template_set,
|
||||||
|
'version' => $this->version,
|
||||||
if (self::$validation_errors[$name])
|
'load_via' => $this->load_via,
|
||||||
{
|
);
|
||||||
self::$validation_errors[$name] .= ', ';
|
|
||||||
}
|
|
||||||
self::$validation_errors[$name] .= $error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we have not ignored validation errors
|
|
||||||
*
|
|
||||||
* @param string $ignore_validation='' if not empty regular expression for validation-errors to ignore
|
|
||||||
* @param string $cname=null name-prefix, which need to be ignored, default self::$name_vars
|
|
||||||
* @return boolean true if there are not ignored validation errors, false otherwise
|
|
||||||
*/
|
|
||||||
public static function validation_errors($ignore_validation='',$cname='')
|
|
||||||
{
|
|
||||||
// if (is_null($cname)) $cname = self::$name_vars;
|
|
||||||
//echo "<p>uietemplate::validation_errors('$ignore_validation','$cname') validation_error="; _debug_array(self::$validation_errors);
|
|
||||||
if (!$ignore_validation) return count(self::$validation_errors) > 0;
|
|
||||||
|
|
||||||
foreach(self::$validation_errors as $name => $error)
|
|
||||||
{
|
|
||||||
if ($cname) $name = preg_replace('/^'.$cname.'\[([^\]]+)\](.*)$/','\\1\\2',$name);
|
|
||||||
|
|
||||||
// treat $ignoare_validation only as regular expression, if it starts with a slash
|
|
||||||
if ($ignore_validation[0] == '/' && !preg_match($ignore_validation,$name) ||
|
|
||||||
$ignore_validation[0] != '/' && $ignore_validation != $name)
|
|
||||||
{
|
|
||||||
//echo "<p>uietemplate::validation_errors('$ignore_validation','$cname') name='$name' ($error) not ignored!!!</p>\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//echo "<p>uietemplate::validation_errors('$ignore_validation','$cname') name='$name' ($error) ignored</p>\n";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,8 +11,13 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// include only widgets which can't be autoloaded (or contain sub-widgets which cant)
|
||||||
|
require_once EGW_INCLUDE_ROOT.'/etemplate/inc/class.etemplate_widget_textbox.inc.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eTemplate widget baseclass
|
* eTemplate widget baseclass
|
||||||
|
*
|
||||||
|
* @todo text content, eg. the styles of a template are not parsed, thought they are not used here either
|
||||||
*/
|
*/
|
||||||
class etemplate_widget
|
class etemplate_widget
|
||||||
{
|
{
|
||||||
@ -44,6 +49,22 @@ class etemplate_widget
|
|||||||
*/
|
*/
|
||||||
protected $children = array();
|
protected $children = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request object of the currently created request
|
||||||
|
*
|
||||||
|
* It's a static variable as etemplates can contain further etemplates (rendered by a different object)
|
||||||
|
*
|
||||||
|
* @var etemplate_request
|
||||||
|
*/
|
||||||
|
static protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON response object, if we run via a JSON request
|
||||||
|
*
|
||||||
|
* @var egw_json_response
|
||||||
|
*/
|
||||||
|
static protected $response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -89,6 +110,30 @@ class etemplate_widget
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry of classes implementing widgets
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
static protected $widget_registry = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a given class for certain widgets
|
||||||
|
*
|
||||||
|
* Registration is only needed if widget (base-)name is not autoloadable,
|
||||||
|
* eg. class etemplate_widget_template does NOT need to be registered.
|
||||||
|
*
|
||||||
|
* @param string $class
|
||||||
|
* @param string|array $widgets
|
||||||
|
*/
|
||||||
|
public static function registerWidget($class, $widgets)
|
||||||
|
{
|
||||||
|
foreach((array)$widgets as $widget)
|
||||||
|
{
|
||||||
|
self::$widget_registry[$widget] = $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method to construct all widgets
|
* Factory method to construct all widgets
|
||||||
*
|
*
|
||||||
@ -98,22 +143,20 @@ class etemplate_widget
|
|||||||
*/
|
*/
|
||||||
public static function factory($type, $xml, $id=null)
|
public static function factory($type, $xml, $id=null)
|
||||||
{
|
{
|
||||||
static $type2class_name = array();
|
$class_name =& self::$widget_registry[$type];
|
||||||
|
|
||||||
$class_name =& $type2class_name[$type];
|
|
||||||
|
|
||||||
if (!isset($class_name))
|
if (!isset($class_name))
|
||||||
{
|
{
|
||||||
list($basetype) = explode('-',$type);
|
list($basetype) = explode('-',$type);
|
||||||
if (!class_exists($class_name = 'etemplate_'.str_replace('-','_',$type).'_widget') &&
|
if (!class_exists($class_name = 'etemplate_widget_'.str_replace('-','_',$type)) &&
|
||||||
!class_exists($class_name = 'etemplate_'.str_replace('-','_',$basetype).'_widget'))
|
!class_exists($class_name = 'etemplate_widget_'.str_replace('-','_',$basetype)))
|
||||||
{
|
{
|
||||||
// default to widget class, we can not ignore it, as the widget may contain other widgets
|
// default to widget class, we can not ignore it, as the widget may contain other widgets
|
||||||
$class_name = 'etemplate_widget';
|
$class_name = 'etemplate_widget';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// currently only overlays can contain templates, other widgets can only reference to templates via id
|
// currently only overlays can contain templates, other widgets can only reference to templates via id
|
||||||
if ($type == 'template' && $id && ($template = etemplate_template_widget::read($id)))
|
if ($type == 'template' && $id && ($template = etemplate_widget_template::instance($id)))
|
||||||
{
|
{
|
||||||
return $template;
|
return $template;
|
||||||
}
|
}
|
||||||
@ -144,15 +187,23 @@ class etemplate_widget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate input of a widget
|
* Validate input
|
||||||
|
*
|
||||||
|
* Default implementation only calls validate on it's children
|
||||||
*
|
*
|
||||||
* @param array $content
|
* @param array $content
|
||||||
|
* @param array &$validated=array() validated content
|
||||||
* @param string $cname='' current namespace
|
* @param string $cname='' current namespace
|
||||||
* @return mixed
|
* @return boolean true if no validation error, false otherwise
|
||||||
*/
|
*/
|
||||||
public function validate(array $content, $cname = '')
|
public function validate(array $content, &$validated=array(), $cname = '')
|
||||||
{
|
{
|
||||||
|
$ok = true;
|
||||||
|
foreach($this->children as $child)
|
||||||
|
{
|
||||||
|
$ok = $child->validate($content, $validated, $cname) && $ok;
|
||||||
|
}
|
||||||
|
return $ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,6 +230,8 @@ class etemplate_widget
|
|||||||
{
|
{
|
||||||
echo ' '.$name.'="'.htmlspecialchars($value).'"';
|
echo ' '.$name.'="'.htmlspecialchars($value).'"';
|
||||||
}
|
}
|
||||||
|
echo ' php-class="'.get_class($this).'"';
|
||||||
|
|
||||||
if ($this->children)
|
if ($this->children)
|
||||||
{
|
{
|
||||||
echo ">\n";
|
echo ">\n";
|
||||||
@ -193,4 +246,163 @@ class etemplate_widget
|
|||||||
echo " />\n";
|
echo " />\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build the name of a form-element from a basename and name
|
||||||
|
*
|
||||||
|
* name and basename can contain sub-indices in square bracets, eg. basename="base[basesub1][basesub2]"
|
||||||
|
* and name = "name[sub]" gives "base[basesub1][basesub2][name][sub]"
|
||||||
|
*
|
||||||
|
* @param string $cname basename
|
||||||
|
* @param string $name name
|
||||||
|
* @return string complete form-name
|
||||||
|
*/
|
||||||
|
static function form_name($cname,$name)
|
||||||
|
{
|
||||||
|
$name_parts = explode('[',str_replace(']','',$name));
|
||||||
|
if (!empty($cname))
|
||||||
|
{
|
||||||
|
array_unshift($name_parts,$cname);
|
||||||
|
}
|
||||||
|
$form_name = array_shift($name_parts);
|
||||||
|
if (count($name_parts))
|
||||||
|
{
|
||||||
|
$form_name .= '['.implode('][',$name_parts).']';
|
||||||
|
}
|
||||||
|
return $form_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a reference to $arr[$idx]
|
||||||
|
*
|
||||||
|
* This works for non-trival indexes like 'a[b][c]' too: it returns &$arr[a][b][c]
|
||||||
|
* $sub = get_array($arr,'a[b]'); $sub = 'c'; is equivalent to $arr['a']['b'] = 'c';
|
||||||
|
*
|
||||||
|
* @param array $arr the array to search, referenz as a referenz gets returned
|
||||||
|
* @param string $idx the index, may contain sub-indices like a[b], see example below
|
||||||
|
* @param boolean $reference_into default False, if True none-existing sub-arrays/-indices get created to be returned as referenz, else False is returned
|
||||||
|
* @param bool $skip_empty returns false if $idx is not present in $arr
|
||||||
|
* @return mixed reference to $arr[$idx] or false if $idx is not set and not $reference_into
|
||||||
|
*/
|
||||||
|
static function &get_array(&$arr,$idx,$reference_into=False,$skip_empty=False)
|
||||||
|
{
|
||||||
|
if (!is_array($arr))
|
||||||
|
{
|
||||||
|
throw new egw_exception_assertion_failed(__METHOD__."(\$arr,'$idx',$reference_into,$skip_empty) \$arr is no array!");
|
||||||
|
}
|
||||||
|
if (is_object($idx)) return false; // given an error in php5.2
|
||||||
|
|
||||||
|
$idxs = explode('[',str_replace(']','',$idx));
|
||||||
|
$pos = &$arr;
|
||||||
|
foreach($idxs as $idx)
|
||||||
|
{
|
||||||
|
if (!is_array($pos) && !$reference_into)
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
if($skip_empty && (!is_array($pos) || !isset($pos[$idx]))) return false;
|
||||||
|
$pos = &$pos[$idx];
|
||||||
|
}
|
||||||
|
return $pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a widget is readonly:
|
||||||
|
* - readonly attribute set
|
||||||
|
* - $readonlys[__ALL__] set and $readonlys[$form_name] !== false
|
||||||
|
* - $readonlys[$form_name] evaluates to true
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function is_readonly($cname='')
|
||||||
|
{
|
||||||
|
$form_name = self::form_name($cname, $this->id);
|
||||||
|
|
||||||
|
$readonly = $this->attrs['readonly'] || self::$request->readonlys[$form_name] ||
|
||||||
|
isset(self::$request->readonlys['__ALL__']) && self::$request->readonlys[$form_name] !== false;
|
||||||
|
|
||||||
|
error_log(__METHOD__."('$cname') this->id='$this->id' --> form_name='$form_name' returning ".array2string($readonly));
|
||||||
|
|
||||||
|
return $readonly;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Validation errors from process_show and the extensions, should be set via etemplate::set_validation_error
|
||||||
|
*
|
||||||
|
* @public array form_name => message pairs
|
||||||
|
*/
|
||||||
|
static protected $validation_errors = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a validation error, to be displayed in the next exec
|
||||||
|
*
|
||||||
|
* @param string $name (complete) name of the widget causing the error
|
||||||
|
* @param string $error error-message already translated
|
||||||
|
* @param string $cname=null set it to '', if the name is already a form-name, defaults to self::$name_vars
|
||||||
|
*/
|
||||||
|
public static function set_validation_error($name,$error,$cname=null)
|
||||||
|
{
|
||||||
|
if (is_null($cname)) $cname = self::$name_vars;
|
||||||
|
//echo "<p>etemplate::set_validation_error('$name','$error','$cname');</p>\n";
|
||||||
|
if ($cname) $name = self::form_name($cname,$name);
|
||||||
|
|
||||||
|
if (self::$validation_errors[$name])
|
||||||
|
{
|
||||||
|
self::$validation_errors[$name] .= ', ';
|
||||||
|
}
|
||||||
|
self::$validation_errors[$name] .= $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we have not ignored validation errors
|
||||||
|
*
|
||||||
|
* @param string $ignore_validation='' if not empty regular expression for validation-errors to ignore
|
||||||
|
* @param string $cname=null name-prefix, which need to be ignored, default self::$name_vars
|
||||||
|
* @return boolean true if there are not ignored validation errors, false otherwise
|
||||||
|
*/
|
||||||
|
public static function validation_errors($ignore_validation='',$cname='')
|
||||||
|
{
|
||||||
|
// if (is_null($cname)) $cname = self::$name_vars;
|
||||||
|
//echo "<p>uietemplate::validation_errors('$ignore_validation','$cname') validation_error="; _debug_array(self::$validation_errors);
|
||||||
|
if (!$ignore_validation) return count(self::$validation_errors) > 0;
|
||||||
|
|
||||||
|
foreach(self::$validation_errors as $name => $error)
|
||||||
|
{
|
||||||
|
if ($cname) $name = preg_replace('/^'.$cname.'\[([^\]]+)\](.*)$/','\\1\\2',$name);
|
||||||
|
|
||||||
|
// treat $ignoare_validation only as regular expression, if it starts with a slash
|
||||||
|
if ($ignore_validation[0] == '/' && !preg_match($ignore_validation,$name) ||
|
||||||
|
$ignore_validation[0] != '/' && $ignore_validation != $name)
|
||||||
|
{
|
||||||
|
//echo "<p>uietemplate::validation_errors('$ignore_validation','$cname') name='$name' ($error) not ignored!!!</p>\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//echo "<p>uietemplate::validation_errors('$ignore_validation','$cname') name='$name' ($error) ignored</p>\n";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Named widget having an own namespace: grid, *box
|
||||||
|
*/
|
||||||
|
class etemplate_widget_named extends etemplate_widget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate input
|
||||||
|
*
|
||||||
|
* Reimplemented because grids can have an own namespace
|
||||||
|
*
|
||||||
|
* @param array $content
|
||||||
|
* @param array &$validated=array() validated content
|
||||||
|
* @param string $cname='' current namespace
|
||||||
|
* @return boolean true if no validation error, false otherwise
|
||||||
|
*/
|
||||||
|
public function validate(array $content, &$validated=array(), $cname = '')
|
||||||
|
{
|
||||||
|
if ($this->id) $cname = self::form_name($cname, $this->id);
|
||||||
|
|
||||||
|
return parent::validate($content, $validated, $cname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// register class for layout widgets, which can have an own namespace
|
||||||
|
etemplate_widget::registerWidget('etemplate_widget_named', array('grid', 'box', 'hbox', 'vbox', 'groupbox'));
|
||||||
|
50
etemplate/inc/class.etemplate_widget_button.inc.php
Normal file
50
etemplate/inc/class.etemplate_widget_button.inc.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware - eTemplate serverside button widget
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package etemplate
|
||||||
|
* @subpackage api
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||||
|
* @copyright 2002-11 by RalfBecker@outdoor-training.de
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eTemplate button widget
|
||||||
|
*/
|
||||||
|
class etemplate_widget_button extends etemplate_widget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate input
|
||||||
|
*
|
||||||
|
* Readonly buttons can NOT be pressed
|
||||||
|
*
|
||||||
|
* @param array $content
|
||||||
|
* @param array &$validated=array() validated content
|
||||||
|
* @param string $cname='' current namespace
|
||||||
|
* @return boolean true if no validation error, false otherwise
|
||||||
|
*/
|
||||||
|
public function validate(array $content, &$validated=array(), $cname = '')
|
||||||
|
{
|
||||||
|
$form_name = self::form_name($cname, $this->id);
|
||||||
|
|
||||||
|
if (self::get_array($content, $form_name) && !$this->is_readonly($cname))
|
||||||
|
{
|
||||||
|
$valid =& self::get_array($validated, $form_name, true);
|
||||||
|
$valid = 'pressed'; // that's what it was in old etemplate
|
||||||
|
|
||||||
|
// recored pressed button globally, was in the template object before, not sure self::$request is the right place ...
|
||||||
|
if ($this->type == 'cancel' || $form_name == 'cancel' || substr($form_name,-10) == '[cancel]')
|
||||||
|
{
|
||||||
|
self::$request->canceled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self::$request->button_pressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parent::validate($content, $validated, $cname);
|
||||||
|
}
|
||||||
|
}
|
@ -11,21 +11,21 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* testwise to have autoloading
|
// allow to call direct for tests (see end of class)
|
||||||
if (!isset($GLOBALS['egw_info']))
|
if (!isset($GLOBALS['egw_info']))
|
||||||
{
|
{
|
||||||
$GLOBALS['egw_info'] = array(
|
$GLOBALS['egw_info'] = array(
|
||||||
'flags' => array(
|
'flags' => array(
|
||||||
'currentapp' => 'login',
|
'currentapp' => 'login',
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
include_once '../../header.inc.php';
|
include_once '../../header.inc.php';
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* eTemplate widget baseclass
|
* eTemplate widget baseclass
|
||||||
*/
|
*/
|
||||||
class etemplate_template_widget extends etemplate_widget
|
class etemplate_widget_template extends etemplate_widget
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Cache of already read templates
|
* Cache of already read templates
|
||||||
@ -35,23 +35,23 @@ class etemplate_template_widget extends etemplate_widget
|
|||||||
protected static $cache = array();
|
protected static $cache = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a templates specified by name, template(-set) and version
|
* Get instance of template specified by name, template(-set) and version
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $template_set='default'
|
* @param string $template_set='default'
|
||||||
* @param string $version=''
|
* @param string $version=''
|
||||||
* @param string $load_via='' use given template to load $name
|
* @param string $load_via='' use given template to load $name
|
||||||
* @todo Reading customized templates from database
|
* @todo Reading customized templates from database
|
||||||
* @return etemplate_template_widget|boolean false if not found
|
* @return etemplate_widget_template|boolean false if not found
|
||||||
*/
|
*/
|
||||||
public static function read($name, $template_set='default', $version='', $load_via='')
|
public static function instance($name, $template_set='default', $version='', $load_via='')
|
||||||
{
|
{
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
if (isset(self::$cache[$name]) || !($path = self::relPath($name, $template_set, $version)))
|
if (isset(self::$cache[$name]) || !($path = self::relPath($name, $template_set, $version)))
|
||||||
{
|
{
|
||||||
if ((!$path || self::read($load_via, $template_set)) && isset(self::$cache[$name]))
|
if ((!$path || self::read($load_via, $template_set)) && isset(self::$cache[$name]))
|
||||||
{
|
{
|
||||||
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') read from cache");
|
//error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') read from cache");
|
||||||
return self::$cache[$name];
|
return self::$cache[$name];
|
||||||
}
|
}
|
||||||
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') template NOT found!");
|
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') template NOT found!");
|
||||||
@ -64,14 +64,14 @@ class etemplate_template_widget extends etemplate_widget
|
|||||||
{
|
{
|
||||||
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'template')
|
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'template')
|
||||||
{
|
{
|
||||||
$template = new etemplate_template_widget($reader);
|
$template = new etemplate_widget_template($reader);
|
||||||
//echo $template->id; _debug_array($template);
|
//echo $template->id; _debug_array($template);
|
||||||
|
|
||||||
self::$cache[$template->id] = $template;
|
self::$cache[$template->id] = $template;
|
||||||
|
|
||||||
if ($template->id == $name)
|
if ($template->id == $name)
|
||||||
{
|
{
|
||||||
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') read in ".round(1000.0*(microtime(true)-$start),2)." ms");
|
//error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') read in ".round(1000.0*(microtime(true)-$start),2)." ms");
|
||||||
return $template;
|
return $template;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,9 +104,28 @@ class etemplate_template_widget extends etemplate_widget
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate input
|
||||||
|
*
|
||||||
|
* Reimplemented because templates can have an own namespace specified in options, NOT id!
|
||||||
|
*
|
||||||
|
* @param array $content
|
||||||
|
* @param array &$validated=array() validated content
|
||||||
|
* @param string $cname='' current namespace
|
||||||
|
* @return boolean true if no validation error, false otherwise
|
||||||
|
*/
|
||||||
|
public function validate(array $content, &$validated=array(), $cname = '')
|
||||||
|
{
|
||||||
|
if ($this->attrs['options']) $cname = self::form_name($cname, $this->attrs['options']);
|
||||||
|
|
||||||
|
return parent::validate($content, $validated, $cname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
header('Content-Type: text/xml');
|
if ($GLOBALS['egw_info']['flags']['currentapp'] == 'login')
|
||||||
$template = etemplate_template_widget::read('timesheet.edit');
|
{
|
||||||
$template->toXml();
|
$template = etemplate_widget_template::instance('timesheet.edit');
|
||||||
*/
|
header('Content-Type: text/xml');
|
||||||
|
echo $template->toXml();
|
||||||
|
}
|
116
etemplate/inc/class.etemplate_widget_textbox.inc.php
Normal file
116
etemplate/inc/class.etemplate_widget_textbox.inc.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware - eTemplate serverside textbox widget
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package etemplate
|
||||||
|
* @subpackage api
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||||
|
* @copyright 2002-11 by RalfBecker@outdoor-training.de
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eTemplate textbox widget with following sub-types:
|
||||||
|
* - textbox optional multiline="true" and rows="123"
|
||||||
|
* - int
|
||||||
|
* - float
|
||||||
|
* - hidden
|
||||||
|
* - colorpicker
|
||||||
|
* sub-types are either passed to constructor or set via 'type' attribute!
|
||||||
|
*/
|
||||||
|
class etemplate_widget_textbox extends etemplate_widget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate input
|
||||||
|
*
|
||||||
|
* Following attributes get checked:
|
||||||
|
* - needed: value must NOT be empty
|
||||||
|
* - min, max: int and float widget only
|
||||||
|
* - maxlength: maximum length of string (longer strings get truncated to allowed size)
|
||||||
|
* - preg: perl regular expression incl. delimiters (set by default for int, float and colorpicker)
|
||||||
|
* - int and float get casted to their type
|
||||||
|
*
|
||||||
|
* @param array $content
|
||||||
|
* @param array &$validated=array() validated content
|
||||||
|
* @param string $cname='' current namespace
|
||||||
|
* @return boolean true if no validation error, false otherwise
|
||||||
|
*/
|
||||||
|
public function validate(array $content, &$validated=array(), $cname = '')
|
||||||
|
{
|
||||||
|
$ok = true;
|
||||||
|
$type = isset($this->attrs['type']) ? $this->attrs['type'] : $this->type;
|
||||||
|
if (!$this->is_readonly($cname))
|
||||||
|
{
|
||||||
|
if (!isset($this->attrs['preg']))
|
||||||
|
{
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case 'int':
|
||||||
|
$this->attrs['preg'] = '/^-?[0-9]*$/';
|
||||||
|
break;
|
||||||
|
case 'float':
|
||||||
|
$this->attrs['preg'] = '/^-?[0-9]*[,.]?[0-9]*$/';
|
||||||
|
break;
|
||||||
|
case 'colorpicker':
|
||||||
|
$this->attrs['preg'] = '/^(#[0-9a-f]{6}|)$/i';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$form_name = self::form_name($cname, $this->id);
|
||||||
|
|
||||||
|
$value = self::get_array($content, $form_name);
|
||||||
|
$valid =& self::get_array($validated, $form_name, true);
|
||||||
|
|
||||||
|
if ((string)$value === '' && $this->attrs['needed'])
|
||||||
|
{
|
||||||
|
self::set_validation_error($form_name,lang('Field must not be empty !!!'),'');
|
||||||
|
$ok = false;
|
||||||
|
}
|
||||||
|
if ((int) $this->attrs['maxlength'] > 0 && strlen($value) > (int) $this->attrs['maxlength'])
|
||||||
|
{
|
||||||
|
$value = substr($value,0,(int) $this->attrs['maxlength']);
|
||||||
|
}
|
||||||
|
if ($this->attrs['preg'] && !preg_match($this->attrs['preg'],$value))
|
||||||
|
{
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case 'int':
|
||||||
|
self::set_validation_error($form_name,lang("'%1' is not a valid integer !!!",$value),'');
|
||||||
|
break;
|
||||||
|
case 'float':
|
||||||
|
self::set_validation_error($form_name,lang("'%1' is not a valid floatingpoint number !!!",$value),'');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
self::set_validation_error($form_name,lang("'%1' has an invalid format !!!",$value)/*." !preg_match('$this->attrs[preg]', '$value')"*/,'');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$ok = false;
|
||||||
|
}
|
||||||
|
elseif ($type == 'int' || $type == 'float') // cast int and float and check range
|
||||||
|
{
|
||||||
|
if ((string)$value !== '' || $this->attrs['needed']) // empty values are Ok if needed is not set
|
||||||
|
{
|
||||||
|
$value = $type == 'int' ? (int) $value : (float) str_replace(',','.',$value); // allow for german (and maybe other) format
|
||||||
|
|
||||||
|
if (!empty($this->attrs['min']) && $value < $this->attrs['min'])
|
||||||
|
{
|
||||||
|
self::set_validation_error($form_name,lang("Value has to be at least '%1' !!!",$this->attrs['min']),'');
|
||||||
|
$value = $type == 'int' ? (int) $this->attrs['min'] : (float) $this->attrs['min'];
|
||||||
|
$ok = false;
|
||||||
|
}
|
||||||
|
if (!empty($this->attrs['max']) && $value > $this->attrs['max'])
|
||||||
|
{
|
||||||
|
self::set_validation_error($form_name,lang("Value has to be at maximum '%1' !!!",$this->attrs['max']),'');
|
||||||
|
$value = $type == 'int' ? (int) $this->attrs['max'] : (float) $this->attrs['max'];
|
||||||
|
$ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$valid = $value;
|
||||||
|
}
|
||||||
|
return parent::validate($content, $validated, $cname) && $ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
etemplate_widget::registerWidget('etemplate_widget_textbox', array('textbox','int','float','passwd','hidden','colorpicker'));
|
Loading…
Reference in New Issue
Block a user