CampaignMonitorAPIConnectorBase::getApiKey()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Sunnysideup\CampaignMonitorApi\Api;
4
5
use Psr\SimpleCache\CacheInterface;
6
use SilverStripe\Control\Controller;
7
use SilverStripe\Core\Config\Configurable;
8
use SilverStripe\Core\Environment;
9
use SilverStripe\Core\Extensible;
10
use SilverStripe\Core\Injector\Injectable;
11
use SilverStripe\Core\Injector\Injector;
12
use CS_REST_General;
13
14
class CampaignMonitorAPIConnectorBase
15
{
16
    use Configurable;
17
    use Extensible;
18
    use Injectable;
19
20
    /**
21
     * @var bool
22
     */
23
    protected $debug = false;
24
25
    /**
26
     * @var bool
27
     */
28
    protected $allowCaching = false;
29
30
    /**
31
     * @var int
32
     */
33
    protected $httpStatusCode = 0;
34
35
    /**
36
     * REQUIRED!
37
     * this is the CM url for logging in.
38
     * which can be used by the client.
39
     *
40
     * @var string
41
     */
42
    private static $campaign_monitor_url = '';
43
44
    /**
45
     * REQUIRED!
46
     *
47
     * @var string
48
     */
49
    private static $client_id = '';
50
51
    /**
52
     * OPTION 1: API KEY!
53
     *
54
     * @var string
55
     */
56
    private static $api_key = '';
57
58
    /**
59
     * OPTION 2: OAUTH OPTION.
60
     *
61
     * @var string
62
     */
63
    private static $client_secret = '';
64
65
    /**
66
     * OPTION 2: OAUTH OPTION.
67
     *
68
     * @var string
69
     */
70
    private static $redirect_uri = '';
71
72
    /**
73
     * OPTION 2: OAUTH OPTION.
74
     *
75
     * @var string
76
     */
77
    private static $code = '';
78
79
    private static $error_code = '';
80
81
    private static $error_description = '';
82
83
    public static function get_last_error_code(): string
84
    {
85
        return self::$error_code;
86
    }
87
88
    public static function get_last_error_description(): string
89
    {
90
        return self::$error_description;
91
    }
92
93
    public static function inst(): static
94
    {
95
        return Injector::inst()->get(static::class);
96
    }
97
98
    /**
99
     * must be called to use this API.
100
     * Check if the API is ready to do stuff...
101
     */
102
    public function isAvailable(): bool
103
    {
104
        $class = Injector::inst()->get(static::class);
105
        $auth = $class->getAuth();
106
107
        return false === empty($auth) ? true : false;
108
    }
109
110
    /**
111
     * must be called to use this API.
112
     */
113
    public function init()
114
    {
115
        require_once BASE_PATH . '/vendor/campaignmonitor/createsend-php/csrest_lists.php';
116
    }
117
118
    /**
119
     * turn debug on or off.
120
     *
121
     * @param bool $b
122
     */
123
    public function setDebug(?bool $b = true)
124
    {
125
        $this->debug = $b;
126
    }
127
128
    public function setAllowCaching(bool $b)
129
    {
130
        $this->allowCaching = $b;
131
    }
132
133
    /**
134
     * @return bool
135
     */
136
    public function getAllowCaching()
137
    {
138
        return $this->allowCaching;
139
    }
140
141
    /**
142
     * returns the HTTP code for the response.
143
     * This can be handy for debuging purposes.
144
     *
145
     * @return int
146
     */
147
    public function getHttpStatusCode()
148
    {
149
        return $this->httpStatusCode;
150
    }
151
152
    /**
153
     * provides the Authorisation Array.
154
     *
155
     * @return array|mixed
156
     */
157
    protected function getAuth()
158
    {
159
        $auth = $this->getFromCache('getAuth');
160
        if (!empty($auth)) {
161
            return $auth;
162
        }
163
        $auth = [];
164
        $apiKey = $this->getApiKey();
165
        if ($apiKey) {
166
            $auth = ['api_key' => $apiKey];
167
        } else {
168
            $clientId = $this->getClientId();
169
            $clientSecret = $clientId ? $this->getClientSecret() : '';
170
            $code = $clientSecret ? $this->getCode() : '';
171
            $redirectUri = $clientSecret ? $this->getRedirectUri() : '';
172
            if ($clientId && $clientSecret && $redirectUri && $code) {
173
                $result = CS_REST_General::exchange_token($clientId, $clientSecret, $redirectUri, $code);
174
175
                if ($result->was_successful()) {
176
                    $auth = [
177
                        'access_token' => $result->response->access_token,
178
                        'refresh_token' => $result->response->refresh_token,
179
                    ];
180
                    //TODO: do we need to check expiry date?
181
                    //$expires_in = $result->response->expires_in;
182
                    // Save $access_token, $expires_in, and $refresh_token.
183
                    if ($this->debug) {
184
                        echo 'access token: ' . $result->response->access_token . "\n";
185
                        echo 'expires in (seconds): ' . $result->response->expires_in . "\n";
186
                        echo 'refresh token: ' . $result->response->refresh_token . "\n";
187
                    }
188
                } else {
189
                    // If you receive '121: Expired OAuth Token', refresh the access token
190
                    if ($result->response && 121 === $result->response->Code) {
191
                        $url = CS_REST_General::authorize_url($clientId, $clientSecret, $redirectUri, $code);
192
193
                        return Controller::curr()->redirect($url);
194
                        // $wrap =
195
                        // list($new_access_token, , $new_refresh_token) = $wrap->refresh_token();
196
                        //
197
                        // $auth = [
198
                        //     'access_token' => $new_access_token,
199
                        //     'refresh_token' => $new_refresh_token,
200
                        // ];
201
                    }
202
                }
203
            }
204
            if (!empty($auth)) {
205
                $this->saveToCache($auth, 'getAuth');
206
            }
207
        }
208
        if (empty($auth)) {
209
            $auth = [];
210
        }
211
212
        return $auth;
213
    }
214
215
    /**
216
     * returns the result or NULL in case of an error
217
     * NULL RESULT IS ERROR!
218
     *
219
     * @param \CS_REST_Wrapper_Result $result
220
     * @param mixed                   $apiCall
221
     * @param mixed                   $description
222
     *
223
     * @return mixed
224
     */
225
    protected function returnResult($result, $apiCall, $description)
226
    {
227
        if ($this->debug) {
228
            if (is_string($result)) {
0 ignored issues
show
introduced by
The condition is_string($result) is always false.
Loading history...
229
                echo "<h1>{$description} ( {$apiCall} ) ...</h1>";
230
                echo "<p style='color: red'>{$result}</p>";
231
            } else {
232
                echo "<h1>{$description} ( {$apiCall} ) ...</h1>";
233
                if ($result->was_successful()) {
234
                    echo '<h2>SUCCESS</h2>';
235
                } else {
236
                    echo '<h2>FAILURE: ' . $result->http_status_code . '</h2>';
237
                }
238
                echo '<pre>';
239
                print_r($result);
240
                echo '</pre>';
241
                echo '<hr /><hr /><hr />';
242
                ob_flush();
243
                flush();
244
            }
245
        }
246
        if (is_string($result)) {
0 ignored issues
show
introduced by
The condition is_string($result) is always false.
Loading history...
247
            $this->httpStatusCode = 500;
248
            self::$error_description = $result;
249
            self::$error_code = 500;
250
251
            return null;
252
        }
253
        if ($result->was_successful()) {
254
            if (!empty($result->response)) {
255
                return $result->response;
256
            }
257
258
            return true;
259
        }
260
        $this->httpStatusCode = $result->http_status_code;
261
        self::$error_description = serialize($result) . ' --- --- ' . serialize($apiCall) . ' --- --- ' . serialize($description);
262
        self::$error_code = $result->http_status_code;
263
264
        return null;
265
    }
266
267
    // caching
268
269
    /**
270
     * @return mixed
271
     */
272
    protected function getFromCache(string $name)
273
    {
274
        if ($this->getAllowCaching()) {
275
            $cache = $this->getCache();
276
            $value = $cache->has($name) ? $cache->get($name) : null;
277
            if ($value) {
278
                return unserialize((string) $value);
279
            }
280
        }
281
282
        return null;
283
    }
284
285
    /**
286
     * @param mixed $unserializedValue
287
     */
288
    protected function saveToCache($unserializedValue, string $name): bool
289
    {
290
        if ($this->getAllowCaching()) {
291
            $serializedValue = serialize($unserializedValue);
292
            $cache = $this->getCache();
293
            $cache->set($name, $serializedValue);
294
295
            return true;
296
        }
297
298
        return false;
299
    }
300
301
    protected function getCache()
302
    {
303
        return Injector::inst()->get(CacheInterface::class . '.CampaignMonitor');
304
    }
305
306
    public function getApiKey(): string
307
    {
308
        return $this->getEnvOrConfigVar('SS_CAMPAIGNMONITOR_API_KEY', 'api_key', true);
309
    }
310
311
    public function getClientId(): string
312
    {
313
        return $this->getEnvOrConfigVar('SS_CAMPAIGNMONITOR_CLIENT_ID', 'client_id', true);
314
    }
315
316
    public function getClientSecret(): string
317
    {
318
        return $this->getEnvOrConfigVar('SS_CAMPAIGNMONITOR_CLIENT_SECRET', 'client_secret', true);
319
    }
320
321
    public function getCode(): string
322
    {
323
        return $this->getEnvOrConfigVar('SS_CAMPAIGNMONITOR_CODE', 'code', true);
324
    }
325
326
    public function getRedirectUri(): string
327
    {
328
        return $this->getEnvOrConfigVar('SS_CAMPAIGNMONITOR_REDIRECT_URI', 'campaign_monitor_url', true);
329
    }
330
331
    protected function getEnvOrConfigVar(string $envVar, string $configVar, ?bool $allowToBeEmpty = false)
332
    {
333
        $var = Environment::getEnv($envVar);
334
        if (!$var) {
335
            $var = $this->Config()->get($configVar);
336
        }
337
        $var = trim($var);
338
        if (!$var && false === $allowToBeEmpty) {
339
            user_error('Please set .env var ' . $envVar . ' (recommended) or config var ' . $configVar, E_USER_NOTICE);
340
        }
341
342
        return $var;
343
    }
344
345
    /**
346
     * @param mixed $customFields (should be an array)
347
     */
348
    protected function cleanCustomFields($customFields): array
349
    {
350
        if (!is_array($customFields)) {
351
            $customFields = [];
352
        }
353
        $customFieldsBetter = [];
354
        foreach ($customFields as $key => $value) {
355
            if (isset($customFields[$key]['Key'], $customFields[$key]['Value'])) {
356
                $customFieldsBetter[] = $customFields[$key];
357
            } elseif (is_array($value)) {
358
                foreach ($value as $innerValue) {
359
                    $customFieldsBetter[] = [
360
                        'Key' => $key,
361
                        'Value' => $innerValue,
362
                        // 'Clear' => empty($value) ? true : false,
363
                    ];
364
                }
365
            } else {
366
                $customFieldsBetter[] = [
367
                    'Key' => $key,
368
                    'Value' => $value,
369
                    // 'Clear' => empty($value) ? true : false,
370
                ];
371
            }
372
        }
373
374
        return $customFieldsBetter;
375
    }
376
}
377