diff --git a/src/JsonFileHandler.php b/src/JsonFileHandler.php index 9c2beeb..348da72 100644 --- a/src/JsonFileHandler.php +++ b/src/JsonFileHandler.php @@ -6,7 +6,7 @@ use rcsofttech85\FileHandler\Exception\FileHandlerException; use rcsofttech85\FileHandler\Utilities\RowColumnHelper; -readonly class JsonFileHandler +class JsonFileHandler { use RowColumnHelper; @@ -15,7 +15,7 @@ * @param array $headers * @param array|false $hideColumns * @param int|false $limit - * @return array + * @return array> * @throws FileHandlerException */ public function toArray( @@ -29,81 +29,128 @@ public function toArray( /** * @param string $filename - * @param array $headers - * @param array|false $hideColumns - * @param int|false $limit - * @return Generator + * @return array> * @throws FileHandlerException */ - private function getRows( - string $filename, - array &$headers, - array|false $hideColumns = false, - int|false $limit = false - ): Generator { + + private function validateFile(string $filename): array + { + $this->checkFileExistence($filename); + $jsonContents = $this->getFileContents($filename); + $contents = $this->parseJson($jsonContents); + if (!$contents) { + throw new FileHandlerException('could not parse json'); + } + $this->validateJsonData($contents); + return $contents; + } + + /** + * @param string $filename + * @return void + * @throws FileHandlerException + */ + private function checkFileExistence(string $filename): void + { if (!file_exists($filename)) { - throw new FileHandlerException('file not found'); + throw new FileHandlerException('File not found'); } - $jsonContents = file_get_contents($filename); + } + /** + * @param string $filename + * @return string + * @throws FileHandlerException + */ + private function getFileContents(string $filename): string + { + $jsonContents = file_get_contents($filename); if (!$jsonContents) { throw new FileHandlerException("{$filename} is not valid"); } + return $jsonContents; + } + /** + * @param string $jsonData + * @return array>|false + */ + private function parseJson(string $jsonData): array|false + { + $data = json_decode($jsonData, true); + if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) { + return false; + } + return $data; + } - if (!$contents = $this->isValidJson($jsonContents)) { + /** + * @param array>|false $data + * @return void + * @throws FileHandlerException + */ + private function validateJsonData(array|false $data): void + { + if (empty($data) || !is_array($data[0])) { throw new FileHandlerException(json_last_error_msg()); } + $firstArrayKeys = array_keys($data[0]); + + foreach ($data as $item) { + $currentArrayKeys = array_keys($item); + if ($firstArrayKeys !== $currentArrayKeys) { + throw new FileHandlerException('Inconsistent JSON data'); + } + } + } + + /** + * @param array> $contents + * @param array,int> $indices + * @param int|false $limit + * @return Generator + */ + private function getProcessedContent(array $contents, array $indices, int|false $limit = false): Generator + { $count = 0; - $headers = array_keys($contents[0]); - $indices = is_array($hideColumns) ? $this->setColumnsToHide($headers, $hideColumns) : []; + $shouldLimit = is_int($limit); + foreach ($contents as $content) { if (!empty($indices)) { $content = array_values($content); $this->removeElementByIndex($content, $indices); } + yield $content; $count++; - if (is_int($limit) && $limit <= $count) { + if ($shouldLimit && $count >= $limit) { break; } } } /** - * @param string $jsonData - * @return array>|false + * @param string $filename + * @param array $headers + * @param array|false $hideColumns + * @param int|false $limit + * @return Generator + * @throws FileHandlerException */ - private function isValidJson(string $jsonData): array|false - { - $data = json_decode($jsonData, true); - - if (json_last_error() !== JSON_ERROR_NONE) { - return false; - } - - - if (!is_array($data)) { - return false; - } - - if (!isset($data[0]) || !is_array($data[0])) { - return false; - } - - $firstArrayKeys = array_keys($data[0]); - - foreach ($data as $item) { - $currentArrayKeys = array_keys($item); + public function getRows( + string $filename, + array &$headers, + array|false $hideColumns = false, + int|false $limit = false + ): Generator { + $contents = $this->validateFile($filename); - if ($firstArrayKeys !== $currentArrayKeys) { - return false; - } - } + $headers = array_keys($contents[0]); + $indices = is_array($hideColumns) ? $this->setColumnsToHide($headers, $hideColumns) : []; - return $data; + return $this->getProcessedContent($contents, $indices, $limit); } }