diff --git a/lib/Service/RowService.php b/lib/Service/RowService.php index 22f393a0b5..72f06861da 100644 --- a/lib/Service/RowService.php +++ b/lib/Service/RowService.php @@ -24,6 +24,7 @@ use OCA\Tables\Model\RowDataInput; use OCA\Tables\ResponseDefinitions; use OCA\Tables\Service\ColumnTypes\IColumnTypeBusiness; +use OCA\Tables\Service\ValueObject\ViewColumnInformation; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\DB\Exception; @@ -274,10 +275,27 @@ private function enhanceWithViewDefaults(?View $view, RowDataInput $data): RowDa return $data; } + /** + * @return array + */ + private function extractReadOnlyColumns (View $view): array { + $columnSettings = $view->getColumnsSettingsArray(); + return array_reduce($columnSettings, static function (array $carry, ViewColumnInformation $column) { + if ($column[ViewColumnInformation::KEY_READONLY]) { + $carry[$column->getId()] = true; + } + return $carry; + }, []); + } + /** * @throws InternalError */ private function cleanupData(RowDataInput $data, array $columns, ?int $tableId, ?int $viewId): RowDataInput { + $readOnlyColumns = $viewId + ? $this->extractReadOnlyColumns($this->viewMapper->find($viewId)) + : null; + $out = new RowDataInput(); foreach ($data as $entry) { $column = $this->getColumnFromColumnsArray((int)$entry['columnId'], $columns); @@ -295,6 +313,10 @@ private function cleanupData(RowDataInput $data, array $columns, ?int $tableId, throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage()); } + if ($readOnlyColumns && isset($readOnlyColumns[$entry['columnId']])) { + continue; + } + // parse given value to respect the column type value format $out->add((int)$entry['columnId'], $this->parseValueByColumnType($column, $entry['value'])); } diff --git a/lib/Service/ValueObject/ViewColumnInformation.php b/lib/Service/ValueObject/ViewColumnInformation.php index 403877daff..45d56e342e 100644 --- a/lib/Service/ValueObject/ViewColumnInformation.php +++ b/lib/Service/ValueObject/ViewColumnInformation.php @@ -17,12 +17,14 @@ class ViewColumnInformation implements ArrayAccess, JsonSerializable { public const KEY_ID = 'columnId'; public const KEY_ORDER = 'order'; + public const KEY_READONLY = 'readonly'; - /** @var array{columndId?: int, order?: int} */ + /** @var array{columndId?: int, order?: int, readonly?: bool} */ protected array $data = []; protected const KEYS = [ self::KEY_ID, self::KEY_ORDER, + self::KEY_READONLY, ]; public function __construct( @@ -33,6 +35,10 @@ public function __construct( $this->offsetSet(self::KEY_ORDER, $order); } + public function getId(): int { + return $this->offsetGet(self::KEY_ID); + } + public function getOrder(): int { return $this->offsetGet(self::KEY_ORDER); } @@ -57,6 +63,7 @@ public function offsetSet(mixed $offset, mixed $value): void { if (!$this->offsetExists($offset)) { return; } + $this->ensureType($offset, $value); $this->data[(string)$offset] = $value; } @@ -70,4 +77,16 @@ public function offsetUnset(mixed $offset): void { public function jsonSerialize(): array { return $this->data; } + + protected function ensureType(string $offset, mixed &$value): void { + switch ($offset) { + case self::KEY_ID: + case self::KEY_ORDER: + $value = (int)$value; + break; + case self::KEY_READONLY: + $value = (bool)$value; + break; + } + } }