Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/Db/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class Column extends EntitySuper implements JsonSerializable {
protected ?string $lastEditByDisplayName = null;
protected ?ViewColumnInformation $viewColumnInformation = null;

protected const VIRTUAL_PROPERTIES = ['createdByDisplayName', 'lastEditByDisplayName', 'viewColumnInformation'];
protected const VIRTUAL_PROPERTIES = ['createdByDisplayName', 'lastEditByDisplayName', 'viewColumnInformation', 'columnName'];

public function __construct() {
$this->addType('id', 'integer');
Expand Down
33 changes: 32 additions & 1 deletion lib/Db/Row2.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
private ?string $lastEditBy = null;
private ?string $lastEditAt = null;
private ?array $data = [];
private array $cellMetadata = [];
private array $changedColumnIds = []; // collect column ids that have changed after $loaded = true

private bool $loaded = false; // set to true if model is loaded, after that changed column ids will be collected
Expand Down Expand Up @@ -133,18 +134,37 @@
return $this->data;
}

/**
* add response-only metadata for a specific column
*/
public function addCellMeta(int $columnId, array $meta): void {
if (!isset($this->cellMetadata[$columnId])) {
$this->cellMetadata[$columnId] = [];
}
$this->cellMetadata[$columnId] = array_merge($this->cellMetadata[$columnId], $meta);
}

/**
* @psalm-return TablesRow

Check failure on line 148 in lib/Db/Row2.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

InvalidReturnType

lib/Db/Row2.php:148:19: InvalidReturnType: The declared return type 'array{createdAt: string, createdBy: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string, lastEditBy: string, tableId: int}' for OCA\Tables\Db\Row2::jsonSerialize is incorrect, got 'array{createdAt: null|string, createdBy: null|string, data: non-empty-list<array<array-key, mixed>|mixed>, id: int|null, lastEditAt: null|string, lastEditBy: null|string, tableId: int|null}' (see https://psalm.dev/011)

Check failure on line 148 in lib/Db/Row2.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidReturnType

lib/Db/Row2.php:148:19: InvalidReturnType: The declared return type 'array{createdAt: string, createdBy: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string, lastEditBy: string, tableId: int}' for OCA\Tables\Db\Row2::jsonSerialize is incorrect, got 'array{createdAt: null|string, createdBy: null|string, data: non-empty-list<array<array-key, mixed>|mixed>, id: int|null, lastEditAt: null|string, lastEditBy: null|string, tableId: int|null}' (see https://psalm.dev/011)
*/
public function jsonSerialize(): array {
$data = [];
foreach ($this->data as $cell) {
$colId = $cell['columnId'];
$merged = $cell;
if (isset($this->cellMetadata[$colId])) {
$merged = array_merge($merged, $this->cellMetadata[$colId]);
}
$data[] = $merged;
}
return [

Check failure on line 160 in lib/Db/Row2.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

InvalidReturnStatement

lib/Db/Row2.php:160:10: InvalidReturnStatement: The inferred type 'array{createdAt: null|string, createdBy: null|string, data: non-empty-list<array<array-key, mixed>|mixed>, id: int|null, lastEditAt: null|string, lastEditBy: null|string, tableId: int|null}' does not match the declared return type 'array{createdAt: string, createdBy: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string, lastEditBy: string, tableId: int}' for OCA\Tables\Db\Row2::jsonSerialize (see https://psalm.dev/128)

Check failure on line 160 in lib/Db/Row2.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidReturnStatement

lib/Db/Row2.php:160:10: InvalidReturnStatement: The inferred type 'array{createdAt: null|string, createdBy: null|string, data: non-empty-list<array<array-key, mixed>|mixed>, id: int|null, lastEditAt: null|string, lastEditBy: null|string, tableId: int|null}' does not match the declared return type 'array{createdAt: string, createdBy: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string, lastEditBy: string, tableId: int}' for OCA\Tables\Db\Row2::jsonSerialize (see https://psalm.dev/128)
'id' => $this->id,
'tableId' => $this->tableId,
'createdBy' => $this->createdBy,
'createdAt' => $this->createdAt,
'lastEditBy' => $this->lastEditBy,
'lastEditAt' => $this->lastEditAt,
'data' => $this->data,
'data' => $data,
];
}

Expand Down Expand Up @@ -191,4 +211,15 @@
$this->loaded = true;
}

/**
* attach columnName as metadata for each cell
*/
public function addColumnNames(array $fullRowData): void {
foreach ($fullRowData as $meta) {
if (isset($meta['columnId']) && array_key_exists('columnName', $meta)) {
$this->addCellMeta((int)$meta['columnId'], ['columnName' => $meta['columnName']]);
}
}
}

}
2 changes: 1 addition & 1 deletion lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
* createdAt: string,
* lastEditBy: string,
* lastEditAt: string,
* data: ?array{columnId: int, value: mixed},
* data: ?array{columnId: int, columnName: string, value: mixed},
* }
*
* @psalm-type TablesShare = array{
Expand Down
26 changes: 25 additions & 1 deletion lib/Service/RowService.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@
/**
* @param int $tableId
* @param string $userId
* @param ?int $limit

Check failure on line 72 in lib/Service/RowService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

InvalidReturnType

lib/Service/RowService.php:72:13: InvalidReturnType: The declared return type 'array<array-key, array{createdAt: string, data: array{columnId: int, value: mixed}|null, id: int, lastEditAt: string}>' for OCA\Tables\Service\RowService::formatRowsForPublicShare is incorrect, got 'array<array-key, array{createdAt: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string}>' (see https://psalm.dev/011)

Check failure on line 72 in lib/Service/RowService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidReturnType

lib/Service/RowService.php:72:13: InvalidReturnType: The declared return type 'array<array-key, array{createdAt: string, data: array{columnId: int, value: mixed}|null, id: int, lastEditAt: string}>' for OCA\Tables\Service\RowService::formatRowsForPublicShare is incorrect, got 'array<array-key, array{createdAt: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string}>' (see https://psalm.dev/011)
* @param ?int $offset
* @return Row2[]
* @throws InternalError

Check failure on line 75 in lib/Service/RowService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

InvalidReturnStatement

lib/Service/RowService.php:75:10: InvalidReturnStatement: The inferred type 'array<array-key, array{createdAt: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string}>' does not match the declared return type 'array<array-key, array{createdAt: string, data: array{columnId: int, value: mixed}|null, id: int, lastEditAt: string}>' for OCA\Tables\Service\RowService::formatRowsForPublicShare (see https://psalm.dev/128)

Check failure on line 75 in lib/Service/RowService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidReturnStatement

lib/Service/RowService.php:75:10: InvalidReturnStatement: The inferred type 'array<array-key, array{createdAt: string, data: array{columnId: int, columnName: string, value: mixed}|null, id: int, lastEditAt: string}>' does not match the declared return type 'array<array-key, array{createdAt: string, data: array{columnId: int, value: mixed}|null, id: int, lastEditAt: string}>' for OCA\Tables\Service\RowService::formatRowsForPublicShare (see https://psalm.dev/128)
* @throws PermissionError
*/
public function findAllByTable(int $tableId, string $userId, ?int $limit = null, ?int $offset = null): array {
Expand Down Expand Up @@ -208,6 +208,28 @@
throw new InternalError('Cannot create row without table or view in context');
}

$fullRowData = [];
$columnNames = [];

foreach ($columns as $column) {
$columnNames[$column->getId()] = $column->getTitle();
}

$rows = $data instanceof RowDataInput ? iterator_to_array($data) : $data;

foreach ($rows as $row) {
$colId = (int)$row['columnId'];
if (!isset($columnNames[$colId])) {
continue;
}

$fullRowData[] = [
'columnId' => $colId,
'value' => $row['value'],
'columnName' => $columnNames[$colId],
];
}

$tableId = $tableId ?? $view->getTableId();

$data = $data instanceof RowDataInput ? $data : RowDataInput::fromArray($data);
Expand All @@ -220,6 +242,8 @@
$row2->setData($data);
try {
$insertedRow = $this->row2Mapper->insert($row2);
// attach columnName to returned row for the response only
$insertedRow->addColumnNames($fullRowData);

$this->eventDispatcher->dispatchTyped(new RowAddedEvent($insertedRow));
$this->activityManager->triggerEvent(
Expand Down Expand Up @@ -334,7 +358,7 @@
if (!$column && $viewId) {
throw new InternalError('Column with id ' . $entry['columnId'] . ' is not part of view with id ' . $viewId);
} elseif (!$column && $tableId) {
throw new InternalError('Column with id ' . $entry['columnId'] . ' is not part of table with id ' . $tableId);
throw new BadRequestError('Column with id ' . $entry['columnId'] . ' is not part of table with id ' . $tableId);
}

if (!$column) {
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- SPDX-FileCopyrightText: 2021 Florian Steffens
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<phpunit bootstrap="tests/bootstrap.php" colors="true">
<phpunit bootstrap="tests/Unit/bootstrap.php" colors="true">
<testsuites>
<testsuite name="unit">
<directory>./tests/Unit</directory>
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/Db/Row2Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Tables\Tests\Unit\Db;

use OCA\Tables\Db\Row2;
use PHPUnit\Framework\TestCase;

class Row2Test extends TestCase {
public function testJsonSerializeMergesCellMetadata(): void {
$row = new Row2();
$row->setTableId(1);

$row->setData([
['columnId' => 57, 'value' => 'foo'],
['columnId' => 58, 'value' => 'bar'],
]);

$json = $row->jsonSerialize();
$this->assertArrayNotHasKey('columnName', $json['data'][0]);

$row->addCellMeta(57, ['columnName' => 'Title 57']);
$resp = $row->jsonSerialize();
$this->assertArrayHasKey('columnName', $resp['data'][0]);
$this->assertSame('Title 57', $resp['data'][0]['columnName']);
}
}
Loading