server-side adds now urls for extra tabs incl. cache-buster, so we dont rely on app-code to add it

This commit is contained in:
Ralf Becker 2016-02-03 15:20:50 +00:00
parent 4c22eeb77e
commit 0261dd0b82
6 changed files with 102 additions and 72 deletions

View File

@ -101,7 +101,7 @@ class admin_account
$readonlys['account_passwd'] = $readonlys['account_passwd2'] = true;
}
return array(
'name' => 'admin.account?'.filemtime(EGW_SERVER_ROOT.'/admin/templates/default/account.xet'),
'name' => 'admin.account',
'prepend' => true,
'label' => 'Account',
'data' => $account,

View File

@ -7,7 +7,7 @@
* @subpackage api
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @copyright 2002-13 by RalfBecker@outdoor-training.de
* @copyright 2002-16 by RalfBecker@outdoor-training.de
* @version $Id$
*/
@ -109,19 +109,24 @@ class etemplate_new extends etemplate_widget_template
$content
);
foreach($hook_data as $extras) {
foreach($hook_data as $extras)
{
if (!$extras) continue;
foreach(isset($extras[0]) ? $extras : array($extras) as $extra) {
if ($extra['data'] && is_array($extra['data'])) {
foreach(isset($extras[0]) ? $extras : array($extras) as $extra)
{
if ($extra['data'] && is_array($extra['data']))
{
$content = array_merge($content, $extra['data']);
}
if ($extra['preserve'] && is_array($extra['preserve'])) {
if ($extra['preserve'] && is_array($extra['preserve']))
{
$preserv = array_merge($preserv, $extra['preserve']);
}
if ($extra['readonlys'] && is_array($extra['readonlys'])) {
if ($extra['readonlys'] && is_array($extra['readonlys']))
{
$readonlys = array_merge($readonlys, $extra['readonlys']);
}
}
@ -306,13 +311,13 @@ class etemplate_new extends etemplate_widget_template
* Process via Ajax submitted content
*
* @param string $etemplate_exec_id
* @param array $content
* @param array $_content
* @param boolean $no_validation
* @throws egw_exception_wrong_parameter
*/
static public function ajax_process_content($etemplate_exec_id, array $content, $no_validation)
static public function ajax_process_content($etemplate_exec_id, array $_content, $no_validation)
{
//error_log(__METHOD__."(".array2string($etemplate_exec_id).', '.array2string($content).")");
//error_log(__METHOD__."(".array2string($etemplate_exec_id).', '.array2string($_content).")");
self::$request = etemplate_request::read($etemplate_exec_id);
//error_log('request='.array2string(self::$request));
@ -337,7 +342,7 @@ class etemplate_new extends etemplate_widget_template
$expand = array(
'cont' => &self::$request->content,
);
$template->run('validate', array('', $expand, $content, &$validated), true); // $respect_disabled=true: do NOT validate disabled widgets and children
$template->run('validate', array('', $expand, $_content, &$validated), true); // $respect_disabled=true: do NOT validate disabled widgets and children
if ($no_validation)
{
@ -345,7 +350,7 @@ class etemplate_new extends etemplate_widget_template
}
elseif (self::validation_errors(self::$request->ignore_validation))
{
error_log(__METHOD__."(,".array2string($content).') validation_errors='.array2string(self::$validation_errors));
error_log(__METHOD__."(,".array2string($_content).') validation_errors='.array2string(self::$validation_errors));
self::$response->generic('et2_validation_error', self::$validation_errors);
exit;
}
@ -353,50 +358,41 @@ class etemplate_new extends etemplate_widget_template
// tell request call to remove request, if it is not modified eg. by call to exec in callback
self::$request->remove_if_not_modified();
$hook_data = $GLOBALS['egw']->hooks->process(
array(
'hook_location' => 'etemplate2_before_process',
'location_name' => $template->id) +
self::complete_array_merge(self::$request->preserv, $validated)
);
foreach($hook_data as $extras) {
foreach($GLOBALS['egw']->hooks->process(array(
'hook_location' => 'etemplate2_before_process',
'location_name' => $template->id,
) + self::complete_array_merge(self::$request->preserv, $validated)) as $extras)
{
if (!$extras) continue;
foreach(isset($extras[0]) ? $extras : array($extras) as $extra) {
if ($extra['data'] && is_array($extra['data'])) {
foreach(isset($extras[0]) ? $extras : array($extras) as $extra)
{
if ($extra['data'] && is_array($extra['data']))
{
$validated = array_merge($validated, $extra['data']);
}
}
}
unset($hook_data);
//error_log(__METHOD__."(,".array2string($content).')');
//error_log(' validated='.array2string($validated));
$content = ExecMethod(self::$request->method, self::complete_array_merge(self::$request->preserv, $validated));
$tcontent = array();
if( is_array($content) ) {
$tcontent = $content;
}
else {
$tcontent = self::complete_array_merge(
self::$request->preserv,
$validated
);
}
$tcontent = is_array($content) ? $content :
self::complete_array_merge(self::$request->preserv, $validated);
$hook_data = $GLOBALS['egw']->hooks->process(
array(
'hook_location' => 'etemplate2_after_process',
'location_name' => $template->id) +
$tcontent
);
'location_name' => $template->id
) + $tcontent);
unset($tcontent);
if( is_array($content) ) {
foreach($hook_data as $extras) {
if (is_array($content))
{
foreach($hook_data as $extras)
{
if (!$extras) continue;
foreach(isset($extras[0]) ? $extras : array($extras) as $extra) {
@ -472,13 +468,6 @@ class etemplate_new extends etemplate_widget_template
return ExecMethod(self::$request->method, self::complete_array_merge(self::$request->preserv, $validated));
}
/**
* Path of template relative to EGW_SERVER_ROOT
*
* @var string
*/
public $rel_path;
public $name;
public $template_set;
public $version;
@ -494,7 +483,7 @@ class etemplate_new extends etemplate_widget_template
* 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 $template_set=null default try template-set from user and if not found "default"
* @param string $template_set =null default try template-set from user and if not found "default"
* @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 string $version version of the eTemplate
@ -505,13 +494,13 @@ class etemplate_new extends etemplate_widget_template
*/
public function read($name,$template_set=null,$lang='default',$group=0,$version='',$load_via='')
{
// For mobile experience try to load custom mobile templates
if (html::$ua_mobile)
{
$template_set = "mobile";
}
unset($lang); unset($group); // not used, but in old signature
$this->rel_path = self::relPath($this->name=$name, $this->template_set=$template_set,
$this->version=$version, $this->laod_via = $load_via);
@ -580,7 +569,7 @@ class etemplate_new extends etemplate_widget_template
* disables all cells with name == $name
*
* @param sting $name cell-name
* @param boolean $disabled=true disable or enable a cell, default true=disable
* @param boolean $disabled =true disable or enable a cell, default true=disable
* @return reference to attribute
* @deprecated use disableElement($name, $disabled=true)
*/
@ -626,7 +615,7 @@ class etemplate_new extends etemplate_widget_template
/**
* Debug callback just outputting content
*
* @param array $content=null
* @param array $content =null
*/
public function debug(array $content=null)
{
@ -658,8 +647,8 @@ class etemplate_new extends etemplate_widget_template
* Format a number according to user prefs with decimal and thousands separator (later only for readonly)
*
* @param int|float|string $number
* @param int $num_decimal_places=2
* @param boolean $readonly=true
* @param int $num_decimal_places =2
* @param boolean $readonly =true
* @return string
*/
static public function number_format($number,$num_decimal_places=2,$readonly=true)

View File

@ -34,12 +34,11 @@ class etemplate_widget_tabbox extends etemplate_widget
* content. This prevents running the method on disabled tabs.
*
* @param string $method_name
* @param array $params=array('') parameter(s) first parameter has to be the cname, second $expand!
* @param boolean $respect_disabled=false false (default): ignore disabled, true: method is NOT run for disabled widgets AND their children
* @param array $params =array('') parameter(s) first parameter has to be the cname, second $expand!
* @param boolean $respect_disabled =false false (default): ignore disabled, true: method is NOT run for disabled widgets AND their children
*/
public function run($method_name, $params=array(''), $respect_disabled=false)
{
// Make sure additional tabs are processed for any method
if($this->attrs['tabs'] && !$this->tabs_attr_evaluated)
{
@ -51,11 +50,14 @@ class etemplate_widget_tabbox extends etemplate_widget
$this->children[1]->children = array();
}
$this->tabs = array();
foreach($this->attrs['tabs'] as $tab)
{
$template= clone etemplate_widget_template::instance($tab['template']);
if($tab['id']) $template->attrs['content'] = $tab['id'];
$this->children[1]->children[] = $template;
$tab['url'] = etemplate_widget_template::rel2url($template->rel_path);
$this->tabs[] = $tab;
unset($template);
}
}
@ -67,8 +69,8 @@ class etemplate_widget_tabbox extends etemplate_widget
{
foreach($this->children[1]->children as $tab)
{
$ro_id = explode('.',$tab->template ? $tab->template : $tab->id);
$ro_id = $ro_id[count($ro_id)-1];
$parts = explode('.',$tab->template ? $tab->template : $tab->id);
$ro_id = array_pop($parts);
if($readonlys[$ro_id])
{
$tab->attrs['disabled'] = $readonlys[$ro_id];
@ -80,6 +82,23 @@ class etemplate_widget_tabbox extends etemplate_widget
parent::run($method_name, $params, $respect_disabled);
}
/**
* Implemented to send tab-urls incl. cache-buster and mobile template switch to client-side
*
* They are send as tab_urls object via modifications.
*
* @param string $cname
*/
public function beforeSendToClient($cname)
{
$form_name = self::form_name($cname, $this->id);
if (!empty($this->tabs))
{
self::setElementAttribute($form_name, 'tabs', $this->tabs);
}
}
/**
* Validate input - just pass through, tabs doesn't care
*

View File

@ -35,6 +35,13 @@ class etemplate_widget_template extends etemplate_widget
*/
protected static $cache = array();
/**
* Path of template relative to EGW_SERVER_ROOT
*
* @var string
*/
public $rel_path;
/**
* Get instance of template specified by name, template(-set) and version
*
@ -47,6 +54,11 @@ class etemplate_widget_template extends etemplate_widget
*/
public static function instance($_name, $template_set=null, $version='', $load_via='')
{
if (html::$ua_mobile)
{
$template_set = "mobile";
}
//$start = microtime(true);
list($name) = explode('?', $_name); // remove optional cache-buster
if (isset(self::$cache[$name]) || !($path = self::relPath($name, $template_set, $version)))
@ -96,6 +108,7 @@ class etemplate_widget_template extends etemplate_widget
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'template')
{
$template = new etemplate_widget_template($reader);
$template->rel_path = $path;
//echo $template->id; _debug_array($template);
self::$cache[$template->id] = $template;

View File

@ -63,7 +63,7 @@ var et2_tabbox = et2_valueWidget.extend([et2_IInput,et2_IResizeable],
// Create the outer tabbox container
this.container = $j(document.createElement("div"))
.addClass("et2_tabbox");
// Create the upper container for the tab flags
this.flagContainer = $j(document.createElement("div"))
.addClass("et2_tabheader")
@ -212,7 +212,7 @@ var et2_tabbox = et2_valueWidget.extend([et2_IInput,et2_IResizeable],
{
var tab = this.options.tabs[i];
var tab_id = tab.id || tab.template;
var tab_options = {id: tab_id, template:tab.template};
var tab_options = {id: tab_id, template:tab.template, url: tab.url};
if(tab.id)
{
tab_options.content = tab.id;
@ -359,9 +359,9 @@ var et2_tabbox = et2_valueWidget.extend([et2_IInput,et2_IResizeable],
entry.contentDiv.appendTo(entry.flagDiv);
}
}
if (this.options.align_tabs == 'v'){
if (this.options.align_tabs == 'v'){
this.container.addClass('vertical');
this.tabContainer.hide();
}

View File

@ -55,6 +55,11 @@ var et2_template = et2_DOMWidget.extend(
"name": "Content index",
"default": et2_no_init,
"description": "Used for passing in specific content to the template other than what it would get by ID."
},
url: {
name: "URL of template",
type: "string",
description: "full URL to load template incl. cache-buster"
}
},
@ -102,16 +107,20 @@ var et2_template = et2_DOMWidget.extend(
if(!xml)
{
// Ask server
var splitted = template_name.split('.');
// use template base url from initial template, to continue using webdav, if that was loaded via webdav
var path = this.getRoot()._inst.template_base_url + splitted.shift() + "/templates/default/" +
splitted.join('.')+ ".xet" + (cache_buster ? '?download='+cache_buster :
// if server did not give a cache-buster, fall back to current time
'?download='+(new Date).valueOf());
if(splitted.length)
var url = this.options.url;
if (!this.options.url)
{
et2_loadXMLFromURL(path, function(_xmldoc) {
var splitted = template_name.split('.');
// use template base url from initial template, to continue using webdav, if that was loaded via webdav
url = this.getRoot()._inst.template_base_url + splitted.shift() + "/templates/default/" +
splitted.join('.')+ ".xet" + (cache_buster ? '?download='+cache_buster : '');
}
// if server did not give a cache-buster, fall back to current time
if (url.indexOf('?') == -1) url += '?download='+(new Date).valueOf();
if(this.options.url || splitted.length)
{
et2_loadXMLFromURL(url, function(_xmldoc) {
// Scan for templates and store them
for(var i = 0; i < _xmldoc.childNodes.length; i++) {
var template = _xmldoc.childNodes[i];