[ Index ]
 

Code source de phpMyAdmin 2.10.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/libraries/ -> PMA_List_Database.class.php (source)

   1  <?php
   2  /**
   3   * holds the PMA_List_Database class
   4   *
   5   */
   6  
   7  /**
   8   * the list base class
   9   */
  10  require_once  './libraries/PMA_List.class.php';
  11  
  12  /**
  13   * handles database lists
  14   *
  15   * <code>
  16   * $PMA_List_Database = new PMA_List_Database($userlink, $controllink);
  17   * </code>
  18   *
  19   * @todo this object should be attached to the PMA_Server object
  20   * @todo ? make use of INFORMATION_SCHEMA
  21   * @todo ? support --skip-showdatabases and user has only global rights
  22   * @access public
  23   * @since phpMyAdmin 2.9.10
  24   */
  25  /*public*/ class PMA_List_Database extends PMA_List
  26  {
  27      /**
  28       * @var mixed   database link resource|object to be used
  29       * @access protected
  30       */
  31      var $_db_link = null;
  32  
  33      /**
  34       * @var mixed   user database link resource|object
  35       * @access protected
  36       */
  37      var $_db_link_user = null;
  38  
  39      /**
  40       * @var mixed   controluser database link resource|object
  41       * @access protected
  42       */
  43      var $_db_link_control = null;
  44  
  45      /**
  46       * @var boolean whether SHOW DATABASES is disabled or not
  47       * @access protected
  48       */
  49      var $_show_databases_disabled = false;
  50  
  51      /**
  52       * Constructor
  53       *
  54       * @uses    PMA_List_Database::$_db_link
  55       * @uses    PMA_List_Database::$_db_link_user
  56       * @uses    PMA_List_Database::$_db_link_control
  57       * @uses    PMA_List_Database::build()
  58       * @param   mixed   $db_link_user       user database link resource|object
  59       * @param   mixed   $db_link_control    control database link resource|object
  60       */
  61      function __construct($db_link_user = null, $db_link_control = null) {
  62          $this->_db_link = $db_link_user;
  63          $this->_db_link_user = $db_link_user;
  64          $this->_db_link_control = $db_link_control;
  65  
  66          $this->build();
  67      }
  68  
  69      /**
  70       * old PHP 4 style constructor
  71       *
  72       * @see PMA_List_Database::__construct()
  73       */
  74      function PMA_List_Database($db_link_user = null, $db_link_control = null) {
  75          $this->__construct($db_link_user, $db_link_control);
  76      }
  77  
  78      /**
  79       * removes all databases not accessible by current user from list
  80       *
  81       * @access  protected
  82       * @uses    PMA_List_Database::$items
  83       * @uses    PMA_List_Database::$_db_link_user
  84       * @uses    PMA_List_Database::$_need_to_reindex to set it if reuqired
  85       * @uses    PMA_DBI_select_db()
  86       */
  87      function _checkAccess()
  88      {
  89          foreach ($this->items as $key => $db) {
  90              if (! @PMA_DBI_select_db($db, $this->_db_link_user)) {
  91                  unset($this->items[$key]);
  92              }
  93          }
  94  
  95          // re-index values
  96          $this->_need_to_reindex = true;
  97      }
  98  
  99      /**
 100       * checks if the configuration wants to hide some databases
 101       *
 102       * @todo temporaly use this docblock to test how to doc $GLOBALS
 103       * @access  protected
 104       * @uses    PMA_List_Database::$items
 105       * @uses    PMA_List_Database::$_need_to_reindex to set it if reuqired
 106       * @uses    preg_match()
 107       * @uses    $GLOBALS['cfg']
 108       * @uses    $GLOBALS['cfg']['Server']
 109       * @uses    $GLOBALS['cfg']['Server']['hide_db']
 110       * @global  array $GLOBALS['cfg']
 111       * @global  array $cfg
 112       */
 113      function _checkHideDatabase()
 114      {
 115          if (empty($GLOBALS['cfg']['Server']['hide_db'])) {
 116              return;
 117          }
 118  
 119          foreach ($this->items as $key => $db) {
 120              if (preg_match('/' . $GLOBALS['cfg']['Server']['hide_db'] . '/', $db)) {
 121                  unset($this->items[$key]);
 122              }
 123          }
 124          // re-index values
 125          $this->_need_to_reindex = true;
 126      }
 127  
 128      /**
 129       * retrieves database list from server
 130       *
 131       * @todo    we could also search mysql tables if all fail?
 132       * @access  protected
 133       * @uses    PMA_List_Database::$_show_databases_disabled for not retrying if SHOW DATABASES is disabled
 134       * @uses    PMA_List_Database::$_db_link
 135       * @uses    PMA_List_Database::$_db_link_control in case of SHOW DATABASES is disabled for userlink
 136       * @uses    PMA_DBI_fetch_result()
 137       * @uses    PMA_DBI_getError()
 138       * @global  boolean $error_showdatabases to alert not allowed SHOW DATABASE
 139       * @global  integer $errno from PMA_DBI_getError()
 140       * @param   string  $like_db_name   usally a db_name containing wildcards
 141       */
 142      function _retrieve($like_db_name = '')
 143      {
 144          if ($this->_show_databases_disabled) {
 145              return array();
 146          }
 147  
 148          if (! empty($like_db_name)) {
 149              $like = " LIKE '" . $like_db_name . "';";
 150          } else {
 151              $like = ";";
 152          }
 153  
 154          $database_list = PMA_DBI_fetch_result('SHOW DATABASES' . $like, null, null, $this->_db_link);
 155          PMA_DBI_getError();
 156  
 157          if ($GLOBALS['errno'] !== 0) {
 158              // failed to get database list, try the control user
 159              // (hopefully there is one and he has SHOW DATABASES right)
 160              $this->_db_link = $this->_db_link_control;
 161              $database_list = PMA_DBI_fetch_result('SHOW DATABASES' . $like, null, null, $this->_db_link);
 162  
 163              PMA_DBI_getError();
 164  
 165              if ($GLOBALS['errno'] !== 0) {
 166                  // failed! we will display a warning that phpMyAdmin could not safely
 167                  // retrieve database list, the admin has to setup a control user or
 168                  // allow SHOW DATABASES
 169                  $GLOBALS['error_showdatabases'] = true;
 170                  $this->_show_databases_disabled = true;
 171              }
 172          }
 173  
 174          return $database_list;
 175      }
 176  
 177      /**
 178       * builds up the list
 179       *
 180       * @uses    PMA_List_Database::$items to initialize it
 181       * @uses    PMA_List_Database::$_need_to_reindex
 182       * @uses    PMA_List_Database::_checkOnlyDatabase()
 183       * @uses    PMA_List_Database::_retrieve()
 184       * @uses    PMA_List_Database::_checkHideDatabase()
 185       * @uses    PMA_List_Database::_checkAccess()
 186       * @uses    PMA_MYSQL_INT_VERSION
 187       * @uses    array_values()
 188       * @uses    natsort()
 189       * @global  array   $cfg
 190       */
 191      function build()
 192      {
 193          $this->items = array();
 194  
 195          if (! $this->_checkOnlyDatabase()) {
 196              $this->items = $this->_retrieve();
 197  
 198              if ($GLOBALS['cfg']['NaturalOrder']) {
 199                  natsort($this->items);
 200                  $this->_need_to_reindex = true;
 201              }
 202          }
 203  
 204          $this->_checkHideDatabase();
 205  
 206          // Before MySQL 4.0.2, SHOW DATABASES could send the
 207          // whole list, so check if we really have access:
 208          if (PMA_MYSQL_INT_VERSION < 40002) {
 209              $this->_checkAccess();
 210          }
 211  
 212          if ($this->_need_to_reindex) {
 213              $this->items = array_values($this->items);
 214          }
 215      }
 216  
 217      /**
 218       * checks the only_db configuration
 219       *
 220       * @uses    PMA_List_Database::$_show_databases_disabled
 221       * @uses    PMA_List_Database::$items
 222       * @uses    PMA_List_Database::_retrieve()
 223       * @uses    PMA_unescape_mysql_wildcards()
 224       * @uses    preg_match()
 225       * @uses    array_diff()
 226       * @uses    array_merge()
 227       * @uses    is_array()
 228       * @uses    strlen()
 229       * @uses    is_string()
 230       * @global  array   $cfg
 231       * @return  boolean false if there is no only_db, otherwise true
 232       */
 233      function _checkOnlyDatabase()
 234      {
 235          if (is_string($GLOBALS['cfg']['Server']['only_db'])
 236           && strlen($GLOBALS['cfg']['Server']['only_db'])) {
 237              $GLOBALS['cfg']['Server']['only_db'] = array(
 238                  $GLOBALS['cfg']['Server']['only_db']
 239              );
 240          }
 241  
 242          if (! is_array($GLOBALS['cfg']['Server']['only_db'])) {
 243              return false;
 244          }
 245  
 246          foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
 247              if ($each_only_db === '*' && ! $this->_show_databases_disabled) {
 248                  // append all not already listed dbs to the list
 249                  $this->items = array_merge($this->items,
 250                      array_diff($this->_retrieve(), $this->items));
 251                  // there can only be one '*', and this can only be last
 252                  break;
 253              }
 254  
 255              // check if the db name contains wildcard,
 256              // thus containing not escaped _ or %
 257              if (! preg_match('/(^|[^\\\\])(_|%)/', $each_only_db)) {
 258                  // ... not contains wildcard
 259                  $this->items[] = PMA_unescape_mysql_wildcards($each_only_db);
 260                  continue;
 261              }
 262  
 263              if (! $this->_show_databases_disabled) {
 264                  $this->items = array_merge($this->items, $this->_retrieve($each_only_db));
 265                  continue;
 266              }
 267  
 268              // @todo induce error, about not using wildcards with SHOW DATABASE disabled?
 269          }
 270  
 271          return true;
 272      }
 273  
 274      /**
 275       * returns default item
 276       *
 277       * @uses    PMA_List::getEmpty()
 278       * @uses    strlen()
 279       * @global  string  $db
 280       * @return  string  default item
 281       */
 282      function getDefault()
 283      {
 284          if (strlen($GLOBALS['db'])) {
 285              return $GLOBALS['db'];
 286          }
 287  
 288          return $this->getEmpty();
 289      }
 290  
 291      /**
 292       * returns array with dbs grouped with extended infos
 293       *
 294       * @uses    $GLOBALS['PMA_List_Database']
 295       * @uses    $GLOBALS['cfgRelation']['commwork']
 296       * @uses    $GLOBALS['cfg']['ShowTooltip']
 297       * @uses    $GLOBALS['cfg']['LeftFrameDBTree']
 298       * @uses    $GLOBALS['cfg']['LeftFrameDBSeparator']
 299       * @uses    $GLOBALS['cfg']['ShowTooltipAliasDB']
 300       * @uses    PMA_getTableCount()
 301       * @uses    PMA_getComments()
 302       * @uses    is_array()
 303       * @uses    implode()
 304       * @uses    strstr()
 305       * @uses    explode()
 306       * @return  array   db list
 307       */
 308      function getGroupedDetails()
 309      {
 310          $dbgroups   = array();
 311          $parts      = array();
 312          foreach ($this->items as $key => $db) {
 313              // garvin: Get comments from PMA comments table
 314              $db_tooltip = '';
 315              if ($GLOBALS['cfg']['ShowTooltip']
 316                && $GLOBALS['cfgRelation']['commwork']) {
 317                  $_db_tooltip = PMA_getComments($db);
 318                  if (is_array($_db_tooltip)) {
 319                      $db_tooltip = implode(' ', $_db_tooltip);
 320                  }
 321              }
 322  
 323              if ($GLOBALS['cfg']['LeftFrameDBTree']
 324                  && $GLOBALS['cfg']['LeftFrameDBSeparator']
 325                  && strstr($db, $GLOBALS['cfg']['LeftFrameDBSeparator']))
 326              {
 327                  // use strpos instead of strrpos; it seems more common to
 328                  // have the db name, the separator, then the rest which
 329                  // might contain a separator
 330                  // like dbname_the_rest
 331                  $pos            = strpos($db, $GLOBALS['cfg']['LeftFrameDBSeparator']);
 332                  $group          = substr($db, 0, $pos);
 333                  $disp_name_cut  = substr($db, $pos);
 334              } else {
 335                  $group          = $db;
 336                  $disp_name_cut  = $db;
 337              }
 338  
 339              $disp_name  = $db;
 340              if ($db_tooltip && $GLOBALS['cfg']['ShowTooltipAliasDB']) {
 341                  $disp_name      = $db_tooltip;
 342                  $disp_name_cut  = $db_tooltip;
 343                  $db_tooltip     = $db;
 344              }
 345  
 346              $dbgroups[$group][$db] = array(
 347                  'name'          => $db,
 348                  'disp_name_cut' => $disp_name_cut,
 349                  'disp_name'     => $disp_name,
 350                  'comment'       => $db_tooltip,
 351                  'num_tables'    => PMA_getTableCount($db),
 352              );
 353          } // end foreach ($GLOBALS['PMA_List_Database']->items as $db)
 354          return $dbgroups;
 355      }
 356  
 357      /**
 358       * returns html code for list with dbs
 359       *
 360       * @return  string  html code list
 361       */
 362      function getHtmlListGrouped($selected = '')
 363      {
 364          if (true === $selected) {
 365              $selected = $this->getDefault();
 366          }
 367  
 368      $return = '<ul id="databaseList" xml:lang="en" dir="ltr">' . "\n";
 369          foreach ($this->getGroupedDetails() as $group => $dbs) {
 370              if (count($dbs) > 1) {
 371          $return .= '<li>' . $group . '<ul>' . "\n";
 372                  // wether display db_name cuted by the group part
 373                  $cut = true;
 374              } else {
 375                  // .. or full
 376                  $cut = false;
 377              }
 378              foreach ($dbs as $db) {
 379              $return .= '<li';
 380          if ($db['name'] == $selected) {
 381              $return .= ' class="selected"';
 382          }
 383                  $return .= '><a' . (! empty($db['comment']) ? ' title="' . $db['comment'] . '"' : '') . ' href="index.php?' . PMA_generate_common_url($db['name']) . '" target="_parent">';
 384                  $return .= ($cut ? $db['disp_name_cut'] : $db['disp_name'])
 385              .' (' . $db['num_tables'] . ')';
 386          $return .= '</a></li>' . "\n";
 387              }
 388              if (count($dbs) > 1) {
 389                  $return .= '</ul></li>' . "\n";
 390              }
 391          }
 392          $return .= '</ul>';
 393  
 394          return $return;
 395      }
 396  
 397      /**
 398       * returns html code for select form element with dbs
 399       *
 400       * @todo IE can not handle different text directions in select boxes so,
 401       * as mostly names will be in english, we set the whole selectbox to LTR
 402       * and EN
 403       *
 404       * @return  string  html code select
 405       */
 406      function getHtmlSelectGrouped($selected = '')
 407      {
 408          if (true === $selected) {
 409              $selected = $this->getDefault();
 410          }
 411  
 412          $return = '<select name="db" id="lightm_db" xml:lang="en" dir="ltr"'
 413              . ' onchange="if (this.value != \'\') window.parent.openDb(this.value);">' . "\n"
 414              . '<option value="" dir="' . $GLOBALS['text_dir'] . '">'
 415              . '(' . $GLOBALS['strDatabases'] . ') ...</option>' . "\n";
 416          foreach ($this->getGroupedDetails() as $group => $dbs) {
 417              if (count($dbs) > 1) {
 418                  $return .= '<optgroup label="' . htmlspecialchars($group)
 419                      . '">' . "\n";
 420                  // wether display db_name cuted by the group part
 421                  $cut = true;
 422              } else {
 423                  // .. or full
 424                  $cut = false;
 425              }
 426              foreach ($dbs as $db) {
 427                  $return .= '<option value="' . htmlspecialchars($db['name']) . '"'
 428                      .' title="' . htmlspecialchars($db['comment']) . '"';
 429                  if ($db['name'] == $selected) {
 430                      $return .= ' selected="selected"';
 431                  }
 432                  $return .= '>' . htmlspecialchars($cut ? $db['disp_name_cut'] : $db['disp_name'])
 433                      .' (' . $db['num_tables'] . ')</option>' . "\n";
 434              }
 435              if (count($dbs) > 1) {
 436                  $return .= '</optgroup>' . "\n";
 437              }
 438          }
 439          $return .= '</select>';
 440  
 441          return $return;
 442      }
 443  
 444      /**
 445       * this is just a backup, if all is fine this can be deleted later
 446       *
 447       * @deprecated
 448       * @access protected
 449       */
 450      function _checkAgainstPrivTables()
 451      {
 452          // 1. get allowed dbs from the "mysql.db" table
 453          // lem9: User can be blank (anonymous user)
 454          $local_query = "
 455              SELECT DISTINCT `Db` FROM `mysql`.`db`
 456              WHERE `Select_priv` = 'Y'
 457              AND `User`
 458              IN ('" . PMA_sqlAddslashes($GLOBALS['cfg']['Server']['user']) . "', '')";
 459          $tmp_mydbs = PMA_DBI_fetch_result($local_query, null, null,
 460              $GLOBALS['controllink']);
 461          if ($tmp_mydbs) {
 462              // Will use as associative array of the following 2 code
 463              // lines:
 464              //   the 1st is the only line intact from before
 465              //     correction,
 466              //   the 2nd replaces $dblist[] = $row['Db'];
 467  
 468              // Code following those 2 lines in correction continues
 469              // populating $dblist[], as previous code did. But it is
 470              // now populated with actual database names instead of
 471              // with regular expressions.
 472              var_dump($tmp_mydbs);
 473              $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['controllink']);
 474              // loic1: all databases cases - part 2
 475              if (isset($tmp_mydbs['%'])) {
 476                  while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
 477                      $dblist[] = $tmp_row[0];
 478                  } // end while
 479              } else {
 480                  while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
 481                      $tmp_db = $tmp_row[0];
 482                      if (isset($tmp_mydbs[$tmp_db]) && $tmp_mydbs[$tmp_db] == 1) {
 483                          $dblist[]           = $tmp_db;
 484                          $tmp_mydbs[$tmp_db] = 0;
 485                      } elseif (!isset($dblist[$tmp_db])) {
 486                          foreach ($tmp_mydbs as $tmp_matchpattern => $tmp_value) {
 487                              // loic1: fixed bad regexp
 488                              // TODO: db names may contain characters
 489                              //       that are regexp instructions
 490                              $re        = '(^|(\\\\\\\\)+|[^\])';
 491                              $tmp_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $tmp_matchpattern));
 492                              // Fixed db name matching
 493                              // 2000-08-28 -- Benjamin Gandon
 494                              if (ereg('^' . $tmp_regex . '$', $tmp_db)) {
 495                                  $dblist[] = $tmp_db;
 496                                  break;
 497                              }
 498                          } // end while
 499                      } // end if ... elseif ...
 500                  } // end while
 501              } // end else
 502              PMA_DBI_free_result($tmp_alldbs);
 503              unset($tmp_mydbs);
 504          } // end if
 505  
 506          // 2. get allowed dbs from the "mysql.tables_priv" table
 507          $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($GLOBALS['cfg']['Server']['user']) . '\'';
 508          $rs          = PMA_DBI_try_query($local_query, $GLOBALS['controllink']);
 509          if ($rs && @PMA_DBI_num_rows($rs)) {
 510              while ($row = PMA_DBI_fetch_assoc($rs)) {
 511                  if (!in_array($row['Db'], $dblist)) {
 512                      $dblist[] = $row['Db'];
 513                  }
 514              } // end while
 515              PMA_DBI_free_result($rs);
 516          } // end if
 517      }
 518  }
 519  ?>


Généré le : Mon Nov 26 15:18:20 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics