|
|
|
@ -104,6 +104,14 @@ class Changeset |
|
|
|
|
*/ |
|
|
|
|
public $removedColumns = []; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Draft row numerator state holder; numbers grow to negative, |
|
|
|
|
* and are replaced with real unique row IDs when the proposal is submitted. |
|
|
|
|
* |
|
|
|
|
* @var int |
|
|
|
|
*/ |
|
|
|
|
public $nextRowID = -1; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Generator iterating all properties, used internally for serialization to array |
|
|
|
|
* |
|
|
|
@ -160,22 +168,6 @@ class Changeset |
|
|
|
|
return $object; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check if there is any change in this changeset |
|
|
|
|
* |
|
|
|
|
* @return bool - any found |
|
|
|
|
*/ |
|
|
|
|
public function hasAnyChanges() |
|
|
|
|
{ |
|
|
|
|
foreach ($this->walkProps() as $prop) { |
|
|
|
|
if (!empty($this->$prop)) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Decorate / transform a single row for the editor view |
|
|
|
|
* |
|
|
|
@ -504,6 +496,9 @@ class Changeset |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// try creating a column with the new data |
|
|
|
|
new Column(array_merge($col->toArray(), $updateObj)); |
|
|
|
|
|
|
|
|
|
if ($this->isNewColumn($id)) { |
|
|
|
|
$this->newColumns[$id] = array_merge($this->newColumns[$id], $updateObj); |
|
|
|
|
} |
|
|
|
@ -569,7 +564,7 @@ class Changeset |
|
|
|
|
* so it can be inserted directly into DB |
|
|
|
|
* @return Collection |
|
|
|
|
*/ |
|
|
|
|
public static function csvToRowsArray($columns, $csvArray, $forTableInsert) |
|
|
|
|
public function csvToRowsArray($columns, $csvArray, $forTableInsert, $useDraftIds) |
|
|
|
|
{ |
|
|
|
|
/** @var Collection $rows */ |
|
|
|
|
$rows = collect($csvArray)->map(function ($row) use ($columns, $forTableInsert) { |
|
|
|
@ -597,9 +592,11 @@ class Changeset |
|
|
|
|
} |
|
|
|
|
})->filter(); |
|
|
|
|
|
|
|
|
|
// TODO we could use some temporary IDs and replace them with |
|
|
|
|
// TODO proper unique IDs when submitting the proposal |
|
|
|
|
$rowNumerator = new RowNumerator(count($csvArray)); |
|
|
|
|
if ($useDraftIds) { |
|
|
|
|
$rowNumerator = new DraftRowNumerator($this, count($csvArray)); |
|
|
|
|
} else { |
|
|
|
|
$rowNumerator = new RowNumerator(count($csvArray)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($forTableInsert) { |
|
|
|
|
return $rows->map(function ($row) use (&$rowNumerator) { |
|
|
|
@ -628,9 +625,7 @@ class Changeset |
|
|
|
|
$template[$column->id] = $column->cast(null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO we could use some temporary IDs and replace them with |
|
|
|
|
// TODO proper unique IDs when submitting the proposal |
|
|
|
|
$numerator = new RowNumerator($count); |
|
|
|
|
$numerator = new DraftRowNumerator($this, $count); |
|
|
|
|
|
|
|
|
|
foreach ($numerator->generate() as $_id) { |
|
|
|
|
$row = $template; |
|
|
|
@ -649,7 +644,7 @@ class Changeset |
|
|
|
|
/** @var Column[] $columns */ |
|
|
|
|
$columns = array_values($this->fetchAndTransformColumns()); |
|
|
|
|
|
|
|
|
|
$rows = self::csvToRowsArray($columns, $csvArray, false) |
|
|
|
|
$rows = self::csvToRowsArray($columns, $csvArray, false, true) |
|
|
|
|
->keyBy('_id'); |
|
|
|
|
|
|
|
|
|
// using '+' to avoid renumbering |
|
|
|
@ -803,4 +798,77 @@ class Changeset |
|
|
|
|
{ |
|
|
|
|
$this->rowUpdates = []; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get row change counts (used for the view) |
|
|
|
|
* |
|
|
|
|
* @return object |
|
|
|
|
*/ |
|
|
|
|
public function getRowChangeCounts() |
|
|
|
|
{ |
|
|
|
|
$numChangedRows = count($this->rowUpdates); |
|
|
|
|
$numNewRows = count($this->newRows); |
|
|
|
|
$numRemovedRows = count($this->removedRows); |
|
|
|
|
|
|
|
|
|
return (object) [ |
|
|
|
|
'changed' => $numChangedRows, |
|
|
|
|
'new' => $numNewRows, |
|
|
|
|
'removed' => $numRemovedRows, |
|
|
|
|
'any' => $numChangedRows || $numNewRows || $numRemovedRows, |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get column change counts (used for the view) |
|
|
|
|
* |
|
|
|
|
* @return object |
|
|
|
|
*/ |
|
|
|
|
public function getColumnChangeCounts() |
|
|
|
|
{ |
|
|
|
|
$numChangedColumns = count($this->columnUpdates); |
|
|
|
|
$numNewColumns = count($this->newColumns); |
|
|
|
|
$numRemovedColumns = count($this->removedColumns); |
|
|
|
|
$reordered = count($this->columnOrder) != 0; |
|
|
|
|
|
|
|
|
|
return (object) [ |
|
|
|
|
'changed' => $numChangedColumns, |
|
|
|
|
'new' => $numNewColumns, |
|
|
|
|
'removed' => $numRemovedColumns, |
|
|
|
|
'reordered' => $reordered, |
|
|
|
|
'any' => $reordered || $numChangedColumns || $numNewColumns || $numRemovedColumns, |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check if there is any change in this changeset |
|
|
|
|
* |
|
|
|
|
* @return bool - any found |
|
|
|
|
*/ |
|
|
|
|
public function hasAnyChanges() |
|
|
|
|
{ |
|
|
|
|
$colChanges = $this->getColumnChangeCounts(); |
|
|
|
|
$rowChanges = $this->getRowChangeCounts(); |
|
|
|
|
|
|
|
|
|
return $colChanges->any || $rowChanges->any; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Replace temporary negative row IDs with real unique row IDs |
|
|
|
|
*/ |
|
|
|
|
public function renumberRows() |
|
|
|
|
{ |
|
|
|
|
$rows = []; |
|
|
|
|
$numerator = new RowNumerator(count($this->newRows)); |
|
|
|
|
foreach ($this->newRows as $row) { |
|
|
|
|
if ($row['_id'] < 0) { |
|
|
|
|
$id = $numerator->next(); |
|
|
|
|
$row['_id'] = $id; |
|
|
|
|
$rows[$id] = $row; |
|
|
|
|
} else { |
|
|
|
|
// keep ID |
|
|
|
|
$rows[$row['_id']] = $row; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
$this->newRows = $rows; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|