diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8e76abb5..7c45e579 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.0.0" + ".": "5.0.1" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 647de165..92aa6915 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 78 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-b79e0eb1ab06f4076c48fa519e2b2ad792a0c483a5d017e43c938ca4c4be6988.yml -openapi_spec_hash: cb3cc2c1145503e5737a880326857aa4 -config_hash: ff903e824043dc81aca51a0ce21896d6 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier%2Fcourier-e3e54d99e2a73fd87519270f2685131050d342e86a4e96130247b854deae5c20.yml +openapi_spec_hash: 897a3fbee24f24d021d6af0df480220c +config_hash: 66a5c28bb74d78454456d9ce7d1c0a0c diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bc42397..915c5397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 5.0.1 (2026-01-14) + +Full Changelog: [v5.0.0...v5.0.1](https://github.com/trycourier/courier-php/compare/v5.0.0...v5.0.1) + +### Bug Fixes + +* typos in README.md ([f1a033c](https://github.com/trycourier/courier-php/commit/f1a033c8c70d2a48f5fea41af512766957d97923)) + + +### Chores + +* fix typo in descriptions ([f46d067](https://github.com/trycourier/courier-php/commit/f46d067a4a66d5a94dde8f4c02621e917c665c32)) +* **internal:** codegen related update ([7b4fa3b](https://github.com/trycourier/courier-php/commit/7b4fa3ba45681760ac59e758fa94756246e343ae)) +* **internal:** codegen related update ([89591b8](https://github.com/trycourier/courier-php/commit/89591b8dd16a7b9c3f55abac64ad65fef05fb94e)) +* **internal:** regenerate SDK with no functional changes ([eb51446](https://github.com/trycourier/courier-php/commit/eb51446e6b4e8368d8e27053d3605d1b089fcac4)) +* **internal:** regenerate SDK with no functional changes ([bd1ea2c](https://github.com/trycourier/courier-php/commit/bd1ea2c50e9c8ddee9d51c7ed6e18e30e2dc5e27)) +* **readme:** remove beta warning now that we're in ga ([c3d5ef7](https://github.com/trycourier/courier-php/commit/c3d5ef7b9481b5c2762f28cff97610277eb2880f)) +* remove custom code ([5b4f359](https://github.com/trycourier/courier-php/commit/5b4f359ac6c2664b81c080dba20e8f6b54629ded)) + ## 5.0.0 (2026-01-12) Full Changelog: [v4.1.0...v5.0.0](https://github.com/trycourier/courier-php/compare/v4.1.0...v5.0.0) diff --git a/LICENSE b/LICENSE index efaa7fe8..ca8054ae 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2025 Courier + Copyright 2026 Courier Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index aef1dabc..8fe02645 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,5 @@ # Courier PHP API library -> [!NOTE] -> The Courier PHP API Library is currently in **beta** and we're excited for you to experiment with it! -> -> This library has not yet been exhaustively tested in production environments and may be missing some features you'd expect in a stable release. As we continue development, there may be breaking changes that require updates to your code. -> -> **We'd love your feedback!** Please share any suggestions, bug reports, feature requests, or general thoughts by [filing an issue](https://www.github.com/trycourier/courier-php/issues/new). - The Courier PHP library provides convenient access to the Courier REST API from any PHP 8.1.0+ application. It is generated with [Stainless](https://www.stainless.com/). @@ -75,6 +68,8 @@ When the library is unable to connect to the API, or if the API returns a non-su send->message( @@ -87,9 +82,9 @@ try { } catch (APIConnectionException $e) { echo "The server could not be reached", PHP_EOL; var_dump($e->getPrevious()); -} catch (RateLimitError $e) { +} catch (RateLimitException $e) { echo "A 429 status code was received; we should back off a bit.", PHP_EOL; -} catch (APIStatusError $e) { +} catch (APIStatusException $e) { echo "Another non-200-range status code was received", PHP_EOL; echo $e->getMessage(); } diff --git a/src/AudienceFilterConfig.php b/src/AudienceFilterConfig.php new file mode 100644 index 00000000..b270c62d --- /dev/null +++ b/src/AudienceFilterConfig.php @@ -0,0 +1,76 @@ +} + */ +final class AudienceFilterConfig implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Array of filter rules (single conditions or nested groups). + * + * @var list $filters + */ + #[Required(list: FilterConfig::class)] + public array $filters; + + /** + * `new AudienceFilterConfig()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * AudienceFilterConfig::with(filters: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new AudienceFilterConfig)->withFilters(...) + * ``` + */ + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list $filters + */ + public static function with(array $filters): self + { + $self = new self; + + $self['filters'] = $filters; + + return $self; + } + + /** + * Array of filter rules (single conditions or nested groups). + * + * @param list $filters + */ + public function withFilters(array $filters): self + { + $self = clone $this; + $self['filters'] = $filters; + + return $self; + } +} diff --git a/src/Audiences/Audience.php b/src/Audiences/Audience.php index 75d20234..36f8170d 100644 --- a/src/Audiences/Audience.php +++ b/src/Audiences/Audience.php @@ -4,21 +4,24 @@ namespace Courier\Audiences; +use Courier\AudienceFilterConfig; +use Courier\Audiences\Audience\Operator; +use Courier\Core\Attributes\Optional; use Courier\Core\Attributes\Required; use Courier\Core\Concerns\SdkModel; use Courier\Core\Contracts\BaseModel; /** - * @phpstan-import-type FilterVariants from \Courier\Audiences\Filter - * @phpstan-import-type FilterShape from \Courier\Audiences\Filter + * @phpstan-import-type AudienceFilterConfigShape from \Courier\AudienceFilterConfig * * @phpstan-type AudienceShape = array{ * id: string, * createdAt: string, * description: string, - * filter: FilterShape, * name: string, * updatedAt: string, + * filter?: null|AudienceFilterConfig|AudienceFilterConfigShape, + * operator?: null|Operator|value-of, * } */ final class Audience implements BaseModel @@ -41,14 +44,6 @@ final class Audience implements BaseModel #[Required] public string $description; - /** - * A single filter to use for filtering. - * - * @var FilterVariants $filter - */ - #[Required] - public SingleFilterConfig|NestedFilterConfig $filter; - /** * The name of the audience. */ @@ -58,18 +53,27 @@ final class Audience implements BaseModel #[Required('updated_at')] public string $updatedAt; + /** + * Filter configuration for audience membership containing an array of filter rules. + */ + #[Optional(nullable: true)] + public ?AudienceFilterConfig $filter; + + /** + * The logical operator (AND/OR) for the top-level filter. + * + * @var value-of|null $operator + */ + #[Optional(enum: Operator::class)] + public ?string $operator; + /** * `new Audience()` is missing required properties by the API. * * To enforce required parameters use * ``` * Audience::with( - * id: ..., - * createdAt: ..., - * description: ..., - * filter: ..., - * name: ..., - * updatedAt: ..., + * id: ..., createdAt: ..., description: ..., name: ..., updatedAt: ... * ) * ``` * @@ -80,7 +84,6 @@ final class Audience implements BaseModel * ->withID(...) * ->withCreatedAt(...) * ->withDescription(...) - * ->withFilter(...) * ->withName(...) * ->withUpdatedAt(...) * ``` @@ -95,25 +98,29 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param FilterShape $filter + * @param AudienceFilterConfig|AudienceFilterConfigShape|null $filter + * @param Operator|value-of|null $operator */ public static function with( string $id, string $createdAt, string $description, - SingleFilterConfig|array|NestedFilterConfig $filter, string $name, string $updatedAt, + AudienceFilterConfig|array|null $filter = null, + Operator|string|null $operator = null, ): self { $self = new self; $self['id'] = $id; $self['createdAt'] = $createdAt; $self['description'] = $description; - $self['filter'] = $filter; $self['name'] = $name; $self['updatedAt'] = $updatedAt; + null !== $filter && $self['filter'] = $filter; + null !== $operator && $self['operator'] = $operator; + return $self; } @@ -148,34 +155,46 @@ public function withDescription(string $description): self } /** - * A single filter to use for filtering. - * - * @param FilterShape $filter + * The name of the audience. */ - public function withFilter( - SingleFilterConfig|array|NestedFilterConfig $filter - ): self { + public function withName(string $name): self + { $self = clone $this; - $self['filter'] = $filter; + $self['name'] = $name; + + return $self; + } + + public function withUpdatedAt(string $updatedAt): self + { + $self = clone $this; + $self['updatedAt'] = $updatedAt; return $self; } /** - * The name of the audience. + * Filter configuration for audience membership containing an array of filter rules. + * + * @param AudienceFilterConfig|AudienceFilterConfigShape|null $filter */ - public function withName(string $name): self + public function withFilter(AudienceFilterConfig|array|null $filter): self { $self = clone $this; - $self['name'] = $name; + $self['filter'] = $filter; return $self; } - public function withUpdatedAt(string $updatedAt): self + /** + * The logical operator (AND/OR) for the top-level filter. + * + * @param Operator|value-of $operator + */ + public function withOperator(Operator|string $operator): self { $self = clone $this; - $self['updatedAt'] = $updatedAt; + $self['operator'] = $operator; return $self; } diff --git a/src/Audiences/Audience/Operator.php b/src/Audiences/Audience/Operator.php new file mode 100644 index 00000000..83ef3f36 --- /dev/null +++ b/src/Audiences/Audience/Operator.php @@ -0,0 +1,15 @@ +, * } */ final class AudienceUpdateParams implements BaseModel @@ -34,12 +38,10 @@ final class AudienceUpdateParams implements BaseModel public ?string $description; /** - * A single filter to use for filtering. - * - * @var FilterVariants|null $filter + * Filter configuration for audience membership containing an array of filter rules. */ #[Optional(nullable: true)] - public SingleFilterConfig|NestedFilterConfig|null $filter; + public ?AudienceFilterConfig $filter; /** * The name of the audience. @@ -47,6 +49,14 @@ final class AudienceUpdateParams implements BaseModel #[Optional(nullable: true)] public ?string $name; + /** + * The logical operator (AND/OR) for the top-level filter. + * + * @var value-of|null $operator + */ + #[Optional(enum: Operator::class, nullable: true)] + public ?string $operator; + public function __construct() { $this->initialize(); @@ -57,18 +67,21 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param FilterShape|null $filter + * @param AudienceFilterConfig|AudienceFilterConfigShape|null $filter + * @param Operator|value-of|null $operator */ public static function with( ?string $description = null, - SingleFilterConfig|array|NestedFilterConfig|null $filter = null, + AudienceFilterConfig|array|null $filter = null, ?string $name = null, + Operator|string|null $operator = null, ): self { $self = new self; null !== $description && $self['description'] = $description; null !== $filter && $self['filter'] = $filter; null !== $name && $self['name'] = $name; + null !== $operator && $self['operator'] = $operator; return $self; } @@ -85,13 +98,12 @@ public function withDescription(?string $description): self } /** - * A single filter to use for filtering. + * Filter configuration for audience membership containing an array of filter rules. * - * @param FilterShape|null $filter + * @param AudienceFilterConfig|AudienceFilterConfigShape|null $filter */ - public function withFilter( - SingleFilterConfig|array|NestedFilterConfig|null $filter - ): self { + public function withFilter(AudienceFilterConfig|array|null $filter): self + { $self = clone $this; $self['filter'] = $filter; @@ -108,4 +120,17 @@ public function withName(?string $name): self return $self; } + + /** + * The logical operator (AND/OR) for the top-level filter. + * + * @param Operator|value-of|null $operator + */ + public function withOperator(Operator|string|null $operator): self + { + $self = clone $this; + $self['operator'] = $operator; + + return $self; + } } diff --git a/src/Audiences/AudienceUpdateParams/Operator.php b/src/Audiences/AudienceUpdateParams/Operator.php new file mode 100644 index 00000000..e59ccb3f --- /dev/null +++ b/src/Audiences/AudienceUpdateParams/Operator.php @@ -0,0 +1,15 @@ +|array - */ - public static function variants(): array - { - return [SingleFilterConfig::class, NestedFilterConfig::class]; - } -} diff --git a/src/Audiences/NestedFilterConfig.php b/src/Audiences/NestedFilterConfig.php deleted file mode 100644 index fbe754ce..00000000 --- a/src/Audiences/NestedFilterConfig.php +++ /dev/null @@ -1,94 +0,0 @@ -, rules: list - * } - */ -final class NestedFilterConfig implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * The operator to use for filtering. - * - * @var value-of $operator - */ - #[Required(enum: Operator::class)] - public string $operator; - - /** @var list $rules */ - #[Required(list: Filter::class)] - public array $rules; - - /** - * `new NestedFilterConfig()` is missing required properties by the API. - * - * To enforce required parameters use - * ``` - * NestedFilterConfig::with(operator: ..., rules: ...) - * ``` - * - * Otherwise ensure the following setters are called - * - * ``` - * (new NestedFilterConfig)->withOperator(...)->withRules(...) - * ``` - */ - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - * - * @param Operator|value-of $operator - * @param list $rules - */ - public static function with(Operator|string $operator, array $rules): self - { - $self = new self; - - $self['operator'] = $operator; - $self['rules'] = $rules; - - return $self; - } - - /** - * The operator to use for filtering. - * - * @param Operator|value-of $operator - */ - public function withOperator(Operator|string $operator): self - { - $self = clone $this; - $self['operator'] = $operator; - - return $self; - } - - /** - * @param list $rules - */ - public function withRules(array $rules): self - { - $self = clone $this; - $self['rules'] = $rules; - - return $self; - } -} diff --git a/src/Audiences/NestedFilterConfig/Operator.php b/src/Audiences/NestedFilterConfig/Operator.php deleted file mode 100644 index 8f63b980..00000000 --- a/src/Audiences/NestedFilterConfig/Operator.php +++ /dev/null @@ -1,41 +0,0 @@ -, path: string, value: string - * } - */ -final class SingleFilterConfig implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * The operator to use for filtering. - * - * @var value-of $operator - */ - #[Required(enum: Operator::class)] - public string $operator; - - /** - * The attribute name from profile whose value will be operated against the filter value. - */ - #[Required] - public string $path; - - /** - * The value to use for filtering. - */ - #[Required] - public string $value; - - /** - * `new SingleFilterConfig()` is missing required properties by the API. - * - * To enforce required parameters use - * ``` - * SingleFilterConfig::with(operator: ..., path: ..., value: ...) - * ``` - * - * Otherwise ensure the following setters are called - * - * ``` - * (new SingleFilterConfig)->withOperator(...)->withPath(...)->withValue(...) - * ``` - */ - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - * - * @param Operator|value-of $operator - */ - public static function with( - Operator|string $operator, - string $path, - string $value - ): self { - $self = new self; - - $self['operator'] = $operator; - $self['path'] = $path; - $self['value'] = $value; - - return $self; - } - - /** - * The operator to use for filtering. - * - * @param Operator|value-of $operator - */ - public function withOperator(Operator|string $operator): self - { - $self = clone $this; - $self['operator'] = $operator; - - return $self; - } - - /** - * The attribute name from profile whose value will be operated against the filter value. - */ - public function withPath(string $path): self - { - $self = clone $this; - $self['path'] = $path; - - return $self; - } - - /** - * The value to use for filtering. - */ - public function withValue(string $value): self - { - $self = clone $this; - $self['value'] = $value; - - return $self; - } -} diff --git a/src/Audiences/SingleFilterConfig/Operator.php b/src/Audiences/SingleFilterConfig/Operator.php deleted file mode 100644 index 547d7d0a..00000000 --- a/src/Audiences/SingleFilterConfig/Operator.php +++ /dev/null @@ -1,41 +0,0 @@ - 'application/json', 'Accept' => 'application/json', - 'User-Agent' => sprintf('Courier/PHP %s', '3.3.0'), + 'User-Agent' => sprintf('Courier/PHP %s', VERSION), 'X-Stainless-Lang' => 'php', - 'X-Stainless-Package-Version' => '3.3.0', - 'X-Stainless-OS' => $this->getNormalizedOS(), - 'X-Stainless-Arch' => $this->getNormalizedArchitecture(), - 'X-Stainless-Runtime' => 'php', + 'X-Stainless-Package-Version' => '5.0.0', + 'X-Stainless-Arch' => Util::machtype(), + 'X-Stainless-OS' => Util::ostype(), + 'X-Stainless-Runtime' => php_sapi_name(), 'X-Stainless-Runtime-Version' => phpversion(), ], baseUrl: $baseUrl, diff --git a/src/ElementalChannelNode.php b/src/ElementalChannelNode.php index e78d400a..3eb59d47 100644 --- a/src/ElementalChannelNode.php +++ b/src/ElementalChannelNode.php @@ -5,7 +5,6 @@ namespace Courier; use Courier\Core\Attributes\Optional; -use Courier\Core\Attributes\Required; use Courier\Core\Concerns\SdkModel; use Courier\Core\Contracts\BaseModel; @@ -24,7 +23,7 @@ * if?: string|null, * loop?: string|null, * ref?: string|null, - * channel: string, + * channel?: string|null, * raw?: array|null, * } */ @@ -50,8 +49,8 @@ final class ElementalChannelNode implements BaseModel * The channel the contents of this element should be applied to. Can be `email`, * `push`, `direct_message`, `sms` or a provider such as slack. */ - #[Required] - public string $channel; + #[Optional] + public ?string $channel; /** * Raw data to apply to the channel. If `elements` has not been specified, `raw` is required. @@ -61,20 +60,6 @@ final class ElementalChannelNode implements BaseModel #[Optional(map: 'mixed', nullable: true)] public ?array $raw; - /** - * `new ElementalChannelNode()` is missing required properties by the API. - * - * To enforce required parameters use - * ``` - * ElementalChannelNode::with(channel: ...) - * ``` - * - * Otherwise ensure the following setters are called - * - * ``` - * (new ElementalChannelNode)->withChannel(...) - * ``` - */ public function __construct() { $this->initialize(); @@ -89,21 +74,20 @@ public function __construct() * @param array|null $raw */ public static function with( - string $channel, ?array $channels = null, ?string $if = null, ?string $loop = null, ?string $ref = null, + ?string $channel = null, ?array $raw = null, ): self { $self = new self; - $self['channel'] = $channel; - null !== $channels && $self['channels'] = $channels; null !== $if && $self['if'] = $if; null !== $loop && $self['loop'] = $loop; null !== $ref && $self['ref'] = $ref; + null !== $channel && $self['channel'] = $channel; null !== $raw && $self['raw'] = $raw; return $self; diff --git a/src/ElementalChannelNodeWithType.php b/src/ElementalChannelNodeWithType.php index 9e043adb..18c66d8d 100644 --- a/src/ElementalChannelNodeWithType.php +++ b/src/ElementalChannelNodeWithType.php @@ -5,7 +5,6 @@ namespace Courier; use Courier\Core\Attributes\Optional; -use Courier\Core\Attributes\Required; use Courier\Core\Concerns\SdkModel; use Courier\Core\Contracts\BaseModel; use Courier\ElementalChannelNodeWithType\Type; @@ -25,7 +24,7 @@ * if?: string|null, * loop?: string|null, * ref?: string|null, - * channel: string, + * channel?: string|null, * raw?: array|null, * type?: null|Type|value-of, * } @@ -52,8 +51,8 @@ final class ElementalChannelNodeWithType implements BaseModel * The channel the contents of this element should be applied to. Can be `email`, * `push`, `direct_message`, `sms` or a provider such as slack. */ - #[Required] - public string $channel; + #[Optional] + public ?string $channel; /** * Raw data to apply to the channel. If `elements` has not been specified, `raw` is required. @@ -67,20 +66,6 @@ final class ElementalChannelNodeWithType implements BaseModel #[Optional(enum: Type::class)] public ?string $type; - /** - * `new ElementalChannelNodeWithType()` is missing required properties by the API. - * - * To enforce required parameters use - * ``` - * ElementalChannelNodeWithType::with(channel: ...) - * ``` - * - * Otherwise ensure the following setters are called - * - * ``` - * (new ElementalChannelNodeWithType)->withChannel(...) - * ``` - */ public function __construct() { $this->initialize(); @@ -96,22 +81,21 @@ public function __construct() * @param Type|value-of|null $type */ public static function with( - string $channel, ?array $channels = null, ?string $if = null, ?string $loop = null, ?string $ref = null, + ?string $channel = null, ?array $raw = null, Type|string|null $type = null, ): self { $self = new self; - $self['channel'] = $channel; - null !== $channels && $self['channels'] = $channels; null !== $if && $self['if'] = $if; null !== $loop && $self['loop'] = $loop; null !== $ref && $self['ref'] = $ref; + null !== $channel && $self['channel'] = $channel; null !== $raw && $self['raw'] = $raw; null !== $type && $self['type'] = $type; diff --git a/src/FilterConfig.php b/src/FilterConfig.php new file mode 100644 index 00000000..12131a71 --- /dev/null +++ b/src/FilterConfig.php @@ -0,0 +1,141 @@ +|null, + * path?: string|null, + * value?: string|null, + * } + */ +final class FilterConfig implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * The operator for this filter. Use comparison operators (EQ, GT, LT, GTE, LTE, NEQ, EXISTS, INCLUDES, STARTS_WITH, ENDS_WITH, IS_BEFORE, IS_AFTER, OMIT) for single conditions, or logical operators (AND, OR) for nested filter groups. + */ + #[Required] + public string $operator; + + /** + * Nested filter rules to combine with AND/OR. Required for nested filter groups, not used for single filter conditions. + * + * @var list|null $filters + */ + #[Optional(list: FilterConfig::class)] + public ?array $filters; + + /** + * The attribute path from the user profile to filter on. Required for single filter conditions, not used for nested filter groups. + */ + #[Optional] + public ?string $path; + + /** + * The value to compare against. Required for single filter conditions, not used for nested filter groups. + */ + #[Optional] + public ?string $value; + + /** + * `new FilterConfig()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * FilterConfig::with(operator: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new FilterConfig)->withOperator(...) + * ``` + */ + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list|null $filters + */ + public static function with( + string $operator, + ?array $filters = null, + ?string $path = null, + ?string $value = null, + ): self { + $self = new self; + + $self['operator'] = $operator; + + null !== $filters && $self['filters'] = $filters; + null !== $path && $self['path'] = $path; + null !== $value && $self['value'] = $value; + + return $self; + } + + /** + * The operator for this filter. Use comparison operators (EQ, GT, LT, GTE, LTE, NEQ, EXISTS, INCLUDES, STARTS_WITH, ENDS_WITH, IS_BEFORE, IS_AFTER, OMIT) for single conditions, or logical operators (AND, OR) for nested filter groups. + */ + public function withOperator(string $operator): self + { + $self = clone $this; + $self['operator'] = $operator; + + return $self; + } + + /** + * Nested filter rules to combine with AND/OR. Required for nested filter groups, not used for single filter conditions. + * + * @param list $filters + */ + public function withFilters(array $filters): self + { + $self = clone $this; + $self['filters'] = $filters; + + return $self; + } + + /** + * The attribute path from the user profile to filter on. Required for single filter conditions, not used for nested filter groups. + */ + public function withPath(string $path): self + { + $self = clone $this; + $self['path'] = $path; + + return $self; + } + + /** + * The value to compare against. Required for single filter conditions, not used for nested filter groups. + */ + public function withValue(string $value): self + { + $self = clone $this; + $self['value'] = $value; + + return $self; + } +} diff --git a/src/ServiceContracts/AudiencesContract.php b/src/ServiceContracts/AudiencesContract.php index 9a96325d..a07e25d1 100644 --- a/src/ServiceContracts/AudiencesContract.php +++ b/src/ServiceContracts/AudiencesContract.php @@ -4,17 +4,17 @@ namespace Courier\ServiceContracts; +use Courier\AudienceFilterConfig; use Courier\Audiences\Audience; use Courier\Audiences\AudienceListMembersResponse; use Courier\Audiences\AudienceListResponse; +use Courier\Audiences\AudienceUpdateParams\Operator; use Courier\Audiences\AudienceUpdateResponse; -use Courier\Audiences\NestedFilterConfig; -use Courier\Audiences\SingleFilterConfig; use Courier\Core\Exceptions\APIException; use Courier\RequestOptions; /** - * @phpstan-import-type FilterShape from \Courier\Audiences\Filter + * @phpstan-import-type AudienceFilterConfigShape from \Courier\AudienceFilterConfig * @phpstan-import-type RequestOpts from \Courier\RequestOptions */ interface AudiencesContract @@ -37,8 +37,9 @@ public function retrieve( * * @param string $audienceID A unique identifier representing the audience id * @param string|null $description A description of the audience - * @param FilterShape|null $filter A single filter to use for filtering + * @param AudienceFilterConfig|AudienceFilterConfigShape|null $filter Filter configuration for audience membership containing an array of filter rules * @param string|null $name The name of the audience + * @param Operator|value-of|null $operator The logical operator (AND/OR) for the top-level filter * @param RequestOpts|null $requestOptions * * @throws APIException @@ -46,8 +47,9 @@ public function retrieve( public function update( string $audienceID, ?string $description = null, - SingleFilterConfig|array|NestedFilterConfig|null $filter = null, + AudienceFilterConfig|array|null $filter = null, ?string $name = null, + Operator|string|null $operator = null, RequestOptions|array|null $requestOptions = null, ): AudienceUpdateResponse; diff --git a/src/ServiceContracts/Lists/SubscriptionsContract.php b/src/ServiceContracts/Lists/SubscriptionsContract.php index 6fb975a7..6fbfab5c 100644 --- a/src/ServiceContracts/Lists/SubscriptionsContract.php +++ b/src/ServiceContracts/Lists/SubscriptionsContract.php @@ -67,7 +67,7 @@ public function subscribe( * * @param string $userID Path param: A unique identifier representing the recipient associated with the list * @param string $listID path param: A unique identifier representing the list you wish to retrieve - * @param RecipientPreferences|RecipientPreferencesShape|null $preferences Body param: + * @param RecipientPreferences|RecipientPreferencesShape|null $preferences Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/ServiceContracts/Notifications/ChecksContract.php b/src/ServiceContracts/Notifications/ChecksContract.php index 13db46e0..be12b121 100644 --- a/src/ServiceContracts/Notifications/ChecksContract.php +++ b/src/ServiceContracts/Notifications/ChecksContract.php @@ -19,9 +19,9 @@ interface ChecksContract /** * @api * - * @param string $submissionID Path param: - * @param string $id Path param: - * @param list $checks Body param: + * @param string $submissionID Path param + * @param string $id Path param + * @param list $checks Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/ServiceContracts/Notifications/ChecksRawContract.php b/src/ServiceContracts/Notifications/ChecksRawContract.php index c184fdba..1f607532 100644 --- a/src/ServiceContracts/Notifications/ChecksRawContract.php +++ b/src/ServiceContracts/Notifications/ChecksRawContract.php @@ -21,7 +21,7 @@ interface ChecksRawContract /** * @api * - * @param string $submissionID Path param: + * @param string $submissionID Path param * @param array|CheckUpdateParams $params * @param RequestOpts|null $requestOptions * diff --git a/src/ServiceContracts/Tenants/Preferences/ItemsContract.php b/src/ServiceContracts/Tenants/Preferences/ItemsContract.php index d43fe33c..8299439d 100644 --- a/src/ServiceContracts/Tenants/Preferences/ItemsContract.php +++ b/src/ServiceContracts/Tenants/Preferences/ItemsContract.php @@ -19,7 +19,7 @@ interface ItemsContract * * @param string $topicID path param: Id of the subscription topic you want to have a default preference for * @param string $tenantID path param: Id of the tenant to update the default preferences for - * @param Status|value-of $status Body param: + * @param Status|value-of $status Body param * @param list>|null $customRouting Body param: The default channels to send to this tenant when has_custom_routing is enabled * @param bool|null $hasCustomRouting Body param: Override channel routing with custom preferences. This will override any template preferences that are set, but a user can still customize their preferences * @param RequestOpts|null $requestOptions diff --git a/src/ServiceContracts/TranslationsContract.php b/src/ServiceContracts/TranslationsContract.php index 06adfcf3..ed786999 100644 --- a/src/ServiceContracts/TranslationsContract.php +++ b/src/ServiceContracts/TranslationsContract.php @@ -32,7 +32,7 @@ public function retrieve( * * @param string $locale Path param: The locale you want to retrieve the translations for * @param string $domain Path param: The domain you want to retrieve translations for. Only `default` is supported at the moment - * @param string $body Body param: + * @param string $body Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/ServiceContracts/Users/PreferencesContract.php b/src/ServiceContracts/Users/PreferencesContract.php index e31dc184..4b2acf8b 100644 --- a/src/ServiceContracts/Users/PreferencesContract.php +++ b/src/ServiceContracts/Users/PreferencesContract.php @@ -54,7 +54,7 @@ public function retrieveTopic( * * @param string $topicID path param: A unique identifier associated with a subscription topic * @param string $userID path param: A unique identifier associated with the user whose preferences you wish to retrieve - * @param Topic|TopicShape $topic Body param: + * @param Topic|TopicShape $topic Body param * @param string|null $tenantID query param: Update the preferences of a user for this specific tenant context * @param RequestOpts|null $requestOptions * diff --git a/src/ServiceContracts/Users/TenantsContract.php b/src/ServiceContracts/Users/TenantsContract.php index 263b4e74..0284a75a 100644 --- a/src/ServiceContracts/Users/TenantsContract.php +++ b/src/ServiceContracts/Users/TenantsContract.php @@ -53,7 +53,7 @@ public function addMultiple( * * @param string $tenantID path param: Id of the tenant the user should be added to * @param string $userID path param: Id of the user to be added to the supplied tenant - * @param array|null $profile Body param: + * @param array|null $profile Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/ServiceContracts/Users/TokensContract.php b/src/ServiceContracts/Users/TokensContract.php index 6928179c..d10f9091 100644 --- a/src/ServiceContracts/Users/TokensContract.php +++ b/src/ServiceContracts/Users/TokensContract.php @@ -42,7 +42,7 @@ public function retrieve( * * @param string $token path param: The full token string * @param string $userID Path param: The user's ID. This can be any uniquely identifiable string. - * @param list $patch Body param: + * @param list $patch Body param * @param RequestOpts|null $requestOptions * * @throws APIException @@ -101,7 +101,7 @@ public function addMultiple( * @param string $token_ path param: The full token string * @param string $userID Path param: The user's ID. This can be any uniquely identifiable string. * @param string $token Body param: Full body of the token. Must match token in URL path parameter. - * @param ProviderKey|value-of $providerKey Body param: + * @param ProviderKey|value-of $providerKey Body param * @param Device|DeviceShape|null $device body param: Information about the device the token came from * @param ExpiryDateShape|null $expiryDate Body param: ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to disable expiration. * @param mixed $properties body param: Properties about the token diff --git a/src/Services/AudiencesRawService.php b/src/Services/AudiencesRawService.php index 65c502b3..c3901b2e 100644 --- a/src/Services/AudiencesRawService.php +++ b/src/Services/AudiencesRawService.php @@ -4,12 +4,14 @@ namespace Courier\Services; +use Courier\AudienceFilterConfig; use Courier\Audiences\Audience; use Courier\Audiences\AudienceListMembersParams; use Courier\Audiences\AudienceListMembersResponse; use Courier\Audiences\AudienceListParams; use Courier\Audiences\AudienceListResponse; use Courier\Audiences\AudienceUpdateParams; +use Courier\Audiences\AudienceUpdateParams\Operator; use Courier\Audiences\AudienceUpdateResponse; use Courier\Client; use Courier\Core\Contracts\BaseResponse; @@ -18,7 +20,7 @@ use Courier\ServiceContracts\AudiencesRawContract; /** - * @phpstan-import-type FilterShape from \Courier\Audiences\Filter + * @phpstan-import-type AudienceFilterConfigShape from \Courier\AudienceFilterConfig * @phpstan-import-type RequestOpts from \Courier\RequestOptions */ final class AudiencesRawService implements AudiencesRawContract @@ -61,7 +63,10 @@ public function retrieve( * * @param string $audienceID A unique identifier representing the audience id * @param array{ - * description?: string|null, filter?: FilterShape|null, name?: string|null + * description?: string|null, + * filter?: AudienceFilterConfig|AudienceFilterConfigShape|null, + * name?: string|null, + * operator?: Operator|value-of|null, * }|AudienceUpdateParams $params * @param RequestOpts|null $requestOptions * diff --git a/src/Services/AudiencesService.php b/src/Services/AudiencesService.php index 5fe6bf8d..68ce0908 100644 --- a/src/Services/AudiencesService.php +++ b/src/Services/AudiencesService.php @@ -4,12 +4,12 @@ namespace Courier\Services; +use Courier\AudienceFilterConfig; use Courier\Audiences\Audience; use Courier\Audiences\AudienceListMembersResponse; use Courier\Audiences\AudienceListResponse; +use Courier\Audiences\AudienceUpdateParams\Operator; use Courier\Audiences\AudienceUpdateResponse; -use Courier\Audiences\NestedFilterConfig; -use Courier\Audiences\SingleFilterConfig; use Courier\Client; use Courier\Core\Exceptions\APIException; use Courier\Core\Util; @@ -17,7 +17,7 @@ use Courier\ServiceContracts\AudiencesContract; /** - * @phpstan-import-type FilterShape from \Courier\Audiences\Filter + * @phpstan-import-type AudienceFilterConfigShape from \Courier\AudienceFilterConfig * @phpstan-import-type RequestOpts from \Courier\RequestOptions */ final class AudiencesService implements AudiencesContract @@ -62,8 +62,9 @@ public function retrieve( * * @param string $audienceID A unique identifier representing the audience id * @param string|null $description A description of the audience - * @param FilterShape|null $filter A single filter to use for filtering + * @param AudienceFilterConfig|AudienceFilterConfigShape|null $filter Filter configuration for audience membership containing an array of filter rules * @param string|null $name The name of the audience + * @param Operator|value-of|null $operator The logical operator (AND/OR) for the top-level filter * @param RequestOpts|null $requestOptions * * @throws APIException @@ -71,12 +72,18 @@ public function retrieve( public function update( string $audienceID, ?string $description = null, - SingleFilterConfig|array|NestedFilterConfig|null $filter = null, + AudienceFilterConfig|array|null $filter = null, ?string $name = null, + Operator|string|null $operator = null, RequestOptions|array|null $requestOptions = null, ): AudienceUpdateResponse { $params = Util::removeNulls( - ['description' => $description, 'filter' => $filter, 'name' => $name] + [ + 'description' => $description, + 'filter' => $filter, + 'name' => $name, + 'operator' => $operator, + ], ); // @phpstan-ignore-next-line argument.type diff --git a/src/Services/Lists/SubscriptionsService.php b/src/Services/Lists/SubscriptionsService.php index 5eafa7a2..7346a6a9 100644 --- a/src/Services/Lists/SubscriptionsService.php +++ b/src/Services/Lists/SubscriptionsService.php @@ -112,7 +112,7 @@ public function subscribe( * * @param string $userID Path param: A unique identifier representing the recipient associated with the list * @param string $listID path param: A unique identifier representing the list you wish to retrieve - * @param RecipientPreferences|RecipientPreferencesShape|null $preferences Body param: + * @param RecipientPreferences|RecipientPreferencesShape|null $preferences Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/Services/Notifications/ChecksRawService.php b/src/Services/Notifications/ChecksRawService.php index 4f911d37..860c6efe 100644 --- a/src/Services/Notifications/ChecksRawService.php +++ b/src/Services/Notifications/ChecksRawService.php @@ -31,7 +31,7 @@ public function __construct(private Client $client) {} /** * @api * - * @param string $submissionID Path param: + * @param string $submissionID Path param * @param array{ * id: string, checks: list * }|CheckUpdateParams $params diff --git a/src/Services/Notifications/ChecksService.php b/src/Services/Notifications/ChecksService.php index c711f056..9d7166dc 100644 --- a/src/Services/Notifications/ChecksService.php +++ b/src/Services/Notifications/ChecksService.php @@ -35,9 +35,9 @@ public function __construct(private Client $client) /** * @api * - * @param string $submissionID Path param: - * @param string $id Path param: - * @param list $checks Body param: + * @param string $submissionID Path param + * @param string $id Path param + * @param list $checks Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/Services/Tenants/Preferences/ItemsService.php b/src/Services/Tenants/Preferences/ItemsService.php index 8a0333f7..efa6bf05 100644 --- a/src/Services/Tenants/Preferences/ItemsService.php +++ b/src/Services/Tenants/Preferences/ItemsService.php @@ -37,7 +37,7 @@ public function __construct(private Client $client) * * @param string $topicID path param: Id of the subscription topic you want to have a default preference for * @param string $tenantID path param: Id of the tenant to update the default preferences for - * @param Status|value-of $status Body param: + * @param Status|value-of $status Body param * @param list>|null $customRouting Body param: The default channels to send to this tenant when has_custom_routing is enabled * @param bool|null $hasCustomRouting Body param: Override channel routing with custom preferences. This will override any template preferences that are set, but a user can still customize their preferences * @param RequestOpts|null $requestOptions diff --git a/src/Services/TranslationsService.php b/src/Services/TranslationsService.php index 66d98949..188a1a02 100644 --- a/src/Services/TranslationsService.php +++ b/src/Services/TranslationsService.php @@ -59,7 +59,7 @@ public function retrieve( * * @param string $locale Path param: The locale you want to retrieve the translations for * @param string $domain Path param: The domain you want to retrieve translations for. Only `default` is supported at the moment - * @param string $body Body param: + * @param string $body Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/Services/Users/PreferencesService.php b/src/Services/Users/PreferencesService.php index d807ad9a..2741d91e 100644 --- a/src/Services/Users/PreferencesService.php +++ b/src/Services/Users/PreferencesService.php @@ -90,7 +90,7 @@ public function retrieveTopic( * * @param string $topicID path param: A unique identifier associated with a subscription topic * @param string $userID path param: A unique identifier associated with the user whose preferences you wish to retrieve - * @param Topic|TopicShape $topic Body param: + * @param Topic|TopicShape $topic Body param * @param string|null $tenantID query param: Update the preferences of a user for this specific tenant context * @param RequestOpts|null $requestOptions * diff --git a/src/Services/Users/TenantsService.php b/src/Services/Users/TenantsService.php index 4d72bcf9..09d5d8ae 100644 --- a/src/Services/Users/TenantsService.php +++ b/src/Services/Users/TenantsService.php @@ -97,7 +97,7 @@ public function addMultiple( * * @param string $tenantID path param: Id of the tenant the user should be added to * @param string $userID path param: Id of the user to be added to the supplied tenant - * @param array|null $profile Body param: + * @param array|null $profile Body param * @param RequestOpts|null $requestOptions * * @throws APIException diff --git a/src/Services/Users/TokensService.php b/src/Services/Users/TokensService.php index e2f859bc..4f217b11 100644 --- a/src/Services/Users/TokensService.php +++ b/src/Services/Users/TokensService.php @@ -69,7 +69,7 @@ public function retrieve( * * @param string $token path param: The full token string * @param string $userID Path param: The user's ID. This can be any uniquely identifiable string. - * @param list $patch Body param: + * @param list $patch Body param * @param RequestOpts|null $requestOptions * * @throws APIException @@ -160,7 +160,7 @@ public function addMultiple( * @param string $token_ path param: The full token string * @param string $userID Path param: The user's ID. This can be any uniquely identifiable string. * @param string $token Body param: Full body of the token. Must match token in URL path parameter. - * @param ProviderKey|value-of $providerKey Body param: + * @param ProviderKey|value-of $providerKey Body param * @param Device|DeviceShape|null $device body param: Information about the device the token came from * @param ExpiryDateShape|null $expiryDate Body param: ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to disable expiration. * @param mixed $properties body param: Properties about the token diff --git a/src/Version.php b/src/Version.php index 71682d0b..8c020cae 100644 --- a/src/Version.php +++ b/src/Version.php @@ -5,5 +5,5 @@ namespace Courier; // x-release-please-start-version -const VERSION = '5.0.0'; +const VERSION = '5.0.1'; // x-release-please-end