Completed
Push — master ( 40f2fc...d48f6d )
by Daniel
02:29
created

CommonCode::getFeedbackMySQLAffectedRecords()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 2
eloc 7
nc 2
nop 0
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
        DomComponentsByDanielGP,
41
        MySQLiByDanielGPqueries,
42
        MySQLiByDanielGP;
43
44
    protected function arrayDiffAssocRecursive($array1, $array2)
45
    {
46
        $difference = [];
47
        foreach ($array1 as $key => $value) {
48
            if (is_array($value)) {
49
                if (!isset($array2[$key]) || !is_array($array2[$key])) {
50
                    $difference[$key] = $value;
51
                } else {
52
                    $workingDiff = $this->arrayDiffAssocRecursive($value, $array2[$key]);
53
                    if (!empty($workingDiff)) {
54
                        $difference[$key] = $workingDiff;
55
                    }
56
                }
57
            } elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
58
                $difference[$key] = $value;
59
            }
60
        }
61
        return $difference;
62
    }
63
64
    private function buildArrayForCurlInterogation($chanel, $rspJsonFromClient)
65
    {
66
        if (curl_errno($chanel)) {
67
            return [
68
                'info'     => $this->setArrayToJson(['#' => curl_errno($chanel), 'description' => curl_error($chanel)]),
69
                'response' => '',
70
            ];
71
        }
72
        return [
73
            'info'     => $this->setArrayToJson(curl_getinfo($chanel)),
74
            'response' => $rspJsonFromClient,
75
        ];
76
    }
77
78
    /**
79
     * Reads the content of a remote file through CURL extension
80
     *
81
     * @param string $fullURL
82
     * @param array $features
83
     * @return blob
84
     */
85
    protected function getContentFromUrlThroughCurl($fullURL, $features = null)
86
    {
87
        if (!function_exists('curl_init')) {
88
            $aReturn = [
89
                'info'     => $this->lclMsgCmn('i18n_Error_ExtensionNotLoaded'),
90
                'response' => '',
91
            ];
92
            return $this->setArrayToJson($aReturn);
93
        }
94
        if (!filter_var($fullURL, FILTER_VALIDATE_URL)) {
95
            $aReturn = [
96
                'info'     => $this->lclMsgCmn('i18n_Error_GivenUrlIsNotValid'),
97
                'response' => '',
98
            ];
99
            return $this->setArrayToJson($aReturn);
100
        }
101
        $aReturn = $this->getContentFromUrlThroughCurlRawArray($fullURL, $features);
102
        return '{ ' . $this->packIntoJson($aReturn, 'info') . ', ' . $this->packIntoJson($aReturn, 'response') . ' }';
103
    }
104
105
    /**
106
     * Reads the content of a remote file through CURL extension
107
     *
108
     * @param string $fullURL
109
     * @param array $features
110
     * @return blob
111
     */
112
    protected function getContentFromUrlThroughCurlAsArrayIfJson($fullURL, $features = null)
113
    {
114
        $result = $this->setJsonToArray($this->getContentFromUrlThroughCurl($fullURL, $features));
115
        if (is_array($result['info'])) {
116
            ksort($result['info']);
117
        }
118
        if (is_array($result['response'])) {
119
            ksort($result['response']);
120
        }
121
        return $result;
122
    }
123
124
    protected function getContentFromUrlThroughCurlRawArray($fullURL, $features = null)
125
    {
126
        $chanel = curl_init();
127
        curl_setopt($chanel, CURLOPT_USERAGENT, $this->getUserAgentByCommonLib());
128
        if ((strpos($fullURL, 'https') !== false) || (isset($features['forceSSLverification']))) {
129
            curl_setopt($chanel, CURLOPT_SSL_VERIFYHOST, false);
130
            curl_setopt($chanel, CURLOPT_SSL_VERIFYPEER, false);
131
        }
132
        curl_setopt($chanel, CURLOPT_URL, $fullURL);
133
        curl_setopt($chanel, CURLOPT_HEADER, false);
134
        curl_setopt($chanel, CURLOPT_RETURNTRANSFER, true);
135
        curl_setopt($chanel, CURLOPT_FRESH_CONNECT, true); //avoid a cached response
136
        curl_setopt($chanel, CURLOPT_FAILONERROR, true);
137
        $rspJsonFromClient = curl_exec($chanel);
138
        $aReturn           = $this->buildArrayForCurlInterogation($chanel, $rspJsonFromClient);
139
        curl_close($chanel);
140
        return $aReturn;
141
    }
142
143
    protected function getFeedbackMySQLAffectedRecords()
144
    {
145
        if (is_null($this->mySQLconnection)) {
146
            $message = 'No MySQL';
147
        } else {
148
            $afRows  = $this->mySQLconnection->affected_rows;
149
            $message = sprintf($this->lclMsgCmnNumber('i18n_Record', 'i18n_Records', $afRows), $afRows);
150
        }
151
        return '<div>' . $message . '</div>';
152
    }
153
154
    /**
155
     * returns the details about Communicator (current) file
156
     *
157
     * @param string $fileGiven
158
     * @return array
159
     */
160
    protected function getFileDetails($fileGiven)
161
    {
162
        if (!file_exists($fileGiven)) {
163
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenFileDoesNotExist'), $fileGiven)];
164
        }
165
        return $this->getFileDetailsRaw($fileGiven);
166
    }
167
168
    /**
169
     * returns a multi-dimensional array with list of file details within a given path
170
     * (by using Symfony/Finder package)
171
     *
172
     * @param  string $pathAnalised
173
     * @return array
174
     */
175
    protected function getListOfFiles($pathAnalised)
176
    {
177
        if (realpath($pathAnalised) === false) {
178
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenPathIsNotValid'), $pathAnalised)];
179
        } elseif (!is_dir($pathAnalised)) {
180
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenPathIsNotFolder')];
181
        }
182
        $finder   = new \Symfony\Component\Finder\Finder();
183
        $iterator = $finder->files()->sortByName()->in($pathAnalised);
184
        $aFiles   = null;
185
        foreach ($iterator as $file) {
186
            $aFiles[$file->getRealPath()] = $this->getFileDetails($file);
187
        }
188
        return $aFiles;
189
    }
190
191
    /**
192
     * Returns server Timestamp into various formats
193
     *
194
     * @param string $returnType
195
     * @return string
196
     */
197
    protected function getTimestamp($returnType = 'string')
198
    {
199
        $crtTime          = gettimeofday();
200
        $knownReturnTypes = ['array', 'float', 'string'];
201
        if (in_array($returnType, $knownReturnTypes)) {
202
            return call_user_func([$this, 'getTimestamp' . ucfirst($returnType)], $crtTime);
203
        }
204
        return sprintf($this->lclMsgCmn('i18n_Error_UnknownReturnType'), $returnType);
205
    }
206
207
    private function getTimestampArray($crtTime)
208
    {
209
        return [
210
            'float'  => $this->getTimestampFloat($crtTime),
211
            'string' => $this->getTimestampString($crtTime),
212
        ];
213
    }
214
215
    private function getTimestampFloat($crtTime)
216
    {
217
        return ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6));
218
    }
219
220
    private function getTimestampString($crtTime)
221
    {
222
        return implode('', [
223
            '<span style="color:black!important;font-weight:bold;">[',
224
            date('Y-m-d H:i:s.', $crtTime['sec']),
225
            substr(round($crtTime['usec'], -3), 0, 3),
226
            ']</span> '
227
        ]);
228
    }
229
230
    /**
231
     * Tests if given string has a valid Json format
232
     *
233
     * @param string $inputJson
234
     * @return boolean|string
235
     */
236
    protected function isJsonByDanielGP($inputJson)
237
    {
238
        if (is_string($inputJson)) {
239
            json_decode($inputJson);
240
            return (json_last_error() == JSON_ERROR_NONE);
241
        }
242
        return $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson');
243
    }
244
245
    private function packIntoJson($aReturn, $keyToWorkWith)
246
    {
247
        if ($this->isJsonByDanielGP($aReturn[$keyToWorkWith])) {
248
            return '"' . $keyToWorkWith . '": ' . $aReturn[$keyToWorkWith];
249
        }
250
        return '"' . $keyToWorkWith . '": {' . $aReturn[$keyToWorkWith] . ' }';
251
    }
252
253
    /**
254
     * Send an array of parameters like a form through a POST action
255
     *
256
     * @param string $urlToSendTo
257
     * @param array $params
258
     * @throws \Exception
259
     */
260
    protected function sendBackgroundEncodedFormElementsByPost($urlToSendTo, $params = [])
261
    {
262
        $postingUrl = filter_var($urlToSendTo, FILTER_VALIDATE_URL);
263
        if ($postingUrl === false) {
264
            throw new \Exception('Invalid URL in ' . __FUNCTION__);
265
        }
266
        if (is_array($params)) {
267
            $cntFailErrMsg = $this->lclMsgCmn('i18n_Error_FailedToConnect');
268
            $this->sendBackgroundPostData($postingUrl, $params, $cntFailErrMsg);
269
            return '';
270
        }
271
        throw new \Exception($this->lclMsgCmn('i18n_Error_GivenParameterIsNotAnArray'));
272
    }
273
274
    private function sendBackgroundPostData($postingUrl, $params, $cntFailErrMsg)
275
    {
276
        $postingString = $this->setArrayToStringForUrl('&', $params);
277
        $pUrlParts     = parse_url($postingUrl);
278
        $postingPort   = 80;
279
        if (isset($pUrlParts['port'])) {
280
            $postingPort = $pUrlParts['port'];
281
        }
282
        $flPointer = fsockopen($pUrlParts['host'], $postingPort, $erN, $erM, 30);
283
        if ($flPointer === false) {
284
            throw new \Exception($cntFailErrMsg . ': ' . $erN . ' (' . $erM . ')');
285
        }
286
        fwrite($flPointer, $this->sendBackgroundPrepareData($pUrlParts, $postingString));
287
        fclose($flPointer);
288
    }
289
290
    private 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