Completed
Push — master ( b3b9ba...a4e869 )
by Daniel
04:24
created

getContentFromUrlThroughCurlAsArrayIfJson()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 15
Code Lines 9

Duplication

Lines 10
Ratio 66.67 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 10
loc 15
rs 8.8571
cc 5
eloc 9
nc 9
nop 2
1
<?php
2
3
/**
4
 *
5
 * The MIT License (MIT)
6
 *
7
 * Copyright (c) 2015 Daniel Popiniuc
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
29
namespace danielgp\common_lib;
30
31
/**
32
 * usefull functions to get quick results
33
 *
34
 * @author Daniel Popiniuc
35
 */
36
trait CommonCode
37
{
38
39
    use CommonLibLocale,
40
        CommonPermissions,
41
        DomComponentsByDanielGP,
42
        DomComponentsByDanielGPwithCDN,
43
        MySQLiByDanielGPqueries,
44
        MySQLiByDanielGP;
45
46
    protected function arrayDiffAssocRecursive($array1, $array2)
47
    {
48
        $difference = [];
49
        foreach ($array1 as $key => $value) {
50
            if (is_array($value)) {
51
                if (!isset($array2[$key]) || !is_array($array2[$key])) {
52
                    $difference[$key] = $value;
53
                } else {
54
                    $workingDiff = $this->arrayDiffAssocRecursive($value, $array2[$key]);
55
                    if (!empty($workingDiff)) {
56
                        $difference[$key] = $workingDiff;
57
                    }
58
                }
59
            } elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
60
                $difference[$key] = $value;
61
            }
62
        }
63
        return $difference;
64
    }
65
66
    /**
67
     * Reads the content of a remote file through CURL extension
68
     *
69
     * @param string $fullURL
70
     * @param array $features
71
     * @return blob
72
     */
73
    protected function getContentFromUrlThroughCurl($fullURL, $features = null)
74
    {
75
        if (!function_exists('curl_init')) {
76
            $aReturn['info']     = $this->lclMsgCmn('i18n_Error_ExtensionNotLoaded');
0 ignored issues
show
Coding Style Comprehensibility introduced by
$aReturn was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aReturn = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
77
            $aReturn['response'] = '';
78
        }
79
        if (!filter_var($fullURL, FILTER_VALIDATE_URL)) {
80
            $aReturn['info']     = $this->lclMsgCmn('i18n_Error_GivenUrlIsNotValid');
0 ignored issues
show
Bug introduced by
The variable $aReturn does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
81
            $aReturn['response'] = '';
82
        }
83
        $aReturn = [];
84
        $chanel  = curl_init();
85
        curl_setopt($chanel, CURLOPT_USERAGENT, $this->getUserAgentByCommonLib());
86
        if ((strpos($fullURL, 'https') !== false) || (isset($features['forceSSLverification']))) {
87
            curl_setopt($chanel, CURLOPT_SSL_VERIFYHOST, false);
88
            curl_setopt($chanel, CURLOPT_SSL_VERIFYPEER, false);
89
        }
90
        curl_setopt($chanel, CURLOPT_URL, $fullURL);
91
        curl_setopt($chanel, CURLOPT_HEADER, false);
92
        curl_setopt($chanel, CURLOPT_RETURNTRANSFER, true);
93
        curl_setopt($chanel, CURLOPT_FRESH_CONNECT, true); //avoid a cached response
94
        curl_setopt($chanel, CURLOPT_FAILONERROR, true);
95
        $rspJsonFromClient = curl_exec($chanel);
96
        if (curl_errno($chanel)) {
97
            $aReturn['info']     = $this->setArrayToJson([
98
                '#'           => curl_errno($chanel),
99
                'description' => curl_error($chanel)
100
            ]);
101
            $aReturn['response'] = '';
102
        } else {
103
            $aReturn['info']     = $this->setArrayToJson(curl_getinfo($chanel));
104
            $aReturn['response'] = $rspJsonFromClient;
105
        }
106
        curl_close($chanel);
107
        $sReturn = '';
0 ignored issues
show
Unused Code introduced by
$sReturn is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
108 View Code Duplication
        if ($this->isJsonByDanielGP($aReturn['info'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
109
            $sReturn = '"info": ' . $aReturn['info'];
110
        } else {
111
            $sReturn = '"info": {' . $aReturn['info'] . ' }';
112
        }
113
        $sReturn .= ', ';
114 View Code Duplication
        if ($this->isJsonByDanielGP($aReturn['response'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
115
            $sReturn .= '"response": ' . $aReturn['response'];
116
        } else {
117
            $sReturn .= '"response": { ' . $aReturn['response'] . ' }';
118
        }
119
        return '{ ' . $sReturn . ' }';
120
    }
121
122
    /**
123
     * Reads the content of a remote file through CURL extension
124
     *
125
     * @param string $fullURL
126
     * @param array $features
127
     * @return blob
128
     */
129
    protected function getContentFromUrlThroughCurlAsArrayIfJson($fullURL, $features = null)
130
    {
131
        $result = $this->setJsonToArray($this->getContentFromUrlThroughCurl($fullURL, $features));
132 View Code Duplication
        if (isset($result['info'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
133
            if (is_array($result['info'])) {
134
                ksort($result['info']);
135
            }
136
        }
137 View Code Duplication
        if (isset($result['response'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
138
            if (is_array($result['response'])) {
139
                ksort($result['response']);
140
            }
141
        }
142
        return $result;
143
    }
144
145
    protected function getFeedbackMySQLAffectedRecords()
146
    {
147
        if (is_null($this->mySQLconnection)) {
148
            $message = 'No MySQL';
149
        } else {
150
            $afRows  = $this->mySQLconnection->affected_rows;
151
            $message = sprintf($this->lclMsgCmnNumber('i18n_Record', 'i18n_Records', $afRows), $afRows);
152
        }
153
        return '<div>'
154
                . $message
155
                . '</div>';
156
    }
157
158
    /**
159
     * returns the details about Communicator (current) file
160
     *
161
     * @param string $fileGiven
162
     * @return array
163
     */
164
    protected function getFileDetails($fileGiven)
165
    {
166
        if (!file_exists($fileGiven)) {
167
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenFileDoesNotExist'), $fileGiven)];
168
        }
169
        $info    = new \SplFileInfo($fileGiven);
170
        $sReturn = [
171
            'File Extension'         => $info->getExtension(),
172
            'File Group'             => $info->getGroup(),
173
            'File Inode'             => $info->getInode(),
174
            'File Link Target'       => ($info->isLink() ? $info->getLinkTarget() : '-'),
175
            'File is Dir'            => $info->isDir(),
176
            'File is Executable'     => $info->isExecutable(),
177
            'File is File'           => $info->isFile(),
178
            'File is Link'           => $info->isLink(),
179
            'File is Readable'       => $info->isReadable(),
180
            'File is Writable'       => $info->isWritable(),
181
            'File Name'              => $info->getBasename('.' . $info->getExtension()),
182
            'File Name w. Extension' => $info->getFilename(),
183
            'File Owner'             => $info->getOwner(),
184
            'File Path'              => $info->getPath(),
185
            'File Permissions'       => $this->explainPerms($info->getPerms()),
186
            'Name'                   => $info->getRealPath(),
187
            'Size'                   => $info->getSize(),
188
            'Sha1'                   => sha1_file($fileGiven),
189
            'Timestamp Accessed'     => [
190
                'PHP number' => $info->getATime(),
191
                'SQL format' => date('Y-m-d H:i:s', $info->getATime()),
192
            ],
193
            'Timestamp Changed'      => [
194
                'PHP number' => $info->getCTime(),
195
                'SQL format' => date('Y-m-d H:i:s', $info->getCTime()),
196
            ],
197
            'Timestamp Modified'     => [
198
                'PHP number' => $info->getMTime(),
199
                'SQL format' => date('Y-m-d H:i:s', $info->getMTime()),
200
            ],
201
            'Type'                   => $info->getType(),
202
        ];
203
        return $sReturn;
204
    }
205
206
    /**
207
     * returns a multi-dimensional array with list of file details within a given path
208
     * (by using Symfony/Finder package)
209
     *
210
     * @param  string $pathAnalised
211
     * @return array
212
     */
213
    protected function getListOfFiles($pathAnalised)
214
    {
215
        if (realpath($pathAnalised) === false) {
216
            $aFiles = [
217
                'error' => sprintf($this->lclMsgCmn('i18n_Error_GivenPathIsNotValid'), $pathAnalised)
218
            ];
219
        } elseif (!is_dir($pathAnalised)) {
220
            $aFiles = [
221
                'error' => $this->lclMsgCmn('i18n_Error_GivenPathIsNotFolder')
222
            ];
223
        } else {
224
            $finder   = new \Symfony\Component\Finder\Finder();
225
            $iterator = $finder
226
                    ->files()
227
                    ->sortByName()
228
                    ->in($pathAnalised);
229
            foreach ($iterator as $file) {
230
                $aFiles[$file->getRealPath()] = $this->getFileDetails($file);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$aFiles was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aFiles = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
231
            }
232
        }
233
        return $aFiles;
0 ignored issues
show
Bug introduced by
The variable $aFiles does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
234
    }
235
236
    /**
237
     * Returns server Timestamp into various formats
238
     *
239
     * @param string $returnType
240
     * @return string
241
     */
242
    protected function getTimestamp($returnType = 'string')
243
    {
244
        $crtTime = gettimeofday();
245
        switch ($returnType) {
246
            case 'array':
247
                $sReturn = [
248
                    'float'  => ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6)),
249
                    'string' => implode('', [
250
                        '<span style="color:black!important;font-weight:bold;">[',
251
                        date('Y-m-d H:i:s.', $crtTime['sec']),
252
                        substr(round($crtTime['usec'], -3), 0, 3),
253
                        ']</span> '
254
                    ]),
255
                ];
256
                break;
257
            case 'float':
258
                $sReturn = ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6));
259
                break;
260
            case 'string':
261
                $sReturn = implode('', [
262
                    '<span style="color:black!important;font-weight:bold;">[',
263
                    date('Y-m-d H:i:s.', $crtTime['sec']),
264
                    substr(round($crtTime['usec'], -3), 0, 3),
265
                    ']</span> '
266
                ]);
267
                break;
268
            default:
269
                $sReturn = sprintf($this->lclMsgCmn('i18n_Error_UnknownReturnType'), $returnType);
270
                break;
271
        }
272
        return $sReturn;
273
    }
274
275
    /**
276
     * Tests if given string has a valid Json format
277
     *
278
     * @param string $inputJson
279
     * @return boolean|string
280
     */
281
    protected function isJsonByDanielGP($inputJson)
282
    {
283
        if (is_string($inputJson)) {
284
            json_decode($inputJson);
285
            return (json_last_error() == JSON_ERROR_NONE);
286
        } else {
287
            return $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson');
288
        }
289
    }
290
291
    /**
292
     * Moves files into another folder
293
     *
294
     * @param type $sourcePath
295
     * @param type $targetPath
296
     * @param type $overwrite
0 ignored issues
show
Bug introduced by
There is no parameter named $overwrite. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
297
     * @return type
298
     */
299
    protected function moveFilesIntoTargetFolder($sourcePath, $targetPath)
300
    {
301
        $filesystem = new \Symfony\Component\Filesystem\Filesystem();
302
        $filesystem->mirror($sourcePath, $targetPath);
303
        $finder     = new \Symfony\Component\Finder\Finder();
304
        $iterator   = $finder
305
                ->files()
306
                ->ignoreUnreadableDirs(true)
307
                ->followLinks()
308
                ->in($sourcePath);
309
        $sFiles     = [];
310
        foreach ($iterator as $file) {
311
            $relativePathFile = str_replace($sourcePath, '', $file->getRealPath());
312
            if (!file_exists($targetPath . $relativePathFile)) {
313
                $sFiles[$relativePathFile] = $targetPath . $relativePathFile;
314
            }
315
        }
316
        return $this->setArrayToJson($sFiles);
317
    }
318
319
    /**
320
     * Remove files older than given rule
321
     * (both Access time and Modified time will be checked
322
     * and only if both matches removal will take place)
323
     *
324
     * @param array $inputArray
325
     * @return string
326
     */
327
    protected function removeFilesOlderThanGivenRule($inputArray)
328
    {
329
        if (is_array($inputArray)) {
330
            if (!isset($inputArray['path'])) {
331
                $proceedWithDeletion = false;
332
                $error               = '`path` has not been provided';
333
            } elseif (!isset($inputArray['dateRule'])) {
334
                $proceedWithDeletion = false;
335
                $error               = '`dateRule` has not been provided';
336
            } else {
337
                $proceedWithDeletion = true;
338
            }
339
        } else {
340
            $proceedWithDeletion = false;
341
        }
342
        if ($proceedWithDeletion) {
343
            $finder   = new \Symfony\Component\Finder\Finder();
344
            $iterator = $finder
345
                    ->files()
346
                    ->ignoreUnreadableDirs(true)
347
                    ->followLinks()
348
                    ->in($inputArray['path']);
349
            $aFiles   = null;
350
            foreach ($iterator as $file) {
351
                if ($file->getATime() < strtotime($inputArray['dateRule'])) {
352
                    $aFiles[] = $file->getRealPath();
353
                }
354
            }
355
            if (is_null($aFiles)) {
356
                return null;
357
            } else {
358
                $filesystem = new \Symfony\Component\Filesystem\Filesystem();
359
                $filesystem->remove($aFiles);
360
                return $this->setArrayToJson($aFiles);
361
            }
362
        } else {
363
            return $error;
0 ignored issues
show
Bug introduced by
The variable $error does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
364
        }
365
    }
366
367
    /**
368
     * Send an array of parameters like a form through a POST action
369
     *
370
     * @param string $urlToSendTo
371
     * @param array $params
372
     * @throws \Exception
373
     * @throws \UnexpectedValueException
374
     */
375
    protected function sendBackgroundEncodedFormElementsByPost($urlToSendTo, $params = [])
0 ignored issues
show
Coding Style introduced by
sendBackgroundEncodedFormElementsByPost uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
376
    {
377
        try {
378
            $postingUrl = filter_var($urlToSendTo, FILTER_VALIDATE_URL);
379
            if ($postingUrl === false) {
380
                throw new \Exception($exc);
381
            } else {
382
                if (is_array($params)) {
383
                    $postingString   = $this->setArrayToStringForUrl('&', $params);
384
                    $postingUrlParts = parse_url($postingUrl);
385
                    $postingPort     = (isset($postingUrlParts['port']) ? $postingUrlParts['port'] : 80);
386
                    $flPointer       = fsockopen($postingUrlParts['host'], $postingPort, $errNo, $errorMessage, 30);
387
                    if ($flPointer === false) {
388
                        throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_FailedToConnect') . ': '
389
                        . $errNo . ' (' . $errorMessage . ')');
390
                    } else {
391
                        $out[] = 'POST ' . $postingUrlParts['path'] . ' ' . $_SERVER['SERVER_PROTOCOL'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$out was never initialized. Although not strictly required by PHP, it is generally a good practice to add $out = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
392
                        $out[] = 'Host: ' . $postingUrlParts['host'];
393
                        if (isset($_SERVER['HTTP_USER_AGENT'])) {
394
                            $out[] = 'User-Agent: ' . filter_var($_SERVER['HTTP_USER_AGENT'], FILTER_SANITIZE_STRING);
395
                        }
396
                        $out[] = 'Content-Type: application/x-www-form-urlencoded';
397
                        $out[] = 'Content-Length: ' . strlen($postingString);
398
                        $out[] = 'Connection: Close' . "\r\n";
399
                        $out[] = $postingString;
400
                        fwrite($flPointer, implode("\r\n", $out));
401
                        fclose($flPointer);
402
                    }
403
                } else {
404
                    throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_GivenParameterIsNotAnArray'));
405
                }
406
            }
407
        } catch (\Exception $exc) {
408
            echo '<pre style="color:#f00">' . $exc->getTraceAsString() . '</pre>';
409
        }
410
    }
411
412
    /**
413
     * Converts an array into JSON string
414
     *
415
     * @param array $inArray
416
     * @return string
417
     */
418
    protected function setArrayToJson(array $inArray)
419
    {
420
        if (!is_array($inArray)) {
421
            return $this->lclMsgCmn('i18n_Error_GivenInputIsNotArray');
422
        }
423
        $rtrn      = utf8_encode(json_encode($inArray, JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
424
        $jsonError = $this->setJsonErrorInPlainEnglish();
425
        if (is_null($jsonError)) {
426
            return $rtrn;
427
        } else {
428
            return $jsonError;
429
        }
430
    }
431
432
    /**
433
     * Replace space with break line for each key element
434
     *
435
     * @param array $aElements
436
     * @return array
437
     */
438
    protected function setArrayToArrayKbr(array $aElements)
439
    {
440
        foreach ($aElements as $key => $value) {
441
            $aReturn[str_replace(' ', '<br/>', $key)] = $value;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$aReturn was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aReturn = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
442
        }
443
        return $aReturn;
0 ignored issues
show
Bug introduced by
The variable $aReturn does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
444
    }
445
446
    /**
447
     * Converts a single-child array into an parent-child one
448
     *
449
     * @param type $inArray
450
     * @return type
451
     */
452
    protected function setArrayValuesAsKey(array $inArray)
453
    {
454
        $outArray = array_combine($inArray, $inArray);
455
        ksort($outArray);
456
        return $outArray;
457
    }
458
459
    /**
460
     * Returns proper result from a mathematical division in order to avoid Zero division erorr or Infinite results
461
     *
462
     * @param float $fAbove
463
     * @param float $fBelow
464
     * @param mixed $mArguments
465
     * @return decimal
466
     */
467
    protected function setDividedResult($fAbove, $fBelow, $mArguments = 0)
468
    {
469
        // prevent infinite result AND division by 0
470
        if (($fAbove == 0) || ($fBelow == 0)) {
471
            $nReturn = 0;
472
        } else {
473
            if (is_array($mArguments)) {
474
                $nReturn = $this->setNumberFormat(($fAbove / $fBelow), [
475
                    'MinFractionDigits' => $mArguments[1],
476
                    'MaxFractionDigits' => $mArguments[1],
477
                ]);
478
            } else {
479
                $nReturn = $this->setNumberFormat(round(($fAbove / $fBelow), $mArguments));
480
            }
481
        }
482
        return $nReturn;
483
    }
484
485
    /**
486
     * Provides a list of all known JSON errors and their description
487
     *
488
     * @return type
489
     */
490
    private function setJsonErrorInPlainEnglish()
491
    {
492
        $knownErrors  = [
493
            JSON_ERROR_NONE           => null,
494
            JSON_ERROR_DEPTH          => 'Maximum stack depth exceeded',
495
            JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
496
            JSON_ERROR_CTRL_CHAR      => 'Unexpected control character found',
497
            JSON_ERROR_SYNTAX         => 'Syntax error, malformed JSON',
498
            JSON_ERROR_UTF8           => 'Malformed UTF-8 characters, possibly incorrectly encoded',
499
        ];
500
        $currentError = json_last_error();
501
        $sReturn      = null;
502
        if (in_array($currentError, $knownErrors)) {
503
            $sReturn = $knownErrors[$currentError];
504
        }
505
        return $sReturn;
506
    }
507
508
    /**
509
     * Converts a JSON string into an Array
510
     *
511
     * @param string $inputJson
512
     * @return array
513
     */
514
    protected function setJsonToArray($inputJson)
515
    {
516
        if (!$this->isJsonByDanielGP($inputJson)) {
517
            return [
518
                'error' => $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson')
519
            ];
520
        }
521
        $sReturn   = (json_decode($inputJson, true));
522
        $jsonError = $this->setJsonErrorInPlainEnglish();
523
        if (is_null($jsonError)) {
524
            return $sReturn;
525
        } else {
526
            return [
527
                'error' => $jsonError
528
            ];
529
        }
530
    }
531
}
532