These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * phpDocumentor |
||
4 | * |
||
5 | * PHP Version 5.3 |
||
6 | * |
||
7 | * @copyright 2010-2014 Mike van Riel / Naenius (http://www.naenius.com) |
||
8 | * @license http://www.opensource.org/licenses/mit-license.php MIT |
||
9 | * @link http://phpdoc.org |
||
10 | */ |
||
11 | |||
12 | namespace phpDocumentor\Plugin\Core\Transformer\Writer\Xml; |
||
13 | |||
14 | use phpDocumentor\Descriptor\TagDescriptor; |
||
15 | |||
16 | /** |
||
17 | * Creates an XML Element 'tag' and appends it to the provided parent element. |
||
18 | * |
||
19 | * With this class we convert a TagDescriptor, or any child thereof, into an XML element that is subsequently appended |
||
20 | * onto a provided parent element (usually an XML Element that represents a DocBlock). |
||
21 | * |
||
22 | * During the conversion process the generated XML Element is enriched with additional elements and attributes based on |
||
23 | * which tags are provided (or more specifically which methods that support). |
||
24 | */ |
||
25 | class TagConverter |
||
26 | { |
||
27 | /** |
||
28 | * Export this tag to the given DocBlock. |
||
29 | * |
||
30 | * @param \DOMElement $parent Element to augment. |
||
31 | * @param TagDescriptor $tag The tag to export. |
||
32 | * |
||
33 | * @return \DOMElement |
||
34 | */ |
||
35 | 8 | public function convert(\DOMElement $parent, TagDescriptor $tag) |
|
36 | { |
||
37 | 8 | $description = $this->getDescription($tag); |
|
38 | |||
39 | 8 | $child = new \DOMElement('tag'); |
|
40 | 8 | $parent->appendChild($child); |
|
41 | |||
42 | 8 | $child->setAttribute('name', str_replace('&', '&', $tag->getName())); |
|
43 | 8 | $child->setAttribute('line', $parent->getAttribute('line')); |
|
44 | 8 | $child->setAttribute('description', str_replace('&', '&', $description)); |
|
45 | 8 | $this->addTypes($tag, $child); |
|
46 | |||
47 | // TODO: make the tests below configurable from the outside so that more could be added using plugins |
||
48 | 8 | if (method_exists($tag, 'getVariableName')) { |
|
49 | 2 | $child->setAttribute('variable', str_replace('&', '&', $tag->getVariableName())); |
|
0 ignored issues
–
show
|
|||
50 | } |
||
51 | 8 | if (method_exists($tag, 'getReference')) { |
|
52 | 1 | $child->setAttribute('link', str_replace('&', '&', $tag->getReference())); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
phpDocumentor\Descriptor\TagDescriptor as the method getReference() does only exist in the following sub-classes of phpDocumentor\Descriptor\TagDescriptor : phpDocumentor\Descriptor\Tag\SeeDescriptor , phpDocumentor\Descriptor\Tag\UsesDescriptor . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
53 | } |
||
54 | 8 | if (method_exists($tag, 'getLink')) { |
|
55 | 1 | $child->setAttribute('link', str_replace('&', '&', $tag->getLink())); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
phpDocumentor\Descriptor\TagDescriptor as the method getLink() does only exist in the following sub-classes of phpDocumentor\Descriptor\TagDescriptor : phpDocumentor\Descriptor\Tag\LinkDescriptor . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
56 | } |
||
57 | 8 | if (method_exists($tag, 'getMethodName')) { |
|
58 | 1 | $child->setAttribute('method_name', str_replace('&', '&', $tag->getMethodName())); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
phpDocumentor\Descriptor\TagDescriptor as the method getMethodName() does only exist in the following sub-classes of phpDocumentor\Descriptor\TagDescriptor : phpDocumentor\Descriptor\Tag\MethodDescriptor . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
59 | } |
||
60 | |||
61 | 8 | return $child; |
|
62 | } |
||
63 | |||
64 | /** |
||
65 | * Returns the description from the Tag with the version prepended when applicable. |
||
66 | * |
||
67 | * @param TagDescriptor $tag |
||
68 | * |
||
69 | * @todo the version should not be prepended here but in templates; remove this. |
||
70 | * |
||
71 | * @return string |
||
72 | */ |
||
73 | 8 | protected function getDescription(TagDescriptor $tag) |
|
74 | { |
||
75 | 8 | $description = ''; |
|
76 | |||
77 | //@version, @deprecated, @since |
||
78 | 8 | if (method_exists($tag, 'getVersion')) { |
|
79 | 1 | $description .= $tag->getVersion() . ' '; |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
phpDocumentor\Descriptor\TagDescriptor as the method getVersion() does only exist in the following sub-classes of phpDocumentor\Descriptor\TagDescriptor : phpDocumentor\Descriptor\Tag\DeprecatedDescriptor , phpDocumentor\Descriptor\Tag\SinceDescriptor , phpDocumentor\Descriptor\Tag\VersionDescriptor . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
80 | } |
||
81 | |||
82 | 8 | $description .= $tag->getDescription(); |
|
83 | |||
84 | 8 | return trim($description); |
|
85 | } |
||
86 | |||
87 | /** |
||
88 | * Adds type elements and a type attribute to the tag if a method 'getTypes' is present. |
||
89 | * |
||
90 | * @param TagDescriptor $tag |
||
91 | * @param \DOMElement $child |
||
92 | * |
||
93 | * @return void |
||
94 | */ |
||
95 | 8 | protected function addTypes(TagDescriptor $tag, \DOMElement $child) |
|
96 | { |
||
97 | 8 | if (!method_exists($tag, 'getTypes')) { |
|
98 | 6 | return; |
|
99 | } |
||
100 | |||
101 | 2 | $typeString = ''; |
|
102 | 2 | foreach ($tag->getTypes() as $type) { |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
phpDocumentor\Descriptor\TagDescriptor as the method getTypes() does only exist in the following sub-classes of phpDocumentor\Descriptor\TagDescriptor : phpDocumentor\Descriptor...BaseTypes\TypedAbstract , phpDocumentor\Descriptor...s\TypedVariableAbstract , phpDocumentor\Descriptor\Tag\ParamDescriptor , phpDocumentor\Descriptor\Tag\PropertyDescriptor , phpDocumentor\Descriptor\Tag\ReturnDescriptor , phpDocumentor\Descriptor\Tag\ThrowsDescriptor , phpDocumentor\Descriptor\Tag\VarDescriptor . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
103 | 1 | $typeString .= $type . '|'; |
|
104 | |||
105 | /** @var \DOMElement $typeNode */ |
||
106 | 1 | $typeNode = $child->appendChild(new \DOMElement('type')); |
|
107 | 1 | $typeNode->appendChild(new \DOMText($type)); |
|
108 | } |
||
109 | |||
110 | 2 | $child->setAttribute('type', str_replace('&', '&', rtrim($typeString, '|'))); |
|
111 | 2 | } |
|
112 | } |
||
113 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: