Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pôle IS
Bundles Symfony 2
plantuml-bundle
Commits
58699241
Commit
58699241
authored
Aug 01, 2017
by
Guillaume Perréal
Browse files
CS.
parent
d81585f4
Changes
73
Hide whitespace changes
Inline
Side-by-side
Command/GenerateCommand.php
View file @
58699241
<?php
/*
* Copyright (C) 201
5
IRSTEA
* Copyright (C) 201
6-2017
IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\Command
;
use
Irstea\PlantUmlBundle\Writer\OutputWriter
;
...
...
@@ -14,9 +14,7 @@ use Symfony\Component\Console\Output\OutputInterface;
use
Symfony\Component\Security\Core\Exception\InvalidArgumentException
;
/**
* Description of ImportAffiliationCommand
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of ImportAffiliationCommand.
*/
class
GenerateCommand
extends
ContainerAwareCommand
{
...
...
@@ -24,13 +22,12 @@ class GenerateCommand extends ContainerAwareCommand
{
$this
->
setName
(
'irstea:plantuml:generate'
)
->
setDescription
(
"
Génère un graphe en PlantUML.
"
)
->
setDescription
(
'
Génère un graphe en PlantUML.
'
)
->
addArgument
(
'graph'
,
InputArgument
::
REQUIRED
,
'Nom du graphe à générer'
);
}
/**
*
* @param InputInterface $input
* @param InputInterface $input
* @param OutputInterface $output
*
* @SuppressWarnings(UnusedFormalParameter)
...
...
Command/RenderCommand.php
View file @
58699241
<?php
/*
* Copyright (C) 201
5
IRSTEA
* Copyright (C) 201
6-2017
IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\Command
;
use
Irstea\PlantUmlBundle\Model\Graph
;
use
Irstea\PlantUmlBundle\Writer\OutputWriter
;
use
Irstea\PlantUmlBundle\Writer\StreamWriter
;
use
Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand
;
use
Symfony\Component\Console\Input\InputArgument
;
...
...
@@ -16,13 +15,9 @@ use Symfony\Component\Console\Input\InputOption;
use
Symfony\Component\Console\Output\OutputInterface
;
use
Symfony\Component\Console\Style\SymfonyStyle
;
use
Symfony\Component\Filesystem\Filesystem
;
use
Symfony\Component\Process\ProcessBuilder
;
use
Symfony\Component\Security\Core\Exception\InvalidArgumentException
;
/**
* Description of ImportAffiliationCommand
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of ImportAffiliationCommand.
*/
class
RenderCommand
extends
ContainerAwareCommand
{
...
...
@@ -31,14 +26,13 @@ class RenderCommand extends ContainerAwareCommand
$this
->
setName
(
'irstea:plantuml:render'
)
->
setDescription
(
"Créer la page d'un graphe ou plusieurs graphes."
)
->
addOption
(
'output'
,
'o'
,
InputOption
::
VALUE_REQUIRED
,
"
Répertoire de destination.
"
)
->
addOption
(
'format'
,
'f'
,
InputOption
::
VALUE_REQUIRED
,
"
Format du fichier à générer
"
)
->
addOption
(
'output'
,
'o'
,
InputOption
::
VALUE_REQUIRED
,
'
Répertoire de destination.
'
)
->
addOption
(
'format'
,
'f'
,
InputOption
::
VALUE_REQUIRED
,
'
Format du fichier à générer
'
)
->
addArgument
(
'graph'
,
InputArgument
::
OPTIONAL
|
InputArgument
::
IS_ARRAY
,
'Graphe à générer'
);
}
/**
*
* @param InputInterface $input
* @param InputInterface $input
* @param OutputInterface $output
*
* @SuppressWarnings(UnusedFormalParameter)
...
...
@@ -51,8 +45,8 @@ class RenderCommand extends ContainerAwareCommand
$io
=
new
SymfonyStyle
(
$input
,
$output
);
foreach
(
$graphs
as
$name
)
{
$target
=
$outputDir
.
DIRECTORY_SEPARATOR
.
$name
.
"."
.
$format
;
foreach
(
$graphs
as
$name
)
{
$target
=
$outputDir
.
DIRECTORY_SEPARATOR
.
$name
.
'.'
.
$format
;
$io
->
section
(
"Graphe:
$name
"
);
...
...
@@ -72,27 +66,27 @@ class RenderCommand extends ContainerAwareCommand
$io
->
writeln
(
json_encode
(
$desc
,
JSON_PRETTY_PRINT
));
}
$io
->
write
(
"
Exploration des classes:
"
);
$io
->
write
(
'
Exploration des classes:
'
);
$graph
->
visitAll
();
$io
->
writeln
(
"
<info>Ok</info>.
"
);
$io
->
writeln
(
'
<info>Ok</info>.
'
);
$io
->
write
(
"
Démarrage de PlantUML:
"
);
$io
->
write
(
'
Démarrage de PlantUML:
'
);
list
(
$proc
,
$pipes
)
=
$this
->
startProcess
(
$target
,
$format
);
$io
->
writeln
(
"
<info>Ok</info>.
"
);
$io
->
writeln
(
'
<info>Ok</info>.
'
);
$io
->
write
(
"
Génération du graphe:
"
);
$io
->
write
(
'
Génération du graphe:
'
);
$writer
=
new
StreamWriter
(
$pipes
[
0
]);
$graph
->
writeTo
(
$writer
);
fclose
(
$pipes
[
0
]);
$io
->
writeln
(
"
<info>Ok</info>.
"
);
$io
->
writeln
(
'
<info>Ok</info>.
'
);
$io
->
write
(
"
Rendu graphique par PlantUML:
"
);
$io
->
write
(
'
Rendu graphique par PlantUML:
'
);
$res
=
proc_close
(
$proc
);
if
(
$res
===
0
)
{
$io
->
writeln
(
"
<info>Ok</info>.
"
);
$io
->
writeln
(
'
<info>Ok</info>.
'
);
}
else
{
$io
->
writeln
(
"
<error>Nok</error>.
"
);
$io
->
writeln
(
'
<error>Nok</error>.
'
);
}
}
...
...
@@ -107,7 +101,7 @@ class RenderCommand extends ContainerAwareCommand
'-jar'
,
$ctn
->
getParameter
(
'irstea_plant_uml.binaries.plamtuml_jar'
),
'-graphvizdot'
,
$ctn
->
getParameter
(
'irstea_plant_uml.binaries.dot'
),
'-pipe'
,
'-t'
.
$format
'-t'
.
$format
,
]);
$desc
=
[
...
...
@@ -116,7 +110,7 @@ class RenderCommand extends ContainerAwareCommand
// stdout
[
'file'
,
$target
,
'wt'
],
// stderr
STDERR
STDERR
,
];
$pipes
=
[];
...
...
@@ -124,5 +118,4 @@ class RenderCommand extends ContainerAwareCommand
return
[
$proc
,
$pipes
];
}
}
DependencyInjection/Builder/ClassFilterBuilder.php
View file @
58699241
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
* Copyright (C) 2016-2017 IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\DependencyInjection\Builder
;
...
...
@@ -17,9 +15,7 @@ use Symfony\Component\DependencyInjection\Definition;
use
Symfony\Component\DependencyInjection\Reference
;
/**
* Description of ClassFilterBuilder
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of ClassFilterBuilder.
*/
class
ClassFilterBuilder
{
...
...
@@ -36,10 +32,10 @@ class ClassFilterBuilder
/**
* @var string[]
*/
static
private
$filterClasses
=
[
private
static
$filterClasses
=
[
'classes'
=>
ClassFilter
::
class
,
'directories'
=>
DirectoryFilter
::
class
,
'namespaces'
=>
NamespaceFilter
::
class
'namespaces'
=>
NamespaceFilter
::
class
,
];
/**
...
...
@@ -52,6 +48,7 @@ class ClassFilterBuilder
/**
* @param array $config
*
* @return Reference
*/
public
function
build
(
array
$config
)
...
...
@@ -71,6 +68,7 @@ class ClassFilterBuilder
/**
* @param mixed $data
*
* @return mixed
*/
protected
function
normalize
(
$data
)
...
...
@@ -81,7 +79,7 @@ class ClassFilterBuilder
if
(
is_array
(
$data
))
{
$res
=
[];
$isList
=
true
;
foreach
(
$data
as
$k
=>
$v
)
{
foreach
(
$data
as
$k
=>
$v
)
{
$normalized
=
$this
->
normalize
(
$v
);
if
(
!
empty
(
$normalized
))
{
$res
[
$k
]
=
$normalized
;
...
...
@@ -98,14 +96,17 @@ class ClassFilterBuilder
}
else
{
ksort
(
$res
);
}
return
$res
;
}
return
$data
;
}
/**
* @param type $id
* @param type
$id
* @param array $config
*
* @return Reference
*/
protected
function
doBuild
(
$id
,
array
$config
)
...
...
@@ -128,14 +129,15 @@ class ClassFilterBuilder
}
$this
->
container
->
setDefinition
(
$id
,
new
Definition
(
AllFilter
::
class
,
[
$filters
]));
return
new
Reference
(
$id
);
}
/**
* @param array $filters
* @param array
$filters
* @param string $id
* @param array $config
* @param bool $notFound
* @param array
$config
* @param bool
$notFound
*/
protected
function
buildSubFilter
(
array
&
$filters
,
$id
,
array
$config
,
$notFound
)
{
...
...
DependencyInjection/Builder/GraphDefinitionBuilder.php
View file @
58699241
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
* Copyright (C) 2016-2017 IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\DependencyInjection\Builder
;
...
...
@@ -19,9 +17,7 @@ use Symfony\Component\DependencyInjection\DefinitionDecorator;
use
Symfony\Component\DependencyInjection\Reference
;
/**
* Description of GraphDefinitionBuilder
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of GraphDefinitionBuilder.
*/
class
GraphDefinitionBuilder
{
...
...
@@ -51,16 +47,14 @@ class GraphDefinitionBuilder
private
$entityManager
;
/**
*
* @var Definition
*/
private
$definition
=
null
;
/**
*
* @param ContainerBuilder $container
* @param string $baseId
* @param array $config
* @param string
$baseId
* @param array
$config
*/
public
function
__construct
(
ContainerBuilder
$container
,
$baseId
,
array
$config
,
ClassFilterBuilder
$filterBuilder
)
{
...
...
@@ -81,6 +75,7 @@ class GraphDefinitionBuilder
if
(
!
$this
->
definition
)
{
return
$this
->
definition
=
$this
->
doBuild
();
}
return
$this
->
definition
;
}
...
...
@@ -95,7 +90,7 @@ class GraphDefinitionBuilder
$decorator
=
$this
->
buildFilteredDecorator
();
$namespace
=
$this
->
buildNamespace
();
$visitor
=
$this
->
setDefinition
(
"
visitor
"
,
ClassVisitor
::
class
,
$decorator
,
$layoutFilter
,
$namespace
);
$visitor
=
$this
->
setDefinition
(
'
visitor
'
,
ClassVisitor
::
class
,
$decorator
,
$layoutFilter
,
$namespace
);
return
new
Definition
(
Graph
::
class
,
[
$visitor
,
$source
]);
}
...
...
@@ -109,7 +104,8 @@ class GraphDefinitionBuilder
$filter
=
$this
->
filterBuilder
->
build
(
$this
->
config
[
'sources'
]);
if
(
$filter
)
{
$filtered
=
$this
->
setDefinition
(
"finder"
,
FilteringFinder
::
class
,
$finder
,
$filter
);
$filtered
=
$this
->
setDefinition
(
'finder'
,
FilteringFinder
::
class
,
$finder
,
$filter
);
return
[
$filtered
,
$filter
];
}
...
...
@@ -123,11 +119,11 @@ class GraphDefinitionBuilder
{
$config
=
$this
->
config
[
'sources'
];
switch
(
$config
[
'type'
])
{
switch
(
$config
[
'type'
])
{
case
'entities'
:
return
$this
->
setDefinition
(
"
finder.entities
"
,
EntityFinder
::
class
,
$this
->
entityManager
);
return
$this
->
setDefinition
(
'
finder.entities
'
,
EntityFinder
::
class
,
$this
->
entityManager
);
case
'classes'
:
return
$this
->
setDefinition
(
"
finder.classes
"
,
ClassFinder
::
class
,
$config
[
'directories'
]);
return
$this
->
setDefinition
(
'
finder.classes
'
,
ClassFinder
::
class
,
$config
[
'directories'
]);
}
}
...
...
@@ -178,6 +174,7 @@ class GraphDefinitionBuilder
/**
* @param string $type
*
* @return Reference
*/
protected
function
buildTypedDecorator
(
$type
)
...
...
@@ -200,7 +197,7 @@ class GraphDefinitionBuilder
{
$type
=
$this
->
config
[
'layout'
][
'namespaces'
];
if
(
$type
===
"
entities
"
)
{
if
(
$type
===
'
entities
'
)
{
return
$this
->
setDefinitionDecorator
(
"namespace.
$type
"
,
"irstea.plant_uml.namespaces.
$type
.template"
,
...
...
@@ -215,9 +212,10 @@ class GraphDefinitionBuilder
}
/**
* @param string $localId
* @param string
$localId
* @param string|Definition $classOrDef
* @param array ...$arguments
* @param array ...$arguments
*
* @return Reference
*/
protected
function
setDefinition
(
$localId
,
$classOrDef
,
...
$arguments
)
...
...
@@ -229,24 +227,28 @@ class GraphDefinitionBuilder
}
$id
=
$this
->
globalId
(
$localId
);
$this
->
container
->
setDefinition
(
$id
,
$definition
);
return
new
Reference
(
$id
);
}
/**
* @param string $localId
* @param string $templateId
* @param array ...$arguments
* @param array ...$arguments
*
* @return Reference
*/
protected
function
setDefinitionDecorator
(
$localId
,
$templateId
,
...
$arguments
)
{
$def
=
new
DefinitionDecorator
(
$templateId
);
$def
->
setArguments
(
$arguments
);
return
$this
->
setDefinition
(
$localId
,
$def
);
}
/**
* @param string $localId
*
* @return string
*/
protected
function
globalId
(
$localId
)
...
...
DependencyInjection/Configuration.php
View file @
58699241
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
* Copyright (C) 2016-2017 IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\DependencyInjection
;
...
...
@@ -12,9 +10,7 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use
Symfony\Component\Config\Definition\ConfigurationInterface
;
/**
* Description of Configuration
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of Configuration.
*/
class
Configuration
implements
ConfigurationInterface
{
...
...
@@ -28,12 +24,12 @@ class Configuration implements ConfigurationInterface
->
addDefaultsIfNotSet
()
->
children
()
->
scalarNode
(
'directory'
)
->
info
(
"
Répertoire dans lequel écrire les fichiers.
"
)
->
defaultValue
(
"
%kernel.root_dir%/Resources/doc
"
)
->
info
(
'
Répertoire dans lequel écrire les fichiers.
'
)
->
defaultValue
(
'
%kernel.root_dir%/Resources/doc
'
)
->
end
()
->
enumNode
(
'format'
)
->
info
(
"
Format de sortie (cf. PlantUML).
"
)
->
defaultValue
(
"
svg
"
)
->
info
(
'
Format de sortie (cf. PlantUML).
'
)
->
defaultValue
(
'
svg
'
)
->
values
([
'png'
,
'svg'
,
'eps'
,
'pdf'
,
'vdx'
,
'html'
,
'xmi'
,
'txt'
,
'utxt'
])
->
end
()
->
end
()
...
...
@@ -44,15 +40,15 @@ class Configuration implements ConfigurationInterface
->
children
()
->
scalarNode
(
'java'
)
->
info
(
"Commande 'java'"
)
->
defaultValue
(
"
java
"
)
->
defaultValue
(
'
java
'
)
->
end
()
->
scalarNode
(
'plamtuml_jar'
)
->
info
(
"
Archive du logiciel PlantUML
"
)
->
info
(
'
Archive du logiciel PlantUML
'
)
->
defaultValue
(
__DIR__
.
'/../vendor/plantuml/plantuml.jar'
)
->
end
()
->
scalarNode
(
'dot'
)
->
info
(
"Commande 'dot' du package 'graphviz'"
)
->
defaultValue
(
"
dot
"
)
->
defaultValue
(
'
dot
'
)
->
end
()
->
end
()
->
end
()
...
...
@@ -69,26 +65,26 @@ class Configuration implements ConfigurationInterface
$decorators
=
[
'inheritance'
,
'traits'
,
'interfaces'
,
'entity'
,
'associations'
,
'methods'
,
'fields'
,
'attributes'
];
$node
->
info
(
"
Graphes.
"
)
->
info
(
'
Graphes.
'
)
->
useAttributeAsKey
(
'name'
)
->
prototype
(
'array'
)
->
info
(
"description d'un graphe à générer."
)
->
children
()
->
arrayNode
(
'sources'
)
->
info
(
"
Sélection des classes à examiner.
"
)
->
info
(
'
Sélection des classes à examiner.
'
)
->
addDefaultsIfNotSet
()
->
children
()
->
enumNode
(
'type'
)
->
info
(
"
Source de la liste de classes.
"
)
->
info
(
'
Source de la liste de classes.
'
)
->
defaultValue
(
'classes'
)
->
values
([
'classes'
,
'entities'
])
->
end
()
->
scalarNode
(
'entity_manager'
)
->
info
(
"
Entity Manager à utiliser pour les entités.
"
)
->
info
(
'
Entity Manager à utiliser pour les entités.
'
)
->
defaultValue
(
'default'
)
->
end
()
->
arrayNode
(
'directories'
)
->
info
(
"
Répertoires contenant les sources.
"
)
->
info
(
'
Répertoires contenant les sources.
'
)
->
defaultValue
([
'%kernel.root_dir%/../src'
])
->
prototype
(
'scalar'
)
->
end
()
->
end
()
...
...
@@ -97,11 +93,11 @@ class Configuration implements ConfigurationInterface
->
end
()
->
end
()
->
arrayNode
(
'layout'
)
->
info
(
"
Configuration de la disposition et du parcours.
"
)
->
info
(
'
Configuration de la disposition et du parcours.
'
)
->
addDefaultsIfNotSet
()
->
children
()
->
enumNode
(
'namespaces'
)
->
info
(
"
Types .
"
)
->
info
(
'
Types .
'
)
->
defaultValue
(
'php'
)
->
values
([
'bundles'
,
'php'
,
'flat'
,
'entities'
])
->
end
()
...
...
@@ -110,11 +106,11 @@ class Configuration implements ConfigurationInterface
->
end
()
->
end
()
->
arrayNode
(
'decoration'
)
->
info
(
"
Informations à afficher sur les classes.
"
)
->
info
(
'
Informations à afficher sur les classes.
'
)
->
addDefaultsIfNotSet
()
->
children
()
->
arrayNode
(
'decorators'
)
->
info
(
"
Liste des décorateurs à utiliser.
"
)
->
info
(
'
Liste des décorateurs à utiliser.
'
)
->
defaultValue
(
$decorators
)
->
prototype
(
'enum'
)
->
values
(
$decorators
)
...
...
@@ -152,6 +148,4 @@ class Configuration implements ConfigurationInterface
return
$node
;
}
}
DependencyInjection/IrsteaPlantUmlExtension.php
View file @
58699241
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
* Copyright (C) 2016-2017 IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\DependencyInjection
;
...
...
@@ -16,15 +14,13 @@ use Symfony\Component\DependencyInjection\Extension\Extension;
use
Symfony\Component\DependencyInjection\Loader
;
/**
* Description of IrsteaPlantUmlExtension
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of IrsteaPlantUmlExtension.
*/
class
IrsteaPlantUmlExtension
extends
Extension
{
public
function
load
(
array
$configs
,
ContainerBuilder
$container
)
{
$loader
=
new
Loader\YamlFileLoader
(
$container
,
new
FileLocator
(
__DIR__
.
'/../Resources/config'
));
$loader
=
new
Loader\YamlFileLoader
(
$container
,
new
FileLocator
(
__DIR__
.
'/../Resources/config'
));
$loader
->
load
(
'services.yml'
);
$configuration
=
new
Configuration
();
...
...
Doctrine/AbstractDoctrineDecorator.php
View file @
58699241
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
* Copyright (C) 2016-2017 IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\Doctrine
;
use
Doctrine\ORM\EntityManagerInterface
;
use
Doctrine\ORM\Mapping\ClassMetadata
;
use
Doctrine\ORM\Mapping\ClassMetadataFactory
;
use
Irstea\PlantUmlBundle\Model\ClassVisitorInterface
;
use
Irstea\PlantUmlBundle\Model\DecoratorInterface
;
use
Irstea\PlantUmlBundle\Model\NodeInterface
;
use
ReflectionClass
;
/**
* Description of AbstractDoctrineDecorator
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of AbstractDoctrineDecorator.
*/
abstract
class
AbstractDoctrineDecorator
implements
DecoratorInterface
{
...
...
@@ -34,8 +27,9 @@ abstract class AbstractDoctrineDecorator implements DecoratorInterface
}
/**
* @param callable $callback
* @param callable
$callback
* @param ReflectionClass $class
*
* @return mixed
*/
protected
function
withMetadata
(
$callback
,
ReflectionClass
$class
=
null
)
...
...
@@ -48,7 +42,7 @@ abstract class AbstractDoctrineDecorator implements DecoratorInterface
if
(
!
$this
->
metadataFactory
->
hasMetadataFor
(
$className
))
{
return
null
;
}
return
$callback
(
$this
->
metadataFactory
->
getMetadataFor
(
$className
));
}
}
Doctrine/AssociationDecorator.php
View file @
58699241
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
* Copyright (C) 2016-2017 IRSTEA
* All rights reserved.
*/
namespace
Irstea\PlantUmlBundle\Doctrine
;
...
...
@@ -16,14 +14,12 @@ use Irstea\PlantUmlBundle\Model\NodeInterface;
use
ReflectionClass
;
/**
* Description of RelationDecorator
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
* Description of RelationDecorator.
*/
class
AssociationDecorator
extends
AbstractDoctrineDecorator
{
use
\
Irstea\PlantUmlBundle\Model\Decorator\InheritableItemDecoratorTrait
;
protected
function
extractItems
(
ReflectionClass
$class
)
{
return
$this
->
withMetadata
(
...
...
@@ -40,25 +36,26 @@ class AssociationDecorator extends AbstractDoctrineDecorator
return
;
}
$target
=
$visitor
->
visitClass
(
$association
[
'targetEntity'
]);
$target
=
$visitor
->
visitClass
(
$association
[
'targetEntity'
]);