| Total Complexity | 50 |
| Total Lines | 282 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like IOHelperTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use IOHelperTrait, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 31 | trait IOHelperTrait |
||
| 32 | { |
||
| 33 | use TaggableCacheItemPoolTrait; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * @var array<string, string> |
||
| 37 | */ |
||
| 38 | public array $tmp = []; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * Provide a generic getStats() method |
||
| 42 | * for files-based drivers |
||
| 43 | * @return DriverStatistic |
||
| 44 | * @throws PhpfastcacheIOException |
||
| 45 | * @throws PhpfastcacheInvalidArgumentException |
||
| 46 | */ |
||
| 47 | public function getStats(): DriverStatistic |
||
| 48 | { |
||
| 49 | $stat = new DriverStatistic(); |
||
| 50 | $path = $this->getFilePath(false); |
||
| 51 | |||
| 52 | if (!is_dir($path)) { |
||
| 53 | throw new PhpfastcacheIOException("Can't read PATH:" . $path); |
||
| 54 | } |
||
| 55 | $stat->setSize(Directory::dirSize($path)) |
||
| 56 | ->setInfo('Number of files used to build the cache: ' . Directory::getFileCount($path)) |
||
| 57 | ->setRawData( |
||
| 58 | [ |
||
| 59 | 'tmp' => $this->tmp, |
||
| 60 | ] |
||
| 61 | ); |
||
| 62 | |||
| 63 | if ($this->getConfig()->isUseStaticItemCaching()) { |
||
| 64 | $stat->setData(implode(', ', \array_keys($this->itemInstances))); |
||
|
|
|||
| 65 | } else { |
||
| 66 | $stat->setData('No data available since static item caching option (useStaticItemCaching) is disabled.'); |
||
| 67 | } |
||
| 68 | |||
| 69 | return $stat; |
||
| 70 | } |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @param string|bool $keyword |
||
| 74 | * @param bool $skip |
||
| 75 | * @return string |
||
| 76 | * @throws PhpfastcacheIOException |
||
| 77 | * @throws PhpfastcacheInvalidArgumentException |
||
| 78 | */ |
||
| 79 | protected function getFilePath(string|bool $keyword, bool $skip = false): string |
||
| 80 | { |
||
| 81 | $path = $this->getPath(); |
||
| 82 | |||
| 83 | if ($keyword === false) { |
||
| 84 | return $path; |
||
| 85 | } |
||
| 86 | |||
| 87 | $filename = $this->encodeFilename($keyword); |
||
| 88 | $folder = \substr($filename, 0, 2) . DIRECTORY_SEPARATOR . \substr($filename, 2, 2); |
||
| 89 | $path = \rtrim($path, '/\\') . DIRECTORY_SEPARATOR . $folder; |
||
| 90 | |||
| 91 | /** |
||
| 92 | * Skip Create Sub Folders; |
||
| 93 | */ |
||
| 94 | if (!$skip && !\is_dir($path) && @!\mkdir($path, $this->getDefaultChmod(), true) && !\is_dir($path)) { |
||
| 95 | throw new PhpfastcacheIOException( |
||
| 96 | 'Path "' . $path . '" is not writable, please set a chmod 0777 or any writable permission and make sure to make use of an absolute path !' |
||
| 97 | ); |
||
| 98 | } |
||
| 99 | |||
| 100 | return $path . \DIRECTORY_SEPARATOR . $filename . '.' . $this->getConfig()->getCacheFileExtension(); |
||
| 101 | } |
||
| 102 | |||
| 103 | /** |
||
| 104 | * @param bool $readonly |
||
| 105 | * @return string |
||
| 106 | * @throws PhpfastcacheIOException |
||
| 107 | * @throws PhpfastcacheInvalidArgumentException |
||
| 108 | */ |
||
| 109 | public function getPath(bool $readonly = false): string |
||
| 110 | { |
||
| 111 | $tmpDir = \rtrim(\ini_get('upload_tmp_dir') ?: \sys_get_temp_dir(), '\\/') . DIRECTORY_SEPARATOR . 'phpfastcache'; |
||
| 112 | $httpHost = $this->getConfig()->getSuperGlobalAccessor()('SERVER', 'HTTP_HOST'); |
||
| 113 | $securityKey = $this->buildSecurityKey($httpHost); |
||
| 114 | |||
| 115 | /** |
||
| 116 | * Extends the temporary directory |
||
| 117 | * with the security key and the driver name |
||
| 118 | */ |
||
| 119 | $tmpDir = \rtrim($tmpDir, '/') . DIRECTORY_SEPARATOR; |
||
| 120 | |||
| 121 | if (empty($this->getConfig()->getPath())) { |
||
| 122 | $path = $tmpDir; |
||
| 123 | } else { |
||
| 124 | $path = \rtrim($this->getConfig()->getPath(), '/') . DIRECTORY_SEPARATOR; |
||
| 125 | } |
||
| 126 | |||
| 127 | $pathSuffix = $securityKey . DIRECTORY_SEPARATOR . $this->getDriverName(); |
||
| 128 | $fullPath = Directory::getAbsolutePath($path . $pathSuffix); |
||
| 129 | $fullPathTmp = Directory::getAbsolutePath($tmpDir . $pathSuffix); |
||
| 130 | |||
| 131 | $this->mkdir($fullPath, $fullPathTmp); |
||
| 132 | |||
| 133 | /** |
||
| 134 | * In readonly mode we only attempt |
||
| 135 | * to verify if the directory exists |
||
| 136 | * or not, if it does not then we |
||
| 137 | * return the temp dir |
||
| 138 | */ |
||
| 139 | if ($readonly) { |
||
| 140 | if ($this->getConfig()->isAutoTmpFallback() && (!@\file_exists($fullPath) || !@\is_writable($fullPath))) { |
||
| 141 | return $fullPathTmp; |
||
| 142 | } |
||
| 143 | return $fullPath; |
||
| 144 | } |
||
| 145 | |||
| 146 | return realpath($fullPath); |
||
| 147 | } |
||
| 148 | |||
| 149 | protected function buildSecurityKey(?string $httpHost): string |
||
| 165 | } |
||
| 166 | |||
| 167 | /** |
||
| 168 | * @throws PhpfastcacheIOException |
||
| 169 | */ |
||
| 170 | protected function mkdir(string $fullPath, string $fullPathTmp): void |
||
| 171 | { |
||
| 172 | $fullPathHash = $this->getConfig()->getDefaultFileNameHashFunction()($fullPath); |
||
| 173 | |||
| 174 | if (!isset($this->tmp[$fullPathHash]) || (!@\file_exists($fullPath) || !@\is_writable($fullPath))) { |
||
| 175 | if (!@\file_exists($fullPath)) { |
||
| 176 | if (@mkdir($fullPath, $this->getDefaultChmod(), true) === false && !\is_dir($fullPath)) { |
||
| 177 | throw new PhpfastcacheIOException('The directory ' . $fullPath . ' could not be created.'); |
||
| 178 | } |
||
| 179 | } elseif (!@\is_writable($fullPath) && !@\chmod($fullPath, $this->getDefaultChmod()) && $this->getConfig()->isAutoTmpFallback()) { |
||
| 180 | /** |
||
| 181 | * Switch back to tmp dir |
||
| 182 | * again if the path is not writable |
||
| 183 | */ |
||
| 184 | $fullPath = $fullPathTmp; |
||
| 185 | if (!@\file_exists($fullPath) && @\mkdir($fullPath, $this->getDefaultChmod(), true) && !\is_dir($fullPath)) { |
||
| 186 | throw new PhpfastcacheIOException('The directory ' . $fullPath . ' could not be created.'); |
||
| 187 | } |
||
| 188 | } |
||
| 189 | |||
| 190 | /** |
||
| 191 | * In case there is no directory |
||
| 192 | * writable including the temporary |
||
| 193 | * one, we must throw an exception |
||
| 194 | */ |
||
| 195 | if (!@\file_exists($fullPath) || !@\is_writable($fullPath)) { |
||
| 196 | throw new PhpfastcacheIOException( |
||
| 197 | 'Path "' . $fullPath . '" is not writable, please set a chmod 0777 or any writable permission and make sure to make use of an absolute path !' |
||
| 198 | ); |
||
| 199 | } |
||
| 200 | |||
| 201 | $this->tmp[$fullPathHash] = $fullPath; |
||
| 202 | } |
||
| 203 | } |
||
| 204 | |||
| 205 | /** |
||
| 206 | * @param string $filename |
||
| 207 | * @return string |
||
| 208 | */ |
||
| 209 | protected static function cleanFileName(string $filename): string |
||
| 210 | { |
||
| 211 | $regex = [ |
||
| 212 | '/[\?\[\]\/\\\=\<\>\:\;\,\'\"\&\$\#\*\(\)\|\~\`\!\{\}]/', |
||
| 213 | '/\.$/', |
||
| 214 | '/^\./', |
||
| 215 | ]; |
||
| 216 | $replace = ['-', '', '']; |
||
| 217 | |||
| 218 | return \trim(\preg_replace($regex, $replace, \trim($filename)), '-'); |
||
| 219 | } |
||
| 220 | |||
| 221 | /** |
||
| 222 | * @return int |
||
| 223 | */ |
||
| 224 | protected function getDefaultChmod(): int |
||
| 225 | { |
||
| 226 | if (!$this->getConfig()->getDefaultChmod()) { |
||
| 227 | return 0777; |
||
| 228 | } |
||
| 229 | |||
| 230 | return $this->getConfig()->getDefaultChmod(); |
||
| 231 | } |
||
| 232 | |||
| 233 | /** |
||
| 234 | * @param string $keyword |
||
| 235 | * @return string |
||
| 236 | */ |
||
| 237 | protected function encodeFilename(string $keyword): string |
||
| 238 | { |
||
| 239 | return $this->getConfig()->getDefaultFileNameHashFunction()($keyword); |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * @param string $file |
||
| 244 | * @return string |
||
| 245 | * @throws PhpfastcacheIOException |
||
| 246 | */ |
||
| 247 | protected function readFile(string $file): string |
||
| 248 | { |
||
| 249 | if (!\is_readable($file)) { |
||
| 250 | throw new PhpfastcacheIOException("Cannot read file located at: $file"); |
||
| 251 | } |
||
| 252 | if (\function_exists('file_get_contents')) { |
||
| 253 | return (string)\file_get_contents($file); |
||
| 254 | } |
||
| 255 | |||
| 256 | $string = ''; |
||
| 257 | |||
| 258 | $fileHandle = @\fopen($file, 'rb'); |
||
| 259 | while (!\feof($fileHandle)) { |
||
| 260 | $line = \fgets($fileHandle); |
||
| 261 | $string .= $line; |
||
| 262 | } |
||
| 263 | \fclose($fileHandle); |
||
| 264 | |||
| 265 | return $string; |
||
| 266 | } |
||
| 267 | |||
| 268 | /******************** |
||
| 269 | * |
||
| 270 | * PSR-6 Extended Methods |
||
| 271 | * |
||
| 272 | *******************/ |
||
| 273 | |||
| 274 | /** |
||
| 275 | * @param string $file |
||
| 276 | * @param string $data |
||
| 277 | * @param bool $secureFileManipulation |
||
| 278 | * @return bool |
||
| 279 | * @throws PhpfastcacheIOException |
||
| 280 | * @throws \Exception |
||
| 281 | */ |
||
| 282 | protected function writeFile(string $file, string $data, bool $secureFileManipulation = false): bool |
||
| 313 | } |
||
| 314 | } |
||
| 315 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.