Initial version#1
Conversation
There was a problem hiding this comment.
Pull request overview
Introduces the initial implementation of the Croct “Plug” PHP SDK, including visitor identity/session management, token issuance/signing, PSR-based HTTP transport, and content/query APIs, along with a comprehensive PHPUnit test suite and updated package/CI/documentation scaffolding.
Changes:
- Add core SDK implementation (tokens, sessions, request context, API client, evaluator/content fetcher, cookie storage/configuration, and varying-response observer).
- Add PHPUnit tests covering identity handling, JWT/token behavior, API requests, cookie behavior, and metadata parsing.
- Update project metadata and tooling (Composer package details, coding standards, PHPStan/PHPCS, GitHub Actions workflow, README, and license).
Reviewed changes
Copilot reviewed 70 out of 77 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/VaryingResponseObserverTest.php | Tests callback invocation behavior of the varying-response decorator. |
| tests/UuidTest.php | Tests UUID generation, validation, parsing, and equality. |
| tests/TokenTest.php | Tests token issuance, parsing, validity, signing, and error cases. |
| tests/SessionTest.php | Tests session-driven client ID/token lifecycle and signing behavior. |
| tests/RequestContextTest.php | Tests request context extraction from globals and PSR-7 requests. |
| tests/PsrApiClientTest.php | Tests request construction, headers, and error mapping in the API client. |
| tests/InMemoryIdentityStoreTest.php | Tests in-memory persistence of client ID and user token. |
| tests/HttpEvaluatorTest.php | Tests evaluator payload construction and exception/fallback behavior. |
| tests/HttpContentFetcherTest.php | Tests content fetch payloads, endpoint selection, and fallbacks. |
| tests/Fixtures/InstalledContentProvider.php | Fixture content provider used in discovery tests. |
| tests/FetchResponseTest.php | Tests response parsing and metadata handling. |
| tests/FetchOptionsTest.php | Tests fetch options fluent API and immutability. |
| tests/Exception/ApiExceptionTest.php | Tests API exception construction from problem/transport errors. |
| tests/EvaluationOptionsTest.php | Tests evaluation options fluent API and immutability. |
| tests/EcKeyFactory.php | Test utility for generating/verifying ES256 signatures. |
| tests/CroctTest.php | End-to-end wiring tests for the main SDK entry point. |
| tests/CookieTest.php | Tests cookie model serialization and attribute exposure. |
| tests/CookieStorageTest.php | Tests cookie-backed identity storage and emission behavior. |
| tests/CookieConfigurationTest.php | Tests cookie configuration defaults and browser-cookie mapping. |
| tests/Content/SlotMetadataTest.php | Tests slot metadata parsing/validation. |
| tests/Content/NullContentProviderTest.php | Tests null content provider behavior. |
| tests/Content/ExperimentMetadataTest.php | Tests experiment metadata parsing/validation. |
| tests/Content/ExperienceMetadataTest.php | Tests experience metadata parsing/validation. |
| tests/Content/ArrayContentProviderTest.php | Tests array-backed content provider behavior. |
| tests/ApiKeyTest.php | Tests API key parsing, validation, signing, and export/redaction. |
| tests/.gitkeep | Keeps tests/ tracked. |
| src/VaryingResponseObserver.php | Decorator to signal when responses vary per visitor. |
| src/Uuid.php | UUID value object with v4 generation and parsing/validation helpers. |
| src/Token.php | Visitor JWT model: issue/parse/sign/validate and claim accessors. |
| src/Session.php | Identity/session manager: client ID + token reissue/upgrade/signing. |
| src/RequestContext.php | Request-derived context (URL/referrer/IP/UA/locale) and evaluation context builder. |
| src/PsrApiClient.php | PSR-18/PSR-17 API transport with auth/context headers and error mapping. |
| src/Plug.php | Public SDK interface for identity, evaluation, and content fetching. |
| src/InMemoryIdentityStore.php | Simple in-memory identity persistence implementation. |
| src/IdentityStore.php | Identity persistence abstraction. |
| src/HttpHeader.php | Enum of SDK HTTP headers. |
| src/HttpEvaluator.php | API-backed CQL evaluator with fallback/exception translation. |
| src/HttpContentFetcher.php | API-backed content fetcher with endpoint switching and fallbacks. |
| src/FetchResponse.php | Slot fetch response wrapper with optional metadata. |
| src/FetchOptions.php | Immutable options for content fetching. |
| src/Exception/MalformedTokenException.php | Exception type for token parsing/corruption. |
| src/Exception/EvaluationException.php | Exception type for evaluation failures. |
| src/Exception/CroctException.php | Marker interface for SDK-thrown exceptions. |
| src/Exception/ContentException.php | Exception type for content fetching failures. |
| src/Exception/ConfigurationException.php | Exception type for invalid configuration. |
| src/Exception/ApiException.php | Exception type for transport/API-level failures. |
| src/Evaluator.php | Evaluator abstraction. |
| src/EvaluationOptions.php | Immutable options for query evaluation. |
| src/Croct.php | Main SDK entry point/wiring with discovery defaults. |
| src/CookieStorage.php | Cookie-backed identity store with response cookie emission support. |
| src/CookieConfiguration.php | Cookie names/lifetimes/attributes + browser cookie mapping. |
| src/Cookie.php | Cookie value object + Set-Cookie header rendering. |
| src/ContentFetcher.php | Content fetcher abstraction. |
| src/Content/SlotMetadata.php | Slot metadata model and parsing/validation. |
| src/Content/NullContentProvider.php | Null provider fallback (no generated content). |
| src/Content/ExperimentMetadata.php | Experiment metadata model and parsing/validation. |
| src/Content/ExperienceMetadata.php | Experience metadata model and parsing/validation. |
| src/Content/ContentSource.php | Enum describing the source of served content. |
| src/Content/ContentProvider.php | Content provider abstraction. |
| src/Content/ArrayContentProvider.php | Array-backed content provider implementation. |
| src/ApiKey.php | API key model including optional private key and ES256 signing. |
| src/ApiClient.php | API client abstraction. |
| src/.gitkeep | Keeps src/ tracked. |
| README.md | Updates README to product-specific SDK introduction and links. |
| phpunit.xml.dist | Renames test suite for the SDK. |
| phpstan.neon.dist | Adjusts PHPStan configuration (checked exceptions list, etc.). |
| phpcs.xml.dist | Updates coding standard paths and adds targeted exclusions. |
| LICENSE | Adds MIT license text. |
| composer.json | Converts template package into croct/plug-php with runtime/test dependencies and scripts. |
| .github/workflows/validate-branch.yaml | Adds reusable workflow-based validation. |
| .github/workflows/release-drafter.yaml | Removes release drafter workflow from template. |
| .github/workflows/branch-validations.yaml | Removes legacy in-repo validation workflow. |
| .github/assets/header-light.svg | Adds README header asset (light). |
| .github/assets/header-light-mobile.svg | Adds README header asset (light mobile). |
| .github/assets/header-dark.svg | Adds README header asset (dark). |
| .github/assets/header-dark-mobile.svg | Adds README header asset (dark mobile). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
caeb118 to
f3d36c9
Compare
8828ae9 to
7318276
Compare
denis-rossati
left a comment
There was a problem hiding this comment.
LGTM aside from Renan's review
| $options = [ | ||
| 'expires' => $cookie->getExpiration() ?? 0, | ||
| 'path' => $cookie->getPath(), | ||
| 'domain' => $cookie->getDomain() ?? '', | ||
| 'secure' => $cookie->isSecure(), | ||
| 'httponly' => $cookie->isHttpOnly(), | ||
| ]; |
| /** | ||
| * Headers that must not be forwarded upstream. | ||
| */ | ||
| private const UNFORWARDED_REQUEST_HEADERS = [ |
There was a problem hiding this comment.
Cookie and Authorization should be here?
There was a problem hiding this comment.
I don't think so. It should forward whenever we get as the script would get that.
# Conflicts: # composer.json
HttpEvaluator uses mb_strlen() and CroctScriptProvider/ApiKey use hash(), so declare ext-mbstring and ext-hash as runtime requirements to prevent incompatible installs. Addresses PR review feedback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Validate the preserved token ID when re-signing a token issued under a different key. Token::parse() does not validate the "jti" claim, so a tampered cookie carrying a non-UUID token ID would make withTokenId() throw and break session resolution; fall back to a fresh UUID instead. Also save and restore $_SERVER/$_GET/$_COOKIE in the request/cookie tests so they no longer leak superglobal state across the suite. Addresses PR review feedback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Add initial implementation.
Checklist