' . $expr . '~i', $request_uri ) ) { return false; } } return true; } /** * Checks for WordPress cookies. * * @return bool */ public function _check_cookies() { foreach ( array_keys( $_COOKIE ) as $cookie_name ) { if ( 'wordpress_test_cookie' === $cookie_name ) { continue; } if ( preg_match( '/^wp-postpass|^comment_author/', $cookie_name ) ) { return false; } } foreach ( $this->_config->get_array( 'dbcache.reject.cookie' ) as $reject_cookie ) { foreach ( array_keys( $_COOKIE ) as $cookie_name ) { if ( strstr( $cookie_name, $reject_cookie ) !== false ) { return false; } } } return true; } /** * Check if user is logged in. * * @return bool */ public function _check_logged_in() { foreach ( array_keys( $_COOKIE ) as $cookie_name ) { if ( strpos( $cookie_name, 'wordpress_logged_in' ) === 0 ) { return false; } } return true; } /** * Get group. * * @access private * * @param string $sql SQL query. * * @return string */ private function _get_group( $sql ) { $sql = strtolower( $sql ); // Collect list of tables used in query. if ( preg_match_all( '~(^|[\s,`])' . $this->wpdb_mixin->prefix . '([0-9a-zA-Z_]+)~i', $sql, $m ) ) { $tables = array_unique( $m[2] ); } else { $tables = array(); } if ( $this->contains_only_tables( $tables, array( 'options' => '*' ) ) ) { $group = 'options'; } elseif ( $this->contains_only_tables( $tables, array( 'comments' => '*', 'commentsmeta' => '*', ) ) ) { $group = 'comments'; } elseif ( count( $tables ) <= 1 ) { $group = 'singletables'; // Request with single table affected. } else { $group = 'remaining'; } if ( $this->use_filters && function_exists( 'apply_filters' ) ) { $group = apply_filters( 'w3tc_dbcache_get_sql_group', $group, $sql, $tables ); } return $group; } /** * Contains only tables. * * @accress private * * @param array $tables Tables. * * @param array $allowed Allowed. */ private function contains_only_tables( $tables, $allowed ) { if ( empty( $tables ) ) { return false; } foreach ( $tables as $t ) { if ( ! isset( $allowed[ $t ] ) ) { return false; } } return true; } /** * Get flush groups * * @access private * * @param string $group Group. * * @param array $extras Extra arguments. */ private function _get_flush_groups( $group, $extras = array() ) { $groups_to_flush = array(); switch ( $group ) { case 'remaining': case 'singletables': $groups_to_flush = array( 'remaining' => '*', 'options' => '*', 'comments' => '*', 'singletables' => '*', ); break; /** * Options are updated on each second request, * ignore by default probability that SELECTs with joins with options are critical and don't flush "remaining". * That can be changed by w3tc_dbcache_get_flush_groups filter. */ case 'options': $groups_to_flush = array( $group => '*' ); break; default: $groups_to_flush = array( $group => '*', 'remaining' => '*', ); } if ( $this->use_filters && function_exists( 'apply_filters' ) ) { $groups_to_flush = apply_filters( 'w3tc_dbcache_get_flush_groups', $groups_to_flush, $group, $extras ); } return $groups_to_flush; } /** * Get reject reason. * * @return string */ public function get_reject_reason() { if ( is_null( $this->cache_reject_reason ) ) { return ''; } $request_wide_string = $this->cache_reject_request_wide ? ( function_exists( '__' ) ? __( 'Request-wide ', 'w3-total-cache' ) : 'Request ' ) : ''; return $request_wide_string . $this->_get_reject_reason_message( $this->cache_reject_reason ); } /** * Get reject reason message. * * @param string $key Key. * * @return string|void */ private function _get_reject_reason_message( $key ) { if ( ! function_exists( '__' ) ) { return $key; } switch ( $key ) { case 'dbcache.disabled': return __( 'Database caching is disabled', 'w3-total-cache' ); case 'DONOTCACHEDB': return __( 'DONOTCACHEDB constant is defined', 'w3-total-cache' ); case 'DOING_AJAX': return __( 'Doing AJAX', 'w3-total-cache' ); case 'request': return __( 'Request URI is rejected', 'w3-total-cache' ); case 'cookie': return __( 'Cookie is rejected', 'w3-total-cache' ); case 'DOING_CRONG': return __( 'Doing cron', 'w3-total-cache' ); case 'APP_REQUEST': return __( 'Application request', 'w3-total-cache' ); case 'XMLRPC_REQUEST': return __( 'XMLRPC request', 'w3-total-cache' ); case 'WP_ADMIN': return __( 'wp-admin', 'w3-total-cache' ); case 'SHORTINIT': return __( 'Short init', 'w3-total-cache' ); case 'query': return __( 'Query is rejected', 'w3-total-cache' ); case 'user.logged_in': return __( 'User is logged in', 'w3-total-cache' ); default: return $key; } } /** * Footer comment. * * @param array $strings Strings. * * @return array */ public function w3tc_footer_comment( $strings ) { $reject_reason = $this->get_reject_reason(); $append = empty( $reject_reason ) ? '' : sprintf( ' (%1$s)', $reject_reason ); if ( $this->query_hits ) { $strings[] = sprintf( // translators: 1: Query hits, 2: Total queries, 3: Total time, 4: Engine name, 5: Reject reason. __( 'Database Caching %1$d/%2$d queries in %3$.3f seconds using %4$s%5$s', 'w3-total-cache' ), $this->query_hits, $this->query_total, $this->time_total, Cache::engine_name( $this->_config->get_string( 'dbcache.engine' ) ), $append ); } else { $strings[] = sprintf( // translators: 1: Engine name, 2: Reject reason. __( 'Database Caching using %1$s%2$s', 'w3-total-cache' ), Cache::engine_name( $this->_config->get_string( 'dbcache.engine' ) ), $append ); } if ( $this->debug ) { $strings[] = ''; $strings[] = __( 'Db cache debug info:', 'w3-total-cache' ); $strings[] = sprintf( '%1$s%2$d', str_pad( __( 'Total queries: ', 'w3-total-cache' ), 20 ), $this->query_total ); $strings[] = sprintf( '%1$s%2$d', str_pad( __( 'Cached queries: ', 'w3-total-cache' ), 20 ), $this->query_hits ); $strings[] = sprintf( '%1$s%2$.4f', str_pad( __( 'Total query time: ', 'w3-total-cache' ), 20 ), $this->time_total ); } if ( $this->log_filehandle ) { fclose( $this->log_filehandle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose $this->log_filehandle = false; } return $strings; } /** * Usage statistics of request. * * @param object $storage Storage object. * * @return void */ public function w3tc_usage_statistics_of_request( $storage ) { $storage->counter_add( 'dbcache_calls_total', $this->query_total ); $storage->counter_add( 'dbcache_calls_hits', $this->query_hits ); $storage->counter_add( 'dbcache_flushes', $this->cache_flushes ); $time_ms = (int) ( $this->time_total * 1000 ); $storage->counter_add( 'dbcache_time_ms', $time_ms ); } /** * Log query. * * @access private * * @param string $line Line to add. * * @return void */ private function log_query( $line ) { if ( ! $this->log_filehandle ) { $filename = Util_Debug::log_filename( 'dbcache-queries' ); $this->log_filehandle = fopen( $filename, 'a' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen } fputcsv( $this->log_filehandle, $line, "\t" ); } }