-
Guillaume Perréal authored051af78f
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
*/
namespace Irstea\PlantUmlBundle\Model\Decorator;
use Irstea\PlantUmlBundle\Model\ClassVisitor;
use Irstea\PlantUmlBundle\Model\ClassVisitorInterface;
use Irstea\PlantUmlBundle\Model\DecoratorInterface;
use Irstea\PlantUmlBundle\Model\NodeInterface;
use ReflectionClass;
/**
* Description of InheritanceDecorator
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
*/
class InheritanceDecorator implements DecoratorInterface
{
public function decorate($className, NodeInterface $node, ClassVisitorInterface $visitor)
{
$class = new ReflectionClass($className);
$parent = $class->getParentClass();
$traits = $class->getTraitNames();
$interfaces = $class->getInterfaceNames();
$indirectInterfaces = array_filter(
array_map(
function ($i) { return $i->getInterfaceNames(); },
$class->getInterfaces()
)
);
if (!empty($indirectInterfaces)) {
$indirectInterfaces = call_user_func_array('array_merge', $indirectInterfaces);
$interfaces = array_diff($interfaces, $indirectInterfaces);
}
if ($parent) {
$traits = array_diff($traits, $parent->getTraitNames());
$interfaces = array_diff($interfaces, $parent->getInterfaceNames());
$this->visitRelations($node, [$parent->getName()], 'Irstea\PlantUmlBundle\Model\Arrow\ExtendsClass', $visitor);
}
$this->visitRelations($node, $interfaces, 'Irstea\PlantUmlBundle\Model\Arrow\ImplementsInterface', $visitor);
$this->visitRelations($node, $traits, 'Irstea\PlantUmlBundle\Model\Arrow\UsesTrait', $visitor);
return $this;
}
protected function visitRelations(NodeInterface $source, array $classNames, $relationClass, ClassVisitorInterface $visitor)
{
foreach ($classNames as $className) {
$target = $visitor->visitClass($className);
if ($target) {
$source->addArrow(new $relationClass($source, $target));
}
}
}
}