[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/etemplate/inc/ -> class.boetemplate.inc.php (source)

   1  <?php
   2      /**************************************************************************\
   3      * eGroupWare - EditableTemplates - Business Objects                       *
   4      * http://www.eGroupWare.org                                                *
   5      * Written by Ralf Becker <RalfBecker@outdoor-training.de>                  *
   6      * --------------------------------------------                             *
   7      *  This program is free software; you can redistribute it and/or modify it *
   8      *  under the terms of the GNU General Public License as published by the   *
   9      *  Free Software Foundation; either version 2 of the License, or (at your  *
  10      *  option) any later version.                                              *
  11      \**************************************************************************/
  12  
  13      /* $Id: class.boetemplate.inc.php 22824 2006-11-10 11:36:13Z ralfbecker $ */
  14  
  15      include_once (EGW_INCLUDE_ROOT . '/etemplate/inc/class.soetemplate.inc.php');
  16  
  17      /**
  18       * Business Object for eTemplates, extending the Storage Object
  19       *
  20       * Not so much so far, as the most logic is still in the UI-class
  21       *
  22       * @package etemplate
  23       * @subpackage api
  24       * @author RalfBecker-AT-outdoor-training.de
  25       * @license GPL
  26       */
  27      class boetemplate extends soetemplate
  28      {
  29          var $extensions = array();
  30  
  31          var $types = array(
  32              'label'    => 'Label',            // Label $cell['label'] is (to be translated) textual content
  33              'text'    => 'Text',            // Textfield 1 Line (size = [length][,maxlength])
  34              'int'    => 'Integer',        // like text, but only numbers (size = [min][,max])
  35              'float'    => 'Floating Point', // --------------- " --------------------------
  36              'textarea'=> 'Textarea',    // Multiline Text Input (size = [rows][,cols])
  37              'htmlarea' => 'Formatted Text (HTML)',
  38              'checkbox'=> 'Checkbox',
  39              'radio'    => 'Radiobutton',    // Radiobutton (size = value if checked)
  40              'button'=> 'Submitbutton',
  41              'hrule'    => 'Horizontal Rule',
  42              'template' => 'Template',    // $cell['name'] contains template-name, $cell['size'] index into $content,$cname,$readonlys
  43              'image'    => 'Image',            // label = url, name=link or method, help=alt or title
  44              'date'    => '',                 // Datefield, size='' timestamp or size=format like 'm/d/Y'
  45              'select'=>    'Selectbox',    // Selectbox ($sel_options[$name] or $content[options-$name] is array with options)
  46                                          // if size > 1 then multiple selections, size lines showed
  47              'html'    => 'Html',            // Raw html in $content[$cell['name']]
  48              'file'    => 'FileUpload',    // show an input type='file', set the local name as $name}_path
  49              'vbox'    => 'VBox',            // a (vertical) box to contain widgets in rows, size = # of rows
  50              'hbox'    => 'HBox',            // a (horizontal) box to contain widgets in cols, size = # of cols 
  51              'groupbox' => 'GroupBox',    // a box with a label containing other elements to group them (html: fieldset)
  52              'box'    => 'Box',            // just a container for widgets (html: div)
  53              'grid'    => 'Grid',            // tabular widget containing rows with columns of widgets
  54              'deck'    => 'Deck'            // a container of elements where only one is visible, size = # of elem.
  55          );
  56          var $garbage_collection_done;
  57  
  58          /**
  59           * constructor of class
  60           *
  61           * Calls the constructor of soetemplate
  62           *
  63           * @param string/array $name name of etemplate or array with name and other keys
  64           * @param string/array $load_via name or array with keys of other etemplate to load in order to get $name
  65           */
  66  		function boetemplate($name='',$load_via='')
  67          {
  68              $this->soetemplate();
  69  
  70              $tname = &$name;
  71              if (is_array($name))
  72              {
  73                  $tname = &$name['name'];
  74              }
  75              $tname = (strstr($tname,'.') === False && !empty($tname) ?
  76                  (is_array($load_via) ? $load_via['name'] : $load_via).'.':'').$tname;
  77  
  78              if (empty($tname) || !$this->read($name,'','',0,'',$load_via))
  79              {
  80                  $this->init($name);
  81              }
  82              $this->garbage_collection_done =& $GLOBALS['egw_info']['etemplate']['garbage_collection_done'];
  83          }
  84  
  85          /**
  86           * checks if a grid row or column is disabled
  87           *
  88           * Expression: [!][@]val[=[@]check] 
  89           * Parts in square brackets are optional, a ! negates the expression, @val evaluates to $content['val']
  90           * if no =check is given all set non-empty and non-zero strings are true (standard php behavior)
  91           *
  92           * @param string $disabled expression to check, eg. "!@var" for !$content['var']
  93           * @param array $content the content-array in the context of the grid
  94           * @return boolean true if the row/col is disabled or false if not
  95           */
  96  		function check_disabled($disabled,$content)
  97          {
  98              if ($this->onclick_handler && !$this->no_onclick)
  99              {
 100                  return false;    // we have an onclick handler
 101              }
 102              //return False;
 103              if ($not = $disabled[0] == '!')
 104              {
 105                  $disabled = substr($disabled,1);
 106              }
 107              list($val,$check_val) = $vals = explode('=',$disabled);
 108  
 109              if ($val[0] == '@')
 110              {
 111                  $val = $this->get_array($content,substr($val,1));
 112              }
 113              if ($check_val[0] == '@')
 114              {
 115                  $check_val = $this->get_array($content,substr($check_val,1));
 116              }
 117              $result = count($vals) == 1 ? $val != '' : $val == $check_val;
 118              if ($not) $result = !$result;
 119              //echo "<p>check_disabled: '".($not?'!':'')."$disabled' = '$val' ".(count($vals) == 1 ? '' : ($not?'!':'=')."= '$check_val'")." = ".($result?'True':'False')."</p>\n";
 120              return $result;
 121          }
 122  
 123          /**
 124           * allows a few variables (eg. row-number) to be used in field-names
 125           *
 126           * This is mainly used for autorepeat, but other use is possible.
 127           * You need to be aware of the rules PHP uses to expand vars in strings, a name
 128           * of "Row$row[length]" will expand to 'Row' as $row is scalar, you need to use
 129           * "Row${row}[length]" instead. Only one indirection is allowd in a string by php !!!
 130           * Out of that reason we have now the variable $row_cont, which is $cont[$row] too.
 131           * Attention !!!
 132           * Using only number as index in field-names causes a lot trouble, as depending
 133           * on the variable type (which php determines itself) you used filling and later
 134           * accessing the array it can by the index or the key of an array element.
 135           * To make it short and clear, use "Row$row" or "$col$row" not "$row" or "$row$col" !!!
 136           *
 137           * @param sring $name the name to expand
 138           * @param int $c is the column index starting with 0 (if you have row-headers, data-cells start at 1)
 139           * @param int $row is the row number starting with 0 (if you have col-headers, data-cells start at 1)
 140           * @param int $c_ is the value of the previous template-inclusion,
 141           *     eg. the column-headers in the eTemplate-editor are templates itself,
 142           *     to show the column-name in the header you can not use $col as it will
 143           *     be constant as it is always the same col in the header-template,
 144           *     what you want is the value of the previous template-inclusion.
 145           * @param int $row_ is the value of the previous template-inclusion,
 146           * @param array $cont content of the template, you might use it to generate button-names with id values in it:
 147           *     "del[$cont[id]]" expands to "del[123]" if $cont = array('id' => 123)
 148           * @return string the expanded name
 149           */
 150  		function expand_name($name,$c,$row,$c_='',$row_='',$cont='')
 151          {
 152              $is_index_in_content = $name[0] == '@';
 153              if (strstr($name,'$') !== False)
 154              {
 155                  if (!$cont)
 156                  {
 157                      $cont = array();
 158                  }
 159                  $col = $this->num2chrs($c-1);    // $c-1 to get: 0:'@', 1:'A', ...
 160                  $col_ = $this->num2chrs($c_-1);
 161                  $row_cont = $cont[$row];
 162                  $col_row_cont = $cont[$col.$row];
 163  
 164                  eval('$name = "'.$name.'";');
 165              }
 166              if ($is_index_in_content)
 167              {
 168                  $name = $this->get_array($cont,substr($name,1));
 169              }
 170              return $name;
 171          }
 172  
 173          /**
 174           * Checks if we have an row- or column autorepeat and sets the indexes for $content, etc.
 175           *
 176           * Autorepeat is important to allow a variable numer of rows or cols, eg. for a list.
 177           * The eTemplate has only one (have to be the last) row or column, which gets
 178           * automaticaly repeated as long as content is availible. To check this the content
 179           * has to be in an sub-array of content. The index / subscript into content is
 180           * determined by the content of size for templates or name for regular fields.
 181           * An autorepeat is defined by an index which contains variables to expand.
 182           * (vor variable expansion in names see expand_names). Usually I use the keys
 183           * $row: 0, 1, 2, 3, ... for only rows, $col: '@', 'A', 'B', 'C', ... for only cols or
 184           * $col$row: '@0','A0',... '@1','A1','B1',... '@2','A2','B2',... for both rows and cells.
 185           * In general everything expand_names can generate is ok - see there.
 186           * As you usually have col- and row-headers, data-cells start with '1' or 'A' !!!
 187           *
 188           * @param array $cell with data of cell: name, type, size, ...
 189           * @param int $c,$r col/row index starting from 0
 190           * @param string &$idx returns the index in $content and $readonlys (NOT $sel_options !!!)
 191           * @param string &$idx_cname returns the basename for the form-name: is $idx if only one value
 192           *        (no ',') is given in size (name (not template-fields) are always only one value)
 193           * @param boolean $check_col to check for col- or row-autorepeat
 194           * @return boolean true if cell is autorepeat (has index with vars / '$') or false otherwise
 195           */
 196  		function autorepeat_idx($cell,$c,$r,&$idx,&$idx_cname,$check_col=False)
 197          {
 198              $org_idx = $idx = $cell[ $cell['type'] == 'template' ? 'size' : 'name' ];
 199  
 200              $idx = $this->expand_name($idx,$c,$r);
 201              if (!($komma = strpos($idx,',')))
 202              {
 203                  $idx_cname = $idx;
 204              }
 205              else
 206              {
 207                  $idx_cname = substr($idx,1+$komma);
 208                  $idx = substr($idx,0,$komma);
 209              }
 210              $Ok = False;
 211              $pat = $org_idx;
 212              while (!$Ok && ($pat = strstr($pat,'$')))
 213              {
 214                  $pat = substr($pat,$pat[1] == '{' ? 2 : 1);
 215  
 216                  if ($check_col)
 217                  {
 218                      $Ok = $pat[0] == 'c' && !(substr($pat,0,4) == 'cont' ||
 219                              substr($pat,0,2) == 'c_' || substr($pat,0,4) == 'col_');
 220                  }
 221                  else
 222                  {
 223                      $Ok = $pat[0] == 'r' && !(substr($pat,0,2) == 'r_' || 
 224                          substr($pat,0,4) == 'row_' && substr($pat,0,8) != 'row_cont');
 225                  }
 226              }
 227              if ($this->name && $this->name == $this->debug)
 228              {
 229                  echo "$this->name ".($check_col ? 'col' : 'row')."-check: c=$c, r=$r, idx='$org_idx'='$idx' idx_cname='$idx_cname' ==> ".($Ok?'True':'False')."<p>\n";
 230              }
 231              return $Ok;
 232          }
 233  
 234          /**
 235           *  creates a new appsession-id via microtime()
 236           */
 237  		function appsession_id()
 238          {
 239              list($msec,$sec) = explode(' ',microtime());
 240              $time = 100 * $sec + (int)(100 * $msec);    // gives precision of 1/100 sec
 241              $id = $GLOBALS['egw_info']['flags']['currentapp'] .':'. $time;
 242              //echo "<p>microtime()=".microtime().", sec=$sec, msec=$msec, id=$id</p>\n";
 243              return $id;
 244          }
 245  
 246          /**
 247           * saves content,readonlys,template-keys, ... via the appsession function
 248           *
 249           * As a user may open several windows with the same content/template wie generate a location-id from microtime
 250           * which is used as location for appsession to descriminate between the different windows. This location-id
 251           * is then saved as a hidden-var in the form. The above mentions session-id has nothing to do / is different
 252           * from the session-id which is constant for all windows opened in one session.
 253           *
 254           * @param array $data the data to save
 255           * @param string $id the id to use or '' to generate a new id
 256           * @return string location-id
 257           */
 258  		function save_appsession($data,$id='')
 259          {
 260              if (!$id)
 261              {
 262                  $id = $this->appsession_id();
 263              }
 264              $GLOBALS['egw']->session->appsession($id,'etemplate',$data);
 265  
 266              if (substr($GLOBALS['egw_info']['server']['sessions_type'],0,4) == 'php4' && !$this->garbage_collection_done)
 267              {
 268                  return $this->php4_session_garbage_collection();
 269              }
 270              return $id;
 271          }
 272  
 273          /**
 274           * gets content,readonlys,template-keys, ... back from the appsession function
 275           *
 276           * @param string $id the location-id
 277           * @return array with session-data
 278           */
 279  		function get_appsession($id)
 280          {
 281              $data = $GLOBALS['egw']->session->appsession($id,'etemplate');
 282              //echo "boetemplate::get_appsession('$id')"; _debug_array($data);
 283  
 284              if (substr($GLOBALS['egw_info']['server']['sessions_type'],0,4) == 'php4')
 285              {
 286                  $this->php4_session_garbage_collection($id);
 287              }
 288              return $data;
 289          }
 290          
 291          /**
 292           * a little bit of garbage collection for php4 sessions (their size is limited by memory_limit)
 293           *
 294           * With constant eTemplate use it can grow quite big and lead to unusable sessions (php terminates
 295           * before any output with "Allowed memory size of ... exhausted").
 296           * We delete now sessions once used after 10min and sessions never or multiple used after 60min.
 297           *
 298           * @param string $id_used id of session just read by get_appsession to increment the usage counter
 299           */
 300  		function php4_session_garbage_collection($id_used='')
 301          {
 302              if (!defined('EGW_SESSION_VAR')) return;    // for 1.0.0 compatibility
 303  
 304              // now we are on php4 sessions and do a bit of garbage collection
 305              $app_sessions =& $_SESSION[EGW_SESSION_VAR]['app_sessions']['etemplate'];
 306              $session_used =& $app_sessions['session_used'];
 307              
 308              if ($id_used)
 309              {
 310                  //echo "session_used[$id_used]='".$session_used[$id_used]."'<br/>\n";
 311                  ++$session_used[$id_used];    // count the number of times a session got used
 312              }
 313              $this->garbage_collection_done = true;
 314  
 315              if (count($app_sessions) < 20) return $data;    // we dont need to care
 316  
 317              list($msec,$sec) = explode(' ',microtime());
 318              $now =     100 * $sec + (int)(100 * $msec);    // gives precision of 1/100 sec
 319  
 320              foreach(array_keys($app_sessions) as $id)
 321              {
 322                  list($app,$time) = explode(':',$id);
 323                  
 324                  if (!$time) continue;    // other data, no session
 325                  
 326                  //echo ++$n.') '.$id.': '.(($now-$time)/100.0)."secs old, used=".$session_used[$id].", size=".strlen($app_sessions[$id])."<br>\n";
 327  
 328                  if ($session_used[$id] == 1 && $time < $now - 10*6000 || // session used and older then 10min
 329                      $time < $now - 60*6000)    // session not used and older then 1h
 330                  {
 331                      //echo "<p>boetemplate::php4_session_garbage_collection('$id_used'): unsetting session '$id' (now=$now)</p>\n";
 332                      unset($app_sessions[$id]);
 333                      unset($session_used[$id]);
 334                  }
 335              }
 336          }
 337  
 338          /**
 339           * gets an attribute in a named cell
 340           *
 341           * @static 
 342           * @param string $name cell-name
 343           * @param string $attr attribute-name
 344           * @return mixed the attribute or False if named cell not found
 345           */
 346          function &get_cell_attribute($name,$attr)
 347          {
 348              return $this->set_cell_attribute($name,$attr,NULL);
 349          }
 350  
 351          /**
 352           * set an attribute in a named cell if val is not NULL else return the attribute
 353           *
 354           * @static 
 355           * @param string $name cell-name
 356           * @param string $attr attribute-name
 357           * @param mixed $val if not NULL sets attribute else returns it
 358           * @return mixed number of changed cells or False, if none changed
 359           */
 360          function &set_cell_attribute($name,$attr,$val)
 361          {
 362              //echo "<p>set_cell_attribute(tpl->name=$this->name, name='$name', attr='$attr',val='$val')</p>\n";
 363  
 364              $extra = array(false,$name,$attr,$val);
 365              $result =& $this->widget_tree_walk('set_cell_attribute_helper',$extra);
 366              
 367              if (is_null($val))
 368              {
 369                  return $result;
 370              }
 371              return $extra[0];
 372          }
 373          
 374          /**
 375           *  disables all cells with name == $name
 376           *
 377           * @param sting $name cell-name
 378           * @param boolean $disabled=true disable or enable a cell, default true=disable
 379           * @return mixed number of changed cells or False, if none changed
 380           */
 381  		function disable_cells($name,$disabled=True)
 382          {
 383              return $this->set_cell_attribute($name,'disabled',$disabled);
 384          }
 385          
 386          /**
 387           * set one or more attibutes for row $n
 388           *
 389           * @deprecated as it uses this->data
 390           * @param int $n numerical row-number starting with 1 (!)
 391           * @param string $height percent or pixel or '' for no height
 392           * @param string $class name of css class (without the leading '.') or '' for no class
 393           * @param string $valign alignment (top,middle,bottom) or '' for none
 394           * @param boolean $disabled True or expression or False to disable or enable the row (Only the number 0 means dont change the attribute !!!)
 395           */
 396  		function set_row_attributes($n,$height=0,$class=0,$valign=0,$disabled=0)
 397          {
 398              list($old_height,$old_disabled) = explode(',',$this->data[0]["h$n"]);
 399              $disabled = $disabled !== 0 ? $disabled : $old_disabled;
 400              $this->data[0]["h$n"] = ($height !== 0 ? $height : $old_height).
 401                  ($disabled ? ','.$disabled : '');
 402              list($old_class,$old_valign) = explode(',',$this->data[0]["c$n"]);
 403              $valign = $valign !== 0 ? $valign : $old_valign;
 404              $this->data[0]["c$n"] = ($class !== 0 ? $class : $old_class).
 405                  ($valign ? ','.$valign : '');
 406          }
 407  
 408          /**
 409           * disables row $n
 410           *
 411           * @deprecated as it uses this->data
 412           * @param int $n numerical row-number starting with 1 (!)
 413           * @param boolean $enable=false can be used to re-enable a row if set to True
 414           */
 415  		function disable_row($n,$enable=False)
 416          {
 417              $this->set_row_attributes($n,0,0,0,!$enable);
 418          }
 419  
 420          /**
 421           * set one or more attibutes for column $c
 422           *
 423           * @deprecated as it uses this->data
 424           * @param int/string $c numerical column-number starting with 0 (!), or the char-code starting with 'A'
 425           * @param string $width percent or pixel or '' for no height
 426           * @param mixed $disabled=0 True or expression or False to disable or enable the column (Only the number 0 means dont change the attribute !!!)
 427           */
 428  		function set_column_attributes($c,$width=0,$disabled=0)
 429          {
 430              if (is_numeric($c))
 431              {
 432                  $c = $this->num2chrs($c);
 433              }
 434              list($old_width,$old_disabled) = explode(',',$this->data[0][$c]);
 435              $disabled = $disabled !== 0 ? $disabled : $old_disabled;
 436              $this->data[0][$c] = ($width !== 0 ? $width : $old_width).
 437                  ($disabled ? ','.$disabled : '');
 438          }
 439  
 440          /**
 441           * disables column $c
 442           *
 443           * @deprecated as it uses this->data
 444           * @param int/string $c numerical column-number starting with 0 (!), or the char-code starting with 'A'
 445           * @param boolean $enable can be used to re-enable a column if set to True
 446          */
 447  		function disable_column($c,$enable=False)
 448          {
 449              $this->set_column_attributes($c,0,!$enable);
 450          }
 451  
 452          /**
 453           * trys to load the Extension / Widget-class from the app or etemplate
 454           *
 455           * @param string $name name of the extension, the classname should be class.${name}_widget.inc.php
 456           *    the $name might be "$name.$app" to give a app-name (default is the current app,or template-name)
 457           * @return string/boolean human readable name or false if not found/loadable
 458           */
 459  		function loadExtension($type)
 460          {
 461              list($class,$app) = explode('.',$type);
 462              $class .= '_widget';
 463  
 464              if (!$app) $app = $GLOBALS['egw_info']['flags']['current_app'];
 465  
 466              if (!file_exists(EGW_SERVER_ROOT."/$app/inc/class.$class.inc.php"))
 467              {
 468                  list($app) = explode('_',$type);
 469              }
 470              if (!file_exists(EGW_SERVER_ROOT."/$app/inc/class.$class.inc.php"))
 471              {
 472                  list($app) = explode('.',$this->name);
 473              }
 474              if (!file_exists(EGW_SERVER_ROOT."/$app/inc/class.$class.inc.php"))
 475              {
 476                  $app = 'etemplate';
 477              }
 478              if (!file_exists(EGW_SERVER_ROOT."/$app/inc/class.$class.inc.php"))
 479              {
 480                  //echo "<p>boetemplate::loadExtension($type) extension not found</p>\n";
 481                  return $GLOBALS['egw_info']['etemplate']['extension'][$type] = False;
 482              }
 483              $GLOBALS['egw_info']['etemplate']['extension'][$type] =& CreateObject($app.'.'.$class,$ui='html');
 484  
 485              //echo "<p>boetemplate::loadExtension($type) extension found in App. $app</p>\n";
 486              return $GLOBALS['egw_info']['etemplate']['extension'][$type]->human_name;
 487          }
 488  
 489          /**
 490           * checks if extension is loaded (load it if it isnt) and optional checks if it has a given method
 491           *
 492           * @param string $name name of the extension, the classname should be class.${name}_widget.inc.php
 493           *    the $name might be "$name.$app" to give a app-name (default is the current app,or template-name)
 494           * @param string $function 'pre_process', 'post_process' or 'render'
 495           * @return boolean true if the extension (incl. method) exists, else false
 496           */
 497  		function haveExtension($type,$function='')
 498          {
 499              return ($GLOBALS['egw_info']['etemplate']['extension'][$type] || $this->loadExtension($type,$ui)) &&
 500                              ($function == '' || $GLOBALS['egw_info']['etemplate']['extension'][$type]->public_functions[$function]);
 501          }
 502  
 503          /**
 504           * executes the pre_process-function of the extension $cell[type]
 505           *
 506           * @param string $type type of the extension
 507           * @param string $name form-name of this widget/field (used as a unique index into extension_data)
 508           * @param mixed  &$value value of the extensions content(-array)
 509           * @param array &$cell table-cell on which the extension operates
 510           * @param array &$readonlys value of the extensions readonly-setting(-array)
 511           * @return mixed the return-value of the extensions preprocess function
 512           */
 513  		function extensionPreProcess($type,$name,&$value,&$cell,&$readonlys)
 514          {
 515              if (!$this->haveExtension($type))
 516              {
 517                  return False;
 518              }
 519              return $GLOBALS['egw_info']['etemplate']['extension'][$type]->pre_process($name,$value,$cell,$readonlys,
 520                  $GLOBALS['egw_info']['etemplate']['extension_data'][$name],$this);
 521          }
 522  
 523          /**
 524           * executes the post_process-function of the extension $cell[type]
 525           *
 526           * @param string $type name of the extension
 527           * @param string $name form-name of this widget/field (used as a unique index into extension_data)
 528           * @param mixed &$value returns the value of the extensions content(-array)
 529           * @param mixed $value_in unprocessed value, eg. as posted by the browser
 530           * @return boolean True if a value should be returned (default for no postprocess fkt.), else False
 531           */
 532  		function extensionPostProcess($type,$name,&$value,$value_in)
 533          {
 534              if (!$this->haveExtension($type,'post_process'))
 535              {
 536                  return True;
 537              }
 538              return $GLOBALS['egw_info']['etemplate']['extension'][$type]->post_process($name,$value,
 539                  $GLOBALS['egw_info']['etemplate']['extension_data'][$name],
 540                  $GLOBALS['egw_info']['etemplate']['loop'],$this,$value_in);
 541          }
 542  
 543          /**
 544           * executes the render-function of the extension $cell[type]
 545           *
 546           * @param string $type name of the extension
 547           * @param string $name form-name of this widget/field (used as a unique index into extension_data)
 548           * @param mixed &$value value of the extensions content(-array)
 549           * @param array &$cell table-cell on which the extension operates
 550           * @param array &$readonlys value of the extensions readonly-setting(-array)
 551           * @return mixed return-value of the render function
 552           */
 553  		function extensionRender($type,$name,&$value,&$cell,$readonly)
 554          {
 555              if (!$this->haveExtension($type,'render'))
 556              {
 557                  return False;
 558              }
 559              return $GLOBALS['egw_info']['etemplate']['extension'][$type]->render($cell,$name,$value,$readonly,
 560                  $GLOBALS['egw_info']['etemplate']['extension_data'][$name],$this);
 561          }
 562  
 563          /**
 564           * checks if $idx is set in array $arr
 565           *
 566           * for one level of subindes identical to isset($arr[$idx])
 567           *
 568           * @static 
 569           * @param array $arr array to check
 570           * @param string $idx may contain multiple subindex (eg.'x[y][z]')
 571           * @return boolean true if set, else false
 572           */
 573  		function isset_array($arr,$idx)
 574          {
 575              $idxs = explode('[',str_replace(']','',$idx));
 576              $last_idx = array_pop($idxs);
 577              $pos = &$arr;
 578              foreach($idxs as $idx)
 579              {
 580                  if (!is_array($pos))
 581                  {
 582                      return False;
 583                  }
 584                  $pos = &$pos[$idx];
 585              }
 586              return isset($pos[$last_idx]);
 587          }
 588  
 589          /**
 590           * sets $arr[$idx] = $val
 591           *
 592           * This works for non-trival indexes like 'a[b][c]' too: $arr['a']['b']['c'] = $val;
 593           *
 594           * @static 
 595           * @param array &$arr the array to search
 596           * @param string $idx the index, may contain sub-indices like a[b], see example below
 597           * @param mixed $val value to set
 598           */
 599  		function set_array(&$arr,$idx,$val)
 600          {
 601              if (!is_array($arr))
 602              {
 603                  die('set_array() $arr is no array<br>'.function_backtrace());
 604              }
 605              $idxs = explode('[',str_replace(']','',$idx));
 606              $pos = &$arr;
 607              foreach($idxs as $idx)
 608              {
 609                  $pos = &$pos[$idx];
 610              }
 611              $pos = $val;
 612          }
 613  
 614          /**
 615           * return a reference to $arr[$idx]
 616           *
 617           * This works for non-trival indexes like 'a[b][c]' too: it returns &$arr[a][b][c]
 618           * $sub = get_array($arr,'a[b]'); $sub = 'c'; is equivalent to $arr['a']['b'] = 'c';
 619           *
 620           * @static 
 621           * @param array $arr the array to search, referenz as a referenz gets returned
 622           * @param string $idx the index, may contain sub-indices like a[b], see example below
 623           * @param boolean $reference_into default False, if True none-existing sub-arrays/-indices get created to be returned as referenz, else False is returned
 624           * @return mixed reference to $arr[$idx] or false if $idx is not set and not $reference_into
 625           */
 626          function &get_array(&$arr,$idx,$reference_into=False)
 627          {
 628              if (!is_array($arr))
 629              {
 630                  die('set_array() $arr is no array<br>'.function_backtrace());
 631              }
 632              if (is_object($idx)) return false;    // given an error in php5.2
 633  
 634              $idxs = explode('[',str_replace(']','',$idx));
 635              $pos = &$arr;
 636              foreach($idxs as $idx)
 637              {
 638                  if (!is_array($pos) && !$referenz_info)
 639                  {
 640                      return False;
 641                  }
 642                  $pos = &$pos[$idx];
 643              }
 644              return $pos;
 645          }
 646  
 647          /**
 648           * unsets $arr[$idx]
 649           *
 650           * This works for non-trival indexes like 'a[b][c]' too
 651           * unset_array($arr,'a[b]'); is equivalent to unset($arr['a']['b']);
 652           *
 653           * @static 
 654           * @param array $arr the array to search, referenz as a referenz gets returned
 655           * @param string $idx the index, may contain sub-indices like a[b], see example below
 656           */
 657  		function unset_array(&$arr,$idx)
 658          {
 659              if (!is_array($arr))
 660              {
 661                  die('set_array() $arr is no array<br>'.function_backtrace());
 662              }
 663              $idxs = explode('[',str_replace(']','',$idx));
 664              $last_idx = array_pop($idxs);
 665              $pos = &$arr;
 666              foreach($idxs as $idx)
 667              {
 668                  $pos = &$pos[$idx];
 669              }
 670              unset($pos[$last_idx]);
 671          }
 672  
 673          /**
 674           * merges $old and $new, content of $new has precedence over $old
 675           *
 676           * THIS IS NOT THE SAME AS PHP4's functions: 
 677           * - array_merge, as it calls itself recursive for values which are arrays.
 678           * - array_merge_recursive accumulates values with the same index and $new does NOT overwrite $old
 679           *
 680           * @static 
 681           * @param array $old
 682           * @param array $new
 683           * @return array the merged array
 684           */
 685  		function complete_array_merge($old,$new)
 686          {
 687              if (is_array($new))
 688              {
 689                  if (!is_array($old)) $old = (array) $old;
 690  
 691                  foreach($new as $k => $v)
 692                  {
 693                      if (!is_array($v) || !isset($old[$k]))
 694                      {
 695                          $old[$k] = $v;
 696                      }
 697                      else
 698                      {
 699                          $old[$k] = $this->complete_array_merge($old[$k],$v);
 700                      }
 701                  }
 702              }
 703              return $old;
 704          }
 705          
 706          /**
 707           * returns a reference to a widget in the widget's children tree spezified by a path
 708           *
 709           * The path get's generated by the widget_tree_walk() methode and consists of the keys of the children arrays. 
 710           * For the 3. Column in the 2. row of a grid which is the only widget in the children-tree it is eg.: "/0/2C"
 711           *
 712           * @param string $path path in the widget tree
 713           * @param int $ancestor=0 0: widget itself, 1: parent, 2: grand-parent, ...
 714           * @return array referenz to the widget spezified or null, if it's not found
 715           */
 716          function &get_widget_by_path($path,$ancestor=0)
 717          {
 718              //echo "<p>boetemplate::get_widget_by_path('$path',$ancestor)</p>\n";
 719              $path_parts = explode('/',$path);
 720              while($ancestor-- > 0)
 721              {
 722                  if (array_pop($path_parts) === '') return null;
 723              }
 724              $path = implode('/',$path_parts);
 725              if ($path == '/' || $path === '') return $this->children;
 726  
 727              return $this->widget_tree_walk('get_widget_by_path_helper',$path);
 728          }
 729  
 730          /**
 731           * returns a reference to a widget in the widget's children tree spezified it's name
 732           *
 733           * It returns the first match!
 734           *
 735           * @param string $name name of the widget
 736           * @return array referenz to the widget spezified or null, if it's not found
 737           */
 738          function &get_widget_by_name($name)
 739          {
 740              return $this->widget_tree_walk('get_widget_by_name_helper',$name);
 741          }
 742  
 743          /**
 744           * generated a file-name from an eTemplates, name, template(-set) and lang
 745           *
 746           * @param string/array $name name of template or array('name'=>$name,'template'=>$template,'lang'=>$lang)
 747           * @param string $template template-set
 748           * @param string $lang language to use
 749           * @return string
 750           */
 751  		function cache_name($name='',$template='default',$lang='default')
 752          {
 753              if (empty($name))
 754              {
 755                  $name     = $this->name;
 756                  $template = $this->template;
 757                  $lang     = $this->lang;
 758              }
 759              elseif (is_array($name))
 760              {
 761                  $template = $name['template'];
 762                  $lang     = $name['lang'];
 763                  $name     = $name['name'];
 764              }
 765              if (empty($template))
 766              {
 767                  $template = 'default';
 768              }
 769              $cname = $template . '/' . $name . (!empty($lang) && $lang != 'default' ? '.' . $lang : '');
 770              //echo "cache_name('$name','$template','$lang') = '$cname'";
 771  
 772              return $cname;
 773          }
 774  
 775          /**
 776           * stores the etemplate in the cache in phpgw_info
 777           */
 778  		function store_in_cache()
 779          {
 780              //echo "<p>store_in_cache('$this->name','$this->template','$this->lang','$this->version')</p>\n";
 781              $GLOBALS['egw_info']['etemplate']['cache'][$this->cache_name()] = $this->as_array(1);
 782          }
 783  
 784          /**
 785           * deletes the etemplate in the cache in phpgw_info
 786           */
 787  		function delete_in_cache()
 788          {
 789              //echo "<p>delete_in_cache('$this->name','$this->template','$this->lang','$this->version')</p>\n";
 790              unset($GLOBALS['egw_info']['etemplate']['cache'][$this->cache_name()]);
 791          }
 792  
 793          /*
 794           * returns true if a given eTemplate is in the cache
 795           *
 796           * @param string/array $name name of template or array('name'=>$name,'template'=>$template,'lang'=>$lang)
 797           * @param string $template template-set
 798           * @param string $lang language to use
 799           * @param int $group to use the template for
 800           * @param string $version of the template
 801           * @return boolean
 802           */
 803  		function in_cache($name,$template='default',$lang='default',$group=0,$version='')
 804          {
 805              $cname = $this->cache_name($name,$template,$lang);
 806              if (is_array($name))
 807              {
 808                  $version = $name['version'];
 809                  $name    = $name['name'];
 810              }
 811              if (!isset($GLOBALS['egw_info']['etemplate']['cache'][$cname]) ||
 812                      !empty($version) && $GLOBALS['egw_info']['etemplate']['cache'][$cname]['version'] != $version)
 813              {
 814                  //echo " NOT found in cache</p>\n";
 815                  return False;
 816              }
 817              //echo " found in cache</p>\n";
 818              return $cname;
 819          }
 820  
 821          /*
 822           * reads the content of an eTemplate from the cache into the current object
 823           *
 824           * same as read but only via the cache
 825           *
 826           * @param string/array $name name of template or array('name'=>$name,'template'=>$template,'lang'=>$lang)
 827           * @param string $template template-set
 828           * @param string $lang language to use
 829           * @param int $group to use the template for
 830           * @param string $version of the template
 831           * @return boolean true if the eTemplate was found in the cache
 832           */
 833  		function read_from_cache($name,$template='default',$lang='default',$group=0,$version='')
 834          {
 835              //if (is_array($name)) $version = $name['version']; echo "<p>read_from_cache(,,,version='$version'): ";
 836              if ($cname = $this->in_cache($name,$template,$lang,$group))
 837              {
 838                  $this->init($GLOBALS['egw_info']['etemplate']['cache'][$cname]);
 839  
 840                  return True;
 841              }
 842              return False;
 843          }
 844  
 845          /**
 846           * reads an eTemplate from the cache or database / filesystem (and updates the cache)
 847           *
 848           * reimplementation of soetemplate::read to use and/or update the cache
 849           *
 850           * @param string $name name of the eTemplate or array with the values for all keys
 851           * @param string $template template-set, '' loads the prefered template of the user, 'default' loads the default one '' in the db
 852           * @param string $lang language, '' loads the pref. lang of the user, 'default' loads the default one '' in the db
 853           * @param int $group id of the (primary) group of the user or 0 for none, not used at the moment !!!
 854           * @param string $version version of the eTemplate
 855           * @param mixed $load_via name/array of keys of etemplate to load in order to get $name (only as second try!)
 856           * @return boolean True if a fitting template is found, else False
 857           */
 858  		function read($name,$template='default',$lang='default',$group=0,$version='',$load_via='')
 859          {
 860              if (is_array($name)) {
 861                  $pname = &$name['name'];
 862              }
 863              else
 864              {
 865                  $pname = &$name;
 866              }    
 867              if (empty($pname))
 868              {
 869                  return False;
 870              }
 871              $parent = is_array($load_via) ? $load_via['name'] : $load_via;
 872  
 873                       if (strstr($pname,'.') === False && !empty($parent))
 874              {
 875                  $pname = $parent . '.' . $pname;
 876              }
 877              if (!$this->read_from_cache($name,$template,$lang,$group,$version))
 878              {
 879                  if (!soetemplate::read($name,$template,$lang,$group,$version))
 880                  {
 881                      if ($load_via && (is_string($load_via) ||
 882                              !isset($load_via['tpls_in_file']) || $load_via['tpls_in_file'] > 1))
 883                      {
 884                          soetemplate::read($load_via);
 885                          return $this->read_from_cache($name,$template,$lang,$group,$version);
 886                      }
 887                      return False;
 888                  }
 889                  $this->store_in_cache();
 890              }
 891              return True;
 892          }
 893  
 894          /**
 895           * saves eTemplate-object to db and update the cache
 896           *
 897           * reimplementation of soetemplate::save to update the cache
 898           *
 899           * @param string $name name of the eTemplate or array with the values for all keys
 900           * @param string $template template-set or '' for the default one
 901           * @param string $lang language or '' for the default one
 902           * @param int $group id of the (primary) group of the user or 0 for none, not used at the moment !!!
 903           * @param string $version version of the eTemplate
 904           * @return the number of affected rows, 1 should be ok, 0 somethings wrong
 905           */
 906  		function save($name='',$template='.',$lang='.',$group=0,$version='.')
 907          {
 908              if ($result = soetemplate::save($name,$template,$lang,$group,$version))
 909              {
 910                  $this->store_in_cache();
 911              }
 912              return $result;
 913          }
 914  
 915          /**
 916           * Deletes the eTemplate from the db, object itself is unchanged
 917           *
 918           * reimplementation of soetemplate::delete to update the cache
 919           *
 920           * @return int number of affected rows, 1 should be ok, 0 somethings wrong
 921           */
 922  		function delete()
 923          {
 924              $this->delete_in_cache();
 925  
 926              return soetemplate::delete();
 927          }
 928  
 929      }
 930  
 931      if (!function_exists('set_cell_attribute_helper'))
 932      {
 933          function &set_cell_attribute_helper(&$widget,&$extra)
 934          {
 935              // extra = array(0=>n,1=>name,2=>attr,3=>value)
 936              if ($widget['name'] == $extra[1])
 937              {
 938                  if (is_null($extra[3])) 
 939                  {
 940                      $extra['__RETURN_NOW__'] = true;    // wouldnt work otherwise, if attr is not yet set == null
 941                      return $widget[$extra[2]];
 942                  }
 943                  $widget[$extra[2]] = $extra[3];
 944                  ++$extra[0];
 945              }
 946          }
 947          
 948          function &get_widget_by_name_helper(&$widget,$extra)
 949          {
 950              if ($widget['name'] == $extra) return $widget;
 951          }
 952          
 953          function &get_widget_by_path_helper(&$widget,$extra,$path)
 954          {
 955              //echo "<p>path_searched='$extra', widget-path($widget[type]:$widget[name])='$path'</p>\n";
 956              if ($path == $extra) return $widget;
 957          }
 958      }


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7