[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/inc/plugins/ -> _plugin.funcs.php (source)

   1  <?php
   2  /**

   3   * Functions for Plugin handling.

   4   *

   5   * This file is part of the evoCore framework - {@link http://evocore.net/}

   6   * See also {@link http://sourceforge.net/projects/evocms/}.

   7   *

   8   * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}

   9   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.

  10   *

  11   * {@internal License choice

  12   * - If you have received this file as part of a package, please find the license.txt file in

  13   *   the same folder or the closest folder above for complete license terms.

  14   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)

  15   *   then you must choose one of the following licenses before using the file:

  16   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php

  17   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php

  18   * }}

  19   *

  20   * {@internal Open Source relicensing agreement:

  21   * Daniel HAHLER grants Francois PLANQUE the right to license

  22   * Daniel HAHLER's contributions to this file and the b2evolution project

  23   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  24   * }}

  25   *

  26   * @package evocore

  27   *

  28   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}

  29   * @author fplanque: Francois PLANQUE

  30   * @author blueyed: Daniel HAHLER

  31   *

  32   * @version $Id: _plugin.funcs.php,v 1.2 2007/09/03 23:45:56 blueyed Exp $

  33   */
  34  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  35  
  36  
  37  /**

  38   * Recursive helper function to display a field of the plugin's settings (by manipulating a Form).

  39   *

  40   * This gets used for PluginSettings ("Edit plugin") and PluginUserSettings ("Edit user settings").

  41   *

  42   * @todo dh> Allow to move setting sets up and down (order). Control goes into /inc/CONTROL/settings/plugins.php.

  43   * @todo NOTE: fp> I'm using this outside of Plugins; I'm not sure about proper factorization yet.

  44   *       This should probably be an extension of the Form class. Sth like "AutoForm" ;)

  45   *

  46   * @param string Settings path, e.g. 'locales[0]' or 'setting'

  47   * @param array Meta data for this setting.

  48   * @param Form (by reference)

  49   * @param string Settings type ('Settings' or 'UserSettings' or 'Widget')

  50   * @param Plugin|Widget

  51   * @param mixed Target (User object for 'UserSettings')

  52   * @param mixed Value to really use (used for recursion into array type settings)

  53   */
  54  function autoform_display_field( $parname, $parmeta, & $Form, $set_type, $Obj, $set_target = NULL, $use_value = NULL )
  55  {
  56      global $debug;
  57      global $htsrv_url;
  58      static $has_array_type;
  59  
  60      if( ! empty($parmeta['no_edit']) )
  61      { // this setting is not editable
  62          return;
  63      }
  64  
  65      $params = array();
  66  
  67      if( $use_value === NULL )
  68      { // outermost level
  69          $has_array_type = false; // for adding a note about JS

  70          $outer_most = true;
  71      }
  72      else
  73      {
  74          $outer_most = false;
  75      }
  76  
  77      // Passthrough some attributes to elements:

  78      foreach( $parmeta as $k => $v )
  79      {
  80          if( in_array( $k, array( 'id', 'onchange', 'onclick', 'onfocus', 'onkeyup', 'onkeydown', 'onreset', 'onselect', 'cols', 'rows', 'maxlength' ) ) )
  81          {
  82              $params[$k] = $v;
  83          }
  84      }
  85      if( ! empty($parmeta['multiple']) )
  86      { // "multiple" attribute for "select" inputs:
  87          $params['multiple'] = 'multiple';
  88      }
  89  
  90      if( isset($parmeta['note']) )
  91      {
  92          $params['note'] = $parmeta['note'];
  93      }
  94  
  95      if( ! isset($parmeta['type']) ||  $parmeta['type'] == 'html_input' )
  96      {
  97          $parmeta['type'] = 'text';
  98      }
  99      elseif( $parmeta['type'] == 'html_textarea' )
 100      {
 101          $parmeta['type'] = 'textarea';
 102      }
 103  
 104      if( strpos($parmeta['type'], 'select_') === 0 )
 105      { // 'allow_none' setting for select_* types
 106          if( isset($parmeta['allow_none']) )
 107          {
 108              $params['allow_none'] = $parmeta['allow_none'];
 109          }
 110      }
 111  
 112      $help_icon = NULL;
 113      if( isset($parmeta['help']) )
 114      {
 115          if( $parmeta['help'] === true )
 116          { // link to $parname-target:
 117              $help_target = '#'.preg_replace( array('~\]?\[\d+\]\[~', '~\]$~'), array('_',''), $parname );
 118          }
 119          else
 120          {
 121              $help_target = $parmeta['help'];
 122          }
 123          $help_icon = $Obj->get_help_link( $help_target );
 124      }
 125  
 126      $set_label = isset($parmeta['label']) ? $parmeta['label'] : '';
 127  
 128      if( ! empty($parmeta['disabled']) )
 129      {
 130          $params['disabled'] = 'disabled';
 131      }
 132  
 133  
 134      // "Layout" settings:

 135      if( isset($parmeta['layout']) )
 136      {
 137          switch( $parmeta['layout'] )
 138          {
 139              case 'begin_fieldset':
 140                  $fieldset_title = $set_label;
 141                  if( isset($help_icon) )
 142                  {
 143                      $Form->begin_fieldset( $fieldset_title, array(), array($help_icon) );
 144                  }
 145                  else
 146                  {
 147                      $Form->begin_fieldset( $fieldset_title );
 148                  }
 149                  break;
 150  
 151              case 'end_fieldset':
 152                  $Form->end_fieldset();
 153                  break;
 154  
 155              case 'separator':
 156                  echo '<hr />';
 157                  break;
 158          }
 159          return;
 160      }
 161  
 162      if( ! empty($help_icon) )
 163      { // Append help icon to note:
 164          if( empty($params['note']) )
 165          {
 166              $params['note'] = $help_icon;
 167          }
 168          else
 169          {
 170              $params['note'] .= ' '.$help_icon;
 171          }
 172      }
 173  
 174      if( isset($use_value) )
 175      {
 176          $set_value = $use_value;
 177      }
 178      else
 179      {
 180          switch( $set_type )
 181          {
 182              case 'Widget':
 183                  $set_value = $Obj->get_param( $parname );
 184                  $error_value = NULL;
 185                  break;
 186  
 187              case 'UserSettings':
 188                  // NOTE: this assumes we come here only on recursion or with $use_value set..!

 189                  $set_value = $Obj->UserSettings->get( $parname, $set_target->ID );
 190                  $error_value = $Obj->PluginUserSettingsValidateSet( $tmp_params = array(
 191                      'name' => $parname,
 192                      'value' => & $set_value,
 193                      'meta' => $parmeta,
 194                      'User' => $set_target,
 195                      'action' => 'display' ) );
 196                  break;
 197  
 198              case 'Settings':
 199                  // NOTE: this assumes we come here only on recursion or with $use_value set..!

 200                  $set_value = $Obj->Settings->get( $parname );
 201                  $error_value = $Obj->PluginSettingsValidateSet( $tmp_params = array(
 202                      'name' => $parname,
 203                      'value' => & $set_value,
 204                      'meta' => $parmeta,
 205                      'action' => 'display' ) );
 206                  break;
 207  
 208              default:
 209                  debug_die( "unhandled set_type $set_type" );
 210                  break;
 211          }
 212  
 213          if( $error_value )
 214          { // add error
 215              param_error( 'edit_plugin_'.$Obj->ID.'_set_'.$parname, NULL, $error_value ); // only add the error to the field

 216          }
 217      }
 218  
 219      // Display input element:

 220      $input_name = 'edit_plugin_'.$Obj->ID.'_set_'.$parname;
 221      if( substr($parmeta['type'], 0, 6) == 'select' && ! empty($parmeta['multiple']) )
 222      { // a "multiple" select:
 223          $input_name .= '[]';
 224      }
 225      switch( $parmeta['type'] )
 226      {
 227          case 'checkbox':
 228              $Form->checkbox_input( $input_name, $set_value, $set_label, $params );
 229              break;
 230  
 231          case 'textarea':
 232              $textarea_rows = isset($parmeta['rows']) ? $parmeta['rows'] : 3;
 233              $Form->textarea_input( $input_name, $set_value, $textarea_rows, $set_label, $params );
 234              break;
 235  
 236          case 'select':
 237              $params['force_keys_as_values'] = true; // so that numeric keys get used as values! autoform_validate_param_value() checks for the keys only.

 238              $Form->select_input_array( $input_name, $set_value, $parmeta['options'], $set_label, NULL, $params );
 239              break;
 240  
 241          case 'select_blog':
 242              $BlogCache = & get_Cache( 'BlogCache' );
 243              $Form->select_input_object( $input_name, $set_value, $BlogCache, $set_label, $params );
 244              break;
 245  
 246          case 'select_group':
 247              $GroupCache = & get_Cache( 'GroupCache' );
 248              $Form->select_input_object( $input_name, $set_value, $GroupCache, $set_label, $params );
 249              break;
 250  
 251          case 'select_user':
 252              $UserCache = & get_Cache( 'UserCache' );
 253              $UserCache->load_all();
 254              if( ! isset($params['loop_object_method']) )
 255              {
 256                  $params['loop_object_method'] = 'get_preferred_name';
 257              }
 258              $Form->select_input_object( $input_name, $set_value, $UserCache, $set_label, $params );
 259              break;
 260  
 261          case 'array':
 262              $has_array_type = true;
 263  
 264              if( substr_count( $parname, '[' ) % 2 )
 265              { // this refers to a specific array type set (with index pos at the end), e.g. when adding a field through AJAX:
 266                  $pos_last_bracket = strrpos($parname, '[');
 267                  $k_nb = substr( $parname, $pos_last_bracket+1, -1 );
 268                  $disp_arrays = array( '' => $set_value ); // empty key..

 269                  $parname = substr($parname, 0, $pos_last_bracket);
 270              }
 271              else
 272              { // display all values hold in this set:
 273                  $disp_whole_set = true;
 274                  $disp_arrays = $set_value;
 275                  $fieldset_title = $set_label;
 276                  if( $debug )
 277                  {
 278                      $fieldset_title .= ' [debug: '.$parname.']';
 279                  }
 280                  $Form->begin_fieldset( $fieldset_title );
 281  
 282                  if( ! empty($params['note']) )
 283                  {
 284                      echo '<p class="notes">'.$params['note'].'</p>';
 285                  }
 286                  $k_nb = 0;
 287              }
 288  
 289  
 290              $user_ID = $set_type == 'UserSettings' ? $set_target->ID : '';
 291              if( is_array( $set_value ) && ! empty($set_value) )
 292              { // Display value of the setting. It may be empty, if there's no set yet.
 293                  foreach( $disp_arrays as $k => $v )
 294                  {
 295                      $fieldset_icons = array();
 296                      if( ! isset($parmeta['min_count']) || count($set_value) > $parmeta['min_count'] )
 297                      { // provide icon to remove this set
 298                          $fieldset_icons[] = action_icon(
 299                                  T_('Delete set!'),
 300                                  'delete',
 301                                  regenerate_url( 'action', array('action=del_settings_set&amp;set_path='.$parname.'['.$k.']'.( $set_type == 'UserSettings' ? '&amp;user_ID='.$user_ID : '' ), 'plugin_ID='.$Obj->ID) ),
 302                                  '',
 303                                  5, 0, /* icon/text prio */
 304                                  // attach onclick event to remove the whole fieldset (AJAX):

 305                                  array(
 306                                      'onclick' => "
 307                                          var oThis = this;
 308                                          \$.get('{$htsrv_url}async.php', {
 309                                                  action: 'del_plugin_sett_set',
 310                                                  plugin_ID: '{$Obj->ID}',
 311                                                  user_ID: '$user_ID',
 312                                                  set_type: '$set_type',
 313                                                  set_path: '{$parname}[$k]'
 314                                              },
 315                                              function(r, status) {
 316                                                  if( r == 'OK' )
 317                                                  {
 318                                                      \$(oThis).parents('fieldset:first').remove();
 319                                                  }
 320                                          } );
 321                                          return false;",
 322                                      )
 323                                  );
 324                      }
 325                      $Form->begin_fieldset( '#'.$k_nb, array('class'=>'bordered'), $fieldset_icons );
 326  
 327                      if( isset($parmeta['key']) )
 328                      { // KEY FOR THIS ENTRY:
 329                          if( ! strlen($k) && isset($parmeta['key']['defaultvalue']) )
 330                          { // key is not given/set and we have a default:
 331                              $l_value = $parmeta['key']['defaultvalue'];
 332                          }
 333                          else
 334                          {
 335                              $l_value = $k;
 336                          }
 337                          // RECURSE:

 338                          autoform_display_field( $parname.'['.$k_nb.'][__key__]', $parmeta['key'], $Form, $set_type, $Obj, $set_target, $l_value );
 339                      }
 340  
 341                      foreach( $parmeta['entries'] as $l_set_name => $l_set_entry )
 342                      {
 343                          $l_value = isset($set_value[$k][$l_set_name]) ? $set_value[$k][$l_set_name] : NULL;
 344                          // RECURSE:

 345                          autoform_display_field( $parname.'['.$k_nb.']['.$l_set_name.']', $l_set_entry, $Form, $set_type, $Obj, $set_target, $l_value );
 346                      }
 347                      $Form->end_fieldset();
 348                      $k_nb++;
 349                  }
 350              }
 351  
 352              // TODO: fix this for AJAX callbacks, when removing and re-adding items (dh):

 353              if( ! isset( $parmeta['max_number'] ) || $parmeta['max_number'] > ($k_nb) )
 354              { // no max_number defined or not reached: display link to add a new set
 355                  $set_path = $parname.'['.$k_nb.']';
 356  
 357                  echo '<div>';
 358                  echo action_icon(
 359                      sprintf( T_('Add a new set of &laquo;%s&raquo;'), $set_label),
 360                      'new',
 361                      regenerate_url( 'action', array('action=add_settings_set', 'set_path='.$set_path.( $set_type == 'UserSettings' ? '&amp;user_ID='.get_param('user_ID') : '' ), 'plugin_ID='.$Obj->ID) ),
 362                      T_('New set'),
 363                      5, 1, /* icon/text prio */
 364                      array('onclick'=> "
 365                          var oThis = this;
 366                          \$.get('{$htsrv_url}async.php', {
 367                                  action: 'add_plugin_sett_set',
 368                                  plugin_ID: '{$Obj->ID}',
 369                                  set_type: '$set_type',
 370                                  set_path: '$set_path'
 371                              },
 372                              function(r, status) {
 373                                  \$(oThis).parent('div').html(r);
 374                              }
 375                          );
 376                          return false;")
 377                      );
 378                  echo '</div>';
 379              }
 380  
 381              if( ! empty($disp_whole_set) )
 382              { // close the surrounding fieldset:
 383                  $Form->end_fieldset();
 384              }
 385  
 386              break;
 387  
 388          case 'password':
 389              $params['type'] = 'password'; // same as text input, but type=password

 390  
 391          case 'float':
 392          case 'integer':
 393          case 'text':
 394              // Default: "text input"

 395              if( isset($parmeta['size']) )
 396              {
 397                  $size = (int)$parmeta['size'];
 398              }
 399              else
 400              { // Default size:
 401                  $size = 15;
 402              }
 403              if( isset($parmeta['maxlength']) )
 404              {
 405                  $params['maxlength'] = (int)$parmeta['maxlength'];
 406              }
 407              else
 408              { // do not use size as maxlength, if not given!
 409                  $params['maxlength'] = '';
 410              }
 411  
 412              $Form->text_input( $input_name, $set_value, $size, $set_label, '', $params ); // TEMP: Note already in params

 413              break;
 414  
 415          default:
 416              debug_die( 'Unsupported type ['.$parmeta['type'].'] from GetDefaultSettings()!' );
 417      }
 418  
 419      if( $outer_most && $has_array_type )
 420      { // Note for Non-Javascript users:
 421          echo '<script type="text/javascript"></script><noscript>';
 422          echo '<p class="note">'.T_('Note: before adding a new set you have to save any changes.').'</p>';
 423          echo '</noscript>';
 424      }
 425  }
 426  
 427  
 428  /**

 429   * Helper method for "add_settings_set" and "delete_settings_set" action.

 430   *

 431   * Walks the given settings path and either inits the target entry or unsets it ($init_value=NULL).

 432   *

 433   * @param Plugin

 434   * @param string Settings type ("Settings" or "UserSettings")

 435   * @param string The settings path, e.g. 'setting[0]foo[1]'. (Is used as array internally for recursion.)

 436   * @param mixed The initial value of the setting, typically array() - NULL to unset it (action "delete_settings_set" uses it)

 437   * @return array|false

 438   */
 439  function _set_setting_by_path( & $Plugin, $set_type, $path, $init_value = array() )
 440  {
 441      $r = get_plugin_settings_node_by_path( $Plugin, $set_type, $path, true );
 442      if( $r === false )
 443      {
 444          return false;
 445      }
 446  
 447      // Make return value handier. Note: list() would copy and destroy the references (setting and set_node)!

 448      $set_name = & $r['set_name'];
 449      $set_node = & $r['set_node'];
 450      $set_meta = & $r['set_meta'];
 451      $set_parent = & $r['set_parent'];
 452      $set_key  = & $r['set_key'];
 453      $setting  = & $r['setting'];
 454      #pre_dump( $r );

 455  
 456      #if( isset($set_node) && $init_value !== NULL )

 457      #{ // Setting already exists (and we do not want to delete), e.g. page reload!

 458      #    return false;

 459      #    /*

 460      #    while( isset($l_setting[ $path[0] ]) )

 461      #    { // bump the index until not set

 462      #        $path[0]++;

 463      #    }

 464      #    */

 465      #}

 466      #else

 467      if( is_null($init_value) )
 468      { // NULL is meant to unset it
 469          unset($set_parent[$set_key]);
 470      }
 471      else
 472      { // Init entries:
 473          // destroys reference: $set_node = $init_value;

 474  
 475          // Copy meta entries:

 476          foreach( $set_meta['entries'] as $k => $v )
 477          {
 478              if( isset( $v['defaultvalue'] ) )
 479              { // set to defaultvalue
 480                  $set_node[$k] = $v['defaultvalue'];
 481              }
 482              else
 483              {
 484                  if( isset($v['type']) && $v['type'] == 'array' )
 485                  {
 486                      $set_node[$k] = array();
 487                  }
 488                  else
 489                  {
 490                      $set_node[$k] = '';
 491                  }
 492              }
 493          }
 494      }
 495  
 496      // Set it into $Plugin->Settings or $Plugin->UserSettings:

 497      $Plugin->$set_type->set( $set_name, $setting );
 498  
 499      return $setting;
 500  }
 501  
 502  
 503  /**

 504   * Get a node from settings by path (e.g. "locales[0][questions]")

 505   *

 506   * @param Plugin

 507   * @param string Settings type ("Settings" or "UserSettings")

 508   * @param string The settings path, e.g. 'setting[0]foo[1]' or even 'setting[]'. (Is used as array internally for recursion.)

 509   * @return array Array(

 510   *          - 'set_name': setting name (string); key of the first level

 511   *          - 'set_node': selected setting node, may be NULL (by reference)

 512   *          - 'set_meta': meta info (from GetDefault[User]Settings()) for selected node (array)

 513   *          - 'set_parent': parent node (by reference)

 514   *          - 'set_key': key in parent node (by reference)

 515   *          - 'setting': whole settings (array)

 516   */
 517  function get_plugin_settings_node_by_path( & $Plugin, $set_type, $path, $create = false )
 518  {
 519      // Init:

 520      if( ! preg_match( '~^\w+(\[\w+\])+$~', $path ) )
 521      {
 522          debug_die( 'Invalid path param!' );
 523      }
 524  
 525      $path = preg_split( '~(\[|\]\[?)~', $path, -1 ); // split by "[" and "][", so we get an array with setting name and index alternating

 526      $foo = array_pop($path); // remove last one

 527      if( ! empty($foo) )
 528          debug_die('Assertion failed!');
 529  
 530      $set_name = $path[0];
 531  
 532      $setting = $Plugin->$set_type->get($set_name);  // $Plugin->Settings or $Plugin->UserSettings

 533  
 534      // meta info for this setting:

 535      $method = 'GetDefault'.$set_type; // GetDefaultSettings or GetDefaultUserSettings

 536      $defaults = $Plugin->$method( $tmp_params = array('for_editing'=>true) );
 537      if( ! isset($defaults[ $set_name ]) )
 538      {
 539          //debug_die( 'Invalid setting ('.$set_name.') - no meta data!' );

 540          return false;
 541      }
 542  
 543      $found_node = & $setting;
 544      $defaults_node = & $defaults;
 545      $set_meta = $defaults[$set_name];
 546      $set_parent = NULL;
 547      $set_key = NULL;
 548  
 549      $count = 0;
 550      while( count($path) )
 551      {
 552          $count++;
 553  
 554          $loop_name = array_shift($path);
 555  
 556          if( $count > 1 )
 557          {
 558              $set_parent = & $found_node[$loop_name];
 559              $set_key = NULL;
 560              $defaults_node = & $defaults_node['entries'][$loop_name];
 561              $found_node = & $found_node[$loop_name];
 562          }
 563          else
 564          {
 565              $defaults_node = & $defaults_node[$loop_name];
 566              $set_parent = & $setting;
 567          }
 568  
 569          if( count($path) )
 570          { // has an index => array
 571              $loop_index = array_shift($path);
 572  
 573              #$set_parent = & $set_parent[$loop_name];

 574              $set_key = $loop_index;
 575  
 576              if( $set_key === '' )
 577              { // []-syntax: append entry
 578                  if( $create && ! count($path) )
 579                  { // only create, if at the end
 580                      $found_node[] = array();
 581                  }
 582                  $found_node = & $found_node[ array_pop(array_keys($found_node)) ];
 583              }
 584              else
 585              { // specific key:
 586                  if( ! isset($found_node[$loop_index]) )
 587                  {
 588                      $found_node[$loop_index] = array();
 589                  }
 590                  $found_node = & $found_node[$loop_index];
 591              }
 592          }
 593      }
 594  
 595      #echo '<h1>RETURN</h1>'; pre_dump( $set_parent, $set_key );

 596      return array(
 597          'set_name' => $set_name,
 598          'set_node' => & $found_node,
 599          'set_meta' => $defaults_node,
 600          'set_parent' => & $set_parent,
 601          'set_key' => & $set_key,
 602          'setting' => & $setting );
 603  }
 604  
 605  
 606  /**

 607   * Set Plugin settings from params.

 608   *

 609   * fp> WARNING: also used outside of plugins. Work in progress.

 610   *

 611   * This handled plugin specific params when saving a user profile (PluginUserSettings) or plugin settings (PluginSettings).

 612   *

 613   * @param string Settings path, e.g. 'locales[0]' or 'setting'

 614   * @param array Meta data for this setting.

 615   * @param Plugin|Widget

 616   * @param string Type of Settings (either 'Settings' or 'UserSettings').

 617   * @param mixed Target (User object for 'UserSettings')

 618   */
 619  function autoform_set_param_from_request( $parname, $parmeta, & $Obj, $set_type, $set_target = NULL )
 620  {
 621      if( isset($parmeta['layout']) )
 622      { // a layout "setting"
 623          return;
 624      }
 625  
 626      if( ! empty($parmeta['disabled']) || ! empty($parmeta['no_edit']) )
 627      { // the setting is disabled
 628          return;
 629      }
 630  
 631      $l_param_type = 'string';
 632      $l_param_default = '';
 633      if( isset($parmeta['type']) )
 634      {
 635          if( substr($parmeta['type'], 0, 6) == 'select' && ! empty($parmeta['multiple']) )
 636          { // a "multiple" select:
 637              $l_param_type = 'array';
 638          }
 639          switch( $parmeta['type'] )
 640          {
 641              case 'array':
 642                  // this settings has a type

 643                  $l_param_type = $parmeta['type'];
 644                  break;
 645  
 646              case 'checkbox':
 647                  $l_param_type = 'integer';
 648                  $l_param_default = 0;
 649                  break;
 650  
 651              case 'html_input':
 652              case 'html_textarea':
 653                  $l_param_type = 'html';
 654                  break;
 655  
 656              default:
 657          }
 658      }
 659  
 660      // Get the value:

 661      $l_value = param( 'edit_plugin_'.$Obj->ID.'_set_'.$parname, $l_param_type, $l_param_default );
 662      // pre_dump( $parname, $l_value );

 663  
 664      if( isset($parmeta['type']) && $parmeta['type'] == 'array' )
 665      { // make keys (__key__) in arrays unique and remove them
 666          handle_array_keys_in_plugin_settings($l_value);
 667      }
 668  
 669      if( ! autoform_validate_param_value('edit_plugin_'.$Obj->ID.'_set_'.$parname, $l_value, $parmeta) )
 670      {
 671          return;
 672      }
 673  
 674      // Validate form values:

 675      switch( $set_type )
 676      {
 677          case 'Widget':
 678              $error_value = NULL;
 679              $Obj->set( $parname, $l_value );
 680              break;
 681  
 682          case 'UserSettings':
 683              // Plugin User settings:

 684              $error_value = $Obj->PluginUserSettingsValidateSet( $dummy = array(
 685                  'name' => $parname,
 686                  'value' => & $l_value,
 687                  'meta' => $parmeta,
 688                  'User' => $set_target,
 689                  'action' => 'set' ) );
 690              // Update the param value, because a plugin might have changed it (through reference):

 691              $GLOBALS['edit_plugin_'.$Obj->ID.'_set_'.$parname] = $l_value;
 692  
 693              if( empty( $error_value ) )
 694              {
 695                  $Obj->UserSettings->set( $parname, $l_value, $set_target->ID );
 696              }
 697              break;
 698  
 699          case 'Settings':
 700              // Plugin global settings:

 701              $error_value = $Obj->PluginSettingsValidateSet( $dummy = array(
 702                  'name' => $parname,
 703                  'value' => & $l_value,
 704                  'meta' => $parmeta,
 705                  'action' => 'set' ) );
 706              // Update the param value, because a plugin might have changed it (through reference):

 707              $GLOBALS['edit_plugin_'.$Obj->ID.'_set_'.$parname] = $l_value;
 708  
 709              if( empty( $error_value ) )
 710              {
 711                  $Obj->Settings->set( $parname, $l_value );
 712              }
 713              break;
 714  
 715          default:
 716              debug_die( "unhandled set_type $set_type" );
 717              break;
 718      }
 719  
 720      if( $error_value )
 721      { // A validation error has occured, record error message:
 722          param_error( 'edit_plugin_'.$Obj->ID.'_set_'.$parname, $error_value );
 723      }
 724  }
 725  
 726  
 727  /**

 728   * Validates settings according to their meta info recursively.

 729   *

 730   * @todo Init "checkbox" values in "array" type settings (they do not get send) (dh)

 731   * @param string Param name

 732   * @param array Meta info

 733   * @return boolean

 734   */
 735  function autoform_validate_param_value( $param_name, $value, $meta )
 736  {
 737      global $Messages;
 738  
 739      if( is_array($value) && isset($meta['entries']) )
 740      {
 741          $r = true;
 742          if(isset($meta['key']))
 743          { // validate keys:
 744              foreach( array_keys($value) as $k )
 745              {
 746                  if( ! autoform_validate_param_value($param_name.'['.$k.'][__key__]', $k, $meta['key']) )
 747                  {
 748                      $r = false;
 749                  }
 750              }
 751          }
 752  
 753          // Check max_count/min_count

 754          // dh> TODO: find a way to link it to the form's fieldset (and add an "error" class to it)

 755          if( isset($meta['max_count']) && count($value) > $meta['max_count'] )
 756          {
 757              $r = false;
 758              $label = isset($meta['label']) ? $meta['label'] : $param_name;
 759              $Messages->add( sprintf( T_('Too many entries in the "%s" set. It must have %d at most.'), $label, $meta['max_count'] ), 'error' );
 760          }
 761          elseif( isset($meta['min_count']) && count($value) < $meta['min_count'] )
 762          {
 763              $r = false;
 764              $label = isset($meta['label']) ? $meta['label'] : $param_name;
 765              $Messages->add( sprintf( T_('Too few entries in the "%s" set. It must have %d at least.'), $label, $meta['min_count'] ), 'error' );
 766          }
 767  
 768          foreach( $meta['entries'] as $mk => $mv )
 769          {
 770              foreach( $value as $vk => $vv )
 771              {
 772                  if( ! isset($vv[$mk]) )
 773                      continue;
 774  
 775                  if( ! autoform_validate_param_value($param_name.'['.$vk.']['.$mk.']', $vv[$mk], $mv) )
 776                  {
 777                      $r = false;
 778                  }
 779              }
 780          }
 781          return $r;
 782      }
 783  
 784  
 785      if( isset($meta['type']) )
 786      {
 787          switch( $meta['type'] )
 788          {
 789              case 'integer':
 790                  if( ! preg_match( '~^[-+]?\d+$~', $value ) )
 791                  {
 792                      param_error( $param_name, sprintf( T_('The value for &laquo;%s&raquo; must be numeric.'), $meta['label'] ), T_('The value must be numeric.') );
 793                      return false;
 794                  }
 795                  break;
 796  
 797              case 'float':
 798                  if( ! preg_match( '~^[-+]?\d+(\.\d+)?$~', $value ) )
 799                  {
 800                      param_error( $param_name, sprintf( T_('The value for &laquo;%s&raquo; must be numeric.'), $meta['label'] ), T_('The value must be numeric.') );
 801                      return false;
 802                  }
 803                  break;
 804  
 805              case 'select':
 806                  $check_options = $value;
 807                  if( ! is_array($check_options) )
 808                  { // no "multiple" select:
 809                      $check_options = array($check_options);
 810                  }
 811  
 812                  foreach($check_options as $v)
 813                  {
 814                      if( ! in_array( $v, array_keys($meta['options']) ) )
 815                      {
 816                          param_error( $param_name, sprintf( T_('Invalid option &laquo;%s&raquo;.'), $v ) );
 817                          return false;
 818                      }
 819                  }
 820                  break;
 821  
 822              case 'select_blog':
 823              case 'select_group':
 824              case 'select_user':
 825                  if( is_array($value) && empty($value) // empty "multiple" select
 826                      || ( ! is_array($value) && ! strlen($value) ) )
 827                  {
 828                      if( empty($meta['allow_none']) )
 829                      { // empty is not ok
 830                          param_error( $param_name, sprintf( T_('Invalid option &laquo;%s&raquo;.'), $value ) );
 831                          return false;
 832                      }
 833                  }
 834                  else
 835                  { // Try retrieving the value from the corresponding Cache:
 836                      switch( $meta['type'] )
 837                      {
 838                          case 'select_blog':
 839                              $Cache = & get_Cache( 'BlogCache' );
 840                              break;
 841  
 842                          case 'select_group':
 843                              $Cache = & get_Cache( 'GroupCache' );
 844                              break;
 845  
 846                          case 'select_user':
 847                              $Cache = & get_Cache( 'UserCache' );
 848                              break;
 849                      }
 850  
 851                      $check_options = $value;
 852                      if( ! is_array($check_options) )
 853                      { // no "multiple" select:
 854                          $check_options = array($check_options);
 855                      }
 856  
 857                      foreach($check_options as $v)
 858                      {
 859                          if( empty($v) && ! empty($meta['allow_none']) )
 860                          { // empty is ok:
 861                              continue;
 862                          }
 863                          if( ! $Cache->get_by_ID($v, false, false) )
 864                          {
 865                              param_error( $param_name, sprintf( T_('Invalid option &laquo;%s&raquo;.'), $v ) );
 866                              return false;
 867                          }
 868                      }
 869                  }
 870                  break;
 871          }
 872      }
 873  
 874      // Check maxlength:

 875      if( isset($meta['maxlength']) )
 876      {
 877          if( strlen($value) > $meta['maxlength'] )
 878          {
 879              param_error( $param_name, sprintf( T_('The value is too long.'), $value ) );
 880          }
 881      }
 882  
 883      // Check valid pattern:

 884      if( isset($meta['valid_pattern']) )
 885      {
 886          $param_pattern = is_array($meta['valid_pattern']) ? $meta['valid_pattern']['pattern'] : $meta['valid_pattern'];
 887          if( ! preg_match( $param_pattern, $value ) )
 888          {
 889              $param_error = is_array($meta['valid_pattern']) ? $meta['valid_pattern']['error'] : sprintf(T_('The value is invalid. It must match the regular expression &laquo;%s&raquo;.'), $param_pattern);
 890              param_error( $param_name, $param_error );
 891              return false;
 892          }
 893      }
 894  
 895      // Check valid range:

 896      if( isset($meta['valid_range']) )
 897      {
 898          // Transform numeric indexes into associative keys:

 899          if( ! isset($meta['valid_range']['min'], $meta['valid_range']['max'])
 900              && isset($meta['valid_range'][0], $meta['valid_range'][1]) )
 901          {
 902              $meta['valid_range']['min'] = $meta['valid_range'][0];
 903              $meta['valid_range']['max'] = $meta['valid_range'][1];
 904          }
 905          if( isset($meta['valid_range'][2]) && ! isset($meta['valid_range']['error']) )
 906          {
 907              $meta['valid_range']['error'] = $meta['valid_range'][2];
 908          }
 909  
 910          if( (isset($meta['valid_range']['min']) && $value < $meta['valid_range']['min'])
 911                  || (isset($meta['valid_range']['max']) && $value > $meta['valid_range']['max']) )
 912          {
 913              if( isset($meta['valid_range']['error']) )
 914              {
 915                  $param_error = $meta['valid_range']['error'];
 916              }
 917              else
 918              {
 919                  if( isset($meta['valid_range']['min']) && isset($meta['valid_range']['max']) )
 920                  {
 921                      $param_error = sprintf(T_('The value is invalid. It must be in the range from %s to %s.'), $meta['valid_range']['min'], $meta['valid_range']['max']);
 922                  }
 923                  elseif( isset($meta['valid_range']['max']) )
 924                  {
 925                      $param_error = sprintf(T_('The value is invalid. It must be smaller than %s.'), $meta['valid_range']['max']);
 926                  }
 927                  else
 928                  {
 929                      $param_error = sprintf(T_('The value is invalid. It must be greater than %s.'), $meta['valid_range']['min']);
 930                  }
 931              }
 932  
 933              param_error( $param_name, $param_error );
 934              return false;
 935          }
 936      }
 937  
 938      return true;
 939  }
 940  
 941  
 942  /**

 943   * This handles the special "__key__" index in all array type values

 944   * in the given array. It makes sure, that "__key__" is unique and

 945   * replaces the original key of the value with it.

 946   * @param array (by reference)

 947   */
 948  function handle_array_keys_in_plugin_settings( & $a )
 949  {
 950      if( ! is_array($a) )
 951      {
 952          return;
 953      }
 954  
 955      $new_arr = array(); // use a new array to maintain order, also for "numeric" keys

 956  
 957      foreach( array_keys($a) as $k )
 958      {
 959          $v = & $a[$k];
 960  
 961          if( is_array($v) && isset($v['__key__']) )
 962          {
 963              if( $k != $v['__key__'] )
 964              {
 965                  $k = $v['__key__'];
 966                  if( ! strlen($k) || isset($a[ $k ]) )
 967                  { // key already exists (or is empty):
 968                      $c = 1;
 969  
 970                      while( isset($a[ $k.'_'.$c ]) )
 971                      {
 972                          $c++;
 973                      }
 974                      $k = $k.'_'.$c;
 975                  }
 976              }
 977              unset($v['__key__']);
 978  
 979              $new_arr[$k] = $v;
 980          }
 981          else
 982          {
 983              $new_arr[$k] = $v;
 984          }
 985  
 986          // Recurse:

 987          foreach( array_keys($v) as $rk )
 988          {
 989              if( is_array($v[$rk]) )
 990              {
 991                  handle_array_keys_in_plugin_settings($v[$rk]);
 992              }
 993          }
 994      }
 995      $a = $new_arr;
 996  }
 997  
 998  
 999  /*

1000   * $Log: _plugin.funcs.php,v $

1001   * Revision 1.2  2007/09/03 23:45:56  blueyed

1002   * Use always the array key as value for "select" settings.

1003   *

1004   * Revision 1.1  2007/06/25 11:00:42  fplanque

1005   * MODULES (refactored MVC)

1006   *

1007   * Revision 1.48  2007/06/19 20:40:26  fplanque

1008   * renamed generic functions to autoform_*

1009   *

1010   * Revision 1.47  2007/06/19 18:47:27  fplanque

1011   * Nuked unnecessary Param (or I'm missing something badly :/)

1012   *

1013   * Revision 1.46  2007/06/19 00:03:26  fplanque

1014   * doc / trying to make sense of automatic settings forms generation.

1015   *

1016   * Revision 1.45  2007/04/26 00:11:08  fplanque

1017   * (c) 2007

1018   *

1019   * Revision 1.44  2007/04/02 20:32:57  blueyed

1020   * Commented out block that caused problems

1021   *

1022   * Revision 1.43  2007/01/23 08:57:36  fplanque

1023   * decrap!

1024   *

1025   * Revision 1.42  2006/12/22 22:36:07  blueyed

1026   * Fixed selecting selected "None" option in "multiple" selects

1027   *

1028   * Revision 1.41  2006/12/22 22:29:35  blueyed

1029   * Support for "multiple" attribute in SELECT elements, especially for GetDefault(User)Settings plugin callback

1030   *

1031   * Revision 1.40  2006/12/10 12:36:58  blueyed

1032   * passthrough "rows" and "maxlength" attributes to input elements

1033   *

1034   * Revision 1.39  2006/12/09 01:55:36  fplanque

1035   * feel free to fill in some missing notes

1036   * hint: "login" does not need a note! :P

1037   *

1038   * Revision 1.38  2006/12/05 02:34:05  blueyed

1039   * Fix for "Minor refactoring".. :/

1040   *

1041   * Revision 1.36  2006/12/05 01:59:12  blueyed

1042   * Added validation for all types of (User)Settings

1043   *

1044   * Revision 1.35  2006/12/04 22:26:06  blueyed

1045   * Fixed calling GetDefault(User)Settings with $params in set_Settings_for_Plugin_from_Request()

1046   *

1047   * Revision 1.34  2006/12/04 21:39:49  blueyed

1048   * Minor refactoring

1049   *

1050   * Revision 1.33  2006/12/01 16:47:26  blueyed

1051   * - Use EVO_NEXT_VERSION, which should get replaced with the next version 1.10 or 2.0 or whatever

1052   * - "action" param for PluginSettingsValidateSet

1053   * - Removed deprecated Plugin::set_param()

1054   *

1055   * Revision 1.32  2006/11/24 18:27:27  blueyed

1056   * Fixed link to b2evo CVS browsing interface in file docblocks

1057   *

1058   * Revision 1.31  2006/11/16 23:43:40  blueyed

1059   * - "key" entry for array-type Plugin(User)Settings can define an input field for the key of the settings entry

1060   * - cleanup

1061   *

1062   * Revision 1.30  2006/11/10 17:14:20  blueyed

1063   * Added "select_blog" type for Plugin (User)Settings

1064   *

1065   * Revision 1.29  2006/11/10 16:37:57  blueyed

1066   * Fixed ID for AJAX DIV

1067   *

1068   * Revision 1.28  2006/11/09 23:40:57  blueyed

1069   * Fixed Plugin UserSettings array type editing; Added jquery and use it for AJAHifying Plugin (User)Settings editing of array types

1070   *

1071   * Revision 1.27  2006/11/02 15:56:53  blueyed

1072   * Add note about having to save the settings, before adding a new set.

1073   *

1074   * Revision 1.26  2006/10/08 22:13:05  blueyed

1075   * Added "float" type to Plugin Setting types.

1076   */
1077  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics