cerebrate/src/Lib/Tools/CsvConverter.php

85 lines
2.0 KiB
PHP

<?php
namespace App\Lib\Tools;
use Cake\Utility\Hash;
class CsvConverter
{
/**
* @param array $data
* @param array $options
* @return string
*/
public static function flattenJSON(array $data, $options=[]): string
{
$csv = '';
$toConvert = [];
if (!self::array_is_list($data)) {
$toConvert = [$data];
} else {
$toConvert = $data;
}
$headers = self::collectHeaders($toConvert);
$csv .= implode(',', self::quoteArray($headers)) . PHP_EOL;
foreach ($toConvert as $i => $item) {
$csv .= self::getRow($headers, $item);
}
return $csv;
}
private static function collectHeaders(array $items): array
{
$allHeaders = [];
foreach ($items as $item) {
$headers = Hash::flatten($item);
foreach ($headers as $head => $value) {
if (str_starts_with($head, '_')) {
continue;
}
if (is_array($value) && empty($value)) {
continue;
}
$allHeaders[$head] = 1;
}
}
return array_keys($allHeaders);
}
private static function getRow(array $headers, array $item): string
{
$tmp = [];
foreach ($headers as $header) {
$value = Hash::get($item, $header);
if (!isset($value)) {
$value = '';
}
if (is_bool($value)) {
$value = !empty($value) ? '1' : '0';
}
$tmp[] = '"' . $value . '"';
}
$row = implode(',', $tmp) . PHP_EOL;
return $row;
}
private static function quoteArray(array $arr): array
{
return array_map(function($item) {
return '"' . $item . '"';
}, $arr);
}
private static function array_is_list(array $arr): bool
{
if ($arr === []) {
return true;
}
return array_keys($arr) === range(0, count($arr) - 1);
}
}