Completed
Push — master ( d48f6d...0338e7 )
by Daniel
02:45
created

CommonCode::setDividedResult()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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