getTokens(); if (! in_array($tokens[$stackPtr]['content'], $this->hooks)) { return; } $previous_comment = $phpcsFile->findPrevious(Tokens::$commentTokens, ( $stackPtr - 1 )); if (false !== $previous_comment) { $correctly_placed = false; if (( $tokens[ $previous_comment ]['line'] + 1 ) === $tokens[ $stackPtr ]['line']) { $correctly_placed = true; } if (true === $correctly_placed) { if (\T_COMMENT === $tokens[ $previous_comment ]['code']) { $phpcsFile->addError( 'A "hook" comment must be a "/**" style docblock comment.', $stackPtr, 'HookCommentWrongStyle' ); return; } elseif (\T_DOC_COMMENT_CLOSE_TAG === $tokens[ $previous_comment ]['code']) { $comment_start = $phpcsFile->findPrevious(\T_DOC_COMMENT_OPEN_TAG, ( $previous_comment - 1 )); // Iterate through each comment to check for "@since" tag. foreach ($tokens[ $comment_start ]['comment_tags'] as $tag) { if ($tokens[$tag]['content'] === '@since') { return; } } $phpcsFile->addError( 'Docblock comment was found for the hook but does not contain a "@since" versioning.', $stackPtr, 'MissingSinceComment' ); return; } } } // Found hook but no docblock comment. $phpcsFile->addError( 'A hook was found, but was not accompanied by a docblock comment on the line above to clarify the meaning of the hook.', $stackPtr, 'MissingHookComment' ); return; } }