MethodDecorator.php 2.33 KB
Newer Older
1
2
<?php
/*
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
3
4
 * Copyright (C) 2016-2017 IRSTEA
 * All rights reserved.
5
6
7
8
9
10
11
12
13
14
15
16
17
 */

namespace Irstea\PlantUmlBundle\Model\Decorator;

use Irstea\PlantUmlBundle\Model\ClassVisitorInterface;
use Irstea\PlantUmlBundle\Model\DecoratorInterface;
use Irstea\PlantUmlBundle\Model\Node\Member\Member;
use Irstea\PlantUmlBundle\Model\Node\Member\MemberInterface;
use Irstea\PlantUmlBundle\Model\NodeInterface;
use ReflectionClass;
use ReflectionMethod;

/**
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
18
 * Description of AttributeDecorator.
19
20
21
22
23
 */
class MethodDecorator implements DecoratorInterface
{
    public function decorate(ReflectionClass $class, NodeInterface $node, ClassVisitorInterface $visitor)
    {
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
24
        foreach ($class->getMethods() as $method) {
25
26
            /* @var $method ReflectionMethod */

27
            if ($method->getDeclaringClass() != $class || $this->isAccessor($method, $class)) {
28
29
30
31
32
                continue;
            }

            $node->addMethod(
                new Member(
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
33
                    $method->getName() . '(...)',
34
35
36
37
                    '',
                    $method->isPrivate() ? MemberInterface::PRIVATE_ :
                        ($method->isProtected() ? MemberInterface::PROTECTED_ :
                            ($method->isPublic() ? MemberInterface::PUBLIC_ :
Raidelet Nicolas's avatar
Raidelet Nicolas committed
38
                                MemberInterface::UNKNOWN))
39
40
41
42
                )
            );
        }
    }
43
44
45

    /**
     * @param ReflectionMethod $method
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
46
47
48
     * @param ReflectionClass  $class
     *
     * @return bool
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
     */
    protected function isAccessor(ReflectionMethod $method, ReflectionClass $class)
    {
        if (!$method->isPublic() || $method->isAbstract() || $method->getDeclaringClass()->isInterface()) {
            return false;
        }
        if ($method->getNumberOfParameters() === 0 && preg_match('/(?:get|is)(\w+)/', $method->getName(), $groups)) {
            $name = lcfirst($groups[1]);
        } elseif ($method->getNumberOfParameters() === 1 && preg_match('/(?:set|add|remove)(\w+)/', $method->getName(), $groups)) {
            $name = lcfirst($groups[1]);
        } else {
            return false;
        }
        if (!$class->hasProperty($name)) {
            return false;
        }
        $property = $class->getProperty($name);
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
66

67
68
        return $property->isStatic() == $method->isStatic();
    }
69
70
71
72
73

    public function toConfig(array &$conf)
    {
        $conf['decorators'][] = 'methods';
    }
74
}