Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 93 additions & 46 deletions src/JsonFileHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use rcsofttech85\FileHandler\Exception\FileHandlerException;
use rcsofttech85\FileHandler\Utilities\RowColumnHelper;

readonly class JsonFileHandler
class JsonFileHandler
{
use RowColumnHelper;

Expand All @@ -15,7 +15,7 @@
* @param array<string> $headers
* @param array<string>|false $hideColumns
* @param int|false $limit
* @return array<string,string>
* @return array<int,array<string,string>>
* @throws FileHandlerException
*/
public function toArray(
Expand All @@ -29,81 +29,128 @@ public function toArray(

/**
* @param string $filename
* @param array<string> $headers
* @param array<string>|false $hideColumns
* @param int|false $limit
* @return Generator
* @return array<int,array<string,string>>
* @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<int,array<string,string>>|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<int,array<string,string>>|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<int,array<string,string>> $contents
* @param array<int<0,max>,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<int,array<string,string>>|false
* @param string $filename
* @param array<string> $headers
* @param array<string,string>|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);
}
}