Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
57.14% |
8 / 14 |
CRAP | |
83.33% |
275 / 330 |
| CommonCode | |
0.00% |
0 / 1 |
|
57.14% |
8 / 14 |
99.35 | |
83.33% |
275 / 330 |
| explainPermissions | |
0.00% |
0 / 1 |
8.88 | |
76.06% |
54 / 71 |
|||
| getContentFromUrlThroughCurl | |
0.00% |
0 / 1 |
9.15 | |
73.81% |
31 / 42 |
|||
| getContentFromUrlThroughCurlAsArrayIfJson | |
100.00% |
1 / 1 |
5 | |
100.00% |
12 / 12 |
|||
| getFileDetails | |
100.00% |
1 / 1 |
3 | |
100.00% |
36 / 36 |
|||
| getListOfFiles | |
100.00% |
1 / 1 |
4 | |
100.00% |
15 / 15 |
|||
| getPackageDetailsFromGivenComposerLockFile | |
0.00% |
0 / 1 |
20.20 | |
92.00% |
46 / 50 |
|||
| getTimestamp | |
100.00% |
1 / 1 |
4 | |
100.00% |
25 / 25 |
|||
| isJsonByDanielGP | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| moveFilesIntoTargetFolder | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 15 |
|||
| removeFilesOlderThanGivenRule | |
0.00% |
0 / 1 |
8.90 | |
75.86% |
22 / 29 |
|||
| setArrayToJson | |
100.00% |
1 / 1 |
3 | |
100.00% |
7 / 7 |
|||
| setArrayValuesAsKey | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| setJsonToArray | |
0.00% |
0 / 1 |
3.02 | |
87.50% |
7 / 8 |
|||
| setJsonErrorInPlainEnglish | |
100.00% |
1 / 1 |
2 | |
100.00% |
13 / 13 |
|||
| <?php | |
| /** | |
| * | |
| * The MIT License (MIT) | |
| * | |
| * Copyright (c) 2015 Daniel Popiniuc | |
| * | |
| * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| * of this software and associated documentation files (the "Software"), to deal | |
| * in the Software without restriction, including without limitation the rights | |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| * copies of the Software, and to permit persons to whom the Software is | |
| * furnished to do so, subject to the following conditions: | |
| * | |
| * The above copyright notice and this permission notice shall be included in all | |
| * copies or substantial portions of the Software. | |
| * | |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| * SOFTWARE. | |
| * | |
| */ | |
| namespace danielgp\common_lib; | |
| /** | |
| * usefull functions to get quick results | |
| * | |
| * @author Daniel Popiniuc | |
| */ | |
| trait CommonCode | |
| { | |
| use CommonLibLocale, | |
| \danielgp\browser_agent_info\BrowserAgentInfosByDanielGP, | |
| DomComponentsByDanielGP, | |
| DomComponentsByDanielGPwithCDN, | |
| MySQLiByDanielGPqueries, | |
| MySQLiByDanielGP; | |
| /** | |
| * Returns an array with meaningfull content of permissions | |
| * | |
| * @param int $permissionNumber | |
| * @return array | |
| */ | |
| protected function explainPermissions($permissionNumber) | |
| { | |
| if (($permissionNumber & 0xC000) == 0xC000) { | |
| $firstFlag = [ | |
| 'code' => 's', | |
| 'name' => 'Socket', | |
| ]; | |
| } elseif (($permissionNumber & 0xA000) == 0xA000) { | |
| $firstFlag = [ | |
| 'code' => 'l', | |
| 'name' => 'Symbolic Link', | |
| ]; | |
| } elseif (($permissionNumber & 0x8000) == 0x8000) { | |
| $firstFlag = [ | |
| 'code' => '-', | |
| 'name' => 'Regular', | |
| ]; | |
| } elseif (($permissionNumber & 0x6000) == 0x6000) { | |
| $firstFlag = [ | |
| 'code' => 'b', | |
| 'name' => 'Block special', | |
| ]; | |
| } elseif (($permissionNumber & 0x4000) == 0x4000) { | |
| $firstFlag = [ | |
| 'code' => 'd', | |
| 'name' => 'Directory', | |
| ]; | |
| } elseif (($permissionNumber & 0x2000) == 0x2000) { | |
| $firstFlag = [ | |
| 'code' => 'c', | |
| 'name' => 'Character special', | |
| ]; | |
| } elseif (($permissionNumber & 0x1000) == 0x1000) { | |
| $firstFlag = [ | |
| 'code' => 'p', | |
| 'name' => 'FIFO pipe', | |
| ]; | |
| } else { | |
| $firstFlag = [ | |
| 'code' => 'u', | |
| 'name' => 'FIFO pipe', | |
| ]; | |
| } | |
| $permissionsString = substr(sprintf('%o', $permissionNumber), -4); | |
| $numericalPermissions = [ | |
| 0 => [ | |
| 'code' => '---', | |
| 'name' => 'none', | |
| ], | |
| 1 => [ | |
| 'code' => '--x', | |
| 'name' => 'execute only', | |
| ], | |
| 2 => [ | |
| 'code' => '-w-', | |
| 'name' => 'write only', | |
| ], | |
| 3 => [ | |
| 'code' => '-wx', | |
| 'name' => 'write and execute', | |
| ], | |
| 4 => [ | |
| 'code' => 'r--', | |
| 'name' => 'read only', | |
| ], | |
| 5 => [ | |
| 'code' => 'r-x', | |
| 'name' => 'read and execute', | |
| ], | |
| 6 => [ | |
| 'code' => 'rw-', | |
| 'name' => 'read and write', | |
| ], | |
| 7 => [ | |
| 'code' => 'rwx', | |
| 'name' => 'read, write and execute', | |
| ], | |
| ]; | |
| return [ | |
| 'Code' => $permissionsString, | |
| 'Overall' => implode('', [ | |
| $firstFlag['code'], | |
| $numericalPermissions[substr($permissionsString, 1, 1)]['code'], | |
| $numericalPermissions[substr($permissionsString, 2, 1)]['code'], | |
| $numericalPermissions[substr($permissionsString, 3, 1)]['code'], | |
| ]), | |
| 'First' => $firstFlag, | |
| 'Owner' => $numericalPermissions[substr($permissionsString, 1, 1)], | |
| 'Group' => $numericalPermissions[substr($permissionsString, 2, 1)], | |
| 'World/Other' => $numericalPermissions[substr($permissionsString, 3, 1)], | |
| ]; | |
| } | |
| /** | |
| * Reads the content of a remote file through CURL extension | |
| * | |
| * @param string $fullURL | |
| * @param array $features | |
| * @return blob | |
| */ | |
| protected function getContentFromUrlThroughCurl($fullURL, $features = null) | |
| { | |
| if (!function_exists('curl_init')) { | |
| $aReturn['info'] = $this->lclMsgCmn('i18n_Error_ExtensionNotLoaded'); | |
| $aReturn['response'] = ''; | |
| } | |
| if (!filter_var($fullURL, FILTER_VALIDATE_URL)) { | |
| $aReturn['info'] = $this->lclMsgCmn('i18n_Error_GivenUrlIsNotValid'); | |
| $aReturn['response'] = ''; | |
| } | |
| $aReturn = []; | |
| $ch = curl_init(); | |
| curl_setopt($ch, CURLOPT_USERAGENT, $this->getUserAgentByCommonLib()); | |
| if ((strpos($fullURL, 'https') !== false) || (isset($features['forceSSLverification']))) { | |
| curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); | |
| curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | |
| } | |
| curl_setopt($ch, CURLOPT_URL, $fullURL); | |
| curl_setopt($ch, CURLOPT_HEADER, false); | |
| curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
| curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); //avoid a cached response | |
| curl_setopt($ch, CURLOPT_FAILONERROR, true); | |
| $responseJsonFromClientOriginal = curl_exec($ch); | |
| if (curl_errno($ch)) { | |
| $aReturn['info'] = $this->setArrayToJson([ | |
| '#' => curl_errno($ch), | |
| 'description' => curl_error($ch) | |
| ]); | |
| $aReturn['response'] = ''; | |
| } else { | |
| $aReturn['info'] = $this->setArrayToJson(curl_getinfo($ch)); | |
| $aReturn['response'] = $responseJsonFromClientOriginal; | |
| } | |
| curl_close($ch); | |
| $sReturn = ''; | |
| if ($this->isJsonByDanielGP($aReturn['info'])) { | |
| $sReturn = '"info": ' . $aReturn['info']; | |
| } else { | |
| $sReturn = '"info": {' . $aReturn['info'] . ' }'; | |
| } | |
| $sReturn .= ', '; | |
| if ($this->isJsonByDanielGP($aReturn['response'])) { | |
| $sReturn .= '"response": ' . $aReturn['response']; | |
| } else { | |
| $sReturn .= '"response": { ' . $aReturn['response'] . ' }'; | |
| } | |
| return '{ ' . $sReturn . ' }'; | |
| } | |
| /** | |
| * Reads the content of a remote file through CURL extension | |
| * | |
| * @param string $fullURL | |
| * @param array $features | |
| * @return blob | |
| */ | |
| protected function getContentFromUrlThroughCurlAsArrayIfJson($fullURL, $features = null) | |
| { | |
| $result = $this->setJsonToArray($this->getContentFromUrlThroughCurl($fullURL, $features)); | |
| if (isset($result['info'])) { | |
| if (is_array($result['info'])) { | |
| ksort($result['info']); | |
| } | |
| } | |
| if (isset($result['response'])) { | |
| if (is_array($result['response'])) { | |
| ksort($result['response']); | |
| } | |
| } | |
| return $result; | |
| } | |
| /** | |
| * returns the details about Communicator (current) file | |
| * | |
| * @param string $fileGiven | |
| * @return array | |
| */ | |
| protected function getFileDetails($fileGiven) | |
| { | |
| if (!file_exists($fileGiven)) { | |
| return [ | |
| 'error' => sprintf($this->lclMsgCmn('i18n_Error_GivenFileDoesNotExist'), $fileGiven) | |
| ]; | |
| } | |
| $info = new \SplFileInfo($fileGiven); | |
| $sReturn = [ | |
| 'File Extension' => $info->getExtension(), | |
| 'File Group' => $info->getGroup(), | |
| 'File Inode' => $info->getInode(), | |
| 'File Link Target' => ($info->isLink() ? $info->getLinkTarget() : '-'), | |
| 'File is Dir' => $info->isDir(), | |
| 'File is Executable' => $info->isExecutable(), | |
| 'File is File' => $info->isFile(), | |
| 'File is Link' => $info->isLink(), | |
| 'File is Readable' => $info->isReadable(), | |
| 'File is Writable' => $info->isWritable(), | |
| 'File Name' => $info->getBasename('.' . $info->getExtension()), | |
| 'File Name w. Extension' => $info->getFilename(), | |
| 'File Owner' => $info->getOwner(), | |
| 'File Path' => $info->getPath(), | |
| 'File Permissions' => array_merge([ | |
| 'Permissions' => $info->getPerms(), | |
| ], $this->explainPermissions($info->getPerms())), | |
| 'Name' => $info->getRealPath(), | |
| 'Size' => $info->getSize(), | |
| 'Sha1' => sha1_file($fileGiven), | |
| 'Timestamp Accessed' => [ | |
| 'PHP number' => $info->getATime(), | |
| 'SQL format' => date('Y-m-d H:i:s', $info->getATime()), | |
| ], | |
| 'Timestamp Changed' => [ | |
| 'PHP number' => $info->getCTime(), | |
| 'SQL format' => date('Y-m-d H:i:s', $info->getCTime()), | |
| ], | |
| 'Timestamp Modified' => [ | |
| 'PHP number' => $info->getMTime(), | |
| 'SQL format' => date('Y-m-d H:i:s', $info->getMTime()), | |
| ], | |
| 'Type' => $info->getType(), | |
| ]; | |
| return $sReturn; | |
| } | |
| /** | |
| * returns a multi-dimensional array with list of file details within a given path | |
| * (by using Symfony/Finder package) | |
| * | |
| * @param string $pathAnalised | |
| * @return array | |
| */ | |
| protected function getListOfFiles($pathAnalised) | |
| { | |
| if (realpath($pathAnalised) === false) { | |
| $aFiles = [ | |
| 'error' => sprintf($this->lclMsgCmn('i18n_Error_GivenPathIsNotValid'), $pathAnalised) | |
| ]; | |
| } elseif (!is_dir($pathAnalised)) { | |
| $aFiles = [ | |
| 'error' => $this->lclMsgCmn('i18n_Error_GivenPathIsNotFolder') | |
| ]; | |
| } else { | |
| $finder = new \Symfony\Component\Finder\Finder(); | |
| $iterator = $finder | |
| ->files() | |
| ->sortByName() | |
| ->in($pathAnalised); | |
| foreach ($iterator as $file) { | |
| $aFiles[$file->getRealPath()] = $this->getFileDetails($file); | |
| } | |
| } | |
| return $aFiles; | |
| } | |
| /** | |
| * Returns a complete list of packages and respective details from a composer.lock file | |
| * | |
| * @param string $fileToRead | |
| * @return array | |
| */ | |
| protected function getPackageDetailsFromGivenComposerLockFile($fileToRead) | |
| { | |
| if (!file_exists($fileToRead)) { | |
| return [ | |
| 'error' => $fileToRead . ' was not found' | |
| ]; | |
| } | |
| $dateTimeToday = new \DateTime(date('Y-m-d', strtotime('today'))); | |
| $defaultNA = '---'; | |
| $finalInformation = []; | |
| $handle = fopen($fileToRead, 'r'); | |
| $fileContents = fread($handle, filesize($fileToRead)); | |
| fclose($handle); | |
| $packages = $this->setJsonToArray($fileContents); | |
| foreach ($packages['packages'] as $value) { | |
| if (isset($value['time'])) { | |
| $dateTime = new \DateTime(date('Y-m-d', strtotime($value['time']))); | |
| $interval = $dateTimeToday->diff($dateTime); | |
| } | |
| if (isset($value['version'])) { | |
| if (substr($value['version'], 0, 1) == 'v') { | |
| $v = substr($value['version'], 1, strlen($value['version']) - 1); | |
| } else { | |
| $v = $value['version']; | |
| } | |
| if (strpos($v, '-') !== false) { | |
| $v = substr($v, 0, strpos($v, '-')); | |
| } | |
| } | |
| if (isset($value['license'])) { | |
| if (is_array($value['license'])) { | |
| $l = implode(', ', $value['license']); | |
| } else { | |
| $l = $value['license']; | |
| } | |
| } else { | |
| $l = $defaultNA; | |
| } | |
| $finalInformation[$value['name']] = [ | |
| 'Aging' => (isset($value['time']) ? $interval->format('%a days ago') : $defaultNA), | |
| 'Description' => (isset($value['description']) ? $value['description'] : $defaultNA), | |
| 'Homepage' => (isset($value['homepage']) ? $value['homepage'] : $defaultNA), | |
| 'License' => $l, | |
| 'Notification URL' => (isset($value['version']) ? $value['notification-url'] : $defaultNA), | |
| 'Package Name' => $value['name'], | |
| 'PHP required' => (isset($value['require']['php']) ? $value['require']['php'] : $defaultNA), | |
| 'Product' => explode('/', $value['name'])[1], | |
| 'Type' => (isset($value['type']) ? $value['type'] : $defaultNA), | |
| 'Time' => (isset($value['time']) ? date('l, d F Y H:i:s', strtotime($value['time'])) : ''), | |
| 'Time as PHP no.' => (isset($value['time']) ? strtotime($value['time']) : ''), | |
| 'URL' => (isset($value['url']) ? $value['url'] : $defaultNA), | |
| 'Vendor' => explode('/', $value['name'])[0], | |
| 'Version' => (isset($value['version']) ? $value['version'] : $defaultNA), | |
| 'Version no.' => (isset($value['version']) ? $v : $defaultNA), | |
| ]; | |
| } | |
| asort($finalInformation); | |
| ksort($finalInformation); | |
| return $finalInformation; | |
| } | |
| /** | |
| * Returns server Timestamp into various formats | |
| * | |
| * @param string $returnType | |
| * @return string | |
| */ | |
| protected function getTimestamp($returnType = 'string') | |
| { | |
| $dt = gettimeofday(); | |
| switch ($returnType) { | |
| case 'array': | |
| $sReturn = [ | |
| 'float' => ($dt['sec'] + $dt['usec'] / pow(10, 6)), | |
| 'string' => implode('', [ | |
| '<span style="color:black!important;font-weight:bold;">[', | |
| date('Y-m-d H:i:s.', $dt['sec']), | |
| substr(round($dt['usec'], -3), 0, 3), | |
| ']</span> ' | |
| ]), | |
| ]; | |
| break; | |
| case 'float': | |
| $sReturn = ($dt['sec'] + $dt['usec'] / pow(10, 6)); | |
| break; | |
| case 'string': | |
| $sReturn = implode('', [ | |
| '<span style="color:black!important;font-weight:bold;">[', | |
| date('Y-m-d H:i:s.', $dt['sec']), | |
| substr(round($dt['usec'], -3), 0, 3), | |
| ']</span> ' | |
| ]); | |
| break; | |
| default: | |
| $sReturn = sprintf($this->lclMsgCmn('i18n_Error_UnknownReturnType'), $returnType); | |
| break; | |
| } | |
| return $sReturn; | |
| } | |
| /** | |
| * Tests if given string has a valid Json format | |
| * | |
| * @param string $inputJson | |
| * @return boolean|string | |
| */ | |
| protected function isJsonByDanielGP($inputJson) | |
| { | |
| if (is_string($inputJson)) { | |
| json_decode($inputJson); | |
| return (json_last_error() == JSON_ERROR_NONE); | |
| } else { | |
| return $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson'); | |
| } | |
| } | |
| /** | |
| * Moves files into another folder | |
| * | |
| * @param type $sourcePath | |
| * @param type $targetPath | |
| * @param type $overwrite | |
| * @return type | |
| */ | |
| protected function moveFilesIntoTargetFolder($sourcePath, $targetPath) | |
| { | |
| $filesystem = new \Symfony\Component\Filesystem\Filesystem(); | |
| $filesystem->mirror($sourcePath, $targetPath); | |
| $finder = new \Symfony\Component\Finder\Finder(); | |
| $iterator = $finder | |
| ->files() | |
| ->ignoreUnreadableDirs(true) | |
| ->followLinks() | |
| ->in($sourcePath); | |
| $sFiles = []; | |
| foreach ($iterator as $file) { | |
| $relativePathFile = str_replace($sourcePath, '', $file->getRealPath()); | |
| if (!file_exists($targetPath . $relativePathFile)) { | |
| $sFiles[$relativePathFile] = $targetPath . $relativePathFile; | |
| } | |
| } | |
| return $this->setArrayToJson($sFiles); | |
| } | |
| /** | |
| * Remove files older than given rule | |
| * (both Access time and Modified time will be checked | |
| * and only if both matches removal will take place) | |
| * | |
| * @param array $inputArray | |
| * @return string | |
| */ | |
| protected function removeFilesOlderThanGivenRule($inputArray) | |
| { | |
| if (is_array($inputArray)) { | |
| if (!isset($inputArray['path'])) { | |
| $proceedWithDeletion = false; | |
| $error = '`path` has not been provided'; | |
| } elseif (!isset($inputArray['dateRule'])) { | |
| $proceedWithDeletion = false; | |
| $error = '`dateRule` has not been provided'; | |
| } else { | |
| $proceedWithDeletion = true; | |
| } | |
| } else { | |
| $proceedWithDeletion = false; | |
| } | |
| if ($proceedWithDeletion) { | |
| $finder = new \Symfony\Component\Finder\Finder(); | |
| $iterator = $finder | |
| ->files() | |
| ->ignoreUnreadableDirs(true) | |
| ->followLinks() | |
| ->in($inputArray['path']); | |
| $aFiles = null; | |
| foreach ($iterator as $file) { | |
| if ($file->getATime() < strtotime($inputArray['dateRule'])) { | |
| $aFiles[] = $file->getRealPath(); | |
| } | |
| } | |
| if (is_null($aFiles)) { | |
| return null; | |
| } else { | |
| $filesystem = new \Symfony\Component\Filesystem\Filesystem(); | |
| $filesystem->remove($aFiles); | |
| return $this->setArrayToJson($aFiles); | |
| } | |
| } else { | |
| return $error; | |
| } | |
| } | |
| /** | |
| * Converts an array into JSON string | |
| * | |
| * @param array $inArray | |
| * @return string | |
| */ | |
| protected function setArrayToJson($inArray) | |
| { | |
| if (!is_array($inArray)) { | |
| return $this->lclMsgCmn('i18n_Error_GivenInputIsNotArray'); | |
| } | |
| $rtrn = utf8_encode(json_encode($inArray, JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); | |
| $jsonError = $this->setJsonErrorInPlainEnglish(); | |
| if (is_null($jsonError)) { | |
| return $rtrn; | |
| } else { | |
| return $jsonError; | |
| } | |
| } | |
| /** | |
| * Converts a single-child array into an parent-child one | |
| * | |
| * @param type $inArray | |
| * @return type | |
| */ | |
| protected function setArrayValuesAsKey($inArray) | |
| { | |
| $outArray = array_combine($inArray, $inArray); | |
| ksort($outArray); | |
| return $outArray; | |
| } | |
| /** | |
| * Converts a JSON string into an Array | |
| * | |
| * @param string $inputJson | |
| * @return array | |
| */ | |
| protected function setJsonToArray($inputJson) | |
| { | |
| if (!$this->isJsonByDanielGP($inputJson)) { | |
| return [ | |
| 'error' => $this->lclMsgCmn('i18n_Error_GivenInputIsNotJson') | |
| ]; | |
| } | |
| $sReturn = (json_decode($inputJson, true)); | |
| $jsonError = $this->setJsonErrorInPlainEnglish(); | |
| if (is_null($jsonError)) { | |
| return $sReturn; | |
| } else { | |
| return [ | |
| 'error' => $jsonError | |
| ]; | |
| } | |
| } | |
| /** | |
| * Provides a list of all known JSON errors and their description | |
| * | |
| * @return type | |
| */ | |
| private function setJsonErrorInPlainEnglish() | |
| { | |
| $knownErrors = [ | |
| JSON_ERROR_NONE => null, | |
| JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', | |
| JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch', | |
| JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', | |
| JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', | |
| JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded', | |
| ]; | |
| $currentError = json_last_error(); | |
| $sReturn = null; | |
| if (in_array($currentError, $knownErrors)) { | |
| $sReturn = $knownErrors[$currentError]; | |
| } | |
| return $sReturn; | |
| } | |
| } |