Created
March 7, 2010 19:47
-
-
Save claussni/324594 to your computer and use it in GitHub Desktop.
Annotations and code generation
This file contains hidden or 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 | |
// set include path to library | |
set_include_path(implode(PATH_SEPARATOR, array( | |
'/opt/ZendFramework-1.10.1/library', | |
get_include_path(), | |
dirname(__FILE__) | |
))); | |
require_once 'Zend/Loader/Autoloader.php'; | |
$autoloader = Zend_Loader_Autoloader::getInstance(); | |
interface IJsonEncodeable { | |
public function getJsonString(); | |
} | |
class JsonEncodeable implements IJsonEncodeable { | |
public function getJsonString() { | |
return json_encode($this); | |
} | |
} | |
class HelloWorld { | |
public function sayHello($to) { | |
echo "Hello, $to!\n"; | |
} | |
} | |
function stripUnderscores($string) { | |
return preg_replace('/^(_)*/', '', $string); | |
} | |
function getTypeCheckCode($propertyName, $propertyType) { | |
$typecheck = ''; | |
if (null !== $propertyType) { | |
switch ($propertyType) { | |
case 'string' : | |
$typecheck = "if (! is_string(\$$propertyName)) " . | |
"throw InvalidArgumentException('Expected given value to be of type string.');\n"; | |
break; | |
case 'int' : | |
$typecheck = "if (! is_int(\$$propertyName)) " . | |
"throw InvalidArgumentException('Expected given value to be of type int.');\n"; | |
break; | |
case 'array' : | |
$typecheck = "if (! is_array(\$$propertyName)) " . | |
"throw InvalidArgumentException('Expected given value to be of type array.');\n"; | |
break; | |
default: | |
break; | |
} | |
} | |
return $typecheck; | |
} | |
function getSetterCode($setterName, $propertyName, $propertyNameNormalized, $phpType = null) { | |
$body = '$this->' . $propertyName . ' = $' . $propertyNameNormalized . '; return $this;'; | |
$parameter['name'] = $propertyNameNormalized; | |
if (null !== $phpType) { | |
$typecheck = getTypeCheckCode($propertyName, $phpType); | |
$body = $typecheck . $body; | |
if ('' === $typecheck) { | |
$parameter['type'] = $phpType; | |
} | |
} | |
return new Zend_CodeGenerator_Php_Method(array( | |
'name' => $setterName, | |
'parameters' => array($parameter), | |
'body' => $body | |
)); | |
} | |
function getGetterCode($getterName, $propertyName, $propertyNameNormalized, $phpType = null) { | |
$body = 'return $this->' . $propertyName . ';'; | |
return new Zend_CodeGenerator_Php_Method(array( | |
'name' => $getterName, | |
'body' => $body | |
)); | |
} | |
function getPropertyType(Zend_CodeGenerator_Php_Property $property) { | |
$docblock = $property->getDocblock(); | |
if (null !== $docblock) { | |
$tags = $docblock->getTags(); | |
foreach ($tags as $tag) { | |
if ($tag->getName() === 'var') { | |
return $tag->getDescription(); | |
} | |
} | |
} | |
} | |
function getGenerateAnnotations(Zend_CodeGenerator_Php_Property $property) { | |
$result = array(); | |
$docblock = $property->getDocblock(); | |
if (null !== $docblock) { | |
$tags = $docblock->getTags('generate'); | |
foreach ($tags as $tag) { | |
$result[] = $tag->getDescription(); | |
} | |
} | |
return $result; | |
} | |
function handleAccessors(Zend_CodeGenerator_Php_Class $class) { | |
foreach ($class->getProperties() as $property) { | |
if ('private' !== $property->getVisibility()) continue; | |
$propertyName = $property->getName(); | |
$propertyNameNormalized = stripUnderscores($propertyName); | |
$setterName = 'set' . ucfirst($propertyNameNormalized); | |
$getterName = 'get' . ucfirst($propertyNameNormalized); | |
$propertyType = getPropertyType($property); | |
$generateAnnotations = getGenerateAnnotations($property); | |
if ((in_array('set', $generateAnnotations)) and (! $class->hasMethod($setterName))) { | |
$class->setMethod(getSetterCode($setterName, $propertyName, $propertyNameNormalized, $propertyType)); | |
} | |
if ((in_array('get', $generateAnnotations)) and (! $class->hasMethod($getterName))) { | |
$class->setMethod(getGetterCode($getterName, $propertyName, $propertyNameNormalized, $propertyType)); | |
} | |
} | |
} | |
function importInterfaceImplementation( | |
Zend_CodeGenerator_Php_Class $class, | |
Zend_CodeGenerator_Php_Class $interface, | |
Zend_CodeGenerator_Php_Class $implementation) { | |
foreach ($interface->getMethods() as $interfaceMethod) { | |
$implMethod = $implementation->getMethod($interfaceMethod->getName()); | |
$class->setMethod($implMethod); | |
} | |
} | |
function handleImports(Zend_CodeGenerator_Php_Class $class) { | |
$docblock = $class->getDocblock(); | |
if (null === $docblock) return; | |
$importTags = $docblock->getTags('import'); | |
foreach ($importTags as $importTag) { | |
$importClassName = $importTag->getDescription(); | |
$importClass = Zend_CodeGenerator_Php_Class::fromReflection( | |
new Zend_Reflection_Class($importClassName)); | |
$importInterfaces = $importClass->getImplementedInterfaces(); | |
if (empty($importInterfaces)) { | |
foreach ($importClass->getMethods() as $method) { | |
$class->setMethod($method); | |
} | |
} else { | |
$implementedInterfaces = $class->getImplementedInterfaces(); | |
$class->setImplementedInterfaces(array_merge($implementedInterfaces, $importInterfaces)); | |
foreach ($importInterfaces as $importInterfaceName) { | |
$importInterface = Zend_CodeGenerator_Php_Class::fromReflection( | |
new Zend_Reflection_Class($importInterfaceName)); | |
importInterfaceImplementation($class, $importInterface, $importClass); | |
} | |
} | |
} | |
} | |
$filename = 'Model.php'; | |
$classname = 'Model'; | |
$generator = Zend_CodeGenerator_Php_File::fromReflectedFileName($filename); | |
$class = $generator->getClass($classname); | |
handleAccessors($class); | |
handleImports($class); | |
echo $class; | |
This file contains hidden or 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 | |
/** | |
* @import JsonEncodeable | |
* @import HelloWorld | |
*/ | |
class Model | |
{ | |
/** | |
* @generate set | |
* @generate get | |
* @var string | |
*/ | |
private $_firstName; | |
/** | |
* @generate set | |
* @generate get | |
* @var string | |
*/ | |
private $_lastName; | |
/** | |
* @generate get | |
* @var string | |
*/ | |
private $_email; | |
/** | |
* @var int | |
*/ | |
private $_age; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment