*/ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff { /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array(T_OPEN_TAG); } /** * 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 null */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { // We are only interested in the first file comment. if ($stackPtr !== 0) { if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) { return; } } // Fetch next non whitespace token $tokens = $phpcsFile->getTokens(); $start = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); // Skip empty files if ($tokens[$start]['code'] === T_CLOSE_TAG) { return; } // Mark as error if this is not a doc comment else if ($start === false || $tokens[$start]['code'] !== T_DOC_COMMENT) { $phpcsFile->addError('Missing required file doc comment.', $stackPtr); return; } // Find comment end token $end = $phpcsFile->findNext(T_DOC_COMMENT, $start + 1, null, true) - 1; // If there is no end, skip processing here if ($end === false) { return; } // List of found comment tags $tags = array(); // check comment lines without the first(/**) an last(*/) line for ($i = $start + 1, $c = ($end - $start); $i <= $c; ++$i) { $line = $tokens[$i]['content']; // Check that each line starts with a '*' if (substr($line, 0, 1) !== '*') { $message = 'The file doc comment should not be idented.'; $phpcsFile->addWarning($message, $i); } else if (preg_match('/^\*\s+@([\w]+)\s+(.*)$/', $line, $match) !== 0) { $tags[$match[1]] = array($match[2], $i); } } // Check that the first and last line is empty if (trim($tokens[$start + 1]['content']) !== '*') { $message = 'The first file comment line should be empty.'; $phpcsFile->addWarning($message, ($start + 1)); } if (trim($tokens[$end - $start]['content']) !== '*') { $message = 'The last file comment line should be empty.'; $phpcsFile->addWarning($message, ($end - $start)); } $this->processPackage($phpcsFile, $start, $tags); $this->processVersion($phpcsFile, $start, $tags); $this->processCopyright($phpcsFile, $start, $tags); $this->processLicense($phpcsFile, $start, $tags); //print_r($tags); } /** * Checks that the tags array contains a valid package tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processPackage(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { if (!isset($tags['package'])) { $message = 'Missing require @package tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (preg_match('/^([\w]+)$/', $tags['package'][0]) === 0) { $message = 'Invalid content found for @package tag.'; $phpcsFile->addWarning($message, $tags['package'][1]); } } /** * Checks that the tags array contains a valid version tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processVersion(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { if (!isset($tags['version'])) { $message = 'Missing require @version tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (preg_match('/^\$Id:[^\$]+\$$/', $tags['version'][0]) === 0) { $message = 'Invalid content found for @version tag, use "$Id: $".'; $phpcsFile->addError($message, $tags['version'][1]); } } /** * Checks that the tags array contains a valid copyright tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processCopyright(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { if (!isset($tags['copyright'])) { $message = 'Missing require @copyright tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (preg_match('/^\(c\) 2[0-9]{3} phpBB Group\s*$/', $tags['copyright'][0]) === 0) { $message = 'Invalid content found for @copyright tag, use "(c) phpBB Group".'; $phpcsFile->addError($message, $tags['copyright'][1]); } } /** * Checks that the tags array contains a valid license tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { $license = 'http://opensource.org/licenses/gpl-license.php GNU Public License'; if (!isset($tags['license'])) { $message = 'Missing require @license tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (trim($tags['license'][0]) !== $license) { $message = 'Invalid content found for @license tag, use ' . '"' . $license . '".'; $phpcsFile->addError($message, $tags['license'][1]); } } }