Chris@0: 'the "redirect.destination" service', Chris@0: 'drupal_render' => 'the "renderer" service', Chris@0: 'entity_load' => 'the "entity_type.manager" service', Chris@0: 'file_load' => 'the "entity_type.manager" service', Chris@0: 'format_date' => 'the "date.formatter" service', Chris@0: 'node_load' => 'the "entity_type.manager" service', Chris@17: 'node_load_multiple' => 'the "entity_type.manager" service', Chris@0: 'node_type_load' => 'the "entity_type.manager" service', Chris@0: 't' => '$this->t()', Chris@0: 'taxonomy_term_load' => 'the "entity_type.manager" service', Chris@0: 'taxonomy_vocabulary_load' => 'the "entity_type.manager" service', Chris@0: 'user_load' => 'the "entity_type.manager" service', Chris@0: 'user_role_load' => 'the "entity_type.manager" service', Chris@0: ); Chris@0: Chris@0: Chris@0: /** Chris@0: * Returns an array of tokens this test wants to listen for. Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: public function register() Chris@0: { Chris@0: return array(T_STRING); Chris@0: Chris@0: }//end register() Chris@0: Chris@0: Chris@0: /** Chris@0: * Processes this test, when one of its tokens is encountered. Chris@0: * Chris@17: * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. Chris@17: * @param int $stackPtr The position of the current token Chris@17: * in the stack passed in $tokens. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@17: public function process(File $phpcsFile, $stackPtr) Chris@0: { Chris@0: $tokens = $phpcsFile->getTokens(); Chris@0: Chris@0: // We are only interested in function calls, which are not in the global Chris@0: // scope. Chris@0: if (isset($this->functions[$tokens[$stackPtr]['content']]) === false Chris@0: || isset($tokens[($stackPtr + 1)]) === false Chris@0: || $tokens[($stackPtr + 1)]['code'] !== T_OPEN_PARENTHESIS Chris@0: || empty($tokens[$stackPtr]['conditions']) === true Chris@0: ) { Chris@0: return; Chris@0: } Chris@0: Chris@0: // If there is an object operator before the call then this is a method Chris@0: // invocation, not a function call. Chris@0: $previous = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); Chris@0: if ($tokens[$previous]['code'] === T_OBJECT_OPERATOR) { Chris@0: return; Chris@0: } Chris@0: Chris@0: // Check that this statement is not in a static function. Chris@0: foreach ($tokens[$stackPtr]['conditions'] as $conditionPtr => $conditionCode) { Chris@0: if ($conditionCode === T_FUNCTION && $phpcsFile->getMethodProperties($conditionPtr)['is_static'] === true) { Chris@0: return; Chris@0: } Chris@0: } Chris@0: Chris@0: // Check if the class extends another class and get the name of the class Chris@0: // that is extended. Chris@0: $classPtr = key($tokens[$stackPtr]['conditions']); Chris@0: $extendsName = $phpcsFile->findExtendedClassName($classPtr); Chris@0: Chris@0: if (($extendsName === false Chris@17: || in_array($extendsName, GlobalDrupalSniff::$baseClasses) === false) Chris@17: && Project::isServiceClass($phpcsFile, $classPtr) === false Chris@0: ) { Chris@0: return; Chris@0: } Chris@0: Chris@0: $warning = '%s() calls should be avoided in classes, use dependency injection and %s instead'; Chris@0: $data = array( Chris@0: $tokens[$stackPtr]['content'], Chris@0: $this->functions[$tokens[$stackPtr]['content']], Chris@0: ); Chris@0: $phpcsFile->addWarning($warning, $stackPtr, 'GlobalFunction', $data); Chris@0: Chris@0: }//end process() Chris@0: Chris@0: Chris@0: }//end class