Skip to content

Instantly share code, notes, and snippets.

@kdambekalns
Created October 12, 2011 12:21
Show Gist options
  • Save kdambekalns/1281082 to your computer and use it in GitHub Desktop.
Save kdambekalns/1281082 to your computer and use it in GitHub Desktop.
Converting Doctrine annotations back to strings

When creating proxy classes, we do not copy the docblock, but generate one, using the parsed annotations of the original class. Thus we need to render them out to string form. This is what we currently use for that purpose...

/**
* Render the source (string) form of an Annotation instance.
*
* @param \Doctrine\Common\Annotations\Annotation $annotation
* @return string
*/
static public function renderAnnotation($annotation) {
$annotationAsString = '@' . get_class($annotation);
$optionNames = get_class_vars(get_class($annotation));
$optionsAsStrings = array();
foreach ($optionNames as $optionName => $optionDefault) {
$optionValue = $annotation->$optionName;
$optionValueAsString = '';
if (is_object($optionValue)) {
$optionValueAsString = self::renderAnnotation($optionValue);
} elseif (is_scalar($optionValue) && is_string($optionValue)) {
$optionValueAsString = '"' . $optionValue . '"';
} elseif (is_array($optionValue)) {
$values = array();
foreach ($optionValue as $k => $v) {
$value = '';
if (is_string($k)) {
$value .= '"' . $k . '"=';
}
if (is_object($v)) {
$value .= self::renderAnnotation($v);
} elseif (is_scalar($v) && is_string($v)) {
$value .= '"' . $v . '"';
} elseif (is_scalar($v)) {
$value .= $v;
}
$values[] = $value;
}
$optionValueAsString = '{ ' . implode(', ', $values) . ' }';
}
switch ($optionName) {
case 'value':
$optionsAsStrings[] = $optionValueAsString;
break;
default:
if ($optionValue === $optionDefault) {
continue;
}
$optionsAsStrings[] = $optionName . '=' . $optionValueAsString;
}
}
return $annotationAsString . ($optionsAsStrings !== array() ? '(' . implode(', ', $optionsAsStrings) . ')' : '');
}
/**
* Render the source (string) form of an Annotation instance.
*
* @param \Doctrine\Common\Annotations\Annotation $annotation
* @return string
*/
static public function renderAnnotation($annotation) {
$annotationAsString = '@' . get_class($annotation);
$optionNames = get_class_vars(get_class($annotation));
$optionsAsStrings = array();
foreach ($optionNames as $optionName => $optionDefault) {
$optionValue = $annotation->$optionName;
$optionValueAsString = '';
if (is_object($optionValue)) {
$optionValueAsString = self::renderAnnotation($optionValue);
} elseif (is_scalar($optionValue) && is_string($optionValue)) {
$optionValueAsString = '"' . $optionValue . '"';
} elseif (is_array($optionValue)) {
$values = array();
foreach ($optionValue as $k => $v) {
$value = '';
if (is_string($k)) {
$value .= '"' . $k . '"=';
}
if (is_object($v)) {
$value .= self::renderAnnotation($v);
} elseif (is_scalar($v) && is_string($v)) {
$value .= '"' . $v . '"';
} elseif (is_scalar($v)) {
$value .= $v;
}
$values[] = $value;
}
$optionValueAsString = '{ ' . implode(', ', $values) . ' }';
}
switch ($optionName) {
case 'value':
$optionsAsStrings[] = $optionValueAsString;
break;
default:
if ($optionValue === $optionDefault) {
continue;
}
$optionsAsStrings[] = $optionName . '=' . $optionValueAsString;
}
}
return $annotationAsString . ($optionsAsStrings !== array() ? '(' . implode(', ', $optionsAsStrings) . ')' : '');
}
/**
* @return array
*/
public function annotationsAndStrings() {
return array(
array(
new \TYPO3\FLOW3\Annotations\Signal(array()),
'@TYPO3\FLOW3\Annotations\Signal'
),
array(
new \TYPO3\FLOW3\Annotations\Scope(array('value' => 'singleton')),
'@TYPO3\FLOW3\Annotations\Scope("singleton")'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('value' => 'foo1', 'type' => 'bar1')),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", argumentName="foo1")'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array('minimum' => 2))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ "minimum"=2 })'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array('foo' => 'hubbabubba'))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ "foo"="hubbabubba" })'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array(new \TYPO3\FLOW3\Annotations\Inject(array())))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ @TYPO3\FLOW3\Annotations\Inject })'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array(new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array('foo' => 'hubbabubba')))))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ @TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ "foo"="hubbabubba" }) })'
),
);
}
/**
* @dataProvider annotationsAndStrings
* @test
*/
public function renderAnnotationRendersCorrectly($annotation, $expectedString) {
$this->assertEquals($expectedString, \TYPO3\FLOW3\Object\Proxy\Compiler::renderAnnotation($annotation));
}
/**
* @return array
*/
public function annotationsAndStrings() {
return array(
array(
new \TYPO3\FLOW3\Annotations\Signal(array()),
'@TYPO3\FLOW3\Annotations\Signal'
),
array(
new \TYPO3\FLOW3\Annotations\Scope(array('value' => 'singleton')),
'@TYPO3\FLOW3\Annotations\Scope("singleton")'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('value' => 'foo1', 'type' => 'bar1')),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", argumentName="foo1")'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array('minimum' => 2))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ "minimum"=2 })'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array('foo' => 'hubbabubba'))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ "foo"="hubbabubba" })'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array(new \TYPO3\FLOW3\Annotations\Inject(array())))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ @TYPO3\FLOW3\Annotations\Inject })'
),
array(
new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array(new \TYPO3\FLOW3\Annotations\Validate(array('type' => 'bar1', 'options' => array('foo' => 'hubbabubba')))))),
'@TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ @TYPO3\FLOW3\Annotations\Validate(type="bar1", options={ "foo"="hubbabubba" }) })'
),
);
}
/**
* @dataProvider annotationsAndStrings
* @test
*/
public function renderAnnotationRendersCorrectly($annotation, $expectedString) {
$this->assertEquals($expectedString, \TYPO3\FLOW3\Object\Proxy\Compiler::renderAnnotation($annotation));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment