Skip to content

Commit b8ff5df

Browse files
authored
1 parent 9033e05 commit b8ff5df

File tree

4 files changed

+149
-6
lines changed

4 files changed

+149
-6
lines changed

AGENTS.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# AGENTS.md
2+
3+
This file helps agentic coding tools work effectively in this repository.
4+
5+
## Scope and intent
6+
- This is a PHP SDK for PayPal Checkout.
7+
- Primary code lives in `src/`; tests live in `tests/`.
8+
- CI runs on PHP 8.1, 8.2, 8.3.
9+
10+
## Build, lint, test
11+
12+
### Install dependencies
13+
- `composer install`
14+
15+
### Build
16+
- No dedicated build step is defined for this library.
17+
18+
### Lint/format
19+
- `composer pint` (Laravel Pint; formatting)
20+
- `./vendor/bin/pint` (same as above)
21+
22+
### Static analysis
23+
- `composer analyse` (PHPStan, level max)
24+
- `phpstan analyse --ansi --debug` (direct)
25+
26+
### Test
27+
- `composer test` (Pest)
28+
- `vendor/bin/pest`
29+
30+
### Run a single test
31+
- `vendor/bin/pest tests/Orders/OrderTest.php`
32+
- `vendor/bin/pest --filter "can initialize an order"`
33+
- `vendor/bin/pest tests/Requests/OrderCreateRequestTest.php --filter "has correct request uri"`
34+
35+
### Test configuration notes
36+
- PHPUnit config: `phpunit.xml`
37+
- Strict settings are enabled (warnings/risky tests fail the run).
38+
39+
## Repository rules
40+
41+
### Cursor/Copilot rules
42+
- No `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md` found.
43+
44+
### Contributing requirements (from `CONTRIBUTING.md`)
45+
- Follow PSR-2 coding standard.
46+
- Add tests for changes.
47+
- Update docs for behavior changes.
48+
- Keep commits meaningful and squash before PR if needed.
49+
50+
## Code style and conventions
51+
52+
### Formatting
53+
- Indent with 4 spaces (see `.editorconfig`).
54+
- Use LF line endings and final newline.
55+
- Keep trailing whitespace trimmed (except Markdown).
56+
- Follow PSR-2 layout rules.
57+
58+
### Namespaces and imports
59+
- Use `PayPal\Checkout\...` namespaces for production code.
60+
- Place `use` statements after `namespace` with a blank line between.
61+
- Prefer alphabetical ordering of imports when adding new ones.
62+
63+
### Naming
64+
- Classes: `PascalCase` (e.g., `OrderCreateRequest`).
65+
- Methods/properties/variables: `camelCase`.
66+
- Constants: `UPPER_SNAKE_CASE` (e.g., `CAPTURE`, `AUTHORIZE`).
67+
- Tests: Pest `it('does something', function () { ... })` with readable names.
68+
69+
### Types and docblocks
70+
- Use typed properties and return types where possible.
71+
- Use docblocks for array element types and readonly notes.
72+
- Interfaces: `Arrayable`, `Jsonable` for objects that serialize.
73+
74+
### Serialization
75+
- Objects implement `toArray()` and `toJson()` via `CastsToJson`.
76+
- Throw `JsonEncodingException` on JSON errors.
77+
- Payload keys are snake_case to match PayPal API.
78+
79+
### Error handling
80+
- Validate inputs early and throw domain exceptions in `src/Exceptions/`.
81+
- Prefer specific exceptions (e.g., `InvalidOrderIntentException`).
82+
- Messages should be explicit and user-facing when appropriate.
83+
84+
### Requests
85+
- Request classes extend `PayPal\Http\PaypalRequest`.
86+
- Use explicit headers and JSON body streams.
87+
- Avoid side effects in request constructors beyond setup.
88+
89+
### Collections and helpers
90+
- `HasCollection` and similar concerns encapsulate list logic.
91+
- Use array_map and small helpers for array transformations.
92+
93+
### Tests
94+
- Use Pest expectations (`expect()->toBe(...)`, etc.).
95+
- Use helper functions in `tests/Pest.php` for common fixtures.
96+
- Keep tests deterministic and JSON comparisons explicit.
97+
98+
## Suggested workflow for changes
99+
- Add or update tests in `tests/` when behavior changes.
100+
- Run `composer pint` before committing formatting changes.
101+
- Run `composer analyse` for static analysis checks.
102+
- Run `composer test` or targeted `vendor/bin/pest` for fast feedback.
103+
104+
## Key files
105+
- `composer.json`: scripts, dependencies, PHP version support.
106+
- `phpstan.neon`: static analysis config.
107+
- `phpunit.xml`: test configuration and strictness settings.
108+
- `tests/Pest.php`: shared test helpers and setup.
109+
- `CONTRIBUTING.md`: PSR-2 and contribution expectations.

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
}
1818
],
1919
"require": {
20-
"php": "^8.1|^8.2|^8.3",
20+
"php": "^8.1|^8.2|^8.3|^8.4",
2121
"ext-json": "*",
2222
"brick/money": "^0.5.2",
2323
"phpjuice/paypal-http-client": "^1.0"
@@ -41,7 +41,8 @@
4141
"prefer-stable": true,
4242
"scripts": {
4343
"test": "vendor/bin/pest --colors=always",
44-
"pint": "./vendor/bin/pint",
44+
"pint": "vendor/bin/pint",
45+
"fmt": "vendor/bin/pint",
4546
"analyse": "phpstan analyse --ansi --debug"
4647
},
4748
"config": {
@@ -50,4 +51,4 @@
5051
"pestphp/pest-plugin": true
5152
}
5253
}
53-
}
54+
}

src/Orders/Item.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class Item implements Arrayable, Jsonable
6060
*/
6161
protected string $category = DIGITAL_GOODS;
6262

63+
/**
64+
* The URL of the item's image.
65+
*/
66+
protected ?string $image_url = null;
67+
6368
/**
6469
* create a new item instance.
6570
*/
@@ -124,13 +129,19 @@ public function getAmount(): AmountContract
124129
*/
125130
public function toArray(): array
126131
{
127-
return [
132+
$payload = [
128133
'name' => $this->getName(),
129134
'unit_amount' => $this->unit_amount->toArray(),
130135
'quantity' => $this->getQuantity(),
131136
'description' => $this->getDescription(),
132137
'category' => $this->getCategory(),
133138
];
139+
140+
if ($this->image_url !== null) {
141+
$payload['image_url'] = $this->image_url;
142+
}
143+
144+
return $payload;
134145
}
135146

136147
/**
@@ -208,4 +219,22 @@ public function setCategory(string $category): self
208219

209220
return $this;
210221
}
222+
223+
/**
224+
* return's item image url.
225+
*/
226+
public function getImageUrl(): ?string
227+
{
228+
return $this->image_url;
229+
}
230+
231+
/**
232+
* set's item image url.
233+
*/
234+
public function setImageUrl(?string $image_url): self
235+
{
236+
$this->image_url = $image_url;
237+
238+
return $this;
239+
}
211240
}

tests/Orders/ItemTest.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@
4747
'quantity' => 2,
4848
'description' => 'Item Description',
4949
'category' => 'DIGITAL_GOODS',
50+
'image_url' => 'https://example.com/image.png',
5051
];
5152

5253
// Act
5354
$item = Item::create('Item 1', '100.00', 'CAD');
5455
$item->setDescription('Item Description')
55-
->setQuantity(2);
56+
->setQuantity(2)
57+
->setImageUrl('https://example.com/image.png');
5658

5759
// Assert
5860
expect($item->toArray())->toBe($expected);
@@ -69,12 +71,14 @@
6971
'quantity' => 2,
7072
'description' => 'Item Description',
7173
'category' => 'DIGITAL_GOODS',
74+
'image_url' => 'https://example.com/image.png',
7275
]);
7376

7477
// Act
7578
$item = Item::create('Item 1', '100.00', 'CAD');
7679
$item->setDescription('Item Description')
77-
->setQuantity(2);
80+
->setQuantity(2)
81+
->setImageUrl('https://example.com/image.png');
7882

7983
// Assert
8084
expect($item->toJson())->toBe($expected);

0 commit comments

Comments
 (0)