Skip to content

Commit

Permalink
Merge pull request #1101 from nextcloud/feat/add-events-for-table-mod…
Browse files Browse the repository at this point in the history
…ification

feat: Add events for row added and row updated
  • Loading branch information
blizzz authored Jul 18, 2024
2 parents 07b3280 + 550a106 commit 54fb451
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 26 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"nextcloud/ocp": "dev-master",
"staabm/annotate-pull-request-from-checkstyle": "^1.8",
"phpunit/phpunit": "^9",
"psalm/phar": "^5.18",
"psalm/phar": "^5.25",
"bamarni/composer-bin-plugin": "^1.8"
},
"config": {
Expand Down
16 changes: 8 additions & 8 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions lib/Db/Row2.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace OCA\Tables\Db;

use JsonSerializable;
use OCA\Tables\Model\Public\Row;
use OCA\Tables\ResponseDefinitions;

/**
Expand Down Expand Up @@ -132,6 +133,15 @@ public function jsonSerialize(): array {
];
}

public function toPublicRow(?array $previousValues = null): Row {
return new Row(
tableId: $this->tableId,
rowId: $this->id,
previousValues: $previousValues,
values: $this->data,
);
}

/**
* Can only be changed by private methods
* @param int $columnId
Expand Down
43 changes: 43 additions & 0 deletions lib/Event/AbstractRowEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace OCA\Tables\Event;

use OCA\Tables\Db\Row2;
use OCA\Tables\Model\Public\Row;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IWebhookCompatibleEvent;

if (interface_exists(\OCP\EventDispatcher\IWebhookCompatibleEvent::class)) {
abstract class AbstractRowEvent extends Event implements IWebhookCompatibleEvent {
protected Row $row;

public function __construct(Row2 $rowEntity, ?array $previousValues = null) {
parent::__construct();
$this->row = $rowEntity->toPublicRow($previousValues);
}

public function getRow(): Row {
return $this->row;
}

public function getWebhookSerializable(): array {
return $this->row->jsonSerialize();
}
}
} else {
// need this block as long as NC < 30 is supported
abstract class AbstractRowEvent extends Event {
protected Row $row;

public function __construct(Row2 $rowEntity, ?array $previousValues = null) {
parent::__construct();
$this->row = $rowEntity->toPublicRow($previousValues);
}

public function getRow(): Row {
return $this->row;
}
}
}
8 changes: 8 additions & 0 deletions lib/Event/RowAddedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

declare(strict_types=1);

namespace OCA\Tables\Event;

final class RowAddedEvent extends AbstractRowEvent {
}
12 changes: 1 addition & 11 deletions lib/Event/RowDeletedEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,5 @@

namespace OCA\Tables\Event;

use OCA\Tables\Db\Row2;
use OCP\EventDispatcher\Event;

final class RowDeletedEvent extends Event {
public function __construct(protected Row2 $row) {
parent::__construct();
}

public function getRow(): Row2 {
return $this->row;
}
final class RowDeletedEvent extends AbstractRowEvent {
}
8 changes: 8 additions & 0 deletions lib/Event/RowUpdatedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

declare(strict_types=1);

namespace OCA\Tables\Event;

final class RowUpdatedEvent extends AbstractRowEvent {
}
2 changes: 1 addition & 1 deletion lib/Listener/WhenRowDeletedAuditLogListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function handle(Event $event): void {
}

$row = $event->getRow();
$rowId = $row->getId();
$rowId = $row->rowId;

$this->auditLogService->log("Row with ID: $rowId was deleted", [
'row' => $row->jsonSerialize(),
Expand Down
46 changes: 46 additions & 0 deletions lib/Model/Public/Row.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace OCA\Tables\Model\Public;

use JsonSerializable;

/**
* @since 0.8
*/
final class Row implements JsonSerializable {

/**
* @param int $tableId
* @param int $rowId
* @param array<int,mixed>|null $previousValues key is the columnId. Only set on Update events.
* @param array<int,mixed>|null $values key is the columnId. Contains values across all events, including Delete.
*
* @since 0.8
*/
public function __construct(
/** @readonly */
public int $tableId,
/** @readonly */
public int $rowId,
/** @readonly */
public null|array $previousValues = null,
/** @readonly */
public null|array $values = null,
) {
}


/**
* @return array{"tableId": int, "rowId": int, "previousValues": null|array<int, mixed>, "values": null|array<int, mixed>}
*
* @since 0.8
*/
public function jsonSerialize(): array {
return [
'tableId' => $this->tableId,
'rowId' => $this->rowId,
'previousValues' => $this->previousValues,
'values' => $this->values,
];
}
}
17 changes: 14 additions & 3 deletions lib/Service/RowService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Errors\NotFoundError;
use OCA\Tables\Errors\PermissionError;
use OCA\Tables\Event\RowAddedEvent;
use OCA\Tables\Event\RowDeletedEvent;
use OCA\Tables\Event\RowUpdatedEvent;
use OCA\Tables\Model\RowDataInput;
use OCA\Tables\ResponseDefinitions;
use OCA\Tables\Service\ColumnTypes\IColumnTypeBusiness;
Expand Down Expand Up @@ -214,7 +216,11 @@ public function create(?int $tableId, ?int $viewId, RowDataInput|array $data): R
$row2->setTableId($tableId);
$row2->setData($data);
try {
return $this->row2Mapper->insert($row2, $this->columnMapper->findAllByTable($tableId));
$insertedRow = $this->row2Mapper->insert($row2, $this->columnMapper->findAllByTable($tableId));

$this->eventDispatcher->dispatchTyped(new RowAddedEvent($insertedRow));

return $insertedRow;
} catch (InternalError|Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': '.$e->getMessage());
Expand Down Expand Up @@ -399,6 +405,7 @@ public function updateSet(
}
}

$previousData = $item->getData();
$data = $this->cleanupData($data, $columns, $item->getTableId(), $viewId);

foreach ($data as $entry) {
Expand All @@ -411,7 +418,11 @@ public function updateSet(
}
}

return $this->filterRowResult($view ?? null, $this->row2Mapper->update($item, $columns));
$updatedRow = $this->row2Mapper->update($item, $columns);

$this->eventDispatcher->dispatchTyped(new RowUpdatedEvent($updatedRow, $previousData));

return $this->filterRowResult($view ?? null, $updatedRow);
}

/**
Expand Down Expand Up @@ -466,7 +477,7 @@ public function delete(int $id, ?int $viewId, string $userId): Row2 {
try {
$deletedRow = $this->row2Mapper->delete($item);

$event = new RowDeletedEvent(row: $item);
$event = new RowDeletedEvent($item, $item->getData());

$this->eventDispatcher->dispatchTyped($event);

Expand Down
5 changes: 3 additions & 2 deletions tests/unit/Listener/WhenRowDeletedAuditLogTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ protected function setUp(): void {
public function testHandle(): void {
$row = new Row2();
$row->setId(1);
$row->setTableId(161);

$event = new RowDeletedEvent(row: $row);
$event = new RowDeletedEvent($row);

$this->auditLogService
->expects($this->once())
->method('log')
->with(
$this->equalTo("Row with ID: {$row->getId()} was deleted"),
$this->equalTo([
'row' => $row->jsonSerialize(),
'row' => $row->toPublicRow()->jsonSerialize(),
])
);

Expand Down

0 comments on commit 54fb451

Please sign in to comment.