Passed
Push — master ( d1b073...af2052 )
by Michael
32s queued 12s
created

issues.php ➔ xoopspartnersHandleHeaderLine()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits of
4
 supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit
6
 authors.
7
8
 This program is distributed in the hope that it will be useful, but
9
 WITHOUT ANY WARRANTY; without even the implied warranty of
10
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/**
14
 * Module: xoopsPartners
15
 *
16
 * @package         module\Xoopspartners\include
17
 * @author          ZySpec <[email protected]>
18
 * @copyright       https://xoops.org 2001-2016 XOOPS Project
19
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
20
 * @since           1.13
21
 */
22
$moduleDirName = basename(dirname(__DIR__));
23
$helper        = \Xmf\Module\Helper::getHelper($modueDirName);
24
$helper->loadLanguage('admin');
25
//require_once dirname(__DIR__) . "/language/english/admin.php"; // messages will be in english
26
27
if (false === @session_start()) {
28
    throw new \RuntimeException('Session could not start.');
29
}
30
31
global $hdrs;
32
$hdrs = [];
33
/**
34
 * Function to put HTTP headers in an array
35
 *
36
 * @param resource $curl
37
 * @param string  $hdrLine
38
 *
39
 * @return int length of header line put into array
40
 */
41
function xoopspartnersHandleHeaderLine($curl, $hdrLine)
0 ignored issues
show
Unused Code introduced by
The parameter $curl is not used and could be removed. ( Ignorable by Annotation )

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

41
function xoopspartnersHandleHeaderLine(/** @scrutinizer ignore-unused */ $curl, $hdrLine)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
42
{
43
    global $hdrs;
44
    $hdrs[] = trim($hdrLine);
45
46
    return mb_strlen($hdrLine);
47
}
48
49
/**
50
 * @param string $hdr
51
 * @param        $hdrArray
52
 * @param bool   $asArray
53
 * @return array|false|string array($hdr=>value) or false if not found
54
 */
55
function xoopspartnersGetHeaderFromArray($hdr, $hdrArray, $asArray = false)
56
{
57
    $val = '';
58
    foreach ($hdrArray as $thisHdr) {
59
        if (preg_match("/^{$hdr}/i", $thisHdr)) {
60
            $val = mb_substr($thisHdr, mb_strlen($hdr));
61
            break;
62
        }
63
    }
64
65
    return (bool)$asArray ? [$hdr => trim($val)] : trim($val);
66
}
67
68
$serviceUrl   = "https://github.com/XoopsModules25x/{$moduleDirName}/issues?state=open";
69
$sessPrefix   = "{$moduleDirName}_";
70
$err          = '';
71
$sKeyEtag     = "{$sessPrefix}github_etag";
72
$sKeyHdrSize  = "{$sessPrefix}github_hdr_size";
73
$sKeyResponse = "{$sessPrefix}github_curl_response";
74
$sKeyArray    = [$sKeyEtag, $sKeyHdrSize, $sKeyResponse];
75
76
$cachedEtag = isset($_SESSION[$sKeyEtag]) ? base64_decode(unserialize($_SESSION[$sKeyEtag]), true) : false;
77
if ($cachedEtag) {
78
    // found the session var so check to see if anything's changed since last time we checked
79
    $curl = curl_init($serviceUrl);
80
    curl_setopt_array(
81
        $curl,
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, 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

81
        /** @scrutinizer ignore-type */ $curl,
Loading history...
82
        [
83
            CURLOPT_RETURNTRANSFER => true,
84
            CURLOPT_HEADER         => true,
85
            CURLOPT_VERBOSE        => true,
86
            CURLOPT_TIMEOUT        => 5,
87
            CURLOPT_HTTPGET        => true,
88
            CURLOPT_USERAGENT      => "XOOPS-{$moduleDirName}",
89
            CURLOPT_HTTPHEADER     => [
90
                'Content-type:application/json',
91
                'If-None-Match: ' . $cachedEtag,
92
            ],
93
            CURLINFO_HEADER_OUT    => true,
94
            CURLOPT_HEADERFUNCTION => 'xoopspartnersHandleHeaderLine',
95
        ]
96
    );
97
    // execute the session
98
    $curl_response = curl_exec($curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, 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

98
    $curl_response = curl_exec(/** @scrutinizer ignore-type */ $curl);
Loading history...
99
    // get the header size and finish off the session
100
    $hdrSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, 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

100
    $hdrSize = curl_getinfo(/** @scrutinizer ignore-type */ $curl, CURLINFO_HEADER_SIZE);
Loading history...
101
    curl_close($curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, 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

101
    curl_close(/** @scrutinizer ignore-type */ $curl);
Loading history...
102
103
    $status = xoopspartnersGetHeaderFromArray('Status: ', $hdrs);
104
    if (preg_match('/^304 Not Modified/', $status)) {
0 ignored issues
show
Bug introduced by
It seems like $status can also be of type array<string,string>; however, parameter $subject of preg_match() 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

104
    if (preg_match('/^304 Not Modified/', /** @scrutinizer ignore-type */ $status)) {
Loading history...
105
        // hasn't been modified so get response & header size from session
106
        $curl_response = isset($_SESSION[$sKeyResponse]) ? base64_decode(unserialize($_SESSION[$sKeyResponse]), true) : [];
107
        $hdrSize       = isset($_SESSION[$sKeyHdrSize]) ? unserialize($_SESSION[$sKeyHdrSize]) : 0;
108
    } elseif (preg_match('/^200 OK/', $status)) {
109
        // ok - request new info
110
        $hdrs = []; //reset the header array for new curl op
111
        $curl = curl_init($serviceUrl);
112
        curl_setopt_array(
113
            $curl,
114
            [
115
                CURLOPT_RETURNTRANSFER => true,
116
                CURLOPT_HEADER         => true,
117
                CURLOPT_VERBOSE        => true,
118
                CURLOPT_TIMEOUT        => 5,
119
                CURLOPT_HTTPGET        => true,
120
                CURLOPT_USERAGENT      => "XOOPS-{$moduleDirName}",
121
                CURLOPT_HTTPHEADER     => ['Content-type:application/json'],
122
                CURLOPT_HEADERFUNCTION => 'xoopspartnersHandleHeaderLine',
123
            ]
124
        );
125
        // execute the session
126
        $curl_response = curl_exec($curl);
127
        // get the header size and finish off the session
128
        $hdrSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
129
        curl_close($curl);
130
131
        $hdrEtag                 = xoopspartnersGetHeaderFromArray('Etag: ', $hdrs);
132
        $_SESSION[$sKeyEtag]     = serialize(base64_encode($hdrEtag));
0 ignored issues
show
Bug introduced by
It seems like $hdrEtag can also be of type array<string,string>; however, parameter $data of base64_encode() 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

132
        $_SESSION[$sKeyEtag]     = serialize(base64_encode(/** @scrutinizer ignore-type */ $hdrEtag));
Loading history...
133
        $_SESSION[$sKeyHdrSize]  = serialize((int)$hdrSize);
134
        $_SESSION[$sKeyResponse] = serialize(base64_encode($curl_response));
135
    } elseif (preg_match('/^403 Forbidden/', $status)) {
136
        // probably exceeded rate limit
137
        $responseArray = explode('\n', $curl_response);
138
        $msgEle        = array_search('message: ', $responseArray, true);
139
        if (false !== $msgEle) {
140
            //found the error message so set it
141
            $err = mb_substr($responseArray[$msgEle], 8); //get the message
142
        } else {
143
            // couldn't find error message, but something went wrong
144
            // clear session vars
145
            foreach ($sKeyArray as $key) {
146
                $_SESSION[$key] = null;
147
                unset($_SESSION[$key]);
148
            }
149
            $err = _AM_XOOPSPARTNERS_ISSUES_ERR_UNKNOWN;
150
        }
151
    } else {
152
        // unknown error condition - display message
153
        // clear session vars
154
        foreach ($sKeyArray as $key) {
155
            $_SESSION[$key] = null;
156
            unset($_SESSION[$key]);
157
        }
158
        $err = _AM_XOOPSPARTNERS_ISSUES_ERR_STATUS;
159
    }
160
} else {
161
    // nothing in session so request new info
162
    $hdrs = [];
163
    $curl = curl_init($serviceUrl);
164
    curl_setopt_array(
165
        $curl,
166
        [
167
            CURLOPT_RETURNTRANSFER => true,
168
            CURLOPT_HEADER         => true,
169
            CURLOPT_VERBOSE        => true,
170
            CURLOPT_TIMEOUT        => 5,
171
            CURLOPT_HTTPGET        => true,
172
            CURLOPT_USERAGENT      => "XOOPS-{$moduleDirName}",
173
            CURLOPT_HTTPHEADER     => ['Content-type:application/json'],
174
            CURLOPT_HEADERFUNCTION => 'xoopspartnersHandleHeaderLine',
175
        ]
176
    );
177
    // execute the session
178
    $curl_response = curl_exec($curl);
179
    // get the header size and finish off the session
180
    $hdrSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
181
    curl_close($curl);
182
183
    $hdrEtag                 = xoopspartnersGetHeaderFromArray('Etag: ', $hdrs);
184
    $_SESSION[$sKeyEtag]     = serialize(base64_encode($hdrEtag));
185
    $_SESSION[$sKeyHdrSize]  = serialize((int)$hdrSize);
186
    $_SESSION[$sKeyResponse] = serialize(base64_encode($curl_response));
187
}
188
$hdr        = mb_substr($curl_response, 0, $hdrSize);
0 ignored issues
show
Bug introduced by
It seems like $curl_response can also be of type array; however, parameter $str of mb_substr() 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

188
$hdr        = mb_substr(/** @scrutinizer ignore-type */ $curl_response, 0, $hdrSize);
Loading history...
189
$rspSize    = mb_strlen($curl_response) - $hdrSize;
0 ignored issues
show
Bug introduced by
It seems like $curl_response can also be of type array; however, parameter $str of mb_strlen() 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

189
$rspSize    = mb_strlen(/** @scrutinizer ignore-type */ $curl_response) - $hdrSize;
Loading history...
190
$response   = mb_substr($curl_response, -$rspSize);
191
$issuesObjs = json_decode($response); //get as objects
192
193
echo "    <br>\n"
194
     . '    <h4 class="odd">'
195
     . _AM_XOOPSPARTNERS_ISSUES_OPEN
196
     . "</h4>\n"
197
     . "    <p class=\"even\">\n"
198
     . "    <table>\n"
199
     . "      <thead>\n"
200
     . "      <tr>\n"
201
     . '        <th class="center width10">'
202
     . _AM_XOOPSPARTNERS_HELP_ISSUE
203
     . "</th>\n"
204
     . '        <th class="center width10">'
205
     . _AM_XOOPSPARTNERS_HELP_DATE
206
     . "</th>\n"
207
     . '        <th class="center">'
208
     . _AM_XOOPSPARTNERS_HELP_TITLE
209
     . "</th>\n"
210
     . '        <th class="center width10">'
211
     . _AM_XOOPSPARTNERS_HELP_SUBMITTER
212
     . "</th>\n"
213
     . "      </tr>\n"
214
     . "      </thead>\n"
215
     . "      <tbody>\n";
216
217
$pullReqFound = false;
218
$suffix       = '';
219
$cssClass     = 'odd';
220
$i            = 0;
221
if (!empty($issuesObjs)) {
222
    foreach ($issuesObjs as $issue) {
223
        if (isset($issue->pull_request)) {
224
            /** @internal {uncomment the following line if you don't want to see pull requests as issues}}} */
225
            //            continue; // github counts pull requests as open issues so ignore these
226
227
            $suffix       = '*';
228
            $pullReqFound = true;
229
        } else {
230
            $suffix = '';
231
        }
232
233
        $dateTimeObj = DateTime::createFromFormat(DateTime::ISO8601, $issue->created_at);
234
        $dispDate    = $dateTimeObj->format('Y-m-d');
235
        ++$i; // issue count
236
237
        echo "      <tr>\n"
238
             . "        <td class=\"{$cssClass} center\">"
239
             . '<a href="'
240
             . $issue->html_url
241
             . '" target="_blank">'
242
             . (int)$issue->number
243
             . "{$suffix}</a>"
244
             . "</td>\n"
245
             . "        <td class=\"{$cssClass} center\">{$dispDate}</td>\n"
246
             . "        <td class=\"{$cssClass} left\" style=\"padding-left: 2em;\">"
247
             . htmlspecialchars($issue->title, ENT_QUOTES | ENT_HTML5)
248
             . "</td>\n"
249
             . "        <td class=\"{$cssClass} center\">"
250
             . '<a href="'
251
             . htmlspecialchars($issue->user->html_url, ENT_QUOTES | ENT_HTML5)
252
             . '" '
253
             . 'target="_blank">'
254
             . htmlspecialchars($issue->user->login, ENT_QUOTES | ENT_HTML5)
255
             . '</a>'
256
             . "</td>\n"
257
             . "      </tr>\n";
258
        $cssClass = ('odd' === $cssClass) ? 'even' : 'odd';
259
    }
260
}
261
262
if (!empty($err)) {
263
    echo "    <tr><td colspan=\"4\" class=\"{$cssClass} center bold italic\">" . htmlspecialchars($err, ENT_QUOTES | ENT_HTML5) . "</td></tr>\n";
264
} elseif (0 == $i) { // no issues found
265
    echo "    <tr><td colspan=\"4\" class=\"{$cssClass} center bold italic\">" . _AM_XOOPSPARTNERS_ISSUES_NONE . "</td></tr>\n";
266
}
267
268
if ($pullReqFound) {
269
    echo "    <tfoot>\n" . '      <tr><td colspan="4" class="left italic marg3 foot">' . _AM_XOOPSPARTNERS_ISSUES_NOTE . "</td></tr>\n" . "    </tfoot>\n";
270
}
271
echo "    </tbody></table></p>\n";
272