Completed
Push — master ( 222f63...75778e )
by Angus
02:21
created

Gravatar   C

Complexity

Total Complexity 64

Size/Duplication

Total Lines 486
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 486
rs 5.8364
c 0
b 0
f 0
wmc 64
lcom 1
cbo 0

How to fix   Complexity   

Complex Class

Complex classes like Gravatar often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Gravatar, and based on these observations, apply Extract Interface, too.

1
<?php defined('BASEPATH') OR exit('No direct script access allowed.');
2
3
/**
4
 * Gravatar Library for CodeIgniter
5
 *
6
 * @author Ivan Tcholakov <[email protected]>, 2015 - 2016
7
 * @author Ryan Marshall <[email protected]>, 2011 - 2015, @link http://irealms.co.uk
8
 *
9
 * Code repository: @link https://github.com/ivantcholakov/Codeigniter-Gravatar
10
 *
11
 * @version 1.1.1
12
 *
13
 * @license The MIT License (MIT)
14
 * @link http://opensource.org/licenses/MIT
15
 */
16
17
// Gravatar pofile error results.
18
defined('GRAVATAR_NO_ERROR') OR define('GRAVATAR_NO_ERROR', 0);
19
defined('GRAVATAR_CANT_CONNECT') OR define('GRAVATAR_CANT_CONNECT', 1);
20
defined('GRAVATAR_INVALID_EMAIL') OR define('GRAVATAR_INVALID_EMAIL', 2);
21
defined('GRAVATAR_PROFILE_DOES_NOT_EXIST') OR define('GRAVATAR_PROFILE_DOES_NOT_EXIST', 3);
22
defined('GRAVATAR_INCORRECT_FORMAT') OR define('GRAVATAR_INCORRECT_FORMAT', 4);
23
24
class Gravatar {
25
26
    protected $defaults;
27
28
    protected $gravatar_base_url;
29
    protected $gravatar_secure_base_url;
30
    protected $gravatar_image_extension;
31
    protected $gravatar_image_size;
32
    protected $gravatar_default_image;
33
    protected $gravatar_force_default_image;
34
    protected $gravatar_rating ;
35
    protected $gravatar_useragent;
36
37
    protected $last_error = GRAVATAR_NO_ERROR;
38
39
    protected $is_https;
40
    protected $curl_exists;
41
    protected $allow_url_fopen;
42
43
    public function __construct($config = array()) {
44
45
        $this->defaults = array(
46
            'gravatar_base_url' => 'http://www.gravatar.com/',
47
            'gravatar_secure_base_url' => 'https://secure.gravatar.com/',
48
            'gravatar_image_extension' => '.png',
49
            'gravatar_image_size' => 80,
50
            'gravatar_default_image' => '',
51
            'gravatar_force_default_image' => false,
52
            'gravatar_rating' => '',
53
            'gravatar_useragent' => 'PHP Gravatar Library',
54
        );
55
56
        $this->is_https = $this->is_https();
57
        $this->curl_exists = function_exists('curl_init');
58
        $allow_url_fopen = @ini_get('allow_url_fopen');
59
        $allow_url_fopen = $allow_url_fopen === false || in_array(strtolower($allow_url_fopen), array('on', 'true', '1'));
60
        $this->allow_url_fopen = $allow_url_fopen;
61
62
        if (!is_array($config)) {
63
            $config = array();
64
        }
65
66
        $this->defaults = array_merge($this->defaults, $config);
67
        $this->initialize($this->defaults);
68
    }
69
70
    public function initialize($config = array()) {
71
72
        if (!is_array($config)) {
73
            $config = array();
74
        }
75
76
        foreach ($config as $key => $value) {
77
            $this->{$key} = $value;
78
        }
79
80
        $this->gravatar_base_url = (string) $this->gravatar_base_url;
81
        $this->gravatar_secure_base_url = (string) $this->gravatar_secure_base_url;
82
        $this->gravatar_image_extension = (string) $this->gravatar_image_extension;
83
84
        $this->gravatar_image_size = (int) $this->gravatar_image_size;
85
86
        if ($this->gravatar_image_size <= 0) {
87
            $this->gravatar_image_size = 80;
88
        }
89
90
        $this->gravatar_default_image = (string) $this->gravatar_default_image;
91
        $this->gravatar_force_default_image = !empty($this->gravatar_force_default_image);
92
        $this->gravatar_rating = (string) $this->gravatar_rating;
93
        $this->gravatar_useragent = (string) $this->gravatar_useragent;
94
95
        return $this;
96
    }
97
98
    public function reset() {
99
100
        $this->initialize($this->defaults);
101
102
        return $this;
103
    }
104
105
    public function get_defaults() {
106
107
        return $this->defaults;
108
    }
109
110
    /**
111
     * Creates a URL for requesting a Gravatar image.
112
     * @link http://en.gravatar.com/site/implement/images/
113
     *
114
     * @param   string      $email                  A registered email.
115
     * @param   int         $size                   The requested size of the avarar in pixels (a square image).
116
     * @param   string      $default_image          The fallback image option: '', '404', 'mm', 'identicon', 'monsterid', 'wavatar', 'retro', 'blank'.
117
     * @param   bool        $force_default_image    Enforces the fallback image to be shown.
118
     * @param   string      $rating                 The level of allowed self-rate of the avatar: '', 'g' (default), 'pg', 'r', 'x'.
119
     * @return  string                              Returns the URL of the avatar to be requested.
120
     *
121
     * When optional parameters are not set, their default values are taken
122
     * from the configuration file application/config/gravatar.php
123
     */
124
    public function get($email, $size = null, $default_image = null, $force_default_image = null, $rating = null) {
125
126
        $url = ($this->is_https ? $this->gravatar_secure_base_url : $this->gravatar_base_url).'avatar/'.$this->create_hash($email).$this->gravatar_image_extension;
127
128
        $query = array();
129
130
        $size = (int) $size;
131
132
        if ($size <= 0) {
133
            $size = $this->gravatar_image_size;
134
        }
135
136
        if ($size > 0) {
137
            $query['s'] = $size;
138
        }
139
140
        if (isset($default_image)) {
141
            $default_image = (string) $default_image;
142
        } else {
143
            $default_image = $this->gravatar_default_image;
144
        }
145
146
        if ($default_image != '') {
147
            $query['d'] = $default_image;
148
        }
149
150
        if (isset($force_default_image)) {
151
            $force_default_image = !empty($force_default_image);
152
        } else {
153
            $force_default_image = $this->gravatar_force_default_image;
154
        }
155
156
        if ($force_default_image) {
157
            $query['f'] = 'y';
158
        }
159
160
        if (isset($rating)) {
161
            $rating = (string) $rating;
162
        } else {
163
            $rating = $this->gravatar_rating;
164
        }
165
166
        if ($rating != '') {
167
            $query['r'] = $rating;
168
        }
169
170
        if (!empty($query)) {
171
            $url = $url.'?'.http_build_query($query);
172
        }
173
174
        return $url;
175
    }
176
177
    /**
178
     * Executes a request for Gravatar profile data and returns it as a multidimensional array.
179
     * @link https://en.gravatar.com/site/implement/profiles/
180
     *
181
     * @param   string      $email          A registered email.
182
     * @return  array/null                  Received profile data.
183
     */
184
    public function get_profile_data($email) {
185
186
        $result = $this->execute_profile_request($email, 'php');
187
188
        if ($this->last_error != GRAVATAR_NO_ERROR) {
189
            return null;
190
        }
191
192
        $result = @ unserialize($result);
193
194
        if ($result === false) {
195
196
            $this->last_error = GRAVATAR_INCORRECT_FORMAT;
197
            return null;
198
        }
199
200
        if (!is_array($result)) {
201
202
            $this->last_error = GRAVATAR_PROFILE_DOES_NOT_EXIST;
203
            return null;
204
        }
205
206
        if (!isset($result['entry']) || !isset($result['entry'][0])) {
207
208
            $this->last_error = GRAVATAR_INCORRECT_FORMAT;
209
            return null;
210
        }
211
212
        return $result['entry'][0];
213
    }
214
215
    /**
216
     * Executes a request for Gravatar profile data and returns raw received response.
217
     * @link https://en.gravatar.com/site/implement/profiles/
218
     *
219
     * @param   string      $email      A registered email.
220
     * @param   string      $format     '', 'json', 'xml', 'php', 'vcf', 'qr'.
221
     * @return  string/null             Received profile raw data.
222
     */
223
    public function execute_profile_request($email, $format = null) {
224
225
        $this->last_error = GRAVATAR_NO_ERROR;
226
227
        if (function_exists('valid_email')) {
228
229
            if (!valid_email($email)) {
230
231
                $this->last_error = GRAVATAR_INVALID_EMAIL;
232
                return null;
233
            }
234
235
        } else {
236
237
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
238
239
                $this->last_error = GRAVATAR_INVALID_EMAIL;
240
                return null;
241
            }
242
        }
243
244
        $format = trim($format);
245
246
        if ($format != '') {
247
            $format = '.'.ltrim($format, '.');
248
        }
249
250
        $result = null;
251
252
        if ($this->curl_exists) {
253
254
            $url = $this->gravatar_secure_base_url.$this->create_hash($email).$format;
255
256
            $ch = curl_init();
257
258
            $options = array(
259
                CURLOPT_USERAGENT, $this->gravatar_useragent,
260
                CURLOPT_RETURNTRANSFER => true,
261
                CURLOPT_POST => true,
262
                CURLOPT_POSTFIELDS => array(),
263
                CURLOPT_URL => $url,
264
                CURLOPT_TIMEOUT => 3,
265
            );
266
267
            if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
268
                $options[CURLOPT_FOLLOWLOCATION] = true;
269
            }
270
271
            curl_setopt_array($ch, $options);
272
273
            $result = curl_exec($ch);
274
275
            $code = @ curl_getinfo($ch, CURLINFO_HTTP_CODE);
276
277
            @ curl_close($ch);
278
279
            if ($code != 200) {
280
281
                $this->last_error = GRAVATAR_CANT_CONNECT;
282
                return null;
283
            }
284
285
        } elseif ($this->allow_url_fopen) {
286
287
            $url = $this->gravatar_base_url.$this->create_hash($email).$format;
288
289
            $options = array(
290
                'http' => array(
291
                    'method' => 'GET',
292
                    'useragent' => $this->gravatar_useragent,
293
                ),
294
            );
295
296
            $context = stream_context_create($options);
297
298
            $result = @ file_get_contents($url, false, $context);
299
300
        } else {
301
302
            $this->last_error = GRAVATAR_CANT_CONNECT;
303
            return null;
304
        }
305
306
        if ($result === false) {
307
308
            $this->last_error = GRAVATAR_CANT_CONNECT;
309
            return null;
310
        }
311
312
        return $result;
313
    }
314
315
    /**
316
     * Returns the error code as a result of the last profile request operation.
317
     *
318
     * @return int          GRAVATAR_NO_ERROR - the last operation was successfull,
319
     *                      other returned value indicates failure.
320
     */
321
    public function last_error() {
322
323
        return $this->last_error;
324
    }
325
326
    /**
327
     * Creates a hash value from a provided e-mail address.
328
     * @link https://en.gravatar.com/site/implement/hash/
329
     *
330
     * @param   string      $email      A registered email.
331
     * @return  string/null             The hash for accessing the avatar or profile data.
332
     */
333
    public function create_hash($email) {
334
335
        return md5(strtolower(trim($email)));
336
    }
337
338
    protected function is_https() {
339
340
        if (function_exists('is_https')) {
341
            return is_https();
342
        }
343
344
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
345
            return true;
346
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
347
            return true;
348
        } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
349
            return true;
350
        }
351
352
        return false;
353
    }
354
355
    //--------------------------------------------------------------------------
356
    // The following original methods are kept here for backward compatibility.
357
    // Consider them as deprecated.
358
    //--------------------------------------------------------------------------
359
360
361
    /**
362
     * Set the email to be used, converting it into an md5 hash as required by gravatar.com
363
     *
364
     * @param string $email
365
     *
366
     * @return string|null Email hash or if email didn't validate then return NULL
367
     *
368
     * @deprecated
369
     */
370
    public function set_email($email)
371
    {
372
        $email = trim(strtolower($email));
373
374
        if ( ! filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
375
        {
376
            return md5($email);
377
        }
378
379
        return NULL;
380
    }
381
382
    /**
383
     * get_gravatar_url
384
     *
385
     * @see http://en.gravatar.com/site/implement/images/ for available options
386
     *
387
     * @param string $rating defaults to g
388
     * @param string $size defaults to 80
389
     * @param string $default_image default sets can be found on the above link
390
     * @param boolean $secure set to TRUE if a secure url is required
391
     *
392
     * @return string gratavar url
393
     *
394
     * @deprecated
395
     */
396
    public function get_gravatar($email, $rating = NULL, $size = NULL, $default_image = NULL, $secure = NULL)
397
    {
398
        $hash = $this->set_email($email);
399
400
        if ($hash === NULL)
401
        {
402
            // $hash has to be set to a value so the gravatar site can return a default image
403
            $hash = 'invalid_email';
404
        }
405
406
        $query_string = NULL;
407
        $options = array();
408
409
        if ($rating !== NULL)
410
        {
411
            $options['r'] = $rating;
412
        }
413
414
        if ($size !== NULL)
415
        {
416
            $options['s'] = $size;
417
        }
418
419
        if ($default_image !== NULL)
420
        {
421
            $options['d'] = urlencode($default_image);
422
        }
423
424
        if (count($options) > 0)
425
        {
426
            $query_string = '?'. http_build_query($options);
427
        }
428
429
        if ($secure !== NULL)
430
        {
431
            $base = $this->gravatar_secure_base_url;
432
        }
433
        else
434
        {
435
            $base = $this->gravatar_base_url;
436
        }
437
438
        return $base .'avatar/'. $hash . $query_string;
439
    }
440
441
    /**
442
     * Grab the full profile data for a given email from gravatar.com in xml format
443
     *
444
     * @param string $email
445
     * @param string fetch_method defaults to file, 'curl' is the other option
446
     *
447
     * @return object|null $xml->entry on success, NULL on an error
448
     *
449
     * @deprecated
450
     */
451
    public function get_profile($email, $fetch_method = 'file')
452
    {
453
        $hash = $this->set_email($email);
454
455
        if ($hash === NULL)
456
        {
457
            // A hash value of NULL will return no xml so the method returns NULL
458
            return NULL;
459
        }
460
461
        libxml_use_internal_errors(TRUE);
462
463
        if ($fetch_method === 'file')
464
        {
465
            if (ini_get('allow_url_fopen') == FALSE)
466
            {
467
                return NULL;
468
            }
469
470
            $str = file_get_contents($this->gravatar_base_url . $hash .'.xml');
471
        }
472
473
        if ($fetch_method === 'curl')
474
        {
475
            if ( ! function_exists('curl_init'))
476
            {
477
                return NULL;
478
            }
479
480
            $ch = curl_init();
481
            $options = array(
482
                CURLOPT_RETURNTRANSFER => TRUE,
483
                CURLOPT_POST => TRUE,
484
                CURLOPT_URL => $this->gravatar_secure_base_url . $hash .'.xml',
485
                CURLOPT_TIMEOUT => 3
486
            );
487
            curl_setopt_array($ch, $options);
488
            $str = curl_exec($ch);
489
        }
490
491
        $xml = simplexml_load_string($str);
492
493
        if ($xml === FALSE)
494
        {
495
            $errors = array();
496
            foreach(libxml_get_errors() as $error)
497
            {
498
                $errors[] = $error->message.'\n';
499
            }
500
            $error_string = implode('\n', $errors);
501
            throw new Exception('Failed loading XML\n'. $error_string);
502
        }
503
        else
504
        {
505
            return $xml->entry;
506
        }
507
    }
508
509
}
510