/**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return int|void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     if (!isset(self::$methods['all'])) {
         self::$methods['all'] = array_merge(self::$methods['cachable'], self::$methods['noncachable']);
         WordPress_Sniff::$cacheGetFunctions = array_merge(WordPress_Sniff::$cacheGetFunctions, array_flip($this->customCacheGetFunctions));
         WordPress_Sniff::$cacheSetFunctions = array_merge(WordPress_Sniff::$cacheSetFunctions, array_flip($this->customCacheSetFunctions));
         WordPress_Sniff::$cacheDeleteFunctions = array_merge(WordPress_Sniff::$cacheDeleteFunctions, array_flip($this->customCacheDeleteFunctions));
     }
     $tokens = $phpcsFile->getTokens();
     // Check for $wpdb variable
     if ($tokens[$stackPtr]['content'] != '$wpdb') {
         return;
     }
     $is_object_call = $phpcsFile->findNext(array(T_OBJECT_OPERATOR), $stackPtr + 1, null, null, null, true);
     if (false == $is_object_call) {
         return;
     }
     // This is not a call to the wpdb object
     $methodPtr = $phpcsFile->findNext(array(T_WHITESPACE), $is_object_call + 1, null, true, null, true);
     $method = $tokens[$methodPtr]['content'];
     if (!isset(self::$methods['all'][$method])) {
         return;
     }
     $endOfStatement = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr + 1, null, null, null, true);
     $endOfLineComment = '';
     for ($i = $endOfStatement + 1; $i < count($tokens); $i++) {
         if ($tokens[$i]['line'] !== $tokens[$endOfStatement]['line']) {
             break;
         }
         if ($tokens[$i]['code'] === T_COMMENT) {
             $endOfLineComment .= $tokens[$i]['content'];
         }
     }
     $whitelisted_db_call = false;
     if (preg_match('/db call\\W*(ok|pass|clear|whitelist)/i', $endOfLineComment, $matches)) {
         $whitelisted_db_call = true;
     }
     // Check for Database Schema Changes
     $_pos = $stackPtr;
     while ($_pos = $phpcsFile->findNext(array(T_CONSTANT_ENCAPSED_STRING, T_DOUBLE_QUOTED_STRING), $_pos + 1, $endOfStatement, null, null, true)) {
         if (preg_match('#\\b(ALTER|CREATE|DROP)\\b#i', $tokens[$_pos]['content'], $matches) > 0) {
             $phpcsFile->addError('Attempting a database schema change is highly discouraged.', $_pos, 'SchemaChange');
         }
     }
     // Flag instance if not whitelisted
     if (!$whitelisted_db_call) {
         $phpcsFile->addWarning('Usage of a direct database call is discouraged.', $stackPtr, 'DirectQuery');
     }
     if (!isset(self::$methods['cachable'][$method])) {
         return $endOfStatement;
     }
     $whitelisted_cache = false;
     $cached = $wp_cache_get = false;
     if (preg_match('/cache\\s+(ok|pass|clear|whitelist)/i', $endOfLineComment, $matches)) {
         $whitelisted_cache = true;
     }
     if (!$whitelisted_cache && !empty($tokens[$stackPtr]['conditions'])) {
         $scope_function = $phpcsFile->getCondition($stackPtr, T_FUNCTION);
         if ($scope_function) {
             $scopeStart = $tokens[$scope_function]['scope_opener'];
             $scopeEnd = $tokens[$scope_function]['scope_closer'];
             for ($i = $scopeStart + 1; $i < $scopeEnd; $i++) {
                 if (T_STRING === $tokens[$i]['code']) {
                     if (isset(WordPress_Sniff::$cacheDeleteFunctions[$tokens[$i]['content']])) {
                         if (in_array($method, array('query', 'update', 'replace', 'delete'))) {
                             $cached = true;
                             break;
                         }
                     } elseif (isset(WordPress_Sniff::$cacheGetFunctions[$tokens[$i]['content']])) {
                         $wp_cache_get = true;
                     } elseif (isset(WordPress_Sniff::$cacheSetFunctions[$tokens[$i]['content']])) {
                         if ($wp_cache_get) {
                             $cached = true;
                             break;
                         }
                     }
                 }
             }
         }
     }
     if (!$cached && !$whitelisted_cache) {
         $message = 'Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set or wp_cache_delete.';
         $phpcsFile->addError($message, $stackPtr, 'NoCaching');
     }
     return $endOfStatement;
 }