Created
February 19, 2011 00:37
-
-
Save wdolek/834678 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* CLI script to check whether php script paths correspond to class names. | |
* (Name Space File Name Checker) | |
* | |
* Naming of classes and file names should meet this standard proposal: | |
* http://groups.google.com/group/php-standards/web/psr-0-final-proposal | |
* | |
* Usage: | |
* php nsfnchecker.php /path/to/libs [<vendor name>] | |
* php nsfnchecker.php /home/wdolek/workspace/repos/nette Nette | |
* | |
* @author Zdenek Havlin aka wdolek | |
* @license "THE BEER-WARE LICENSE" | |
*/ | |
// check input | |
if (!isset ($argv[1])) { | |
exit (1); | |
} | |
/** | |
* @param string $fileName | |
* @return array | |
* @throws Exception | |
*/ | |
function getTokens($fileName) { | |
// check whether file exists | |
if (!file_exists($fileName)) { | |
throw new Exception('File not found'); | |
} | |
// tokens | |
$fileContent = file_get_contents($fileName); | |
$tokensAll = token_get_all($fileContent); | |
// filter for classes and interfaces | |
$classes = array(); | |
$validTokens = array( | |
T_CLASS, | |
T_INTERFACE, | |
T_NAMESPACE, | |
T_NS_SEPARATOR, | |
); | |
$_lastTokenType = null; | |
$_tokenCounter = -1; | |
foreach ($tokensAll as $token) { | |
// not token | |
if (!is_array($token)) { | |
continue; | |
} | |
$tokenType = $token[0]; | |
$tokenValue = $token[1]; | |
switch ($tokenType) { | |
case T_CLASS: | |
case T_INTERFACE: | |
case T_NAMESPACE: | |
++$_tokenCounter; | |
$classes[$_tokenCounter] = array( | |
$tokenType, | |
token_name($tokenType), | |
'', | |
); | |
$_lastTokenType = $tokenType; | |
break; | |
case T_NS_SEPARATOR: | |
if (in_array($_lastTokenType, array(T_CLASS, T_INTERFACE, T_NAMESPACE, T_STRING))) { | |
$_lastTokenType = $tokenType; | |
} | |
break; | |
case T_STRING: | |
if (!in_array($_lastTokenType, $validTokens) || !isset ($classes[$_tokenCounter][0]) || is_null($_lastTokenType)) { | |
continue; | |
} | |
if ($_lastTokenType == T_NS_SEPARATOR) { | |
$classes[$_tokenCounter][2] .= '\\' . $tokenValue; | |
} else { | |
$classes[$_tokenCounter][2] .= $tokenValue; | |
} | |
$_lastTokenType = $tokenType; | |
break; | |
default: | |
if (in_array($_lastTokenType, array(T_CLASS, T_INTERFACE, T_NAMESPACE))) { | |
continue; | |
} | |
$_lastTokenType = null; | |
break; | |
} | |
} | |
return $classes; | |
} | |
/** | |
* @param string $basePath base path of all files (/workspace/libs) | |
* @param string $tokenSourcePath path of file from (/workspace/libs/Nette/Utils/Foo.php) | |
* @param array $tokens | |
* @return array | |
*/ | |
function processTokens($basePath, $tokenSourcePath, array $tokens) { | |
// unify path | |
$basePath = str_replace('\\', '/', $basePath); | |
$tokenSourcePath = str_replace('\\', '/', $tokenSourcePath); | |
// trim slash | |
$basePath = trim($basePath, '/'); | |
$tokenSourcePath = trim($tokenSourcePath, '/'); | |
// remove base path | |
if (strpos($tokenSourcePath, $basePath) === 0) { | |
$tokenSourcePath = str_replace($basePath, '', $tokenSourcePath); | |
$tokenSourcePath = trim($tokenSourcePath, '/'); | |
} | |
// class name (file path/name implies class name) | |
$pathParts = explode('/', $tokenSourcePath); | |
$fileName =& $pathParts[count($pathParts) - 1]; | |
$fileName = str_replace('.php', '', $fileName); | |
$className = implode('\\', $pathParts); | |
// process | |
$result = array(); | |
$ns = null; | |
foreach ($tokens as $token) { | |
if ($token[0] == T_NAMESPACE) { | |
$ns = $token[2]; | |
continue; | |
} | |
// checked class name | |
$cn = empty ($ns) ? $token[2] : ($ns . '\\' . $token[2]); | |
if ($cn == $className) { | |
array_push($result, sprintf('[ok] "%s" in "%s"', | |
$cn, | |
$tokenSourcePath | |
)); | |
} else { | |
array_push($result, sprintf('[er] "%s" does not correspond to path "%s"', | |
$cn, | |
$tokenSourcePath | |
)); | |
} | |
} | |
return $result; | |
} | |
// tokenize | |
$basePath = $argv[1]; | |
$vendorName = isset ($argv[2]) ? $argv[2] : null; | |
$dir2check = new RecursiveDirectoryIterator($basePath . '/' . $vendorName); | |
$rdIterator = new RecursiveIteratorIterator($dir2check); | |
$reIterator = new RegexIterator($rdIterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); | |
$result = array(); | |
foreach ($reIterator as $i) { | |
$result = array_merge( | |
$result, | |
processTokens($basePath, $i[0], getTokens($i[0])) | |
); | |
} | |
foreach ($result as $rmsg) { | |
echo $rmsg, PHP_EOL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment