Completed
Pull Request — develop (#323)
by Mathias
15:36
created

Node::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2016 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\Entity\Tree;
12
13
use Core\Entity\Collection\ArrayCollection;
14
use Core\Entity\EntityTrait;
15
use Core\Entity\IdentifiableEntityTrait;
16
use Doctrine\Common\Collections\Collection;
17
use \Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
18
19
/**
20
 * base class for trees.
21
 *
22
 * @ODM\MappedSuperclass
23
 * @author Mathias Gelhausen <[email protected]>
24
 * @since 0.29
25
 */
26
class Node implements NodeInterface
27
{
28
    use EntityTrait, IdentifiableEntityTrait;
29
30
    /**
31
     * Name of this item.
32
     *
33
     * @ODM\Field(type="string")
34
     * @var string
35
     */
36
    protected $name;
37
38
    /**
39
     * Value of this item.
40
     *
41
     * Used in select form elements.
42
     *
43
     * @ODM\Field(type="string")
44
     * @var string
45
     */
46
    protected $value;
47
48
    /**
49
     * Order priority.
50
     *
51
     * @ODM\Field(type="int")
52
     * @var int
53
     */
54
    protected $priority = 0;
55
56
    /**
57
     * Child nodes.
58
     *
59
     * @ODM\ReferenceMany(discriminatorField="_entity", storeAs="dbRef", strategy="set", sort={"priority"="asc"}, cascade="all", orphanRemoval="true")
60
     * @var Collection
61
     */
62
    protected $children;
63
64
    /**
65
     * Parent node.
66
     *
67
     * @ODM\ReferenceOne(discriminatorField="_entity", storeAs="dbRef", nullable="true")
68
     * @var
69
     */
70
    protected $parent;
71
72
    /**
73
     * Creates a new Tree item.
74
     *
75
     * @param null|string $name
76
     * @param null|string $value
77
     * @param int  $priority
78
     */
79
    public function __construct($name = null, $value = null, $priority = 0)
80
    {
81
        if (null !== $name) {
82
            $this->setName($name);
83
            $this->setValue($value);
84
            $this->setPriority($priority);
85
        }
86
    }
87
88
    /**
89
     * Set the name.
90
     *
91
     * @param string $name
92
     *
93
     * @return self
94
     * @throws \InvalidArgumentException if $name is empty.
95
     */
96
    public function setName($name)
97
    {
98
        if (!$name) {
99
            throw new \InvalidArgumentException('Name must not be empty.');
100
        }
101
102
        $this->name = (string) $name;
103
104
        return $this;
105
    }
106
107
    public function getName()
108
    {
109
        return $this->name;
110
    }
111
112
    /**
113
     * Set the value.
114
     *
115
     * Used in form selects.
116
     *
117
     * @param string $value
118
     *
119
     * @return self
120
     * @throws \InvalidArgumentException if $value AND {@link name} are empty.
121
     */
122
    public function setValue($value)
123
    {
124
        if (!$value) {
125
            if (!$this->getName()) {
126
                throw new \InvalidArgumentException('Value must not be empty.');
127
            }
128
            $value = strtolower(str_replace(' ', '-', $this->getName()));
129
        }
130
131
        $this->value = (string) $value;
132
133
        return $this;
134
    }
135
136
    public function getValue()
137
    {
138
        if (!$this->value) {
139
            $this->setValue(null);
140
        }
141
142
        return $this->value;
143
    }
144
145
    public function setPriority($priority)
146
    {
147
        $this->priority = (int) $priority;
148
149
        return $this;
150
    }
151
152
    public function getPriority()
153
    {
154
        return $this->priority;
155
    }
156
157
    public function setChildren(Collection $children)
158
    {
159
        $this->children = $children;
160
161
        /* @var NodeInterface $child */
162
        foreach ($children as $child) {
163
            $child->setParent($this);
164
        }
165
166
        return $this;
167
    }
168
169
    public function getChildren()
170
    {
171
        if (!$this->children) {
172
            $this->setChildren(new ArrayCollection());
173
        }
174
175
        return $this->children;
176
    }
177
178
    public function hasChildren()
179
    {
180
        return (bool) $this->getChildren()->count();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Traversable as the method count() does only exist in the following implementations of said interface: Applications\Form\Apply, Applications\Form\Attributes, Applications\Form\Base, Applications\Form\BaseFieldset, Applications\Form\CarbonCopyFieldset, Applications\Form\CommentForm, Applications\Form\ContactContainer, Applications\Form\Facts, Applications\Form\FactsFieldset, Applications\Form\FilterApplication, Applications\Form\Mail, Applications\Form\SettingsFieldset, ArrayIterator, ArrayObject, Assetic\Extension\Twig\ValueContainer, Assetic\Filter\FilterCollection, Assetic\Util\TraversableString, Auth\Form\ForgotPassword, Auth\Form\Group, Auth\Form\GroupFieldset, Auth\Form\GroupUsersCollection, Auth\Form\Login, Auth\Form\Register, Auth\Form\SocialProfiles, Auth\Form\SocialProfilesFieldset, Auth\Form\UserBase, Auth\Form\UserBaseFieldset, Auth\Form\UserInfo, Auth\Form\UserInfoContainer, Auth\Form\UserInfoFieldset, Auth\Form\UserPassword, Auth\Form\UserPasswordFieldset, Auth\Form\UserProfileContainer, Auth\Form\UserStatus, Auth\Form\UserStatusContainer, Auth\Form\UserStatusFieldset, CachingIterator, Core\Collection\IdentityWrapper, Core\Entity\Collection\ArrayCollection, Core\Form\BaseForm, Core\Form\ButtonsFieldset, Core\Form\CollectionContainer, Core\Form\Container, Core\Form\DefaultButtonsFieldset, Core\Form\Form, Core\Form\FormSubmitButtonsFieldset, Core\Form\ListFilterButtonsFieldset, Core\Form\LocalizationSettingsFieldset, Core\Form\PermissionsCollection, Core\Form\PermissionsFieldset, Core\Form\RatingFieldset, Core\Form\SummaryForm, Core\Form\SummaryFormButtonsFieldset, Core\Form\TextSearchForm, Core\Form\TextSearchFormButtonsFieldset, Core\Form\TextSearchFormFieldset, Core\Form\Tree\AddItemFieldset, Core\Form\Tree\ManagementFieldset, Core\Form\Tree\ManagementForm, Core\Form\ViewPartialProviderAbstract, Core\Form\WizardContainer, Cv\Form\CvContainer, Cv\Form\EducationFieldset, Cv\Form\EducationForm, Cv\Form\EmploymentFieldset, Cv\Form\EmploymentForm, Cv\Form\LanguageSkillFieldset, Cv\Form\LanguageSkillForm, Cv\Form\NativeLanguageFieldset, Cv\Form\NativeLanguageForm, Cv\Form\PreferredJobFieldset, Cv\Form\PreferredJobForm, Cv\Form\SearchForm, Cv\Form\SearchFormFieldset, Cv\Form\SkillFieldset, Cv\Form\SkillForm, DoctrineTest\Instantiato...tAsset\ArrayObjectAsset, DoctrineTest\InstantiatorTestAsset\PharAsset, DoctrineTest\Instantiato...lizableArrayObjectAsset, DoctrineTest\Instantiato...ceptionArrayObjectAsset, DoctrineTest\Instantiato...sset\WakeUpNoticesAsset, Doctrine\Common\Collections\AbstractLazyCollection, Doctrine\Common\Collections\ArrayCollection, Doctrine\MongoDB\ArrayIterator, Doctrine\MongoDB\CommandCursor, Doctrine\MongoDB\Cursor, Doctrine\MongoDB\EagerCursor, Doctrine\MongoDB\LoggableCursor, Doctrine\MongoDB\Query\Query, Doctrine\ODM\MongoDB\Cursor, Doctrine\ODM\MongoDB\EagerCursor, Doctrine\ODM\MongoDB\PersistentCollection, Doctrine\ODM\MongoDB\Query\Query, Doctrine\ODM\MongoDB\Tools\Console\MetadataFilter, GeoJson\Feature\FeatureCollection, GeoJson\Geometry\GeometryCollection, GlobIterator, Guzzle\Common\Collection, Guzzle\Common\Exception\ExceptionCollection, Guzzle\Http\Exception\MultiTransferException, Guzzle\Http\Message\Header, Guzzle\Http\Message\Header\CacheControl, Guzzle\Http\Message\Header\HeaderCollection, Guzzle\Http\Message\Header\Link, Guzzle\Http\QueryString, Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar, Guzzle\Plugin\Cookie\CookieJar\FileCookieJar, Guzzle\Plugin\History\HistoryPlugin, Guzzle\Service\Command\AbstractCommand, Guzzle\Service\Command\ClosureCommand, Guzzle\Service\Command\Factory\CompositeFactory, Guzzle\Service\Command\OperationCommand, Guzzle\Service\Exception\CommandTransferException, Guzzle\Service\Resource\Model, Guzzle\Service\Resource\ResourceIterator, Guzzle\Tests\Service\Mock\Command\IterableCommand, Guzzle\Tests\Service\Mock\Command\MockCommand, Guzzle\Tests\Service\Mock\Command\OtherCommand, Guzzle\Tests\Service\Mock\Command\Sub\Sub, Guzzle\Tests\Service\Moc...del\MockCommandIterator, HTMLPurifier_StringHash, HttpMessage, HttpRequestPool, Install\Form\Installation, Issue523, Jobs\Form\AdminJobEdit, Jobs\Form\AdminSearchForm, Jobs\Form\AdminSearchFormElementsFieldset, Jobs\Form\AtsMode, Jobs\Form\AtsModeFieldset, Jobs\Form\Base, Jobs\Form\BaseFieldset, Jobs\Form\CategoriesContainer, Jobs\Form\ClassificationsFieldset, Jobs\Form\ClassificationsForm, Jobs\Form\CompanyName, Jobs\Form\CompanyNameFieldset, Jobs\Form\Import, Jobs\Form\ImportFieldset, Jobs\Form\Job, Jobs\Form\JobDescription, Jobs\Form\JobDescriptionBenefits, Jobs\Form\JobDescriptionDescription, Jobs\Form\JobDescriptionFieldset, Jobs\Form\JobDescriptionQualifications, Jobs\Form\JobDescriptionRequirements, Jobs\Form\JobDescriptionTemplate, Jobs\Form\JobDescriptionTitle, Jobs\Form\ListFilter, Jobs\Form\ListFilterAdmin, Jobs\Form\ListFilterAdminFieldset, Jobs\Form\ListFilterBaseFieldset, Jobs\Form\ListFilterLocation, Jobs\Form\ListFilterLocationFieldset, Jobs\Form\ListFilterPersonal, Jobs\Form\ListFilterPersonalFieldset, Jobs\Form\Multipost, Jobs\Form\MultipostButtonFieldset, Jobs\Form\MultipostFieldset, Jobs\Form\Preview, Jobs\Form\PreviewFieldset, Jobs\Form\TemplateLabelBenefits, Jobs\Form\TemplateLabelQualifications, Jobs\Form\TemplateLabelRequirements, MongoCursor, MongoGridFSCursor, Orders\Form\InvoiceAddress, Orders\Form\InvoiceAddressFieldset, Orders\Form\InvoiceAddressSettingsFieldset, Organizations\Form\EmployeeFieldset, Organizations\Form\Employees, Organizations\Form\EmployeesFieldset, Organizations\Form\Organizations, Organizations\Form\OrganizationsContactFieldset, Organizations\Form\OrganizationsContactForm, Organizations\Form\Organ...ionsDescriptionFieldset, Organizations\Form\OrganizationsDescriptionForm, Organizations\Form\OrganizationsFieldset, Organizations\Form\OrganizationsNameFieldset, Organizations\Form\OrganizationsNameForm, Organizations\Form\WorkflowSettings, Organizations\Form\WorkflowSettingsFieldset, PHPUnit_Extensions_GroupTestSuite, PHPUnit_Extensions_PhptTestSuite, PHPUnit_Framework_TestSuite, PHPUnit_Framework_TestSuite_DataProvider, PHP_Token_Stream, Phar, PharData, RecursiveArrayIterator, RecursiveCachingIterator, SQLiteResult, SebastianBergmann\CodeCoverage\Node\Directory, Settings\Form\AbstractSettingsForm, Settings\Form\DisableEle...bleFormSettingsFieldset, Settings\Form\FormAbstract, Settings\Form\Settings, Settings\Form\SettingsFieldset, SimpleXMLElement, SimpleXMLIterator, SplDoublyLinkedList, SplFixedArray, SplHeap, SplMaxHeap, SplMinHeap, SplObjectStorage, SplPriorityQueue, SplQueue, SplStack, Zend\Cache\Storage\Adapter\KeyListIterator, Zend\Code\Annotation\AnnotationCollection, Zend\Code\Scanner\AnnotationScanner, Zend\Config\Config, Zend\Db\Adapter\Driver\IbmDb2\Result, Zend\Db\Adapter\Driver\Mysqli\Result, Zend\Db\Adapter\Driver\Oci8\Result, Zend\Db\Adapter\Driver\Pdo\Result, Zend\Db\Adapter\Driver\Pgsql\Result, Zend\Db\Adapter\Driver\Sqlsrv\Result, Zend\Db\Adapter\ParameterContainer, Zend\Db\ResultSet\AbstractResultSet, Zend\Db\ResultSet\HydratingResultSet, Zend\Db\ResultSet\ResultSet, Zend\Db\Sql\Join, Zend\Di\DefinitionList, Zend\Dom\Document\NodeList, Zend\Dom\NodeList, Zend\EventManager\ResponseCollection, Zend\Feed\Reader\AbstractFeed, Zend\Feed\Reader\Collection, Zend\Feed\Reader\Collection\AbstractCollection, Zend\Feed\Reader\Collection\Author, Zend\Feed\Reader\Collection\Category, Zend\Feed\Reader\Collection\Collection, Zend\Feed\Reader\FeedSet, Zend\Feed\Reader\Feed\AbstractFeed, Zend\Feed\Reader\Feed\Atom, Zend\Feed\Reader\Feed\Atom\Source, Zend\Feed\Reader\Feed\Rss, Zend\Feed\Writer\Feed, Zend\Form\Element\Collection, Zend\Form\Fieldset, Zend\Form\Form, Zend\Form\InputFilterProviderFieldset, Zend\Http\Cookies, Zend\Http\Header\Cookie, Zend\Http\Headers, Zend\I18n\Translator\TextDomain, Zend\Mail\AddressList, Zend\Mail\Headers, Zend\Mail\Storage\AbstractStorage, Zend\Mail\Storage\Folder\Maildir, Zend\Mail\Storage\Folder\Mbox, Zend\Mail\Storage\Imap, Zend\Mail\Storage\Maildir, Zend\Mail\Storage\Mbox, Zend\Mail\Storage\Pop3, Zend\Mail\Storage\Writable\Maildir, Zend\Mvc\Controller\Plugin\FlashMessenger, Zend\Mvc\Router\PriorityList, Zend\Navigation\AbstractContainer, Zend\Navigation\Navigation, Zend\Navigation\Page\AbstractPage, Zend\Navigation\Page\Mvc, Zend\Navigation\Page\Uri, Zend\Paginator\Paginator, Zend\Server\Definition, Zend\Session\AbstractContainer, Zend\Session\Container, Zend\Session\Storage\AbstractSessionArrayStorage, Zend\Session\Storage\ArrayStorage, Zend\Session\Storage\SessionArrayStorage, Zend\Session\Storage\SessionStorage, Zend\Stdlib\ArrayObject, Zend\Stdlib\ArrayStack, Zend\Stdlib\FastPriorityQueue, Zend\Stdlib\Parameters, Zend\Stdlib\PriorityList, Zend\Stdlib\PriorityQueue, Zend\Stdlib\SplPriorityQueue, Zend\Stdlib\SplQueue, Zend\Stdlib\SplStack, Zend\Tag\ItemList, Zend\View\Helper\HeadLink, Zend\View\Helper\HeadMeta, Zend\View\Helper\HeadScript, Zend\View\Helper\HeadStyle, Zend\View\Helper\HeadTitle, Zend\View\Helper\InlineScript, Zend\View\Helper\Placeholder\Container, Zend\View\Helper\Placeho...ainer\AbstractContainer, Zend\View\Helper\Placeho...iner\AbstractStandalone, Zend\View\Model\ConsoleModel, Zend\View\Model\FeedModel, Zend\View\Model\JsonModel, Zend\View\Model\ViewModel, Zend\View\Resolver\AggregateResolver, Zend\View\Variables.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements 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 implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
181
    }
182
183
    public function addChild(NodeInterface $child)
184
    {
185
        $this->getChildren()->add($child);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Traversable as the method add() does only exist in the following implementations of said interface: Applications\Form\Attributes, Applications\Form\Base, Applications\Form\BaseFieldset, Applications\Form\CarbonCopyFieldset, Applications\Form\CommentForm, Applications\Form\Facts, Applications\Form\FactsFieldset, Applications\Form\FilterApplication, Applications\Form\Mail, Applications\Form\SettingsFieldset, Assetic\Asset\AssetCollection, Assetic\Asset\GlobAsset, Auth\Form\ForgotPassword, Auth\Form\Group, Auth\Form\GroupFieldset, Auth\Form\GroupUsersCollection, Auth\Form\Login, Auth\Form\Register, Auth\Form\SocialProfiles, Auth\Form\SocialProfilesFieldset, Auth\Form\UserBase, Auth\Form\UserBaseFieldset, Auth\Form\UserInfo, Auth\Form\UserInfoFieldset, Auth\Form\UserPassword, Auth\Form\UserPasswordFieldset, Auth\Form\UserStatus, Auth\Form\UserStatusFieldset, Core\Collection\IdentityWrapper, Core\Entity\Collection\ArrayCollection, Core\Form\BaseForm, Core\Form\ButtonsFieldset, Core\Form\DefaultButtonsFieldset, Core\Form\Form, Core\Form\FormSubmitButtonsFieldset, Core\Form\ListFilterButtonsFieldset, Core\Form\LocalizationSettingsFieldset, Core\Form\PermissionsCollection, Core\Form\PermissionsFieldset, Core\Form\RatingFieldset, Core\Form\SummaryForm, Core\Form\SummaryFormButtonsFieldset, Core\Form\TextSearchForm, Core\Form\TextSearchFormButtonsFieldset, Core\Form\TextSearchFormFieldset, Core\Form\Tree\AddItemFieldset, Core\Form\Tree\ManagementFieldset, Core\Form\Tree\ManagementForm, Cv\Form\EducationFieldset, Cv\Form\EducationForm, Cv\Form\EmploymentFieldset, Cv\Form\EmploymentForm, Cv\Form\LanguageSkillFieldset, Cv\Form\LanguageSkillForm, Cv\Form\NativeLanguageFieldset, Cv\Form\NativeLanguageForm, Cv\Form\PreferredJobFieldset, Cv\Form\PreferredJobForm, Cv\Form\SearchForm, Cv\Form\SearchFormFieldset, Cv\Form\SkillFieldset, Cv\Form\SkillForm, Doctrine\Common\Collections\AbstractLazyCollection, Doctrine\Common\Collections\ArrayCollection, Doctrine\ODM\MongoDB\PersistentCollection, Guzzle\Common\Collection, Guzzle\Common\Exception\ExceptionCollection, Guzzle\Http\Exception\MultiTransferException, Guzzle\Http\Message\Header, Guzzle\Http\Message\Header\CacheControl, Guzzle\Http\Message\Header\HeaderCollection, Guzzle\Http\Message\Header\Link, Guzzle\Http\QueryString, Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar, Guzzle\Plugin\Cookie\CookieJar\FileCookieJar, Guzzle\Plugin\History\HistoryPlugin, Guzzle\Service\Command\AbstractCommand, Guzzle\Service\Command\ClosureCommand, Guzzle\Service\Command\Factory\CompositeFactory, Guzzle\Service\Command\OperationCommand, Guzzle\Service\Exception\CommandTransferException, Guzzle\Service\Resource\Model, Guzzle\Tests\Service\Mock\Command\IterableCommand, Guzzle\Tests\Service\Mock\Command\MockCommand, Guzzle\Tests\Service\Mock\Command\OtherCommand, Guzzle\Tests\Service\Mock\Command\Sub\Sub, Install\Form\Installation, Jobs\Form\AdminJobEdit, Jobs\Form\AdminSearchForm, Jobs\Form\AdminSearchFormElementsFieldset, Jobs\Form\AtsMode, Jobs\Form\AtsModeFieldset, Jobs\Form\Base, Jobs\Form\BaseFieldset, Jobs\Form\ClassificationsFieldset, Jobs\Form\ClassificationsForm, Jobs\Form\CompanyName, Jobs\Form\CompanyNameFieldset, Jobs\Form\Import, Jobs\Form\ImportFieldset, Jobs\Form\JobDescriptionBenefits, Jobs\Form\JobDescriptionDescription, Jobs\Form\JobDescriptionFieldset, Jobs\Form\JobDescriptionQualifications, Jobs\Form\JobDescriptionRequirements, Jobs\Form\JobDescriptionTitle, Jobs\Form\ListFilter, Jobs\Form\ListFilterAdmin, Jobs\Form\ListFilterAdminFieldset, Jobs\Form\ListFilterBaseFieldset, Jobs\Form\ListFilterLocation, Jobs\Form\ListFilterLocationFieldset, Jobs\Form\ListFilterPersonal, Jobs\Form\ListFilterPersonalFieldset, Jobs\Form\Multipost, Jobs\Form\MultipostButtonFieldset, Jobs\Form\MultipostFieldset, Jobs\Form\Preview, Jobs\Form\PreviewFieldset, Jobs\Form\TemplateLabelBenefits, Jobs\Form\TemplateLabelQualifications, Jobs\Form\TemplateLabelRequirements, Orders\Form\InvoiceAddress, Orders\Form\InvoiceAddressFieldset, Orders\Form\InvoiceAddressSettingsFieldset, Organizations\Form\EmployeeFieldset, Organizations\Form\Employees, Organizations\Form\EmployeesFieldset, Organizations\Form\OrganizationsContactFieldset, Organizations\Form\OrganizationsContactForm, Organizations\Form\Organ...ionsDescriptionFieldset, Organizations\Form\OrganizationsDescriptionForm, Organizations\Form\OrganizationsFieldset, Organizations\Form\OrganizationsNameFieldset, Organizations\Form\OrganizationsNameForm, Organizations\Form\WorkflowSettings, Organizations\Form\WorkflowSettingsFieldset, Settings\Form\AbstractSettingsForm, Settings\Form\DisableEle...bleFormSettingsFieldset, Settings\Form\FormAbstract, Settings\Form\Settings, Settings\Form\SettingsFieldset, Zend\Form\Element\Collection, Zend\Form\Fieldset, Zend\Form\Form, Zend\Form\InputFilterProviderFieldset, Zend\Mail\AddressList, Zend\View\Resolver\TemplateMapResolver.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements 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 implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
186
        $child->setParent($this);
187
188
        return $this;
189
    }
190
191
    public function removeChild(NodeInterface $child)
192
    {
193
        $this->getChildren()->removeElement($child);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Traversable as the method removeElement() does only exist in the following implementations of said interface: Core\Collection\IdentityWrapper, Core\Entity\Collection\ArrayCollection, Doctrine\Common\Collections\AbstractLazyCollection, Doctrine\Common\Collections\ArrayCollection, Doctrine\ODM\MongoDB\PersistentCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements 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 implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
194
195
        return $this;
196
    }
197
198
    public function clearChildren()
199
    {
200
        $this->getChildren()->clear();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Traversable as the method clear() does only exist in the following implementations of said interface: Assetic\Filter\FilterCollection, Core\Collection\IdentityWrapper, Core\Entity\Collection\ArrayCollection, Doctrine\Common\Collections\AbstractLazyCollection, Doctrine\Common\Collections\ArrayCollection, Doctrine\ODM\MongoDB\PersistentCollection, Guzzle\Common\Collection, Guzzle\Http\Message\Header\HeaderCollection, Guzzle\Http\QueryString, Guzzle\Plugin\History\HistoryPlugin, Guzzle\Service\Command\AbstractCommand, Guzzle\Service\Command\ClosureCommand, Guzzle\Service\Command\OperationCommand, Guzzle\Service\Resource\Model, Guzzle\Tests\Service\Mock\Command\IterableCommand, Guzzle\Tests\Service\Mock\Command\MockCommand, Guzzle\Tests\Service\Mock\Command\OtherCommand, Guzzle\Tests\Service\Mock\Command\Sub\Sub, Imagick, ImagickPixelIterator, SolrDocument, Zend\Mvc\Router\PriorityList, Zend\Session\Storage\AbstractSessionArrayStorage, Zend\Session\Storage\ArrayStorage, Zend\Session\Storage\SessionArrayStorage, Zend\Session\Storage\SessionStorage, Zend\Stdlib\PriorityList, Zend\View\Variables.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements 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 implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
201
202
        return $this;
203
    }
204
205
    public function setParent(NodeInterface $parent)
206
    {
207
        $this->parent = $parent;
208
209
        return $this;
210
    }
211
212
    public function getParent()
213
    {
214
        return $this->parent;
215
    }
216
}