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
13 changes: 13 additions & 0 deletions lib/Requests/Calendar/CalendarSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Calendar;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<CalendarParameters>
Expand Down Expand Up @@ -46,6 +47,18 @@ public function update(string $id, mixed $object = null): CalendarParameters
return parent::update($id, $object);
}

/**
* Patch a calendar
*
* @param string $id Calendar identifier
* @param CalendarParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete a calendar
*
Expand Down
13 changes: 13 additions & 0 deletions lib/Requests/Calendar/EventSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Calendar;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<EventParameters>
Expand Down Expand Up @@ -46,6 +47,18 @@ public function update(string $id, mixed $object = null): EventParameters
return parent::update($id, $object);
}

/**
* Patch an event
*
* @param string $id Event identifier
* @param EventParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete an event
*
Expand Down
13 changes: 13 additions & 0 deletions lib/Requests/Contacts/AddressBookSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Contacts;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<AddressBookParameters>
Expand Down Expand Up @@ -46,6 +47,18 @@ public function update(string $id, mixed $object = null): AddressBookParameters
return parent::update($id, $object);
}

/**
* Patch an address book
*
* @param string $id Address book identifier
* @param AddressBookParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete an address book
*
Expand Down
13 changes: 13 additions & 0 deletions lib/Requests/Contacts/ContactSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Contacts;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<ContactParameters>
Expand Down Expand Up @@ -46,6 +47,18 @@ public function update(string $id, mixed $object = null): ContactParameters
return parent::update($id, $object);
}

/**
* Patch a contact
*
* @param string $id Contact identifier
* @param ContactParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete a contact
*
Expand Down
13 changes: 13 additions & 0 deletions lib/Requests/Files/NodeSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Files;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<NodeParameters>
Expand All @@ -35,6 +36,18 @@ public function delete(string $id): static
return parent::delete($id);
}

/**
* Patch a node
*
* @param string $id Node identifier
* @param NodeParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

public function destroyChildren(bool $value): static
{
$this->_command['onDestroyRemoveChildren'] = $value;
Expand Down
7 changes: 7 additions & 0 deletions lib/Requests/Interfaces/RequestParametersInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ interface RequestParametersInterface
* @return self For method chaining
*/
public function bind(&$anchor): static;

/**
* Create a patch snapshot from the current structured parameters
*
* @return RequestPatchInterface The patch representation of these parameters
*/
public function patch(): RequestPatchInterface;
}
43 changes: 43 additions & 0 deletions lib/Requests/Interfaces/RequestPatchInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Sebastian Krupinski <krupinski01@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace JmapClient\Requests\Interfaces;

/**
* Interface for JMAP patch request parameters
*/
interface RequestPatchInterface
{
/**
* Bind the patch to an anchor object
*
* @param object $anchor Reference to the anchor object
* @return self For method chaining
*/
public function bind(&$anchor): static;

/**
* Set a JMAP patch path to a value
*
* @param string $path The JMAP patch path
* @param mixed $value The value for the path
*
* @return self For method chaining
*/
public function path(string $path, mixed $value): static;

/**
* Replace the patch object with raw patch data
*
* @param array<mixed> $value Patch data keyed by JMAP patch path
*
* @return self For method chaining
*/
public function parametersRaw(array $value): static;
}
13 changes: 13 additions & 0 deletions lib/Requests/Mail/MailIdentitySet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Mail;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<MailIdentityParameters>
Expand Down Expand Up @@ -44,6 +45,18 @@ public function update(string $id, mixed $object = null): MailIdentityParameters
return parent::update($id, $object);
}

/**
* Patch an mail identity
*
* @param string $id Mail identity identifier
* @param MailIdentityParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete a mail identity
*
Expand Down
13 changes: 13 additions & 0 deletions lib/Requests/Mail/MailSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Mail;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<MailParameters>
Expand Down Expand Up @@ -44,6 +45,18 @@ public function update(string $id, mixed $object = null): MailParameters
return parent::update($id, $object);
}

/**
* Patch an email
*
* @param string $id Email identifier
* @param MailParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete an email
*
Expand Down
13 changes: 13 additions & 0 deletions lib/Requests/Mail/MailVacationSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Mail;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<MailVacationParameters>
Expand All @@ -32,4 +33,16 @@ public function update(string $id, mixed $object = null): MailVacationParameters
{
return parent::update($id, $object);
}

/**
* Patch an vacation response (there's only one with id "singleton")
*
* @param string $id Vacation response identifier (should be "singleton")
* @param MailVacationParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}
}
13 changes: 13 additions & 0 deletions lib/Requests/Mail/MailboxSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests\Mail;

use JmapClient\Requests\RequestSet;
use JmapClient\Requests\Interfaces\RequestPatchInterface;

/**
* @extends RequestSet<MailboxParameters>
Expand Down Expand Up @@ -45,6 +46,18 @@ public function update(string $id, mixed $object = null): MailboxParameters
{
return parent::update($id, $object);
}

/**
* Patch a mailbox
*
* @param string $id Mailbox identifier
* @param MailboxParameters|RequestPatchInterface|null $object Optional structured or patch object
* @return RequestPatchInterface The patch object for method chaining
*/
public function patch(string $id, mixed $object = null): RequestPatchInterface
{
return parent::patch($id, $object);
}

/**
* Delete a mailbox
Expand Down
50 changes: 50 additions & 0 deletions lib/Requests/RequestParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JmapClient\Requests;

use JmapClient\Requests\Interfaces\RequestParametersInterface;
use JmapClient\Requests\Interfaces\RequestPatchInterface;
use stdClass;

class RequestParameters implements RequestParametersInterface
Expand All @@ -34,6 +35,50 @@ public function bind(&$anchor): static
return $this;
}

public function patch(): RequestPatchInterface
{
$flatten = function (object|array $parameters, string $prefix = '') use (&$flatten): array {
$patch = [];

$entries = is_object($parameters) ? get_object_vars($parameters) : $parameters;

foreach ($entries as $name => $value) {
$path = $prefix === '' ? self::escapePatchSegment($name) : $prefix . '/' . self::escapePatchSegment($name);

if (is_object($value)) {
$entries = $flatten($value, $path);
if ($entries === []) {
$patch[$path] = new stdClass();
continue;
}

$patch = array_merge($patch, $entries);
continue;
}

if (is_array($value) && array_is_list($value) === false) {
$entries = $flatten($value, $path);
if ($entries === []) {
$patch[$path] = new stdClass();
continue;
}

$patch = array_merge($patch, $entries);
continue;
}

$patch[$path] = $value;
}

return $patch;
};

$patch = new RequestPatch();
$patch->parametersRaw($flatten($this->_parameters));

return $patch;
}

protected function parameter(string $name, mixed $value): static
{
$this->_parameters->$name = $value;
Expand Down Expand Up @@ -65,4 +110,9 @@ public function parametersRaw(array $value): static
$this->_parameters = (object) $value;
return $this;
}

private static function escapePatchSegment(string $segment): string
{
return str_replace(['~', '/'], ['~0', '~1'], $segment);
}
}
Loading
Loading