Completed
Push — master ( 283203...274200 )
by lan tian
11s
created

Agent::curlGet()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 1
nop 3
crap 6
1
<?php
2
3
namespace Toplan\PhpSms;
4
5
abstract class Agent
6
{
7
    const SUCCESS = 'success';
8
    const INFO = 'info';
9
    const CODE = 'code';
10
11
    /**
12
     * The configuration information.
13
     *
14
     * @var array
15
     */
16
    protected $config = [];
17
18
    /**
19
     * The custom params of request.
20
     *
21
     * @var array
22
     */
23
    protected $params = [];
24
25
    /**
26
     * The result data.
27
     *
28
     * @var array
29
     */
30
    protected $result = [];
31
32
    /**
33
     * Constructor.
34
     *
35
     * @param array $config
36
     */
37 27
    public function __construct(array $config = [])
38
    {
39 27
        $this->reset();
40 27
        $this->config($config);
41 27
    }
42
43
    /**
44
     * Reset states.
45
     */
46 42
    public function reset()
47
    {
48 42
        $this->result = [
49 42
            self::SUCCESS => false,
50 42
            self::INFO    => null,
51 42
            self::CODE    => 0,
52
        ];
53 42
    }
54
55
    /**
56
     * Get or set the configuration information.
57
     *
58
     * @param string|array $key
59
     * @param mixed        $value
60
     * @param bool         $override
61
     *
62
     * @return mixed
63
     */
64 27 View Code Duplication
    public function config($key = null, $value = null, $override = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
    {
66 27
        if (is_array($key) && is_bool($value)) {
67 3
            $override = $value;
68 3
        }
69
70 27
        return Util::operateArray($this->config, $key, $value, null, null, $override);
71
    }
72
73
    /**
74
     * Get or set the custom params.
75
     *
76
     * @param string|array $key
77
     * @param mixed        $value
78
     * @param bool         $override
79
     *
80
     * @return mixed
81
     */
82 27 View Code Duplication
    public function params($key = null, $value = null, $override = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
    {
84 27
        if (is_array($key) && is_bool($value)) {
85 27
            $override = $value;
86 27
        }
87
88 27
        return Util::operateArray($this->params, $key, $value, null, null, $override);
89
    }
90
91
    /**
92
     * SMS send process.
93
     *
94
     * @param       $to
95
     * @param       $content
96
     * @param       $tempId
97
     * @param array $data
98
     * @param array $params
99
     */
100 24
    public function sendSms($to, $content = null, $tempId = null, array $data = [], array $params = [])
101
    {
102 24
        $this->reset();
103 24
        $this->params($params, true);
104 24
        if ($tempId && $this instanceof TemplateSms) {
105 3
            $this->sendTemplateSms($to, $tempId, $data);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Toplan\PhpSms\Agent as the method sendTemplateSms() does only exist in the following sub-classes of Toplan\PhpSms\Agent: Toplan\PhpSms\AlidayuAgent, Toplan\PhpSms\AliyunAgent, Toplan\PhpSms\JuHeAgent, Toplan\PhpSms\LogAgent, Toplan\PhpSms\ParasiticAgent, Toplan\PhpSms\QcloudAgent, Toplan\PhpSms\SendCloudAgent, Toplan\PhpSms\SubMailAgent, Toplan\PhpSms\UcpaasAgent, Toplan\PhpSms\YunTongXunAgent. 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...
106 24
        } elseif ($content && $this instanceof ContentSms) {
107 21
            $this->sendContentSms($to, $content);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Toplan\PhpSms\Agent as the method sendContentSms() does only exist in the following sub-classes of Toplan\PhpSms\Agent: Toplan\PhpSms\LogAgent, Toplan\PhpSms\LuosimaoAgent, Toplan\PhpSms\ParasiticAgent, Toplan\PhpSms\QcloudAgent, Toplan\PhpSms\SmsBaoAgent, Toplan\PhpSms\YunPianAgent. 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...
108 21
        }
109 24
    }
110
111
    /**
112
     * Voice send process.
113
     *
114
     * @param       $to
115
     * @param       $content
116
     * @param       $tempId
117
     * @param array $data
118
     * @param       $code
119
     * @param       $fileId
120
     * @param array $params
121
     */
122 6
    public function sendVoice($to, $content = null, $tempId = null, array $data = [], $code = null, $fileId = null, array $params = [])
123
    {
124 6
        $this->reset();
125 6
        $this->params($params, true);
126 6
        if ($tempId && $this instanceof TemplateVoice) {
127
            $this->sendTemplateVoice($to, $tempId, $data);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Toplan\PhpSms\Agent as the method sendTemplateVoice() does only exist in the following sub-classes of Toplan\PhpSms\Agent: Toplan\PhpSms\AlidayuAgent, Toplan\PhpSms\ParasiticAgent. 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...
128 6
        } elseif ($fileId && $this instanceof FileVoice) {
129
            $this->sendFileVoice($to, $fileId);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Toplan\PhpSms\Agent as the method sendFileVoice() does only exist in the following sub-classes of Toplan\PhpSms\Agent: Toplan\PhpSms\ParasiticAgent. 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...
130 6
        } elseif ($code && $this instanceof VoiceCode) {
131 6
            $this->sendVoiceCode($to, $code);
0 ignored issues
show
Bug introduced by
The method sendVoiceCode() does not exist on Toplan\PhpSms\Agent. Did you maybe mean sendVoice()?

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...
132 6
        } elseif ($content && $this instanceof ContentVoice) {
133
            $this->sendContentVoice($to, $content);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Toplan\PhpSms\Agent as the method sendContentVoice() does only exist in the following sub-classes of Toplan\PhpSms\Agent: Toplan\PhpSms\ParasiticAgent, Toplan\PhpSms\QcloudAgent. 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...
134
        }
135 6
    }
136
137
    /**
138
     * @codeCoverageIgnore
139
     *
140
     * @param       $url
141
     * @param array $params
142
     * @param array $opts
143
     *
144
     * @return array
145
     */
146
    public function curlPost($url, array $params = [], array $opts = [])
147
    {
148
        $params = $this->params($params);
149
        $opts = array_merge([
150
            CURLOPT_POSTFIELDS  => $params,
151
        ], $opts, [
152
            CURLOPT_POST    => true,
153
            CURLOPT_URL     => $url,
154
        ]);
155
156
        return self::curl($opts);
157
    }
158
159
    /**
160
     * @codeCoverageIgnore
161
     *
162
     * @param       $url
163
     * @param array $params
164
     * @param array $opts
165
     *
166
     * @return array
167
     */
168
    public function curlGet($url, array $params = [], array $opts = [])
169
    {
170
        $params = $this->params($params);
171
        $queryStr = http_build_query($params);
172
        $opts = array_merge($opts, [
173
            CURLOPT_POST    => false,
174
            CURLOPT_URL     => $queryStr ? "$url?$queryStr" : $url,
175
        ]);
176
177
        return self::curl($opts);
178
    }
179
180
    /**
181
     * cURl
182
     *
183
     * @codeCoverageIgnore
184
     *
185
     * @param array $opts curl options
186
     *
187
     * @return array ['request', 'response']
188
     *               request: Whether request success.
189
     *               response: Response data.
190
     */
191
    public static function curl(array $opts = [])
192
    {
193
        $ch = curl_init();
194
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
195
        curl_setopt($ch, CURLOPT_HEADER, false);
196
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
197
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
198
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
199
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
200
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
201
        foreach ($opts as $key => $value) {
202
            curl_setopt($ch, $key, $value);
203
        }
204
205
        $response = curl_exec($ch);
206
        $request = $response !== false;
207
        if (!$request) {
208
            $response = curl_getinfo($ch);
209
        }
210
        curl_close($ch);
211
212
        return compact('request', 'response');
213
    }
214
215
    /**
216
     * Get or set the result data.
217
     *
218
     * @param $name
219
     * @param $value
220
     *
221
     * @return mixed
222
     */
223 33
    public function result($name = null, $value = null)
224
    {
225 33
        if ($name === null) {
226 30
            return $this->result;
227
        }
228 30
        if (array_key_exists($name, $this->result)) {
229 30
            if ($value === null) {
230 6
                return $this->result[$name];
231
            }
232 30
            $this->result[$name] = $value;
233 30
        }
234 30
    }
235
236
    /**
237
     * Overload object properties.
238
     *
239
     * @param $name
240
     *
241
     * @return mixed
242
     */
243 6
    public function __get($name)
244
    {
245 6
        return $this->config($name);
246
    }
247
248
    /**
249
     * When using isset() or empty() on inaccessible object properties,
250
     * the __isset() overloading method will be called.
251
     *
252
     * @param $name
253
     *
254
     * @return bool
255
     */
256 3
    public function __isset($name)
257
    {
258 3
        return isset($this->config[$name]);
259
    }
260
}
261