AbstractObject::getId()   A
last analyzed

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
namespace Trello\Model;
4
5
use Trello\ClientInterface;
6
use Trello\Api\ApiInterface;
7
use Trello\Exception\BadMethodCallException;
8
9
/**
10
 * @codeCoverageIgnore
11
 */
12
abstract class AbstractObject
13
{
14
    /**
15
     * @var ClientInterface
16
     */
17
    protected $client;
18
19
    /**
20
     * @var string
21
     */
22
    protected $apiName;
23
24
    /**
25
     * @var ApiInterface
26
     */
27
    protected $api;
28
29
    /**
30
     * @var array
31
     */
32
    protected $fields;
33
34
    /**
35
     * Default load params, should be overwritten
36
     * in child classes
37
     *
38
     * @var array
39
     */
40
    protected $loadParams = array('fields' => 'all');
41
42
    /**
43
     * @var string
44
     */
45
    protected $id;
46
47
    /**
48
     * @var array
49
     */
50
    protected $data;
51
52
    /**
53
     * Constructor.
54
     *
55
     * @param ClientInterface $client the Trello client
56
     * @param string          $id     the id of the object
57
     */
58
    public function __construct(ClientInterface $client, $id = null)
59
    {
60
        $this->client = $client;
61
        $this->api    = $client->api($this->apiName);
62
63
        $this->fields = $this->api->getFields();
64
65
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
66
            $this->id = $id;
67
            $this->refresh();
68
        }
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function getId()
75
    {
76
        return $this->id;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function refresh()
83
    {
84
        $this->preRefresh();
85
        $this->data = $this->api->show($this->id, $this->loadParams);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Trello\Api\ApiInterface as the method show() does only exist in the following implementations of said interface: Trello\Api\Action, Trello\Api\Board, Trello\Api\Board\Cards, Trello\Api\Board\Labels, Trello\Api\Card, Trello\Api\Card\Attachments, Trello\Api\Card\Stickers, Trello\Api\Cardlist, Trello\Api\Checklist, Trello\Api\Member, Trello\Api\Notification, Trello\Api\Organization, Trello\Api\Token, Trello\Api\Token\Webhooks, Trello\Api\Webhook.

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...
86
        $this->postRefresh();
87
88
        return $this;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function save()
95
    {
96
        try {
97
            $this->preSave();
98
            $this->id ? $this->update() : $this->create();
99
            $this->postSave();
100
        } catch (BadMethodCallException $e) {
101
            throw new BadMethodCallException(sprintf(
102
                "You can't %s %s objects.",
103
                $this->id ? 'update' : 'create',
104
                get_called_class()
105
            ));
106
        }
107
108
        return $this->refresh();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function remove()
115
    {
116
        try {
117
            $this->preRemove();
118
            $this->api->remove($this->id);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Trello\Api\ApiInterface as the method remove() does only exist in the following implementations of said interface: Trello\Api\Action, Trello\Api\Board\Members, Trello\Api\Card\Attachments, Trello\Api\Card\Checklists, Trello\Api\Card\Labels, Trello\Api\Card\Members, Trello\Api\Card\Stickers, Trello\Api\Checklist, Trello\Api\Checklist\Items, Trello\Api\Token, Trello\Api\Token\Webhooks, Trello\Api\Webhook.

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...
119
            $this->postRemove();
120
        } catch (BadMethodCallException $e) {
121
            throw new BadMethodCallException(sprintf(
122
                "You can't remove %s objects.",
123
                get_called_class()
124
            ));
125
        }
126
127
        return $this;
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133
    public function getData()
134
    {
135
        return $this->data;
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function setData(array $data)
142
    {
143
        $this->data = $data;
144
145
        return $this;
146
    }
147
148
    /**
149
     * Update the object through API
150
     *
151
     * @return AbstractObject
152
     */
153
    protected function update()
154
    {
155
        $this->preUpdate();
156
        $this->data = $this->api->update($this->id, $this->data);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Trello\Api\ApiInterface as the method update() does only exist in the following implementations of said interface: Trello\Api\Action, Trello\Api\Board, Trello\Api\Card, Trello\Api\Card\Stickers, Trello\Api\Cardlist, Trello\Api\Checklist, Trello\Api\Checklist\Items, Trello\Api\Member, Trello\Api\Notification, Trello\Api\Token\Webhooks, Trello\Api\Webhook.

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...
157
        $this->postUpdate();
158
159
        return $this;
160
    }
161
162
    /**
163
     * Create the object through API
164
     *
165
     * @return AbstractObject
166
     */
167
    protected function create()
168
    {
169
        $this->preCreate();
170
        $this->data = $this->api->create($this->data);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Trello\Api\ApiInterface as the method create() does only exist in the following implementations of said interface: Trello\Api\Board, Trello\Api\Board\Cardlists, Trello\Api\Board\Checklists, Trello\Api\Card, Trello\Api\Card\Attachments, Trello\Api\Card\Checklists, Trello\Api\Card\Stickers, Trello\Api\Cardlist, Trello\Api\Cardlist\Cards, Trello\Api\Checklist, Trello\Api\Checklist\Items, Trello\Api\Token\Webhooks, Trello\Api\Webhook.

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...
171
        $this->id   = $this->data['id'];
172
        $this->postCreate();
173
174
        return $this;
175
    }
176
177
    /**
178
     * Called before saving (creating or updating) an entity
179
     */
180
    protected function preSave()
181
    {
182
    }
183
184
    /**
185
     * Called after saving (creating or updating) an entity
186
     */
187
    protected function postSave()
188
    {
189
    }
190
191
    /**
192
     * Called before creating an entity
193
     */
194
    protected function preCreate()
195
    {
196
    }
197
198
    /**
199
     * Called after creating an entity
200
     */
201
    protected function postCreate()
202
    {
203
    }
204
205
    /**
206
     * Called before updating an entity
207
     */
208
    protected function preUpdate()
209
    {
210
    }
211
212
    /**
213
     * Called after updating an entity
214
     */
215
    protected function postUpdate()
216
    {
217
    }
218
219
    /**
220
     * Called before refreshing an entity
221
     */
222
    protected function preRefresh()
223
    {
224
    }
225
226
    /**
227
     * Called after refreshing an entity
228
     */
229
    protected function postRefresh()
230
    {
231
    }
232
233
    /**
234
     * Called before removing an entity
235
     */
236
    protected function preRemove()
237
    {
238
    }
239
240
    /**
241
     * Called after removing an entity
242
     */
243
    protected function postRemove()
244
    {
245
    }
246
}
247