Completed
Push — master ( 1f598b...c0ad9a )
by Daniel
02:43
created

sendBackgroundEncodedFormElementsByPost()   B

Complexity

Conditions 6
Paths 17

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
c 6
b 0
f 0
dl 0
loc 27
rs 8.439
cc 6
eloc 21
nc 17
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 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
    private function buildArrayForCurlInterogation($chanel, $rspJsonFromClient)
66
    {
67
        if (curl_errno($chanel)) {
68
            return [
69
                'info'     => $this->setArrayToJson(['#' => curl_errno($chanel), 'description' => curl_error($chanel)]),
70
                'response' => '',
71
            ];
72
        }
73
        return [
74
            'info'     => $this->setArrayToJson(curl_getinfo($chanel)),
75
            'response' => $rspJsonFromClient,
76
        ];
77
    }
78
79
    /**
80
     * Reads the content of a remote file through CURL extension
81
     *
82
     * @param string $fullURL
83
     * @param array $features
84
     * @return blob
85
     */
86
    protected function getContentFromUrlThroughCurl($fullURL, $features = null)
87
    {
88
        if (!function_exists('curl_init')) {
89
            $aReturn = [
90
                'info'     => $this->lclMsgCmn('i18n_Error_ExtensionNotLoaded'),
91
                'response' => '',
92
            ];
93
            return $this->setArrayToJson($aReturn);
94
        }
95
        if (!filter_var($fullURL, FILTER_VALIDATE_URL)) {
96
            $aReturn = [
97
                'info'     => $this->lclMsgCmn('i18n_Error_GivenUrlIsNotValid'),
98
                'response' => '',
99
            ];
100
            return $this->setArrayToJson($aReturn);
101
        }
102
        $aReturn = $this->getContentFromUrlThroughCurlRawArray($fullURL, $features);
103
        return '{ ' . $this->packIntoJson($aReturn, 'info') . ', ' . $this->packIntoJson($aReturn, 'response') . ' }';
104
    }
105
106
    /**
107
     * Reads the content of a remote file through CURL extension
108
     *
109
     * @param string $fullURL
110
     * @param array $features
111
     * @return blob
112
     */
113
    protected function getContentFromUrlThroughCurlAsArrayIfJson($fullURL, $features = null)
114
    {
115
        $result = $this->setJsonToArray($this->getContentFromUrlThroughCurl($fullURL, $features));
116
        if (is_array($result['info'])) {
117
            ksort($result['info']);
118
        }
119
        if (is_array($result['response'])) {
120
            ksort($result['response']);
121
        }
122
        return $result;
123
    }
124
125
    protected function getContentFromUrlThroughCurlRawArray($fullURL, $features = null)
126
    {
127
        $chanel = curl_init();
128
        curl_setopt($chanel, CURLOPT_USERAGENT, $this->getUserAgentByCommonLib());
129
        if ((strpos($fullURL, 'https') !== false) || (isset($features['forceSSLverification']))) {
130
            curl_setopt($chanel, CURLOPT_SSL_VERIFYHOST, false);
131
            curl_setopt($chanel, CURLOPT_SSL_VERIFYPEER, false);
132
        }
133
        curl_setopt($chanel, CURLOPT_URL, $fullURL);
134
        curl_setopt($chanel, CURLOPT_HEADER, false);
135
        curl_setopt($chanel, CURLOPT_RETURNTRANSFER, true);
136
        curl_setopt($chanel, CURLOPT_FRESH_CONNECT, true); //avoid a cached response
137
        curl_setopt($chanel, CURLOPT_FAILONERROR, true);
138
        $rspJsonFromClient = curl_exec($chanel);
139
        $aReturn           = $this->buildArrayForCurlInterogation($chanel, $rspJsonFromClient);
140
        curl_close($chanel);
141
        return $aReturn;
142
    }
143
144
    protected function getFeedbackMySQLAffectedRecords()
145
    {
146
        if (is_null($this->mySQLconnection)) {
147
            $message = 'No MySQL';
148
        } else {
149
            $afRows  = $this->mySQLconnection->affected_rows;
150
            $message = sprintf($this->lclMsgCmnNumber('i18n_Record', 'i18n_Records', $afRows), $afRows);
151
        }
152
        return '<div>' . $message . '</div>';
153
    }
154
155
    /**
156
     * returns the details about Communicator (current) file
157
     *
158
     * @param string $fileGiven
159
     * @return array
160
     */
161
    protected function getFileDetails($fileGiven)
162
    {
163
        if (!file_exists($fileGiven)) {
164
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenFileDoesNotExist'), $fileGiven)];
165
        }
166
        return $this->getFileDetailsRaw($fileGiven);
167
    }
168
169
    /**
170
     * returns a multi-dimensional array with list of file details within a given path
171
     * (by using Symfony/Finder package)
172
     *
173
     * @param  string $pathAnalised
174
     * @return array
175
     */
176
    protected function getListOfFiles($pathAnalised)
177
    {
178
        if (realpath($pathAnalised) === false) {
179
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenPathIsNotValid'), $pathAnalised)];
180
        } elseif (!is_dir($pathAnalised)) {
181
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenPathIsNotFolder')];
182
        }
183
        $finder   = new \Symfony\Component\Finder\Finder();
184
        $iterator = $finder->files()->sortByName()->in($pathAnalised);
185
        $aFiles   = null;
186
        foreach ($iterator as $file) {
187
            $aFiles[$file->getRealPath()] = $this->getFileDetails($file);
188
        }
189
        return $aFiles;
190
    }
191
192
    /**
193
     * Returns server Timestamp into various formats
194
     *
195
     * @param string $returnType
196
     * @return string
197
     */
198
    protected function getTimestamp($returnType = 'string')
199
    {
200
        $crtTime          = gettimeofday();
201
        $knownReturnTypes = ['array', 'float', 'string'];
202
        if (in_array($returnType, $knownReturnTypes)) {
203
            return call_user_func([$this, 'getTimestamp' . ucfirst($returnType)], $crtTime);
204
        }
205
        return sprintf($this->lclMsgCmn('i18n_Error_UnknownReturnType'), $returnType);
206
    }
207
208
    private function getTimestampArray($crtTime)
209
    {
210
        return [
211
            'float'  => $this->getTimestampFloat($crtTime),
212
            'string' => $this->getTimestampString($crtTime),
213
        ];
214
    }
215
216
    private function getTimestampFloat($crtTime)
217
    {
218
        return ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6));
219
    }
220
221
    private function getTimestampString($crtTime)
222
    {
223
        return implode('', [
224
            '<span style="color:black!important;font-weight:bold;">[',
225
            date('Y-m-d H:i:s.', $crtTime['sec']),
226
            substr(round($crtTime['usec'], -3), 0, 3),
227
            ']</span> '
228
        ]);
229
    }
230
231
    /**
232
     * Tests if given string has a valid Json format
233
     *
234
     * @param string $inputJson
235
     * @return boolean|string
236
     */
237
    protected function isJsonByDanielGP($inputJson)
238
    {
239
        if (is_string($inputJson)) {
240
            json_decode($inputJson);
241
            return (json_last_error() == JSON_ERROR_NONE);
242
        }
243
        return $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson');
244
    }
245
246
    private function packIntoJson($aReturn, $keyToWorkWith)
247
    {
248
        if ($this->isJsonByDanielGP($aReturn[$keyToWorkWith])) {
249
            return '"' . $keyToWorkWith . '": ' . $aReturn[$keyToWorkWith];
250
        }
251
        return '"' . $keyToWorkWith . '": {' . $aReturn[$keyToWorkWith] . ' }';
252
    }
253
254
    /**
255
     * Send an array of parameters like a form through a POST action
256
     *
257
     * @param string $urlToSendTo
258
     * @param array $params
259
     * @throws \Exception
260
     * @throws \UnexpectedValueException
261
     */
262
    protected function sendBackgroundEncodedFormElementsByPost($urlToSendTo, $params = [])
263
    {
264
        try {
265
            $postingUrl = filter_var($urlToSendTo, FILTER_VALIDATE_URL);
266
            if ($postingUrl === false) {
267
                throw new \Exception($exc);
268
            } else {
269
                if (is_array($params)) {
270
                    $postingString = $this->setArrayToStringForUrl('&', $params);
271
                    $pUrlParts     = parse_url($postingUrl);
272
                    $postingPort   = (isset($pUrlParts['port']) ? $pUrlParts['port'] : 80);
273
                    $flPointer     = fsockopen($pUrlParts['host'], $postingPort, $errNo, $errorMessage, 30);
274
                    if ($flPointer === false) {
275
                        throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_FailedToConnect') . ': '
276
                        . $errNo . ' (' . $errorMessage . ')');
277
                    } else {
278
                        fwrite($flPointer, $this->sendBackgroundPrepareData($pUrlParts, $postingString));
279
                        fclose($flPointer);
280
                    }
281
                } else {
282
                    throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_GivenParameterIsNotAnArray'));
283
                }
284
            }
285
        } catch (\Exception $exc) {
286
            echo '<pre style="color:#f00">' . $exc->getTraceAsString() . '</pre>';
287
        }
288
    }
289
290
    protected function sendBackgroundPrepareData($pUrlParts, $postingString)
291
    {
292
        $this->initializeSprGlbAndSession();
293
        $out   = [];
294
        $out[] = 'POST ' . $pUrlParts['path'] . ' ' . $this->tCmnSuperGlobals->server->get['SERVER_PROTOCOL'];
295
        $out[] = 'Host: ' . $pUrlParts['host'];
296
        if (is_null($this->tCmnSuperGlobals->server->get('HTTP_USER_AGENT'))) {
297
            $out[] = 'User-Agent: ' . $this->tCmnSuperGlobals->server->get('HTTP_USER_AGENT');
298
        }
299
        $out[] = 'Content-Type: application/x-www-form-urlencoded';
300
        $out[] = 'Content-Length: ' . strlen($postingString);
301
        $out[] = 'Connection: Close' . "\r\n";
302
        $out[] = $postingString;
303
        return implode("\r\n", $out);
304
    }
305
306
    /**
307
     * Returns proper result from a mathematical division in order to avoid Zero division erorr or Infinite results
308
     *
309
     * @param float $fAbove
310
     * @param float $fBelow
311
     * @param mixed $mArguments
312
     * @return decimal
313
     */
314
    protected function setDividedResult($fAbove, $fBelow, $mArguments = 0)
315
    {
316
        if (($fAbove == 0) || ($fBelow == 0)) { // prevent infinite result AND division by 0
317
            return 0;
318
        }
319
        if (is_array($mArguments)) {
320
            $frMinMax = [
321
                'MinFractionDigits' => $mArguments[1],
322
                'MaxFractionDigits' => $mArguments[1],
323
            ];
324
            return $this->setNumberFormat(($fAbove / $fBelow), $frMinMax);
325
        }
326
        return $this->setNumberFormat(round(($fAbove / $fBelow), $mArguments));
327
    }
328
329
    /**
330
     * Converts a JSON string into an Array
331
     *
332
     * @param string $inputJson
333
     * @return array
334
     */
335
    protected function setJsonToArray($inputJson)
336
    {
337
        if (!$this->isJsonByDanielGP($inputJson)) {
338
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson')];
339
        }
340
        $sReturn   = (json_decode($inputJson, true));
341
        $jsonError = $this->setJsonErrorInPlainEnglish();
342
        if (is_null($jsonError)) {
343
            return $sReturn;
344
        } else {
345
            return ['error' => $jsonError];
346
        }
347
    }
348
}
349