|
|
@@ -0,0 +1,195 @@ |
|
|
<?php |
|
|
/** |
|
|
* Super-simple script to convert a existing project to use namespaces |
|
|
* |
|
|
* @author Hans-Peter Buniat <[email protected]> |
|
|
* @copyright 2012 Hans-Peter Buniat <[email protected]> |
|
|
* @license http://opensource.org/licenses/BSD-3-Clause |
|
|
*/ |
|
|
class namespaceRefactor { |
|
|
|
|
|
/** |
|
|
* The found files |
|
|
* |
|
|
* @var array |
|
|
*/ |
|
|
protected $_aFiles = array(); |
|
|
|
|
|
/** |
|
|
* The found classes |
|
|
* |
|
|
* @var array |
|
|
*/ |
|
|
protected $_aClasses = array(); |
|
|
|
|
|
/** |
|
|
* Write the results to the file or just dump the changes |
|
|
* |
|
|
* @var bool |
|
|
*/ |
|
|
protected $_bWrite = false; |
|
|
|
|
|
/** |
|
|
* The directory where we're looking for files |
|
|
* |
|
|
* @var string |
|
|
*/ |
|
|
protected $_sDirectory = ''; |
|
|
|
|
|
/** |
|
|
* An optional prefix |
|
|
* |
|
|
* @var string |
|
|
*/ |
|
|
protected $_sPrefix; |
|
|
|
|
|
/** |
|
|
* Create |
|
|
* |
|
|
* @param array $aOpts |
|
|
*/ |
|
|
public function __construct(array $aOpts) { |
|
|
$this->_sDirectory = $aOpts['d']; |
|
|
$this->_sPrefix = $aOpts['p']; |
|
|
if ($aOpts['w'] === 'true') { |
|
|
$this->_bWrite = true; |
|
|
} |
|
|
} |
|
|
|
|
|
/** |
|
|
* Get all php-files from the given directory |
|
|
* |
|
|
* @return namespaceRefactor |
|
|
*/ |
|
|
public function getFiles() { |
|
|
$oIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->_sDirectory)); |
|
|
$aSuffixes = array( |
|
|
'php' |
|
|
); |
|
|
|
|
|
$sRegex = '/^.+\.(' . implode('|', $aSuffixes) . ')$/i'; |
|
|
$oFiles = new RegexIterator($oIterator, $sRegex, RecursiveRegexIterator::GET_MATCH); |
|
|
$this->_aFiles = array(); |
|
|
foreach($oFiles as $aFile) { |
|
|
$this->_aFiles[] = $aFile[0]; |
|
|
} |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Parse all files and find class-declarations |
|
|
* - If a file does contain a namespace declaration, the class-declaration should not be converted |
|
|
* |
|
|
* @return namespaceRefactor |
|
|
*/ |
|
|
public function readClasses() { |
|
|
$aFiles = array(); |
|
|
foreach ($this->_aFiles as $sFile) { |
|
|
$aFiles[$sFile] = array(); |
|
|
$aTokens = token_get_all(file_get_contents($sFile)); |
|
|
|
|
|
$aFound = array(); |
|
|
$bLocked = $bClassFound = false; |
|
|
foreach ($aTokens as $aToken) { |
|
|
$sType = is_array($aToken) ? $aToken[0] : null; |
|
|
$sData = (string) (is_array($aToken) ? $aToken[1] : $aToken); |
|
|
|
|
|
if ($bLocked === false and $bClassFound === true and $sType === T_STRING) { |
|
|
$this->_aClasses[$sData] = $sData; |
|
|
$aFound[] = $sData; |
|
|
$aFiles[$sFile] = $sData; |
|
|
$bClassFound = false; |
|
|
} |
|
|
|
|
|
if ($sType === T_CLASS) { |
|
|
$bClassFound = true; |
|
|
} |
|
|
|
|
|
// ensure, that classes which are already namespaced are not replaced again |
|
|
if ($sType === T_NAMESPACE) { |
|
|
$bLocked = true; |
|
|
foreach ($aFound as $sFoundClass) { |
|
|
if (empty($this->_aClasses[$sFoundClass]) !== true) { |
|
|
unset($this->_aClasses[$sFoundClass]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
$this->_aFiles = $aFiles; |
|
|
return $this; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Create the new namespace class for all found classes |
|
|
* |
|
|
* @return namespaceRefactor |
|
|
*/ |
|
|
public function getNamespaces() { |
|
|
$aClasses = array(); |
|
|
foreach ($this->_aClasses as $sClass) { |
|
|
$aClass = explode('_', $sClass); |
|
|
if (count($aClass) > 1 or empty($this->_sPrefix) !== true) { |
|
|
$sNewClass = array_pop($aClass); |
|
|
$sNamespace = (count($aClass) > 1) ? sprintf('\%s', implode('\\', $aClass)): ''; |
|
|
$aClasses[$sClass] = array( |
|
|
'class' => $sNewClass, |
|
|
'namespace' => $sNamespace |
|
|
); |
|
|
|
|
|
if (empty($this->_sPrefix) !== true) { |
|
|
$aClasses[$sClass]['namespace'] = sprintf('\%s%s', $this->_sPrefix, $aClasses[$sClass]['namespace']); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
$this->_aClasses = $aClasses; |
|
|
return $this; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Replace the declarations |
|
|
* |
|
|
* @return void |
|
|
*/ |
|
|
public function replace() { |
|
|
foreach ($this->_aFiles as $sFile => $sClass) { |
|
|
$sContent = file_get_contents($sFile); |
|
|
$sCompare = $sContent; |
|
|
if (empty($sClass) !== true and empty($this->_aClasses[$sClass]) !== true) { |
|
|
$aContent = explode(' */', $sContent); |
|
|
$aContent[1] = sprintf('%snamespace %s;%s%s',PHP_EOL, substr($this->_aClasses[$sClass]['namespace'], 1), PHP_EOL, $aContent[1]); |
|
|
$sContent = implode(' */', $aContent); |
|
|
} |
|
|
|
|
|
foreach ($this->_aClasses as $sFindClass => $aReplace) { |
|
|
$sReplace = ($sClass === $sFindClass) ? $aReplace['class'] : sprintf('%s\%s', $aReplace['namespace'], $aReplace['class']); |
|
|
$sContent = str_replace($sFindClass, $sReplace, $sContent); |
|
|
} |
|
|
|
|
|
if ($sCompare !== $sContent) { |
|
|
if ($this->_bWrite === true) { |
|
|
file_put_contents($sFile, $sContent); |
|
|
} |
|
|
else { |
|
|
print_r(sprintf('%s:%s%s', $sFile, PHP_EOL, $sContent)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
$aOpts = getopt('d:w:p:'); |
|
|
if (empty($aOpts['d']) === true) { |
|
|
print_r('usage: ' . $argv[0] . ' -p prefix -d directory -w [false|true]' . PHP_EOL); |
|
|
exit; |
|
|
} |
|
|
|
|
|
if (empty($aOpts['w']) === true) { |
|
|
$aOpts['w'] = 'false'; |
|
|
} |
|
|
|
|
|
$o = new namespaceRefactor($aOpts); |
|
|
$o->getFiles()->readClasses()->getNamespaces()->replace(); |