Skip to content

Add wither methods, static constructors, and default constants to immutable entity objects#1

Merged
karpilin merged 9 commits into5.xfrom
copilot/improve-developer-experience
Dec 9, 2025
Merged

Add wither methods, static constructors, and default constants to immutable entity objects#1
karpilin merged 9 commits into5.xfrom
copilot/improve-developer-experience

Conversation

Copy link
Copy Markdown

Copilot AI commented Dec 4, 2025

Plan: Add Withers to Immutable Objects for Better Developer Experience ✅

  • Add withers to Cell base class (withStyle, withComment) - removed as constructors vary
  • Add withers to all Cell implementations (withValue, withStyle, withComment, withoutStyle, withoutComment)
    • StringCell
    • NumericCell
    • BooleanCell
    • DateTimeCell
    • DateIntervalCell
    • FormulaCell (withValue, withComputedValue, withStyle, withComment, withoutStyle, withoutComment)
    • EmptyCell
    • ErrorCell (withRawValue, withStyle, withComment, withoutStyle, withoutComment)
  • Add withHeight wither to Row class
  • Add withers to Comment class (withHeight, withWidth, withMarginLeft, withMarginTop, withVisible, withFillColor, withTextRuns)
  • Add withers to TextRun class (withText, withFontSize, withFontColor, withFontName, withBold, withItalic)
  • Add withers to Border class (withBorderPart, withoutBorder, withBorderParts)
  • Add withers to BorderPart class (withName, withColor, withWidth, withStyle)
  • Add static named constructors to all classes (Cell types, Comment, TextRun, Border, BorderPart)
  • Extract default constructor values as public constants
  • Create comprehensive tests for all new withers and static constructors
  • Update tests to use named constructors instead of direct constructors
  • Fix coding standards issues (php-cs-fixer)
  • Fix static analysis issues (PHPStan)
  • Refactor withers to use non-optional parameters with separate "without" methods

Summary

Successfully added 80+ wither methods and 13 static named constructors across entity classes. Extracted default constructor values as public constants for better discoverability and reusability. All tests now use the new named constructor API, showcasing best practices.

Key Design Decisions

Non-optional wither parameters: All withStyle() and withComment() methods now require non-null parameters for clearer API semantics. To remove style or comment, use the dedicated withoutStyle() and withoutComment() methods.

Simplified Border API: Renamed withoutBorderPart() to withoutBorder() for brevity. Removed withoutBorderParts() as it was redundant with Border::create().

Public constants for defaults: Extracted all default constructor values as public constants (excluding booleans and empty arrays) for better discoverability and maintainability. This includes defaults that reference other class constants (e.g., BorderPart::DEFAULT_COLOR = Color::BLACK).

Test consistency: All tests now use named constructors (::create()) instead of direct constructors, demonstrating the recommended API usage pattern.

Examples

// Set non-null values with withers
$cell = StringCell::create('value')
    ->withStyle($style)
    ->withComment($comment);

// Unset values with dedicated without methods
$cellWithoutStyle = $cell->withoutStyle();
$cellWithoutComment = $cell->withoutComment();

// Use public constants for default values
$comment = Comment::create()
    ->withHeight(Comment::DEFAULT_HEIGHT)
    ->withFillColor(Comment::DEFAULT_FILL_COLOR);

$borderPart = BorderPart::create(BorderName::LEFT)
    ->withColor(BorderPart::DEFAULT_COLOR)
    ->withWidth(BorderPart::DEFAULT_WIDTH);

// Border operations
$border = Border::create()
    ->withBorderParts($leftPart, $rightPart, $topPart)
    ->withoutBorder(BorderName::LEFT);

Public Constants Added

  • Comment: DEFAULT_HEIGHT, DEFAULT_WIDTH, DEFAULT_MARGIN_LEFT, DEFAULT_MARGIN_TOP, DEFAULT_FILL_COLOR
  • TextRun: DEFAULT_FONT_SIZE, DEFAULT_FONT_COLOR, DEFAULT_FONT_NAME
  • Row: DEFAULT_HEIGHT (also updated static methods to use constant consistently)
  • BorderPart: DEFAULT_COLOR, DEFAULT_WIDTH, DEFAULT_STYLE

Fixes Applied

  • php-cs-fixer: Fixed blank line whitespace and fully qualified type imports
  • PHPStan: Added proper type hints for non-empty-string parameters
  • Code formatting: Broke long lines in Comment class methods
  • Consistency: All static methods in Row now use DEFAULT_HEIGHT constant
  • Test improvements: All tests now use named constructors for consistency
Original prompt

work on improving deweloper experience by introducing a set of withers to the immutable objects like Cell, Row etc


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Introduce withers for immutable objects like Cell and Row Add wither methods to immutable entity objects Dec 4, 2025
Copilot AI requested a review from karpilin December 4, 2025 13:14
@karpilin
Copy link
Copy Markdown
Owner

karpilin commented Dec 4, 2025

@copilot 1. add static named constructors to these classes.
2. for Border allow for mltiple Borders set on the wither ie withBorderParts(BorderPart ...$borderParts)
3. for Border add withoutBorderParts() to unset any

- Add create() static constructors to all Cell types, Comment, TextRun, Border, BorderPart
- Static constructors only include required parameters (optional params set via withers)
- Add withBorderParts() to Border for setting multiple parts at once
- Add withoutBorderParts() to Border to clear all parts
- Update all tests to match new signatures

Co-authored-by: karpilin <[email protected]>
Copy link
Copy Markdown
Author

Copilot AI commented Dec 4, 2025

@copilot 1. add static named constructors to these classes.
2. for Border allow for mltiple Borders set on the wither ie withBorderParts(BorderPart ...$borderParts)
3. for Border add withoutBorder...

Done in f13d2b9:

  1. Added create() static constructors to all Cell types, Comment, TextRun, Border, and BorderPart - using only required parameters as requested
  2. Added withBorderParts(BorderPart ...$borderParts) to Border for setting multiple parts at once
  3. Added withoutBorderParts() to Border to clear all parts

Examples:

// Static constructors with only required params
$cell = StringCell::create('value');
$textRun = TextRun::create('text');
$borderPart = BorderPart::create(BorderName::LEFT);

// Optional params set via withers
$styledCell = $cell->withStyle($style)->withComment($comment);

// Multiple border parts at once
$border = Border::create()
    ->withBorderParts($leftPart, $rightPart, $topPart);

// Clear all parts
$emptyBorder = $border->withoutBorderParts();

Copilot AI changed the title Add wither methods to immutable entity objects Add wither methods and static constructors to immutable entity objects Dec 4, 2025
@karpilin karpilin requested a review from Copilot December 4, 2025 13:33
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances developer experience by adding wither methods and static constructors to immutable entity objects (Cell, Row, Comment, TextRun, Border, BorderPart), making it easier to create and modify immutable objects using a fluent interface.

  • Adds wither methods to 8 cell implementations, Row, Comment, TextRun, Border, and BorderPart
  • Introduces static create() constructors that accept only required parameters
  • Maintains immutability by returning new instances from all wither methods

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Common/Entity/Cell/StringCell.php Adds create(), withValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/NumericCell.php Adds create(), withValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/BooleanCell.php Adds create(), withValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/FormulaCell.php Adds create(), withValue(), withComputedValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/ErrorCell.php Adds create(), withRawValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/EmptyCell.php Adds create(), withValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/DateTimeCell.php Adds create(), withValue(), withStyle(), withComment() withers
src/Common/Entity/Cell/DateIntervalCell.php Adds create(), withValue(), withStyle(), withComment() withers
src/Common/Entity/Row.php Adds withHeight() to complement existing withCells()
src/Common/Entity/Comment/Comment.php Adds create() and 7 wither methods for all properties
src/Common/Entity/Comment/TextRun.php Adds create() and 6 wither methods for all properties
src/Common/Entity/Style/Border.php Adds create(), withBorderPart(), withoutBorderPart(), withBorderParts(), withoutBorderParts()
src/Common/Entity/Style/BorderPart.php Adds create(), withName(), withColor(), withWidth(), withStyle() withers
tests/Common/Entity/CellTest.php Adds 78 lines of tests covering all cell type withers and static constructors
tests/Common/Entity/RowTest.php Adds tests for withHeight() and withCells()
tests/Common/Entity/Comment/CommentTest.php New file with 7 test methods for Comment withers
tests/Common/Entity/Comment/TextRunTest.php New file with 7 test methods for TextRun withers
tests/Common/Entity/Style/BorderTest.php Adds 6 test methods for Border wither operations
tests/Common/Entity/Style/BorderPartTest.php New file with 5 test methods for BorderPart withers

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@karpilin karpilin marked this pull request as ready for review December 4, 2025 13:42
@karpilin
Copy link
Copy Markdown
Owner

karpilin commented Dec 4, 2025

@copilot fix the issues found in CI for condign standards and static code analysis

- Fix no_whitespace_in_blank_line in BorderTest.php (line 87)
- Fix fully_qualified_strict_types in CellTest.php (add Comment import, use fully qualified class names)
- Add PHPDoc @param annotation to BorderPart::withColor() for non-empty-string type
- Format Comment.php wither methods to break long lines (>120 chars)

Co-authored-by: karpilin <[email protected]>
Copy link
Copy Markdown
Author

Copilot AI commented Dec 4, 2025

@copilot fix the issues found in CI for condign standards and static code analysis

Fixed in ce69741:

php-cs-fixer issues:

  1. no_whitespace_in_blank_line in BorderTest.php - removed trailing whitespace from blank line
  2. fully_qualified_strict_types in CellTest.php - added missing Comment import and replaced Cell\* with fully qualified class names

PHPStan issue:

  • Added @param non-empty-string $color PHPDoc annotation to BorderPart::withColor() method

Additional improvements:

  • Formatted Comment class wither methods to break lines over 120 characters for better readability

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/OndraM/ci-detector/zipball/8b0223b5ed235fd377c75fdd1bfcad05c0f168b8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/f171dc216bc8a4192d5a0876a899cce6f9e379d6
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/colinodell/json5/zipball/5724d21bc5c910c2560af1b8915f0cc0163579c8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/infection/abstract-testframework-adapter/zipball/18925e20d15d1a5995bb85c9dc09e8751e1e069b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/infection/extension-installer/zipball/9b351d2910b9a23ab4815542e93d541e0ca0cdcf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/infection/include-interceptor/zipball/0cc76d95a79d9832d74e74492b0a30139904bdf7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/infection/infection/zipball/f9628fcd7f76eadf24726e57a81937c42458232b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/infection/mutator/zipball/3c976d721b02b32f851ee4e15d553ef1e9186d1d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/jsonrainbow/json-schema/zipball/134e98916fa2f663afa623970af345cd788e8967
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/marc-mabe/php-enum/zipball/bb426fcdd65c60fb3638ef741e8782508fda7eef
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/phpbench/container/zipball/0c7b2d36c1ea53fe27302fb8873ded7172047196
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/phpbench/phpbench/zipball/b641dde59d969ea42eed70a39f9b51950bc96878
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/d6211c46213d4181054b3d77b10a5c5cb0d59538
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sanmai/DuoClock/zipball/30aa40092396dc96b68c8e8d49162619574477e2
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sanmai/di-container/zipball/355534ad7970fc7dab4211ecaf2da5c546855ee8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sanmai/later/zipball/72a82d783864bca90412d8a26c1878f8981fee97
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sanmai/pipeline/zipball/c3b87db671ee0bc286860bd13bdb7cfc108b7d7e
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/environment/zipball/24a711b5c916efc6d6e62aa65aa2ec98fef77f68
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/console/zipball/0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/event-dispatcher/zipball/9dddcddff1ef974ad87b3708e4b442dc38b2261d
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/finder/zipball/340b9ed7320570f319028a2cbec46d40535e94bd
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/options-resolver/zipball/b38026df55197f9e39a44f3215788edf83187b80
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/process/zipball/7ca8dc2d0dcf4882658313aba8be5d9fd01026c8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/stopwatch/zipball/8a24af0a2e8a872fb745047180649b8418303084
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/thecodingmachine/safe/zipball/2cdd579eeaa2e78e51c7509b50cc9fb89a956236
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)
  • https://api.github.com/repos/webmozarts/glob/zipball/8a2842112d6916e61e0e15e316465b611f3abc17
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/Pu4WUy /usr/bin/composer install --no-interaction --prefer-dist (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@karpilin
Copy link
Copy Markdown
Owner

karpilin commented Dec 9, 2025

@copilot
rename Border::withoutBorderPart() to Border::withoutBorder()
remove Border::withoutBorderParts(), as it is duplicate of create()

make parameters to all withers to be non-optional, and add a method that unsets a parameter on an object.

…rename Border methods

- Rename Border::withoutBorderPart() to Border::withoutBorder()
- Remove Border::withoutBorderParts() (duplicate of create())
- Make withStyle() and withComment() parameters non-optional (remove ? from Style and Comment)
- Add withoutStyle() and withoutComment() methods to all Cell classes
- Add tests for withoutStyle() and withoutComment() methods
- Update BorderTest to use new method names

Co-authored-by: karpilin <[email protected]>
Copy link
Copy Markdown
Author

Copilot AI commented Dec 9, 2025

@copilot
rename Border::withoutBorderPart() to Border::withoutBorder()
remove Border::withoutBorderParts(), as it is duplicate of create()
...

Done in 051b35c:

Border methods:

  • Renamed withoutBorderPart()withoutBorder()
  • Removed withoutBorderParts() (was duplicate of create())

Wither parameters made non-optional:

  • Changed withStyle(?Style $style)withStyle(Style $style) in all Cell classes
  • Changed withComment(?Comment $comment)withComment(Comment $comment) in all Cell classes

Added "without" methods to unset parameters:

  • withoutStyle() - returns cell with style set to null
  • withoutComment() - returns cell with comment set to null

Example usage:

// Set non-null values with withers
$cell = StringCell::create('value')
    ->withStyle($style)
    ->withComment($comment);

// Unset values with without methods  
$cellWithoutStyle = $cell->withoutStyle();
$cellWithoutComment = $cell->withoutComment();

// Border example
$border = Border::create()
    ->withBorderPart($leftPart)
    ->withoutBorder(BorderName::LEFT);

@karpilin
Copy link
Copy Markdown
Owner

karpilin commented Dec 9, 2025

@copilot
for all classes we have modified, if there is a default property value set on the constructor, please extract it to a publicly visible constant

Copilot AI and others added 2 commits December 9, 2025 11:42
- Add public constants for default values in Comment class (height, width, margins, fillColor)
- Add public constants for default values in TextRun class (fontSize, fontColor, fontName)
- Add public constant for default height in Row class
- Exclude boolean and empty array defaults per requirements

Co-authored-by: karpilin <[email protected]>
- Add DEFAULT_COLOR, DEFAULT_WIDTH, DEFAULT_STYLE constants to BorderPart
- Update Row::fromValues() and Row::fromValuesWithStyles() to use self::DEFAULT_HEIGHT
- Follow requirement to extract defaults even when referencing other class constants

Co-authored-by: karpilin <[email protected]>
Copy link
Copy Markdown
Author

Copilot AI commented Dec 9, 2025

@copilot
for all classes we have modified, if there is a default property value set on the constructor, please extract it to a publicly visible constant

Done in 322ad3a and f739654:

Extracted public constants for all default values:

  • Comment: DEFAULT_HEIGHT, DEFAULT_WIDTH, DEFAULT_MARGIN_LEFT, DEFAULT_MARGIN_TOP, DEFAULT_FILL_COLOR
  • TextRun: DEFAULT_FONT_SIZE, DEFAULT_FONT_COLOR, DEFAULT_FONT_NAME
  • Row: DEFAULT_HEIGHT
  • BorderPart: DEFAULT_COLOR, DEFAULT_WIDTH, DEFAULT_STYLE

Key points:

  • Excluded boolean and empty array defaults (kept inline)
  • Extracted defaults even when they reference other class constants (e.g., BorderPart::DEFAULT_COLOR = Color::BLACK)
  • Updated all static methods to use constants consistently (e.g., Row::fromValues() now uses self::DEFAULT_HEIGHT)

Example usage:

$comment = new Comment(
    height: Comment::DEFAULT_HEIGHT,
    fillColor: Comment::DEFAULT_FILL_COLOR
);

$borderPart = new BorderPart(
    BorderName::LEFT,
    color: BorderPart::DEFAULT_COLOR
);

Copilot AI changed the title Add wither methods and static constructors to immutable entity objects Add wither methods, static constructors, and default constants to immutable entity objects Dec 9, 2025
@karpilin
Copy link
Copy Markdown
Owner

karpilin commented Dec 9, 2025

@copilot
update newly added tests to use named constructors for object creation, not constructor

- Replace new ClassName() with ClassName::create() in all test files
- Use fluent interface with withers for setting optional properties
- Affected files: CellTest, CommentTest, TextRunTest, BorderPartTest, BorderTest
- Improves code consistency and showcases the new API design

Co-authored-by: karpilin <[email protected]>
Copy link
Copy Markdown
Author

Copilot AI commented Dec 9, 2025

@copilot
update newly added tests to use named constructors for object creation, not constructor

Done in 833a68b:

Updated all test files to use named constructors (::create()) instead of direct constructors:

Changes made:

  • CellTest.php: All Cell types now use ::create() (StringCell, NumericCell, BooleanCell, FormulaCell, EmptyCell, ErrorCell, DateTimeCell, DateIntervalCell)
  • CommentTest.php: Use Comment::create() and TextRun::create()
  • TextRunTest.php: Use TextRun::create() with fluent withers
  • BorderPartTest.php: Use BorderPart::create()
  • BorderTest.php: Use Border::create() and BorderPart::create()

Example transformation:

// Before
$cell = new StringCell('test', $style, null);
$comment = new Comment(visible: true);

// After
$cell = StringCell::create('test')->withStyle($style);
$comment = Comment::create()->withVisible(true);

This showcases the recommended fluent API pattern throughout the test suite.

@karpilin karpilin merged commit 2705554 into 5.x Dec 9, 2025
30 checks passed
@karpilin karpilin deleted the copilot/improve-developer-experience branch December 9, 2025 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants