BPDB

The BuddyPress BPDB class.

Defined (2)

The class is defined in the following location(s).

/bp-forums/bbpress/bb-includes/backpress/class.bpdb.php  
  1. class BPDB 
  2. /** 
  3. * Whether to show SQL/DB errors 
  4. * @since 1.0 
  5. * @access private 
  6. * @var bool 
  7. */ 
  8. var $show_errors = false; 
  9.  
  10. /** 
  11. * Whether to suppress errors during the DB bootstrapping. 
  12. * @access private 
  13. * @since 1.0 
  14. * @var bool 
  15. */ 
  16. var $suppress_errors = false; 
  17.  
  18. /** 
  19. * The last error during query. 
  20. * @since 1.0 
  21. * @var string 
  22. */ 
  23. var $last_error = ''; 
  24.  
  25. /** 
  26. * Amount of queries made 
  27. * @since 1.0 
  28. * @access private 
  29. * @var int 
  30. */ 
  31. var $num_queries = 0; 
  32.  
  33. /** 
  34. * The last query made 
  35. * @since 1.0 
  36. * @access private 
  37. * @var string 
  38. */ 
  39. var $last_query = null; 
  40.  
  41. /** 
  42. * Saved info on the table column 
  43. * @since 1.0 
  44. * @access private 
  45. * @var array 
  46. */ 
  47. var $col_info = array(); 
  48.  
  49. /** 
  50. * Saved queries that were executed 
  51. * @since 1.0 
  52. * @access private 
  53. * @var array 
  54. */ 
  55. var $queries = array(); 
  56.  
  57. /** 
  58. * Whether to use the query log 
  59. * @since 1.0 
  60. * @access private 
  61. * @var bool 
  62. */ 
  63. var $save_queries = false; 
  64.  
  65. /** 
  66. * Table prefix 
  67. * You can set this to have multiple installations 
  68. * in a single database. The second reason is for possible 
  69. * security precautions. 
  70. * @since 1.0 
  71. * @access private 
  72. * @var string 
  73. */ 
  74. var $prefix = ''; 
  75.  
  76. /** 
  77. * Whether the database queries are ready to start executing. 
  78. * @since 1.0 
  79. * @access private 
  80. * @var bool 
  81. */ 
  82. var $ready = false; 
  83.  
  84. /** 
  85. * The currently connected MySQL connection resource. 
  86. * @since 1.0 
  87. * @access private 
  88. * @var bool|resource 
  89. */ 
  90. var $dbh = false; 
  91.  
  92. /** 
  93. * List of tables 
  94. * @since 1.0 
  95. * @access private 
  96. * @var array 
  97. */ 
  98. var $tables = array(); 
  99.  
  100. /** 
  101. * Whether to use mysql_real_escape_string 
  102. * @since 1.0 
  103. * @access public 
  104. * @var bool 
  105. */ 
  106. var $real_escape = false; 
  107.  
  108. /** 
  109. * PHP4 style constructor 
  110. * @since 1.0 
  111. * @return unknown Returns the result of bpdb::__construct() 
  112. */ 
  113. function BPDB() 
  114. $args = func_get_args(); 
  115. register_shutdown_function( array( &$this, '__destruct' ) ); 
  116. return call_user_func_array( array( &$this, '__construct' ), $args ); 
  117.  
  118. /** 
  119. * PHP5 style constructor 
  120. * Grabs the arguments, calls bpdb::_init() and then connects to the database 
  121. * @since 1.0 
  122. * @return void 
  123. */ 
  124. function __construct() 
  125. $args = func_get_args(); 
  126. $args = call_user_func_array( array( &$this, '_init' ), $args ); 
  127.  
  128. $this->db_connect_host( $args ); 
  129.  
  130. /** 
  131. * Initialises the class variables based on provided arguments 
  132. * @since 1.0 
  133. * @param array $args The provided connection settings 
  134. * @return array The current connection settings after processing by init 
  135. */ 
  136. function _init( $args ) 
  137. if ( !extension_loaded( 'mysql' ) ) { 
  138. $this->show_errors(); 
  139. $this->bail( BPDB__PHP_EXTENSION_MISSING ); 
  140. return; 
  141.  
  142. if ( 4 == func_num_args() ) { 
  143. $args = array( 
  144. 'user' => $args,  
  145. 'password' => func_get_arg( 1 ),  
  146. 'name' => func_get_arg( 2 ),  
  147. 'host' => func_get_arg( 3 ) 
  148. ); 
  149.  
  150. $defaults = array( 
  151. 'user' => false,  
  152. 'password' => false,  
  153. 'name' => false,  
  154. 'host' => 'localhost',  
  155. 'charset' => false,  
  156. 'collate' => false,  
  157. 'errors' => false 
  158. ); 
  159.  
  160. $args = wp_parse_args( $args, $defaults ); 
  161.  
  162. switch ( $args['errors'] ) { 
  163. case 'show' : 
  164. $this->show_errors( true ); 
  165. break; 
  166. case 'suppress' : 
  167. $this->suppress_errors( true ); 
  168. break; 
  169.  
  170. return $args; 
  171.  
  172. /** 
  173. * PHP5 style destructor, registered as shutdown function in PHP4 
  174. * @since 1.0 
  175. * @return bool Always returns true 
  176. */ 
  177. function __destruct() 
  178. return true; 
  179.  
  180. /** 
  181. * Figure out which database server should handle the query, and connect to it. 
  182. * @since 1.0 
  183. * @param string query 
  184. * @return resource mysql database connection 
  185. */ 
  186. function &db_connect( $query = '' ) 
  187. $false = false; 
  188. if ( empty( $query ) ) { 
  189. return $false; 
  190. return $this->dbh; 
  191.  
  192. /** 
  193. * Connects to the database server and selects a database 
  194. * @since 1.0 
  195. * @param array args 
  196. * name => string DB name (required) 
  197. * user => string DB user (optional: false) 
  198. * password => string DB user password (optional: false) 
  199. * host => string DB hostname (optional: 'localhost') 
  200. * charset => string DB default charset. Used in a SET NAMES query. (optional) 
  201. * collate => string DB default collation. If charset supplied, optionally added to the SET NAMES query (optional) 
  202. * @return void|bool void if cannot connect, false if cannot select, true if success 
  203. */ 
  204. function db_connect_host( $args ) 
  205. extract( $args, EXTR_SKIP ); 
  206.  
  207. unset( $this->dbh ); // De-reference before re-assigning 
  208. $this->dbh = @mysql_connect( $host, $user, $password, true ); 
  209.  
  210. if ( !$this->dbh ) { 
  211. if ( !$this->suppress_errors ) { 
  212. $this->show_errors(); 
  213. $this->bail( BPDB__CONNECT_ERROR_MESSAGE ); 
  214. return; 
  215.  
  216. $this->ready = true; 
  217.  
  218. if ( $this->has_cap( 'collation' ) ) { 
  219. if ( !empty( $charset ) ) { 
  220. if ( function_exists( 'mysql_set_charset' ) ) { 
  221. mysql_set_charset( $charset, $this->dbh ); 
  222. $this->real_escape = true; 
  223. } else { 
  224. $collation_query = "SET NAMES '{$charset}'"; 
  225. if ( !empty( $collate ) ) { 
  226. $collation_query .= " COLLATE '{$collate}'"; 
  227. $this->query( $collation_query, true ); 
  228.  
  229. return $this->select( $name, $this->dbh ); 
  230.  
  231. /** 
  232. * Sets the table prefix for the WordPress tables. 
  233. * @since 1.0 
  234. * @param string prefix 
  235. * @param false|array tables (optional: false) 
  236. * table identifiers are array keys 
  237. * array values 
  238. * empty: set prefix: array( 'posts' => false, 'users' => false, ... ) 
  239. * string: set to that array value: array( 'posts' => 'my_posts', 'users' => 'my_users' ) 
  240. * OR array values (with numeric keys): array( 'posts', 'users', ... ) 
  241. * @return string the previous prefix (mostly only meaningful if all $table parameter was false) 
  242. */ 
  243. function set_prefix( $prefix, $tables = false ) 
  244. if ( !$prefix ) { 
  245. return false; 
  246. if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) { 
  247. return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' ); // No gettext here 
  248.  
  249. $old_prefix = $this->prefix; 
  250.  
  251. if ( $tables && is_array( $tables ) ) { 
  252. $_tables =& $tables; 
  253. } else { 
  254. $_tables =& $this->tables; 
  255. $this->prefix = $prefix; 
  256.  
  257. foreach ( $_tables as $key => $value ) { 
  258. if ( is_numeric( $key ) ) { // array( 'posts', 'users', ... ) 
  259. $this->$value = $prefix . $value; 
  260. } elseif ( !$value ) { 
  261. $this->$key = $prefix . $key; // array( 'posts' => false, 'users' => false, ... ) 
  262. } elseif ( is_string( $value ) ) { // array( 'posts' => 'my_posts', 'users' => 'my_users' ) 
  263. $this->$key = $value; 
  264.  
  265. return $old_prefix; 
  266.  
  267. /** 
  268. * Selects a database using the current database connection. 
  269. * The database name will be changed based on the current database 
  270. * connection. On failure, the execution will bail and display an DB error. 
  271. * @since 1.0 
  272. * @param string $db MySQL database name 
  273. * @return bool True on success, false on failure. 
  274. */ 
  275. function select( $db, &$dbh ) 
  276. if ( !@mysql_select_db( $db, $dbh ) ) { 
  277. $this->ready = false; 
  278. $this->show_errors(); 
  279. $this->bail( BPDB__SELECT_ERROR_MESSAGE ); 
  280. return false; 
  281. return true; 
  282.  
  283. function _weak_escape( $string ) 
  284. return addslashes( $string ); 
  285.  
  286. function _real_escape( $string ) 
  287. if ( $this->dbh && $this->real_escape ) { 
  288. return mysql_real_escape_string( $string, $this->dbh ); 
  289. } else { 
  290. return addslashes( $string ); 
  291.  
  292. function _escape( $data ) 
  293. if ( is_array( $data ) ) { 
  294. foreach ( (array) $data as $k => $v ) { 
  295. if ( is_array( $v ) ) { 
  296. $data[$k] = $this->_escape( $v ); 
  297. } else { 
  298. $data[$k] = $this->_real_escape( $v ); 
  299. } else { 
  300. $data = $this->_real_escape( $data ); 
  301.  
  302. return $data; 
  303.  
  304. /** 
  305. * Escapes content for insertion into the database using addslashes(), for security 
  306. * @since 1.0 
  307. * @param string|array $data 
  308. * @return string query safe string 
  309. */ 
  310. function escape( $data ) 
  311. if ( is_array( $data ) ) { 
  312. foreach ( (array) $data as $k => $v ) { 
  313. if ( is_array( $v ) ) { 
  314. $data[$k] = $this->escape( $v ); 
  315. } else { 
  316. $data[$k] = $this->_weak_escape( $v ); 
  317. } else { 
  318. $data = $this->_weak_escape( $data ); 
  319.  
  320. return $data; 
  321.  
  322. /** 
  323. * Escapes content by reference for insertion into the database, for security 
  324. * @since 1.0 
  325. * @param string $s 
  326. */ 
  327. function escape_by_ref( &$string ) 
  328. $string = $this->_real_escape( $string ); 
  329.  
  330. /** 
  331. * Escapes array recursively for insertion into the database, for security 
  332. * @param array $array 
  333. */ 
  334. function escape_deep( $array ) 
  335. return $this->_escape( $array ); 
  336.  
  337. /** 
  338. * Prepares a SQL query for safe execution. Uses sprintf()-like syntax. 
  339. * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string). 
  340. * Does not support sign, padding, alignment, width or precision specifiers. 
  341. * Does not support argument numbering/swapping. 
  342. * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}. 
  343. * Both %d and %s should be left unquoted in the query string. 
  344. * <code> 
  345. * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 ) 
  346. * </code> 
  347. * @link http://php.net/sprintf Description of syntax. 
  348. * @since 1.0 
  349. * @param string $query Query statement with sprintf()-like placeholders 
  350. * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}. 
  351. * @param mixed $args, ... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}. 
  352. * @return null|string Sanitized query string 
  353. */ 
  354. function prepare( $query = null ) // ( $query, *$args ) 
  355. if ( is_null( $query ) ) { 
  356. return; 
  357. $args = func_get_args(); 
  358. array_shift( $args ); 
  359. // If args were passed as an array (as in vsprintf), move them up 
  360. if ( isset( $args[0] ) && is_array( $args[0] ) ) { 
  361. $args = $args[0]; 
  362. $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it 
  363. $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting 
  364. $query = str_replace( '%s', "'%s'", $query ); // quote the strings 
  365. array_walk( $args, array( &$this, 'escape_by_ref' ) ); 
  366. return @vsprintf( $query, $args ); 
  367.  
  368. /** 
  369. * Get SQL/DB error 
  370. * @since 1.0 
  371. * @param string $str Error string 
  372. */ 
  373. function get_error( $str = '' ) 
  374. if ( empty( $str ) ) { 
  375. if ( $this->last_error ) { 
  376. $str = $this->last_error; 
  377. } else { 
  378. return false; 
  379.  
  380. $caller = $this->get_caller(); 
  381. $error_str = sprintf( BPDB__ERROR_STRING, $str, $this->last_query, $caller ); 
  382.  
  383. if ( class_exists( 'WP_Error' ) ) { 
  384. return new WP_Error( 'db_query', $error_str, array( 'query' => $this->last_query, 'error' => $str, 'caller' => $caller ) ); 
  385. } else { 
  386. return array( 'query' => $this->last_query, 'error' => $str, 'caller' => $caller, 'error_str' => $error_str ); 
  387.  
  388. /** 
  389. * Print SQL/DB error. 
  390. * @since 1.0 
  391. * @param string $str The error to display 
  392. * @return bool False if the showing of errors is disabled. 
  393. */ 
  394. function print_error( $str = '' ) 
  395. if ( $this->suppress_errors ) { 
  396. return false; 
  397.  
  398. $error = $this->get_error( $str ); 
  399. if ( is_object( $error ) && is_a( $error, 'WP_Error' ) ) { 
  400. $err = $error->get_error_data(); 
  401. $err['error_str'] = $error->get_error_message(); 
  402. } else { 
  403. $err =& $error; 
  404.  
  405. $log_file = ini_get( 'error_log' ); 
  406. if ( !empty( $log_file ) && ( 'syslog' != $log_file ) && is_writable( $log_file ) && function_exists( 'error_log' ) ) { 
  407. error_log($err['error_str'], 0); 
  408.  
  409. // Is error output turned on or not 
  410. if ( !$this->show_errors ) { 
  411. return false; 
  412.  
  413. $str = htmlspecialchars( $err['error'], ENT_QUOTES ); 
  414. $query = htmlspecialchars( $err['query'], ENT_QUOTES ); 
  415. $caller = htmlspecialchars( $err['caller'], ENT_QUOTES ); 
  416.  
  417. // If there is an error then take note of it 
  418.  
  419. printf( BPDB__ERROR_HTML, $str, $query, $caller ); 
  420.  
  421. /** 
  422. * Enables showing of database errors. 
  423. * This function should be used only to enable showing of errors. 
  424. * bpdb::hide_errors() should be used instead for hiding of errors. However,  
  425. * this function can be used to enable and disable showing of database 
  426. * errors. 
  427. * @since 1.0 
  428. * @param bool $show Whether to show or hide errors 
  429. * @return bool Old value for showing errors. 
  430. */ 
  431. function show_errors( $show = true ) 
  432. $errors = $this->show_errors; 
  433. $this->show_errors = $show; 
  434. return $errors; 
  435.  
  436. /** 
  437. * Disables showing of database errors. 
  438. * @since 1.0 
  439. * @return bool Whether showing of errors was active or not 
  440. */ 
  441. function hide_errors() 
  442. return $this->show_errors( false ); 
  443.  
  444. /** 
  445. * Whether to suppress database errors. 
  446. * @since 1.0 
  447. * @param bool $suppress 
  448. * @return bool previous setting 
  449. */ 
  450. function suppress_errors( $suppress = true ) 
  451. $errors = $this->suppress_errors; 
  452. $this->suppress_errors = $suppress; 
  453. return $errors; 
  454.  
  455. /** 
  456. * Kill cached query results. 
  457. * @since 1.0 
  458. */ 
  459. function flush() 
  460. $this->last_result = array(); 
  461. $this->col_info = array(); 
  462. $this->last_query = null; 
  463. $this->last_error = ''; 
  464. $this->num_rows = 0; 
  465.  
  466. /** 
  467. * Perform a MySQL database query, using current database connection. 
  468. * More information can be found on the codex page. 
  469. * @since 1.0 
  470. * @param string $query 
  471. * @return int|false Number of rows affected/selected or false on error 
  472. */ 
  473. function query( $query, $use_current = false ) 
  474. if ( !$this->ready ) { 
  475. return false; 
  476.  
  477. // filter the query, if filters are available 
  478. // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method 
  479. if ( function_exists( 'apply_filters' ) ) { 
  480. $query = apply_filters( 'query', $query ); 
  481.  
  482. // initialise return 
  483. $return_val = 0; 
  484. $this->flush(); 
  485.  
  486. // Log how the function was called 
  487. $this->func_call = "\$db->query(\"$query\")"; 
  488.  
  489. // Keep track of the last query for debug.. 
  490. $this->last_query = $query; 
  491.  
  492. // Perform the query via std mysql_query function.. 
  493. if ( SAVEQUERIES ) { 
  494. $this->timer_start(); 
  495.  
  496. if ( $use_current ) { 
  497. $dbh =& $this->dbh; 
  498. } else { 
  499. $dbh = $this->db_connect( $query ); 
  500.  
  501. $this->result = @mysql_query( $query, $dbh ); 
  502. ++$this->num_queries; 
  503.  
  504. if ( SAVEQUERIES ) { 
  505. $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); 
  506.  
  507. // If there is an error then take note of it.. 
  508. if ( $this->last_error = mysql_error( $dbh ) ) { 
  509. return $this->print_error( $this->last_error ); 
  510.  
  511. if ( preg_match( "/^\\s*(insert|delete|update|replace|alter) /i", $query ) ) { 
  512. $this->rows_affected = mysql_affected_rows( $dbh ); 
  513. // Take note of the insert_id 
  514. if ( preg_match( "/^\\s*(insert|replace) /i", $query ) ) { 
  515. $this->insert_id = mysql_insert_id( $dbh ); 
  516. // Return number of rows affected 
  517. $return_val = $this->rows_affected; 
  518. } else { 
  519. $i = 0; 
  520. while ( $i < @mysql_num_fields( $this->result ) ) { 
  521. $this->col_info[$i] = @mysql_fetch_field( $this->result ); 
  522. $i++; 
  523. $num_rows = 0; 
  524. while ( $row = @mysql_fetch_object( $this->result ) ) { 
  525. $this->last_result[$num_rows] = $row; 
  526. $num_rows++; 
  527.  
  528. @mysql_free_result( $this->result ); 
  529.  
  530. // Log number of rows the query returned 
  531. $this->num_rows = $num_rows; 
  532.  
  533. // Return number of rows selected 
  534. $return_val = $this->num_rows; 
  535.  
  536. return $return_val; 
  537.  
  538. /** 
  539. * Insert a row into a table. 
  540. * <code> 
  541. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) ) 
  542. * </code> 
  543. * @since 1.0 
  544. * @see bpdb::prepare() 
  545. * @param string $table table name 
  546. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). 
  547. * @param array|string $format (optional) An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings. 
  548. * @return int|false The number of rows inserted, or false on error. 
  549. */ 
  550. function insert( $table, $data, $format = null ) 
  551. $formats = $format = (array) $format; 
  552. $fields = array_keys( $data ); 
  553. $formatted_fields = array(); 
  554. foreach ( $fields as $field ) { 
  555. if ( !empty( $format ) ) { 
  556. $form = ( $form = array_shift( $formats ) ) ? $form : $format[0]; 
  557. } elseif ( isset( $this->field_types[$field] ) ) { 
  558. $form = $this->field_types[$field]; 
  559. } elseif ( is_null( $data[$field] ) ) { 
  560. $form = 'NULL'; 
  561. unset( $data[$field] ); 
  562. } else { 
  563. $form = '%s'; 
  564. $formatted_fields[] = $form; 
  565. $sql = "INSERT INTO `$table` (`" . implode( '`, `', $fields ) . "`) VALUES (" . implode( ", ", $formatted_fields ) . ")"; 
  566. return $this->query( $this->prepare( $sql, $data ) ); 
  567.  
  568. /** 
  569. * Update a row in the table 
  570. * <code> 
  571. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) ) 
  572. * </code> 
  573. * @since 1.0 
  574. * @see bpdb::prepare() 
  575. * @param string $table table name 
  576. * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). 
  577. * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw". 
  578. * @param array|string $format (optional) An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings. 
  579. * @param array|string $format_where (optional) An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $where will be treated as strings. 
  580. * @return int|false The number of rows updated, or false on error. 
  581. */ 
  582. function update( $table, $data, $where, $format = null, $where_format = null ) 
  583. if ( !is_array( $where ) ) { 
  584. return false; 
  585.  
  586. $formats = $format = (array) $format; 
  587. $bits = $wheres = array(); 
  588. foreach ( (array) array_keys( $data ) as $field ) { 
  589. if ( !empty( $format ) ) { 
  590. $form = ( $form = array_shift( $formats ) ) ? $form : $format[0]; 
  591. } elseif ( isset( $this->field_types[$field] ) ) { 
  592. $form = $this->field_types[$field]; 
  593. } elseif ( is_null( $data[$field] ) ) { 
  594. $form = 'NULL'; 
  595. unset( $data[$field] ); 
  596. } else { 
  597. $form = '%s'; 
  598. $bits[] = "`$field` = {$form}"; 
  599.  
  600. $where_formats = $where_format = (array) $where_format; 
  601. foreach ( (array) array_keys( $where ) as $field ) { 
  602. if ( !empty( $where_format ) ) { 
  603. $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0]; 
  604. } elseif ( isset( $this->field_types[$field] ) ) { 
  605. $form = $this->field_types[$field]; 
  606. } elseif ( is_null( $where[$field] ) ) { 
  607. unset( $where[$field] ); 
  608. $wheres[] = "`$field` IS NULL"; 
  609. continue; 
  610. } else { 
  611. $form = '%s'; 
  612. $wheres[] = "`$field` = {$form}"; 
  613.  
  614. $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ); 
  615. return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) ); 
  616.  
  617. /** 
  618. * Retrieve one variable from the database. 
  619. * Executes a SQL query and returns the value from the SQL result. 
  620. * If the SQL result contains more than one column and/or more than one row, this function returns the value in the column and row specified. 
  621. * If $query is null, this function returns the value in the specified column and row from the previous SQL result. 
  622. * @since 1.0 
  623. * @param string|null $query SQL query. If null, use the result from the previous query. 
  624. * @param int $x (optional) Column of value to return. Indexed from 0. 
  625. * @param int $y (optional) Row of value to return. Indexed from 0. 
  626. * @return string Database query result 
  627. */ 
  628. function get_var( $query=null, $x = 0, $y = 0 ) 
  629. $this->func_call = "\$db->get_var(\"$query\", $x, $y)"; 
  630. if ( $query ) { 
  631. $this->query( $query ); 
  632.  
  633. // Extract var out of cached results based x, y vals 
  634. if ( !empty( $this->last_result[$y] ) ) { 
  635. $values = array_values( get_object_vars( $this->last_result[$y] ) ); 
  636.  
  637. // If there is a value return it else return null 
  638. return ( isset($values[$x]) && $values[$x]!=='' ) ? $values[$x] : null; 
  639.  
  640. /** 
  641. * Retrieve one row from the database. 
  642. * Executes a SQL query and returns the row from the SQL result. 
  643. * @since 1.0 
  644. * @param string|null $query SQL query. 
  645. * @param string $output (optional) one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...), a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively. 
  646. * @param int $y (optional) Row to return. Indexed from 0. 
  647. * @return mixed Database query result in format specifed by $output 
  648. */ 
  649. function get_row( $query = null, $output = OBJECT, $y = 0 ) 
  650. $this->func_call = "\$db->get_row(\"$query\", $output, $y)"; 
  651. if ( $query ) { 
  652. $this->query( $query ); 
  653. } else { 
  654. return null; 
  655.  
  656. if ( !isset( $this->last_result[$y] ) ) { 
  657. return null; 
  658.  
  659. if ( $output == OBJECT ) { 
  660. return $this->last_result[$y] ? $this->last_result[$y] : null; 
  661. } elseif ( $output == ARRAY_A ) { 
  662. return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null; 
  663. } elseif ( $output == ARRAY_N ) { 
  664. return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null; 
  665. } else { 
  666. $this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" ); 
  667.  
  668. /** 
  669. * Retrieve one column from the database. 
  670. * Executes a SQL query and returns the column from the SQL result. 
  671. * If the SQL result contains more than one column, this function returns the column specified. 
  672. * If $query is null, this function returns the specified column from the previous SQL result. 
  673. * @since 1.0 
  674. * @param string|null $query SQL query. If null, use the result from the previous query. 
  675. * @param int $x Column to return. Indexed from 0. 
  676. * @return array Database query result. Array indexed from 0 by SQL result row number. 
  677. */ 
  678. function get_col( $query = null , $x = 0 ) 
  679. if ( $query ) { 
  680. $this->query( $query ); 
  681.  
  682. $new_array = array(); 
  683. // Extract the column values 
  684. for ( $i=0; $i < count( $this->last_result ); $i++ ) { 
  685. $new_array[$i] = $this->get_var( null, $x, $i ); 
  686. return $new_array; 
  687.  
  688. /** 
  689. * Retrieve an entire SQL result set from the database (i.e., many rows) 
  690. * Executes a SQL query and returns the entire SQL result. 
  691. * @since 1.0 
  692. * @param string $query SQL query. 
  693. * @param string $output (optional) ane of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K | ARRAY_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number. Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. With OBJECT_K and ARRAY_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded. 
  694. * @return mixed Database query results 
  695. */ 
  696. function get_results( $query = null, $output = OBJECT )  
  697. $this->func_call = "\$db->get_results(\"$query\", $output)"; 
  698.  
  699. if ( $query ) { 
  700. $this->query($query); 
  701. } else { 
  702. return null; 
  703.  
  704. if ( $output == OBJECT ) { 
  705. // Return an integer-keyed array of row objects 
  706. return $this->last_result; 
  707. } elseif ( $output == OBJECT_K || $output == ARRAY_K ) { 
  708. // Return an array of row objects with keys from column 1 
  709. // (Duplicates are discarded) 
  710. $key = $this->col_info[0]->name; 
  711. foreach ( $this->last_result as $row ) { 
  712. if ( !isset( $new_array[ $row->$key ] ) ) { 
  713. $new_array[ $row->$key ] = $row; 
  714. if ( $output == ARRAY_K ) { 
  715. return array_map( 'get_object_vars', $new_array ); 
  716. return $new_array; 
  717. } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { 
  718. // Return an integer-keyed array of... 
  719. if ( $this->last_result ) { 
  720. $i = 0; 
  721. foreach( $this->last_result as $row ) { 
  722. if ( $output == ARRAY_N ) { 
  723. // ...integer-keyed row arrays 
  724. $new_array[$i] = array_values( get_object_vars( $row ) ); 
  725. } else { 
  726. // ...column name-keyed row arrays 
  727. $new_array[$i] = get_object_vars( $row ); 
  728. ++$i; 
  729. return $new_array; 
  730.  
  731. /** 
  732. * Retrieve column metadata from the last query. 
  733. * @since 1.0 
  734. * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill 
  735. * @param int $col_offset 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type 
  736. * @return mixed Column Results 
  737. */ 
  738. function get_col_info( $info_type = 'name', $col_offset = -1 ) 
  739. if ( $this->col_info ) { 
  740. if ( $col_offset == -1 ) { 
  741. $i = 0; 
  742. foreach( (array) $this->col_info as $col ) { 
  743. $new_array[$i] = $col->{$info_type}; 
  744. $i++; 
  745. return $new_array; 
  746. } else { 
  747. return $this->col_info[$col_offset]->{$info_type}; 
  748.  
  749. /** 
  750. * Starts the timer, for debugging purposes. 
  751. * @since 1.0 
  752. * @return true 
  753. */ 
  754. function timer_start() 
  755. $mtime = microtime(); 
  756. $mtime = explode( ' ', $mtime ); 
  757. $this->time_start = $mtime[1] + $mtime[0]; 
  758. return true; 
  759.  
  760. /** 
  761. * Stops the debugging timer. 
  762. * @since 1.0 
  763. * @return int Total time spent on the query, in milliseconds 
  764. */ 
  765. function timer_stop() 
  766. $mtime = microtime(); 
  767. $mtime = explode( ' ', $mtime ); 
  768. $time_end = $mtime[1] + $mtime[0]; 
  769. $time_total = $time_end - $this->time_start; 
  770. return $time_total; 
  771.  
  772. /** 
  773. * Wraps errors in a nice header and footer and dies. 
  774. * Will not die if bpdb::$show_errors is true 
  775. * @since 1.0 
  776. * @param string $message 
  777. * @return false|void 
  778. */ 
  779. function bail( $message ) 
  780. if ( !$this->show_errors ) { 
  781. if ( class_exists( 'WP_Error' ) ) 
  782. $this->error = new WP_Error( '500', $message ); 
  783. else 
  784. $this->error = $message; 
  785. return false; 
  786. backpress_die( $message ); 
  787.  
  788. /** 
  789. * Whether or not MySQL database is at least the required minimum version. 
  790. * @since 1.0 
  791. * @return WP_Error 
  792. */ 
  793. function check_database_version( $dbh_or_table = false ) 
  794. // Make sure the server has MySQL 4.0 
  795. if ( version_compare( $this->db_version( $dbh_or_table ), '4.0.0', '<' ) ) { 
  796. return new WP_Error( 'database_version', BPDB__DB_VERSION_ERROR ); 
  797.  
  798. /** 
  799. * Whether of not the database supports collation. 
  800. * Called when BackPress is generating the table scheme. 
  801. * @since 1.0 
  802. * @return bool True if collation is supported, false if version does not 
  803. */ 
  804. function supports_collation() 
  805. return $this->has_cap( 'collation' ); 
  806.  
  807. /** 
  808. * Generic function to determine if a database supports a particular feature 
  809. * @since 1.0 
  810. * @param string $db_cap the feature 
  811. * @param false|string|resource $dbh_or_table Which database to test. False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource. 
  812. * @return bool 
  813. */ 
  814. function has_cap( $db_cap, $dbh_or_table = false ) 
  815. $version = $this->db_version( $dbh_or_table ); 
  816.  
  817. switch ( strtolower( $db_cap ) ) { 
  818. case 'collation' : 
  819. case 'group_concat' : 
  820. case 'subqueries' : 
  821. return version_compare( $version, '4.1', '>=' ); 
  822. break; 
  823.  
  824. case 'index_hint_for_join' : 
  825. return version_compare( $version, '5.0', '>=' ); 
  826. break; 
  827.  
  828. case 'index_hint_lists' : 
  829. case 'index_hint_for_any' : 
  830. return version_compare( $version, '5.1', '>=' ); 
  831. break; 
  832.  
  833. return false; 
  834.  
  835. /** 
  836. * The database version number 
  837. * @since 1.0 
  838. * @param false|string|resource $dbh_or_table Which database to test. False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource. 
  839. * @return false|string false on failure, version number on success 
  840. */ 
  841. function db_version( $dbh_or_table = false ) 
  842. if ( !$dbh_or_table ) { 
  843. $dbh =& $this->dbh; 
  844. } elseif ( is_resource( $dbh_or_table ) ) { 
  845. $dbh =& $dbh_or_table; 
  846. } else { 
  847. $dbh = $this->db_connect( "DESCRIBE $dbh_or_table" ); 
  848.  
  849. if ( $dbh ) { 
  850. return preg_replace( '|[^0-9\.]|', '', mysql_get_server_info( $dbh ) ); 
  851. return false; 
  852.  
  853. /** 
  854. * Retrieve the name of the function that called bpdb. 
  855. * Requires PHP 4.3 and searches up the list of functions until it reaches 
  856. * the one that would most logically had called this method. 
  857. * @since 1.0 
  858. * @return string The name of the calling function 
  859. */ 
  860. function get_caller() 
  861. // requires PHP 4.3+ 
  862. if ( !is_callable( 'debug_backtrace' ) ) { 
  863. return ''; 
  864.  
  865. $bt = debug_backtrace(); 
  866. $caller = array(); 
  867.  
  868. $bt = array_reverse( $bt ); 
  869. foreach ( (array) $bt as $call ) { 
  870. if ( @$call['class'] == __CLASS__ ) { 
  871. continue; 
  872. $function = $call['function']; 
  873. if ( isset( $call['class'] ) ) { 
  874. $function = $call['class'] . "->$function"; 
  875. $caller[] = $function; 
  876. $caller = join( ', ', $caller ); 
  877.  
  878. return $caller; 
/bp-forums/bp-forums-bbpress-sa.php  
  1. class BPDB extends WPDB { 
  2. var $db_servers = array(); 
  3.  
  4. /** 
  5. * Constructor. 
  6. * @since 1.1.0 
  7. * @see WPDB::__construct() for description of parameters. 
  8. */ 
  9. function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) { 
  10. parent::__construct( $dbuser, $dbpassword, $dbname, $dbhost ); 
  11.  
  12. $args = call_user_func_array( array( &$this, 'init' ), func_get_args() ); 
  13.  
  14. if ( $args['host'] ) 
  15. $this->db_servers['dbh_global'] = $args; 
  16.  
  17. /** 
  18. * Determine if a database supports a particular feature. 
  19. * Overridden here to work around differences between bbPress's 
  20. * and WordPress's implementations. In particular, when 
  21. * BuddyPress tries to run bbPress' SQL installation script,  
  22. * the collation check always failed. The capability is long 
  23. * supported by WordPress' minimum required MySQL version, so 
  24. * this is safe. 
  25. * @since 1.1.0 
  26. * @see WPDB::has_cap() for a description of parameters and 
  27. * return values. 
  28. * @param string $db_cap See {@link WPDB::has_cap()}. 
  29. * @param string $_table_name See {@link WPDB::has_cap()}. 
  30. * @return bool See {@link WPDB::has_cap()}. 
  31. */ 
  32. function has_cap( $db_cap, $_table_name='' ) { 
  33. if ( 'collation' == $db_cap ) 
  34. return true; 
  35.  
  36. return parent::has_cap( $db_cap ); 
  37.  
  38. /** 
  39. * Initialize the class variables based on provided arguments. 
  40. * Based on, and taken from, the BackPress class in turn taken 
  41. * from the 1.0 branch of bbPress. 
  42. * @see BBDB::__construct() for a description of params. 
  43. * @param array $args Array of args to parse. 
  44. * @return array $args. 
  45. */ 
  46. function init( $args ) { 
  47. if ( 4 == func_num_args() ) { 
  48. $args = array( 
  49. 'user' => $args,  
  50. 'password' => func_get_arg( 1 ),  
  51. 'name' => func_get_arg( 2 ),  
  52. 'host' => func_get_arg( 3 ),  
  53. 'charset' => defined( 'BBDB_CHARSET' ) ? BBDB_CHARSET : false,  
  54. 'collate' => defined( 'BBDB_COLLATE' ) ? BBDB_COLLATE : false,  
  55. ); 
  56.  
  57. $defaults = array( 
  58. 'user' => false,  
  59. 'password' => false,  
  60. 'name' => false,  
  61. 'host' => 'localhost',  
  62. 'charset' => false,  
  63. 'collate' => false,  
  64. 'errors' => false 
  65. ); 
  66.  
  67. return wp_parse_args( $args, $defaults ); 
  68.  
  69. /** 
  70. * Stub for escape_deep() compatibility. 
  71. * @since 1.1.0 
  72. * @param mixed $data See {@link WPDB::escape_deep()}. 
  73. * @return mixed $data See {@link WPDB::escape_deep()}. 
  74. */ 
  75. function escape_deep( $data ) { 
  76. return esc_sql( $data );