Skip to content

Instantly share code, notes, and snippets.

@rogierslag
Last active December 29, 2015 02:29
Show Gist options
  • Save rogierslag/7600789 to your computer and use it in GitHub Desktop.
Save rogierslag/7600789 to your computer and use it in GitHub Desktop.
Finds the current PHP namespace and all `use` statements in a file
<?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