[ Index ]
 

Code source de Horde 3.1.3

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

title

Body

[fermer]

/lib/Horde/ -> Config.php (source)

   1  <?php
   2  
   3  require_once 'Horde/Form.php';
   4  
   5  /**
   6   * The Config:: package provides a framework for managing the
   7   * configuration of Horde applications, writing conf.php files from
   8   * conf.xml source files, generating user interfaces, etc.
   9   *
  10   * The Horde_Config_Node DOM classes and subclasses
  11   * (Horde_Config_Document, Horde_Config_Element) are simply massaged
  12   * from code written by to emulate PHP4's DOMXML extension with PHP5's
  13   * DOM support. Only changes are naming and syntactic sugar/Horde
  14   * coding standards; all credit goes to Alexandre and the code is used
  15   * with his permission. His original code can be found at:
  16   *
  17   *   http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/
  18   *
  19   * $Horde: framework/Horde/Horde/Config.php,v 1.80.2.26 2006/06/01 23:44:32 jan Exp $
  20   *
  21   * Copyright 2002-2006 Chuck Hagenbuch <chuck@horde.org>
  22   *
  23   * See the enclosed file COPYING for license information (LGPL). If you
  24   * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  25   *
  26   * @author  Chuck Hagenbuch <chuck@horde.org>
  27   * @since   Horde 3.0
  28   * @package Horde_Framework
  29   */
  30  class Horde_Config {
  31  
  32      /**
  33       * The name of the configured application.
  34       *
  35       * @var string
  36       */
  37      var $_app;
  38  
  39      /**
  40       * The XML tree of the configuration file traversed to an
  41       * associative array.
  42       *
  43       * @var array
  44       */
  45      var $_xmlConfigTree = null;
  46  
  47      /**
  48       * The content of the generated configuration file.
  49       *
  50       * @var string
  51       */
  52      var $_phpConfig;
  53  
  54      /**
  55       * The content of the old configuration file.
  56       *
  57       * @var string
  58       */
  59      var $_oldConfig;
  60  
  61      /**
  62       * The manual configuration in front of the generated configuration.
  63       *
  64       * @var string
  65       */
  66      var $_preConfig;
  67  
  68      /**
  69       * The manual configuration after the generated configuration.
  70       *
  71       * @var string
  72       */
  73      var $_postConfig;
  74  
  75      /**
  76       * The current $conf array of the configured application.
  77       *
  78       * @var array
  79       */
  80      var $_currentConfig = array();
  81  
  82      /**
  83       * The CVS version tag of the conf.xml file which will be copied into the
  84       * conf.php file.
  85       *
  86       * @var string
  87       */
  88      var $_versionTag = '';
  89  
  90      /**
  91       * The line marking the begin of the generated configuration.
  92       *
  93       * @var string
  94       */
  95      var $_configBegin = "/* CONFIG START. DO NOT CHANGE ANYTHING IN OR AFTER THIS LINE. */\n";
  96  
  97      /**
  98       * The line marking the end of the generated configuration.
  99       *
 100       * @var string
 101       */
 102      var $_configEnd = "/* CONFIG END. DO NOT CHANGE ANYTHING IN OR BEFORE THIS LINE. */\n";
 103  
 104      /**
 105       * Constructor.
 106       *
 107       * @param string $app  The name of the application to be configured.
 108       */
 109      function Horde_Config($app)
 110      {
 111          $this->_app = $app;
 112      }
 113  
 114      /**
 115       * Reads the application's conf.xml file and builds an associative array
 116       * from its XML tree.
 117       *
 118       * @param array $custom_conf   Any settings that shall be included in the
 119       *                             generated configuration.
 120       *
 121       * @return array  An associative array representing the configuration tree.
 122       */
 123      function readXMLConfig($custom_conf = null)
 124      {
 125          if (is_null($this->_xmlConfigTree) || $custom_conf) {
 126              require_once 'Horde/Text.php';
 127  
 128              global $registry;
 129              $path = $registry->get('fileroot', $this->_app) . '/config';
 130  
 131              if ($custom_conf) {
 132                  $this->_currentConfig = $custom_conf;
 133              } else {
 134                  /* Fetch the current conf.php contents. */
 135                  @eval($this->getPHPConfig());
 136                  if (isset($conf)) {
 137                      $this->_currentConfig = $conf;
 138                  }
 139              }
 140  
 141              /* Load the DOM object. */
 142              $doc = Horde_Config_Document::factory($path . '/conf.xml');
 143  
 144              /* Check if there is a CVS version tag and store it. */
 145              $node = $doc->first_child();
 146              while (!empty($node)) {
 147                  if ($node->type == XML_COMMENT_NODE) {
 148                      if (preg_match('/\$.*?conf\.xml,v .*? .*\$/', $node->node_value(), $match)) {
 149                          $this->_versionTag = $match[0] . "\n";
 150                          break;
 151                      }
 152                  }
 153                  $node = $node->next_sibling();
 154              }
 155  
 156              /* Parse the config file. */
 157              $this->_xmlConfigTree = array();
 158              $root = $doc->root();
 159              if ($root->has_child_nodes()) {
 160                  $this->_parseLevel($this->_xmlConfigTree, $root->child_nodes(), '');
 161              }
 162          }
 163  
 164          return $this->_xmlConfigTree;
 165      }
 166  
 167      /**
 168       * Returns the file content of the current configuration file.
 169       *
 170       * @return string  The unparsed configuration file content.
 171       */
 172      function getPHPConfig()
 173      {
 174          if (is_null($this->_oldConfig)) {
 175              global $registry;
 176              $path = $registry->get('fileroot', $this->_app) . '/config';
 177              if (file_exists($path . '/conf.php')) {
 178                  $this->_oldConfig = file_get_contents($path . '/conf.php');
 179                  if (!empty($this->_oldConfig)) {
 180                      $this->_oldConfig = preg_replace('/<\?php\n?/', '', $this->_oldConfig);
 181                      $pos = strpos($this->_oldConfig, $this->_configBegin);
 182                      if ($pos !== false) {
 183                          $this->_preConfig = substr($this->_oldConfig, 0, $pos);
 184                          $this->_oldConfig = substr($this->_oldConfig, $pos);
 185                      }
 186                      $pos = strpos($this->_oldConfig, $this->_configEnd);
 187                      if ($pos !== false) {
 188                          $this->_postConfig = substr($this->_oldConfig, $pos + strlen($this->_configEnd));
 189                          $this->_oldConfig = substr($this->_oldConfig, 0, $pos);
 190                      }
 191                  }
 192              } else {
 193                  $this->_oldConfig = '';
 194              }
 195          }
 196          return $this->_oldConfig;
 197      }
 198  
 199      /**
 200       * Generates the content of the application's configuration file.
 201       *
 202       * @param Variables $formvars  The processed configuration form data.
 203       * @param array $custom_conf   Any settings that shall be included in the
 204       *                             generated configuration.
 205       *
 206       * @return string  The content of the generated configuration file.
 207       */
 208      function generatePHPConfig($formvars, $custom_conf = null)
 209      {
 210          $this->readXMLConfig($custom_conf);
 211          $this->getPHPConfig();
 212  
 213          $this->_phpConfig = "<?php\n";
 214          $this->_phpConfig .= $this->_preConfig;
 215          $this->_phpConfig .= $this->_configBegin;
 216          if (!empty($this->_versionTag)) {
 217              $this->_phpConfig .= '// ' . $this->_versionTag;
 218          }
 219          $this->_generatePHPConfig($this->_xmlConfigTree, '', $formvars);
 220          $this->_phpConfig .= $this->_configEnd;
 221          $this->_phpConfig .= $this->_postConfig;
 222  
 223          return $this->_phpConfig;
 224      }
 225  
 226      /**
 227       * Generates the configuration file items for a part of the configuration
 228       * tree.
 229       *
 230       * @access private
 231       *
 232       * @param array $section  An associative array containing the part of the
 233       *                        traversed XML configuration tree that should be
 234       *                        processed.
 235       * @param string $prefix  A configuration prefix determining the current
 236       *                        position inside the configuration file. This
 237       *                        prefix will be translated to keys of the $conf
 238       *                        array in the generated configuration file.
 239       * @param Variables $formvars  The processed configuration form data.
 240       */
 241      function _generatePHPConfig($section, $prefix, $formvars)
 242      {
 243          if (!is_array($section)) {
 244              return;
 245          }
 246  
 247          foreach ($section as $name => $configitem) {
 248              $prefixedname = empty($prefix) ? $name : $prefix . '|' . $name;
 249              $configname = str_replace('|', '__', $prefixedname);
 250              $quote = !isset($configitem['quote']) || $configitem['quote'] !== false;
 251              if ($configitem == 'placeholder') {
 252                  $this->_phpConfig .= '$conf[\'' . str_replace('|', '\'][\'', $prefix) . "'] = array();\n";
 253              } elseif (isset($configitem['switch'])) {
 254                  $val = $formvars->getExists($configname, $wasset);
 255                  if (!$wasset) {
 256                      $val = isset($configitem['default']) ? $configitem['default'] : null;
 257                  }
 258                  if (isset($configitem['switch'][$val])) {
 259                      $value = $val;
 260                      if ($quote && $value != 'true' && $value != 'false') {
 261                          $value = "'" . $value . "'";
 262                      }
 263                      $this->_generatePHPConfig($configitem['switch'][$val]['fields'], $prefix, $formvars);
 264                  }
 265              } elseif (isset($configitem['_type'])) {
 266                  $val = $formvars->getExists($configname, $wasset);
 267                  if (!$wasset) {
 268                      $val = isset($configitem['default']) ? $configitem['default'] : null;
 269                  }
 270  
 271                  $type = $configitem['_type'];
 272                  switch ($type) {
 273                  case 'multienum':
 274                      if (is_array($val)) {
 275                          $encvals = array();
 276                          foreach ($val as $v) {
 277                              $encvals[] = $this->_quote($v);
 278                          }
 279                          $arrayval = "'" . implode('\', \'', $encvals) . "'";
 280                          if ($arrayval == "''") {
 281                              $arrayval = '';
 282                          }
 283                      } else {
 284                          $arrayval = '';
 285                      }
 286                      $value = 'array(' . $arrayval . ')';
 287                      break;
 288  
 289                  case 'boolean':
 290                      if (is_bool($val)) {
 291                          $value = $val ? 'true' : 'false';
 292                      } else {
 293                          $value = ($val == 'on') ? 'true' : 'false';
 294                      }
 295                      break;
 296  
 297                  case 'stringlist':
 298                      $values = explode(',', $val);
 299                      if (!is_array($values)) {
 300                          $value = "array('" . $this->_quote(trim($values)) . "')";
 301                      } else {
 302                          $encvals = array();
 303                          foreach ($values as $v) {
 304                              $encvals[] = $this->_quote(trim($v));
 305                          }
 306                          $arrayval = "'" . implode('\', \'', $encvals) . "'";
 307                          if ($arrayval == "''") {
 308                              $arrayval = '';
 309                          }
 310                          $value = 'array(' . $arrayval . ')';
 311                      }
 312                      break;
 313  
 314                  case 'int':
 315                      if ($val !== '') {
 316                          $value = (int)$val;
 317                      }
 318                      break;
 319  
 320                  case 'octal':
 321                      $value = sprintf('0%o', octdec($val));
 322                      break;
 323  
 324                  case 'header':
 325                  case 'description':
 326                      break;
 327  
 328                  default:
 329                      if ($val != '') {
 330                          $value = $val;
 331                          if ($quote && $value != 'true' && $value != 'false') {
 332                              $value = "'" . $this->_quote($value) . "'";
 333                          }
 334                      }
 335                      break;
 336                  }
 337              } else {
 338                  $this->_generatePHPConfig($configitem, $prefixedname, $formvars);
 339              }
 340  
 341              if (isset($value)) {
 342                  $this->_phpConfig .= '$conf[\'' . str_replace('__', '\'][\'', $configname) . '\'] = ' . $value . ";\n";
 343              }
 344              unset($value);
 345          }
 346      }
 347  
 348      /**
 349       * Parses one level of the configuration XML tree into the associative
 350       * array containing the traversed configuration tree.
 351       *
 352       * @access private
 353       *
 354       * @param array &$conf     The already existing array where the processed
 355       *                         XML tree portion should be appended to.
 356       * @param array $children  An array containing the XML nodes of the level
 357       *                         that should be parsed.
 358       * @param string $ctx      A string representing the current position
 359       *                         (context prefix) inside the configuration XML
 360       *                         file.
 361       */
 362      function _parseLevel(&$conf, $children, $ctx)
 363      {
 364          require_once 'Horde/Text/Filter.php';
 365  
 366          foreach ($children as $node) {
 367              if ($node->type != XML_ELEMENT_NODE) {
 368                  continue;
 369              }
 370              $name = $node->get_attribute('name');
 371              $desc = Text_Filter::filter($node->get_attribute('desc'), 'linkurls', array('callback' => 'Horde::externalUrl'));
 372              $required = !($node->get_attribute('required') == 'false');
 373              $quote = !($node->get_attribute('quote') == 'false');
 374              if (!empty($ctx)) {
 375                  $curctx = $ctx . '|' . $name;
 376              } else {
 377                  $curctx = $name;
 378              }
 379  
 380              switch ($node->tagname) {
 381              case 'configdescription':
 382                  if (empty($name)) {
 383                      $name = md5(microtime());
 384                  }
 385                  $conf[$name] = array('_type' => 'description',
 386                                       'desc' => Text_Filter::filter($this->_default($curctx, $this->_getNodeOnlyText($node)), 'linkurls', array('callback' => 'Horde::externalUrl')));
 387                  break;
 388  
 389              case 'configheader':
 390                  if (empty($name)) {
 391                      $name = md5(microtime());
 392                  }
 393                  $conf[$name] = array('_type' => 'header',
 394                                       'desc' => $this->_default($curctx, $this->_getNodeOnlyText($node)));
 395                  break;
 396  
 397              case 'configswitch':
 398                  $values = $this->_getSwitchValues($node, $ctx);
 399                  if ($quote) {
 400                      $default = $this->_default($curctx, $this->_getNodeOnlyText($node));
 401                  } else {
 402                      $default = $this->_defaultRaw($curctx, $this->_getNodeOnlyText($node));
 403                  }
 404                  if ($default === '') {
 405                      $default = key($values);
 406                  }
 407                  if (is_bool($default)) {
 408                      $default = $default ? 'true' : 'false';
 409                  }
 410                  $conf[$name] = array('desc' => $desc,
 411                                       'switch' => $values,
 412                                       'default' => $default);
 413                  break;
 414  
 415              case 'configenum':
 416                  $values = $this->_getEnumValues($node);
 417                  if ($quote) {
 418                      $default = $this->_default($curctx, $this->_getNodeOnlyText($node));
 419                  } else {
 420                      $default = $this->_defaultRaw($curctx, $this->_getNodeOnlyText($node));
 421                  }
 422                  if ($default === '') {
 423                      $default = key($values);
 424                  }
 425                  if (is_bool($default)) {
 426                      $default = $default ? 'true' : 'false';
 427                  }
 428                  $conf[$name] = array('_type' => 'enum',
 429                                       'required' => $required,
 430                                       'quote' => $quote,
 431                                       'values' => $values,
 432                                       'desc' => $desc,
 433                                       'default' => $default);
 434                  break;
 435  
 436              case 'configlist':
 437                  $default = $this->_default($curctx, null);
 438                  if ($default === null) {
 439                      $default = $this->_getNodeOnlyText($node);
 440                  } elseif (is_array($default)) {
 441                      $default = implode(', ', $default);
 442                  }
 443                  $conf[$name] = array('_type' => 'stringlist',
 444                                       'required' => $required,
 445                                       'desc' => $desc,
 446                                       'default' => $default);
 447                  break;
 448  
 449              case 'configmultienum':
 450                  $values = $this->_getEnumValues($node);
 451                  require_once  'Horde/Array.php';
 452                  $conf[$name] = array('_type' => 'multienum',
 453                                       'required' => $required,
 454                                       'values' => $values,
 455                                       'desc' => $desc,
 456                                       'default' => Horde_Array::valuesToKeys($this->_default($curctx, explode(',', $this->_getNodeOnlyText($node)))));
 457                  break;
 458  
 459              case 'configpassword':
 460                  $conf[$name] = array('_type' => 'password',
 461                                       'required' => $required,
 462                                       'desc' => $desc,
 463                                       'default' => $this->_default($curctx, $this->_getNodeOnlyText($node)));
 464                  break;
 465  
 466              case 'configstring':
 467                  $conf[$name] = array('_type' => 'text',
 468                                       'required' => $required,
 469                                       'desc' => $desc,
 470                                       'default' => $this->_default($curctx, $this->_getNodeOnlyText($node)));
 471                  if ($conf[$name]['default'] === false) {
 472                      $conf[$name]['default'] = 'false';
 473                  } elseif ($conf[$name]['default'] === true) {
 474                      $conf[$name]['default'] = 'true';
 475                  }
 476                  break;
 477  
 478              case 'configboolean':
 479                  $default = $this->_getNodeOnlyText($node);
 480                  if (empty($default) || $default === 'false') {
 481                      $default = false;
 482                  } else {
 483                      $default = true;
 484                  }
 485                  $conf[$name] = array('_type' => 'boolean',
 486                                       'required' => $required,
 487                                       'desc' => $desc,
 488                                       'default' => $this->_default($curctx, $default));
 489                  break;
 490  
 491              case 'configinteger':
 492                  $values = $this->_getEnumValues($node);
 493                  $conf[$name] = array('_type' => 'int',
 494                                       'required' => $required,
 495                                       'values' => $values,
 496                                       'desc' => $desc,
 497                                       'default' => $this->_default($curctx, $this->_getNodeOnlyText($node)));
 498                  if ($node->get_attribute('octal') == 'true' &&
 499                      $conf[$name]['default'] != '') {
 500                      $conf[$name]['_type'] = 'octal';
 501                      $conf[$name]['default'] = sprintf('0%o', $this->_default($curctx, octdec($this->_getNodeOnlyText($node))));
 502                  }
 503                  break;
 504  
 505              case 'configphp':
 506                  $conf[$name] = array('_type' => 'php',
 507                                       'required' => $required,
 508                                       'quote' => false,
 509                                       'desc' => $desc,
 510                                       'default' => $this->_defaultRaw($curctx, $this->_getNodeOnlyText($node)));
 511                  break;
 512  
 513              case 'configsql':
 514                  $conf[$node->get_attribute('switchname')] = $this->_configSQL($ctx, $node);
 515                  break;
 516  
 517              case 'configvfs':
 518                  $conf[$node->get_attribute('switchname')] = $this->_configVFS($ctx, $node);
 519                  break;
 520  
 521              case 'configsection':
 522                  $conf[$name] = array();
 523                  $cur = &$conf[$name];
 524                  if ($node->has_child_nodes()) {
 525                      $this->_parseLevel($cur, $node->child_nodes(), $curctx);
 526                  }
 527                  break;
 528  
 529              case 'configtab':
 530                  $key = md5(microtime());
 531                  $conf[$key] = array('tab' => $name,
 532                                      'desc' => $desc);
 533                  if ($node->has_child_nodes()) {
 534                      $this->_parseLevel($conf, $node->child_nodes(), $ctx);
 535                  }
 536                  break;
 537  
 538              case 'configplaceholder':
 539                  $conf[md5(microtime())] = 'placeholder';
 540                  break;
 541  
 542              default:
 543                  $conf[$name] = array();
 544                  $cur = &$conf[$name];
 545                  if ($node->has_child_nodes()) {
 546                      $this->_parseLevel($cur, $node->child_nodes(), $curctx);
 547                  }
 548                  break;
 549              }
 550          }
 551      }
 552  
 553      /**
 554       * Returns the configuration tree for an SQL backend configuration to
 555       * replace a <configsql> tag.
 556       * Subnodes will be parsed and added to both the Horde defaults and the
 557       * Custom configuration parts.
 558       *
 559       * @access private
 560       *
 561       * @param string $ctx         The context of the <configsql> tag.
 562       * @param DomNode $node       The DomNode representation of the <configsql>
 563       *                            tag.
 564       * @param string $switchname  If DomNode is not set, the value of the
 565       *                            tag's switchname attribute.
 566       *
 567       * @return array  An associative array with the SQL configuration tree.
 568       */
 569      function _configSQL($ctx, $node = null, $switchname = 'driverconfig')
 570      {
 571          $persistent = array(
 572              '_type' => 'boolean',
 573              'required' => false,
 574              'desc' => 'Request persistent connections?',
 575              'default' => $this->_default($ctx . '|persistent', false));
 576          $hostspec = array(
 577              '_type' => 'text',
 578              'required' => true,
 579              'desc' => 'Database server/host',
 580              'default' => $this->_default($ctx . '|hostspec', ''));
 581          $username = array(
 582              '_type' => 'text',
 583              'required' => true,
 584              'desc' => 'Username to connect to the database as',
 585              'default' => $this->_default($ctx . '|username', ''));
 586          $password = array(
 587              '_type' => 'text',
 588              'required' => false,
 589              'desc' => 'Password to connect with',
 590              'default' => $this->_default($ctx . '|password', ''));
 591          $database = array(
 592              '_type' => 'text',
 593              'required' => true,
 594              'desc' => 'Database name to use',
 595              'default' => $this->_default($ctx . '|database', ''));
 596          $socket = array(
 597              '_type' => 'text',
 598              'required' => false,
 599              'desc' => 'Location of UNIX socket',
 600              'default' => $this->_default($ctx . '|socket', ''));
 601          $port = array(
 602              '_type' => 'int',
 603              'required' => false,
 604              'desc' => 'Port the DB is running on, if non-standard',
 605              'default' => $this->_default($ctx . '|port', null));
 606          $protocol = array(
 607              'desc' => 'How should we connect to the database?',
 608              'default' => $this->_default($ctx . '|protocol', 'unix'),
 609              'switch' => array(
 610                  'unix' => array(
 611                      'desc' => 'UNIX Sockets',
 612                      'fields' => array(
 613                          'socket' => $socket)),
 614                  'tcp' => array(
 615                      'desc' => 'TCP/IP',
 616                      'fields' => array(
 617                          'port' => $port))));
 618          $mysql_protocol = $protocol;
 619          $mysql_protocol['switch']['tcp']['fields']['port']['default'] = $this->_default($ctx . '|port', 3306);
 620          $charset = array(
 621              '_type' => 'text',
 622              'required' => true,
 623              'desc' => 'Internally used charset',
 624              'default' => $this->_default($ctx . '|charset', 'iso-8859-1'));
 625  
 626          $oci8_fields = array(
 627              'persistent' => $persistent,
 628              'username' => $username,
 629              'password' => $password);
 630          if (function_exists('oci_connect')) {
 631              $oci8_fields['database'] = array(
 632                  '_type' => 'text',
 633                  'required' => true,
 634                  'desc' => 'Database name or Easy Connect parameter',
 635                  'default' => $this->_default($ctx . '|database', 'horde'));
 636          } else {
 637              $oci8_fields['hostspec'] = array(
 638                  '_type' => 'text',
 639                  'required' => true,
 640                  'desc' => 'Database name or Easy Connect parameter',
 641                  'default' => $this->_default($ctx . '|hostspec', 'horde'));
 642          }
 643          $oci8_fields['charset'] = $charset;
 644  
 645          $custom_fields = array(
 646              'required' => true,
 647              'desc' => 'What database backend should we use?',
 648              'default' => $this->_default($ctx . '|phptype', 'false'),
 649              'switch' => array(
 650                  'false' => array(
 651                      'desc' => '[None]',
 652                      'fields' => array()),
 653                  'dbase' => array(
 654                      'desc' => 'dBase',
 655                      'fields' => array(
 656                          'database' => array(
 657                              '_type' => 'text',
 658                              'required' => true,
 659                              'desc' => 'Absolute path to the database file',
 660                              'default' => $this->_default($ctx . '|database', '')),
 661                          'mode' => array(
 662                              '_type' => 'enum',
 663                              'desc' => 'The mode to open the file with',
 664                              'values' => array(
 665                                  0 => 'Read Only',
 666                                  2 => 'Read Write'),
 667                              'default' => $this->_default($ctx . '|mode', 2)),
 668  
 669                          'charset' => $charset)),
 670                  'ibase' => array(
 671                      'desc' => 'Firebird/InterBase',
 672                      'fields' => array(
 673                          'dbsyntax' => array(
 674                              '_type' => 'enum',
 675                              'desc' => 'The database syntax variant to use',
 676                              'required' => false,
 677                              'values' => array(
 678                                  'ibase' => 'InterBase',
 679                                  'firebird' => 'Firebird'),
 680                              'default' => $this->_default($ctx . '|dbsyntax', 'firebird')),
 681                          'persistent' => $persistent,
 682                          'hostspec' => $hostspec,
 683                          'username' => $username,
 684                          'password' => $password,
 685                          'database' => $database,
 686                          'buffers' => array(
 687                              '_type' => 'int',
 688                              'desc' => 'The number of database buffers to allocate',
 689                              'required' => false,
 690                              'default' => $this->_default($ctx . '|buffers', null)),
 691                          'dialect' => array(
 692                              '_type' => 'int',
 693                              'desc' => 'The default SQL dialect for any statement executed within a connection.',
 694                              'required' => false,
 695                              'default' => $this->_default($ctx . '|dialect', null)),
 696                          'role' => array(
 697                              '_type' => 'text',
 698                              'desc' => 'Role',
 699                              'required' => false,
 700                              'default' => $this->_default($ctx . '|role', null)),
 701                          'charset' => $charset)),
 702                  'fbsql' => array(
 703                      'desc' => 'Frontbase',
 704                      'fields' => array(
 705                          'persistent' => $persistent,
 706                          'hostspec' => $hostspec,
 707                          'username' => $username,
 708                          'password' => $password,
 709                          'database' => $database,
 710                          'charset' => $charset)),
 711                  'ifx' => array(
 712                      'desc' => 'Informix',
 713                      'fields' => array(
 714                          'persistent' => $persistent,
 715                          'username' => $username,
 716                          'password' => $password,
 717                          'database' => $database,
 718                          'charset' => $charset)),
 719                  'msql' => array(
 720                      'desc' => 'mSQL',
 721                      'fields' => array(
 722                          'persistent' => $persistent,
 723                          'hostspec' => $hostspec,
 724                          'username' => $username,
 725                          'password' => $password,
 726                          'port' => $port,
 727                          'database' => $database,
 728                          'charset' => $charset)),
 729                  'mssql' => array(
 730                      'desc' => 'MS SQL Server',
 731                      'fields' => array(
 732                          'persistent' => $persistent,
 733                          'hostspec' => $hostspec,
 734                          'username' => $username,
 735                          'password' => $password,
 736                          'port' => $port,
 737                          'database' => $database,
 738                          'charset' => $charset)),
 739                  'mysql' => array(
 740                      'desc' => 'MySQL',
 741                      'fields' => array(
 742                          'persistent' => $persistent,
 743                          'hostspec' => $hostspec,
 744                          'username' => $username,
 745                          'password' => $password,
 746                          'protocol' => $mysql_protocol,
 747                          'database' => $database,
 748                          'charset' => $charset)),
 749                  'mysqli' => array(
 750                      'desc' => 'MySQL (mysqli)',
 751                      'fields' => array(
 752                          'persistent' => $persistent,
 753                          'hostspec' => $hostspec,
 754                          'username' => $username,
 755                          'password' => $password,
 756                          'port' => $port,
 757                          'socket' => $socket,
 758                          'database' => $database,
 759                          'charset' => $charset)),
 760                  'oci8' => array(
 761                      'desc' => 'Oracle',
 762                      'fields' => $oci8_fields),
 763                  'odbc' => array(
 764                      'desc' => 'ODBC',
 765                      'fields' => array(
 766                          'persistent' => $persistent,
 767                          'username' => $username,
 768                          'password' => $password,
 769                          'hostspec' => array(
 770                              '_type' => 'text',
 771                              'desc' => 'DSN',
 772                              'default' => $this->_default($ctx . '|hostspec', '')),
 773                          'dbsyntax' => array(
 774                              '_type' => 'enum',
 775                              'desc' => 'The database syntax variant to use',
 776                              'required' => false,
 777                              'values' => array(
 778                                  'sql92' => 'SQL92',
 779                                  'access' => 'Access',
 780                                  'db2' => 'DB2',
 781                                  'solid' => 'Solid',
 782                                  'navision' => 'Navision',
 783                                  'mssql' => 'MS SQL Server',
 784                                  'sybase' => 'Sybase',
 785                                  'mysql' => 'MySQL',
 786                                  'mysqli' => 'MySQL (mysqli)',
 787                                  ),
 788                              'default' => $this->_default($ctx . '|dbsyntax', 'sql92')),
 789                          'cursor' => array(
 790                              '_type' => 'enum',
 791                              'desc' => 'Cursor type',
 792                              'quote' => false,
 793                              'required' => false,
 794                              'values' => array(
 795                                  'null' => 'None',
 796                                  'SQL_CUR_DEFAULT' => 'Default',
 797                                  'SQL_CUR_USE_DRIVER' => 'Use Driver',
 798                                  'SQL_CUR_USE_ODBC' => 'Use ODBC',
 799                                  'SQL_CUR_USE_IF_NEEDED' => 'Use If Needed'),
 800                              'default' => $this->_default($ctx . '|cursor', null)),
 801                          'charset' => $charset)),
 802                  'pgsql' => array(
 803                      'desc' => 'PostgreSQL',
 804                      'fields' => array(
 805                          'persistent' => $persistent,
 806                          'hostspec' => $hostspec,
 807                          'username' => $username,
 808                          'password' => $password,
 809                          'protocol' => $protocol,
 810                          'database' => $database,
 811                          'charset' => $charset)),
 812                  'sqlite' => array(
 813                      'desc' => 'SQLite',
 814                      'fields' => array(
 815                          'database' => array(
 816                              '_type' => 'text',
 817                              'required' => true,
 818                              'desc' => 'Absolute path to the database file',
 819                              'default' => $this->_default($ctx . '|database', '')),
 820                          'mode' => array(
 821                              '_type' => 'text',
 822                              'desc' => 'The mode to open the file with',
 823                              'default' => $this->_default($ctx . '|mode', '0644')),
 824                          'charset' => $charset)),
 825                  'sybase' => array(
 826                      'desc' => 'Sybase',
 827                      'fields' => array(
 828                          'persistent' => $persistent,
 829                          'hostspec' => $hostspec,
 830                          'username' => $username,
 831                          'password' => $password,
 832                          'database' => $database,
 833                          'appname' => array(
 834                              '_type' => 'text',
 835                              'desc' => 'Application Name',
 836                              'required' => false,
 837                              'default' => $this->_default($ctx . '|appname', '')),
 838                          'charset' => $charset))));
 839  
 840          if (isset($node) && $node->get_attribute('baseconfig') == 'true') {
 841              return $custom_fields;
 842          }
 843  
 844          $config = array(
 845              'desc' => 'Driver configuration',
 846              'default' => $this->_default($ctx . '|' . (isset($node) ? $node->get_attribute('switchname') : $switchname), 'horde'),
 847              'switch' => array(
 848                  'horde' => array(
 849                      'desc' => 'Horde defaults',
 850                      'fields' => array()),
 851                  'custom' => array(
 852                      'desc' => 'Custom parameters',
 853                      'fields' => array(
 854                          md5(microtime()) => array(
 855                              '_type' => 'description',
 856                              'desc' => 'Any parameters that the storage driver needs.'),
 857                          'phptype' => $custom_fields))));
 858  
 859          if (isset($node) && $node->has_child_nodes()) {
 860              $cur = array();
 861              $this->_parseLevel($cur, $node->child_nodes(), $ctx);
 862              $config['switch']['horde']['fields'] = array_merge($config['switch']['horde']['fields'], $cur);
 863              $config['switch']['custom']['fields'] = array_merge($config['switch']['custom']['fields'], $cur);
 864          }
 865  
 866          return $config;
 867      }
 868  
 869      /**
 870       * Returns the configuration tree for a VFS backend configuration to
 871       * replace a <configvfs> tag.
 872       * Subnodes will be parsed and added to both the Horde defaults and the
 873       * Custom configuration parts.
 874       *
 875       * @access private
 876       *
 877       * @param string $ctx    The context of the <configvfs> tag.
 878       * @param DomNode $node  The DomNode representation of the <configvfs>
 879       *                       tag.
 880       *
 881       * @return array  An associative array with the VFS configuration tree.
 882       */
 883      function _configVFS($ctx, $node)
 884      {
 885          $sql = $this->_configSQL($ctx . '|params');
 886          $config =
 887              array(
 888                  'desc' => 'What VFS driver should we use?',
 889                  'default' => $this->_default($ctx . '|' . $node->get_attribute('switchname'), 'horde'),
 890                  'switch' => array(
 891                      'none' => array(
 892                          'desc' => 'None',
 893                          'fields' => array()),
 894                      'horde' => array(
 895                          'desc' => 'Horde defaults',
 896                          'fields' => array()),
 897                      'file' => array(
 898                          'desc' => 'Files on the local system',
 899                          'fields' => array(
 900                              'params' => array(
 901                                  'vfsroot' => array(
 902                                      '_type' => 'text',
 903                                      'desc' => 'Where on the real filesystem should Horde use as root of the virtual filesystem?',
 904                                      'default' => $this->_default($ctx . '|params|vfsroot', '/tmp'))))),
 905                      'sql' => array(
 906                          'desc' => 'SQL database',
 907                          'fields' => array(
 908                              'params' => array(
 909                                  'driverconfig' => $sql)))));
 910  
 911          $cases = $this->_getSwitchValues($node, $ctx . '|params');
 912          foreach ($cases as $case => $fields) {
 913              if (isset($config['switch'][$case])) {
 914                  $config['switch'][$case]['fields']['params'] = array_merge($config['switch'][$case]['fields']['params'], $fields['fields']);
 915              }
 916          }
 917  
 918          return $config;
 919      }
 920  
 921      /**
 922       * Returns a certain value from the current configuration array or
 923       * a default value, if not found.
 924       *
 925       * @access private
 926       *
 927       * @param string $ctx     A string representing the key of the
 928       *                        configuration array to return.
 929       * @param mixed $default  The default value to return if the key wasn't
 930       *                        found.
 931       *
 932       * @return mixed  Either the value of the configuration array's requested
 933       *                key or the default value if the key wasn't found.
 934       */
 935      function _default($ctx, $default)
 936      {
 937          $ctx = explode('|', $ctx);
 938          $ptr = $this->_currentConfig;
 939          for ($i = 0; $i < count($ctx); $i++) {
 940              if (!isset($ptr[$ctx[$i]])) {
 941                  return $default;
 942              } else {
 943                  $ptr = $ptr[$ctx[$i]];
 944              }
 945          }
 946          if (is_string($ptr)) {
 947              return String::convertCharset($ptr, 'iso-8859-1');
 948          } else {
 949              return $ptr;
 950          }
 951      }
 952  
 953      /**
 954       * Returns a certain value from the current configuration file or
 955       * a default value, if not found.
 956       * It does NOT return the actual value, but the PHP expression as used
 957       * in the configuration file.
 958       *
 959       * @access private
 960       *
 961       * @param string $ctx     A string representing the key of the
 962       *                        configuration array to return.
 963       * @param mixed $default  The default value to return if the key wasn't
 964       *                        found.
 965       *
 966       * @return mixed  Either the value of the configuration file's requested
 967       *                key or the default value if the key wasn't found.
 968       */
 969      function _defaultRaw($ctx, $default)
 970      {
 971          $ctx = explode('|', $ctx);
 972          $pattern = '/^\$conf\[\'' . implode("'\]\['", $ctx) . '\'\] = (.*);$/m';
 973          if (preg_match($pattern, $this->getPHPConfig(), $matches)) {
 974              return $matches[1];
 975          }
 976          return $default;
 977      }
 978  
 979      /**
 980       * Returns the content of all text node children of the specified node.
 981       *
 982       * @access private
 983       *
 984       * @param DomNode $node  A DomNode object whose text node children to return.
 985       *
 986       * @return string  The concatenated values of all text nodes.
 987       */
 988      function _getNodeOnlyText($node)
 989      {
 990          $text = '';
 991          if (!$node->has_child_nodes()) {
 992              return $node->get_content();
 993          }
 994          foreach ($node->child_nodes() as $tnode) {
 995              if ($tnode->type == XML_TEXT_NODE) {
 996                  $text .= $tnode->content;
 997              }
 998          }
 999  
1000          return trim($text);
1001      }
1002  
1003      /**
1004       * Returns an associative array containing all possible values of the
1005       * specified <configenum> tag.
1006       * The keys contain the actual enum values while the values contain their
1007       * corresponding descriptions.
1008       *
1009       * @access private
1010       *
1011       * @param DomNode $node  The DomNode representation of the <configenum> tag
1012       *                       whose values should be returned.
1013       *
1014       * @return array  An associative array with all possible enum values.
1015       */
1016      function _getEnumValues($node)
1017      {
1018          $values = array();
1019          if (!$node->has_child_nodes()) {
1020              return array();
1021          }
1022          foreach ($node->child_nodes() as $vnode) {
1023              if ($vnode->type == XML_ELEMENT_NODE &&
1024                  $vnode->tagname == 'values') {
1025                  if (!$vnode->has_child_nodes()) {
1026                      return array();
1027                  }
1028                  foreach ($vnode->child_nodes() as $value) {
1029                      if ($value->type == XML_ELEMENT_NODE) {
1030                          if ($value->tagname == 'configspecial') {
1031                              return $this->_handleSpecials($value);
1032                          } elseif ($value->tagname == 'value') {
1033                              $text = $value->get_content();
1034                              $desc = $value->get_attribute('desc');
1035                              if (!empty($desc)) {
1036                                  $values[$text] = $desc;
1037                              } else {
1038                                  $values[$text] = $text;
1039                              }
1040                          }
1041                      }
1042                  }
1043              }
1044          }
1045          return $values;
1046      }
1047  
1048      /**
1049       * Returns a multidimensional associative array representing the specified
1050       * <configswitch> tag.
1051       *
1052       * @access private
1053       *
1054       * @param DomNode &$node  The DomNode representation of the <configswitch>
1055       *                        tag to process.
1056       *
1057       * @return array  An associative array representing the node.
1058       */
1059      function _getSwitchValues(&$node, $curctx)
1060      {
1061          if (!$node->has_child_nodes()) {
1062              return array();
1063          }
1064          $values = array();
1065          foreach ($node->child_nodes() as $case) {
1066              if ($case->type == XML_ELEMENT_NODE) {
1067                  $name = $case->get_attribute('name');
1068                  $values[$name] = array();
1069                  $values[$name]['desc'] = $case->get_attribute('desc');
1070                  $values[$name]['fields'] = array();
1071                  if ($case->has_child_nodes()) {
1072                      $this->_parseLevel($values[$name]['fields'], $case->child_nodes(), $curctx);
1073                  }
1074              }
1075          }
1076          return $values;
1077      }
1078  
1079      /**
1080       * Returns an associative array containing the possible values of a
1081       * <configspecial> tag as used inside of enum configurations.
1082       *
1083       * @access private
1084       *
1085       * @param DomNode $node  The DomNode representation of the <configspecial>
1086       *                       tag.
1087       *
1088       * @return array  An associative array with the possible values.
1089       */
1090      function _handleSpecials($node)
1091      {
1092          switch ($node->get_attribute('name')) {
1093          case 'list-horde-apps':
1094              global $registry;
1095              require_once  'Horde/Array.php';
1096              $apps = Horde_Array::valuesToKeys($registry->listApps(array('hidden', 'notoolbar', 'active')));
1097              asort($apps);
1098              return $apps;
1099              break;
1100  
1101          case 'list-horde-languages':
1102              return array_map(create_function('$val', 'return preg_replace(array("/&#x([0-9a-f]{4});/ie", "/(&[^;]+;)/e"), array("String::convertCharset(pack(\"H*\", \"$1\"), \"ucs-2\", \"' . NLS::getCharset() . '\")", "String::convertCharset(html_entity_decode(\"$1\", ENT_COMPAT, \"iso-8859-1\"), \"iso-8859-1\", \"' . NLS::getCharset() . '\")"), $val);'), $GLOBALS['nls']['languages']);
1103              break;
1104  
1105          case 'list-blocks':
1106              require_once  'Horde/Block/Collection.php';
1107              $collection = &Horde_Block_Collection::singleton('portal');
1108              return $collection->getBlocksList();
1109  
1110          case 'list-client-fields':
1111              global $registry;
1112              $f = array();
1113              if ($registry->hasMethod('clients/getClientSource')) {
1114                  $addressbook = $registry->call('clients/getClientSource');
1115                  $fields = $registry->call('clients/fields', array($addressbook));
1116                  if (!is_a($fields, 'PEAR_Error')) {
1117                      foreach ($fields as $field) {
1118                          $f[$field['name']] = $field['label'];
1119                      }
1120                  }
1121              }
1122              return $f;
1123              break;
1124          }
1125  
1126          return array();
1127      }
1128  
1129      /**
1130       * Returns the specified string with escaped single quotes
1131       *
1132       * @access private
1133       *
1134       * @param string $string  A string to escape.
1135       *
1136       * @return string  The specified string with single quotes being escaped.
1137       */
1138      function _quote($string)
1139      {
1140          return str_replace("'", "\'", $string);
1141      }
1142  
1143  }
1144  
1145  /**
1146   * A Horde_Form:: form that implements a user interface for the config
1147   * system.
1148   *
1149   * @author  Chuck Hagenbuch <chuck@horde.org>
1150   * @since   Horde 3.0
1151   * @package Horde_Framework
1152   */
1153  class ConfigForm extends Horde_Form {
1154  
1155      /**
1156       * Don't use form tokens for the configuration form - while
1157       * generating configuration info, things like the Token system
1158       * might not work correctly. This saves some headaches.
1159       *
1160       * @var boolean
1161       */
1162      var $_useFormToken = false;
1163  
1164      /**
1165       * Contains the Horde_Config object that this form represents.
1166       *
1167       * @var Horde_Config
1168       */
1169      var $_xmlConfig;
1170  
1171      /**
1172       * Contains the Variables object of this form.
1173       *
1174       * @var Variables
1175       */
1176      var $_vars;
1177  
1178      /**
1179       * Constructor.
1180       *
1181       * @param Variables &$vars  The Variables object of this form.
1182       * @param string $app             The name of the application that this
1183       *                                configuration form is for.
1184       */
1185      function ConfigForm(&$vars, $app)
1186      {
1187          parent::Horde_Form($vars);
1188  
1189          $this->_xmlConfig = &new Horde_Config($app);
1190          $this->_vars = &$vars;
1191          $config = $this->_xmlConfig->readXMLConfig();
1192          $this->addHidden('', 'app', 'text', true);
1193          $this->_buildVariables($config);
1194      }
1195  
1196      /**
1197       * Builds the form based on the specified level of the configuration tree.
1198       *
1199       * @access private
1200       *
1201       * @param array $config   The portion of the configuration tree for that
1202       *                        the form fields should be created.
1203       * @param string $prefix  A string representing the current position
1204       *                        inside the configuration tree.
1205       */
1206      function _buildVariables($config, $prefix = '')
1207      {
1208          if (!is_array($config)) {
1209              return;
1210          }
1211          foreach ($config as $name => $configitem) {
1212              $prefixedname = empty($prefix) ? $name : $prefix . '|' . $name;
1213              $varname = str_replace('|', '__', $prefixedname);
1214              $description = null;
1215              if ($configitem == 'placeholder') {
1216                  continue;
1217              } elseif (isset($configitem['tab'])) {
1218                  $this->setSection($configitem['tab'], $configitem['desc']);
1219              } elseif (isset($configitem['switch'])) {
1220                  $selected = $this->_vars->getExists($varname, $wasset);
1221                  $var_params = array();
1222                  $select_option = true;
1223                  if (is_bool($configitem['default'])) {
1224                      $configitem['default'] = $configitem['default'] ? 'true' : 'false';
1225                  }
1226                  foreach ($configitem['switch'] as $option => $case) {
1227                      $var_params[$option] = $case['desc'];
1228                      if ($option == $configitem['default']) {
1229                          $select_option = false;
1230                          if (!$wasset) {
1231                              $selected = $option;
1232                          }
1233                      }
1234                  }
1235                  $v = &$this->addVariable($configitem['desc'], $varname, 'enum', true, false, null, array($var_params, $select_option));
1236                  if (array_key_exists('default', $configitem)) {
1237                      $v->setDefault($configitem['default']);
1238                  }
1239                  $v_action = &Horde_Form_Action::factory('reload');
1240                  $v->setAction($v_action);
1241                  if (isset($selected) && isset($configitem['switch'][$selected])) {
1242                      $this->_buildVariables($configitem['switch'][$selected]['fields'], $prefix);
1243                  }
1244              } elseif (isset($configitem['_type'])) {
1245                  $required = (isset($configitem['required'])) ? $configitem['required'] : true;
1246                  $type = $configitem['_type'];
1247                  // FIXME: multienum fields can well be required, meaning that
1248                  // you need to select at least one entry. Changing this before
1249                  // Horde 4.0 would break a lot of configuration files though.
1250                  if ($type == 'multienum' || $type == 'header' ||
1251                      $type == 'description') {
1252                      $required = false;
1253                  }
1254                  if ($type == 'multienum' || $type == 'enum') {
1255                      $var_params = array($configitem['values']);
1256                  } else {
1257                      $var_params = array();
1258                  }
1259                  if ($type == 'php') {
1260                      $type = 'text';
1261                      $description = 'Enter a valid PHP expression.';
1262                  }
1263                  $v = &$this->addVariable($configitem['desc'], $varname, $type, $required, false, $description, $var_params);
1264                  if (isset($configitem['default'])) {
1265                      $v->setDefault($configitem['default']);
1266                  }
1267              } else {
1268                  $this->_buildVariables($configitem, $prefixedname);
1269              }
1270          }
1271      }
1272  
1273  }
1274  
1275  class Horde_Config_Document extends Horde_Config_Node {
1276  
1277      function factory($file)
1278      {
1279          if (function_exists('domxml_open_file')) {
1280              return domxml_open_file($file);
1281          } elseif (version_compare(phpversion(), '5', '>=')) {
1282              return $doc = new Horde_Config_Document($file);
1283          } else {
1284              Horde::fatal('DOM support not present.', __FILE__, __LINE__);
1285          }
1286      }
1287  
1288      function Horde_Config_Document($filename)
1289      {
1290          $this->node = new DOMDocument();
1291          $this->node->load($filename);
1292      }
1293  
1294      function root()
1295      {
1296          return $root = new Horde_Config_Element($this->node->documentElement);
1297      }
1298  
1299  }
1300  
1301  class Horde_Config_Node {
1302  
1303      var $node;
1304  
1305      function Horde_Config_Node($aDomNode) {$this->node=$aDomNode;}
1306  
1307      function __get($name)
1308      {
1309          switch ($name) {
1310          case 'type':
1311              return $this->node->nodeType;
1312  
1313          case 'tagname':
1314              return $this->node->tagName;
1315  
1316          case 'content':
1317              return $this->node->textContent;
1318  
1319          default:
1320              return false;
1321          }
1322      }
1323  
1324      function child_nodes()
1325      {
1326          $nodeList = $this->node->childNodes;
1327          $nodeSet = array();
1328          if (isset($nodeList)) {
1329              $i = 0;
1330              while ($node = $nodeList->item($i)) {
1331                  $nodeSet[] = new Horde_Config_Element($node);
1332                  $i++;
1333              }
1334          }
1335          return $nodeSet;
1336      }
1337  
1338      function first_child()
1339      {
1340          return new Horde_Config_Element($this->node->firstChild);
1341      }
1342  
1343      function get_content()
1344      {
1345          return $this->node->textContent;
1346      }
1347  
1348      function has_child_nodes()
1349      {
1350          return $this->node->hasChildNodes();
1351      }
1352  
1353      function next_sibling()
1354      {
1355          return new Horde_Config_Element($this->node->nextSibling);
1356      }
1357  
1358      function node_value()
1359      {
1360          return $this->node->nodeValue;
1361      }
1362  
1363  }
1364  
1365  class Horde_Config_Element extends Horde_Config_Node {
1366  
1367      function get_attribute($name)
1368      {
1369          return $this->node->getAttribute($name);
1370      }
1371  
1372  }


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