[ 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.nextmatch_widget.inc.php (source)

   1  <?php
   2      /**************************************************************************\
   3      * eGroupWare - eTemplate Extension - Nextmatch Widget                      *
   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.nextmatch_widget.inc.php 22883 2006-12-05 10:11:26Z ralfbecker $ */
  14  
  15      /**
  16       * eTemplate Extension: Widget that show only a certain number of data-rows and allows to modifiy the rows shown (scroll).
  17       *
  18       * This widget replaces the old nextmatch-class. It is independent of the UI,
  19       * as it only uses etemplate-widgets and has therefor no render-function
  20       *
  21       * $content[$id] = array(    // I = value set by the app, 0 = value on return / output
  22       *     'get_rows'       =>        // I  method/callback to request the data for the rows eg. 'notes.bo.get_rows'
  23       *     'filter_label'   =>        // I  label for filter    (optional)
  24       *     'filter_help'    =>        // I  help-msg for filter (optional)
  25       *     'no_filter'      => True// I  disable the 1. filter
  26       *     'no_filter2'     => True// I  disable the 2. filter (params are the same as for filter)
  27       *     'no_cat'         => True// I  disable the cat-selectbox
  28       *  'cat_app'        =>     // I  application the cat's should be from, default app in get_rows
  29       *     'template'       =>        // I  template to use for the rows, if not set via options
  30       *     'header_left'    =>        // I  template to show left of the range-value, left-aligned (optional)
  31       *     'header_right'   =>        // I  template to show right of the range-value, right-aligned (optional)
  32       *     'bottom_too'     => True// I  show the nextmatch-line (arrows, filters, search, ...) again after the rows
  33       *    'never_hide'     => True// I  never hide the nextmatch-line if less then maxmatch entries
  34       *     'start'          =>        // IO position in list
  35       *    'num_rows'       =>     // IO number of rows to show, defaults to maxmatches from the general prefs
  36       *     'cat_id'         =>        // IO category, if not 'no_cat' => True
  37       *     'search'         =>        // IO search pattern
  38       *     'order'          =>        // IO name of the column to sort after (optional for the sortheaders)
  39       *     'sort'           =>        // IO direction of the sort: 'ASC' or 'DESC'
  40       *     'col_filter'     =>        // IO array of column-name value pairs (optional for the filterheaders)
  41       *     'filter'         =>        // IO filter, if not 'no_filter' => True
  42       *     'filter_no_lang' => True// I  set no_lang for filter (=dont translate the options)
  43       *    'filter_onchange'=> 'this.form.submit();' // I onChange action for filter, default: this.form.submit();
  44       *     'filter2'        =>        // IO filter2, if not 'no_filter2' => True
  45       *     'filter2_no_lang'=> True// I  set no_lang for filter2 (=dont translate the options)
  46       *    'filter2_onchange'=> 'this.form.submit();' // I onChange action for filter2, default: this.form.submit();
  47       *     'rows'           =>        //  O content set by callback
  48       *     'total'          =>        //  O the total number of entries
  49       *     'sel_options'    =>        //  O additional or changed sel_options set by the callback and merged into $tmpl->sel_options
  50       * );
  51       * @package etemplate
  52       * @subpackage extensions
  53       * @author RalfBecker-AT-outdoor-training.de
  54       * @license GPL
  55       */
  56      class nextmatch_widget
  57      {
  58          /** 
  59           * exported methods of this class
  60           * @var array
  61           */
  62          var $public_functions = array(
  63              'pre_process' => True,
  64              'post_process' => True
  65          );
  66          /**
  67           * availible extensions and there names for the editor
  68           * @var array
  69           */
  70          var $human_name = array(
  71              'nextmatch' => 'Nextmatch',
  72              'nextmatch-sortheader' => 'Nextmatch Sortheader',
  73              'nextmatch-filterheader' => 'Nextmatch Filterheader',
  74              'nextmatch-accountfilter' => 'Nextmatch Accountfilter',
  75          );
  76  
  77          /**
  78           * Constructor of the extension
  79           *
  80           * @param string $ui '' for html
  81           */
  82  		function nextmatch_widget($ui)
  83          {
  84          }
  85  
  86          /**
  87           * returns last part of a form-name
  88           * @internal 
  89           */
  90  		function last_part($name)
  91          {
  92              $parts = explode('[',str_replace(']','',$name));
  93              return $parts[count($parts)-1];
  94          }
  95  
  96          /**
  97           * pre-processing of the extension
  98           *
  99           * This function is called before the extension gets rendered
 100           *
 101           * @param string $name form-name of the control
 102           * @param mixed &$value value / existing content, can be modified
 103           * @param array &$cell array with the widget, can be modified for ui-independent widgets 
 104           * @param array &$readonlys names of widgets as key, to be made readonly
 105           * @param mixed &$extension_data data the extension can store persisten between pre- and post-process
 106           * @param object &$tmpl reference to the template we belong too
 107           * @return boolean true if extra label is allowed, false otherwise
 108           */
 109  		function pre_process($name,&$value,&$cell,&$readonlys,&$extension_data,&$tmpl)
 110          {
 111              $nm_global = &$GLOBALS['egw_info']['etemplate']['nextmatch'];
 112              //echo "<p>nextmatch_widget.pre_process(name='$name',type='$cell[type]'): value = "; _debug_array($value);
 113              //echo "<p>nextmatch_widget.pre_process(name='$name',type='$cell[type]'): nm_global = "; _debug_array($nm_global);
 114  
 115              $extension_data = array(
 116                  'type' => $cell['type']
 117              );
 118              switch ($cell['type'])
 119              {
 120                  case 'nextmatch-sortheader':    // Option: default sort: ASC(default) or DESC
 121                      $extension_data['default_sort'] = preg_match('/^(ASC|DESC)$/i',$cell['size']) ? strtoupper($cell['size']) : 'ASC';
 122                      $cell['type'] = 'button';
 123                      $cell['onchange'] = True;
 124                      if (!$cell['help'])
 125                      {
 126                          $cell['help'] = 'click to order after that criteria';
 127                      }
 128                      if ($this->last_part($name) == $nm_global['order'])    // we're the active column
 129                      {
 130                          $cell[1] = $cell;
 131                          $cell[1]['span'] .= ',activ_sortcolumn';
 132                          unset($cell[1]['align']);
 133                          $cell[2] = $tmpl->empty_cell('image',$nm_global['sort'] != 'DESC' ? 'down' : 'up');
 134                          $cell['type'] = 'hbox';
 135                          $cell['size'] = '2,0,0';
 136                          $cell['name'] = $cell['label'] = '';
 137                      }
 138                      else
 139                      {
 140                          $cell['span'] .= ',inactiv_sortcolumn';
 141                      }
 142                      return True;
 143  
 144                  case 'nextmatch-filterheader':    // Option: as for selectbox: [extra-label(default ALL)[,#lines(default 1)]]
 145                      $cell['type'] = 'select';
 146                      if (!$cell['size'])
 147                      {
 148                          $cell['size'] = 'All';
 149                      }
 150                      if (!$cell['help'])
 151                      {
 152                          $cell['help'] = 'select which values to show';
 153                      }
 154                      $cell['onchange'] = $cell['noprint'] = True;
 155                      $extension_data['old_value'] = $value = $nm_global['col_filter'][$this->last_part($name)];
 156                      return True;
 157  
 158                  case 'nextmatch-accountfilter':    // Option: as for selectbox: [extra-label(default ALL)[,#lines(default 1)]]
 159                      $cell['type'] = 'select-account';
 160                      $cell['name'] .= '[account]';
 161                      if (!$cell['size'])
 162                      {
 163                          $cell['size'] = 'All';
 164                      }
 165                      if (!$cell['help'])
 166                      {
 167                          $cell['help'] = 'select which accounts to show';
 168                      }
 169                      $cell['onchange'] = $cell['noprint'] = True;
 170                      $extension_data['old_value'] = $value = $nm_global['col_filter'][$this->last_part($name)];
 171                      return True;
 172              }
 173              if (!$value['filter_onchange']) $value['filter_onchange'] = 'this.form.submit();';
 174              if (!$value['filter2_onchange']) $value['filter2_onchange'] = 'this.form.submit();';
 175  
 176              // presetting the selectboxes with their default values, to NOT loop, because post-process thinks they changed
 177              if (!isset($value['cat_id'])) $value['cat_id'] = '';
 178              if (!isset($value['search'])) $value['search'] = '';
 179              foreach(array('filter','filter2') as $f)
 180              {
 181                  if (!isset($value[$f]))
 182                  {
 183                      list($value[$f]) = isset($tmpl->sel_options[$f]) ? @each($tmpl->sel_options[$f]) : @each($value['options-'.$f]);
 184                      if (!is_string($value[$f])) $value[$f] = (string) $value[$f];
 185                  }
 186              }
 187              list($app,$class,$method) = explode('.',$value['get_rows']);
 188              if ($app && $class)
 189              {
 190                  if (is_object($GLOBALS[$class]))    // use existing instance (put there by a previous CreateObject)
 191                  {
 192                      $obj =& $GLOBALS[$class];
 193                  }
 194                  else
 195                  {
 196                      $obj =& CreateObject($app.'.'.$class);
 197                  }
 198              }
 199              if (!isset($value['cat_app'])) $value['cat_app'] = $app;    // if no cat_app set, use the app from the get_rows func
 200  
 201              $max = $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'];
 202              $row_options = array();
 203              foreach(array(5,12,25,50,100,200,500,999) as $n)
 204              {
 205                  if ($n-5 <= $max && $max <= $n+5) $n = $max;
 206                  $row_options[$n] = $n;
 207              }
 208              if (!isset($row_options[$max]))
 209              {
 210                  $row_options[$max] = $max;
 211                  ksort($row_options);
 212              }
 213              $value['options-num_rows'] =& $row_options;
 214  
 215              if (!isset($value['num_rows'])) $value['num_rows'] = $max;
 216              if ($value['num_rows'] != $max)
 217              {
 218                  $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'] = $max = $value['num_rows'];
 219              }                
 220              if (!is_object($obj) || !method_exists($obj,$method))
 221              {
 222                  $GLOBALS['egw_info']['etemplate']['validation_errors'][$name] = "nextmatch_widget::pre_process($cell[name]): '$value[get_rows]' is no valid method !!!";
 223              }
 224              else
 225              {
 226                  $total = $value['total'] = $obj->$method($value,$value['rows'],$readonlys['rows']);
 227                  
 228                  // allow the get_rows function to override / set sel_options
 229                  if (isset($value['rows']['sel_options']) && is_array($value['rows']['sel_options']))
 230                  {
 231                      $tmpl->sel_options = array_merge($tmpl->sel_options,$value['rows']['sel_options']);
 232                      unset($value['rows']['sel_options']);
 233                  }
 234              }
 235              if ($method && $total && $value['start'] >= $total)
 236              {
 237                  $value['start'] = 0;
 238                  $total = $obj->$method($value,$value['rows'],$readonlys['rows']);
 239              }
 240              if (is_array($value['rows'][0]))    // fixed 0 based arrays
 241              {
 242                  array_unshift($value['rows'],false);
 243              }
 244              list($template,$options) = explode(',',$cell['size']);
 245              if ($template)    // template name can be supplied either in $value['template'] or the options-field
 246              {
 247                  $value['template'] = $template;
 248              }
 249              if (!is_object($value['template']))
 250              {
 251                  $value['template'] =& new etemplate($value['template'],$tmpl->as_array());
 252              }
 253              if ($total < 1 && $value['template']->rows > 1)
 254              {
 255                  $value['template']->data[0]['h'.$value['template']->rows] .= ',1';    // disable the last data row
 256              }
 257              if (!$value['never_hide'] && $total <= $max && $options && $value['search'] == '' &&
 258                   ($value['no_cat'] || !$value['cat_id']) &&
 259                   ($value['no_filter'] || !$value['filter'] || $value['filter'] == 'none') &&
 260                   ($value['no_filter2'] || !$value['filter2'] || $value['filter2'] == 'none'))
 261              {                                            // disable whole nextmatch line if no scrolling necessary
 262                  if ($value['header_left'] || $value['header_right'])
 263                  {
 264                      $nextmatch =& new etemplate('etemplate.nextmatch_widget.header_only');
 265                      $cell['size'] = $cell['name'];
 266                      $cell['obj'] = &$nextmatch;
 267                      $cell['name'] = $nextmatch->name;
 268                  }
 269                  else
 270                  {
 271                      $cell['size'] = $cell['name'].'[rows]';
 272                      $cell['obj'] = &$value['template'];
 273                      $cell['name'] = $value['template']->name;
 274                  }
 275              }
 276              else
 277              {
 278                  $nextmatch =& new etemplate('etemplate.nextmatch_widget');
 279                  // keep the editor away from the generated tmpls
 280                  $nextmatch->no_onclick = true;            
 281                  
 282                  if(isset($value['no_search'])) $value['no_start_search'] = $value['no_search'];
 283                  foreach(array('no_cat'=>'cat_id','no_filter'=>'filter','no_filter2'=>'filter2', 'no_search' => 'search', 'no_start_search' => 'start_search' ) as $val_name => $cell_name)
 284                  {
 285                      if (isset($value[$val_name])) $nextmatch->disable_cells($cell_name,$value[$val_name]);
 286                  }
 287                  foreach(array('header_left','header_right') as $name)
 288                  {
 289                      if (!$value[$name]) $nextmatch->disable_cells('@'.$name);
 290                  }
 291                  foreach(array('filter','filter2') as $cell_name)
 292                  {
 293                      if (isset($value[$cell_name.'_no_lang'])) $nextmatch->set_cell_attribute($cell_name,'no_lang',$value[$cell_name.'_no_lang']);
 294                  }
 295                  $start = $value['start'];
 296                  $end   = $start+$max > $total ? $total : $start+$max;
 297                  $value['range'] = $total ? (1+$start) . ' - ' . $end : '0';
 298                  $nextmatch->set_cell_attribute('first','readonly',$start <= 0);
 299                  $nextmatch->set_cell_attribute('left', 'readonly',$start <= 0);
 300                  $nextmatch->set_cell_attribute('right','readonly',$start+$max >= $total);
 301                  $nextmatch->set_cell_attribute('last', 'readonly',$start+$max >= $total);
 302  
 303                  $cell['size'] = $cell['name'];
 304                  $cell['obj'] = &$nextmatch;
 305                  $cell['name'] = $nextmatch->name;
 306              }
 307              $cell['type'] = 'template';
 308              $cell['label'] = $cell['help'] = '';
 309  
 310              // save values in persistent extension_data to be able use it in post_process
 311              $extension_data += $value;
 312  
 313              foreach(array('sort','order','col_filter') as $n)    // save them for the sortheader
 314              {
 315                  $nm_global[$n] = $value[$n];
 316              }
 317              $value['bottom'] = $value;    // copy the values for the bottom-bar
 318  
 319              return False;    // NO extra Label
 320          }
 321  
 322          /**
 323           * postprocessing method, called after the submission of the form
 324           *
 325           * It has to copy the allowed/valid data from $value_in to $value, otherwise the widget
 326           * will return no data (if it has a preprocessing method). The framework insures that
 327           * the post-processing of all contained widget has been done before.
 328           *
 329           * Only used by select-dow so far
 330           *
 331           * @param string $name form-name of the widget
 332           * @param mixed &$value the extension returns here it's input, if there's any
 333           * @param mixed &$extension_data persistent storage between calls or pre- and post-process
 334           * @param boolean &$loop can be set to true to request a re-submision of the form/dialog
 335           * @param object &$tmpl the eTemplate the widget belongs too
 336           * @param mixed &value_in the posted values (already striped of magic-quotes)
 337           * @return boolean true if $value has valid content, on false no content will be returned!
 338           */
 339  		function post_process($name,&$value,&$extension_data,&$loop,&$tmpl,$value_in)
 340          {
 341              $nm_global = &$GLOBALS['egw_info']['etemplate']['nextmatch'];
 342              //echo "<p>nextmatch_widget.post_process(type='$extension_data[type]', name='$name',value_in='$value_in',order='$nm_global[order]'): value = "; _debug_array($value);
 343              switch($extension_data['type'])
 344              {
 345                  case 'nextmatch-sortheader':
 346                      if ($value_in)
 347                      {
 348                          $nm_global['order'] = $this->last_part($name);
 349                          $nm_global['default_sort'] = $extension_data['default_sort'];
 350                      }
 351                      return False;    // dont report value back, as it's in the wrong location (rows)
 352  
 353                  case 'select-account':        // used by nextmatch-accountfilter
 354                  case 'nextmatch-filterheader':
 355                      if ($value_in != $extension_data['old_value'] && !(!$value_in && !$extension_data['old_value']))
 356                      {
 357                          //echo "<p>setting nm_global[filter][".$this->last_part($name)."]='$value_in' (was '$extension_data[old_value]')</p>\n";
 358                          $nm_global['filter'][$this->last_part($name)] = $value_in;
 359                      }
 360                      return False;    // dont report value back, as it's in the wrong location (rows)
 361              }
 362              $old_value = $extension_data;
 363  
 364              $value['start'] = $old_value['start'];    // need to be set, to be reported back
 365  
 366              if (is_array($value['bottom']))            // we have a second bottom-bar
 367              {
 368                  $inputs = array('search','cat_id','filter','filter2','num_rows');
 369                  foreach($inputs as $name)
 370                  {
 371                      if (isset($value['bottom'][$name]) && $value[$name] == $old_value[$name])
 372                      {
 373                          //echo "value[$name] overwritten by bottom-value[$name]='".$value['bottom'][$name]."', old_value[$name]='".$old_value[$name]."'<br>\n";
 374                          $value[$name] = $value['bottom'][$name];
 375                      }
 376                  }
 377                  $buttons = array('start_search','first','left','right','last');
 378                  foreach($buttons as $name)
 379                  {
 380                      if (isset($value['bottom'][$name]) && $value['bottom'][$name])
 381                      {
 382                          $value[$name] = $value['bottom'][$name];
 383                      }
 384                  }
 385                  unset($value['bottom']);
 386              }
 387              if (isset($old_value['num_rows']) && !is_null($value['num_rows']) && $value['num_rows'] != $old_value['num_rows'])
 388              {
 389                  $loop = true;    // num_rows changed
 390              }
 391              $max = $value['num_rows'] ? $value['num_rows'] : $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'];
 392  
 393              if ($value['start_search'] || $value['search'] != $old_value['search'] ||
 394                  isset($value['cat_id']) && $value['cat_id'] != $old_value['cat_id'] ||
 395                  isset($value['filter']) && $value['filter'] != $old_value['filter'] ||
 396                  isset($value['filter2']) && $value['filter2'] != $old_value['filter2'])
 397              {
 398                  //echo "<p>search='$old_value[search]'->'$value[search]', filter='$old_value[filter]'->'$value[filter]', filter2='$old_value[filter2]'->'$value[filter2]'<br>";
 399                  //echo "new filter --> loop</p>";
 400                  //echo "value ="; _debug_array($value);
 401                  //echo "old_value ="; _debug_array($old_value);
 402                  $loop = True;
 403              }
 404              elseif ($value['first'] || $value['left'] && $old_value['start'] < $max)
 405              {
 406                  $value['start'] = 0;
 407                  unset($value['first']);
 408                  $loop = True;
 409              }
 410              elseif ($value['left'])
 411              {
 412                  $value['start'] = $old_value['start'] - $max;
 413                  unset($value['left']);
 414                  $loop = True;
 415              }
 416              elseif ($value['right'])
 417              {
 418                  $value['start'] = $old_value['start'] + $max;
 419                  unset($value['right']);
 420                  $loop = True;
 421              }
 422              elseif ($value['last'])
 423              {
 424                  $value['start'] = (int) (($old_value['total']-1) / $max) * $max;
 425                  unset($value['last']);
 426                  $loop = True;
 427              }
 428              elseif ($nm_global['order'])
 429              {
 430                  $value['order'] = $nm_global['order'];
 431                  if ($old_value['order'] != $value['order'])
 432                  {
 433                      $value['sort'] = $nm_global['default_sort'];
 434                  }
 435                  else
 436                  {
 437                      $value['sort'] = $old_value['sort'] != 'DESC' ? 'DESC' : 'ASC';
 438                  }
 439                  //echo "<p>old_value=$old_value[order]/$old_value[sort] ==> $value[order]/$value[sort]</p>\n";
 440                  $loop = True;
 441              }
 442              elseif ($nm_global['filter'])
 443              {
 444                  if (!is_array($value['col_filter'])) $value['col_filter'] = array();
 445  
 446                  $value['col_filter'] += $nm_global['filter'];
 447                  $loop = True;
 448              }
 449              return True;
 450          }
 451      }


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