$needsEscaping = ( ( $options & self::ESCAPE_FORCE ) !== 0 || 'cli' === self::$sapiName ) || ( ( $options & self::ESCAPE_QUOTE ) !== 0 && ! is_int( $value ) && ! is_float( $value ) ); if ( $needsEscaping ) { $value = esc_sql( $value ); $value = "'$value'"; } return $value; } /** * Get the current escape options. * * @since 1.0.0 * * @return integer The current escape options. */ public function getEscapeOptions() { return $this->escapeOptions; } /** * Set the current escape options. * * @since 1.0.0 * * @param integer $options */ public function setEscapeOptions( $options ) { $this->escapeOptions = $options; } /** * Backtick-escapes an array of column and/or table names. * * @since 1.0.0 * * @param array $cols An array of column names to be escaped. * @return array An array of escaped column names. */ private function escapeColNames( $cols ) { if ( ! is_array( $cols ) ) { $cols = [ $cols ]; } foreach ( $cols as &$col ) { if ( false === stripos( $col, '(' ) && false === stripos( $col, ' ' ) && false === stripos( $col, '*' ) ) { if ( stripos( $col, '.' ) ) { list( $table, $c ) = explode( '.', $col ); $col = "`$table`.`$c`"; continue; } $col = "`$col`"; } } return $cols; } /** * Gets a variable list of function arguments and reformats them as needed for many of the functions of this class. * * @since 1.0.0 * * @param mixed $values This could be anything, but if used properly its usually a string or an array. * @return array If the preparation is correct it will return an array of arguments. */ private function prepArgs( $values ) { $values = (array) $values; if ( ! is_array( $values[0] ) && count( $values ) === 2 ) { $values = [ $values[0] => $values[1] ]; } elseif ( is_array( $values[0] ) && count( $values ) === 1 ) { $values = $values[0]; } return $values; } /** * Resets all the variables that make up the query. * * @since 1.0.0 * * @param array $what Set which items you want to reset, all are selected by default. * @return Database Returns the Database object. */ public function reset( $what = [ 'table', 'statement', 'limit', 'group', 'order', 'select', 'set', 'onDuplicate', 'ignore', 'where', 'union', 'distinct', 'orderDirection', 'query', 'output', 'stripTags', 'models', 'join' ] ) { // If we are not running a select query, let's bust the cache for this table. $selectStatements = [ 'SELECT', 'SELECT DISTINCT' ]; if ( ! empty( $this->statement ) && ! in_array( $this->statement, $selectStatements, true ) ) { $this->bustCache( $this->getCacheTableName() ); } foreach ( (array) $what as $var ) { switch ( $var ) { case 'group': case 'order': case 'select': case 'set': case 'onDuplicate': case 'where': case 'union': case 'join': $this->$var = []; break; case 'orderDirection': $this->$var = 'ASC'; break; case 'ignore': case 'stripTags': $this->$var = false; break; case 'output': $this->$var = 'OBJECT'; break; default: if ( isset( $this->$var ) ) { $this->$var = null; } break; } } return $this; } /** * Get the current value of one or more query properties. If only one property is specified, returns the value; * if an array of values is specified, then returns an array of values. * * @since 1.0.0 * * @param string|array $what You can pass in an array of options to retrieve. By default it selects all if them. * @return string|array Returns the value of whichever variables are passed in. */ public function getQueryProperty( $what = [ 'table', 'statement', 'limit', 'group', 'order', 'select', 'set', 'onDuplicate', 'where', 'union', 'distinct', 'orderDirection', 'query', 'output', 'result' ] ) { if ( is_array( $what ) ) { $return = []; foreach ( (array) $what as $which ) { $return[ $which ] = $this->$which; } return $return; } else { return $this->$what; } } /** * Get a table name for the cache key. * * @since 1.0.0 * * @param string $cacheTableName The table name to check against. * @return string The cache key table name. */ private function getCacheTableName( $cacheTableName = null ) { $cacheTableName = empty( $cacheTableName ) ? $this->table : $cacheTableName; foreach ( $this->customTables as $tableName ) { if ( false !== stripos( $cacheTableName, $this->prefix . $tableName ) ) { $cacheTableName = $tableName; break; } } return $cacheTableName; } /** * Busts the cache for the given table name. * * @since 1.0.0 * * @param string|null $tableName The table name. * @return void */ public function bustCache( $tableName = null ) { if ( ! $tableName ) { // Bust all the cache. $this->cache = []; return; } unset( $this->cache[ $tableName ] ); } /** * In order to not have a conflict, we need to return a clone. * * @since 1.0.0 * * @return Database The cloned Database object. */ public function noConflict() { return clone $this; } /** * Acquires a database lock with the given name. * * @since 1.2.5 * * @param string $lockName The name of the lock to acquire. * @param integer $timeout The timeout in seconds. Default is 0 which means it will return immediately if the lock cannot be acquired. * @return boolean Whether the lock was acquired. */ public function acquireLock( $lockName, $timeout = 0 ) { $lockResult = $this->db->get_var( $this->db->prepare( 'SELECT GET_LOCK(%s, %d)', $lockName, $timeout ) ); $acquired = '1' === $lockResult; if ( $acquired ) { // Register a shutdown function to always release the lock even if a fatal error occurs. register_shutdown_function( function () use ( $lockName ) { $this->releaseLock( $lockName ); } ); } return $acquired; } /** * Releases a database lock with the given name. * * @since 1.2.5 * * @param string $lockName The name of the lock to release. * @return boolean Whether the lock was released. */ public function releaseLock( $lockName ) { $releaseResult = $this->db->query( $this->db->prepare( 'SELECT RELEASE_LOCK(%s)', $lockName ) ); return false !== $releaseResult; } }