Completed
Push — master ( fe0d66...6612d0 )
by Daniel
04:01
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
    /**
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
        $aReturn = [];
75
        if (!function_exists('curl_init')) {
76
            $aReturn['info']     = $this->lclMsgCmn('i18n_Error_ExtensionNotLoaded');
77
            $aReturn['response'] = '';
78
        }
79
        if (!filter_var($fullURL, FILTER_VALIDATE_URL)) {
80
            $aReturn['info']     = $this->lclMsgCmn('i18n_Error_GivenUrlIsNotValid');
81
            $aReturn['response'] = '';
82
        }
83
        $chanel = curl_init();
84
        curl_setopt($chanel, CURLOPT_USERAGENT, $this->getUserAgentByCommonLib());
85
        if ((strpos($fullURL, 'https') !== false) || (isset($features['forceSSLverification']))) {
86
            curl_setopt($chanel, CURLOPT_SSL_VERIFYHOST, false);
87
            curl_setopt($chanel, CURLOPT_SSL_VERIFYPEER, false);
88
        }
89
        curl_setopt($chanel, CURLOPT_URL, $fullURL);
90
        curl_setopt($chanel, CURLOPT_HEADER, false);
91
        curl_setopt($chanel, CURLOPT_RETURNTRANSFER, true);
92
        curl_setopt($chanel, CURLOPT_FRESH_CONNECT, true); //avoid a cached response
93
        curl_setopt($chanel, CURLOPT_FAILONERROR, true);
94
        $rspJsonFromClient = curl_exec($chanel);
95
        if (curl_errno($chanel)) {
96
            $aReturn['info']     = $this->setArrayToJson([
97
                '#'           => curl_errno($chanel),
98
                'description' => curl_error($chanel)
99
            ]);
100
            $aReturn['response'] = '';
101
        } else {
102
            $aReturn['info']     = $this->setArrayToJson(curl_getinfo($chanel));
103
            $aReturn['response'] = $rspJsonFromClient;
104
        }
105
        curl_close($chanel);
106
        return '{ ' . $this->packIntoJson($aReturn, 'info') . ', ' . $this->packIntoJson($aReturn, 'response') . ' }';
107
    }
108
109
    /**
110
     * Reads the content of a remote file through CURL extension
111
     *
112
     * @param string $fullURL
113
     * @param array $features
114
     * @return blob
115
     */
116
    protected function getContentFromUrlThroughCurlAsArrayIfJson($fullURL, $features = null)
117
    {
118
        $result = $this->setJsonToArray($this->getContentFromUrlThroughCurl($fullURL, $features));
119 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...
120
            if (is_array($result['info'])) {
121
                ksort($result['info']);
122
            }
123
        }
124 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...
125
            if (is_array($result['response'])) {
126
                ksort($result['response']);
127
            }
128
        }
129
        return $result;
130
    }
131
132
    protected function getFeedbackMySQLAffectedRecords()
133
    {
134
        if (is_null($this->mySQLconnection)) {
135
            $message = 'No MySQL';
136
        } else {
137
            $afRows  = $this->mySQLconnection->affected_rows;
138
            $message = sprintf($this->lclMsgCmnNumber('i18n_Record', 'i18n_Records', $afRows), $afRows);
139
        }
140
        return '<div>' . $message . '</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
        $info = new \SplFileInfo($fileGiven);
155
        return [
156
            'File Extension'         => $info->getExtension(),
157
            'File Group'             => $info->getGroup(),
158
            'File Inode'             => $info->getInode(),
159
            'File Link Target'       => ($info->isLink() ? $info->getLinkTarget() : '-'),
160
            'File is Dir'            => $info->isDir(),
161
            'File is Executable'     => $info->isExecutable(),
162
            'File is File'           => $info->isFile(),
163
            'File is Link'           => $info->isLink(),
164
            'File is Readable'       => $info->isReadable(),
165
            'File is Writable'       => $info->isWritable(),
166
            'File Name'              => $info->getBasename('.' . $info->getExtension()),
167
            'File Name w. Extension' => $info->getFilename(),
168
            'File Owner'             => $info->getOwner(),
169
            'File Path'              => $info->getPath(),
170
            'File Permissions'       => $this->explainPerms($info->getPerms()),
171
            'Name'                   => $info->getRealPath(),
172
            'Size'                   => $info->getSize(),
173
            'Sha1'                   => sha1_file($fileGiven),
174
            'Timestamp Accessed'     => [
175
                'PHP number' => $info->getATime(),
176
                'SQL format' => date('Y-m-d H:i:s', $info->getATime()),
177
            ],
178
            'Timestamp Changed'      => [
179
                'PHP number' => $info->getCTime(),
180
                'SQL format' => date('Y-m-d H:i:s', $info->getCTime()),
181
            ],
182
            'Timestamp Modified'     => [
183
                'PHP number' => $info->getMTime(),
184
                'SQL format' => date('Y-m-d H:i:s', $info->getMTime()),
185
            ],
186
            'Type'                   => $info->getType(),
187
        ];
188
    }
189
190
    /**
191
     * returns a multi-dimensional array with list of file details within a given path
192
     * (by using Symfony/Finder package)
193
     *
194
     * @param  string $pathAnalised
195
     * @return array
196
     */
197
    protected function getListOfFiles($pathAnalised)
198
    {
199
        if (realpath($pathAnalised) === false) {
200
            return ['error' => sprintf($this->lclMsgCmn('i18n_Error_GivenPathIsNotValid'), $pathAnalised)];
201
        } elseif (!is_dir($pathAnalised)) {
202
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenPathIsNotFolder')];
203
        }
204
        $aFiles   = null;
205
        $finder   = new \Symfony\Component\Finder\Finder();
206
        $iterator = $finder
207
                ->files()
208
                ->sortByName()
209
                ->in($pathAnalised);
210
        foreach ($iterator as $file) {
211
            $aFiles[$file->getRealPath()] = $this->getFileDetails($file);
212
        }
213
        return $aFiles;
214
    }
215
216
    /**
217
     * Returns server Timestamp into various formats
218
     *
219
     * @param string $returnType
220
     * @return string
221
     */
222
    protected function getTimestamp($returnType = 'string')
223
    {
224
        $crtTime = gettimeofday();
225
        switch ($returnType) {
226
            case 'array':
227
                $sReturn = [
228
                    'float'  => ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6)),
229
                    'string' => implode('', [
230
                        '<span style="color:black!important;font-weight:bold;">[',
231
                        date('Y-m-d H:i:s.', $crtTime['sec']),
232
                        substr(round($crtTime['usec'], -3), 0, 3),
233
                        ']</span> '
234
                    ]),
235
                ];
236
                break;
237
            case 'float':
238
                $sReturn = ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6));
239
                break;
240
            case 'string':
241
                $sReturn = implode('', [
242
                    '<span style="color:black!important;font-weight:bold;">[',
243
                    date('Y-m-d H:i:s.', $crtTime['sec']),
244
                    substr(round($crtTime['usec'], -3), 0, 3),
245
                    ']</span> '
246
                ]);
247
                break;
248
            default:
249
                $sReturn = sprintf($this->lclMsgCmn('i18n_Error_UnknownReturnType'), $returnType);
250
                break;
251
        }
252
        return $sReturn;
253
    }
254
255
    /**
256
     * Moves files into another folder
257
     *
258
     * @param type $sourcePath
259
     * @param type $targetPath
260
     * @return type
261
     */
262
    protected function moveFilesIntoTargetFolder($sourcePath, $targetPath)
263
    {
264
        $filesystem = new \Symfony\Component\Filesystem\Filesystem();
265
        $filesystem->mirror($sourcePath, $targetPath);
266
        $finder     = new \Symfony\Component\Finder\Finder();
267
        $iterator   = $finder
268
                ->files()
269
                ->ignoreUnreadableDirs(true)
270
                ->followLinks()
271
                ->in($sourcePath);
272
        $sFiles     = [];
273
        foreach ($iterator as $file) {
274
            $relativePathFile = str_replace($sourcePath, '', $file->getRealPath());
275
            if (!file_exists($targetPath . $relativePathFile)) {
276
                $sFiles[$relativePathFile] = $targetPath . $relativePathFile;
277
            }
278
        }
279
        return $this->setArrayToJson($sFiles);
280
    }
281
282
    /**
283
     * Send an array of parameters like a form through a POST action
284
     *
285
     * @param string $urlToSendTo
286
     * @param array $params
287
     * @throws \Exception
288
     * @throws \UnexpectedValueException
289
     */
290
    protected function sendBackgroundEncodedFormElementsByPost($urlToSendTo, $params = [])
291
    {
292
        try {
293
            $postingUrl = filter_var($urlToSendTo, FILTER_VALIDATE_URL);
294
            if ($postingUrl === false) {
295
                throw new \Exception($exc);
296
            } else {
297
                if (is_array($params)) {
298
                    $postingString = $this->setArrayToStringForUrl('&', $params);
299
                    $pUrlParts     = parse_url($postingUrl);
300
                    $postingPort   = (isset($pUrlParts['port']) ? $pUrlParts['port'] : 80);
301
                    $flPointer     = fsockopen($pUrlParts['host'], $postingPort, $errNo, $errorMessage, 30);
302
                    if ($flPointer === false) {
303
                        throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_FailedToConnect') . ': '
304
                        . $errNo . ' (' . $errorMessage . ')');
305
                    } else {
306
                        fwrite($flPointer, $this->sendBackgroundPrepareData($pUrlParts, $postingString));
307
                        fclose($flPointer);
308
                    }
309
                } else {
310
                    throw new \UnexpectedValueException($this->lclMsgCmn('i18n_Error_GivenParameterIsNotAnArray'));
311
                }
312
            }
313
        } catch (\Exception $exc) {
314
            echo '<pre style="color:#f00">' . $exc->getTraceAsString() . '</pre>';
315
        }
316
    }
317
318
    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...
319
    {
320
        $this->initializeSprGlbAndSession();
321
        $out   = [];
322
        $out[] = 'POST ' . $pUrlParts['path'] . ' ' . $this->tCmnSuperGlobals->server->get['SERVER_PROTOCOL'];
323
        $out[] = 'Host: ' . $pUrlParts['host'];
324
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
325
            $out[] = 'User-Agent: ' . $this->tCmnSuperGlobals->server->get('HTTP_USER_AGENT');
326
        }
327
        $out[] = 'Content-Type: application/x-www-form-urlencoded';
328
        $out[] = 'Content-Length: ' . strlen($postingString);
329
        $out[] = 'Connection: Close' . "\r\n";
330
        $out[] = $postingString;
331
        return implode("\r\n", $out);
332
    }
333
334
    /**
335
     * Converts an array into JSON string
336
     *
337
     * @param array $inArray
338
     * @return string
339
     */
340
    protected function setArrayToJson(array $inArray)
341
    {
342
        if (!is_array($inArray)) {
343
            return $this->lclMsgCmn('i18n_Error_GivenInputIsNotArray');
344
        }
345
        $rtrn      = utf8_encode(json_encode($inArray, JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
346
        $jsonError = $this->setJsonErrorInPlainEnglish();
347
        if (is_null($jsonError)) {
348
            return $rtrn;
349
        } else {
350
            return $jsonError;
351
        }
352
    }
353
354
    /**
355
     * Returns proper result from a mathematical division in order to avoid Zero division erorr or Infinite results
356
     *
357
     * @param float $fAbove
358
     * @param float $fBelow
359
     * @param mixed $mArguments
360
     * @return decimal
361
     */
362
    protected function setDividedResult($fAbove, $fBelow, $mArguments = 0)
363
    {
364
        // prevent infinite result AND division by 0
365
        if (($fAbove == 0) || ($fBelow == 0)) {
366
            return 0;
367
        }
368
        if (is_array($mArguments)) {
369
            return $this->setNumberFormat(($fAbove / $fBelow), [
370
                        'MinFractionDigits' => $mArguments[1],
371
                        'MaxFractionDigits' => $mArguments[1],
372
            ]);
373
        }
374
        return $this->setNumberFormat(round(($fAbove / $fBelow), $mArguments));
375
    }
376
377
    /**
378
     * Converts a JSON string into an Array
379
     *
380
     * @param string $inputJson
381
     * @return array
382
     */
383
    protected function setJsonToArray($inputJson)
384
    {
385
        if (!$this->isJsonByDanielGP($inputJson)) {
386
            return ['error' => $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson')];
387
        }
388
        $sReturn   = (json_decode($inputJson, true));
389
        $jsonError = $this->setJsonErrorInPlainEnglish();
390
        if (is_null($jsonError)) {
391
            return $sReturn;
392
        } else {
393
            return ['error' => $jsonError];
394
        }
395
    }
396
}
397