Skip to content

Instantly share code, notes, and snippets.

@tomasnorre
Forked from hpbuniat/namespaceRefactor.php
Created February 18, 2016 12:36
Show Gist options
  • Save tomasnorre/fa894fb4967fabb7dbe3 to your computer and use it in GitHub Desktop.
Save tomasnorre/fa894fb4967fabb7dbe3 to your computer and use it in GitHub Desktop.
Super-simple script to convert a existing project to use namespaces
<?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 or $sType === T_INTERFACE) {
$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) {
$iLenght = strlen($this->_sPrefix);
if (substr($aClasses[$sClass]['namespace'], 1, $iLenght) !== $this->_sPrefix) {
$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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment