Completed
Branch master (3b8125)
by
unknown
01:25
created

InterfaceManager   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 4
dl 0
loc 156
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A isValidNamespace() 0 4 1
A getClassManager() 0 4 1
A setClassManager() 0 5 1
A getNamespace() 0 4 1
A getMethods() 0 4 1
A setMethods() 0 5 1
A getComment() 0 4 1
A getName() 0 4 1
A getNamespaceWithoutName() 0 4 1
A getDirectory() 0 4 1
A getNamespaceWithoutNameAndBackslashPrefix() 0 4 1
A getTemplateTags() 0 9 1
1
<?php
2
3
namespace HelloWordPl\SimpleEntityGeneratorBundle\Lib\Items;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use HelloWordPl\SimpleEntityGeneratorBundle\Lib\Interfaces\DumpableInterface;
7
use HelloWordPl\SimpleEntityGeneratorBundle\Lib\Interfaces\RenderableInterface;
8
use HelloWordPl\SimpleEntityGeneratorBundle\Lib\Interfaces\StructureWithMethodsInterface;
9
use HelloWordPl\SimpleEntityGeneratorBundle\Lib\Tools;
10
use Symfony\Component\Validator\Constraints as Assert;
11
use HelloWordPl\SimpleEntityGeneratorBundle\Lib\Traits\TemplateTrait;
12
13
/**
14
 * Class Interface Manager
15
 *
16
 * @author Sławomir Kania <[email protected]>
17
 */
18
class InterfaceManager implements RenderableInterface, DumpableInterface, StructureWithMethodsInterface
19
{
20
    use TemplateTrait;
21
22
    /**
23
     * @Assert\NotNull(message = "Interface has to know about class!")
24
     * @Assert\Valid()
25
     */
26
    private $classManager = null;
27
28
    /**
29
     * @var ArrayCollection
30
     * @Assert\NotNull(message = "Interface methods collection can not be emtpy")
31
     * @Assert\Valid()
32
     */
33
    private $methods = null;
34
35
    /**
36
     * Construct
37
     *
38
     * @param ClassManager $classManager
39
     */
40
    public function __construct(ClassManager $classManager)
41
    {
42
        $this->setClassManager($classManager);
43
        $this->setMethods(new ArrayCollection());
44
    }
45
46
    /**
47
     * @Assert\IsTrue(message = "Invalid interface namespace, check yaml schema! eg. \AppBundle\Location\Entity")
48
     * @return boolean
49
     */
50
    public function isValidNamespace()
51
    {
52
        return Tools::isNamespaceValid($this->getNamespace());
53
    }
54
55
    /**
56
     * @return ClassManager
57
     */
58
    public function getClassManager()
59
    {
60
        return $this->classManager;
61
    }
62
63
    /**
64
     * @param ClassManager $classManager
65
     * @return InterfaceManager
66
     */
67
    public function setClassManager(ClassManager $classManager)
68
    {
69
        $this->classManager = $classManager;
70
        return $this;
71
    }
72
73
    /**
74
     * Return namespace
75
     *
76
     * @return string
77
     */
78
    public function getNamespace()
79
    {
80
        return sprintf("%s%s", $this->getClassManager()->getNamespace(), "Interface");
81
    }
82
83
    /**
84
     * Return collection of methods
85
     *
86
     * @return ArrayCollection
87
     */
88
    public function getMethods()
89
    {
90
        return $this->methods;
91
    }
92
93
    /**
94
     * Set collection of methods
95
     *
96
     * @param ArrayCollection $methods
97
     * @return InterfaceManager
98
     */
99
    public function setMethods(ArrayCollection $methods)
100
    {
101
        $this->methods = $methods;
102
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (HelloWordPl\SimpleEntity...\Items\InterfaceManager) is incompatible with the return type declared by the interface HelloWordPl\SimpleEntity...dsInterface::setMethods of type HelloWordPl\SimpleEntity...rfaces\InterfaceManager.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
103
    }
104
105
    /**
106
     * Return comment for interface
107
     *
108
     * @return string
109
     */
110
    public function getComment()
111
    {
112
        return sprintf("Interface for entity : %s", $this->getClassManager()->getNamespace());
113
    }
114
115
    /**
116
     * Return name of class/interface from namespace
117
     *
118
     * @return string
119
     * @throws Exception
120
     */
121
    public function getName()
122
    {
123
        return Tools::getNameFromNamespace($this->getNamespace());
124
    }
125
126
    /**
127
     * Return namespace without name - for rendering namespace in class
128
     *
129
     * @return string
130
     * @throws Exception
131
     */
132
    public function getNamespaceWithoutName()
133
    {
134
        return Tools::getNamespaceWithoutName($this->getNamespace());
135
    }
136
137
    /**
138
     * Return namespace without name - for createing directory
139
     *
140
     * @return string
141
     * @throws Exception
142
     */
143
    public function getDirectory()
144
    {
145
        return Tools::getDirectoryFromNamespace($this->getNamespace());
146
    }
147
148
    /**
149
     * Return namespace without name - for rendering namespace in class
150
     *
151
     * @return string
152
     * @throws Exception
153
     */
154
    public function getNamespaceWithoutNameAndBackslashPrefix()
155
    {
156
        return Tools::removeBackslashPrefixFromNamespace(Tools::getNamespaceWithoutName($this->getNamespace()));
157
    }
158
159
    /**
160
     * Return set of tags used in template
161
     *
162
     * @return array
163
     */
164
    public function getTemplateTags()
165
    {
166
        return [
167
            self::TAG_NAMESPACE,
168
            self::TAG_COMMENT,
169
            self::TAG_NAME,
170
            self::TAG_METHODS,
171
        ];
172
    }
173
}
174