Last active
December 29, 2015 02:29
-
-
Save rogierslag/7600789 to your computer and use it in GitHub Desktop.
Finds the current PHP namespace and all `use` statements in a file
This file contains 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 | |
// Get all the files | |
$files = openAllFiles ( '/Users/Rogier/Desktop/Developer/nl.tudelft/FPtudelft/AWS/vendor', '' ); | |
// For each file start the replace operations | |
foreach ( $files as $fileLocation ) { | |
// The current namespaces | |
$uses = array (); | |
$namespacePrefix = ''; | |
// Read the file into an array | |
$fileArray = file ( $fileLocation ); | |
foreach ( $fileArray as $ln => $line ) { | |
// Remove comments from the line | |
$line = removeLineComment ( $line ); | |
// Read the namespace | |
if (empty ( $namespacePrefix )) { | |
$namespacePrefix = dealWithNamespace ( $line ); | |
if (! empty ( $namespacePrefix )) { | |
$fileArray [$ln] = ''; | |
continue; | |
} | |
} | |
// Read the use statement | |
$oldCount = count ( $uses ); | |
$uses = dealWithUseStatement ( $line, $uses ); | |
if (count ( $uses ) > $oldCount) { | |
$fileArray [$ln] = ''; | |
continue; | |
} | |
// Class contents | |
$line = dealWithClassDefinition ( $line, $uses, $namespacePrefix ); | |
$line = dealWithDynamicClassReference ( $line, $uses, $namespacePrefix ); | |
$line = dealWithStaticClassReference ( $line, $uses, $namespacePrefix ); | |
$line = dealWithException ( $line, $uses, $namespacePrefix ); | |
// Write the line back to the array | |
$fileArray [$ln] = $line; | |
} | |
// Write the resultant file back to disk | |
file_put_contents($fileLocation, implode ( "", $fileArray )); | |
} | |
/** | |
* List all the files in the directory recusrively | |
* @param string $startDir | |
* @param string $newDir | |
* @return Ambigous <multitype:string , multitype:> | |
*/ | |
function openAllFiles($startDir, $newDir) { | |
$currentDir = $startDir . "/" . $newDir; | |
$handle = scandir ( $currentDir ); | |
$allFiles = array (); | |
foreach ( $handle as &$entry ) { | |
if ($entry == "." or $entry == "..") | |
continue; | |
if (is_dir ( $currentDir . "/" . $entry )) { | |
$allFiles = array_merge ( openAllFiles ( $currentDir, $entry ), $allFiles ); | |
// echo "=========".$currentDir."=========\n"; | |
} else { | |
$parts = explode ( '.', $entry ); | |
if ($parts [1] == "php") { | |
$allFiles [] = $currentDir . '/' . $entry; | |
} | |
} | |
} | |
return $allFiles; | |
} | |
/** | |
* Find use statements in the line and adds them to the array | |
* @param string $line | |
* @param array $useArray | |
* @throws Exception if a name conflict arises | |
* @return array | |
*/ | |
function dealWithUseStatement($line, $useArray) { | |
$matches = array (); | |
preg_match_all ( "/use\s*([a-z0-9_\\\\]+)\s*(as\s*([a-z0-9_]*))?\s*\;/i", $line, $matches ); | |
if (! empty ( $matches [3] [0] )) { | |
// In this case we found a `use` statement with a rename `as` | |
if (isset ( $useArray [$matches [3] [0]] )) { | |
// Already exists, throw an exception | |
throw new Exception (); | |
} | |
$useArray [$matches [3] [0]] = str_replace ( '\\', '_', $matches [1] [0] ); | |
} else if (! empty ( $matches [1] [0] )) { | |
// In this case we have found a regular `use` statement | |
if (isset ( $useArray [$matches [1] [0]] )) { | |
// Already exists, throw an exception | |
throw new Exception (); | |
} | |
$className = substr ( $matches [1] [0], strrpos ( $matches [1] [0], '\\' ) + 1 ); | |
$useArray [$className] = str_replace ( '\\', '_', $matches [1] [0] ); | |
} | |
// Return the array (with or without a new rewrite) | |
return $useArray; | |
} | |
/** | |
* Find the current namespace and return it | |
* @param string $line | |
* @return string | |
*/ | |
function dealWithNamespace($line) { | |
preg_match_all ( "/namespace\s*([a-z0-9_\\\\]+)\s*\;/i", $line, $matches ); | |
if (! empty ( $matches [1] [0] )) { | |
return str_replace ( '\\', '_', $matches [1] [0] ) . '_'; | |
} | |
return ''; | |
} | |
/** | |
* rewrite the class definition | |
* @param string $line | |
* @param array $replacement | |
* @param string $namespace | |
* @return string | |
*/ | |
function dealWithClassDefinition($line, $replacement, $namespace) { | |
$matches = array (); | |
$c = preg_match_all ( '/^\s*class ([a-z0-9]+)\s*(extends ([a-z0-9]+))?\s*(implements ([a-z0-9]+(,\s?[a-z0-9]+)*))?/i', $line, $matches ); | |
if ($c > 0) { | |
$line = str_replace ( $matches [1] [0], $namespace . $matches [1] [0], $line ); | |
if (isset ( $matches [3] [0] )) { | |
if (! isset ( $replacements [$matches [3] [0]] )) { | |
$line = str_replace ( $matches [3] [0], $namespace . $matches [3] [0], $line ); | |
} else { | |
$line = str_replace ( $matches [3] [0], $replacements [$matches [3] [0]], $line ); | |
} | |
} | |
$interfaces = explode ( ',', $matches [5] [0] ); | |
if (count ( $interfaces ) > 0 && ! empty ( $interfaces [0] )) { | |
// By sorting on length we always obtain the most complete replacement | |
usort ( $interfaces, 'sortArrayByLength' ); | |
foreach ( $interfaces as $interface ) { | |
if (interface_exists ( $interface )) { | |
// PHP native interface, do not rewrite | |
continue; | |
} | |
$line = str_replace ( $interface, $replacement [$interface], $line ); | |
} | |
} | |
} | |
return $line; | |
} | |
/** | |
* rewrite class instantiations | |
* @param unknown $line | |
* @param unknown $replacements | |
* @param unknown $namespace | |
* @return mixed | |
*/ | |
function dealWithDynamicClassReference($line, $replacements, $namespace) { | |
// Check for new instantiations | |
$matches = array (); | |
$c = preg_match_all ( '/\s*new\s+([a-z0-9_]+)/i', $line, $matches ); | |
if ($c > 0) { | |
if (! isset ( $replacements [$matches [1] [0]] )) { | |
$line = str_replace ( $matches [1] [0], $namespace . $matches [1] [0], $line ); | |
} else { | |
$line = str_replace ( $matches [1] [0], $replacements [$matches [1] [0]], $line ); | |
} | |
} | |
return $line; | |
} | |
/** | |
* Rewrite class references | |
* @param unknown $line | |
* @param unknown $replacements | |
* @param unknown $namespace | |
* @return mixed | |
*/ | |
function dealWithStaticClassReference($line, $replacements, $namespace) { | |
// Check for new instantiations | |
$matches = array (); | |
$c = preg_match_all ( '/\s*([a-z0-9_]+)\s*::/i', $line, $matches ); | |
if ($c > 0) { | |
if (! isset ( $replacements [$matches [1] [0]] )) { | |
$line = str_replace ( $matches [1] [0], $namespace . $matches [1] [0], $line ); | |
} else { | |
$line = str_replace ( $matches [1] [0], $replacements [$matches [1] [0]], $line ); | |
} | |
} | |
return $line; | |
} | |
/** | |
* rewrite exceptions | |
* @param unknown $line | |
* @param unknown $replacements | |
* @param unknown $namespace | |
* @return mixed | |
*/ | |
function dealWithException($line, $replacements, $namespace) { | |
$matches = array (); | |
$c = preg_match_all ( '/catch\s*\(\s*([a-z0-9_]+)/i', $line, $matches ); | |
if ($c > 0) { | |
$exceptionKnown = class_exists ( $matches [1] [0] ); | |
if (! $exceptionKnown) { | |
// Do not rewrite native PHP exceptions | |
if (! isset ( $replacements [$matches [1] [0]] )) { | |
$line = str_replace ( $matches [1] [0], $namespace . $matches [1] [0], $line ); | |
} else { | |
$line = str_replace ( $matches [1] [0], $replacements [$matches [1] [0]], $line ); | |
} | |
} | |
} | |
return $line; | |
} | |
/** | |
* Remove line comments | |
* @param unknown $line | |
* @return unknown|string | |
*/ | |
function removeLineComment($line) { | |
$commentStart = strpos ( $line, '//' ); | |
if ($commentStart === FALSE) { | |
return $line; | |
} else { | |
return substr ( $line, 0, $commentStart ); | |
} | |
} | |
/** | |
* Sort a array by the length of the elements | |
* @param unknown $a | |
* @param unknown $b | |
* @return number | |
*/ | |
function sortArrayByLength($a, $b) { | |
return strlen ( $b ) - strlen ( $a ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment