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
21 changes: 21 additions & 0 deletions lib/public/Json/JsonDeserializable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

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

namespace OCP\Json;

/**
* Interface for objects that can be deserialized from JSON data.
*
* @since 33.0.0
*/
interface JsonDeserializable {

public static function jsonDeserialize(array|string $data): static;

}
36 changes: 35 additions & 1 deletion lib/public/Mail/Provider/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*/
namespace OCP\Mail\Provider;

use JsonSerializable;
use OCP\Json\JsonDeserializable;

/**
* Mail Address Object
*
Expand All @@ -16,7 +19,7 @@
* @since 30.0.0
*
*/
class Address implements \OCP\Mail\Provider\IAddress {
class Address implements IAddress, JsonSerializable, JsonDeserializable {

/**
* initialize the mail address object
Expand All @@ -32,6 +35,37 @@ public function __construct(
) {
}

/**
* export this objects data as an array
*
* @since 33.0.0
*
* @return array representation of this object as an array
*/
public function jsonSerialize(): array {
return [
'address' => $this->address,
'label' => $this->label,
];
}

/**
* import this objects data from an array
*
* @since 33.0.0
*
* @param array array representation of this object
*/
public static function jsonDeserialize(array|string $data): static {
if (is_string($data)) {
$data = json_decode($data, true);
}
$address = $data['address'] ?? null;
$label = $data['label'] ?? null;

return new static($address, $label);
}

/**
* sets the mail address
*
Expand Down
40 changes: 39 additions & 1 deletion lib/public/Mail/Provider/Attachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*/
namespace OCP\Mail\Provider;

use JsonSerializable;
use OCP\Json\JsonDeserializable;

/**
* Mail Attachment Object
*
Expand All @@ -16,7 +19,7 @@
* @since 30.0.0
*
*/
class Attachment implements \OCP\Mail\Provider\IAttachment {
class Attachment implements IAttachment, JsonSerializable, JsonDeserializable {

/**
* initialize the mail attachment object
Expand All @@ -36,6 +39,41 @@ public function __construct(
) {
}

/**
* export this objects data as an array
*
* @since 33.0.0
*
* @return array representation of this object as an array
*/
public function jsonSerialize(): array {
return [
'contents' => base64_encode($this->contents ?? ''),
'name' => $this->name,
'type' => $this->type,
'embedded' => $this->embedded,
];
}

/**
* import this objects data from an array
*
* @since 33.0.0
*
* @param array array representation of this object
*/
public static function jsonDeserialize(array|string $data): static {
if (is_string($data)) {
$data = json_decode($data, true);
}
$contents = base64_decode($data['contents'] ?? '');
$name = $data['name'] ?? null;
$type = $data['type'] ?? null;
$embedded = $data['embedded'] ?? false;

return new static($contents, $name, $type, $embedded);
}

/**
* sets the attachment file name
*
Expand Down
60 changes: 59 additions & 1 deletion lib/public/Mail/Provider/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*/
namespace OCP\Mail\Provider;

use JsonSerializable;
use OCP\Json\JsonDeserializable;

/**
* Mail Message Object
*
Expand All @@ -16,7 +19,7 @@
* @since 30.0.0
*
*/
class Message implements \OCP\Mail\Provider\IMessage {
class Message implements IMessage, JsonSerializable, JsonDeserializable {

/**
* initialize the mail message object
Expand All @@ -30,6 +33,61 @@ public function __construct(
) {
}

/**
* export this objects data as an array
*
* @since 33.0.0
*
* @return array representation of this object as an array
*/
public function jsonSerialize(): array {
$data = $this->data;
$data['bodyHtml'] = base64_encode($this->data['bodyHtml'] ?? '');
$data['bodyPlain'] = base64_encode($this->data['bodyPlain'] ?? '');
$data['subject'] = base64_encode($this->data['subject'] ?? '');
return $data;
}

/**
* import this objects data from an array
*
* @since 33.0.0
*
* @param array array representation of this object
*/
public static function jsonDeserialize(array|string $data): static {
if (is_string($data)) {
$data = json_decode($data, true);
}
// decode encoded fields
$data['bodyHtml'] = base64_decode($data['bodyHtml'] ?? '');
$data['bodyPlain'] = base64_decode($data['bodyPlain'] ?? '');
$data['subject'] = base64_decode($data['subject'] ?? '');
// convert object fields
foreach (['from', 'replyTo'] as $field) {
if (isset($data[$field]) && is_array($data[$field])) {
$data[$field] = Address::jsonDeserialize($data[$field]);
} else {
$data[$field] = null;
}
}
foreach (['to', 'cc', 'bcc', 'attachments'] as $field) {
if (isset($data[$field]) && is_array($data[$field])) {
foreach ($data[$field] as $key => $item) {
if (is_array($item)) {
if ($field === 'attachments') {
$data[$field][$key] = Attachment::jsonDeserialize($item);
} else {
$data[$field][$key] = Address::jsonDeserialize($item);
}
}
}
}
}

return new static($data);
}

/**
* arbitrary unique text string identifying this message
*
Expand Down
20 changes: 20 additions & 0 deletions lib/public/TaskProcessing/EShapeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ enum EShapeType: int {
case Video = 4;
case File = 5;
case Enum = 6;
case Array = 7;
case Object = 8;
case ListOfNumbers = 10;
case ListOfTexts = 11;
case ListOfImages = 12;
Expand Down Expand Up @@ -72,6 +74,12 @@ private function validateNonFileType(mixed $value): void {
if ($this === EShapeType::ListOfNumbers && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) {
throw new ValidationException('Non-numeric list item provided for ListOfNumbers slot');
}
if ($this === EShapeType::Array && !is_array($value)) {
throw new ValidationException('Non-array item provided for Array slot');
}
if ($this === EShapeType::Object && !is_object($value)) {
throw new ValidationException('Non-object item provided for Object slot');
}
}

/**
Expand Down Expand Up @@ -109,6 +117,12 @@ public function validateInput(mixed $value): void {
if ($this === EShapeType::ListOfFiles && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) {
throw new ValidationException('Non-audio list item provided for ListOfFiles slot');
}
if ($this === EShapeType::Array && !is_array($value)) {
throw new ValidationException('Non-array item provided for Array slot');
}
if ($this === EShapeType::Object && !is_object($value)) {
throw new ValidationException('Non-object item provided for Object slot');
}
}

/**
Expand Down Expand Up @@ -175,6 +189,12 @@ public function validateOutputWithFileIds(mixed $value): void {
if ($this === EShapeType::ListOfFiles && (!is_array($value) || count(array_filter($value, fn ($item) => !is_numeric($item))) > 0)) {
throw new ValidationException('Non-audio list item provided for ListOfFiles slot');
}
if ($this === EShapeType::Array && !is_array($value)) {
throw new ValidationException('Non-array item provided for Array slot');
}
if ($this === EShapeType::Object && !is_object($value)) {
throw new ValidationException('Non-object item provided for Object slot');
}
}

/**
Expand Down
Loading