fix: do not ignore move command object target uri

Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
pull/54201/head
SebastianKrupinski 2025-04-21 17:26:41 +07:00 committed by Andy Scherzinger
parent 5bf72b4621
commit 4aba03f319
3 changed files with 24 additions and 15 deletions

@ -246,7 +246,12 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMov
}
try {
return $this->carddavBackend->moveCard($sourceNode->getAddressbookId(), (int)$this->addressBookInfo['id'], $sourceNode->getUri(), $sourceNode->getOwner());
return $this->carddavBackend->moveCard(
$sourceNode->getAddressbookId(),
$sourceNode->getUri(),
$this->getResourceId(),
$targetName,
);
} catch (Exception $e) {
// Avoid injecting LoggerInterface everywhere
Server::get(LoggerInterface::class)->error('Could not move calendar object: ' . $e->getMessage(), ['exception' => $e]);

@ -475,7 +475,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
*/
public function getCards($addressbookId) {
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid'])
$query->select(['id', 'addressbookid', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid'])
->from($this->dbCardsTable)
->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressbookId)));
@ -512,7 +512,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
*/
public function getCard($addressBookId, $cardUri) {
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid'])
$query->select(['id', 'addressbookid', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid'])
->from($this->dbCardsTable)
->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId)))
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($cardUri)))
@ -555,7 +555,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
$cards = [];
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid'])
$query->select(['id', 'addressbookid', 'uri', 'lastmodified', 'etag', 'size', 'carddata', 'uid'])
->from($this->dbCardsTable)
->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId)))
->andWhere($query->expr()->in('uri', $query->createParameter('uri')));
@ -717,32 +717,33 @@ class CardDavBackend implements BackendInterface, SyncSupport {
/**
* @throws Exception
*/
public function moveCard(int $sourceAddressBookId, int $targetAddressBookId, string $cardUri, string $oldPrincipalUri): bool {
return $this->atomic(function () use ($sourceAddressBookId, $targetAddressBookId, $cardUri, $oldPrincipalUri) {
$card = $this->getCard($sourceAddressBookId, $cardUri);
public function moveCard(int $sourceAddressBookId, string $sourceObjectUri, int $targetAddressBookId, string $tragetObjectUri): bool {
return $this->atomic(function () use ($sourceAddressBookId, $sourceObjectUri, $targetAddressBookId, $tragetObjectUri) {
$card = $this->getCard($sourceAddressBookId, $sourceObjectUri);
if (empty($card)) {
return false;
}
$sourceObjectId = (int)$card['id'];
$query = $this->db->getQueryBuilder();
$query->update('cards')
->set('addressbookid', $query->createNamedParameter($targetAddressBookId, IQueryBuilder::PARAM_INT))
->where($query->expr()->eq('uri', $query->createNamedParameter($cardUri, IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR))
->set('uri', $query->createNamedParameter($tragetObjectUri, IQueryBuilder::PARAM_STR))
->where($query->expr()->eq('uri', $query->createNamedParameter($sourceObjectUri, IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR))
->andWhere($query->expr()->eq('addressbookid', $query->createNamedParameter($sourceAddressBookId, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT))
->executeStatement();
$this->purgeProperties($sourceAddressBookId, (int)$card['id']);
$this->updateProperties($sourceAddressBookId, $card['uri'], $card['carddata']);
$this->purgeProperties($sourceAddressBookId, $sourceObjectId);
$this->updateProperties($targetAddressBookId, $tragetObjectUri, $card['carddata']);
$this->addChange($sourceAddressBookId, $card['uri'], 3);
$this->addChange($targetAddressBookId, $card['uri'], 1);
$this->addChange($sourceAddressBookId, $sourceObjectUri, 3);
$this->addChange($targetAddressBookId, $tragetObjectUri, 1);
$card = $this->getCard($targetAddressBookId, $cardUri);
$card = $this->getCard($targetAddressBookId, $tragetObjectUri);
// Card wasn't found - possibly because it was deleted in the meantime by a different client
if (empty($card)) {
return false;
}
$targetAddressBookRow = $this->getAddressBookById($targetAddressBookId);
// the address book this card is being moved to does not exist any longer
if (empty($targetAddressBookRow)) {

@ -33,7 +33,10 @@ class AddressBookTest extends TestCase {
$card = new Card($backend, $addressBookInfo, ['id' => 5, 'carddata' => 'RANDOM VCF DATA', 'uri' => 'something', 'addressbookid' => 23]);
$backend->expects($this->once())->method('moveCard')->with(23, 666, 'something', 'user1')->willReturn(true);
$backend->expects($this->once())
->method('moveCard')
->with(23, 'something', 666, 'new')
->willReturn(true);
$addressBook->moveInto('new', 'old', $card);
}