| 1196 | 1196 | * |
| 1197 | 1197 | * The following placeholders can be used in the query string: |
| 1198 | 1198 | * %d (integer) |
| 1199 | 1199 | * %f (float) |
| 1200 | 1200 | * %s (string) |
| 1201 | 1201 | * |
| 1202 | 1202 | * All placeholders MUST be left unquoted in the query string. A corresponding argument MUST be passed for each placeholder. |
| 1203 | 1203 | * |
| 1204 | 1204 | * Literal percentage signs (%) in the query string must be written as %%. Percentage wildcards (for example, |
| 1205 | 1205 | * to use in LIKE syntax) must be passed via a substitution argument containing the complete LIKE string, these |
| 1206 | 1206 | * cannot be inserted directly in the query string. Also see {@see esc_like()}. |
| 1207 | 1207 | * |
| 1208 | 1208 | * This method DOES NOT support sign, padding, alignment, width or precision specifiers. |
| 1209 | 1209 | * This method DOES NOT support argument numbering or swapping. |
| 1210 | 1210 | * |
| 1212 | 1212 | * of the two is not supported. |
| 1213 | 1213 | * |
| 1214 | 1214 | * Examples: |
| 1215 | 1215 | * $wpdb->prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d OR `other_field` LIKE %s", array( 'foo', 1337, '%bar' ) ); |
| 1216 | 1216 | * $wpdb->prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' ); |
| 1217 | 1217 | * |
| 1218 | 1218 | * @link https://secure.php.net/sprintf Description of syntax. |
| 1219 | 1219 | * @since 2.3.0 |
| 1220 | 1220 | * |
| 1221 | 1221 | * @param string $query Query statement with sprintf()-like placeholders |
| 1222 | 1222 | * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called with an array of arguments, |
| 1223 | 1223 | * or the first variable to substitute into the query's placeholders if being called with individual arguments. |
| 1224 | 1224 | * @param mixed $args,... further variables to substitute into the query's placeholders if being called wih individual arguments. |
| 1225 | 1225 | * @return string|void Sanitized query string, if there is a query to prepare. |
| 1226 | 1226 | */ |
| 1775 | 1775 | |
| 1776 | 1776 | // MySQL server has gone away, try to reconnect. |
| 1777 | 1777 | $mysql_errno = 0; |
| 1778 | 1778 | if ( ! empty( $this->dbh ) ) { |
| 1779 | 1779 | if ( $this->use_mysqli ) { |
| 1780 | 1780 | if ( $this->dbh instanceof mysqli ) { |
| 1781 | 1781 | $mysql_errno = mysqli_errno( $this->dbh ); |
| 1782 | 1782 | } else { |
| 1783 | 1783 | // $dbh is defined, but isn't a real connection. |
| 1784 | 1784 | // Something has gone horribly wrong, let's try a reconnect. |
| 1785 | 1785 | $mysql_errno = 2006; |
| 1786 | 1786 | } |
| 1787 | 1787 | } else { |
| 1788 | 1788 | if ( is_resource( $this->dbh ) ) { |
| 1789 | 1789 | $mysql_errno = mysql_errno( $this->dbh ); |
| 1790 | 1790 | } else { |
| 1791 | 1791 | $mysql_errno = 2006; |
| 1792 | 1792 | } |
| 1793 | 1793 | } |
| 1794 | 1794 | } |
| 1795 | 1795 | |
| 1796 | 1796 | if ( empty( $this->dbh ) || 2006 == $mysql_errno ) { |
| 1797 | 1797 | if ( $this->check_connection() ) { |
| 1834 | 1834 | } else { |
| 1835 | 1835 | $this->rows_affected = mysql_affected_rows( $this->dbh ); |
| 1836 | 1836 | } |
| 1837 | 1837 | // Take note of the insert_id |
| 1838 | 1838 | if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) { |
| 1839 | 1839 | if ( $this->use_mysqli ) { |
| 1840 | 1840 | $this->insert_id = mysqli_insert_id( $this->dbh ); |
| 1841 | 1841 | } else { |
| 1842 | 1842 | $this->insert_id = mysql_insert_id( $this->dbh ); |
| 1843 | 1843 | } |
| 1844 | 1844 | } |
| 1845 | 1845 | // Return number of rows affected |
| 1846 | 1846 | $return_val = $this->rows_affected; |
| 1847 | 1847 | } else { |
| 1848 | 1848 | $num_rows = 0; |
| 1849 | | if ( $this->use_mysqli && $this->result instanceof mysqli_result ) { |
| | 1849 | if ( $this->use_mysqli && $this->result instanceof mysqli_stmt ) { |
| | 1850 | $row = array(); |
| | 1851 | $mysqli_stmt_bind_result_args = array( $this->result ); |
| | 1852 | |
| | 1853 | foreach ( mysqli_fetch_fields( mysqli_stmt_result_metadata( $this->result ) ) as $field ) { |
| | 1854 | $row[ $field->name ] = null; |
| | 1855 | $mysqli_stmt_bind_result_args[] = &$row[ $field->name ]; |
| | 1856 | } |
| | 1857 | call_user_func_array( 'mysqli_stmt_bind_result', $mysqli_stmt_bind_result_args ); |
| | 1858 | |
| | 1859 | while ( mysqli_stmt_fetch( $this->result ) ) { |
| | 1860 | $this->last_result[$num_rows] = $row; |
| | 1861 | $num_rows++; |
| | 1862 | } |
| | 1863 | } elseif ( $this->use_mysqli && $this->result instanceof mysqli_result ) { |
| 1850 | 1864 | while ( $row = mysqli_fetch_object( $this->result ) ) { |
| 1851 | 1865 | $this->last_result[$num_rows] = $row; |
| 1852 | 1866 | $num_rows++; |
| 1853 | 1867 | } |
| 1854 | 1868 | } elseif ( is_resource( $this->result ) ) { |
| 1855 | 1869 | while ( $row = mysql_fetch_object( $this->result ) ) { |
| 1856 | 1870 | $this->last_result[$num_rows] = $row; |
| 1857 | 1871 | $num_rows++; |
| 1858 | 1872 | } |
| 1859 | 1873 | } |
| 1860 | 1874 | |
| 1861 | 1875 | // Log number of rows the query returned |
| 1862 | 1876 | // and return number of rows selected |
| 1863 | 1877 | $this->num_rows = $num_rows; |
| 1864 | 1878 | $return_val = $num_rows; |
| 1865 | 1879 | } |
| 1866 | 1880 | |
| 1867 | 1881 | return $return_val; |
| 1868 | 1882 | } |
| 1869 | 1883 | |
| 1870 | 1884 | /** |
| 1871 | 1885 | * Internal function to perform the mysql_query() call. |
| 1872 | 1886 | * |
| 1873 | 1887 | * @since 3.9.0 |
| 1874 | 1888 | * |
| 1875 | 1889 | * @see wpdb::query() |
| 1876 | 1890 | * |
| 1877 | 1891 | * @param string $query The query to run. |
| 1878 | 1892 | */ |
| 1884 | | if ( ! empty( $this->dbh ) && $this->use_mysqli ) { |
| | 1898 | if ( ! empty( $this->dbh ) && $this->use_mysqli && $prepared_query_data !== false ) { |
| | 1899 | $prepared_value_types = ''; |
| | 1900 | $prepared_values = array(); |
| | 1901 | $valid_data_types = array( 's', 'd', 'i' ); |
| | 1902 | foreach ( $prepared_query_data as $v ) { |
| | 1903 | if ( is_array( $v ) && isset( $v['type'] ) ) { |
| | 1904 | if ( in_array( $v['type'], $valid_data_types, true ) ) { |
| | 1905 | $prepared_value_types .= $v['type']; |
| | 1906 | } else { |
| | 1907 | $prepared_value_types .= 's'; |
| | 1908 | } |
| | 1909 | $prepared_values[] = $v['value']; |
| | 1910 | } else { |
| | 1911 | // Strings can be passed without the data type. |
| | 1912 | $prepared_value_types .= 's'; |
| | 1913 | $prepared_values[] = $v; |
| | 1914 | } |
| | 1915 | } |
| | 1916 | |
| | 1917 | $prepared_query = mysqli_prepare( $this->dbh, $query ); |
| | 1918 | if ( ! $prepared_query ) { |
| | 1919 | // TODO: Handling of a invalid query |
| | 1920 | // $this->result = false; |
| | 1921 | } |
| | 1922 | |
| | 1923 | /*if ( $prepared_query->param_count != count( $__raw_prepared_data ) ) { |
| | 1924 | // TODO Catch this before a PHP Warning is hit and yell even louder than a Warning at the developer? |
| | 1925 | _doing_it_completely_wrong( "Incorrect parameter count!" ); |
| | 1926 | throw new Exception( 'Incorrect parameter count!' ); |
| | 1927 | }*/ |
| | 1928 | |
| | 1929 | $mysqli_stmt_bind_param_args = array( |
| | 1930 | $prepared_query, |
| | 1931 | $prepared_value_types |
| | 1932 | // ... args by ref: |
| | 1933 | ); |
| | 1934 | foreach ( $prepared_values as $i => $v ) { |
| | 1935 | $mysqli_stmt_bind_param_args[] = & $prepared_values[$i]; |
| | 1936 | } |
| | 1937 | call_user_func_array( 'mysqli_stmt_bind_param', $mysqli_stmt_bind_param_args ); |
| | 1938 | |
| | 1939 | mysqli_stmt_execute( $prepared_query ); |
| | 1940 | |
| | 1941 | // $this->result = mysqli_stmt_get_result( $prepared_query ); // PHP 5.3+ only |
| | 1942 | $this->result = $prepared_query; |
| | 1943 | |
| | 1944 | } elseif ( ! empty( $this->dbh ) && $this->use_mysqli ) { |
| 1887 | 1952 | $this->result = mysql_query( $query, $this->dbh ); |
| 1888 | 1953 | } |
| 1889 | 1954 | $this->num_queries++; |
| 1890 | 1955 | |
| 1891 | 1956 | if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { |
| 1892 | 1957 | $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); |
| 1893 | 1958 | } |
| 1894 | 1959 | } |
| 1895 | 1960 | |
| 1896 | 1961 | /** |
| 1897 | 1962 | * Insert a row into a table. |
| 1898 | 1963 | * |
| 1899 | 1964 | * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) ) |
| 1900 | 1965 | * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) ) |
| 1901 | 1966 | * |
| 2052 | 2117 | } |
| 2053 | 2118 | foreach ( $where as $field => $value ) { |
| 2054 | 2119 | if ( is_null( $value['value'] ) ) { |
| 2055 | 2120 | $conditions[] = "`$field` IS NULL"; |
| 2056 | 2121 | continue; |
| 2057 | 2122 | } |
| 2058 | 2123 | |
| 2059 | 2124 | $conditions[] = "`$field` = " . $value['format']; |
| 2060 | 2125 | $values[] = $value['value']; |
| 2061 | 2126 | } |
| 2062 | 2127 | |
| 2063 | 2128 | $fields = implode( ', ', $fields ); |
| 2064 | 2129 | $conditions = implode( ' AND ', $conditions ); |
| 2065 | 2130 | |
| 2066 | 2131 | $sql = "UPDATE `$table` SET $fields WHERE $conditions"; |
| 2068 | 2133 | $this->check_current_query = false; |
| 2069 | 2134 | return $this->query( $this->prepare( $sql, $values ) ); |
| 2070 | 2135 | } |
| 2071 | 2136 | |
| 2072 | 2137 | /** |
| 2073 | 2138 | * Delete a row in the table |
| 2074 | 2139 | * |
| 2075 | 2140 | * wpdb::delete( 'table', array( 'ID' => 1 ) ) |
| 2076 | 2141 | * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) ) |
| 2077 | 2142 | * |
| 2078 | 2143 | * @since 3.4.0 |
| 2079 | 2144 | * @see wpdb::prepare() |
| 2080 | 2145 | * @see wpdb::$field_types |
| 2081 | 2146 | * @see wp_set_wpdb_vars() |
| 2082 | 2147 | * |
| 2260 | 2325 | |
| 2261 | 2326 | /** |
| 2262 | 2327 | * Retrieve one variable from the database. |
| 2263 | 2328 | * |
| 2264 | 2329 | * Executes a SQL query and returns the value from the SQL result. |
| 2265 | 2330 | * 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. |
| 2266 | 2331 | * If $query is null, this function returns the value in the specified column and row from the previous SQL result. |
| 2267 | 2332 | * |
| 2268 | 2333 | * @since 0.71 |
| 2269 | 2334 | * |
| 2270 | 2335 | * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query. |
| 2271 | 2336 | * @param int $x Optional. Column of value to return. Indexed from 0. |
| 2272 | 2337 | * @param int $y Optional. Row of value to return. Indexed from 0. |
| 2273 | 2338 | * @return string|null Database query result (as string), or null on failure |
| 2274 | 2339 | */ |
| 2284 | 2360 | } |
| 2285 | 2361 | |
| 2286 | 2362 | // Extract var out of cached results based x,y vals |
| 2287 | 2363 | if ( !empty( $this->last_result[$y] ) ) { |
| 2288 | 2364 | $values = array_values( get_object_vars( $this->last_result[$y] ) ); |
| 2289 | 2365 | } |
| 2290 | 2366 | |
| 2291 | 2367 | // If there is a value return it else return null |
| 2292 | 2368 | return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null; |
| 2293 | 2369 | } |
| 2294 | 2370 | |
| 2295 | 2371 | /** |
| 2296 | 2372 | * Retrieve one row from the database. |
| 2297 | 2373 | * |
| 2298 | 2374 | * Executes a SQL query and returns the row from the SQL result. |
| 2299 | 2375 | * |
| 2300 | 2376 | * @since 0.71 |
| 2301 | 2377 | * |
| 2302 | 2378 | * @param string|null $query SQL query. |
| 2303 | 2379 | * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to |
| 2304 | 2380 | * an stdClass object, an associative array, or a numeric array, respectively. Default OBJECT. |
| 2305 | 2381 | * @param int $y Optional. Row to return. Indexed from 0. |
| 2306 | 2382 | * @return array|object|null|void Database query result in format specified by $output or null on failure |
| 2307 | 2383 | */ |
| 2317 | 2405 | } else { |
| 2318 | 2406 | return null; |
| 2319 | 2407 | } |
| 2320 | 2408 | |
| 2321 | 2409 | if ( !isset( $this->last_result[$y] ) ) |
| 2322 | 2410 | return null; |
| 2323 | 2411 | |
| 2324 | 2412 | if ( $output == OBJECT ) { |
| 2325 | 2413 | return $this->last_result[$y] ? $this->last_result[$y] : null; |
| 2326 | 2414 | } elseif ( $output == ARRAY_A ) { |
| 2327 | 2415 | return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null; |
| 2328 | 2416 | } elseif ( $output == ARRAY_N ) { |
| 2329 | 2417 | return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null; |
| 2330 | 2418 | } elseif ( strtoupper( $output ) === OBJECT ) { |
| 2331 | 2419 | // Back compat for OBJECT being previously case insensitive. |
| 2336 | 2424 | } |
| 2337 | 2425 | |
| 2338 | 2426 | /** |
| 2339 | 2427 | * Retrieve one column from the database. |
| 2340 | 2428 | * |
| 2341 | 2429 | * Executes a SQL query and returns the column from the SQL result. |
| 2342 | 2430 | * If the SQL result contains more than one column, this function returns the column specified. |
| 2343 | 2431 | * If $query is null, this function returns the specified column from the previous SQL result. |
| 2344 | 2432 | * |
| 2345 | 2433 | * @since 0.71 |
| 2346 | 2434 | * |
| 2347 | 2435 | * @param string|null $query Optional. SQL query. Defaults to previous query. |
| 2348 | 2436 | * @param int $x Optional. Column to return. Indexed from 0. |
| 2349 | 2437 | * @return array Database query result. Array indexed from 0 by SQL result row number. |
| 2350 | 2438 | */ |
| 2358 | 2452 | } |
| 2359 | 2453 | |
| 2360 | 2454 | $new_array = array(); |
| 2361 | 2455 | // Extract the column values |
| 2362 | 2456 | for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) { |
| 2363 | 2457 | $new_array[$i] = $this->get_var( null, $x, $i ); |
| 2364 | 2458 | } |
| 2365 | 2459 | return $new_array; |
| 2366 | 2460 | } |
| 2367 | 2461 | |
| 2368 | 2462 | /** |
| 2369 | 2463 | * Retrieve an entire SQL result set from the database (i.e., many rows) |
| 2370 | 2464 | * |
| 2371 | 2465 | * Executes a SQL query and returns the entire SQL result. |
| 2372 | 2466 | * |
| 2373 | 2467 | * @since 0.71 |
| 2374 | 2468 | * |
| 2375 | 2469 | * @param string $query SQL query. |
| 2376 | 2470 | * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. |
| 2377 | 2471 | * With one of the first three, return an array of rows indexed from 0 by SQL result row number. |
| 2378 | 2472 | * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. |
| 2379 | 2473 | * With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. |
| 2380 | 2474 | * Duplicate keys are discarded. |
| 2381 | 2475 | * @return array|object|null Database query results |
| 2382 | 2476 | */ |
| 2392 | 2492 | } else { |
| 2393 | 2493 | return null; |
| 2394 | 2494 | } |
| 2395 | 2495 | |
| 2396 | 2496 | $new_array = array(); |
| 2397 | 2497 | if ( $output == OBJECT ) { |
| 2398 | 2498 | // Return an integer-keyed array of row objects |
| 2399 | 2499 | return $this->last_result; |
| 2400 | 2500 | } elseif ( $output == OBJECT_K ) { |
| 2401 | 2501 | // Return an array of row objects with keys from column 1 |
| 2402 | 2502 | // (Duplicates are discarded) |
| 2403 | 2503 | foreach ( $this->last_result as $row ) { |
| 2404 | 2504 | $var_by_ref = get_object_vars( $row ); |
| 2405 | 2505 | $key = array_shift( $var_by_ref ); |
| 2406 | 2506 | if ( ! isset( $new_array[ $key ] ) ) |