|  |  | @ -104,6 +104,14 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public $removedColumns = []; |  |  |  |     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 |  |  |  |      * Generator iterating all properties, used internally for serialization to array | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
	
		
		
			
				
					|  |  | @ -160,22 +168,6 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |         return $object; |  |  |  |         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 |  |  |  |      * 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)) { |  |  |  |         if ($this->isNewColumn($id)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $this->newColumns[$id] = array_merge($this->newColumns[$id], $updateObj); |  |  |  |             $this->newColumns[$id] = array_merge($this->newColumns[$id], $updateObj); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -569,7 +564,7 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |      *                               so it can be inserted directly into DB |  |  |  |      *                               so it can be inserted directly into DB | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return Collection |  |  |  |      * @return Collection | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static function csvToRowsArray($columns, $csvArray, $forTableInsert) |  |  |  |     public function csvToRowsArray($columns, $csvArray, $forTableInsert, $useDraftIds) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         /** @var Collection $rows */ |  |  |  |         /** @var Collection $rows */ | 
			
		
	
		
		
			
				
					
					|  |  |  |         $rows = collect($csvArray)->map(function ($row) use ($columns, $forTableInsert) { |  |  |  |         $rows = collect($csvArray)->map(function ($row) use ($columns, $forTableInsert) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -597,9 +592,11 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         })->filter(); |  |  |  |         })->filter(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // TODO we could use some temporary IDs and replace them with |  |  |  |         if ($useDraftIds) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // TODO   proper unique IDs when submitting the proposal |  |  |  |             $rowNumerator = new DraftRowNumerator($this, count($csvArray)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $rowNumerator = new RowNumerator(count($csvArray)); |  |  |  |             $rowNumerator = new RowNumerator(count($csvArray)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if ($forTableInsert) { |  |  |  |         if ($forTableInsert) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             return $rows->map(function ($row) use (&$rowNumerator) { |  |  |  |             return $rows->map(function ($row) use (&$rowNumerator) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -628,9 +625,7 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |             $template[$column->id] = $column->cast(null); |  |  |  |             $template[$column->id] = $column->cast(null); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // TODO we could use some temporary IDs and replace them with |  |  |  |         $numerator = new DraftRowNumerator($this, $count); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // TODO   proper unique IDs when submitting the proposal |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         $numerator = new RowNumerator($count); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         foreach ($numerator->generate() as $_id) { |  |  |  |         foreach ($numerator->generate() as $_id) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $row = $template; |  |  |  |             $row = $template; | 
			
		
	
	
		
		
			
				
					|  |  | @ -649,7 +644,7 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |         /** @var Column[] $columns */ |  |  |  |         /** @var Column[] $columns */ | 
			
		
	
		
		
			
				
					
					|  |  |  |         $columns = array_values($this->fetchAndTransformColumns()); |  |  |  |         $columns = array_values($this->fetchAndTransformColumns()); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         $rows = self::csvToRowsArray($columns, $csvArray, false) |  |  |  |         $rows = self::csvToRowsArray($columns, $csvArray, false, true) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             ->keyBy('_id'); |  |  |  |             ->keyBy('_id'); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // using '+' to avoid renumbering |  |  |  |         // using '+' to avoid renumbering | 
			
		
	
	
		
		
			
				
					|  |  | @ -803,4 +798,77 @@ class Changeset | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         $this->rowUpdates = []; |  |  |  |         $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; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |