Example #1
0
 /**
  * Handle the actual write to CsvRow
  * @param object $dataRow
  * @param CsvRow $csvRow
  * @param string $arrayParentId
  * @param string $column
  * @param string $dataType
  * @param string $type
  * @return void
  */
 protected function parseField(\stdClass $dataRow, CsvRow $csvRow, $arrayParentId, $column, $dataType, $type)
 {
     // TODO safeColumn should be associated with $this->struct[$type]
     // (and parentCols -> create in parse() where the arr is created)
     // Actually, the csvRow should REALLY have a pointer to the real name (not validated),
     // perhaps sorting the child columns on its own?
     // (because keys in struct don't contain child objects)
     $safeColumn = $this->createSafeName($column);
     // skip empty objects & arrays to prevent creating empty tables
     // or incomplete column names
     if (!isset($dataRow->{$column}) || is_null($dataRow->{$column}) || empty($dataRow->{$column}) && !is_scalar($dataRow->{$column})) {
         // do not save empty objects to prevent creation of ["obj_name" => null]
         if ($dataType != 'object') {
             $csvRow->setValue($safeColumn, null);
         }
         return;
     }
     if ($dataType == "NULL") {
         // Throw exception instead? Any usecase? TODO get rid of it maybe?
         $this->log->log("WARNING", "Encountered data where 'NULL' was expected from previous analysis", ['type' => $type, 'data' => $dataRow]);
         $csvRow->setValue($column, json_encode($dataRow));
         return;
     }
     if ($this->getStruct()->isArrayOf($dataType)) {
         if (!is_array($dataRow->{$column})) {
             $dataRow->{$column} = [$dataRow->{$column}];
         }
         $dataType = 'array';
     }
     switch ($dataType) {
         case "array":
             $csvRow->setValue($safeColumn, $arrayParentId);
             $this->parse($dataRow->{$column}, $type . "." . $column, $arrayParentId);
             break;
         case "object":
             $childRow = $this->parseRow($dataRow->{$column}, $type . "." . $column, [], $arrayParentId);
             foreach ($childRow->getRow() as $key => $value) {
                 // FIXME createSafeName is duplicated here
                 $csvRow->setValue($this->createSafeName($safeColumn . '_' . $key), $value);
             }
             break;
         default:
             // If a column is an object/array while $struct expects a single column, log an error
             if (is_scalar($dataRow->{$column})) {
                 $csvRow->setValue($safeColumn, $dataRow->{$column});
             } else {
                 $jsonColumn = json_encode($dataRow->{$column});
                 $this->log->log("ERROR", "Data parse error in '{$column}' - unexpected '" . $this->analyzer->getType($dataRow->{$column}) . "' where '{$dataType}' was expected!", ["data" => $jsonColumn, "row" => json_encode($dataRow)]);
                 $csvRow->setValue($safeColumn, $jsonColumn);
             }
             break;
     }
 }
 public function testArrayOfNull()
 {
     $analyzer = new Analyzer($this->getLogger('analyzer', true));
     $analyzer->getStruct()->setAutoUpgradeToArray(true);
     $analyzer->analyze([(object) ['val' => ['stringArr'], 'obj' => [(object) ['key' => 'objValue']]], (object) ['val' => [null], 'obj' => [null]]], 's2null');
     $analyzer->analyze([(object) ['val' => ['stringArr'], 'obj' => [(object) ['key' => 'objValue']]], (object) ['val' => [null], 'obj' => [null]]], 'null2s');
     self::assertEquals(['s2null' => ['val' => 'arrayOfscalar', 'obj' => 'arrayOfobject'], 's2null.val' => ['data' => 'scalar'], 'null2s' => ['val' => 'arrayOfscalar', 'obj' => 'arrayOfobject'], 'null2s.val' => ['data' => 'scalar'], 's2null.obj' => ['key' => 'scalar'], 'null2s.obj' => ['key' => 'scalar']], $analyzer->getStruct()->getStruct());
 }