Skip to content

Instantly share code, notes, and snippets.

@TiMESPLiNTER
Last active March 24, 2017 06:41
Show Gist options
  • Select an option

  • Save TiMESPLiNTER/75958e0e0f7bbbfb0cf7923e1fd0d863 to your computer and use it in GitHub Desktop.

Select an option

Save TiMESPLiNTER/75958e0e0f7bbbfb0cf7923e1fd0d863 to your computer and use it in GitHub Desktop.
Automatic mud object creation
<?php
namespace MudObjectCreator;
use JMS\Serializer\SerializerInterface;
use PhpParser\Error;
use PhpParser\NodeTraverser;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class MudObjectCreator
{
public static function createRealObjectFromMudObject($mudObject, array $constructorMap = [])
{
$mudClass = get_class($mudObject);
$originalClass = preg_replace('/Mud$/', null, $mudClass);
$refClass = new \ReflectionClass($originalClass);
$constructor = $refClass->getMethod('__construct');
$args = [];
$alreadySet = [];
foreach ($constructor->getParameters() as $param) {
$alreadySet[] = $paramName = $param->name;
$args[] = $mudObject->$paramName;
}
$object = $refClass->newInstanceArgs($args);
foreach ($refClass->getProperties() as $property) {
$propertyName = $property->name;
if (true === in_array($propertyName, $alreadySet, true)) {
continue;
}
$property->setAccessible(true);
$property->setValue($object, $mudObject->$propertyName);
}
return $object;
}
public static function createMudClassFromOriginalClass(string $class): string
{
$reflector = new \ReflectionClass($class);
$classFile = $reflector->getFileName();
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
$prettyPrinter = new Standard();
$traverser = new NodeTraverser();
$traverser->addVisitor(new NodeVisitor());
try {
$stmts = $parser->parse(file_get_contents($classFile));
$mudClassName = $class . 'Mud';
$mudClassFile = __DIR__.'/' . strtr($mudClassName, ['\\' => '_']) .'.php';
echo($mudClassName);
// traverse
$stmts = $traverser->traverse($stmts);
$code = $prettyPrinter->prettyPrint($stmts);
file_put_contents($mudClassFile, "<?php\n".$code);
require_once $mudClassFile;
return $mudClassName;
} catch (Error $e) {
echo 'Parse Error: ', $e->getMessage();
}
}
}
<?php
namespace MudObjectCreator;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
class NodeVisitor extends NodeVisitorAbstract
{
public function leaveNode(Node $node) {
if ($node instanceof Node\Stmt\Property) {
$node->flags = Node\Stmt\Class_::MODIFIER_PUBLIC;
} elseif ($node instanceof Node\Stmt\Class_) {
$node->name = $node->name.'Mud';
} elseif ($node instanceof Node\Stmt\ClassMethod) {
$nullNode = new Node\Expr\ConstFetch(new Node\Name('null'));
foreach ($node->params as $param) {
if ($node->name === '__construct') {
$param->default = $nullNode;
}
$param->type = null;
}
$node->returnType = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment