Skip to content
Merged
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
3 changes: 2 additions & 1 deletion src/Database/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -697,10 +697,11 @@ abstract public function createDocuments(string $collection, array $documents):
* @param string $collection
* @param string $id
* @param Document $document
* @param bool $skipPermissions
*
* @return Document
*/
abstract public function updateDocument(string $collection, string $id, Document $document): Document;
abstract public function updateDocument(string $collection, string $id, Document $document, bool $skipPermissions): Document;

/**
* Update documents
Expand Down
197 changes: 100 additions & 97 deletions src/Database/Adapter/MariaDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -925,13 +925,14 @@ public function createDocument(string $collection, Document $document): Document
* @param string $collection
* @param string $id
* @param Document $document
* @param bool $skipPermissions
* @return Document
* @throws Exception
* @throws PDOException
* @throws DuplicateException
* @throws \Throwable
*/
public function updateDocument(string $collection, string $id, Document $document): Document
public function updateDocument(string $collection, string $id, Document $document, bool $skipPermissions): Document
{
try {
$attributes = $document->getAttributes();
Expand All @@ -942,149 +943,151 @@ public function updateDocument(string $collection, string $id, Document $documen
$name = $this->filter($collection);
$columns = '';

$sql = "
if (!$skipPermissions) {
$sql = "
SELECT _type, _permission
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);
$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);

/**
* Get current permissions from the database
*/
$sqlPermissions = $this->getPDO()->prepare($sql);
$sqlPermissions->bindValue(':_uid', $document->getId());
/**
* Get current permissions from the database
*/
$sqlPermissions = $this->getPDO()->prepare($sql);
$sqlPermissions->bindValue(':_uid', $document->getId());

if ($this->sharedTables) {
$sqlPermissions->bindValue(':_tenant', $this->tenant);
}
if ($this->sharedTables) {
$sqlPermissions->bindValue(':_tenant', $this->tenant);
}

$sqlPermissions->execute();
$permissions = $sqlPermissions->fetchAll();
$sqlPermissions->closeCursor();
$sqlPermissions->execute();
$permissions = $sqlPermissions->fetchAll();
$sqlPermissions->closeCursor();

$initial = [];
foreach (Database::PERMISSIONS as $type) {
$initial[$type] = [];
}
$initial = [];
foreach (Database::PERMISSIONS as $type) {
$initial[$type] = [];
}

$permissions = array_reduce($permissions, function (array $carry, array $item) {
$carry[$item['_type']][] = $item['_permission'];
$permissions = array_reduce($permissions, function (array $carry, array $item) {
$carry[$item['_type']][] = $item['_permission'];

return $carry;
}, $initial);
return $carry;
}, $initial);

/**
* Get removed Permissions
*/
$removals = [];
foreach (Database::PERMISSIONS as $type) {
$diff = \array_diff($permissions[$type], $document->getPermissionsByType($type));
if (!empty($diff)) {
$removals[$type] = $diff;
/**
* Get removed Permissions
*/
$removals = [];
foreach (Database::PERMISSIONS as $type) {
$diff = \array_diff($permissions[$type], $document->getPermissionsByType($type));
if (!empty($diff)) {
$removals[$type] = $diff;
}
}
}

/**
* Get added Permissions
*/
$additions = [];
foreach (Database::PERMISSIONS as $type) {
$diff = \array_diff($document->getPermissionsByType($type), $permissions[$type]);
if (!empty($diff)) {
$additions[$type] = $diff;
/**
* Get added Permissions
*/
$additions = [];
foreach (Database::PERMISSIONS as $type) {
$diff = \array_diff($document->getPermissionsByType($type), $permissions[$type]);
if (!empty($diff)) {
$additions[$type] = $diff;
}
}
}

/**
* Query to remove permissions
*/
$removeQuery = '';
if (!empty($removals)) {
$removeQuery = ' AND (';
foreach ($removals as $type => $permissions) {
$removeQuery .= "(
/**
* Query to remove permissions
*/
$removeQuery = '';
if (!empty($removals)) {
$removeQuery = ' AND (';
foreach ($removals as $type => $permissions) {
$removeQuery .= "(
_type = '{$type}'
AND _permission IN (" . implode(', ', \array_map(fn (string $i) => ":_remove_{$type}_{$i}", \array_keys($permissions))) . ")
)";
if ($type !== \array_key_last($removals)) {
$removeQuery .= ' OR ';
if ($type !== \array_key_last($removals)) {
$removeQuery .= ' OR ';
}
}
}
}
if (!empty($removeQuery)) {
$removeQuery .= ')';
$sql = "
if (!empty($removeQuery)) {
$removeQuery .= ')';
$sql = "
DELETE
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

$removeQuery = $sql . $removeQuery;
$removeQuery = $sql . $removeQuery;

$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);
$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);

$stmtRemovePermissions = $this->getPDO()->prepare($removeQuery);
$stmtRemovePermissions->bindValue(':_uid', $document->getId());
$stmtRemovePermissions = $this->getPDO()->prepare($removeQuery);
$stmtRemovePermissions->bindValue(':_uid', $document->getId());

if ($this->sharedTables) {
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
}
if ($this->sharedTables) {
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
}

foreach ($removals as $type => $permissions) {
foreach ($permissions as $i => $permission) {
$stmtRemovePermissions->bindValue(":_remove_{$type}_{$i}", $permission);
foreach ($removals as $type => $permissions) {
foreach ($permissions as $i => $permission) {
$stmtRemovePermissions->bindValue(":_remove_{$type}_{$i}", $permission);
}
}
}
}

/**
* Query to add permissions
*/
if (!empty($additions)) {
$values = [];
foreach ($additions as $type => $permissions) {
foreach ($permissions as $i => $_) {
$value = "( :_uid, '{$type}', :_add_{$type}_{$i}";

if ($this->sharedTables) {
$value .= ", :_tenant)";
} else {
$value .= ")";
/**
* Query to add permissions
*/
if (!empty($additions)) {
$values = [];
foreach ($additions as $type => $permissions) {
foreach ($permissions as $i => $_) {
$value = "( :_uid, '{$type}', :_add_{$type}_{$i}";

if ($this->sharedTables) {
$value .= ", :_tenant)";
} else {
$value .= ")";
}

$values[] = $value;
}

$values[] = $value;
}
}

$sql = "
$sql = "
INSERT INTO {$this->getSQLTable($name . '_perms')} (_document, _type, _permission
";

if ($this->sharedTables) {
$sql .= ', _tenant)';
} else {
$sql .= ')';
}
if ($this->sharedTables) {
$sql .= ', _tenant)';
} else {
$sql .= ')';
}

$sql .= " VALUES " . \implode(', ', $values);
$sql .= " VALUES " . \implode(', ', $values);

$sql = $this->trigger(Database::EVENT_PERMISSIONS_CREATE, $sql);
$sql = $this->trigger(Database::EVENT_PERMISSIONS_CREATE, $sql);

$stmtAddPermissions = $this->getPDO()->prepare($sql);
$stmtAddPermissions = $this->getPDO()->prepare($sql);

$stmtAddPermissions->bindValue(":_uid", $document->getId());
$stmtAddPermissions->bindValue(":_uid", $document->getId());

if ($this->sharedTables) {
$stmtAddPermissions->bindValue(":_tenant", $this->tenant);
}
if ($this->sharedTables) {
$stmtAddPermissions->bindValue(":_tenant", $this->tenant);
}

foreach ($additions as $type => $permissions) {
foreach ($permissions as $i => $permission) {
$stmtAddPermissions->bindValue(":_add_{$type}_{$i}", $permission);
foreach ($additions as $type => $permissions) {
foreach ($permissions as $i => $permission) {
$stmtAddPermissions->bindValue(":_add_{$type}_{$i}", $permission);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Database/Adapter/Pool.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public function createDocuments(string $collection, array $documents): array
return $this->delegate(__FUNCTION__, \func_get_args());
}

public function updateDocument(string $collection, string $id, Document $document): Document
public function updateDocument(string $collection, string $id, Document $document, bool $skipPermissions): Document
{
return $this->delegate(__FUNCTION__, \func_get_args());
}
Expand Down
Loading