Completed
Push — master ( 6091e1...47dbb9 )
by Daniel
03:05
created

CommonCode::isJsonByDanielGP()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
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 CommonBasic,
40
        CommonPermissions,
41
        DomComponentsByDanielGP,
42
        MySQLiByDanielGPqueries,
43
        MySQLiByDanielGP;
44
45
    protected function arrayDiffAssocRecursive($array1, $array2)
46
    {
47
        $difference = [];
48
        foreach ($array1 as $key => $value) {
49
            if (is_array($value)) {
50
                if (!isset($array2[$key]) || !is_array($array2[$key])) {
51
                    $difference[$key] = $value;
52
                } else {
53
                    $workingDiff = $this->arrayDiffAssocRecursive($value, $array2[$key]);
54
                    if (!empty($workingDiff)) {
55
                        $difference[$key] = $workingDiff;
56
                    }
57
                }
58
            } elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
59
                $difference[$key] = $value;
60
            }
61
        }
62
        return $difference;
63
    }
64
65
    /**
66
     * Reads the content of a remote file through CURL extension
67
     *
68
     * @param string $fullURL
69
     * @param array $features
70
     * @return blob
71
     */
72
    protected function getContentFromUrlThroughCurl($fullURL, $features = null)
73
    {
74
        if (!function_exists('curl_init')) {
75
            $aReturn = [
76
                'info'     => $this->lclMsgCmn('i18n_Error_ExtensionNotLoaded'),
77
                'response' => '',
78
            ];
79
            return $this->setArrayToJson($aReturn);
80
        }
81
        if (!filter_var($fullURL, FILTER_VALIDATE_URL)) {
82
            $aReturn = [
83
                'info'     => $this->lclMsgCmn('i18n_Error_GivenUrlIsNotValid'),
84
                'response' => '',
85
            ];
86
            return $this->setArrayToJson($aReturn);
87
        }
88
        $aReturn = $this->getContentFromUrlThroughCurlRawArray($fullURL, $features);
89
        return '{ ' . $this->packIntoJson($aReturn, 'info') . ', ' . $this->packIntoJson($aReturn, 'response') . ' }';
90
    }
91
92
    /**
93
     * Reads the content of a remote file through CURL extension
94
     *
95
     * @param string $fullURL
96
     * @param array $features
97
     * @return blob
98
     */
99
    protected function getContentFromUrlThroughCurlAsArrayIfJson($fullURL, $features = null)
100
    {
101
        $result = $this->setJsonToArray($this->getContentFromUrlThroughCurl($fullURL, $features));
102
        if (is_array($result['info'])) {
103
            ksort($result['info']);
104
        }
105
        if (is_array($result['response'])) {
106
            ksort($result['response']);
107
        }
108
        return $result;
109
    }
110
111
    protected function getContentFromUrlThroughCurlRawArray($fullURL, $features = null)
112
    {
113
        $chanel = curl_init();
114
        curl_setopt($chanel, CURLOPT_USERAGENT, $this->getUserAgentByCommonLib());
115
        if ((strpos($fullURL, 'https') !== false) || (isset($features['forceSSLverification']))) {
116
            curl_setopt($chanel, CURLOPT_SSL_VERIFYHOST, false);
117
            curl_setopt($chanel, CURLOPT_SSL_VERIFYPEER, false);
118
        }
119
        curl_setopt($chanel, CURLOPT_URL, $fullURL);
120
        curl_setopt($chanel, CURLOPT_HEADER, false);
121
        curl_setopt($chanel, CURLOPT_RETURNTRANSFER, true);
122
        curl_setopt($chanel, CURLOPT_FRESH_CONNECT, true); //avoid a cached response
123
        curl_setopt($chanel, CURLOPT_FAILONERROR, true);
124
        $rspJsonFromClient = curl_exec($chanel);
125
        $aReturn           = [];
126
        if (curl_errno($chanel)) {
127
            $aReturn['info']     = $this->setArrayToJson([
128
                '#'           => curl_errno($chanel),
129
                'description' => curl_error($chanel)
130
            ]);
131
            $aReturn['response'] = '';
132
        } else {
133
            $aReturn['info']     = $this->setArrayToJson(curl_getinfo($chanel));
134
            $aReturn['response'] = $rspJsonFromClient;
135
        }
136
        curl_close($chanel);
137
        return $aReturn;
138
    }
139
140
    protected function getFeedbackMySQLAffectedRecords()
141
    {
142
        if (is_null($this->mySQLconnection)) {
143
            $message = 'No MySQL';
144
        } else {
145
            $afRows  = $this->mySQLconnection->affected_rows;
146
            $message = sprintf($this->lclMsgCmnNumber('i18n_Record', 'i18n_Records', $afRows), $afRows);
147
        }
148
        return '<div>' . $message . '</div>';
149
    }
150
151
    /**
152
     * returns the details about Communicator (current) file
153
     *
154
     * @param string $fileGiven
155
     * @return array
156
     */
157
    protected function getFileDetails($fileGiven)
158
    {
159
        if (!file_exists($fileGiven)) {
160
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenFileDoesNotExist'), $fileGiven)];
161
        }
162
        $info = new \SplFileInfo($fileGiven);
163
        return [
164
            'File Extension'         => $info->getExtension(),
165
            'File Group'             => $info->getGroup(),
166
            'File Inode'             => $info->getInode(),
167
            'File Link Target'       => ($info->isLink() ? $info->getLinkTarget() : '-'),
168
            'File is Dir'            => $info->isDir(),
169
            'File is Executable'     => $info->isExecutable(),
170
            'File is File'           => $info->isFile(),
171
            'File is Link'           => $info->isLink(),
172
            'File is Readable'       => $info->isReadable(),
173
            'File is Writable'       => $info->isWritable(),
174
            'File Name'              => $info->getBasename('.' . $info->getExtension()),
175
            'File Name w. Extension' => $info->getFilename(),
176
            'File Owner'             => $info->getOwner(),
177
            'File Path'              => $info->getPath(),
178
            'File Permissions'       => $this->explainPerms($info->getPerms()),
179
            'Name'                   => $info->getRealPath(),
180
            'Size'                   => $info->getSize(),
181
            'Sha1'                   => sha1_file($fileGiven),
182
            'Timestamp Accessed'     => [
183
                'PHP number' => $info->getATime(),
184
                'SQL format' => date('Y-m-d H:i:s', $info->getATime()),
185
            ],
186
            'Timestamp Changed'      => [
187
                'PHP number' => $info->getCTime(),
188
                'SQL format' => date('Y-m-d H:i:s', $info->getCTime()),
189
            ],
190
            'Timestamp Modified'     => [
191
                'PHP number' => $info->getMTime(),
192
                'SQL format' => date('Y-m-d H:i:s', $info->getMTime()),
193
            ],
194
            'Type'                   => $info->getType(),
195
        ];
196
    }
197
198
    /**
199
     * returns a multi-dimensional array with list of file details within a given path
200
     * (by using Symfony/Finder package)
201
     *
202
     * @param  string $pathAnalised
203
     * @return array
204
     */
205
    protected function getListOfFiles($pathAnalised)
206
    {
207
        if (realpath($pathAnalised) === false) {
208
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenPathIsNotValid'), $pathAnalised)];
209
        } elseif (!is_dir($pathAnalised)) {
210
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenPathIsNotFolder')];
211
        }
212
        $aFiles   = null;
213
        $finder   = new \Symfony\Component\Finder\Finder();
214
        $iterator = $finder
215
                ->files()
216
                ->sortByName()
217
                ->in($pathAnalised);
218
        foreach ($iterator as $file) {
219
            $aFiles[$file->getRealPath()] = $this->getFileDetails($file);
220
        }
221
        return $aFiles;
222
    }
223
224
    /**
225
     * Returns server Timestamp into various formats
226
     *
227
     * @param string $returnType
228
     * @return string
229
     */
230
    protected function getTimestamp($returnType = 'string')
231
    {
232
        $crtTime = gettimeofday();
233
        switch ($returnType) {
234
            case 'array':
235
                $sReturn = [
236
                    'float'  => ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6)),
237
                    'string' => implode('', [
238
                        '<span style="color:black!important;font-weight:bold;">[',
239
                        date('Y-m-d H:i:s.', $crtTime['sec']),
240
                        substr(round($crtTime['usec'], -3), 0, 3),
241
                        ']</span> '
242
                    ]),
243
                ];
244
                break;
245
            case 'float':
246
                $sReturn = ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6));
247
                break;
248
            case 'string':
249
                $sReturn = 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
                break;
256
            default:
257
                $sReturn = sprintf($this->lclMsgCmn('i18n_Error_UnknownReturnType'), $returnType);
258
                break;
259
        }
260
        return $sReturn;
261
    }
262
263
    /**
264
     * Tests if given string has a valid Json format
265
     *
266
     * @param string $inputJson
267
     * @return boolean|string
268
     */
269
    protected function isJsonByDanielGP($inputJson)
270
    {
271
        if (is_string($inputJson)) {
272
            json_decode($inputJson);
273
            return (json_last_error() == JSON_ERROR_NONE);
274
        }
275
        return $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson');
276
    }
277
278
    private function packIntoJson($aReturn, $keyToWorkWith)
279
    {
280
        if ($this->isJsonByDanielGP($aReturn[$keyToWorkWith])) {
281
            return '"' . $keyToWorkWith . '": ' . $aReturn[$keyToWorkWith];
282
        }
283
        return '"' . $keyToWorkWith . '": {' . $aReturn[$keyToWorkWith] . ' }';
284
    }
285
286
    /**
287
     * Send an array of parameters like a form through a POST action
288
     *
289
     * @param string $urlToSendTo
290
     * @param array $params
291
     * @throws \Exception
292
     * @throws \UnexpectedValueException
293
     */
294
    protected function sendBackgroundEncodedFormElementsByPost($urlToSendTo, $params = [])
295
    {
296
        try {
297
            $postingUrl = filter_var($urlToSendTo, FILTER_VALIDATE_URL);
298
            if ($postingUrl === false) {
299
                throw new \Exception($exc);
300
            } else {
301
                if (is_array($params)) {
302
                    $postingString = $this->setArrayToStringForUrl('&', $params);
303
                    $pUrlParts     = parse_url($postingUrl);
304
                    $postingPort   = (isset($pUrlParts['port']) ? $pUrlParts['port'] : 80);
305
                    $flPointer     = fsockopen($pUrlParts['host'], $postingPort, $errNo, $errorMessage, 30);
306
                    if ($flPointer === false) {
307
                        throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_FailedToConnect') . ': '
308
                        . $errNo . ' (' . $errorMessage . ')');
309
                    } else {
310
                        fwrite($flPointer, $this->sendBackgroundPrepareData($pUrlParts, $postingString));
311
                        fclose($flPointer);
312
                    }
313
                } else {
314
                    throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_GivenParameterIsNotAnArray'));
315
                }
316
            }
317
        } catch (\Exception $exc) {
318
            echo '<pre style="color:#f00">' . $exc->getTraceAsString() . '</pre>';
319
        }
320
    }
321
322
    protected function sendBackgroundPrepareData($pUrlParts, $postingString)
0 ignored issues
show
Coding Style introduced by
sendBackgroundPrepareData 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...
323
    {
324
        $this->initializeSprGlbAndSession();
325
        $out   = [];
326
        $out[] = 'POST ' . $pUrlParts['path'] . ' ' . $this->tCmnSuperGlobals->server->get['SERVER_PROTOCOL'];
327
        $out[] = 'Host: ' . $pUrlParts['host'];
328
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
329
            $out[] = 'User-Agent: ' . $this->tCmnSuperGlobals->server->get('HTTP_USER_AGENT');
330
        }
331
        $out[] = 'Content-Type: application/x-www-form-urlencoded';
332
        $out[] = 'Content-Length: ' . strlen($postingString);
333
        $out[] = 'Connection: Close' . "\r\n";
334
        $out[] = $postingString;
335
        return implode("\r\n", $out);
336
    }
337
338
    /**
339
     * Returns proper result from a mathematical division in order to avoid Zero division erorr or Infinite results
340
     *
341
     * @param float $fAbove
342
     * @param float $fBelow
343
     * @param mixed $mArguments
344
     * @return decimal
345
     */
346
    protected function setDividedResult($fAbove, $fBelow, $mArguments = 0)
347
    {
348
        if (($fAbove == 0) || ($fBelow == 0)) { // prevent infinite result AND division by 0
349
            return 0;
350
        }
351
        if (is_array($mArguments)) {
352
            $frMinMax = [
353
                'MinFractionDigits' => $mArguments[1],
354
                'MaxFractionDigits' => $mArguments[1],
355
            ];
356
            return $this->setNumberFormat(($fAbove / $fBelow), $frMinMax);
357
        }
358
        return $this->setNumberFormat(round(($fAbove / $fBelow), $mArguments));
359
    }
360
361
    /**
362
     * Converts a JSON string into an Array
363
     *
364
     * @param string $inputJson
365
     * @return array
366
     */
367
    protected function setJsonToArray($inputJson)
368
    {
369
        if (!$this->isJsonByDanielGP($inputJson)) {
370
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson')];
371
        }
372
        $sReturn   = (json_decode($inputJson, true));
373
        $jsonError = $this->setJsonErrorInPlainEnglish();
374
        if (is_null($jsonError)) {
375
            return $sReturn;
376
        } else {
377
            return ['error' => $jsonError];
378
        }
379
    }
380
}
381