Completed
Push — master ( b035c8...ddcf44 )
by Paweł
02:10
created

News::addGenres()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 13
ccs 7
cts 7
cp 1
crap 3
rs 9.8333
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Wszetko\Sitemap\Items;
5
6
use DateTimeInterface;
7
8
/**
9
 * Class News
10
 *
11
 * @package Wszetko\Sitemap\Items
12
 * @method setPublicationDate($publicationDate)
13
 * @method getPublicationDate()
14
 * @method setPublicationName($publicationName)
15
 * @method getPublicationName()
16
 * @method setPublicationLanguage($publicationLanguage)
17
 * @method getPublicationLanguage()
18
 * @method setAccess($access)
19
 * @method getAccess()
20
 * @method setTitle($title)
21
 * @method getTitle()
22
 * @method setGenres($genres)
23
 * @method addGenres($genres)
24
 * @method getGenres()
25
 * @method setKeywords($keywords)
26
 * @method addKeywords($keywords)
27
 * @method getKeywords()
28
 * @method setStockTickers($stockTickers)
29
 * @method addStockTickers($stockTickers)
30
 * @method getStockTickers()
31
 */
32
class News extends Extension
33
{
34
    /**
35
     * Name of Namescapce
36
     */
37
    const NAMESPACE_NAME = 'news';
38
39
    /**
40
     * Namespace URL
41
     */
42
    const NAMESPACE_URL = 'http://www.google.com/schemas/sitemap-news/0.9';
43
44
    /**
45
     * Element name
46
     */
47
    const ELEMENT_NAME = 'news';
48
49
    /**
50
     * Publication name.
51
     *
52
     * @var \Wszetko\Sitemap\Items\DataTypes\StringType
53
     */
54
    protected $publicationName;
55
56
    /**
57
     * Publication language.
58
     *
59
     * @var \Wszetko\Sitemap\Items\DataTypes\StringType
60
     */
61
    protected $publicationLanguage;
62
63
    /**
64
     * Access.
65
     *
66
     * @var \Wszetko\Sitemap\Items\DataTypes\StringType
67
     */
68
    protected $access;
69
70
    /**
71
     * List of genres, comma-separated string values.
72
     *
73
     * @dataType \Wszetko\Sitemap\Items\DataTypes\StringType
74
     * @var \Wszetko\Sitemap\Items\DataTypes\ArrayType
75
     */
76
    protected $genres;
77
78
    /**
79
     * Date of publication.
80
     *
81
     * @var \Wszetko\Sitemap\Items\DataTypes\DateTimeType
82
     */
83
    protected $publicationDate;
84
85
    /**
86
     * Title.
87
     *
88
     * @var \Wszetko\Sitemap\Items\DataTypes\StringType
89
     */
90
    protected $title;
91
92
    /**
93
     * Key words, comma-separated string values.
94
     *
95
     * @dataType \Wszetko\Sitemap\Items\DataTypes\StringType
96
     * @var \Wszetko\Sitemap\Items\DataTypes\ArrayType
97
     */
98
    protected $keywords;
99
100
    /**
101
     * Key words, comma-separated string values.
102
     *
103
     * @dataType \Wszetko\Sitemap\Items\DataTypes\StringType
104
     * @var \Wszetko\Sitemap\Items\DataTypes\ArrayType
105
     */
106
    protected $stockTickers;
107
108
    /**
109
     * News constructor.
110
     *
111
     * @param string                   $publicationName
112
     * @param string                   $publicationLanguage
113
     * @param DateTimeInterface|string $publicationDate
114
     * @param string                   $title
115
     *
116
     * @throws \ReflectionException
117
     */
118 14
    public function __construct(
119
        string $publicationName,
120
        string $publicationLanguage,
121
        $publicationDate,
122
        string $title
123
    ) {
124 14
        parent::__construct();
125
126 14
        $this->publicationName
127 14
            ->setRequired(true);
128 14
        $this->setPublicationName($publicationName);
129 13
        $this->publicationLanguage
130 13
            ->setValueRegex("/^(?'lang'zh-cn|zh-tw|([a-z]{2,3}))?$/", 'lang')
131 13
            ->setRequired(true);
132 13
        $this->publicationDate
133 13
            ->setRequired(true);
134 13
        $this->setPublicationLanguage($publicationLanguage);
135 12
        $this->setPublicationDate($publicationDate);
136 10
        $this->setTitle($title);
137 10
        $this->access
138 10
            ->setAllowedValues('Subscription, Registration');
139 10
        $this->genres
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Wszetko\Sitemap\Items\DataTypes\AbstractDataType as the method setAllowedValues() does only exist in the following sub-classes of Wszetko\Sitemap\Items\DataTypes\AbstractDataType: Wszetko\Sitemap\Items\DataTypes\ExternalURLType, Wszetko\Sitemap\Items\DataTypes\StringType, Wszetko\Sitemap\Items\DataTypes\URLType. 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

  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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
140 10
            ->getBaseDataType()
141 10
            ->setAllowedValues('PressRelease, Satire, Blog, OpEd, Opinion, UserGenerated');
142 10
        $this->stockTickers
0 ignored issues
show
Bug introduced by
The method setValueRegex() does not exist on Wszetko\Sitemap\Items\DataTypes\AbstractDataType. Did you maybe mean setValue()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
143 10
            ->setMaxElements(5)
144 10
            ->getBaseDataType()
145 10
            ->setValueRegex("/^(?'stockTickers'\w+:\w+)?$/", 'stockTickers');
146 10
    }
147
148
    /**
149
     * @return array
150
     */
151 1
    public function toArray(): array
152
    {
153
        $array = [
154 1
            '_namespace' => static::NAMESPACE_NAME,
155 1
            '_element' => 'news',
156
            'news' => [
157
                'publication' => [
158 1
                    'name' => $this->getPublicationName(),
159 1
                    'language' => $this->getPublicationLanguage()
160
                ],
161 1
                'publication_date' => $this->getPublicationDate(),
162 1
                'title' => $this->getTitle()
163
            ]
164
        ];
165
166 1
        if ($this->getAccess()) {
167 1
            $array['news']['access'] = $this->getAccess();
168
        }
169
170 1
        if ($this->getGenres()) {
171 1
            $array['news']['genres'] = implode(', ', $this->getGenres());
172
        }
173
174 1
        if ($this->getKeywords()) {
175 1
            $array['news']['keywords'] = implode(',', $this->getKeywords());
176
        }
177
178 1
        if ($this->getStockTickers()) {
179 1
            $array['news']['stock_tickers'] = implode(', ', $this->getStockTickers());
180
        }
181
182 1
        return $array;
183
    }
184
}
185