├── hooks
├── .gitkeep
├── DDTrace
│ ├── .gitignore
│ ├── examples
│ │ ├── .gitignore
│ │ └── AutoloadDDTrace
│ │ │ ├── README.md
│ │ │ ├── composer.json
│ │ │ └── src
│ │ │ └── main.php
│ ├── psalm-baseline.xml
│ ├── src
│ │ ├── _autoload.php
│ │ └── DDTraceHook.php
│ ├── phpstan.neon.dist
│ ├── psalm.xml
│ ├── tests
│ │ ├── unit
│ │ │ └── DDTraceHookTest.php
│ │ ├── TestCase.php
│ │ └── integration
│ │ │ └── DDTraceHookTest.php
│ ├── phpunit.xml.dist
│ ├── phpcs.xml.dist
│ ├── CHANGELOG.md
│ └── README.md
├── OpenTelemetry
│ ├── .gitignore
│ ├── examples
│ │ ├── .gitignore
│ │ ├── AutoloadOTelSDK
│ │ │ ├── README.md
│ │ │ ├── composer.json
│ │ │ └── src
│ │ │ │ └── main.php
│ │ └── OTelManualInstrumentation
│ │ │ ├── README.md
│ │ │ └── composer.json
│ ├── psalm-baseline.xml
│ ├── src
│ │ ├── _autoload.php
│ │ ├── TracerHelper.php
│ │ └── OpenTelemetryHook.php
│ ├── phpstan.neon.dist
│ ├── psalm.xml
│ ├── tests
│ │ ├── unit
│ │ │ └── OpenTelemetryHookTest.php
│ │ ├── TestCase.php
│ │ └── integration
│ │ │ └── OpenTelemetryHookTest.php
│ ├── CHANGELOG.md
│ ├── phpunit.xml.dist
│ ├── phpcs.xml.dist
│ └── README.md
└── Validators
│ ├── .gitignore
│ ├── examples
│ ├── .gitignore
│ └── ExampleRegexpValidators
│ │ ├── README.md
│ │ ├── composer.json
│ │ └── src
│ │ └── main.php
│ ├── psalm-baseline.xml
│ ├── phpstan.neon.dist
│ ├── src
│ ├── Exceptions
│ │ └── ValidationException.php
│ └── Regexp
│ │ ├── InvalidRegularExpressionException.php
│ │ └── RegexpValidatorHook.php
│ ├── tests
│ ├── integration
│ │ └── RegexpValidatorHookTest.php
│ ├── TestCase.php
│ └── unit
│ │ └── RegexpValidatorHookTest.php
│ ├── psalm.xml
│ ├── phpunit.xml.dist
│ ├── CHANGELOG.md
│ ├── phpcs.xml.dist
│ ├── README.md
│ └── composer.json
├── providers
├── .gitkeep
├── Flagd
│ ├── .gitignore
│ ├── examples
│ │ ├── .gitignore
│ │ └── Http
│ │ │ ├── README.md
│ │ │ ├── composer.json
│ │ │ └── src
│ │ │ └── main.php
│ ├── proto
│ │ ├── README.md
│ │ └── php
│ │ │ ├── GPBMetadata
│ │ │ └── Schema
│ │ │ │ └── V1
│ │ │ │ └── Schema.php
│ │ │ └── Schema
│ │ │ └── V1
│ │ │ ├── ResolveIntRequest.php
│ │ │ ├── ResolveFloatRequest.php
│ │ │ ├── ResolveObjectRequest.php
│ │ │ ├── ResolveStringRequest.php
│ │ │ ├── ResolveBooleanRequest.php
│ │ │ ├── ServiceClient.php
│ │ │ ├── EventStreamResponse.php
│ │ │ ├── ResolveIntResponse.php
│ │ │ ├── ResolveFloatResponse.php
│ │ │ ├── ResolveBooleanResponse.php
│ │ │ └── ResolveStringResponse.php
│ ├── psalm-baseline.xml
│ ├── src
│ │ ├── errors
│ │ │ ├── InvalidConfigException.php
│ │ │ ├── InvalidTypeException.php
│ │ │ └── RequestBuildException.php
│ │ ├── config
│ │ │ ├── Protocols.php
│ │ │ ├── Defaults.php
│ │ │ ├── IConfig.php
│ │ │ ├── IHttpConfig.php
│ │ │ ├── ConfigFactory.php
│ │ │ ├── HttpConfig.php
│ │ │ ├── Config.php
│ │ │ └── Validator.php
│ │ ├── service
│ │ │ ├── ServiceFactory.php
│ │ │ └── ServiceInterface.php
│ │ ├── http
│ │ │ ├── GrpcWebEndpoint.php
│ │ │ ├── Method.php
│ │ │ ├── FlagdResponseValidator.php
│ │ │ └── FlagdResponseResolutionDetailsAdapter.php
│ │ ├── common
│ │ │ ├── SafeArrayAccessor.php
│ │ │ ├── EvaluationContextArrayFactory.php
│ │ │ └── ResponseCodeErrorCodeMap.php
│ │ └── FlagdProvider.php
│ ├── phpstan.neon.dist
│ ├── psalm.xml
│ ├── phpunit.xml.dist
│ ├── phpcs.xml.dist
│ ├── tests
│ │ └── TestCase.php
│ ├── CHANGELOG.md
│ └── README.md
├── Split
│ ├── .gitignore
│ ├── examples
│ │ ├── .gitignore
│ │ └── SplitSDK
│ │ │ ├── README.md
│ │ │ ├── composer.json
│ │ │ └── src
│ │ │ └── main.php
│ ├── psalm-baseline.xml
│ ├── phpstan.neon.dist
│ ├── tests
│ │ ├── integration
│ │ │ └── files
│ │ │ │ └── splits.yml
│ │ ├── TestCase.php
│ │ └── unit
│ │ │ └── SplitProviderTest.php
│ ├── src
│ │ ├── errors
│ │ │ ├── SplitFactoryCreationException.php
│ │ │ ├── InvalidTreatmentTypeException.php
│ │ │ └── TargetingKeyMissingException.php
│ │ └── treatments
│ │ │ ├── TreatmentParser.php
│ │ │ └── TreatmentValidator.php
│ ├── psalm.xml
│ ├── phpunit.xml.dist
│ ├── phpcs.xml.dist
│ ├── CHANGELOG.md
│ ├── README.md
│ └── composer.json
└── CloudBees
│ ├── .gitignore
│ ├── examples
│ ├── .gitignore
│ └── CloudBees
│ │ ├── README.md
│ │ ├── composer.json
│ │ └── src
│ │ └── main.php
│ ├── psalm-baseline.xml
│ ├── phpstan.neon.dist
│ ├── src
│ ├── transformers
│ │ ├── IdentityTransformer.php
│ │ └── JsonTransformer.php
│ ├── errors
│ │ ├── InvalidJsonTypeException.php
│ │ └── JsonParseException.php
│ ├── context
│ │ └── ContextAdapter.php
│ └── CloudBeesProvider.php
│ ├── scripts
│ └── seed-data.json
│ ├── psalm.xml
│ ├── CHANGELOG.md
│ ├── phpunit.xml.dist
│ ├── tests
│ ├── unit
│ │ └── JsonTransformerTest.php
│ ├── TestCase.php
│ └── integration
│ │ └── CloudBeesProviderTest.php
│ ├── phpcs.xml.dist
│ ├── README.md
│ └── composer.json
├── .tool-versions
├── .pre-commit-config.yaml
├── .gitmodules
├── renovate.json
├── devenv.yaml
├── .release-please-manifest.json
├── release-please-config.json
├── .gitsplit.yml
├── composer.json
├── devenv.nix
├── README.md
└── devenv.lock
/hooks/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/providers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | php 8.0.24
2 | # php 8.1.11
3 | # php 8.2.1
4 |
--------------------------------------------------------------------------------
/hooks/DDTrace/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor
3 | /build
--------------------------------------------------------------------------------
/hooks/DDTrace/examples/.gitignore:
--------------------------------------------------------------------------------
1 | /*/vendor
2 | /*/composer.lock
--------------------------------------------------------------------------------
/providers/Flagd/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor
3 | /build
--------------------------------------------------------------------------------
/providers/Split/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor
3 | /build
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor
3 | /build
--------------------------------------------------------------------------------
/hooks/Validators/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor
3 | /build
--------------------------------------------------------------------------------
/hooks/Validators/examples/.gitignore:
--------------------------------------------------------------------------------
1 | /*/vendor
2 | /*/composer.lock
--------------------------------------------------------------------------------
/providers/CloudBees/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor
3 | /build
--------------------------------------------------------------------------------
/providers/Flagd/examples/.gitignore:
--------------------------------------------------------------------------------
1 | /*/vendor
2 | /*/composer.lock
--------------------------------------------------------------------------------
/providers/Split/examples/.gitignore:
--------------------------------------------------------------------------------
1 | /*/vendor
2 | /*/composer.lock
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/examples/.gitignore:
--------------------------------------------------------------------------------
1 | /*/vendor
2 | /*/composer.lock
--------------------------------------------------------------------------------
/providers/CloudBees/examples/.gitignore:
--------------------------------------------------------------------------------
1 | /*/vendor
2 | /*/composer.lock
--------------------------------------------------------------------------------
/providers/Flagd/examples/Http/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature flagd HTTP example
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | /nix/store/kjn5c8afbhm6xjdaz5z4z2ldwpknw0z9-pre-commit-config.json
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "schemas"]
2 | path = providers/Flagd/schemas
3 | url = https://github.com/tcarrio/schemas/
4 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/README.md:
--------------------------------------------------------------------------------
1 | # proto
2 |
3 | **⚠️ This folder is entirely generated code. Do not modify it by hand!**
--------------------------------------------------------------------------------
/hooks/DDTrace/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/providers/Flagd/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/providers/Split/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/hooks/Validators/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/providers/CloudBees/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/devenv.yaml:
--------------------------------------------------------------------------------
1 | inputs:
2 | nixpkgs:
3 | url: github:NixOS/nixpkgs/nixpkgs-unstable
4 | pre-commit-hooks:
5 | url: github:cachix/pre-commit-hooks.nix
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/GPBMetadata/Schema/V1/Schema.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infomaniak/php-sdk-contrib/main/providers/Flagd/proto/php/GPBMetadata/Schema/V1/Schema.php
--------------------------------------------------------------------------------
/providers/Split/examples/SplitSDK/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature Split SDK example
2 |
3 | This example provides an example of bootstrapping and using the OpenFeature Split provider.
4 |
--------------------------------------------------------------------------------
/hooks/Validators/examples/ExampleRegexpValidators/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature Validators Hook example
2 |
3 | This example provides an example of using the validators hooks for OpenFeature.
4 |
--------------------------------------------------------------------------------
/providers/CloudBees/examples/CloudBees/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature CloudBees SDK example
2 |
3 | This example provides an example of bootstrapping and using the OpenFeature CloudBees provider.
4 |
--------------------------------------------------------------------------------
/hooks/DDTrace/src/_autoload.php:
--------------------------------------------------------------------------------
1 | getProtocol()) {
15 | default:
16 | return HttpService::fromConfig($config);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/providers/Flagd/src/http/GrpcWebEndpoint.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf(Hook::class, $hook);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/providers/Flagd/examples/Http/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-feature/flagd-http-example",
3 | "description": "An example of using OpenFeature with the Flagd provider over HTTP",
4 | "type": "project",
5 | "license": "Apache-2.0",
6 | "autoload": {
7 | "psr-4": {
8 | "OpenFeature\\Providers\\Examples\\FlagdHttpExample\\": "src/"
9 | }
10 | },
11 | "authors": [
12 | {
13 | "name": "Tom Carrio",
14 | "email": "tom@carrio.dev"
15 | }
16 | ],
17 | "require": {
18 | "open-feature/sdk": "^1.2.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/providers/Flagd/src/http/FlagdResponseValidator.php:
--------------------------------------------------------------------------------
1 | getClient('dev.openfeature.contrib.php.demo', '1.0.0');
13 |
14 | $version = $client->getStringValue('dev.openfeature.contrib.php.version-value', 'unknown');
15 |
16 | echo 'Version is ' . $version;
--------------------------------------------------------------------------------
/hooks/DDTrace/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/providers/Flagd/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/providers/Split/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/hooks/Validators/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/providers/CloudBees/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/providers/Flagd/src/config/IHttpConfig.php:
--------------------------------------------------------------------------------
1 | assertNotEmpty($api->getHooks());
24 | $this->assertInstanceOf(Hook::class, $api->getHooks()[0]);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/tests/unit/OpenTelemetryHookTest.php:
--------------------------------------------------------------------------------
1 | assertNotEmpty($api->getHooks());
24 | $this->assertInstanceOf(Hook::class, $api->getHooks()[0]);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/providers/Flagd/examples/Http/src/main.php:
--------------------------------------------------------------------------------
1 | 'localhost',
19 | 'port' => 8013,
20 | 'secure' => false,
21 | 'protocol' => 'http'
22 | ]);
23 |
24 | $api->setProvider($provider);
25 |
26 | // retrieve an OpenFeatureClient
27 | $client = $api->getClient('http-example', '1.0');
28 |
29 | $flagValue = $client->getBooleanDetails('dev.openfeature.example_flag', true, null, null);
30 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/examples/OTelManualInstrumentation/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-feature/otel-manual-instrumentation-example",
3 | "description": "An example of using the OpenTelemetry hook for OpenFeature with manual instrumentation",
4 | "type": "project",
5 | "license": "Apache-2.0",
6 | "authors": [
7 | {
8 | "name": "Tom Carrio",
9 | "email": "tom@carrio.dev"
10 | }
11 | ],
12 | "require": {
13 | "guzzlehttp/guzzle": "*",
14 | "php-http/guzzle7-adapter": "*",
15 | "slim/slim": "~4",
16 | "php-di/php-di": "^6.3",
17 | "php-di/slim-bridge": "^3.2",
18 | "open-telemetry/api": "0.0.17",
19 | "open-telemetry/sdk": "0.0.17",
20 | "open-feature/sdk": "^1.2.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/providers/Flagd/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./tests/unit
12 |
13 |
14 |
15 |
16 |
17 | ./src
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/hooks/Validators/examples/ExampleRegexpValidators/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-feature/validators-hook-example",
3 | "description": "An example of using the validator hooks for OpenFeature",
4 | "type": "project",
5 | "license": "Apache-2.0",
6 | "authors": [
7 | {
8 | "name": "Tom Carrio",
9 | "email": "tom@carrio.dev"
10 | }
11 | ],
12 | "require": {
13 | "open-feature/sdk": "^1.2.0",
14 | "open-feature/validators-hook": "dev-main"
15 | },
16 | "repositories": [
17 | {
18 | "type": "path",
19 | "url": "../../",
20 | "options": {
21 | "versions": {
22 | "open-feature/validators-hook": "dev-main"
23 | }
24 | }
25 | }
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 0.2.0 (2023-01-09)
4 |
5 |
6 | ### ⚠ BREAKING CHANGES
7 |
8 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39))
9 |
10 | ### Features
11 |
12 | * otel hook ([#22](https://github.com/open-feature/php-sdk-contrib/issues/22)) ([be3f1e9](https://github.com/open-feature/php-sdk-contrib/commit/be3f1e9ed37dee4bbce8e3701e4693c1b949c398))
13 | * **otel-hook:** autoload registration of otel hook ([#25](https://github.com/open-feature/php-sdk-contrib/issues/25)) ([789a95c](https://github.com/open-feature/php-sdk-contrib/commit/789a95c47bc278b333bf8b241b0e342baa27acc5))
14 |
15 |
16 | ### Miscellaneous Chores
17 |
18 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39)) ([b452080](https://github.com/open-feature/php-sdk-contrib/commit/b452080443d837c66b554b1bb1a07cadba5a152a))
19 |
--------------------------------------------------------------------------------
/providers/CloudBees/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 0.3.0 (2023-01-09)
4 |
5 |
6 | ### ⚠ BREAKING CHANGES
7 |
8 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39))
9 |
10 | ### Features
11 |
12 | * otel hook ([#22](https://github.com/open-feature/php-sdk-contrib/issues/22)) ([be3f1e9](https://github.com/open-feature/php-sdk-contrib/commit/be3f1e9ed37dee4bbce8e3701e4693c1b949c398))
13 | * **otel-hook:** autoload registration of otel hook ([#25](https://github.com/open-feature/php-sdk-contrib/issues/25)) ([789a95c](https://github.com/open-feature/php-sdk-contrib/commit/789a95c47bc278b333bf8b241b0e342baa27acc5))
14 |
15 |
16 | ### Miscellaneous Chores
17 |
18 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39)) ([b452080](https://github.com/open-feature/php-sdk-contrib/commit/b452080443d837c66b554b1bb1a07cadba5a152a))
19 |
--------------------------------------------------------------------------------
/providers/CloudBees/src/transformers/JsonTransformer.php:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./tests/unit
12 |
13 |
14 | ./tests/integration
15 |
16 |
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/providers/Split/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./tests/unit
12 |
13 |
14 | ./tests/integration
15 |
16 |
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./tests/unit
12 |
13 |
14 | ./tests/integration
15 |
16 |
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/hooks/Validators/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./tests/unit
12 |
13 |
14 | ./tests/integration
15 |
16 |
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/providers/CloudBees/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | ./tests/unit
12 |
13 |
14 | ./tests/integration
15 |
16 |
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/hooks/Validators/examples/ExampleRegexpValidators/src/main.php:
--------------------------------------------------------------------------------
1 | getClient('split-example', '1.0');
18 |
19 | // create some example hook validators
20 |
21 | $alphanumericValidator = new RegexpValidatorHook('/^[A-Za-z0-9]+$/');
22 | $hexadecimalValidator = new RegexpValidatorHook('/^[0-9a-f]+$/');
23 | $asciiValidator = new RegexpValidatorHook('/^[ -~]$/');
24 |
25 | $client->setHooks([
26 | $alphanumericValidator,
27 | $hexadecimalValidator,
28 | $asciiValidator
29 | ]);
30 |
31 | $flagValue = $client->getBooleanDetails('dev.openfeature.example_flag', true, null, null);
32 |
--------------------------------------------------------------------------------
/providers/CloudBees/src/errors/InvalidJsonTypeException.php:
--------------------------------------------------------------------------------
1 | resolutionError = new ResolutionErrorImpl(ErrorCode::PARSE_ERROR(), 'An error occurred while parsing the JSON');
21 | }
22 |
23 | public function getResolutionError(): ResolutionError
24 | {
25 | return $this->resolutionError;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/providers/CloudBees/src/errors/JsonParseException.php:
--------------------------------------------------------------------------------
1 | resolutionError = new ResolutionErrorImpl(ErrorCode::PARSE_ERROR(), 'An error occurred while parsing the JSON');
21 | }
22 |
23 | public function getResolutionError(): ResolutionError
24 | {
25 | return $this->resolutionError;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/providers/CloudBees/tests/unit/JsonTransformerTest.php:
--------------------------------------------------------------------------------
1 | assertNotNull($decodedValue);
26 | $this->assertIsArray($decodedValue);
27 | $this->assertEquals($decodedValue['name'], $name);
28 | $this->assertEquals($decodedValue['version'], $version);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/providers/Flagd/src/common/SafeArrayAccessor.php:
--------------------------------------------------------------------------------
1 | arr = $arr;
18 | }
19 |
20 | /**
21 | * @param mixed[] $arr
22 | */
23 | public static function with(array $arr): SafeArrayAccessor
24 | {
25 | return new SafeArrayAccessor($arr);
26 | }
27 |
28 | /**
29 | * @param mixed[] $arr
30 | *
31 | * @return mixed
32 | */
33 | public static function getKeyFromArray(array $arr, string $key)
34 | {
35 | return $arr[$key] ?? null;
36 | }
37 |
38 | /**
39 | * @return mixed
40 | */
41 | public function get(string $key)
42 | {
43 | return self::getKeyFromArray($this->arr, $key);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/examples/AutoloadOTelSDK/src/main.php:
--------------------------------------------------------------------------------
1 | getClient('dev.openfeature.contrib.php.demo', '1.0.0');
22 |
23 | $version = $client->getStringValue('dev.openfeature.contrib.php.version-value', 'unknown');
24 |
25 | echo 'Version is ' . $version;
--------------------------------------------------------------------------------
/providers/Split/src/errors/InvalidTreatmentTypeException.php:
--------------------------------------------------------------------------------
1 | resolutionError = new ProviderResolutionError(ErrorCode::TYPE_MISMATCH(), 'Treatment value does not match the expected type');
21 | }
22 |
23 | public function getResolutionError(): ResolutionError
24 | {
25 | return $this->resolutionError;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/providers/Split/src/errors/TargetingKeyMissingException.php:
--------------------------------------------------------------------------------
1 | resolutionError = new ProviderResolutionError(ErrorCode::TARGETING_KEY_MISSING(), 'The targeting key is required for Split');
21 | }
22 |
23 | public function getResolutionError(): ResolutionError
24 | {
25 | return $this->resolutionError;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/providers/Flagd/src/common/EvaluationContextArrayFactory.php:
--------------------------------------------------------------------------------
1 | getAttributes()->toArray(),
27 | $context->getTargetingKey() ? ['targetingKey' => $context->getTargetingKey()] : [],
28 | );
29 |
30 | if (sizeof($contextArray) === 0) {
31 | return new stdClass();
32 | }
33 | }
34 |
35 | return $contextArray;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/providers/CloudBees/src/context/ContextAdapter.php:
--------------------------------------------------------------------------------
1 | getAttributes()->toArray(),
25 | ['targetingKey' => $context->getTargetingKey()],
26 | ),
27 | /**
28 | * @param mixed $value
29 | */
30 | fn ($value) => !is_null($value),
31 | ),
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "bootstrap-sha": "91dbcca98f4a56ec37ce1b03bc0f39aeaba6dbd3",
3 | "separate-pull-requests": true,
4 | "prerelease": false,
5 | "bump-minor-pre-major": true,
6 | "bump-patch-for-minor-pre-major": true,
7 | "include-v-in-tag": false,
8 | "packages": {
9 | "hooks/DDTrace": {
10 | "package-name": "open-feature/dd-trace-hook",
11 | "release-as": "0.2.0"
12 | },
13 | "hooks/OpenTelemetry": {
14 | "package-name": "open-feature/otel-hook",
15 | "release-as": "0.2.0"
16 | },
17 | "hooks/Validators": {
18 | "package-name": "open-feature/validators-hook",
19 | "release-as": "0.2.0"
20 | },
21 | "providers/CloudBees": {
22 | "package-name": "open-feature/cloudbees-provider",
23 | "release-as": "0.3.0"
24 | },
25 | "providers/Flagd": {
26 | "package-name": "open-feature/flagd-provider",
27 | "release-as": "0.4.0"
28 | },
29 | "providers/Split": {
30 | "package-name": "open-feature/split-provider",
31 | "release-as": "0.3.0"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/hooks/Validators/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [0.2.0](https://github.com/open-feature/php-sdk-contrib/compare/open-feature/validators-hook-0.2.0...open-feature/validators-hook-0.2.0) (2023-02-12)
4 |
5 |
6 | ### Features
7 |
8 | * deprecate php 7 ([#59](https://github.com/open-feature/php-sdk-contrib/issues/59)) ([d028e6d](https://github.com/open-feature/php-sdk-contrib/commit/d028e6d7741d07b7edef21b43b249fdb2d18d8f2))
9 |
10 | ## 0.2.0 (2023-01-09)
11 |
12 |
13 | ### ⚠ BREAKING CHANGES
14 |
15 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39))
16 |
17 | ### Features
18 |
19 | * **validators-hook:** created new package with validation offering ([#30](https://github.com/open-feature/php-sdk-contrib/issues/30)) ([a2501e6](https://github.com/open-feature/php-sdk-contrib/commit/a2501e6440e8f25ce3231fffd225f5cf13ab5fe4))
20 |
21 |
22 | ### Miscellaneous Chores
23 |
24 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39)) ([b452080](https://github.com/open-feature/php-sdk-contrib/commit/b452080443d837c66b554b1bb1a07cadba5a152a))
25 |
--------------------------------------------------------------------------------
/hooks/DDTrace/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ./src
9 | ./tests
10 |
11 | */tests/fixtures/*
12 | */tests/*/fixtures/*
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/hooks/DDTrace/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | $class
25 | * @param mixed ...$arguments
26 | *
27 | * @return T & MockInterface
28 | *
29 | * @template T
30 | *
31 | * phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
32 | */
33 | public function mockery(string $class, ...$arguments)
34 | {
35 | /** @var T & MockInterface $mock */
36 | $mock = Mockery::mock($class, ...$arguments);
37 |
38 | return $mock;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ./src
9 | ./tests
10 |
11 | */tests/fixtures/*
12 | */tests/*/fixtures/*
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/hooks/Validators/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ./src
9 | ./tests
10 |
11 | */tests/fixtures/*
12 | */tests/*/fixtures/*
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/providers/CloudBees/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ./src
9 | ./tests
10 |
11 | */tests/fixtures/*
12 | */tests/*/fixtures/*
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/providers/Flagd/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ./src
9 | ./tests
10 |
11 | */tests/fixtures/*
12 | */tests/*/fixtures/*
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/providers/Split/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ./src
9 | ./tests
10 |
11 | */tests/fixtures/*
12 | */tests/*/fixtures/*
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/providers/Flagd/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | $class
25 | * @param mixed ...$arguments
26 | *
27 | * @return T & MockInterface
28 | *
29 | * @template T
30 | *
31 | * phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
32 | */
33 | public function mockery(string $class, ...$arguments)
34 | {
35 | /** @var T & MockInterface $mock */
36 | $mock = Mockery::mock($class, ...$arguments);
37 |
38 | return $mock;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/providers/Split/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | $class
25 | * @param mixed ...$arguments
26 | *
27 | * @return T & MockInterface
28 | *
29 | * @template T
30 | *
31 | * phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
32 | */
33 | public function mockery(string $class, ...$arguments)
34 | {
35 | /** @var T & MockInterface $mock */
36 | $mock = Mockery::mock($class, ...$arguments);
37 |
38 | return $mock;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/hooks/Validators/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | $class
25 | * @param mixed ...$arguments
26 | *
27 | * @return T & MockInterface
28 | *
29 | * @template T
30 | *
31 | * phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
32 | */
33 | public function mockery(string $class, ...$arguments)
34 | {
35 | /** @var T & MockInterface $mock */
36 | $mock = Mockery::mock($class, ...$arguments);
37 |
38 | return $mock;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | $class
25 | * @param mixed ...$arguments
26 | *
27 | * @return T & MockInterface
28 | *
29 | * @template T
30 | *
31 | * phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
32 | */
33 | public function mockery(string $class, ...$arguments)
34 | {
35 | /** @var T & MockInterface $mock */
36 | $mock = Mockery::mock($class, ...$arguments);
37 |
38 | return $mock;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/providers/CloudBees/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | $class
25 | * @param mixed ...$arguments
26 | *
27 | * @return T & MockInterface
28 | *
29 | * @template T
30 | *
31 | * phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
32 | */
33 | public function mockery(string $class, ...$arguments)
34 | {
35 | /** @var T & MockInterface $mock */
36 | $mock = Mockery::mock($class, ...$arguments);
37 |
38 | return $mock;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/providers/Split/examples/SplitSDK/src/main.php:
--------------------------------------------------------------------------------
1 | 'tcp',
19 | 'host' => getenv('REDIS_HOST'),
20 | 'port' => getenv('REDIS_PORT'),
21 | 'timeout' => 881,
22 | ];
23 |
24 | $options = ['prefix' => ''];
25 |
26 | $splitConfig = [
27 | 'cache' => [
28 | 'adapter' => 'predis',
29 | 'parameters' => $parameters,
30 | 'options' => $options,
31 | ],
32 | ];
33 |
34 | $splitApiKey = getenv('SPLIT_API_KEY');
35 |
36 | $provider = new SplitProvider($splitApiKey, $splitConfig);
37 |
38 | $api->setProvider($provider);
39 |
40 | // retrieve an OpenFeatureClient
41 | $client = $api->getClient('split-example', '1.0');
42 |
43 | $flagValue = $client->getBooleanDetails('dev.openfeature.example_flag', true, null, null);
44 |
--------------------------------------------------------------------------------
/providers/Split/tests/unit/SplitProviderTest.php:
--------------------------------------------------------------------------------
1 | getPathToValidSplitFile();
18 |
19 | $apiKey = 'localhost';
20 | $config = [
21 | 'splitFile' => $splitFile,
22 | ];
23 |
24 | // When
25 | $instance = new SplitProvider($apiKey, $config);
26 |
27 | // Then
28 | $this->assertNotNull($instance);
29 | $this->assertInstanceOf(Provider::class, $instance);
30 | }
31 |
32 | private function getPathToValidSplitFile(): string
33 | {
34 | $splitFs = vfsStream::setup('root', 0777, [
35 | '.split' => '',
36 | ]);
37 |
38 | return $splitFs->getChild('.split')->url();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/providers/Flagd/src/common/ResponseCodeErrorCodeMap.php:
--------------------------------------------------------------------------------
1 | ErrorCode::FLAG_NOT_FOUND(),
38 | 'invalid_argument' => ErrorCode::TYPE_MISMATCH(),
39 | ];
40 |
41 | self::$initialized = true;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/providers/Flagd/src/config/HttpConfig.php:
--------------------------------------------------------------------------------
1 | client = $client;
20 | $this->requestFactory = $requestFactory;
21 | $this->streamFactory = $streamFactory;
22 | }
23 |
24 | public function getClient(): ClientInterface
25 | {
26 | return $this->client;
27 | }
28 |
29 | public function getRequestFactory(): RequestFactoryInterface
30 | {
31 | return $this->requestFactory;
32 | }
33 |
34 | public function getStreamFactory(): StreamFactoryInterface
35 | {
36 | return $this->streamFactory;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.gitsplit.yml:
--------------------------------------------------------------------------------
1 | # Path to a cache directory Used to speed up the split over time by reusing git's objects
2 | cache_url: "/cache/gitsplit"
3 |
4 | # Path to the repository to split (default = current path)
5 | project_url: "https://github.com/open-feature/php-sdk-contrib.git"
6 |
7 | # List of splits.
8 | splits:
9 | - prefix: "hooks/OpenTelemetry"
10 | target: "https://${GH_TOKEN}@github.com/open-feature-php/otel-hook.git"
11 | - prefix: "hooks/DDTrace"
12 | target: "https://${GH_TOKEN}@github.com/open-feature-php/dd-trace-hook.git"
13 | - prefix: "hooks/Validators"
14 | target: "https://${GH_TOKEN}@github.com/open-feature-php/validators-hook.git"
15 | - prefix: "providers/Flagd"
16 | target: "https://${GH_TOKEN}@github.com/open-feature-php/flagd-provider.git"
17 | - prefix: "providers/Split"
18 | target: "https://${GH_TOKEN}@github.com/open-feature-php/split-provider.git"
19 | - prefix: "providers/CloudBees"
20 | target: "https://${GH_TOKEN}@github.com/open-feature-php/cloudbees-provider.git"
21 |
22 | # List of references to split (defined as regexp)
23 | origins:
24 | - ^main$
25 | - ^test$
26 | - ^split$
27 | - ^v\d+\.\d+\.\d+$
28 | - ^\d+\.\d+\.\d+$
29 |
--------------------------------------------------------------------------------
/hooks/DDTrace/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [0.2.0](https://github.com/open-feature/php-sdk-contrib/compare/open-feature/dd-trace-hook-0.2.0...open-feature/dd-trace-hook-0.2.0) (2023-02-12)
4 |
5 |
6 | ### Features
7 |
8 | * deprecate php 7 ([#59](https://github.com/open-feature/php-sdk-contrib/issues/59)) ([d028e6d](https://github.com/open-feature/php-sdk-contrib/commit/d028e6d7741d07b7edef21b43b249fdb2d18d8f2))
9 |
10 | ## 0.2.0 (2023-01-09)
11 |
12 |
13 | ### ⚠ BREAKING CHANGES
14 |
15 | * fix release-please config ([#38](https://github.com/open-feature/php-sdk-contrib/issues/38))
16 | * fix release-please config
17 |
18 | ### Features
19 |
20 | * dd-trace hook ([#26](https://github.com/open-feature/php-sdk-contrib/issues/26)) ([d2b1a04](https://github.com/open-feature/php-sdk-contrib/commit/d2b1a0440bbb0d1fa557b3aefd32eee6267f2823))
21 |
22 |
23 | ### Miscellaneous Chores
24 |
25 | * fix release-please config ([0210952](https://github.com/open-feature/php-sdk-contrib/commit/0210952af1d6774744c633507a9bec73f3cf7251))
26 | * fix release-please config ([#38](https://github.com/open-feature/php-sdk-contrib/issues/38)) ([8ee9fe3](https://github.com/open-feature/php-sdk-contrib/commit/8ee9fe37584ad6754272ad3ac016902e6ebd48d8))
27 |
--------------------------------------------------------------------------------
/providers/Flagd/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [0.4.0](https://github.com/open-feature/php-sdk-contrib/compare/open-feature/flagd-provider-0.4.0...open-feature/flagd-provider-0.4.0) (2023-02-12)
4 |
5 |
6 | ### Features
7 |
8 | * deprecate php 7 ([#59](https://github.com/open-feature/php-sdk-contrib/issues/59)) ([d028e6d](https://github.com/open-feature/php-sdk-contrib/commit/d028e6d7741d07b7edef21b43b249fdb2d18d8f2))
9 |
10 | ## 0.4.0 (2023-01-09)
11 |
12 |
13 | ### ⚠ BREAKING CHANGES
14 |
15 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39))
16 |
17 | ### Features
18 |
19 | * otel hook ([#22](https://github.com/open-feature/php-sdk-contrib/issues/22)) ([be3f1e9](https://github.com/open-feature/php-sdk-contrib/commit/be3f1e9ed37dee4bbce8e3701e4693c1b949c398))
20 | * **otel-hook:** autoload registration of otel hook ([#25](https://github.com/open-feature/php-sdk-contrib/issues/25)) ([789a95c](https://github.com/open-feature/php-sdk-contrib/commit/789a95c47bc278b333bf8b241b0e342baa27acc5))
21 |
22 |
23 | ### Miscellaneous Chores
24 |
25 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39)) ([b452080](https://github.com/open-feature/php-sdk-contrib/commit/b452080443d837c66b554b1bb1a07cadba5a152a))
26 |
--------------------------------------------------------------------------------
/hooks/DDTrace/tests/integration/DDTraceHookTest.php:
--------------------------------------------------------------------------------
1 | clearHooks();
19 |
20 | // When
21 | $this->simulateAutoload();
22 |
23 | // Then
24 |
25 | $this->assertCount(1, $api->getHooks());
26 | $this->assertInstanceOf(Hook::class, $api->getHooks()[0]);
27 | }
28 |
29 | public function testCanBeRegistered(): void
30 | {
31 | // Given
32 | $api = OpenFeatureAPI::getInstance();
33 | $api->clearHooks();
34 |
35 | // When
36 | DDTraceHook::register();
37 |
38 | // Then
39 | $this->assertCount(1, $api->getHooks());
40 | $this->assertInstanceOf(Hook::class, $api->getHooks()[0]);
41 | }
42 |
43 | private function simulateAutoload(): void
44 | {
45 | require __DIR__ . '/../../src/_autoload.php';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/tests/integration/OpenTelemetryHookTest.php:
--------------------------------------------------------------------------------
1 | clearHooks();
19 |
20 | // When
21 | $this->simulateAutoload();
22 |
23 | // Then
24 |
25 | $this->assertCount(1, $api->getHooks());
26 | $this->assertInstanceOf(Hook::class, $api->getHooks()[0]);
27 | }
28 |
29 | public function testCanBeRegistered(): void
30 | {
31 | // Given
32 | $api = OpenFeatureAPI::getInstance();
33 | $api->clearHooks();
34 |
35 | // When
36 | OpenTelemetryHook::register();
37 |
38 | // Then
39 | $this->assertCount(1, $api->getHooks());
40 | $this->assertInstanceOf(Hook::class, $api->getHooks()[0]);
41 | }
42 |
43 | private function simulateAutoload(): void
44 | {
45 | require __DIR__ . '/../../src/_autoload.php';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/providers/Flagd/src/config/Config.php:
--------------------------------------------------------------------------------
1 | host = $host ?? Defaults::DEFAULT_HOST;
18 | $this->port = $port ?? Defaults::DEFAULT_PORT;
19 | $this->protocol = $protocol ?? Defaults::DEFAULT_PROTOCOL;
20 | $this->secure = $secure ?? Defaults::DEFAULT_SECURE;
21 | $this->httpConfig = $httpConfig ?? null;
22 | }
23 |
24 | public function getHost(): string
25 | {
26 | return $this->host;
27 | }
28 |
29 | public function getPort(): int
30 | {
31 | return $this->port;
32 | }
33 |
34 | public function getProtocol(): string
35 | {
36 | return $this->protocol;
37 | }
38 |
39 | public function isSecure(): bool
40 | {
41 | return $this->secure;
42 | }
43 |
44 | public function getHttpConfig(): ?IHttpConfig
45 | {
46 | return $this->httpConfig;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/providers/Split/src/treatments/TreatmentParser.php:
--------------------------------------------------------------------------------
1 | has(TracerInterface::class)) {
27 | /** @var TracerInterface|null $maybeTracer */
28 | $maybeTracer = $container->get(TracerInterface::class);
29 |
30 | if ($maybeTracer instanceof TracerInterface) {
31 | return $maybeTracer;
32 | }
33 | }
34 | }
35 |
36 | return Globals::tracerProvider()->getTracer('open-feature/otel-hook', '0.0.1');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/devenv.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 |
5 | # https://devenv.sh/packages/
6 | packages = [ pkgs.git ];
7 |
8 | # https://devenv.sh/languages/
9 | languages.nix.enable = true;
10 | languages.php.enable = true;
11 | languages.php.package = pkgs.php80;
12 |
13 | # https://devenv.sh/basics/
14 | env.PROJECT_NAME = "openfeature-php-sdk";
15 |
16 | # https://devenv.sh/scripts/
17 | scripts.hello.exec = "echo $ Started devenv shell in $PROJECT_NAME";
18 |
19 | enterShell = ''
20 | hello
21 | echo
22 | git --version
23 | php --version
24 | echo
25 |
26 | # optimization step -- files and directories that match entries
27 | # in the .gitignore will still be traversed, and the .devenv
28 | # directory contains over 5000 files and 121MB.
29 | if ! grep -E "excludesfile.+\.gitignore" .git/config &>/dev/null
30 | then
31 | git config --local core.excludesfile .gitignore
32 | fi
33 | '';
34 |
35 | ## https://devenv.sh/pre-commit-hooks/
36 | pre-commit.hooks = {
37 | # # general formatting
38 | # prettier.enable = true;
39 | # github actions
40 | actionlint.enable = true;
41 | # nix
42 | deadnix.enable = true;
43 | nixfmt.enable = true;
44 | # php
45 | # phpcbf.enable = true;
46 | # # ensure Markdown code is executable
47 | # mdsh.enable = true;
48 | };
49 |
50 | # https://devenv.sh/processes/
51 | # processes.ping.exec = "ping example.com";
52 | }
53 |
--------------------------------------------------------------------------------
/providers/Split/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [0.3.0](https://github.com/open-feature/php-sdk-contrib/compare/open-feature/split-provider-0.3.0...open-feature/split-provider-0.3.0) (2023-02-12)
4 |
5 |
6 | ### Features
7 |
8 | * deprecate php 7 ([#59](https://github.com/open-feature/php-sdk-contrib/issues/59)) ([d028e6d](https://github.com/open-feature/php-sdk-contrib/commit/d028e6d7741d07b7edef21b43b249fdb2d18d8f2))
9 |
10 | ## 0.3.0 (2023-01-09)
11 |
12 |
13 | ### ⚠ BREAKING CHANGES
14 |
15 | * reset release-please config ([#40](https://github.com/open-feature/php-sdk-contrib/issues/40))
16 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39))
17 |
18 | ### Features
19 |
20 | * otel hook ([#22](https://github.com/open-feature/php-sdk-contrib/issues/22)) ([be3f1e9](https://github.com/open-feature/php-sdk-contrib/commit/be3f1e9ed37dee4bbce8e3701e4693c1b949c398))
21 | * **otel-hook:** autoload registration of otel hook ([#25](https://github.com/open-feature/php-sdk-contrib/issues/25)) ([789a95c](https://github.com/open-feature/php-sdk-contrib/commit/789a95c47bc278b333bf8b241b0e342baa27acc5))
22 |
23 |
24 | ### Miscellaneous Chores
25 |
26 | * reset release-please ([#39](https://github.com/open-feature/php-sdk-contrib/issues/39)) ([b452080](https://github.com/open-feature/php-sdk-contrib/commit/b452080443d837c66b554b1bb1a07cadba5a152a))
27 | * reset release-please config ([#40](https://github.com/open-feature/php-sdk-contrib/issues/40)) ([b9a3b7e](https://github.com/open-feature/php-sdk-contrib/commit/b9a3b7e1017dc56ddfdd767fb8dab2d01b641699))
28 |
--------------------------------------------------------------------------------
/providers/Split/src/treatments/TreatmentValidator.php:
--------------------------------------------------------------------------------
1 | =8.0-blue.svg)
6 | 
7 | 
8 |
9 | ## Overview
10 |
11 | The `php-contrib-sdk` repository is a monorepository containing various providers and hooks for OpenFeature's PHP SDK. Packages include:
12 |
13 | - Providers
14 | - [Flagd](./providers/Flagd/README.md)
15 | - [Split](./providers/Split/README.md)
16 | - [CloudBees](./providers/CloudBees/README.md)
17 | - Hooks
18 | - [OpenTelemetry](./hooks/OpenTelemetry/README.md)
19 | - [Datadog](./hooks/DDTrace/README.md)
20 | - [Validators](./hooks/Validators/README.md)
21 |
22 | ### Status
23 |
24 | This repository is marked as **experimental** since the repository structure itself could change. However, each the packages within the repository maintains its own release status.
25 |
26 | ## Development
27 |
28 | ### PHP Versioning
29 |
30 | This library targets PHP version 8.0 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
31 |
32 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
33 |
34 | ### Installation and Dependencies
35 |
36 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
37 |
38 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
39 |
40 | ### Testing
41 |
42 | Each package implements its own test suite.
43 |
44 | Run tests with `composer run test` in the package's directory.
45 |
--------------------------------------------------------------------------------
/hooks/Validators/src/Regexp/RegexpValidatorHook.php:
--------------------------------------------------------------------------------
1 | regexp = self::validateRegexp($regexp);
26 | }
27 |
28 | public function before(HookContext $context, HookHints $hints): ?EvaluationContext
29 | {
30 | return null;
31 | }
32 |
33 | public function after(HookContext $context, ResolutionDetails $details, HookHints $hints): void
34 | {
35 | /** @var string $resolvedValue */
36 | $resolvedValue = $details->getValue();
37 |
38 | if ($this->testResolvedValue($resolvedValue)) {
39 | return;
40 | }
41 |
42 | throw new ValidationException();
43 | }
44 |
45 | public function error(HookContext $context, Throwable $error, HookHints $hints): void
46 | {
47 | // no-op
48 | }
49 |
50 | public function finally(HookContext $context, HookHints $hints): void
51 | {
52 | // no-op
53 | }
54 |
55 | public function supportsFlagValueType(string $flagValueType): bool
56 | {
57 | return $flagValueType === FlagValueType::STRING;
58 | }
59 |
60 | private function testResolvedValue(string $resolvedValue): bool
61 | {
62 | return preg_match($this->regexp, $resolvedValue) === 1;
63 | }
64 |
65 | private static function validateRegexp(string $regexp): string
66 | {
67 | if (self::isValidRegexp($regexp)) {
68 | return $regexp;
69 | }
70 |
71 | throw new InvalidRegularExpressionException($regexp);
72 | }
73 |
74 | private static function isValidRegexp(string $regexp): bool
75 | {
76 | return is_int(@preg_match($regexp, ''));
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/providers/Flagd/src/FlagdProvider.php:
--------------------------------------------------------------------------------
1 | config = Validator::validate($config);
28 |
29 | $this->service = ServiceFactory::fromConfig($this->config);
30 | }
31 |
32 | public function resolveBooleanValue(string $flagKey, bool $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
33 | {
34 | return $this->service->resolveValue($flagKey, FlagValueType::BOOLEAN, $defaultValue, $context);
35 | }
36 |
37 | public function resolveStringValue(string $flagKey, string $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
38 | {
39 | return $this->service->resolveValue($flagKey, FlagValueType::STRING, $defaultValue, $context);
40 | }
41 |
42 | public function resolveIntegerValue(string $flagKey, int $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
43 | {
44 | return $this->service->resolveValue($flagKey, FlagValueType::INTEGER, $defaultValue, $context);
45 | }
46 |
47 | public function resolveFloatValue(string $flagKey, float $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
48 | {
49 | return $this->service->resolveValue($flagKey, FlagValueType::FLOAT, $defaultValue, $context);
50 | }
51 |
52 | public function resolveObjectValue(string $flagKey, mixed $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
53 | {
54 | return $this->service->resolveValue($flagKey, FlagValueType::OBJECT, $defaultValue, $context);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/hooks/Validators/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature Validator Hooks
2 |
3 | [](https://cloud-native.slack.com/archives/C0344AANLA1)
4 | [](https://packagist.org/packages/open-feature/validators-hook)
5 | [](https://packagist.org/packages/open-feature/validators-hook)
6 | 
7 | [](https://packagist.org/packages/open-feature/validators-hook)
8 |
9 | ## Overview
10 |
11 | Validator Hook constructs that provide means to execute validation against resolved feature flag values.
12 |
13 | This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).
14 |
15 | ## Installation
16 |
17 | ```sh
18 | composer require open-feature/validators-hook
19 | ```
20 |
21 | ## Usage
22 |
23 | The following validator hook constructs are available, but more are being worked on over time:
24 |
25 | - `RegexpValidatorHook`
26 |
27 |
28 | ```php
29 | use OpenFeature\Hooks\Validators\RegexpValidatorHook;
30 |
31 | $alphanumericValidator = new RegexpValidatorHook('/^[A-Za-z0-9]+$/');
32 | $hexadecimalValidator = new RegexpValidatorHook('/^[0-9a-f]+$/');
33 | $asciiValidator = new RegexpValidatorHook('/^[ -~]$/');
34 |
35 | // this specific invocation will use this validator
36 | $client->resolveStringValue('test-flag', 'deadbeef', null, new EvaluationOptions([$hexadecimalValidator]));
37 | ```
38 |
39 | For more examples, see the [examples](./examples/).
40 |
41 | ## Development
42 |
43 | ### PHP Versioning
44 |
45 | This library targets PHP version 8.0 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
46 |
47 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
48 |
49 | ### Installation and Dependencies
50 |
51 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
52 |
53 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
54 |
55 | ### Testing
56 |
57 | Run tests with `composer run test`.
58 |
--------------------------------------------------------------------------------
/providers/Flagd/src/http/FlagdResponseResolutionDetailsAdapter.php:
--------------------------------------------------------------------------------
1 | withValue($defaultValue)
23 | ->withError(new ResolutionError(ErrorCode::TYPE_MISMATCH()))
24 | ->build();
25 | }
26 |
27 | /**
28 | * @param string[] $response
29 | * @param mixed[]|bool|DateTime|float|int|string|null $defaultValue
30 | */
31 | public static function forError(array $response, mixed $defaultValue): ResolutionDetails
32 | {
33 | $responseCode = $response['code'];
34 | if ($responseCode && ResponseCodeErrorCodeMap::has($responseCode)) {
35 | /**
36 | * @var ErrorCode $responseErrorCode
37 | */
38 | $responseErrorCode = ResponseCodeErrorCodeMap::get($responseCode);
39 |
40 | $resolutionError = new ResolutionError(
41 | $responseErrorCode,
42 | $response['message'] ?? (string) ErrorCode::GENERAL(),
43 | );
44 | } else {
45 | $resolutionError = new ResolutionError(ErrorCode::GENERAL(), (string) ErrorCode::GENERAL());
46 | }
47 |
48 | return (new ResolutionDetailsBuilder())
49 | ->withValue($defaultValue)
50 | ->withError($resolutionError)
51 | ->build();
52 | }
53 |
54 | /**
55 | * @param array{value: mixed[]|bool|DateTime|float|int|string|null, variant: ?string, reason: ?string} $response
56 | */
57 | public static function forSuccess(array $response): ResolutionDetails
58 | {
59 | $builder = new ResolutionDetailsBuilder();
60 |
61 | $builder->withValue($response['value']);
62 |
63 | if (isset($response['variant'])) {
64 | $builder->withVariant($response['variant']);
65 | }
66 |
67 | if (isset($response['reason'])) {
68 | $builder->withReason($response['reason']);
69 | }
70 |
71 | return $builder->build();
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/providers/CloudBees/examples/CloudBees/src/main.php:
--------------------------------------------------------------------------------
1 | setDevModeKey($devModeKey);
52 |
53 | if (isEnabled('ROLLOUT_LOGGING')) {
54 | $logFile = join(DIRECTORY_SEPARATOR, [
55 | sys_get_temp_dir(),
56 | 'rollout',
57 | 'logs',
58 | 'demo.log'
59 | ]);
60 |
61 | LoggerFactory::setup((new MonologLoggerFactory())
62 | ->setDefaultHandlers([
63 | new StreamHandler($logFile, Logger::DEBUG)
64 | ]));
65 | }
66 |
67 | if (isEnabled('ROLLOUT_CACHE')) {
68 | $roxOptionsBuilder
69 | ->setCacheStorage(new DoctrineCacheStorage(
70 | new ChainCache([
71 | new ArrayCache(),
72 | new FilesystemCache('/tmp/rollout/cache'),
73 | ])
74 | ))
75 | ->setLogCacheHitsAndMisses(true)
76 | ->setConfigFetchIntervalInSeconds(30);
77 | }
78 |
79 | $provider = CloudBeesProvider::setup($apiKey, new RoxOptions($roxOptionsBuilder));
80 |
81 | $api->setProvider($provider);
82 |
83 | // retrieve an OpenFeatureClient
84 | $client = $api->getClient('cloudbees-example', '1.0');
85 |
86 | $flagValue = $client->getBooleanDetails('dev.openfeature.example_flag', true, null, null);
87 |
88 | // make sure to shutdown the CloudBees provider
89 | CloudBeesProvider::shutdown();
90 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature OpenTelemetry Hook
2 |
3 | [](https://cloud-native.slack.com/archives/C0344AANLA1)
4 | [](https://packagist.org/packages/open-feature/otel-hook)
5 | [](https://packagist.org/packages/open-feature/otel-hook)
6 | 
7 | [](https://packagist.org/packages/open-feature/otel-hook)
8 |
9 | ## Overview
10 |
11 | OpenTelemetry is an open specification for distributed tracing, metrics, and logging. It defines a semantic convention for feature flagging which is utilized in this hook to report flag evaluations.
12 |
13 | This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).
14 |
15 | ### Autoloading
16 |
17 | This package supports Composer autoloading. Thus, simply installing the package is all you need in order to immediately get started with OpenTracing for OpenFeature! Examples are provided that showcase the simple setup as well. Check out the Usage section for more info.
18 |
19 | ### OpenTelemetry Package Status
20 |
21 | The OpenTelemetry package for PHP is still in beta, so there could be changes required. However, it exposes global primitives for span retrieval that should not require any configuration upfront for the provider to just work.
22 |
23 | ## Installation
24 |
25 | ```sh
26 | composer require open-feature/otel-hook
27 | ```
28 |
29 | ## Usage
30 |
31 | The `OpenTelemetryHook` should be registered to the OpenFeatureAPI globally for use across all evaluations.
32 |
33 | It makes use of the `open-telemetry/api` packages `Globals` utility for current span retrieval, thus has
34 | no dependency on configuration or injection of tracers.
35 |
36 | ```php
37 | use OpenFeature\Hooks\OpenTelemetry\OpenTelemetryHook;
38 |
39 | OpenTelemetryHook::register();
40 | ```
41 |
42 | For more information on OpenTelemetry, check out [their documentation](https://opentelemetry.io/docs/instrumentation/php/).
43 |
44 | For more examples, see the [examples](./examples/).
45 |
46 | ## Development
47 |
48 | ### PHP Versioning
49 |
50 | This library targets PHP version 8.0 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
51 |
52 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
53 |
54 | ### Installation and Dependencies
55 |
56 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
57 |
58 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
59 |
60 | ### Testing
61 |
62 | Run tests with `composer run test`.
63 |
--------------------------------------------------------------------------------
/hooks/DDTrace/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature DDTrace Hook
2 |
3 | [](https://cloud-native.slack.com/archives/C0344AANLA1)
4 | [](https://packagist.org/packages/open-feature/dd-trace-hook)
5 | [](https://packagist.org/packages/open-feature/dd-trace-hook)
6 | 
7 | [](https://packagist.org/packages/open-feature/dd-trace-hook)
8 |
9 | ## Overview
10 |
11 | `dd-trace` is the Datadog tracing library for PHP. It is built on the OpenTracing specification.
12 |
13 | This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).
14 |
15 | ### Design
16 |
17 | OpenTracing is now an archived project of the CNCF, with suggestions to move towards OpenTelemetry. Feel free to check out our [OpenTelemetry hook for OpenFeature](../OpenTelemetry/README.md) as well. OpenTelemetry defines a semantic convention for feature flagging which is utilized in this hook to report flag evaluations, which is the basis for the log events being performed in this library for `dd-trace`.
18 |
19 | ### Autoloading
20 |
21 | This package supports Composer autoloading. Thus, simply installing the package is all you need in order to immediately get started with Datadog's DDTrace for OpenFeature! Examples are provided that showcase the simple setup as well. Check out the **Usage** section for more info.
22 |
23 | ## Installation
24 |
25 | ```sh
26 | composer require open-feature/dd-trace-hook
27 | ```
28 |
29 | ## Usage
30 |
31 | The `DDTraceHook` should be registered to the OpenFeatureAPI globally for use across all evaluations.
32 |
33 | It makes use of the `dd-trace` packages `Globals` utility for current span retrieval, thus has
34 | no dependency on configuration or injection of tracers.
35 |
36 | ```php
37 | use OpenFeature\Hooks\DDTrace\DDTraceHook;
38 |
39 | DDTraceHook::register();
40 | ```
41 |
42 | For more information on DDTrace, check out [their documentation](https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/php?tab=containers).
43 |
44 | For more examples, see the [examples](./examples/).
45 |
46 | ## Development
47 |
48 | ### PHP Versioning
49 |
50 | This library targets PHP version 8.0 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
51 |
52 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
53 |
54 | ### Installation and Dependencies
55 |
56 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
57 |
58 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
59 |
60 | ### Testing
61 |
62 | Run tests with `composer run test`.
63 |
--------------------------------------------------------------------------------
/hooks/Validators/tests/unit/RegexpValidatorHookTest.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf(Hook::class, $hook);
25 | }
26 |
27 | public function testCannotCreateInvalidRegexpForHook(): void
28 | {
29 | $this->expectException(InvalidRegularExpressionException::class);
30 |
31 | new RegexpValidatorHook('/[\\]/');
32 | }
33 |
34 | public function testAlphanumericRegexpHookPasses(): void
35 | {
36 | $hook = new RegexpValidatorHook('/^[A-Za-z0-9]+$/');
37 |
38 | $this->assertInstanceOf(Hook::class, $hook);
39 |
40 | $this->executeHook($hook, 'Abc123');
41 | }
42 |
43 | public function testAlphanumericRegexpHookFails(): void
44 | {
45 | $hook = new RegexpValidatorHook('/^[A-Za-z0-9]+$/');
46 |
47 | $this->assertInstanceOf(Hook::class, $hook);
48 |
49 | $this->expectException(ValidationException::class);
50 |
51 | $this->executeHook($hook, 'This, a sentence, has other invalid characters.');
52 | }
53 |
54 | public function testHexadecimalRegexpHookPasses(): void
55 | {
56 | $hook = new RegexpValidatorHook('/^[0-9a-f]+$/');
57 |
58 | $this->assertInstanceOf(Hook::class, $hook);
59 |
60 | $this->executeHook($hook, 'deadbeef007');
61 | }
62 |
63 | public function testHexadecimalRegexpHookFails(): void
64 | {
65 | $hook = new RegexpValidatorHook('/^[0-9a-f]+$/');
66 |
67 | $this->assertInstanceOf(Hook::class, $hook);
68 |
69 | $this->expectException(ValidationException::class);
70 |
71 | $this->executeHook($hook, '0123456789abcdefg');
72 | }
73 |
74 | public function testAsciiRegexpHookPasses(): void
75 | {
76 | $hook = new RegexpValidatorHook('/^[ -~]+$/');
77 |
78 | $this->assertInstanceOf(Hook::class, $hook);
79 |
80 | $this->executeHook($hook, 'Only ASCII characters get used here: See?');
81 | }
82 |
83 | public function testAsciiRegexpHookFails(): void
84 | {
85 | $hook = new RegexpValidatorHook('/^[ -~]+$/');
86 |
87 | $this->assertInstanceOf(Hook::class, $hook);
88 |
89 | $this->expectException(ValidationException::class);
90 |
91 | $this->executeHook($hook, '死');
92 | }
93 |
94 | private function executeHook(Hook $hook, string $resolvedValue): void
95 | {
96 | $ctx = HookContextFactory::from(
97 | 'any-key',
98 | FlagValueType::STRING,
99 | 'default-value',
100 | null,
101 | new Metadata('client'),
102 | new Metadata('provider'),
103 | );
104 |
105 | $details = ResolutionDetailsFactory::fromSuccess($resolvedValue);
106 |
107 | $nullHints = new HookHints();
108 |
109 | $hook->after($ctx, $details, $nullHints);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveIntRequest.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveIntRequest
15 | */
16 | class ResolveIntRequest extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * Flag key of the requested flag.
20 | *
21 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
22 | */
23 | protected $flag_key = '';
24 | /**
25 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
26 | *
27 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
28 | */
29 | protected $context = null;
30 |
31 | /**
32 | * Constructor.
33 | *
34 | * @param array $data {
35 | * Optional. Data for populating the Message object.
36 | *
37 | * @type string $flag_key
38 | * Flag key of the requested flag.
39 | * @type \Google\Protobuf\Struct $context
40 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
41 | * }
42 | */
43 | public function __construct($data = NULL) {
44 | \GPBMetadata\Schema\V1\Schema::initOnce();
45 | parent::__construct($data);
46 | }
47 |
48 | /**
49 | * Flag key of the requested flag.
50 | *
51 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
52 | * @return string
53 | */
54 | public function getFlagKey()
55 | {
56 | return $this->flag_key;
57 | }
58 |
59 | /**
60 | * Flag key of the requested flag.
61 | *
62 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
63 | * @param string $var
64 | * @return $this
65 | */
66 | public function setFlagKey($var)
67 | {
68 | GPBUtil::checkString($var, True);
69 | $this->flag_key = $var;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
76 | *
77 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
78 | * @return \Google\Protobuf\Struct|null
79 | */
80 | public function getContext()
81 | {
82 | return $this->context;
83 | }
84 |
85 | public function hasContext()
86 | {
87 | return isset($this->context);
88 | }
89 |
90 | public function clearContext()
91 | {
92 | unset($this->context);
93 | }
94 |
95 | /**
96 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
97 | *
98 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
99 | * @param \Google\Protobuf\Struct $var
100 | * @return $this
101 | */
102 | public function setContext($var)
103 | {
104 | GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
105 | $this->context = $var;
106 |
107 | return $this;
108 | }
109 |
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveFloatRequest.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveFloatRequest
15 | */
16 | class ResolveFloatRequest extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * Flag key of the requested flag.
20 | *
21 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
22 | */
23 | protected $flag_key = '';
24 | /**
25 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
26 | *
27 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
28 | */
29 | protected $context = null;
30 |
31 | /**
32 | * Constructor.
33 | *
34 | * @param array $data {
35 | * Optional. Data for populating the Message object.
36 | *
37 | * @type string $flag_key
38 | * Flag key of the requested flag.
39 | * @type \Google\Protobuf\Struct $context
40 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
41 | * }
42 | */
43 | public function __construct($data = NULL) {
44 | \GPBMetadata\Schema\V1\Schema::initOnce();
45 | parent::__construct($data);
46 | }
47 |
48 | /**
49 | * Flag key of the requested flag.
50 | *
51 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
52 | * @return string
53 | */
54 | public function getFlagKey()
55 | {
56 | return $this->flag_key;
57 | }
58 |
59 | /**
60 | * Flag key of the requested flag.
61 | *
62 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
63 | * @param string $var
64 | * @return $this
65 | */
66 | public function setFlagKey($var)
67 | {
68 | GPBUtil::checkString($var, True);
69 | $this->flag_key = $var;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
76 | *
77 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
78 | * @return \Google\Protobuf\Struct|null
79 | */
80 | public function getContext()
81 | {
82 | return $this->context;
83 | }
84 |
85 | public function hasContext()
86 | {
87 | return isset($this->context);
88 | }
89 |
90 | public function clearContext()
91 | {
92 | unset($this->context);
93 | }
94 |
95 | /**
96 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
97 | *
98 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
99 | * @param \Google\Protobuf\Struct $var
100 | * @return $this
101 | */
102 | public function setContext($var)
103 | {
104 | GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
105 | $this->context = $var;
106 |
107 | return $this;
108 | }
109 |
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveObjectRequest.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveObjectRequest
15 | */
16 | class ResolveObjectRequest extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * Flag key of the requested flag.
20 | *
21 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
22 | */
23 | protected $flag_key = '';
24 | /**
25 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
26 | *
27 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
28 | */
29 | protected $context = null;
30 |
31 | /**
32 | * Constructor.
33 | *
34 | * @param array $data {
35 | * Optional. Data for populating the Message object.
36 | *
37 | * @type string $flag_key
38 | * Flag key of the requested flag.
39 | * @type \Google\Protobuf\Struct $context
40 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
41 | * }
42 | */
43 | public function __construct($data = NULL) {
44 | \GPBMetadata\Schema\V1\Schema::initOnce();
45 | parent::__construct($data);
46 | }
47 |
48 | /**
49 | * Flag key of the requested flag.
50 | *
51 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
52 | * @return string
53 | */
54 | public function getFlagKey()
55 | {
56 | return $this->flag_key;
57 | }
58 |
59 | /**
60 | * Flag key of the requested flag.
61 | *
62 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
63 | * @param string $var
64 | * @return $this
65 | */
66 | public function setFlagKey($var)
67 | {
68 | GPBUtil::checkString($var, True);
69 | $this->flag_key = $var;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
76 | *
77 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
78 | * @return \Google\Protobuf\Struct|null
79 | */
80 | public function getContext()
81 | {
82 | return $this->context;
83 | }
84 |
85 | public function hasContext()
86 | {
87 | return isset($this->context);
88 | }
89 |
90 | public function clearContext()
91 | {
92 | unset($this->context);
93 | }
94 |
95 | /**
96 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
97 | *
98 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
99 | * @param \Google\Protobuf\Struct $var
100 | * @return $this
101 | */
102 | public function setContext($var)
103 | {
104 | GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
105 | $this->context = $var;
106 |
107 | return $this;
108 | }
109 |
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveStringRequest.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveStringRequest
15 | */
16 | class ResolveStringRequest extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * Flag key of the requested flag.
20 | *
21 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
22 | */
23 | protected $flag_key = '';
24 | /**
25 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
26 | *
27 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
28 | */
29 | protected $context = null;
30 |
31 | /**
32 | * Constructor.
33 | *
34 | * @param array $data {
35 | * Optional. Data for populating the Message object.
36 | *
37 | * @type string $flag_key
38 | * Flag key of the requested flag.
39 | * @type \Google\Protobuf\Struct $context
40 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
41 | * }
42 | */
43 | public function __construct($data = NULL) {
44 | \GPBMetadata\Schema\V1\Schema::initOnce();
45 | parent::__construct($data);
46 | }
47 |
48 | /**
49 | * Flag key of the requested flag.
50 | *
51 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
52 | * @return string
53 | */
54 | public function getFlagKey()
55 | {
56 | return $this->flag_key;
57 | }
58 |
59 | /**
60 | * Flag key of the requested flag.
61 | *
62 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
63 | * @param string $var
64 | * @return $this
65 | */
66 | public function setFlagKey($var)
67 | {
68 | GPBUtil::checkString($var, True);
69 | $this->flag_key = $var;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
76 | *
77 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
78 | * @return \Google\Protobuf\Struct|null
79 | */
80 | public function getContext()
81 | {
82 | return $this->context;
83 | }
84 |
85 | public function hasContext()
86 | {
87 | return isset($this->context);
88 | }
89 |
90 | public function clearContext()
91 | {
92 | unset($this->context);
93 | }
94 |
95 | /**
96 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
97 | *
98 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
99 | * @param \Google\Protobuf\Struct $var
100 | * @return $this
101 | */
102 | public function setContext($var)
103 | {
104 | GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
105 | $this->context = $var;
106 |
107 | return $this;
108 | }
109 |
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveBooleanRequest.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveBooleanRequest
15 | */
16 | class ResolveBooleanRequest extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * Flag key of the requested flag.
20 | *
21 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
22 | */
23 | protected $flag_key = '';
24 | /**
25 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
26 | *
27 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
28 | */
29 | protected $context = null;
30 |
31 | /**
32 | * Constructor.
33 | *
34 | * @param array $data {
35 | * Optional. Data for populating the Message object.
36 | *
37 | * @type string $flag_key
38 | * Flag key of the requested flag.
39 | * @type \Google\Protobuf\Struct $context
40 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
41 | * }
42 | */
43 | public function __construct($data = NULL) {
44 | \GPBMetadata\Schema\V1\Schema::initOnce();
45 | parent::__construct($data);
46 | }
47 |
48 | /**
49 | * Flag key of the requested flag.
50 | *
51 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
52 | * @return string
53 | */
54 | public function getFlagKey()
55 | {
56 | return $this->flag_key;
57 | }
58 |
59 | /**
60 | * Flag key of the requested flag.
61 | *
62 | * Generated from protobuf field string flag_key = 1 [json_name = "flagKey"];
63 | * @param string $var
64 | * @return $this
65 | */
66 | public function setFlagKey($var)
67 | {
68 | GPBUtil::checkString($var, True);
69 | $this->flag_key = $var;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
76 | *
77 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
78 | * @return \Google\Protobuf\Struct|null
79 | */
80 | public function getContext()
81 | {
82 | return $this->context;
83 | }
84 |
85 | public function hasContext()
86 | {
87 | return isset($this->context);
88 | }
89 |
90 | public function clearContext()
91 | {
92 | unset($this->context);
93 | }
94 |
95 | /**
96 | * Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context
97 | *
98 | * Generated from protobuf field .google.protobuf.Struct context = 2 [json_name = "context"];
99 | * @param \Google\Protobuf\Struct $var
100 | * @return $this
101 | */
102 | public function setContext($var)
103 | {
104 | GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
105 | $this->context = $var;
106 |
107 | return $this;
108 | }
109 |
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/providers/CloudBees/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature CloudBees Provider for PHP
2 |
3 | [](https://cloud-native.slack.com/archives/C0344AANLA1)
4 | [](https://packagist.org/packages/open-feature/cloudbees-provider)
5 | [](https://packagist.org/packages/open-feature/cloudbees-provider)
6 | 
7 | [](https://packagist.org/packages/open-feature/cloudbees-provider)
8 |
9 | ## Overview
10 |
11 | CloudBees Feature Management is designed to release, control, and measure features at scale. This repository and package provides the client side code for interacting with it via the OpenFeature PHP SDK.
12 |
13 | This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).
14 |
15 | ### Limitations
16 |
17 | There is [an open issue](https://github.com/rollout/rox-php/issues/37) with object deserialization in the upstream library used for Rollout, CloudBees Feature Management SDK for PHP. Objects are also not first-class citizens of the feature management system, as in there is no direct "object" retrieval. Instead the OpenFeature provider builds upon the string retrieval with JSON as the expected format. This doesn't _really_ work though, due to the open issue above. Once that is resolved, JSON objects saved in CloudBees Feature Management system will simply be accessible.
18 |
19 | ## Installation
20 |
21 | ```sh
22 | composer require open-feature/cloudbees-provider
23 | ```
24 |
25 | ## Usage
26 |
27 | The `CloudBeesProvider` can be created with the static `setup` method. This works in much the same way as the `Rox::setup` method, so you can refer to the Rollout documentation for PHP [here](https://docs.cloudbees.com/docs/cloudbees-feature-management/latest/getting-started/php-sdk) for more information.
28 |
29 | ```php
30 | // retrieve the OpenFeatureAPI instance
31 | $api = OpenFeatureAPI::getInstance();
32 |
33 | // setup the CloudBeesProvider with the default settings
34 | $provider = CloudBeesProvider::setup($apiKey);
35 |
36 | // set the OpenFeature provider
37 | $api->setProvider($provider);
38 |
39 | // retrieve an OpenFeatureClient
40 | $client = $api->getClient('cloudbees-example', '1.0');
41 |
42 | $flagValue = $client->getBooleanDetails('dev.openfeature.example_flag', true, null, null);
43 |
44 | // ... do work with the $flagValue
45 |
46 | // IMPORTANT! make sure to shutdown the CloudBees provider
47 | CloudBeesProvider::shutdown();
48 |
49 | ```
50 |
51 | ## Development
52 |
53 | ### PHP Versioning
54 |
55 | This library targets PHP version 8.0 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
56 |
57 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
58 |
59 | ### Installation and Dependencies
60 |
61 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
62 |
63 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
64 |
65 | ### Testing
66 |
67 | Run tests with `composer run test`.
68 |
69 | #### Integration tests
70 |
71 | The integration test suite utilizes a locally available mock server for Rollout called Roxy.
72 |
73 | The docker image is published under `rollout/roxy`.
74 |
75 | For more information on Roxy, see [the documentation](https://docs.cloudbees.com/docs/cloudbees-feature-management/latest/debugging/microservices-automated-testing-and-local-development#_running_roxy).
76 |
--------------------------------------------------------------------------------
/providers/Flagd/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature Flagd Provider for PHP
2 |
3 | [](https://cloud-native.slack.com/archives/C0344AANLA1)
4 | [](https://packagist.org/packages/open-feature/flagd-provider)
5 | [](https://packagist.org/packages/open-feature/flagd-provider)
6 | 
7 | [](https://packagist.org/packages/open-feature/flagd-provider)
8 |
9 | ## Overview
10 |
11 | Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to OpenFeature schema for flag definitions. This repository and package provides the client side code for interacting with it via the OpenFeature PHP SDK.
12 |
13 | This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).
14 |
15 | ## Installation
16 |
17 | ```sh
18 | composer require open-feature/flagd-provider
19 | ```
20 |
21 | ## Usage
22 |
23 | The `FlagdProvider` client constructor takes a single optional argument with 3 fields, their default values correspond to the default arguments supplied to the flagd server:
24 |
25 | ```php
26 | /** @var \Psr\Http\Client\ClientInterface $client */
27 | $client;
28 |
29 | /** @var Psr\Http\Message\RequestFactoryInterface $requestFactory */
30 | $requestFactory;
31 |
32 | /** @var Psr\Http\Message\StreamFactoryInterface $streamFactory */
33 | $streamFactory;
34 |
35 | OpenFeatureAPI::setProvider(new FlagdProvider([
36 | 'protocol' => 'http',
37 | 'host' => 'localhost',
38 | 'port' => 8013,
39 | 'secure' => true,
40 | 'httpConfig' => [
41 | 'client' => $client,
42 | 'requestFactory' => $requestFactory,
43 | 'streamFactory' => $streamFactory,
44 | ],
45 | ]));
46 | ```
47 |
48 | - **protocol**: "http" _(defaults to http)_
49 | - **host**: string _(defaults to "localhost")_
50 | - **port**: number _(defaults to 8013)_
51 | - **secure**: true | false _(defaults to false)_
52 | - **httpConfig**: An array or `HttpConfig` object, providing implementations for PSR interfaces
53 | - **client**: a `ClientInterface` implementation
54 | - **requestFactory**: a `RequestFactoryInterface` implementation
55 | - **streamFactory**: a `StreamFactoryInterface` implementation
56 |
57 | ### gRPC vs HTTP
58 |
59 | The Flagd server is gRPC but offers gRPC Web endpoints that can be accessed over HTTP. The latter is used by the current implementation of the Flagd provider, with future development planned to implement a gRPC native provider option. There are certain flexibilities around HTTP with PHP available, whereas gRPC is an opinionated code-generation strategy, but they are both useful and gRPC native may provide better performance over certain sync/async scenarios. An additional goal will be to provide benchmarking of the Flagd provider's protocol for various scenarios so this decision can be made more easily by consumers of the provider.
60 |
61 | ## Development
62 |
63 | ### PHP Versioning
64 |
65 | This library targets PHP version and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
66 |
67 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
68 |
69 | ### Installation and Dependencies
70 |
71 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
72 |
73 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
74 |
75 | ### Testing
76 |
77 | Run tests with `composer run test`.
78 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ServiceClient.php:
--------------------------------------------------------------------------------
1 | _simpleRequest('/schema.v1.Service/ResolveBoolean',
29 | $argument,
30 | ['\Schema\V1\ResolveBooleanResponse', 'decode'],
31 | $metadata, $options);
32 | }
33 |
34 | /**
35 | * @param \Schema\V1\ResolveStringRequest $argument input argument
36 | * @param array $metadata metadata
37 | * @param array $options call options
38 | * @return \Grpc\UnaryCall
39 | */
40 | public function ResolveString(\Schema\V1\ResolveStringRequest $argument,
41 | $metadata = [], $options = []) {
42 | return $this->_simpleRequest('/schema.v1.Service/ResolveString',
43 | $argument,
44 | ['\Schema\V1\ResolveStringResponse', 'decode'],
45 | $metadata, $options);
46 | }
47 |
48 | /**
49 | * @param \Schema\V1\ResolveFloatRequest $argument input argument
50 | * @param array $metadata metadata
51 | * @param array $options call options
52 | * @return \Grpc\UnaryCall
53 | */
54 | public function ResolveFloat(\Schema\V1\ResolveFloatRequest $argument,
55 | $metadata = [], $options = []) {
56 | return $this->_simpleRequest('/schema.v1.Service/ResolveFloat',
57 | $argument,
58 | ['\Schema\V1\ResolveFloatResponse', 'decode'],
59 | $metadata, $options);
60 | }
61 |
62 | /**
63 | * @param \Schema\V1\ResolveIntRequest $argument input argument
64 | * @param array $metadata metadata
65 | * @param array $options call options
66 | * @return \Grpc\UnaryCall
67 | */
68 | public function ResolveInt(\Schema\V1\ResolveIntRequest $argument,
69 | $metadata = [], $options = []) {
70 | return $this->_simpleRequest('/schema.v1.Service/ResolveInt',
71 | $argument,
72 | ['\Schema\V1\ResolveIntResponse', 'decode'],
73 | $metadata, $options);
74 | }
75 |
76 | /**
77 | * @param \Schema\V1\ResolveObjectRequest $argument input argument
78 | * @param array $metadata metadata
79 | * @param array $options call options
80 | * @return \Grpc\UnaryCall
81 | */
82 | public function ResolveObject(\Schema\V1\ResolveObjectRequest $argument,
83 | $metadata = [], $options = []) {
84 | return $this->_simpleRequest('/schema.v1.Service/ResolveObject',
85 | $argument,
86 | ['\Schema\V1\ResolveObjectResponse', 'decode'],
87 | $metadata, $options);
88 | }
89 |
90 | /**
91 | * @param \Google\Protobuf\GPBEmpty $argument input argument
92 | * @param array $metadata metadata
93 | * @param array $options call options
94 | * @return \Grpc\ServerStreamingCall
95 | */
96 | public function EventStream(\Google\Protobuf\GPBEmpty $argument,
97 | $metadata = [], $options = []) {
98 | return $this->_serverStreamRequest('/schema.v1.Service/EventStream',
99 | $argument,
100 | ['\Schema\V1\EventStreamResponse', 'decode'],
101 | $metadata, $options);
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/hooks/OpenTelemetry/src/OpenTelemetryHook.php:
--------------------------------------------------------------------------------
1 | addHooks(self::$instance);
50 | self::$registeredHook = true;
51 | }
52 |
53 | private static ?OpenTelemetryHook $instance = null;
54 | private static bool $registeredHook = false;
55 |
56 | public function before(HookContext $context, HookHints $hints): ?EvaluationContext
57 | {
58 | return null;
59 | }
60 |
61 | public function after(HookContext $context, ResolutionDetails $details, HookHints $hints): void
62 | {
63 | $span = Span::getCurrent();
64 |
65 | $span->addEvent(self::EVENT_NAME, [
66 | self::FLAG_KEY => $context->getFlagKey(),
67 | self::FLAG_PROVIDER_NAME => OpenFeatureAPI::getInstance()->getProvider()->getMetadata()->getName(),
68 | self::FLAG_VARIANT => $details->getVariant(),
69 | ]);
70 | }
71 |
72 | public function error(HookContext $context, Throwable $error, HookHints $hints): void
73 | {
74 | $span = Span::getCurrent();
75 |
76 | $span->recordException($error, [
77 | self::FLAG_KEY => $context->getFlagKey(),
78 | self::FLAG_PROVIDER_NAME => OpenFeatureAPI::getInstance()->getProvider()->getMetadata()->getName(),
79 | ]);
80 | }
81 |
82 | public function finally(HookContext $context, HookHints $hints): void
83 | {
84 | // no-op
85 | }
86 |
87 | public function supportsFlagValueType(string $flagValueType): bool
88 | {
89 | return true;
90 | }
91 |
92 | /**
93 | * Hooks can be cleared by other means so we can't simply memoize whether a registration has occurred
94 | *
95 | * However if no registration has yet happened then we can absolutely determine that the hook will
96 | * not be registered yet.
97 | */
98 | private static function isRegisteredInHooks(): bool
99 | {
100 | foreach (OpenFeatureAPI::getInstance()->getHooks() as $hook) {
101 | if ($hook instanceof OpenTelemetryHook) {
102 | return true;
103 | }
104 | }
105 |
106 | return false;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/EventStreamResponse.php:
--------------------------------------------------------------------------------
1 | schema.v1.EventStreamResponse
15 | */
16 | class EventStreamResponse extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * String key indicating the type of event that is being received, e.g. provider_ready or configuration_change
20 | *
21 | * Generated from protobuf field string type = 1 [json_name = "type"];
22 | */
23 | protected $type = '';
24 | /**
25 | * Object structure for use when sending relevant metadata to provide context to the event.
26 | * Can be left unset when it is not required.
27 | *
28 | * Generated from protobuf field .google.protobuf.Struct data = 2 [json_name = "data"];
29 | */
30 | protected $data = null;
31 |
32 | /**
33 | * Constructor.
34 | *
35 | * @param array $data {
36 | * Optional. Data for populating the Message object.
37 | *
38 | * @type string $type
39 | * String key indicating the type of event that is being received, e.g. provider_ready or configuration_change
40 | * @type \Google\Protobuf\Struct $data
41 | * Object structure for use when sending relevant metadata to provide context to the event.
42 | * Can be left unset when it is not required.
43 | * }
44 | */
45 | public function __construct($data = NULL) {
46 | \GPBMetadata\Schema\V1\Schema::initOnce();
47 | parent::__construct($data);
48 | }
49 |
50 | /**
51 | * String key indicating the type of event that is being received, e.g. provider_ready or configuration_change
52 | *
53 | * Generated from protobuf field string type = 1 [json_name = "type"];
54 | * @return string
55 | */
56 | public function getType()
57 | {
58 | return $this->type;
59 | }
60 |
61 | /**
62 | * String key indicating the type of event that is being received, e.g. provider_ready or configuration_change
63 | *
64 | * Generated from protobuf field string type = 1 [json_name = "type"];
65 | * @param string $var
66 | * @return $this
67 | */
68 | public function setType($var)
69 | {
70 | GPBUtil::checkString($var, True);
71 | $this->type = $var;
72 |
73 | return $this;
74 | }
75 |
76 | /**
77 | * Object structure for use when sending relevant metadata to provide context to the event.
78 | * Can be left unset when it is not required.
79 | *
80 | * Generated from protobuf field .google.protobuf.Struct data = 2 [json_name = "data"];
81 | * @return \Google\Protobuf\Struct|null
82 | */
83 | public function getData()
84 | {
85 | return $this->data;
86 | }
87 |
88 | public function hasData()
89 | {
90 | return isset($this->data);
91 | }
92 |
93 | public function clearData()
94 | {
95 | unset($this->data);
96 | }
97 |
98 | /**
99 | * Object structure for use when sending relevant metadata to provide context to the event.
100 | * Can be left unset when it is not required.
101 | *
102 | * Generated from protobuf field .google.protobuf.Struct data = 2 [json_name = "data"];
103 | * @param \Google\Protobuf\Struct $var
104 | * @return $this
105 | */
106 | public function setData($var)
107 | {
108 | GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
109 | $this->data = $var;
110 |
111 | return $this;
112 | }
113 |
114 | }
115 |
116 |
--------------------------------------------------------------------------------
/providers/CloudBees/tests/integration/CloudBeesProviderTest.php:
--------------------------------------------------------------------------------
1 | setRoxyURL('http://localhost:4444/')),
31 | );
32 |
33 | $this->instance = $instance;
34 | }
35 |
36 | public function testCanBeInstantiated(): void
37 | {
38 | // Given
39 | $instance = $this->instance;
40 |
41 | // Then
42 | $this->assertNotNull($instance);
43 | $this->assertInstanceOf(CloudBeesProvider::class, $instance);
44 | $this->assertInstanceOf(Provider::class, $instance);
45 | }
46 |
47 | public function testCanResolveBool(): void
48 | {
49 | // Given
50 | $flagName = 'dev.openfeature.bool_flag';
51 | $defaultValue = false;
52 | $expectedValue = true;
53 |
54 | // When
55 | $details = $this->instance->resolveBooleanValue($flagName, $defaultValue);
56 | $value = $details->getValue();
57 |
58 | // Then
59 | $this->assertNotEquals($value, $defaultValue);
60 | $this->assertEquals($value, $expectedValue);
61 | }
62 |
63 | public function testCanResolveInt(): void
64 | {
65 | // Given
66 | $flagName = 'dev.openfeature.int_flag';
67 | $defaultValue = 0;
68 | $expectedValue = 42;
69 |
70 | // When
71 | $details = $this->instance->resolveIntegerValue($flagName, $defaultValue);
72 | $value = $details->getValue();
73 |
74 | // Then
75 | $this->assertNotEquals($value, $defaultValue);
76 | $this->assertEquals($value, $expectedValue);
77 | }
78 |
79 | public function testCanResolveFloat(): void
80 | {
81 | // Given
82 | $flagName = 'dev.openfeature.float_flag';
83 | $defaultValue = 0.0;
84 | $expectedValue = 3.14;
85 |
86 | // When
87 | $details = $this->instance->resolveFloatValue($flagName, $defaultValue);
88 | $value = $details->getValue();
89 |
90 | // Then
91 | $this->assertNotEquals($value, $defaultValue);
92 | $this->assertEquals($value, $expectedValue);
93 | }
94 |
95 | public function testCanResolveString(): void
96 | {
97 | // Given
98 | $flagName = 'dev.openfeature.string_flag';
99 | $defaultValue = 'default';
100 | $expectedValue = 'string-value';
101 |
102 | // When
103 | $details = $this->instance->resolveStringValue($flagName, $defaultValue);
104 | $value = $details->getValue();
105 |
106 | // Then
107 | $this->assertNotEquals($value, $defaultValue);
108 | $this->assertEquals($value, $expectedValue);
109 | }
110 |
111 | public function testCanResolveObject(): void
112 | {
113 | // Given
114 | $flagName = 'dev.openfeature.object_flag';
115 | $defaultValue = ['anything' => 'at all'];
116 | $expectedValue = [];
117 |
118 | // When
119 | $details = $this->instance->resolveObjectValue($flagName, $defaultValue);
120 | $value = $details->getValue();
121 |
122 | // Then
123 | $this->assertNotEquals($value, $defaultValue);
124 | $this->assertEquals($value, $expectedValue);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/providers/Split/README.md:
--------------------------------------------------------------------------------
1 | # OpenFeature SplitIO Provider for PHP
2 |
3 | [](https://cloud-native.slack.com/archives/C0344AANLA1)
4 | [](https://packagist.org/packages/open-feature/split-provider)
5 | [](https://packagist.org/packages/open-feature/split-provider)
6 | 
7 | [](https://packagist.org/packages/open-feature/split-provider)
8 |
9 | ## Overview
10 |
11 | Split is a feature delivery platform that powers feature flag management, software experimentation, and continuous delivery. This repository and package provides the client side code for interacting with it via the OpenFeature PHP SDK.
12 |
13 | This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).
14 |
15 | ## Installation
16 |
17 | ```sh
18 | composer require open-feature/split-provider
19 | ```
20 |
21 | ## Usage
22 |
23 | The `SplitProvider` client constructor takes a single optional argument with 3 fields, their default values correspond to the default arguments supplied to the flagd server:
24 |
25 | ```php
26 | $splitConfig = [
27 | 'cache' => [
28 | 'adapter' => 'predis',
29 | 'parameters' => [
30 | 'scheme' => 'tcp',
31 | 'host' => getenv('REDIS_HOST'),
32 | 'port' => getenv('REDIS_PORT'),
33 | 'timeout' => 881,
34 | ],
35 | 'options' => [
36 | 'prefix' => '',
37 | ],
38 | ],
39 | ];
40 |
41 | $splitApiKey = getenv('SPLIT_API_KEY');
42 |
43 | $provider = new SplitProvider($splitApiKey, $splitConfig);
44 | ```
45 |
46 | For more information on the configuration options, please see the Split PHP SDK documentation on [Configuration](https://help.split.io/hc/en-us/articles/360020350372-PHP-SDK#configuration).
47 |
48 | Resolving values requires the use of the `EvaluationContext, where you can provide the `targetingKey` for the evaluation (the identifier which represents the user/account/etc.)
49 |
50 | ```php
51 | $client = $api->getClient('split-example', '1.0.0');
52 |
53 | $featureEnabled = $client->getBooleanDetails('dev.openfeature.example_flag', false, new EvaluationContext('user-id'), null);
54 |
55 | if ($featureEnabled) {
56 | // do new logic here
57 | } else {
58 | // do old logic here
59 | }
60 | ```
61 |
62 | You can provide more elaborate attributes to resolve values, but the values must conform to the requirements of the Split SDK. Information on what attributes are allowed can be found in the [Attributes section](https://help.split.io/hc/en-us/articles/360020350372-PHP-SDK#attribute-syntax) of the PHP SDK documentation.
63 |
64 | ```php
65 | $client = $api->getClient('split-example', '1.0.0');
66 |
67 | $featureEnabled = $client->getBooleanDetails('dev.openfeature.example_flag', false, new EvaluationContext('user-id', [
68 | 'plan_type' => 'growth',
69 | 'registered_date' => (new DateTime('now', new DateTimeZone('UTC')))->getTimestamp(),
70 | 'deal_size' => 10000,
71 | 'paying_customer' => True,
72 | 'permissions' => ['gold','silver','platinum'],
73 | ]), null);
74 |
75 | if ($featureEnabled) {
76 | // do new logic here
77 | } else {
78 | // do old logic here
79 | }
80 | ```
81 |
82 | ## Development
83 |
84 | ### PHP Versioning
85 |
86 | This library targets PHP version 8.0 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.
87 |
88 | This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.
89 |
90 | ### Installation and Dependencies
91 |
92 | Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.
93 |
94 | We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.
95 |
96 | ### Testing
97 |
98 | Run tests with `composer run test`.
99 |
--------------------------------------------------------------------------------
/providers/Flagd/src/config/Validator.php:
--------------------------------------------------------------------------------
1 | getHost());
55 | $port = self::validatePort($config->getPort());
56 | $protocol = self::validateProtocol($config->getProtocol());
57 | $secure = self::validateSecure($config->isSecure());
58 | $httpConfig = self::validateHttpConfig($config->getHttpConfig());
59 |
60 | return new Config($host, $port, $protocol, $secure, $httpConfig);
61 | }
62 |
63 | private static function validateSecure(mixed $secure): bool
64 | {
65 | if (is_bool($secure)) {
66 | return $secure;
67 | }
68 |
69 | return Defaults::DEFAULT_SECURE;
70 | }
71 |
72 | private static function validateHost(mixed $host): string
73 | {
74 | if (is_string($host) && preg_match(self::VALID_HOST_REGEXP, $host)) {
75 | return $host;
76 | }
77 |
78 | return Defaults::DEFAULT_HOST;
79 | }
80 |
81 | private static function validatePort(mixed $port): int
82 | {
83 | [$minPort, $maxPort] = self::VALID_PORT_RANGE;
84 |
85 | if (is_int($port) && $port >= $minPort && $port <= $maxPort) {
86 | return $port;
87 | }
88 |
89 | return Defaults::DEFAULT_PORT;
90 | }
91 |
92 | private static function validateProtocol(mixed $protocol): string
93 | {
94 | if (is_string($protocol) && in_array($protocol, self::VALID_PROTOCOLS)) {
95 | return $protocol;
96 | }
97 |
98 | return Defaults::DEFAULT_PROTOCOL;
99 | }
100 |
101 | private static function validateHttpConfig(mixed $httpConfig): ?IHttpConfig
102 | {
103 | if (is_null($httpConfig)) {
104 | return null;
105 | }
106 |
107 | if (is_array($httpConfig)) {
108 | /** @var ClientInterface|mixed $client */
109 | $client = $httpConfig['client'];
110 | /** @var RequestFactoryInterface|mixed $requestFactory */
111 | $requestFactory = $httpConfig['requestFactory'];
112 | /** @var StreamFactoryInterface|mixed $streamFactory */
113 | $streamFactory = $httpConfig['streamFactory'];
114 |
115 | if (
116 | $client instanceof ClientInterface
117 | && $requestFactory instanceof RequestFactoryInterface
118 | && $streamFactory instanceof StreamFactoryInterface
119 | ) {
120 | return new HttpConfig($client, $requestFactory, $streamFactory);
121 | }
122 | }
123 |
124 | if ($httpConfig instanceof IHttpConfig) {
125 | return $httpConfig;
126 | }
127 |
128 | return null;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveIntResponse.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveIntResponse
15 | */
16 | class ResolveIntResponse extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * The response value of the int flag evaluation, will be unset in the case of error.
20 | *
21 | * Generated from protobuf field int64 value = 1 [json_name = "value"];
22 | */
23 | protected $value = 0;
24 | /**
25 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
26 | *
27 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
28 | */
29 | protected $reason = '';
30 | /**
31 | * The variant name of the returned flag value.
32 | *
33 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
34 | */
35 | protected $variant = '';
36 |
37 | /**
38 | * Constructor.
39 | *
40 | * @param array $data {
41 | * Optional. Data for populating the Message object.
42 | *
43 | * @type int|string $value
44 | * The response value of the int flag evaluation, will be unset in the case of error.
45 | * @type string $reason
46 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
47 | * @type string $variant
48 | * The variant name of the returned flag value.
49 | * }
50 | */
51 | public function __construct($data = NULL) {
52 | \GPBMetadata\Schema\V1\Schema::initOnce();
53 | parent::__construct($data);
54 | }
55 |
56 | /**
57 | * The response value of the int flag evaluation, will be unset in the case of error.
58 | *
59 | * Generated from protobuf field int64 value = 1 [json_name = "value"];
60 | * @return int|string
61 | */
62 | public function getValue()
63 | {
64 | return $this->value;
65 | }
66 |
67 | /**
68 | * The response value of the int flag evaluation, will be unset in the case of error.
69 | *
70 | * Generated from protobuf field int64 value = 1 [json_name = "value"];
71 | * @param int|string $var
72 | * @return $this
73 | */
74 | public function setValue($var)
75 | {
76 | GPBUtil::checkInt64($var);
77 | $this->value = $var;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
84 | *
85 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
86 | * @return string
87 | */
88 | public function getReason()
89 | {
90 | return $this->reason;
91 | }
92 |
93 | /**
94 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
95 | *
96 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
97 | * @param string $var
98 | * @return $this
99 | */
100 | public function setReason($var)
101 | {
102 | GPBUtil::checkString($var, True);
103 | $this->reason = $var;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * The variant name of the returned flag value.
110 | *
111 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
112 | * @return string
113 | */
114 | public function getVariant()
115 | {
116 | return $this->variant;
117 | }
118 |
119 | /**
120 | * The variant name of the returned flag value.
121 | *
122 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
123 | * @param string $var
124 | * @return $this
125 | */
126 | public function setVariant($var)
127 | {
128 | GPBUtil::checkString($var, True);
129 | $this->variant = $var;
130 |
131 | return $this;
132 | }
133 |
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveFloatResponse.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveFloatResponse
15 | */
16 | class ResolveFloatResponse extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * The response value of the float flag evaluation, will be empty in the case of error.
20 | *
21 | * Generated from protobuf field double value = 1 [json_name = "value"];
22 | */
23 | protected $value = 0.0;
24 | /**
25 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
26 | *
27 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
28 | */
29 | protected $reason = '';
30 | /**
31 | * The variant name of the returned flag value.
32 | *
33 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
34 | */
35 | protected $variant = '';
36 |
37 | /**
38 | * Constructor.
39 | *
40 | * @param array $data {
41 | * Optional. Data for populating the Message object.
42 | *
43 | * @type float $value
44 | * The response value of the float flag evaluation, will be empty in the case of error.
45 | * @type string $reason
46 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
47 | * @type string $variant
48 | * The variant name of the returned flag value.
49 | * }
50 | */
51 | public function __construct($data = NULL) {
52 | \GPBMetadata\Schema\V1\Schema::initOnce();
53 | parent::__construct($data);
54 | }
55 |
56 | /**
57 | * The response value of the float flag evaluation, will be empty in the case of error.
58 | *
59 | * Generated from protobuf field double value = 1 [json_name = "value"];
60 | * @return float
61 | */
62 | public function getValue()
63 | {
64 | return $this->value;
65 | }
66 |
67 | /**
68 | * The response value of the float flag evaluation, will be empty in the case of error.
69 | *
70 | * Generated from protobuf field double value = 1 [json_name = "value"];
71 | * @param float $var
72 | * @return $this
73 | */
74 | public function setValue($var)
75 | {
76 | GPBUtil::checkDouble($var);
77 | $this->value = $var;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
84 | *
85 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
86 | * @return string
87 | */
88 | public function getReason()
89 | {
90 | return $this->reason;
91 | }
92 |
93 | /**
94 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
95 | *
96 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
97 | * @param string $var
98 | * @return $this
99 | */
100 | public function setReason($var)
101 | {
102 | GPBUtil::checkString($var, True);
103 | $this->reason = $var;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * The variant name of the returned flag value.
110 | *
111 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
112 | * @return string
113 | */
114 | public function getVariant()
115 | {
116 | return $this->variant;
117 | }
118 |
119 | /**
120 | * The variant name of the returned flag value.
121 | *
122 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
123 | * @param string $var
124 | * @return $this
125 | */
126 | public function setVariant($var)
127 | {
128 | GPBUtil::checkString($var, True);
129 | $this->variant = $var;
130 |
131 | return $this;
132 | }
133 |
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveBooleanResponse.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveBooleanResponse
15 | */
16 | class ResolveBooleanResponse extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * The response value of the boolean flag evaluation, will be unset in the case of error.
20 | *
21 | * Generated from protobuf field bool value = 1 [json_name = "value"];
22 | */
23 | protected $value = false;
24 | /**
25 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
26 | *
27 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
28 | */
29 | protected $reason = '';
30 | /**
31 | * The variant name of the returned flag value.
32 | *
33 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
34 | */
35 | protected $variant = '';
36 |
37 | /**
38 | * Constructor.
39 | *
40 | * @param array $data {
41 | * Optional. Data for populating the Message object.
42 | *
43 | * @type bool $value
44 | * The response value of the boolean flag evaluation, will be unset in the case of error.
45 | * @type string $reason
46 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
47 | * @type string $variant
48 | * The variant name of the returned flag value.
49 | * }
50 | */
51 | public function __construct($data = NULL) {
52 | \GPBMetadata\Schema\V1\Schema::initOnce();
53 | parent::__construct($data);
54 | }
55 |
56 | /**
57 | * The response value of the boolean flag evaluation, will be unset in the case of error.
58 | *
59 | * Generated from protobuf field bool value = 1 [json_name = "value"];
60 | * @return bool
61 | */
62 | public function getValue()
63 | {
64 | return $this->value;
65 | }
66 |
67 | /**
68 | * The response value of the boolean flag evaluation, will be unset in the case of error.
69 | *
70 | * Generated from protobuf field bool value = 1 [json_name = "value"];
71 | * @param bool $var
72 | * @return $this
73 | */
74 | public function setValue($var)
75 | {
76 | GPBUtil::checkBool($var);
77 | $this->value = $var;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
84 | *
85 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
86 | * @return string
87 | */
88 | public function getReason()
89 | {
90 | return $this->reason;
91 | }
92 |
93 | /**
94 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
95 | *
96 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
97 | * @param string $var
98 | * @return $this
99 | */
100 | public function setReason($var)
101 | {
102 | GPBUtil::checkString($var, True);
103 | $this->reason = $var;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * The variant name of the returned flag value.
110 | *
111 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
112 | * @return string
113 | */
114 | public function getVariant()
115 | {
116 | return $this->variant;
117 | }
118 |
119 | /**
120 | * The variant name of the returned flag value.
121 | *
122 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
123 | * @param string $var
124 | * @return $this
125 | */
126 | public function setVariant($var)
127 | {
128 | GPBUtil::checkString($var, True);
129 | $this->variant = $var;
130 |
131 | return $this;
132 | }
133 |
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/providers/Flagd/proto/php/Schema/V1/ResolveStringResponse.php:
--------------------------------------------------------------------------------
1 | schema.v1.ResolveStringResponse
15 | */
16 | class ResolveStringResponse extends \Google\Protobuf\Internal\Message
17 | {
18 | /**
19 | * The response value of the string flag evaluation, will be unset in the case of error.
20 | *
21 | * Generated from protobuf field string value = 1 [json_name = "value"];
22 | */
23 | protected $value = '';
24 | /**
25 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
26 | *
27 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
28 | */
29 | protected $reason = '';
30 | /**
31 | * The variant name of the returned flag value.
32 | *
33 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
34 | */
35 | protected $variant = '';
36 |
37 | /**
38 | * Constructor.
39 | *
40 | * @param array $data {
41 | * Optional. Data for populating the Message object.
42 | *
43 | * @type string $value
44 | * The response value of the string flag evaluation, will be unset in the case of error.
45 | * @type string $reason
46 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
47 | * @type string $variant
48 | * The variant name of the returned flag value.
49 | * }
50 | */
51 | public function __construct($data = NULL) {
52 | \GPBMetadata\Schema\V1\Schema::initOnce();
53 | parent::__construct($data);
54 | }
55 |
56 | /**
57 | * The response value of the string flag evaluation, will be unset in the case of error.
58 | *
59 | * Generated from protobuf field string value = 1 [json_name = "value"];
60 | * @return string
61 | */
62 | public function getValue()
63 | {
64 | return $this->value;
65 | }
66 |
67 | /**
68 | * The response value of the string flag evaluation, will be unset in the case of error.
69 | *
70 | * Generated from protobuf field string value = 1 [json_name = "value"];
71 | * @param string $var
72 | * @return $this
73 | */
74 | public function setValue($var)
75 | {
76 | GPBUtil::checkString($var, True);
77 | $this->value = $var;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
84 | *
85 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
86 | * @return string
87 | */
88 | public function getReason()
89 | {
90 | return $this->reason;
91 | }
92 |
93 | /**
94 | * The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details
95 | *
96 | * Generated from protobuf field string reason = 2 [json_name = "reason"];
97 | * @param string $var
98 | * @return $this
99 | */
100 | public function setReason($var)
101 | {
102 | GPBUtil::checkString($var, True);
103 | $this->reason = $var;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * The variant name of the returned flag value.
110 | *
111 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
112 | * @return string
113 | */
114 | public function getVariant()
115 | {
116 | return $this->variant;
117 | }
118 |
119 | /**
120 | * The variant name of the returned flag value.
121 | *
122 | * Generated from protobuf field string variant = 3 [json_name = "variant"];
123 | * @param string $var
124 | * @return $this
125 | */
126 | public function setVariant($var)
127 | {
128 | GPBUtil::checkString($var, True);
129 | $this->variant = $var;
130 |
131 | return $this;
132 | }
133 |
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/hooks/DDTrace/src/DDTraceHook.php:
--------------------------------------------------------------------------------
1 | addHooks(self::$instance);
55 | self::$registeredHook = true;
56 | }
57 |
58 | private static ?DDTraceHook $instance = null;
59 | private static bool $registeredHook = false;
60 |
61 | public function before(HookContext $context, HookHints $hints): ?EvaluationContext
62 | {
63 | return null;
64 | }
65 |
66 | public function after(HookContext $context, ResolutionDetails $details, HookHints $hints): void
67 | {
68 | $span = self::getCurrentSpan();
69 | if (!$span) {
70 | return;
71 | }
72 |
73 | $span->log([
74 | Tag::LOG_MESSAGE => [
75 | self::FLAG_KEY => $context->getFlagKey(),
76 | self::FLAG_PROVIDER_NAME => OpenFeatureAPI::getInstance()->getProvider()->getMetadata()->getName(),
77 | self::FLAG_VARIANT => $details->getVariant(),
78 | ],
79 | ], new DateTimeImmutable('now'));
80 | }
81 |
82 | public function error(HookContext $context, Throwable $error, HookHints $hints): void
83 | {
84 | $span = self::getCurrentSpan();
85 | if (!$span) {
86 | return;
87 | }
88 |
89 | $span->log([
90 | Tag::LOG_ERROR_OBJECT => [
91 | self::FLAG_KEY => $context->getFlagKey(),
92 | self::FLAG_PROVIDER_NAME => OpenFeatureAPI::getInstance()->getProvider()->getMetadata()->getName(),
93 | ],
94 | ], new DateTimeImmutable('now'));
95 | }
96 |
97 | public function finally(HookContext $context, HookHints $hints): void
98 | {
99 | // no-op
100 | }
101 |
102 | public function supportsFlagValueType(string $flagValueType): bool
103 | {
104 | return true;
105 | }
106 |
107 | /**
108 | * Hooks can be cleared by other means so we can't simply memoize whether a registration has occurred
109 | *
110 | * However if no registration has yet happened then we can absolutely determine that the hook will
111 | * not be registered yet.
112 | */
113 | private static function isRegisteredInHooks(): bool
114 | {
115 | foreach (OpenFeatureAPI::getInstance()->getHooks() as $hook) {
116 | if ($hook instanceof DDTraceHook) {
117 | return true;
118 | }
119 | }
120 |
121 | return false;
122 | }
123 |
124 | private static function getCurrentSpan(): ?Span
125 | {
126 | if (!class_exists(GlobalTracer::class)) {
127 | return null;
128 | }
129 |
130 | return GlobalTracer::get()->getActiveSpan();
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/devenv.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "devenv": {
4 | "locked": {
5 | "dir": "src/modules",
6 | "lastModified": 1675875772,
7 | "narHash": "sha256-sYXHPZ4tsjdG+UXK0mYnABhiS/RuzHiV9uGOU9YakwE=",
8 | "owner": "cachix",
9 | "repo": "devenv",
10 | "rev": "eac5eb12eb42765f5f252972dc876d1f96b03dfe",
11 | "type": "github"
12 | },
13 | "original": {
14 | "dir": "src/modules",
15 | "owner": "cachix",
16 | "repo": "devenv",
17 | "type": "github"
18 | }
19 | },
20 | "flake-compat": {
21 | "flake": false,
22 | "locked": {
23 | "lastModified": 1673956053,
24 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
25 | "owner": "edolstra",
26 | "repo": "flake-compat",
27 | "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
28 | "type": "github"
29 | },
30 | "original": {
31 | "owner": "edolstra",
32 | "repo": "flake-compat",
33 | "type": "github"
34 | }
35 | },
36 | "flake-utils": {
37 | "locked": {
38 | "lastModified": 1667395993,
39 | "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
40 | "owner": "numtide",
41 | "repo": "flake-utils",
42 | "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
43 | "type": "github"
44 | },
45 | "original": {
46 | "owner": "numtide",
47 | "repo": "flake-utils",
48 | "type": "github"
49 | }
50 | },
51 | "gitignore": {
52 | "inputs": {
53 | "nixpkgs": [
54 | "pre-commit-hooks",
55 | "nixpkgs"
56 | ]
57 | },
58 | "locked": {
59 | "lastModified": 1660459072,
60 | "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
61 | "owner": "hercules-ci",
62 | "repo": "gitignore.nix",
63 | "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
64 | "type": "github"
65 | },
66 | "original": {
67 | "owner": "hercules-ci",
68 | "repo": "gitignore.nix",
69 | "type": "github"
70 | }
71 | },
72 | "nixpkgs": {
73 | "locked": {
74 | "lastModified": 1675758091,
75 | "narHash": "sha256-7gFSQbSVAFUHtGCNHPF7mPc5CcqDk9M2+inlVPZSneg=",
76 | "owner": "NixOS",
77 | "repo": "nixpkgs",
78 | "rev": "747927516efcb5e31ba03b7ff32f61f6d47e7d87",
79 | "type": "github"
80 | },
81 | "original": {
82 | "owner": "NixOS",
83 | "ref": "nixpkgs-unstable",
84 | "repo": "nixpkgs",
85 | "type": "github"
86 | }
87 | },
88 | "nixpkgs-stable": {
89 | "locked": {
90 | "lastModified": 1673800717,
91 | "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
92 | "owner": "NixOS",
93 | "repo": "nixpkgs",
94 | "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
95 | "type": "github"
96 | },
97 | "original": {
98 | "owner": "NixOS",
99 | "ref": "nixos-22.11",
100 | "repo": "nixpkgs",
101 | "type": "github"
102 | }
103 | },
104 | "nixpkgs_2": {
105 | "locked": {
106 | "lastModified": 1671271357,
107 | "narHash": "sha256-xRJdLbWK4v2SewmSStYrcLa0YGJpleufl44A19XSW8k=",
108 | "owner": "NixOS",
109 | "repo": "nixpkgs",
110 | "rev": "40f79f003b6377bd2f4ed4027dde1f8f922995dd",
111 | "type": "github"
112 | },
113 | "original": {
114 | "owner": "NixOS",
115 | "ref": "nixos-unstable",
116 | "repo": "nixpkgs",
117 | "type": "github"
118 | }
119 | },
120 | "pre-commit-hooks": {
121 | "inputs": {
122 | "flake-compat": "flake-compat",
123 | "flake-utils": "flake-utils",
124 | "gitignore": "gitignore",
125 | "nixpkgs": "nixpkgs_2",
126 | "nixpkgs-stable": "nixpkgs-stable"
127 | },
128 | "locked": {
129 | "lastModified": 1675688762,
130 | "narHash": "sha256-oit/SxMk0B380ASuztBGQLe8TttO1GJiXF8aZY9AYEc=",
131 | "owner": "cachix",
132 | "repo": "pre-commit-hooks.nix",
133 | "rev": "ab608394886fb04b8a5df3cb0bab2598400e3634",
134 | "type": "github"
135 | },
136 | "original": {
137 | "owner": "cachix",
138 | "repo": "pre-commit-hooks.nix",
139 | "type": "github"
140 | }
141 | },
142 | "root": {
143 | "inputs": {
144 | "devenv": "devenv",
145 | "nixpkgs": "nixpkgs",
146 | "pre-commit-hooks": "pre-commit-hooks"
147 | }
148 | }
149 | },
150 | "root": "root",
151 | "version": 7
152 | }
153 |
--------------------------------------------------------------------------------
/providers/CloudBees/src/CloudBeesProvider.php:
--------------------------------------------------------------------------------
1 | resolve(
67 | $defaultValue,
68 | fn () => Rox::dynamicApi()->isEnabled($flagKey, $defaultValue, ContextAdapter::adapt($context)),
69 | );
70 | }
71 |
72 | public function resolveStringValue(string $flagKey, string $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
73 | {
74 | return $this->resolve(
75 | $defaultValue,
76 | fn () => Rox::dynamicApi()->getValue($flagKey, $defaultValue, [/* TODO: Variations */], ContextAdapter::adapt($context)),
77 | );
78 | }
79 |
80 | public function resolveIntegerValue(string $flagKey, int $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
81 | {
82 | return $this->resolve(
83 | $defaultValue,
84 | fn () => Rox::dynamicApi()->getInt($flagKey, $defaultValue, [/* TODO: Variations */], ContextAdapter::adapt($context)),
85 | );
86 | }
87 |
88 | public function resolveFloatValue(string $flagKey, float $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
89 | {
90 | return $this->resolve(
91 | $defaultValue,
92 | fn () => Rox::dynamicApi()->getDouble($flagKey, $defaultValue, [/* TODO: Variations */], ContextAdapter::adapt($context)),
93 | );
94 | }
95 |
96 | /**
97 | * @param mixed[] $defaultValue
98 | */
99 | public function resolveObjectValue(string $flagKey, array $defaultValue, ?EvaluationContext $context = null): ResolutionDetails
100 | {
101 | return $this->resolve(
102 | $defaultValue,
103 | fn () => Rox::dynamicApi()->getValue($flagKey, 'anything', [/* TODO: Variations */], ContextAdapter::adapt($context)),
104 | new JsonTransformer(),
105 | );
106 | }
107 |
108 | /**
109 | * @param bool|string|int|float|mixed[] $defaultValue
110 | */
111 | private function resolve(mixed $defaultValue, callable $fn, ?callable $transformer = null): ResolutionDetails
112 | {
113 | if (is_null($transformer)) {
114 | $transformer = new IdentityTransformer();
115 | }
116 |
117 | try {
118 | /**
119 | * @var bool|string|int|float $value
120 | */
121 | $value = call_user_func($fn);
122 |
123 | /**
124 | * @var bool|string|int|float|mixed[] $transformed
125 | */
126 | $transformed = call_user_func($transformer, $value);
127 |
128 | return (new ResolutionDetailsBuilder())
129 | ->withValue($transformed)
130 | ->build();
131 | } catch (Throwable $err) {
132 | $detailsBuilder = new ResolutionDetailsBuilder();
133 |
134 | $detailsBuilder->withValue($defaultValue);
135 |
136 | if ($err instanceof ThrowableWithResolutionError) {
137 | $detailsBuilder->withError($err->getResolutionError());
138 | } else {
139 | $detailsBuilder->withError(new ResolutionError(ErrorCode::GENERAL(), $err->getMessage()));
140 | }
141 |
142 | return $detailsBuilder->build();
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/hooks/Validators/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-feature/validators-hook",
3 | "description": "A validator hooks package for OpenFeature",
4 | "license": "Apache-2.0",
5 | "type": "library",
6 | "keywords": [
7 | "featureflags",
8 | "featureflagging",
9 | "openfeature",
10 | "validator",
11 | "hook"
12 | ],
13 | "authors": [
14 | {
15 | "name": "OpenFeature PHP Maintainers",
16 | "homepage": "https://github.com/orgs/open-feature/teams/php-maintainer"
17 | },
18 | {
19 | "name": "open-feature/php-sdk-contrib Contributors",
20 | "homepage": "https://github.com/open-feature/php-sdk-contrib/graphs/contributors"
21 | }
22 | ],
23 | "require": {
24 | "php": "^8",
25 | "open-feature/sdk": "^2.0"
26 | },
27 | "require-dev": {
28 | "ergebnis/composer-normalize": "^2.25",
29 | "friendsofphp/php-cs-fixer": "^3.13",
30 | "hamcrest/hamcrest-php": "^2.0",
31 | "mdwheele/zalgo": "^0.3.1",
32 | "mikey179/vfsstream": "v1.6.11",
33 | "mockery/mockery": "^1.5",
34 | "phan/phan": "^5.4",
35 | "php-parallel-lint/php-console-highlighter": "^1.0",
36 | "php-parallel-lint/php-parallel-lint": "^1.3",
37 | "phpstan/extension-installer": "^1.1",
38 | "phpstan/phpstan": "~1.10.0",
39 | "phpstan/phpstan-mockery": "^1.0",
40 | "phpstan/phpstan-phpunit": "^1.1",
41 | "psalm/plugin-mockery": "^0.9.1",
42 | "psalm/plugin-phpunit": "^0.18.0",
43 | "ramsey/coding-standard": "^2.0.3",
44 | "ramsey/composer-repl": "^1.4",
45 | "ramsey/conventional-commits": "^1.3",
46 | "roave/security-advisories": "dev-latest",
47 | "spatie/phpunit-snapshot-assertions": "^4.2",
48 | "vimeo/psalm": "~4.30.0"
49 | },
50 | "minimum-stability": "dev",
51 | "prefer-stable": true,
52 | "autoload": {
53 | "psr-4": {
54 | "OpenFeature\\Hooks\\Validators\\": "src"
55 | }
56 | },
57 | "autoload-dev": {
58 | "psr-4": {
59 | "OpenFeature\\Hooks\\Validators\\Test\\": "tests"
60 | }
61 | },
62 | "config": {
63 | "allow-plugins": {
64 | "phpstan/extension-installer": true,
65 | "dealerdirect/phpcodesniffer-composer-installer": true,
66 | "ergebnis/composer-normalize": true,
67 | "captainhook/plugin-composer": true,
68 | "ramsey/composer-repl": true
69 | },
70 | "sort-packages": true
71 | },
72 | "extra": {
73 | "captainhook": {
74 | "force-install": false
75 | }
76 | },
77 | "scripts": {
78 | "dev:analyze": [
79 | "@dev:analyze:phpstan",
80 | "@dev:analyze:psalm"
81 | ],
82 | "dev:analyze:phpstan": "phpstan analyse --ansi --debug --memory-limit=512M",
83 | "dev:analyze:psalm": "psalm",
84 | "dev:build:clean": "git clean -fX build/",
85 | "dev:lint": [
86 | "@dev:lint:syntax",
87 | "@dev:lint:style"
88 | ],
89 | "dev:lint:fix": "phpcbf",
90 | "dev:lint:style": "phpcs --colors",
91 | "dev:lint:syntax": "parallel-lint --colors src/ tests/",
92 | "dev:test": [
93 | "@dev:lint",
94 | "@dev:analyze",
95 | "@dev:test:unit",
96 | "@dev:test:integration"
97 | ],
98 | "dev:test:coverage:ci": "phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml",
99 | "dev:test:coverage:html": "phpunit --colors=always --coverage-html build/coverage/coverage-html/",
100 | "dev:test:unit": [
101 | "@dev:test:unit:setup",
102 | "phpunit --colors=always --testdox --testsuite=unit",
103 | "@dev:test:unit:teardown"
104 | ],
105 | "dev:test:unit:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on",
106 | "dev:test:unit:setup": "echo 'Setup for unit tests...'",
107 | "dev:test:unit:teardown": "echo 'Tore down for unit tests...'",
108 | "dev:test:integration": [
109 | "@dev:test:integration:setup",
110 | "phpunit --colors=always --testdox --testsuite=integration",
111 | "@dev:test:integration:teardown"
112 | ],
113 | "dev:test:integration:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on",
114 | "dev:test:integration:setup": "echo 'Setup for integration tests...'",
115 | "dev:test:integration:teardown": "echo 'Tore down integration tests...'",
116 | "test": "@dev:test"
117 | },
118 | "scripts-descriptions": {
119 | "dev:analyze": "Runs all static analysis checks.",
120 | "dev:analyze:phpstan": "Runs the PHPStan static analyzer.",
121 | "dev:analyze:psalm": "Runs the Psalm static analyzer.",
122 | "dev:build:clean": "Cleans the build/ directory.",
123 | "dev:lint": "Runs all linting checks.",
124 | "dev:lint:fix": "Auto-fixes coding standards issues, if possible.",
125 | "dev:lint:style": "Checks for coding standards issues.",
126 | "dev:lint:syntax": "Checks for syntax errors.",
127 | "dev:test": "Runs linting, static analysis, and unit tests.",
128 | "dev:test:coverage:ci": "Runs unit tests and generates CI coverage reports.",
129 | "dev:test:coverage:html": "Runs unit tests and generates HTML coverage report.",
130 | "dev:test:unit": "Runs unit tests.",
131 | "test": "Runs linting, static analysis, and unit tests."
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/providers/CloudBees/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-feature/cloudbees-provider",
3 | "description": "The CloudBees provider package for OpenFeature",
4 | "license": "Apache-2.0",
5 | "type": "library",
6 | "keywords": [
7 | "featureflags",
8 | "featureflagging",
9 | "openfeature",
10 | "cloudbees",
11 | "rox",
12 | "rollout",
13 | "provider"
14 | ],
15 | "authors": [
16 | {
17 | "name": "OpenFeature PHP Maintainers",
18 | "homepage": "https://github.com/orgs/open-feature/teams/php-maintainer"
19 | },
20 | {
21 | "name": "open-feature/php-sdk-contrib Contributors",
22 | "homepage": "https://github.com/open-feature/php-sdk-contrib/graphs/contributors"
23 | }
24 | ],
25 | "require": {
26 | "php": "^8",
27 | "open-feature/sdk": "^2.0",
28 | "rollout/rox": "^5.0"
29 | },
30 | "require-dev": {
31 | "ergebnis/composer-normalize": "^2.25",
32 | "friendsofphp/php-cs-fixer": "^3.13",
33 | "hamcrest/hamcrest-php": "^2.0",
34 | "mdwheele/zalgo": "^0.3.1",
35 | "mockery/mockery": "^1.5",
36 | "phan/phan": "^5.4",
37 | "php-parallel-lint/php-console-highlighter": "^1.0",
38 | "php-parallel-lint/php-parallel-lint": "^1.3",
39 | "phpstan/extension-installer": "^1.1",
40 | "phpstan/phpstan": "~1.10.0",
41 | "phpstan/phpstan-mockery": "^1.0",
42 | "phpstan/phpstan-phpunit": "^1.1",
43 | "psalm/plugin-mockery": "^0.11.0",
44 | "psalm/plugin-phpunit": "^0.18.0",
45 | "ramsey/coding-standard": "^2.0.3",
46 | "ramsey/composer-repl": "^1.4",
47 | "ramsey/conventional-commits": "^1.3",
48 | "roave/security-advisories": "dev-latest",
49 | "spatie/phpunit-snapshot-assertions": "^4.2",
50 | "vimeo/psalm": "~4.30.0"
51 | },
52 | "minimum-stability": "dev",
53 | "prefer-stable": true,
54 | "autoload": {
55 | "psr-4": {
56 | "OpenFeature\\Providers\\CloudBees\\": "src/"
57 | }
58 | },
59 | "autoload-dev": {
60 | "psr-4": {
61 | "OpenFeature\\Providers\\CloudBees\\Test\\": "tests/"
62 | }
63 | },
64 | "config": {
65 | "allow-plugins": {
66 | "phpstan/extension-installer": true,
67 | "dealerdirect/phpcodesniffer-composer-installer": true,
68 | "ergebnis/composer-normalize": true,
69 | "captainhook/plugin-composer": true,
70 | "ramsey/composer-repl": true
71 | },
72 | "sort-packages": true
73 | },
74 | "extra": {
75 | "captainhook": {
76 | "force-install": false
77 | }
78 | },
79 | "scripts": {
80 | "dev:analyze": [
81 | "@dev:analyze:phpstan",
82 | "@dev:analyze:psalm"
83 | ],
84 | "dev:analyze:phpstan": "phpstan analyse --ansi --debug --memory-limit=512M",
85 | "dev:analyze:psalm": "psalm",
86 | "dev:build:clean": "git clean -fX build/",
87 | "dev:lint": [
88 | "@dev:lint:syntax",
89 | "@dev:lint:style"
90 | ],
91 | "dev:lint:fix": "phpcbf",
92 | "dev:lint:style": "phpcs --colors",
93 | "dev:lint:syntax": "parallel-lint --colors src/ tests/",
94 | "dev:test": [
95 | "@dev:lint",
96 | "@dev:analyze",
97 | "@dev:test:unit",
98 | "@dev:test:integration"
99 | ],
100 | "dev:test:coverage:ci": "phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml",
101 | "dev:test:coverage:html": "phpunit --colors=always --coverage-html build/coverage/coverage-html/",
102 | "dev:test:unit": "phpunit --colors=always --testdox tests/unit",
103 | "dev:test:unit:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on tests/unit",
104 | "dev:test:unit:setup": "echo 'Setup for unit tests...'",
105 | "dev:test:unit:teardown": "echo 'Tore down unit tests...'",
106 | "dev:test:integration": [
107 | "@dev:test:integration:teardown",
108 | "@dev:test:integration:setup",
109 | "phpunit --colors=always --testdox tests/integration",
110 | "@dev:test:integration:teardown"
111 | ],
112 | "dev:test:integration:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on tests/integration",
113 | "dev:test:integration:setup": "python3 scripts/scaffold-integration-tests.py",
114 | "dev:test:integration:teardown": "python3 scripts/scaffold-integration-tests.py stop",
115 | "test": "@dev:test"
116 | },
117 | "scripts-descriptions": {
118 | "dev:analyze": "Runs all static analysis checks.",
119 | "dev:analyze:phpstan": "Runs the PHPStan static analyzer.",
120 | "dev:analyze:psalm": "Runs the Psalm static analyzer.",
121 | "dev:build:clean": "Cleans the build/ directory.",
122 | "dev:lint": "Runs all linting checks.",
123 | "dev:lint:fix": "Auto-fixes coding standards issues, if possible.",
124 | "dev:lint:style": "Checks for coding standards issues.",
125 | "dev:lint:syntax": "Checks for syntax errors.",
126 | "dev:test": "Runs linting, static analysis, and unit tests.",
127 | "dev:test:coverage:ci": "Runs unit tests and generates CI coverage reports.",
128 | "dev:test:coverage:html": "Runs unit tests and generates HTML coverage report.",
129 | "dev:test:unit": "Runs unit tests.",
130 | "test": "Runs linting, static analysis, and unit tests."
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/providers/Split/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-feature/split-provider",
3 | "description": "The Split provider package for OpenFeature",
4 | "license": "Apache-2.0",
5 | "type": "library",
6 | "keywords": [
7 | "featureflags",
8 | "featureflagging",
9 | "openfeature",
10 | "split",
11 | "splitio",
12 | "provider"
13 | ],
14 | "authors": [
15 | {
16 | "name": "OpenFeature PHP Maintainers",
17 | "homepage": "https://github.com/orgs/open-feature/teams/php-maintainer"
18 | },
19 | {
20 | "name": "open-feature/php-sdk-contrib Contributors",
21 | "homepage": "https://github.com/open-feature/php-sdk-contrib/graphs/contributors"
22 | }
23 | ],
24 | "require": {
25 | "php": "^8",
26 | "open-feature/sdk": "^2.0",
27 | "splitsoftware/split-sdk-php": "^7.1"
28 | },
29 | "require-dev": {
30 | "ergebnis/composer-normalize": "^2.25",
31 | "friendsofphp/php-cs-fixer": "^3.13",
32 | "hamcrest/hamcrest-php": "^2.0",
33 | "mdwheele/zalgo": "^0.3.1",
34 | "mikey179/vfsstream": "v1.6.11",
35 | "mockery/mockery": "^1.5",
36 | "phan/phan": "^5.4",
37 | "php-parallel-lint/php-console-highlighter": "^1.0",
38 | "php-parallel-lint/php-parallel-lint": "^1.3",
39 | "phpstan/extension-installer": "^1.1",
40 | "phpstan/phpstan": "~1.10.0",
41 | "phpstan/phpstan-mockery": "^1.0",
42 | "phpstan/phpstan-phpunit": "^1.1",
43 | "psalm/plugin-mockery": "^0.11.0",
44 | "psalm/plugin-phpunit": "^0.18.0",
45 | "ramsey/coding-standard": "^2.0.3",
46 | "ramsey/composer-repl": "^1.4",
47 | "ramsey/conventional-commits": "^1.3",
48 | "roave/security-advisories": "dev-latest",
49 | "spatie/phpunit-snapshot-assertions": "^4.2",
50 | "vimeo/psalm": "~4.30.0"
51 | },
52 | "minimum-stability": "dev",
53 | "prefer-stable": true,
54 | "autoload": {
55 | "psr-4": {
56 | "OpenFeature\\Providers\\Split\\": "src/"
57 | }
58 | },
59 | "autoload-dev": {
60 | "psr-4": {
61 | "OpenFeature\\Providers\\Split\\Test\\": "tests/"
62 | }
63 | },
64 | "config": {
65 | "allow-plugins": {
66 | "phpstan/extension-installer": true,
67 | "dealerdirect/phpcodesniffer-composer-installer": true,
68 | "ergebnis/composer-normalize": true,
69 | "captainhook/plugin-composer": true,
70 | "ramsey/composer-repl": true
71 | },
72 | "sort-packages": true
73 | },
74 | "extra": {
75 | "captainhook": {
76 | "force-install": false
77 | }
78 | },
79 | "scripts": {
80 | "dev:analyze": [
81 | "@dev:analyze:phpstan",
82 | "@dev:analyze:psalm"
83 | ],
84 | "dev:analyze:phpstan": "phpstan analyse --ansi --debug --memory-limit=512M",
85 | "dev:analyze:psalm": "psalm",
86 | "dev:build:clean": "git clean -fX build/",
87 | "dev:lint": [
88 | "@dev:lint:syntax",
89 | "@dev:lint:style"
90 | ],
91 | "dev:lint:fix": "phpcbf",
92 | "dev:lint:style": "phpcs --colors",
93 | "dev:lint:syntax": "parallel-lint --colors src/ tests/",
94 | "dev:test": [
95 | "@dev:lint",
96 | "@dev:analyze",
97 | "@dev:test:unit",
98 | "@dev:test:integration"
99 | ],
100 | "dev:test:coverage:ci": "phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml",
101 | "dev:test:coverage:html": "phpunit --colors=always --coverage-html build/coverage/coverage-html/",
102 | "dev:test:unit": [
103 | "@dev:test:unit:setup",
104 | "phpunit --colors=always --testdox --testsuite=unit",
105 | "@dev:test:unit:teardown"
106 | ],
107 | "dev:test:unit:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on",
108 | "dev:test:unit:setup": "echo 'Setup for unit tests...'",
109 | "dev:test:unit:teardown": "echo 'Tore down for unit tests...'",
110 | "dev:test:integration": [
111 | "@dev:test:integration:setup",
112 | "phpunit --colors=always --testdox --testsuite=integration",
113 | "@dev:test:integration:teardown"
114 | ],
115 | "dev:test:integration:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on",
116 | "dev:test:integration:setup": "echo 'Setup for integration tests...'",
117 | "dev:test:integration:teardown": "echo 'Tore down integration tests...'",
118 | "test": "@dev:test"
119 | },
120 | "scripts-descriptions": {
121 | "dev:analyze": "Runs all static analysis checks.",
122 | "dev:analyze:phpstan": "Runs the PHPStan static analyzer.",
123 | "dev:analyze:psalm": "Runs the Psalm static analyzer.",
124 | "dev:build:clean": "Cleans the build/ directory.",
125 | "dev:lint": "Runs all linting checks.",
126 | "dev:lint:fix": "Auto-fixes coding standards issues, if possible.",
127 | "dev:lint:style": "Checks for coding standards issues.",
128 | "dev:lint:syntax": "Checks for syntax errors.",
129 | "dev:test": "Runs linting, static analysis, and unit tests.",
130 | "dev:test:coverage:ci": "Runs unit tests and generates CI coverage reports.",
131 | "dev:test:coverage:html": "Runs unit tests and generates HTML coverage report.",
132 | "dev:test:unit": "Runs unit tests.",
133 | "test": "Runs linting, static analysis, and unit tests."
134 | }
135 | }
136 |
--------------------------------------------------------------------------------