Passed
Push — master ( 1c7137...b5ef5e )
by Pieter van der
03:26 queued 14s
created

Tiqr_Message_FCM::_sendFirebase()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 54
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 35
c 5
b 0
f 0
dl 0
loc 54
rs 8.1155
cc 8
nc 7
nop 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the tiqr project.
4
 *
5
 * The tiqr project aims to provide an open implementation for
6
 * authentication using mobile devices. It was initiated by
7
 * SURFnet and developed by Egeniq.
8
 *
9
 * More information: http://www.tiqr.org
10
 *
11
 * @author Joost van Dijk <[email protected]>
12
 *
13
 * @package tiqr
14
 *
15
 * @license New BSD License - See LICENSE file for details.
16
 *
17
 * @copyright (C) 2010-2015 SURFnet BV
18
 */
19
20
21
/** @internal base includes */
22
require_once('Tiqr/Message/Abstract.php');
23
24
/**
25
 * Android Cloud To Device Messaging message.
26
 * @author peter
27
 */
28
class Tiqr_Message_FCM extends Tiqr_Message_Abstract
29
{
30
    /**
31
     * Send message.
32
     *
33
     * @throws Tiqr_Message_Exception_AuthFailure
34
     * @throws Tiqr_Message_Exception_SendFailure
35
     */
36
    public function send()
37
    {
38
        $options = $this->getOptions();
39
        $apiKey = $options['firebase.apikey'];
40
41
        $translatedAddress = $this->getAddress();
42
        $alertText = $this->getText();
43
        $url = $this->getCustomProperty('challenge');
44
45
        $this->_sendFirebase($translatedAddress, $alertText, $url, $apiKey);
46
    }
47
48
    /**
49
     * Send a message to a device using the firebase API key.
50
     *
51
     * @param $deviceToken string device ID
52
     * @param $alert string alert message
53
     * @param $challenge string tiqr challenge url
54
     * @param $apiKey string api key for firebase
55
     * @param $retry boolean is this a 2nd attempt
56
     * @param Tiqr_Message_Exception $gcmException
57
     *
58
     * @throws Tiqr_Message_Exception_SendFailure
59
     */
60
    private function _sendFirebase($deviceToken, $alert, $challenge, $apiKey, $retry=false)
61
    {
62
        $msg = array(
63
            'challenge' => $challenge,
64
            'text'      => $alert,
65
        );
66
67
        $fields = array(
68
            'registration_ids' => array($deviceToken),
69
            'data' => $msg,
70
            'time_to_live' => 300,
71
        );
72
73
        $headers = array(
74
            'Authorization: key=' . $apiKey,
75
            'Content-Type: application/json',
76
        );
77
78
        $ch = curl_init();
79
        curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
80
        curl_setopt($ch, CURLOPT_POST, true);
81
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
82
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
83
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
84
        $result = curl_exec($ch);
85
        $errors = curl_error($ch);
86
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
87
        $remoteip = curl_getinfo($ch,CURLINFO_PRIMARY_IP);
88
        curl_close($ch);
89
90
        if ($result === false) {
91
            throw new Tiqr_Message_Exception_SendFailure("Server unavailable", true);
92
        }
93
94
        if (!empty($errors)) {
95
            throw new Tiqr_Message_Exception_SendFailure("Http error occurred: ". $errors, true);
96
        }
97
98
        // Wait and retry once in case of a 502 Bad Gateway error
99
        if ($statusCode === 502 && !($retry)) {
100
          sleep(2);
101
          $this->_sendFirebase($deviceToken, $alert, $challenge, $apiKey, true);
102
          return;
103
        }
104
105
        if ($statusCode !== 200) {
106
            throw new Tiqr_Message_Exception_SendFailure(sprintf('Invalid status code : %s. Server : %s. Response : "%s".', $statusCode, $remoteip, $result), true);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type true; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
            throw new Tiqr_Message_Exception_SendFailure(sprintf('Invalid status code : %s. Server : %s. Response : "%s".', $statusCode, $remoteip, /** @scrutinizer ignore-type */ $result), true);
Loading history...
107
        }
108
109
        // handle errors, ignoring registration_id's
110
        $response = json_decode($result, true);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type true; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

110
        $response = json_decode(/** @scrutinizer ignore-type */ $result, true);
Loading history...
111
        foreach ($response['results'] as $k => $v) {
112
            if (isset($v['error'])) {
113
                throw new Tiqr_Message_Exception_SendFailure("Error in GCM response: " . $v['error'], true);
114
            }
115
        }
116
    }
117
}
118