* @copyright 2002-11 by RalfBecker@outdoor-training.de
* @package etemplate
* @subpackage api
* @version $Id$
*/
/**
* creates dialogs / HTML-forms from eTemplate descriptions
*
* Usage example:
*
* $tmpl = new etemplate('app.template.name');
* $tmpl->exec('app.class.callback',$content_to_show);
*
* This creates a form from the eTemplate 'app.template.name' and takes care that
* the method / public function 'callback' in class 'class' of 'app' gets called
* if the user submits the form. For the complete param's see the description of exec.
*
* etemplate or uietemplate extends boetemplate, all vars and public functions are inherited
*/
class etemplate extends boetemplate
{
/**
* integer debug-level or template-name or cell-type or '' = off
* 1=calls to show and process_show, 2=content after process_show,
* 3=calls to show_cell and process_show_cell
*
* @public int/string
*/
public $debug;
/**
* Inner width of browser window
*
* @public int
*/
public $innerWidth;
/**
* Reference to the content-param of the last call to show, for extensions to use
*
* @public array
*/
public $content;
/**
* Reference to the sel_options-param of the last call to show, for extensions to use
*
* @public array
*/
public $sel_options;
/**
* Name of the form of the currently processed etemplate
*
* @public string
*/
static $name_form='eTemplate';
/**
* Used form-names in this request
*
* @public array
*/
static $name_forms=array();
/**
* Basename of the variables (content) in $_POST and id's, usually 'exec',
* if there's not more then one eTemplate on the page (then it will be exec, exec2, exec3, ...
*
* @public string
*/
static $name_vars='exec';
/**
* Are we running as sitemgr module or not
*
* @public boolean
*/
public $sitemgr=false;
/**
* Javascript to be called, when a widget get's double-clicked (used only by the editor)
* A '%p' gets replace with the colon ':' separated template-name, -version and path of the clicked widget.
*
* @public string
*/
public $onclick_handler;
/**
* Does template processes onclick itself, or forwards it to a proxy
*
* @var boolean
*/
public $no_onclick = false;
/**
* handler to call for onclick
*
* @var string
*/
public $onclick_proxy;
/**
* Extra options for forms, eg. enctype="multipart/form-data"
*
* @public string
*/
static protected $form_options = '';
/**
* 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();
/**
* Flag if the browser has javascript enabled
*
* @var boolean
*/
static public $java_script;
/**
* Flag if exec() is called as part of a hook, replaces the 1.6 and earlier $GLOBALS['egw_info']['etemplate']['hooked'] global variable
*
* @var boolean
*/
static public $hooked;
/**
* The following 3 static vars are used to allow eTemplate apps to hook into each other
*
* @var mixed
*/
static private $previous_content;
static private $hook_content;
static private $hook_app;
/**
* constructor of etemplate class, reads an eTemplate if $name is given
*
* @param string $name of etemplate or array with name and other keys
* @param string/array $load_via with keys of other etemplate to load in order to get $name
*/
function __construct($name='',$load_via='')
{
parent::__construct($name,$load_via);
$this->sitemgr = isset($GLOBALS['Common_BO']) && is_object($GLOBALS['Common_BO']);
if (($this->innerWidth = (int) $_POST['innerWidth']))
{
$GLOBALS['egw']->session->appsession('innerWidth','etemplate',$this->innerWidth);
}
elseif (!($this->innerWidth = (int) $GLOBALS['egw']->session->appsession('innerWidth','etemplate')))
{
$this->innerWidth = 1018; // default width for an assumed screen-resolution of 1024x768
}
//echo "
_POST[innerWidth]='$_POST[innerWidth]', innerWidth=$this->innerWidth
\n"; } /** * Abstracts a html-location-header call * * In other UI's than html this needs to call the methode, defined by menuaction or * open a browser-window for any other links. * * @param string/array $params url or array with get-params incl. menuaction */ static function location($params='') { egw::redirect_link(is_array($params) ? '/index.php' : $params, is_array($params) ? $params : ''); } /** * Generats a Dialog from an eTemplate - abstract the UI-layer * * This is the only function an application should use, all other are INTERNAL and * do NOT abstract the UI-layer, because they return HTML. * Generates a webpage with a form from the template and puts process_exec in the * form as submit-url to call process_show for the template before it * ExecuteMethod's the given $method of the caller. * * @param string $method Methode (e.g. 'etemplate.editor.edit') to be called if form is submitted * @param array $content with content to fill the input-fields of template, eg. the text-field * with name 'name' gets its content from $content['name'] * @param $sel_options array or arrays with the options for each select-field, keys are the * field-names, eg. array('name' => array(1 => 'one',2 => 'two')) set the * options for field 'name'. ($content['options-name'] is possible too !!!) * @param array $readonlys with field-names as keys for fields with should be readonly * (eg. to implement ACL grants on field-level or to remove buttons not applicable) * @param array $preserv with vars which should be transported to the $method-call (eg. an id) array('id' => $id) sets $_POST['id'] for the $method-call * @param int $output_mode * 0 = echo incl. navbar * 1 = return html * -1 = first time return html, after use 0 (echo html incl. navbar), eg. for home * 2 = echo without navbar (eg. for popups) * 3 = return eGW independent html site * @param string $ignore_validation if not empty regular expression for validation-errors to ignore * @param array $changes change made in the last call if looping, only used internaly by process_exec * @return string html for $output_mode == 1, else nothing */ function exec($method,$content,$sel_options='',$readonlys='',$preserv='',$output_mode=0,$ignore_validation='',$changes='') { //echo "'.__METHOD__."($method,...) etemplate[hooked]=".(int)self::$hooked.", etemplate[hook_app]='".self::$hook_app."', isset(etemplate[content])=".(int)isset(self::$previous_content)."
\n"; if ($this->sitemgr) { $GLOBALS['egw_info']['flags']['java_script'] .= $this->include_java_script(2); } else { // support the old global var, in case old apps like 1.6 infolog use it if (isset($GLOBALS['egw_info']['etemplate']['hooked'])) self::$hooked = $GLOBALS['egw_info']['etemplate']['hooked']; if (!@self::$hooked && (int) $output_mode != 1 && (int) $output_mode != -1) // not just returning the html { $GLOBALS['egw_info']['flags']['java_script'] .= $this->include_java_script(2); if ($GLOBALS['egw_info']['flags']['currentapp'] != 'etemplate') { $css_file = '/etemplate/templates/'.$GLOBALS['egw_info']['server']['template_set'].'/app.css'; if (!file_exists(EGW_SERVER_ROOT.$css_file)) { $css_file = '/etemplate/templates/default/app.css'; } $GLOBALS['egw_info']['flags']['css'] .= "\n\t\t\n\t\t".''."\n\t\t'."\n"; echo 'uiself::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 (!self::ignore_validation_match($name, $ignore_validation)) { //echo "
uiself::validation_errors('$ignore_validation','$cname') name='$name' ($error) not ignored!!!
\n"; return true; } //echo "uiself::validation_errors('$ignore_validation','$cname') name='$name' ($error) ignored
\n"; } return false; } /** * Check if given form-name matches ai ignore-validation rule * * @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 * @param string $cname * @return boolean */ static function ignore_validation_match($form_name, $ignore_validation, $cname=null) { if (is_null($cname)) $cname = self::$name_vars; if ($cname) $form_name = preg_replace('/^'.$cname.'\[([^\]]+)\](.*)$/','\\1\\2', $form_name); return empty($ignore_validation) || $ignore_validation[0] == '/' && preg_match($ignore_validation, $form_name) || $ignore_validation[0] != '/' && $ignore_validation == $form_name; } /** * Makes the necessary adjustments to _POST before it calls the app's method * * This function is only to submit forms to, create with exec. * All eTemplates / forms executed with exec are submited to this function * via /etemplate/process_exec.php?menuaction=