Skip to content

Commit

Permalink
Merge branch 'feature/#6593-#5864-export-metadata-should-contain-enti…
Browse files Browse the repository at this point in the history
…ty-listeners'

Close #6593
Close #5864
ge aborts
  • Loading branch information
Ocramius committed Aug 16, 2017
2 parents 9005c5a + 894490c commit 76e2155
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 64 deletions.
105 changes: 65 additions & 40 deletions lib/Doctrine/ORM/Tools/EntityGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -604,18 +604,23 @@ protected function getType($type)
*/
protected function generateEntityNamespace(ClassMetadataInfo $metadata)
{
if ($this->hasNamespace($metadata)) {
return 'namespace ' . $this->getNamespace($metadata) .';';
if (! $this->hasNamespace($metadata)) {
return '';
}

return 'namespace ' . $this->getNamespace($metadata) .';';
}

/**
* @return string
*/
protected function generateEntityUse()
{
if ($this->generateAnnotations) {
return "\n".'use Doctrine\ORM\Mapping as ORM;'."\n";
} else {
return "";
if (! $this->generateAnnotations) {
return '';
}

return "\n".'use Doctrine\ORM\Mapping as ORM;'."\n";
}

/**
Expand Down Expand Up @@ -738,9 +743,7 @@ private function generateEmbeddableConstructor(ClassMetadataInfo $metadata)
}

foreach ($fieldMappings as $fieldMapping) {
if (isset($fieldMapping['declaredField']) &&
isset($metadata->embeddedClasses[$fieldMapping['declaredField']])
) {
if (isset($fieldMapping['declaredField'], $metadata->embeddedClasses[$fieldMapping['declaredField']])) {
continue;
}

Expand Down Expand Up @@ -911,16 +914,16 @@ protected function hasMethod($method, ClassMetadataInfo $metadata)
* @param ClassMetadataInfo $metadata
*
* @return array
*
* @throws \ReflectionException
*/
protected function getTraits(ClassMetadataInfo $metadata)
{
if (! ($metadata->reflClass !== null || class_exists($metadata->name))) {
return [];
}

$reflClass = $metadata->reflClass === null
? new \ReflectionClass($metadata->name)
: $metadata->reflClass;
$reflClass = $metadata->reflClass ?? new \ReflectionClass($metadata->name);

$traits = [];

Expand Down Expand Up @@ -1010,6 +1013,7 @@ protected function generateEntityDocBlock(ClassMetadataInfo $metadata)
'generateDiscriminatorColumnAnnotation',
'generateDiscriminatorMapAnnotation',
'generateEntityAnnotation',
'generateEntityListenerAnnotation',
];

foreach ($methods as $method) {
Expand Down Expand Up @@ -1113,9 +1117,11 @@ protected function generateTableConstraints($constraintName, array $constraints)
*/
protected function generateInheritanceAnnotation(ClassMetadataInfo $metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
return '@' . $this->annotationsPrefix . 'InheritanceType("'.$this->getInheritanceTypeString($metadata->inheritanceType).'")';
if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
return '';
}

return '@' . $this->annotationsPrefix . 'InheritanceType("'.$this->getInheritanceTypeString($metadata->inheritanceType).'")';
}

/**
Expand All @@ -1125,14 +1131,16 @@ protected function generateInheritanceAnnotation(ClassMetadataInfo $metadata)
*/
protected function generateDiscriminatorColumnAnnotation(ClassMetadataInfo $metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$discrColumn = $metadata->discriminatorColumn;
$columnDefinition = 'name="' . $discrColumn['name']
. '", type="' . $discrColumn['type']
. '", length=' . $discrColumn['length'];

return '@' . $this->annotationsPrefix . 'DiscriminatorColumn(' . $columnDefinition . ')';
if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
return '';
}

$discrColumn = $metadata->discriminatorColumn;
$columnDefinition = 'name="' . $discrColumn['name']
. '", type="' . $discrColumn['type']
. '", length=' . $discrColumn['length'];

return '@' . $this->annotationsPrefix . 'DiscriminatorColumn(' . $columnDefinition . ')';
}

/**
Expand All @@ -1142,15 +1150,17 @@ protected function generateDiscriminatorColumnAnnotation(ClassMetadataInfo $meta
*/
protected function generateDiscriminatorMapAnnotation(ClassMetadataInfo $metadata)
{
if ($metadata->inheritanceType != ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$inheritanceClassMap = [];
if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
return null;
}

foreach ($metadata->discriminatorMap as $type => $class) {
$inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
}
$inheritanceClassMap = [];

return '@' . $this->annotationsPrefix . 'DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
foreach ($metadata->discriminatorMap as $type => $class) {
$inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
}

return '@' . $this->annotationsPrefix . 'DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
}

/**
Expand All @@ -1163,18 +1173,14 @@ protected function generateEntityStubMethods(ClassMetadataInfo $metadata)
$methods = [];

foreach ($metadata->fieldMappings as $fieldMapping) {
if (isset($fieldMapping['declaredField']) &&
isset($metadata->embeddedClasses[$fieldMapping['declaredField']])
) {
if (isset($fieldMapping['declaredField'], $metadata->embeddedClasses[$fieldMapping['declaredField']])) {
continue;
}

$nullableField = $this->nullableFieldExpression($fieldMapping);

if (( ! isset($fieldMapping['id']) ||
! $fieldMapping['id'] ||
$metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE
) && (! $metadata->isEmbeddedClass || ! $this->embeddablesImmutable)
if ((!$metadata->isEmbeddedClass || !$this->embeddablesImmutable)
&& (!isset($fieldMapping['id']) || ! $fieldMapping['id'] || $metadata->generatorType === ClassMetadataInfo::GENERATOR_TYPE_NONE)
&& $code = $this->generateEntityStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'], $nullableField)
) {
$methods[] = $code;
Expand Down Expand Up @@ -1307,12 +1313,9 @@ protected function generateEntityFieldMappingProperties(ClassMetadataInfo $metad
$lines = [];

foreach ($metadata->fieldMappings as $fieldMapping) {
if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
$metadata->isInheritedField($fieldMapping['fieldName']) ||
(
isset($fieldMapping['declaredField']) &&
isset($metadata->embeddedClasses[$fieldMapping['declaredField']])
)
if (isset($fieldMapping['declaredField'], $metadata->embeddedClasses[$fieldMapping['declaredField']]) ||
$this->hasProperty($fieldMapping['fieldName'], $metadata) ||
$metadata->isInheritedField($fieldMapping['fieldName'])
) {
continue;
}
Expand Down Expand Up @@ -1413,6 +1416,7 @@ protected function generateLifecycleCallbackMethod($name, $methodName, ClassMeta
if ($this->hasMethod($methodName, $metadata)) {
return '';
}

$this->staticReflection[$metadata->name]['methods'][] = $methodName;

$replacements = [
Expand Down Expand Up @@ -1748,6 +1752,27 @@ protected function generateEmbeddedPropertyDocBlock(array $embeddedClass)
return implode("\n", $lines);
}

private function generateEntityListenerAnnotation(ClassMetadataInfo $metadata): string
{
if (0 === \count($metadata->entityListeners)) {
return '';
}

$processedClasses = [];
foreach ($metadata->entityListeners as $event => $eventListeners) {
foreach ($eventListeners as $eventListener) {
$processedClasses[] = '"' . $eventListener['class'] . '"';
}
}

return \sprintf(
'%s%s({%s})',
'@' . $this->annotationsPrefix,
'EntityListeners',
\implode(',', \array_unique($processedClasses))
);
}

/**
* @param string $code
* @param int $num
Expand Down
4 changes: 2 additions & 2 deletions lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function exportClassMetadata(ClassMetadataInfo $metadata)
}

/**
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata
* @param ClassMetadataInfo $metadata
*
* @return string
*/
Expand All @@ -69,7 +69,7 @@ protected function _generateOutputPath(ClassMetadataInfo $metadata)
}

/**
* @param \Doctrine\ORM\Tools\EntityGenerator $entityGenerator
* @param EntityGenerator $entityGenerator
*
* @return void
*/
Expand Down
20 changes: 20 additions & 0 deletions lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ public function exportClassMetadata(ClassMetadataInfo $metadata)
}
}

$lines = array_merge($lines, $this->processEntityListeners($metadata));

foreach ($metadata->fieldMappings as $fieldMapping) {
$lines[] = '$metadata->mapField(' . $this->_varExport($fieldMapping) . ');';
}
Expand Down Expand Up @@ -177,4 +179,22 @@ protected function _varExport($var)

return $export;
}

private function processEntityListeners(ClassMetadataInfo $metadata) : array
{
$lines = [];

foreach ($metadata->entityListeners as $event => $entityListenerConfig) {
foreach ($entityListenerConfig as $entityListener) {
$lines[] = \sprintf(
'$metadata->addEntityListener(%s, %s, %s);',
\var_export($event, true),
\var_export($entityListener['class'], true),
\var_export($entityListener['method'], true)
);
}
}

return $lines;
}
}
70 changes: 55 additions & 15 deletions lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
namespace Doctrine\ORM\Tools\Export\Driver;

use Doctrine\ORM\Mapping\ClassMetadataInfo;
use SimpleXMLElement;

/**
* ClassMetadata exporter for Doctrine XML mapping files.
Expand All @@ -40,10 +41,10 @@ class XmlExporter extends AbstractExporter
*/
public function exportClassMetadata(ClassMetadataInfo $metadata)
{
$xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping ".
"xmlns=\"http://doctrine-project.org/schemas/orm/doctrine-mapping\" " .
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ".
"xsi:schemaLocation=\"http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd\" />");
$xml = new SimpleXmlElement('<?xml version="1.0" encoding="utf-8"?><doctrine-mapping ' .
'xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" ' .
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' .
'xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd" />');

if ($metadata->isMappedSuperclass) {
$root = $xml->addChild('mapped-superclass');
Expand Down Expand Up @@ -390,16 +391,18 @@ public function exportClassMetadata(ClassMetadataInfo $metadata)
}
}

$this->processEntityListeners($metadata, $root);

return $this->_asXml($xml);
}

/**
* Exports (nested) option elements.
*
* @param \SimpleXMLElement $parentXml
* @param array $options
* @param SimpleXMLElement $parentXml
* @param array $options
*/
private function exportTableOptions(\SimpleXMLElement $parentXml, array $options)
private function exportTableOptions(SimpleXMLElement $parentXml, array $options) : void
{
foreach ($options as $name => $option) {
$isArray = is_array($option);
Expand All @@ -418,12 +421,12 @@ private function exportTableOptions(\SimpleXMLElement $parentXml, array $options
/**
* Export sequence information (if available/configured) into the current identifier XML node
*
* @param \SimpleXMLElement $identifierXmlNode
* @param SimpleXMLElement $identifierXmlNode
* @param ClassMetadataInfo $metadata
*
* @return void
*/
private function exportSequenceInformation(\SimpleXMLElement $identifierXmlNode, ClassMetadataInfo $metadata)
private function exportSequenceInformation(SimpleXMLElement $identifierXmlNode, ClassMetadataInfo $metadata) : void
{
$sequenceDefinition = $metadata->sequenceGeneratorDefinition;

Expand All @@ -438,17 +441,54 @@ private function exportSequenceInformation(\SimpleXMLElement $identifierXmlNode,
$sequenceGeneratorXml->addAttribute('initial-value', $sequenceDefinition['initialValue']);
}

/**
* @param \SimpleXMLElement $simpleXml
*
* @return string $xml
*/
private function _asXml($simpleXml)
private function _asXml(SimpleXMLElement $simpleXml) : string
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->loadXML($simpleXml->asXML());
$dom->formatOutput = true;

return $dom->saveXML();
}

private function processEntityListeners(ClassMetadataInfo $metadata, SimpleXMLElement $root): void
{
if (0 === \count($metadata->entityListeners)) {
return;
}

$entityListenersXml = $root->addChild('entity-listeners');
$entityListenersXmlMap = [];

$this->generateEntityListenerXml($metadata, $entityListenersXmlMap, $entityListenersXml);
}

private function generateEntityListenerXml(ClassMetadataInfo $metadata, array $entityListenersXmlMap, SimpleXMLElement $entityListenersXml): void
{
foreach ($metadata->entityListeners as $event => $entityListenerConfig) {
foreach ($entityListenerConfig as $entityListener) {
$entityListenerXml = $this->addClassToMapIfExists(
$entityListenersXmlMap,
$entityListener,
$entityListenersXml
);

$entityListenerCallbackXml = $entityListenerXml->addChild('lifecycle-callback');
$entityListenerCallbackXml->addAttribute('type', $event);
$entityListenerCallbackXml->addAttribute('method', $entityListener['method']);
}
}
}

private function addClassToMapIfExists(array $entityListenersXmlMap, array $entityListener, SimpleXMLElement $entityListenersXml): SimpleXMLElement
{
if (isset($entityListenersXmlMap[$entityListener['class']])) {
return $entityListenersXmlMap[$entityListener['class']];
}

$entityListenerXml = $entityListenersXml->addChild('entity-listener');
$entityListenerXml->addAttribute('class', $entityListener['class']);
$entityListenersXmlMap[$entityListener['class']] = $entityListenerXml;

return $entityListenerXml;
}
}
Loading

0 comments on commit 76e2155

Please sign in to comment.