Skip to content

Instantly share code, notes, and snippets.

@lilianalillyy
Last active April 20, 2023 11:19
Show Gist options
  • Save lilianalillyy/ee8de66b416fd1d680c58eba3f641d15 to your computer and use it in GitHub Desktop.
Save lilianalillyy/ee8de66b416fd1d680c58eba3f641d15 to your computer and use it in GitHub Desktop.
ublaboo->contributte
<?php declare(strict_types=1);
require __DIR__ . "/vendor/autoload.php";
const BaseOldNamespace = "Ublaboo\\DataGrid";
const BaseNewNamespace = "Contributte\\Datagrid";
const Replace = true;
const Test = false;
// ------------
const OldNamespace = BaseOldNamespace . (Test ? "\\Tests" : "");
const NewNamespace = BaseNewNamespace . (Test ? "\\Tests" : "");
$base = __DIR__ . (Test ? "/tests" : "/src");
function _join(array $values): string {
return implode("\\", $values);
}
function _split(string $value): array {
return explode("\\", $value);
}
function _fixCasing(string $value): string {
return str_replace("DataGrid", "Datagrid", $value);
}
function _trim(string $path): string
{
return substr($path, str_starts_with($path, "\\") ? 1 : 0, str_ends_with($path, "\\") ? -1 : strlen($path));
}
function _put(string $path, string $data): void
{
if (!file_exists($path)) {
$parent = implode(DIRECTORY_SEPARATOR, array_slice(explode(DIRECTORY_SEPARATOR, $path), 0, -1));
if (!file_exists($parent)) {
mkdir($parent, recursive: true);
}
}
file_put_contents($path, $data);
}
function convertPathToPsr4(string $filePath, string $base): string
{
$path = str_replace(".php", "", str_replace(DIRECTORY_SEPARATOR, "\\", str_replace($base . DIRECTORY_SEPARATOR, "", $filePath)));
return _trim($path);
}
class ClassDef
{
public string $oldClassName;
public string $newClassName;
public string $oldNamespace;
public string $newNamespace;
public string $newClass;
public bool $isFinalClass;
public bool $isAbstractClass;
public bool $isTrait;
public bool $isEnum;
public bool $isInterface;
public bool $isOldDataGridClass;
public function __construct(
public string $oldClass,
public string $oldContent,
public string $filePath,
)
{
$this->oldNamespace = _join(array_slice($oldSplit = _split($this->oldClass), 0, -1));
$this->oldClassName = $oldSplit[array_key_last($oldSplit)];
$this->newNamespace = _join(array_merge(_split(NewNamespace), array_slice($oldSplit, 2, count($oldSplit))));
$this->newClassName = _fixCasing($this->oldClassName);
$this->newClass = join([$this->newNamespace, $this->newClassName]);
$this->isOldDataGridClass = $this->oldNamespace === OldNamespace && $this->oldClassName === "DataGrid";
$this->isFinalClass = str_contains($oldContent, "final class $this->oldClassName");
$this->isAbstractClass = str_contains($oldContent, "abstract class $this->oldClassName");
$this->isTrait = str_contains($oldContent, "trait $this->oldClassName");
$this->isEnum = str_contains($oldContent, "enum $this->oldClassName");
$this->isInterface = str_contains($oldContent, "interface $this->oldClassName");
}
}
/**
* @param iterable $paths
* @return array<string, ClassDef[]>
* @throws Exception
*/
function createClassDefMap(iterable $paths, string $base): array
{
/** @var array<string, ClassDef[]> $map */
$map = [];
foreach ($paths as $path) {
$path = $path instanceof SplFileInfo ? $path->getPathname() : $path;
if (!str_ends_with($path, ".php") && !str_ends_with($path, ".phpt")) continue;
$content = file_get_contents($path);
if ($content === false) {
throw new Exception("Failed to read '$path'");
}
$oldClass = _trim(_join([OldNamespace, convertPathToPsr4($path, $base)]));
$map[$ns = _join(array_slice(_split($oldClass), 0, -1))] = array_merge($map[$ns] ?? [], [new ClassDef($oldClass, $content, $path)]);
}
return $map;
}
// fix dirs first
function fixNames(string $base) {
foreach (scandir($base) as $dir) {
if ($dir === "." || $dir === "..") continue;
$path = implode(DIRECTORY_SEPARATOR, [$base, $dir]);
$newPath = _fixCasing($path);
if ($path !== $newPath) {
exec("mv $path $newPath");
}
if (is_dir($newPath)) {
fixNames($newPath);
}
}
}
$paths = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($base), RecursiveIteratorIterator::SELF_FIRST);
$map = createClassDefMap($paths, $base);
$result = [
"<?php declare(strict_types=1);",
];
foreach ($map as $oldNamespace => $defs) {
$classLines = [];
$elseIfLines = [];
$datagrid = [];
foreach ($defs as $def) {
$classLines[] = " /** @deprecated Moved to {@see \\$def->newClass} */";
if ($def->isFinalClass) {
$classLines[] = " final class $def->oldClassName {} // cannot extend a final class";
} elseif ($def->isTrait) {
$classLines[] = " trait $def->oldClassName { use $def->newClass; }";
} elseif ($def->isEnum) {
$classLines[] = " enum $def->oldClassName {} // cannot extend an enum";
} else {
$classLines[] = " " . ($def->isAbstractClass ? "abstract " : "") . ($def->isInterface ? "interface" : "class") . " $def->oldClassName extends \\$def->newClass {}";
}
$elseIfLines[] = "if (!class_exists('$def->oldClass')) {";
$elseIfLines[] = " class_alias('$def->newClass', '$def->oldClass');";
$elseIfLines[] = "}";
if (Replace) {
$newContent = str_replace(OldNamespace, NewNamespace, $def->oldContent);
$newContent = _fixCasing($newContent);
// Contributte\Datagrid\DataGrid BC support
if (!Test && $def->isOldDataGridClass) {
$datagrid = [
"",
"namespace $def->newNamespace;",
"",
"if (false) {",
" class DataGrid extends \\$oldNamespace\\DataGrid {} // Case insensitivity ergo contributte NS doesnt work (class cant extend itself)",
"} elseif (!class_exists('$def->newNamespace\\Datagrid')) {",
" class_alias('$oldNamespace\\DataGrid', '$def->newNamespace\\Datagrid');",
"}"
];
}
_put($def->filePath, $newContent);
}
}
$result = array_merge($result, [
"",
"namespace $oldNamespace;",
"",
"if (false) {",
...$classLines,
"}",
...$elseIfLines,
...$datagrid,
]);
}
if (Replace) {
fixNames($base);
}
echo implode("\n", $result);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment