Skip to content

Conversation

@MarjovanLier
Copy link
Owner

@MarjovanLier MarjovanLier commented May 23, 2025

Summary

This merge request introduces significant performance optimisations to the StringManipulation library, addresses critical validation bugs, and establishes a Docker-first development workflow with automated testing and commit validation. Key improvements include optimised string replacement and search methods, enhanced date validation, and a consistent testing environment using Docker.

Context and Background

The StringManipulation library is a core component for various text processing tasks. To ensure its reliability, efficiency, and maintainability, these changes were necessary. The introduction of a Dockerized testing environment and pre-commit hooks aims to improve code quality, standardize the development process, and make onboarding easier for contributors. Performance enhancements directly impact applications relying on this library for string operations.

(Changed) Make StringManipulation final and update static to self references

Make `StringManipulation` class final and replace `static` with `self`.

Converted the `StringManipulation` class to `final` to prevent inheritance and replaced all occurrences of `static` with `self` for improved clarity and static binding. Additionally, updated development dependencies in `composer.json` to their latest versions for enhanced tooling support.
@coderabbitai
Copy link

coderabbitai bot commented May 23, 2025

📝 Walkthrough

Walkthrough

This update introduces extensive improvements to the StringManipulation project, including new Docker and pre-commit infrastructure, enhanced documentation, stricter code style and commit message enforcement, and significant performance optimizations. It adds new scripts, configuration files, and benchmarks, refactors core string manipulation logic for efficiency, and updates tests to cover edge cases and optimizations.

Changes

File(s) Change Summary
.dockerignore, Dockerfile, docker-compose.yml, run-tests-docker.sh, test-runner.sh Added Docker and Docker Compose configuration for PHP 8.3 test environments, with scripts for running tests inside containers and optimizing build contexts by ignoring unnecessary files.
.githooks/commit-msg, .gitmessage, commitlint-docker.sh, commitlint.config.js, package.json Introduced conventional commit message enforcement via commitlint (with Docker wrapper), a sample message template, and npm scripts for hook setup. The commit-msg hook now validates messages and adds Signed-off-by lines automatically.
.pre-commit-config.yaml, setup-hooks.sh Added pre-commit configuration and setup script to automate code style, linting, static analysis, and security checks using Dockerized hooks and standard pre-commit plugins.
CONTRIBUTING.md, CLAUDE.md, IMPROVEMENTS.md Added comprehensive contributor guidelines, coding standards, and a summary of recent optimizations, bug fixes, and code quality improvements.
README.md Updated to use British English spellings, removed the "Time Part Validation" feature, updated date validation examples, and adjusted example variable names for consistency.
src/StringManipulation.php Refactored to a final class, optimized strReplace (using strtr for single-character replacements and early returns), added static caching for accent mappings, improved searchWords and nameFix for efficiency and clarity, updated isValidDate and isValidTimePart for full date and time validation, and made internal method call consistency improvements.
src/AccentNormalization.php Removed duplicate character mappings in the accent removal arrays.
src/UnicodeMappings.php Clarified and corrected PHPDoc comments for Unicode-to-UTF-8 mapping constants and usage examples.
composer.json Updated development dependencies to newer versions and removed an obsolete flag from the test:phan script.
.phan/config.php Set minimum PHP version to 8.3, reduced parallel processes, and expanded analysis to include the tests directory.
rector.php Skipped the RemoveConcatAutocastRector rule to avoid conflicts with Psalm strict mode.
.gitignore Added ignores for Qodana, Docker, pre-commit, Node.js, and temporary files.
qodana.yaml Removed Qodana configuration file.
LICENSE, infection.json5, phpmd.xml, phpstan.neon, pint.json, qodana.sarif.json, updates.sh Added missing trailing newlines to ensure POSIX compliance.
tests/Unit/StrReplaceTest.php, tests/Unit/Utf8AnsiTest.php Added PHPDoc type annotations and new tests to safeguard and explicitly verify strReplace optimizations, including single-character and empty string handling.
tests/Unit/NameFixTest.php Separated the null input test case from other negative tests for nameFix, using a dedicated assertion for null.
tests/Unit/IsValidTimePartTest.php Expanded test data to include full date components and added cases for invalid dates and months. Updated docblocks accordingly.
tests/Benchmark/StringManipulationBenchmark.php Introduced a new benchmark suite for all public methods, measuring and reporting performance before and after optimizations.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant Git
    participant Pre-commit Hooks
    participant Docker
    participant Composer
    participant Test Suite

    Developer->>Git: git commit
    Git->>Pre-commit Hooks: Run pre-commit checks
    Pre-commit Hooks->>Docker: Run code style, lint, static analysis in containers
    Pre-commit Hooks->>Composer: Validate composer.json/lock
    Pre-commit Hooks->>Test Suite: Run PHPUnit and other tests
    Pre-commit Hooks->>Git: If all pass, allow commit
    Pre-commit Hooks->>Git: If fail, block commit
    Developer->>Git: git push
    Git->>Pre-commit Hooks: Run pre-push hooks (e.g., mutation tests)
Loading

Suggested reviewers

  • qodo-merge-pro

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Hello @MarjovanLier, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

Hello! Gemini here, providing a summary of this pull request to help everyone quickly understand the changes and context.

This pull request, authored by @MarjovanLier, focuses on improving the documentation and code quality of the project. The main goals are to standardize spelling to South African English, fix errors and inconsistencies in the README.md file, and address several code quality issues such as duplicate code, naming inconsistencies, and documentation inaccuracies within the source files.

Highlights

  • Documentation Spelling Standardization: Standardized spelling across the README.md file from American English to South African English (e.g., 'optimize' to 'optimise', 'standardize' to 'standardise').
  • README.md Corrections: Fixed several issues in README.md, including removing a duplicate section on UTF-8 to ANSI conversion, correcting a method reference from validateDate() to isValidDate(), removing references to a non-existent validateTime() method, and correcting output descriptions for utf8Ansi examples.
  • Code Quality Improvements: Addressed code quality issues by removing duplicate PHPDoc for removeAccents(), fixing a duplicate character ('ë') in the REMOVE_ACCENTS_FROM array, standardizing a parameter name ($valor to $value) in utf8Ansi(), and updating documentation for the UnicodeMappings trait.
  • Performance Optimization & Testing: Introduced a static cache for accent replacement mappings in removeAccents() for performance optimization and added new tests for the strReplace() method to specifically target single-character and empty string optimization paths and mutation testing.
  • Dependency Updates: Updated several development dependencies in composer.json to newer versions.

Changelog

Click here to see the changelog
  • README.md
    • Standardized spelling (optimize -> optimise, standardize -> standardise, capitalizing -> capitalising, normalize -> normalise).
    • Removed duplicate 'UTF-8 to ANSI Conversion' section.
    • Corrected method reference from validateDate() to isValidDate() in the Date Validation example.
    • Removed the 'Time Part Validation' section and its example, as the method does not exist.
    • Corrected the output description for the utf8Ansi example from 'in ANSI format' to a simpler description.
  • composer.json
    • Updated development dependencies: infection/infection (>=0.29.11 -> >=0.29.14), laravel/pint (>=1.20.0 -> >=1.21.1), phpstan/phpstan (>=2.1.4 -> >=2.1.8), rector/rector (>=2.0.9 -> >=2.0.10), vimeo/psalm (>=6.5.1 -> >=6.7).
  • src/AccentNormalization.php
    • Removed a duplicate 'ë' character from the REMOVE_ACCENTS_FROM and REMOVE_ACCENTS_TO arrays.
  • src/StringManipulation.php
    • Made the StringManipulation class final.
    • Added a static property $ACCENTS_REPLACEMENT to cache accent replacement arrays for performance.
    • Modified removeAccents() to use the new static cache for replacements.
    • Changed static:: calls to self:: for consistency.
    • Renamed the $valor parameter to $value in the utf8Ansi() method for clarity.
    • Updated PHPDoc for removeAccents() and strReplace().
    • Removed @psalm-suppress tags from utf8Ansi() and strReplace().
  • src/UnicodeMappings.php
    • Updated documentation to clarify that the UTF8_ANSI2 constant maps Unicode escape sequences to UTF-8 characters, not Unicode characters to ANSI.
  • tests/Unit/StrReplaceTest.php
    • Added testSingleCharacterOptimization() to verify the strtr optimization path.
    • Added testSingleCharacterVsMultipleCharacter() to test the distinction between single and multiple character replacements and potential mutation testing scenarios.
    • Added testEmptyStringOptimization() to test edge cases with empty subject or search/replace strings.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


Docs get a polish,
Code gets a fix,
South African words,
A spelling mix.
Tests now run slick.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23

Changed

  • Standardised spelling to South African English throughout the codebase *
  • Improved documentation accuracy in README.md, removing references to non-existent methods
  • Fixed code quality issues including duplicate code and parameter naming inconsistencies

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@codecov
Copy link

codecov bot commented May 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (d24e598) to head (fa25532).
Report is 1 commits behind head on main.

Additional details and impacted files
@@              Coverage Diff              @@
##               main       #45      +/-   ##
=============================================
+ Coverage     98.80%   100.00%   +1.19%     
- Complexity       26        33       +7     
=============================================
  Files             1         1              
  Lines            84        81       -3     
=============================================
- Hits             83        81       -2     
+ Misses            1         0       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented May 23, 2025

PR Code Suggestions ✨

Latest suggestions up to 91c3cce

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Optimize array initialization

The current implementation creates new arrays on each call if the cache is
empty. This is inefficient as it allocates memory unnecessarily. Consider using
a direct assignment to the 'search' and 'replace' keys instead of recreating the
entire array structure.

src/StringManipulation.php [229-235]

 // Use a strict comparison instead of empty()
 if (count(self::$ACCENTS_REPLACEMENT['search']) === 0) {
-    self::$ACCENTS_REPLACEMENT = [
-        'search' => [...self::REMOVE_ACCENTS_FROM, '  '],
-        'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
-    ];
+    self::$ACCENTS_REPLACEMENT['search'] = [...self::REMOVE_ACCENTS_FROM, '  '];
+    self::$ACCENTS_REPLACEMENT['replace'] = [...self::REMOVE_ACCENTS_TO, ' '];
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: This suggestion improves efficiency by updating only the relevant keys in the static property instead of reassigning the entire array, which can be a minor optimization for memory and performance. The change is accurate and contextually relevant.

Medium
Validate parameter types

The optimization for single character replacements is a good performance
improvement, but it doesn't handle the case where $search is a single character
but $replace is an array. This could lead to unexpected behavior. Add a check to
ensure $replace is also a string.

src/StringManipulation.php [279-282]

+// Optimize single character replacements using strtr which is faster for this case
+if (is_string($search) && is_string($replace) && strlen($search) === 1) {
+    return strtr($subject, [$search => $replace]);
+}
 
-
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly highlights the need to ensure both $search and $replace are strings before using strtr, which is already enforced in the code. While the check is present, the suggestion reinforces type safety, offering a minor improvement.

Low
  • Update

Previous suggestions

Suggestions up to commit 97fe4c0
CategorySuggestion                                                                                                                                    Impact
General
Use consistent naming convention

The static property name uses uppercase with underscores, which doesn't follow
PSR-12 naming conventions for properties. Consider renaming it to use camelCase
format for better consistency with PHP standards.

src/StringManipulation.php [42-45]

-private static array $ACCENTS_REPLACEMENT = [
+private static array $accentsReplacement = [
     'search' => [],
     'replace' => [],
 ];
Suggestion importance[1-10]: 5

__

Why: Renaming the static property to camelCase improves consistency with PSR-12 and PHP community standards, but this is a minor style improvement with limited impact on functionality.

Low
Improve comment accuracy

The comment about using strict comparison instead of empty() is misleading since
the code is already using a strict comparison. Additionally, if the property
name is changed to camelCase as suggested, this code would need to be updated to
match.

src/StringManipulation.php [229-235]

-// Use a strict comparison instead of empty()
-if (count(self::$ACCENTS_REPLACEMENT['search']) === 0) {
-    self::$ACCENTS_REPLACEMENT = [
+// Initialize replacement arrays if not already populated
+if (count(self::$accentsReplacement['search']) === 0) {
+    self::$accentsReplacement = [
         'search' => [...self::REMOVE_ACCENTS_FROM, '  '],
         'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
     ];
 }
Suggestion importance[1-10]: 4

__

Why: Updating the comment for accuracy and aligning the property name with the previous naming suggestion improves code clarity and maintainability, but the impact is minor and mostly stylistic.

Low
Suggestions up to commit 5768c3f
CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix inconsistent return flow

The current implementation has inconsistent return behavior. When $macFix is
true, it returns immediately, but when $mcFix is true, it continues execution.
This creates a potential bug where both conditions could be true but only the
Mac replacement would be applied. Restructure to ensure consistent behavior.

src/StringManipulation.php [169-178]

 // Fix mc/mac spacing if needed
 if ($mcFix) {
     $lastName = self::strReplace('Mc ', 'Mc', $lastName);
 }
 
 if ($macFix) {
-    return self::strReplace('Mac ', 'Mac', $lastName);
+    $lastName = self::strReplace('Mac ', 'Mac', $lastName);
 }
 
 return $lastName;
Suggestion importance[1-10]: 7

__

Why: The suggestion addresses a subtle control flow issue where only one of the 'mc' or 'mac' fixes would be applied if both were true. By restructuring to always apply both replacements before returning, it improves correctness and consistency, though the practical impact may be limited.

Medium
General
Optimize array initialization

The current implementation creates new arrays on each call when the cache is
empty. This is inefficient as it allocates memory unnecessarily. Use direct
assignment to the 'search' and 'replace' keys instead of recreating the entire
array structure.

src/StringManipulation.php [229-235]

 // Use a strict comparison instead of empty()
 if (count(self::$ACCENTS_REPLACEMENT['search']) === 0) {
-    self::$ACCENTS_REPLACEMENT = [
-        'search' => [...self::REMOVE_ACCENTS_FROM, '  '],
-        'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
-    ];
+    self::$ACCENTS_REPLACEMENT['search'] = [...self::REMOVE_ACCENTS_FROM, '  '];
+    self::$ACCENTS_REPLACEMENT['replace'] = [...self::REMOVE_ACCENTS_TO, ' '];
 }
Suggestion importance[1-10]: 6

__

Why: This suggestion proposes a minor optimization by assigning to the 'search' and 'replace' keys directly instead of recreating the entire array. While this is a small efficiency improvement, it does not significantly affect correctness or functionality.

Low

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is a solid pull request that significantly improves documentation accuracy, consistency, and code quality. The standardisation to South African English throughout the documentation is well-executed, and the code refactorings enhance maintainability and performance.

Key improvements I noted:

  • Documentation Clarity: The updates to README.md (removing obsolete sections, correcting method references, improving example accuracy) and especially the UnicodeMappings.php trait documentation are excellent. The clarification regarding Unicode escape sequence decoding is particularly valuable.
  • Code Quality & Refinements: Making the StringManipulation class final and consistently using self:: for static calls are good practices for this type of utility class. The parameter renaming (e.g., $valor to $value in utf8Ansi) enhances readability and consistency.
  • Performance Optimisation: The introduction of caching for accent replacement mappings in the removeAccents method is a smart optimisation, likely to improve performance for scenarios involving frequent calls to this method.
  • Bug Fix: The removal of the duplicate 'ë' character in AccentNormalization.php is a good catch and corrects a potential data issue.
  • Testing: The new unit tests added in StrReplaceTest.php for string replacement optimisations (targeting PHP's internal strtr usage for single characters) and edge cases are a great addition. They increase confidence in the string replacement functionality under various conditions.

The changes are well-organized, and the intent behind each modification is clear from the PR description and the code itself. Great work on these enhancements!

Summary of Findings

  • PHPDoc Clarity for StringManipulation::strReplace: The PHPDoc for the StringManipulation::strReplace method (src/StringManipulation.php, line 267) describes it as an "optimised version" of PHP's str_replace. While it leverages PHP's native function (which has its own internal optimisations that the new tests help explore), the wrapper itself is a direct passthrough and doesn't add further optimisations beyond what str_replace() natively provides. Clarifying this in the PHPDoc (e.g., stating it's a consistent internal wrapper that utilizes PHP's str_replace) could prevent potential misunderstanding about where the optimisation lies. This was considered low severity and not commented on directly due to review settings.

Merge Readiness

This pull request is in excellent shape. The comprehensive documentation improvements, code quality enhancements, bug fixes, and new tests significantly benefit the project. I have not identified any critical, high, or medium severity issues that would block merging. While I am an AI and cannot formally approve PRs, based on my review, the changes appear ready for consideration by other reviewers for merging.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
src/StringManipulation.php (4)

37-46: Good performance optimisation with caching.

Adding a static cache for accent replacement mappings improves performance by avoiding recreating arrays on every call to removeAccents(). The PHPDoc clearly explains the purpose and implementation.

Consider aligning array keys for better readability according to PER Coding Style 2.0:

    private static array $ACCENTS_REPLACEMENT = [
-        'search' => [],
-        'replace' => [],
+        'search'  => [],
+        'replace' => [],
    ];
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


82-87: Early return pattern improves code flow.

The switch from static:: to self:: provides consistency, and the early return pattern simplifies logic by avoiding unnecessary processing.

Add a period to the inline comment to match coding standards:

-// Early return if nameFix returned null
+// Early return if nameFix returned null.
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 84-84: src/StringManipulation.php#L84
Inline comments must end in full-stops, exclamation marks, or question marks

🪛 GitHub Check: codecov/patch

[warning] 86-86: src/StringManipulation.php#L86
Added line #L86 was not covered by tests


100-104: Improved code structure with variable assignment before operation.

This refactoring improves readability by separating space normalization and trimming operations, while also handling potential null values from preg_replace().

Fix comment punctuation and add parentheses around the null coalescing operation:

-// Reduce spaces to a single space
+// Reduce spaces to a single space.

-// Return the trimmed result, ensuring we always have a string
-return trim($result ?? '');
+// Return the trimmed result, ensuring we always have a string.
+return trim(($result ?? ''));
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 100-100: src/StringManipulation.php#L100
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 103-103: src/StringManipulation.php#L103
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 104-104: src/StringManipulation.php#L104
Operation must be bracketed


212-218: Consistent parameter naming in UTF-8 conversion.

Changing parameter name from $valor to $value improves naming consistency throughout the codebase and aligns with English naming conventions.

Fix spacing between parameter and default value:

-public static function utf8Ansi(?string $value = ''): string
+public static function utf8Ansi(?string $value=''): string
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 217-217: src/StringManipulation.php#L217
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d24e598 and fe2185d.

📒 Files selected for processing (6)
  • README.md (6 hunks)
  • composer.json (1 hunks)
  • src/AccentNormalization.php (0 hunks)
  • src/StringManipulation.php (7 hunks)
  • src/UnicodeMappings.php (1 hunks)
  • tests/Unit/StrReplaceTest.php (1 hunks)
💤 Files with no reviewable changes (1)
  • src/AccentNormalization.php
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.php`: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID princi...

**/*.php: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and encourage FOOP techniques—such as employing immutable data, pure functions, and functional composition—to improve maintainability, testability, and performance.

  • src/UnicodeMappings.php
  • tests/Unit/StrReplaceTest.php
  • src/StringManipulation.php
🪛 GitHub Check: Codacy Static Code Analysis
tests/Unit/StrReplaceTest.php

[notice] 72-72: tests/Unit/StrReplaceTest.php#L72
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 76-76: tests/Unit/StrReplaceTest.php#L76
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 81-81: tests/Unit/StrReplaceTest.php#L81
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 90-90: tests/Unit/StrReplaceTest.php#L90
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 92-92: tests/Unit/StrReplaceTest.php#L92
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 96-96: tests/Unit/StrReplaceTest.php#L96
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 99-99: tests/Unit/StrReplaceTest.php#L99
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 104-104: tests/Unit/StrReplaceTest.php#L104
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 106-106: tests/Unit/StrReplaceTest.php#L106
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 109-109: tests/Unit/StrReplaceTest.php#L109
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 112-112: tests/Unit/StrReplaceTest.php#L112
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 123-123: tests/Unit/StrReplaceTest.php#L123
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 127-127: tests/Unit/StrReplaceTest.php#L127
Inline comments must end in full-stops, exclamation marks, or question marks

src/StringManipulation.php

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


[notice] 84-84: src/StringManipulation.php#L84
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 100-100: src/StringManipulation.php#L100
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 103-103: src/StringManipulation.php#L103
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 104-104: src/StringManipulation.php#L104
Operation must be bracketed


[notice] 217-217: src/StringManipulation.php#L217
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1

🪛 GitHub Check: build (8.4)
tests/Unit/StrReplaceTest.php

[failure] 74-74:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 78-78:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 100-100:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 101-101:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 114-114:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 115-115:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 125-125:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 129-129:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().

🪛 GitHub Check: build (8.3)
tests/Unit/StrReplaceTest.php

[failure] 74-74:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 78-78:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 100-100:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 101-101:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 114-114:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 115-115:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 125-125:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().


[failure] 129-129:
Dynamic call to static method PHPUnit\Framework\Assert::assertSame().

🪛 GitHub Check: codecov/patch
src/StringManipulation.php

[warning] 86-86: src/StringManipulation.php#L86
Added line #L86 was not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: guardrails/scan
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (24)
composer.json (3)

49-50: Update to development dependencies looks good.

The version requirement increases for infection/infection and laravel/pint align with modern PHP development practices and ensure you're getting the latest bug fixes and features.


55-55: PHPStan update is appropriate.

Updating to PHPStan 2.x is a good move as it provides significantly improved type inference and analysis capabilities over previous versions.


59-61: Good choice with Rector and Psalm updates.

The upgrades to Rector 2.x and Psalm 6.x provide enhanced code transformation capabilities and static analysis, respectively. These align well with the focus on maintainable, type-safe PHP code.

src/UnicodeMappings.php (4)

10-12: Documentation accuracy improvement is excellent.

The updated description correctly explains the actual purpose of the trait - mapping Unicode escape sequences to UTF-8 characters rather than ANSI conversion. This clarification prevents potential misunderstandings.


15-15: Clear functional example provided.

The comment now correctly describes how to use the constant with strtr(), which aligns with functional programming principles by showing how to compose this mapping with string transformation functions.


18-20: Example and usage note improvements.

The example code and usage note now accurately reflect the actual purpose of the trait, making it more likely that developers will use it correctly in their implementations.


25-27: Improved constant documentation.

The PHPDoc for the UTF8_ANSI2 constant now accurately describes its structure and purpose, which enhances code readability and maintainability.

README.md (8)

32-33: South African English spelling standardisation.

The change from "optimize" to "optimise" aligns with the project's standardisation to South African English spelling conventions.


34-35: Consistent terminology in documentation.

The change from "standardize" and "capitalizing" to "standardise" and "capitalising" maintains consistency with South African English spelling throughout the documentation.


83-84: Consistent terminology for search optimisation.

The terminology change aligns with South African English spelling conventions and maintains consistency throughout the documentation.


95-95: Consistent capitalization terminology.

The change to "capitalising" aligns with South African English spelling conventions in the documentation.


113-113: Simplified output description.

Removing unnecessary details in the output comment keeps the documentation concise and focused.


118-119: Consistent terminology for text normalisation.

The change to "normalise" maintains consistency with South African English spelling conventions throughout the documentation.


123-124: Consistent terminology in example code comments.

The change to "normalised" in the example aligns with South African English spelling conventions.


134-135: Method name and parameter correction.

Updating from validateDate() to isValidDate() with the format parameter reflects the actual API of the library, improving documentation accuracy. This change is crucial for correct usage of the library.

src/StringManipulation.php (9)

32-32: Appropriate use of final keyword for utility class.

Marking this utility class as final is a good practice as it prevents inheritance, which is ideal for this type of static utility class that shouldn't be extended.


90-92: Method call style updated consistently.

Changed from static:: to self::, which is appropriate since we're calling static methods from within the same class that can't be overridden due to the final class declaration.


95-99: Consistent method call style maintained.

Changed from static:: to self:: for consistency throughout the class, enhancing readability and maintainability.


138-140: Consistent method call style.

Changed from static:: to self:: for consistency, which reduces cognitive load when reading the code.


147-148: Consistent method call style in name prefixes handling.

Changed from static:: to self:: for consistency. This is particularly important in these specific naming conventions handlers.

Also applies to: 155-156


187-192: Improved null handling with defensive programming.

Changed from static:: to self:: for consistency and added null coalescing to safely handle potential null values, which is a good defensive programming practice.


219-224: Consistent parameter usage and method call style.

Updated variable name from $valor to $value throughout the method body to match the parameter name change. Also switched from static:: to self:: for accessing class constants.


234-235: Improved documentation of performance optimisations.

The PHPDoc now accurately describes the performance optimisation strategy using cached arrays, which helps future developers understand the implementation.


267-273: Clearer documentation for the strReplace() method.

The updated PHPDoc more accurately describes the purpose and functionality of this method as an optimised wrapper around the built-in str_replace function.

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Improved documentation accuracy and consistency in README.md
  • Made StringManipulation class final and optimised static method calls

Fixed

  • Removed duplicate code and fixed naming inconsistencies
  • Corrected method references and examples in documentation

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Incomplete Implementation

The nameFix method has conditional blocks for mcFix and macFix that check conditions but don't execute the string replacement in the new code. The string replacements were removed from the if blocks but not re-implemented elsewhere.

if (preg_match('#mc(?! )#', $lowerLastName) === 1) {
    $mcFix = true;
    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
}

$macFix = false;
$lowerLastName = strtolower($lastName);

if (preg_match('#mac(?! )#', $lowerLastName) === 1) {
    $macFix = true;
    $lastName = self::strReplace('mac', 'mac ', $lowerLastName);
}
Caching Optimization

The new accent replacement caching mechanism is a good optimization, but consider adding unit tests specifically for this feature to ensure the cached arrays are working correctly across multiple method calls.

 * Static property to cache accent replacement mappings for performance optimisation.
 * This is populated lazily in the removeAccents() method and reused across calls.
 *
 * @var array{search: string[], replace: string[]}
 */
private static array $ACCENTS_REPLACEMENT = [
    'search'  => [],
    'replace' => [],
];

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
tests/Unit/StrReplaceTest.php (1)

84-116: Well-designed test for differentiation between optimization paths.

This test elegantly compares the single character replacement (using strtr internally) with array-based replacements (using str_replace), ensuring consistent behavior despite different code paths. The overlapping replacements test is particularly valuable for verifying the optimization's correctness.

I'd recommend fixing the minor style issue identified by Codacy:

- // Create a scenario where strtr and str_replace have observable differences.
-
+ // Create a scenario where strtr and str_replace have observable differences.

The same applies to line 104 - remove the blank line following the inline comment.

🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 90-90: tests/Unit/StrReplaceTest.php#L90
There must be no blank line following an inline comment


[notice] 104-104: tests/Unit/StrReplaceTest.php#L104
There must be no blank line following an inline comment

src/StringManipulation.php (2)

37-46: Great implementation of static property caching for performance.

The addition of a static cache for accent replacement mappings implements the lazy loading pattern efficiently. This optimization reduces redundant array creation across method calls.

The array formatting should be adjusted to comply with PER Coding Style 2.0:

    private static array $ACCENTS_REPLACEMENT = [
-        'search'  => [],
-        'replace' => [],
+        'search' => [],
+        'replace' => [],
    ];

This addresses the 'binary_operator_spaces' rule violation detected by the pipeline.

🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


245-261: Excellent implementation of lazy loading pattern for accent replacements.

This change implements an efficient caching strategy that only populates the replacement arrays when needed. Using the spread operator to merge arrays is a clean approach, and extracting the arrays to variables before passing to strReplace() improves readability.

Minor style improvement:

-        // Use a strict comparison instead of empty()
+        // Use a strict comparison instead of empty().
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 245-245: src/StringManipulation.php#L245
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 248-248: src/StringManipulation.php#L248
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 249-249: src/StringManipulation.php#L249
Array key not aligned correctly; expected 42 spaces but found 16

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe2185d and 23567c6.

📒 Files selected for processing (3)
  • .gitignore (1 hunks)
  • src/StringManipulation.php (7 hunks)
  • tests/Unit/StrReplaceTest.php (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.php`: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID princi...

**/*.php: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and encourage FOOP techniques—such as employing immutable data, pure functions, and functional composition—to improve maintainability, testability, and performance.

  • src/StringManipulation.php
  • tests/Unit/StrReplaceTest.php
🪛 GitHub Check: Codacy Static Code Analysis
src/StringManipulation.php

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


[notice] 245-245: src/StringManipulation.php#L245
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 248-248: src/StringManipulation.php#L248
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 249-249: src/StringManipulation.php#L249
Array key not aligned correctly; expected 42 spaces but found 16

tests/Unit/StrReplaceTest.php

[notice] 90-90: tests/Unit/StrReplaceTest.php#L90
There must be no blank line following an inline comment


[notice] 104-104: tests/Unit/StrReplaceTest.php#L104
There must be no blank line following an inline comment

🪛 GitHub Check: codecov/patch
src/StringManipulation.php

[warning] 86-86: src/StringManipulation.php#L86
Added line #L86 was not covered by tests

🪛 GitHub Actions: PHP CI
src/StringManipulation.php

[error] 1-1: Code style check failed: 'binary_operator_spaces' rule violation detected by pint. Run 'pint' to fix code style issues.

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: guardrails/scan
🔇 Additional comments (7)
tests/Unit/StrReplaceTest.php (2)

65-82: Excellent test implementation for single character optimization path.

This test effectively targets and validates the single character optimization path within the strReplace method. It successfully kills potential IncrementInteger mutations by explicitly verifying that behavior differs when search string length is exactly 1 versus 2.

The assertions and test cases are well-structured, and all style recommendations have been correctly implemented (static assertions and proper comment punctuation).


118-130: Comprehensive edge case coverage for empty strings.

This test correctly verifies two important edge cases:

  1. Empty subject string optimization (immediate return)
  2. Empty search string handling

These cases are often overlooked but can be sources of subtle bugs. The test implementation follows the recommended static assertion style and proper comment punctuation.

src/StringManipulation.php (5)

32-32: Excellent use of the final keyword.

Making the class final improves encapsulation and prevents potential inheritance issues, aligning with composition over inheritance principles. This change enhances the API's robustness by controlling how the functionality can be extended.


82-92: Improved consistency in static method calls.

The change from static:: to self:: enhances consistency throughout the class. Since the class is now marked as final, self:: is the appropriate choice as no polymorphic behavior is intended.

The whitespace structuring for the strtolower call also improves readability.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 86-86: src/StringManipulation.php#L86
Added line #L86 was not covered by tests


138-140: Consistent method calling convention applied.

The standardization of static method calls using self:: instead of static:: improves consistency and matches the final class declaration. This makes the code more maintainable as the calling convention is uniform throughout the class.


217-223: Parameter naming standardization improves API consistency.

Changing the parameter name from $valor to $value standardizes the naming convention across the codebase, improving readability and maintainability. The use of self:: for the constant access is also consistent with the overall refactoring approach.

The default parameter value and null handling is well-implemented.


267-268: Improved PHPDoc clarity for the optimized implementation.

The PHPDoc update accurately describes the method as an optimized version of PHP's native str_replace function, which aligns with the implementation details and the comprehensive test coverage added in the test file.

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Improved documentation accuracy and consistency in README.md
  • Optimised string manipulation methods with caching for better performance

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/StringManipulation.php (1)

82-87: Good defensive programming with early null check.

The early return after calling nameFix() is a robust defensive programming technique. However, line 86 is not covered by tests according to code coverage reports.

Please add a test for this early return path when nameFix() returns null:

#!/bin/bash
# Check test coverage for the early return condition
rg -A 3 "test.*searchWords.*null" tests/
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 86-86: src/StringManipulation.php#L86
Added line #L86 was not covered by tests

🧹 Nitpick comments (4)
src/StringManipulation.php (4)

37-46: Excellent implementation of lazy loading pattern for accent replacements.

The static property caching implementation is a solid performance optimisation. The lazy initialization in removeAccents() ensures we only pay the memory cost when needed.

However, there are some code style issues with array alignment:

 private static array $ACCENTS_REPLACEMENT = [
-    'search'  => [],
-    'replace' => [],
+    'search' => [],
+    'replace' => [],
 ];
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


147-147: Consider using null coalescing operator for consistency.

The strReplace call works correctly, but you might want to maintain consistency with line 188 where you use the null coalescing operator.

-            $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
+            $lastName = self::strReplace('mc', 'mc ', $lowerLastName ?? '');

217-223: Parameter renaming improves consistency.

Renaming from (likely) $valor to $value improves naming consistency. There's a minor style issue with spacing:

-public static function utf8Ansi(?string $value = ''): string
+public static function utf8Ansi(?string $value=''): string

Also, consider using the null coalescing operator instead of the conditional check for more concise code:

-    if ($value === null) {
-        return '';
-    }
-
-    return strtr($value, self::UTF8_ANSI2);
+    return strtr($value ?? '', self::UTF8_ANSI2);
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 217-217: src/StringManipulation.php#L217
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


245-251: Effective caching strategy with proper initialization check.

Using count() === 0 is more explicit than empty() for checking if the array is initialized. The use of the spread operator for array merging is clean and readable.

The comment is missing a full stop at the end according to coding standards:

-        // Use a strict comparison instead of empty()
+        // Use a strict comparison instead of empty().

The array alignment should be consistent:

             self::$ACCENTS_REPLACEMENT = [
-                'search' => [...self::REMOVE_ACCENTS_FROM, '  '],
-                'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
+                'search'  => [...self::REMOVE_ACCENTS_FROM, '  '],
+                'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
             ];
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 245-245: src/StringManipulation.php#L245
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 248-248: src/StringManipulation.php#L248
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 249-249: src/StringManipulation.php#L249
Array key not aligned correctly; expected 42 spaces but found 16

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23567c6 and 929a4ce.

📒 Files selected for processing (1)
  • src/StringManipulation.php (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.php`: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID princi...

**/*.php: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and encourage FOOP techniques—such as employing immutable data, pure functions, and functional composition—to improve maintainability, testability, and performance.

  • src/StringManipulation.php
🪛 GitHub Check: Codacy Static Code Analysis
src/StringManipulation.php

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


[notice] 217-217: src/StringManipulation.php#L217
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


[notice] 245-245: src/StringManipulation.php#L245
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 248-248: src/StringManipulation.php#L248
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 249-249: src/StringManipulation.php#L249
Array key not aligned correctly; expected 42 spaces but found 16

🪛 GitHub Check: codecov/patch
src/StringManipulation.php

[warning] 86-86: src/StringManipulation.php#L86
Added line #L86 was not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: build (8.4)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build (8.3)
  • GitHub Check: guardrails/scan
🔇 Additional comments (5)
src/StringManipulation.php (5)

32-32: Good choice making the class final!

Making the class final prevents inheritance, which is a strong design decision that aligns with the Single Responsibility Principle. This enforces the class's role as a utility collection and prevents potential LSP violations through extension.


89-104: Clean refactoring of whitespace normalization.

The improved code organization with better comments enhances readability. The consistent use of self:: for static method calls is appropriate for a final class, as it avoids the overhead of late static binding.


138-140: Well-structured method chaining for string processing.

The standardized approach using self:: for static method calls is consistent and appropriate for a final class. The code flow is clear and follows a logical sequence of transformations.


253-260: Good extraction of variables for readability.

Extracting the arrays to variables before passing them to strReplace() improves readability and makes the code easier to understand and maintain.


267-268: Improved PHPDoc accuracy.

The PHPDoc update correctly describes the method as an optimised version of the built-in str_replace function, which clarifies its purpose and performance characteristics.

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Improved documentation accuracy and consistency in README.md
  • Made StringManipulation class final and updated static method calls to use self
  • Added caching for accent replacement mappings to improve performance

Fixed

  • Removed duplicate PHPDoc for removeAccents() method
  • Fixed duplicate 'ë' character in REMOVE_ACCENTS_FROM array
  • Standardised parameter naming in utf8Ansi() method

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit 929a4ce.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Incomplete Implementation

The code sets up mcFix and macFix flags but doesn't implement the string replacement logic in the conditional blocks. The replacement code was removed but not re-implemented.

if (preg_match('#mc(?! )#', $lowerLastName) === 1) {
    $mcFix = true;
    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
}

$macFix = false;
$lowerLastName = strtolower($lastName);

if (preg_match('#mac(?! )#', $lowerLastName) === 1) {
    $macFix = true;
    $lastName = self::strReplace('mac', 'mac ', $lowerLastName);
}
Caching Strategy

The new caching mechanism for accent replacements is a good optimization, but should verify thread safety in multi-threaded environments since it modifies static class properties.

/**
 * Static property to cache accent replacement mappings for performance optimisation.
 * This is populated lazily in the removeAccents() method and reused across calls.
 *
 * @var array{search: string[], replace: string[]}
 */
private static array $ACCENTS_REPLACEMENT = [
    'search'  => [],
    'replace' => [],
];

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Fixed documentation errors and inconsistencies in README.md
  • Improved code quality by removing duplicate code and standardising naming conventions

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/StringManipulation.php (2)

207-213: Improved parameter naming consistency

Changing the parameter name from $valor to $value creates more consistent naming conventions across the codebase. This aligns with the PR's goal of standardizing conventions.

However, there's a small spacing issue in the default parameter:

-    public static function utf8Ansi(?string $value = ''): string
+    public static function utf8Ansi(?string $value=''): string

According to PER Coding Style 2.0, there should be no space between the parameter name and equals sign.

🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 212-212: src/StringManipulation.php#L212
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


240-246: Efficient lazy initialization pattern

The implementation of lazy initialization for accent replacement mappings is an excellent performance optimization. This ensures the arrays are only created when needed and then reused for subsequent calls.

The code could be improved by:

  1. Adding a period at the end of the inline comment
  2. Ensuring consistent array indentation
-        // Use a strict comparison instead of empty()
+        // Use a strict comparison instead of empty().
         if (count(self::$ACCENTS_REPLACEMENT['search']) === 0) {
             self::$ACCENTS_REPLACEMENT = [
-                'search' => [...self::REMOVE_ACCENTS_FROM, '  '],
-                'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
+                'search'  => [...self::REMOVE_ACCENTS_FROM, '  '],
+                'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
             ];
         }
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 240-240: src/StringManipulation.php#L240
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 243-243: src/StringManipulation.php#L243
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 244-244: src/StringManipulation.php#L244
Array key not aligned correctly; expected 42 spaces but found 16

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 929a4ce and c6bba6e.

📒 Files selected for processing (1)
  • src/StringManipulation.php (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.php`: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID princi...

**/*.php: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and encourage FOOP techniques—such as employing immutable data, pure functions, and functional composition—to improve maintainability, testability, and performance.

  • src/StringManipulation.php
🪛 GitHub Check: Codacy Static Code Analysis
src/StringManipulation.php

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


[notice] 212-212: src/StringManipulation.php#L212
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


[notice] 240-240: src/StringManipulation.php#L240
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 243-243: src/StringManipulation.php#L243
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 244-244: src/StringManipulation.php#L244
Array key not aligned correctly; expected 42 spaces but found 16

🪛 PHPStan (2.1.15)
src/StringManipulation.php

86-86: Parameter #3 $subject of static method MarjovanLier\StringManipulation\StringManipulation::strReplace() expects string, string|null given.

(argument.type)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: guardrails/scan
  • GitHub Check: build (8.4)
  • GitHub Check: build (8.3)
🔇 Additional comments (15)
src/StringManipulation.php (15)

32-32: Good decision making the class final!

Making the class final prevents inheritance, which is a solid design choice for utility classes that aren't meant to be extended. This improves encapsulation and enforces the use of composition over inheritance, aligning with SOLID principles.


37-46: Excellent implementation of static property caching

The introduction of a static property to cache accent replacement mappings is a great performance optimization. The PHPDoc is well-structured with appropriate type annotations, and the use of a private property maintains encapsulation.

Just a minor style note: the array key indentation doesn't align with PER Coding Style 2.0 expectations, but since the PR's focus is on functionality rather than formatting, this can be addressed in a separate styling pass.

🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


90-90: Consistent method call style

Changing from static:: to self:: for method calls is appropriate since the class is now final. This improves code consistency and makes the binding intention explicit.


93-94: Consistent method call style

Excellent consistency improvement with self:: notation, making static binding explicit.


96-99: Improved whitespace normalization and null handling

The logic for normalizing whitespace and ensuring a non-null return value has been refined. Using the null coalescing operator in ($result ?? '') is a clean, functional approach to handle potential null values.


133-135: Consistent method call style and proper function composition

The method chain uses consistent self:: notation and creates a clear sequence of transformations from the input to the final output, following functional composition principles.


142-142: Consistent method call style

Maintaining the same method call style with self:: notation throughout the codebase improves readability and maintainability.


150-150: Consistent method call style

Continuing with the consistent use of self:: notation.


182-183: Consistent method call style and defensive null handling

Using the null coalescing operator ($lastName ?? '') is a good defensive programming practice, ensuring the method always receives a string even in edge cases.


186-187: Consistent method call style and defensive null handling

The null coalescing operator provides the same defensive programming benefit here, ensuring robust behavior even with unexpected input.


218-218: Consistent method call style

The switch from static:: to self:: notation is maintained throughout the codebase, which is good for consistency.


248-250: Good variable extraction before method call

Extracting the arrays to variables before passing to strReplace() improves readability and maintainability. This is a good practice that makes the code more explicit and easier to debug.


251-255: Consistent method call style

The consistent use of self:: notation is maintained throughout the method calls in the codebase.


262-266: Improved PHPDoc clarity

The PHPDoc now clearly indicates that this is an optimized version of the built-in PHP str_replace function, which provides better context for why this method exists.


84-87:

Details

❌ Incorrect review comment

Add test coverage for the early return path

This change adds an early return if nameFix() returns null, but based on past review comments, this path may not be covered by tests. Consider adding a unit test that invokes searchWords() with input causing nameFix() to return null.


🏁 Script executed:

#!/bin/bash
# Check test coverage for the early return path in searchWords()
echo "Checking for tests that might cover the early return path..."
rg -A 5 "testSearchWords.*nameFix.*null" tests/
rg -A 5 "searchWords.*nameFix.*null" tests/

Length of output: 226


We need to confirm there are truly no tests touching this path. Let's search for any references to nameFix or searchWords in the test suite:


🏁 Script executed:

#!/bin/bash
echo "Searching for any nameFix or searchWords references in tests..."
rg -n "nameFix" tests/
rg -n "searchWords" tests/

Length of output: 3597


🏁 Script executed:

#!/bin/bash
# Retrieve the implementation of searchWords to identify its control flow
rg -n "function searchWords" -A 15 src/StringManipulation.php

Length of output: 705


Ignore test for a non-existent early return
The only early exit in searchWords() is when the input itself is null, and you already have:

  • self::assertNull(StringManipulation::searchWords(null)); in tests/Unit/SearchWordsTest.php (line 40).

Moreover, nameFix() never returns null, so there’s no secondary early‐return path to cover. No additional unit test is needed here.

Likely an incorrect or invalid review comment.

🧰 Tools
🪛 PHPStan (2.1.15)

86-86: Parameter #3 $subject of static method MarjovanLier\StringManipulation\StringManipulation::strReplace() expects string, string|null given.

(argument.type)

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Fixed documentation errors and inconsistencies in README.md
  • Improved code quality by removing duplicate code and standardising parameter naming

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit ed40381.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Incomplete Implementation

The nameFix method has conditional blocks for mcFix and macFix that check conditions but don't perform the string replacements in the new code. The replacements are only done at the end of the method.

if (preg_match('#mc(?! )#', $lowerLastName) === 1) {
    $mcFix = true;
    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
}

$macFix = false;
$lowerLastName = strtolower($lastName);

if (preg_match('#mac(?! )#', $lowerLastName) === 1) {
    $macFix = true;
    $lastName = self::strReplace('mac', 'mac ', $lowerLastName);
}
Missing Functionality

The removeAccents method caches the accent replacement arrays for performance, but the cached arrays are never used in the actual replacement operation.

    // Use a strict comparison instead of empty()
    if (count(self::$ACCENTS_REPLACEMENT['search']) === 0) {
        self::$ACCENTS_REPLACEMENT = [
            'search' => [...self::REMOVE_ACCENTS_FROM, '  '],
            'replace' => [...self::REMOVE_ACCENTS_TO, ' '],
        ];
    }

    $search = self::$ACCENTS_REPLACEMENT['search'];
    $replace = self::$ACCENTS_REPLACEMENT['replace'];

    return self::strReplace(
        $search,
        $replace,
        $str,
    );
}

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/StringManipulation.php (3)

37-46: Excellent implementation of lazy loading pattern for accent replacements.

The static property for caching accent replacements is a good performance optimization, particularly for applications that make heavy use of accent removal. The property is well-documented with appropriate PHPDoc type annotations.

However, the array formatting could be improved for consistency:

private static array $ACCENTS_REPLACEMENT = [
-    'search'  => [],
-    'replace' => [],
+    'search' => [],
+    'replace' => [],
];
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


214-214: Parameter default spacing inconsistency.

There's an inconsistent space between the parameter $value and the equals sign. According to PER Coding Style 2.0 (which extends PSR-12), there should be no space before the equals sign in parameter default values.

-public static function utf8Ansi(?string $value = ''): string
+public static function utf8Ansi(?string $value=''): string
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 214-214: src/StringManipulation.php#L214
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


242-258: Well-implemented caching strategy for accent replacements.

This is an excellent implementation of lazy initialization for the accent replacement arrays. The code:

  1. Uses strict comparison instead of empty() - good practice
  2. Initializes the arrays only once using the spread operator
  3. Extracts variables before passing to strReplace() for improved readability

Two minor suggestions:

  1. Add a period at the end of the inline comment on line 242
  2. Consider using a more memory-efficient approach by initializing the arrays directly in the property declaration if the contents are known at compile time
// Use a strict comparison instead of empty().
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 242-242: src/StringManipulation.php#L242
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 245-245: src/StringManipulation.php#L245
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 246-246: src/StringManipulation.php#L246
Array key not aligned correctly; expected 42 spaces but found 16

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6bba6e and 6619fad.

📒 Files selected for processing (1)
  • src/StringManipulation.php (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.php`: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID princi...

**/*.php: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and encourage FOOP techniques—such as employing immutable data, pure functions, and functional composition—to improve maintainability, testability, and performance.

  • src/StringManipulation.php
🪛 GitHub Check: Codacy Static Code Analysis
src/StringManipulation.php

[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 46-46: src/StringManipulation.php#L46
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


[notice] 214-214: src/StringManipulation.php#L214
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


[notice] 242-242: src/StringManipulation.php#L242
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 245-245: src/StringManipulation.php#L245
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 246-246: src/StringManipulation.php#L246
Array key not aligned correctly; expected 42 spaces but found 16

🪛 GitHub Check: build (8.3)
src/StringManipulation.php

[warning] 84-84:
Escaped Mutant for Mutator "CastString":

@@ @@
// Apply the name fixing standards to the input string
// Since we already checked that $words is not null above, and nameFix only returns
// null when its input is null, we can safely cast to string here for PHPStan.

  •    $words = (string) self::nameFix($words);
    
  •    $words = self::nameFix($words);
       // Replace various special characters with spaces and convert the string to lowercase
       $words = strtolower(self::strReplace(['{', '}', '(', ')', '/', '\\', '@', ':', '"', '?', ',', '.'], ' ', $words));
       // Remove accents from characters within the string
    
🪛 GitHub Check: build (8.4)
src/StringManipulation.php

[warning] 84-84:
Escaped Mutant for Mutator "CastString":

@@ @@
// Apply the name fixing standards to the input string
// Since we already checked that $words is not null above, and nameFix only returns
// null when its input is null, we can safely cast to string here for PHPStan.

  •    $words = (string) self::nameFix($words);
    
  •    $words = self::nameFix($words);
       // Replace various special characters with spaces and convert the string to lowercase
       $words = strtolower(self::strReplace(['{', '}', '(', ')', '/', '\\', '@', ':', '"', '?', ',', '.'], ' ', $words));
       // Remove accents from characters within the string
    
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: guardrails/scan
🔇 Additional comments (13)
src/StringManipulation.php (13)

32-32: Good use of final keyword.

Making the class final is a solid decision for a utility class with only static methods. This prevents inheritance issues and aligns with the principle of designing for composition over inheritance.


82-85: Ensure type safety with appropriate casting.

The explicit string casting is a good approach for ensuring type safety with static analyzers. However, mutation testing indicates this cast could be removed without affecting functionality since you already check for null earlier.

Since you're using strict types, I'd recommend keeping the cast for better static analysis compatibility and explicit intent.

🧰 Tools
🪛 GitHub Check: build (8.3)

[warning] 84-84:
Escaped Mutant for Mutator "CastString":

@@ @@
// Apply the name fixing standards to the input string
// Since we already checked that $words is not null above, and nameFix only returns
// null when its input is null, we can safely cast to string here for PHPStan.

  •    $words = (string) self::nameFix($words);
    
  •    $words = self::nameFix($words);
       // Replace various special characters with spaces and convert the string to lowercase
       $words = strtolower(self::strReplace(['{', '}', '(', ')', '/', '\\', '@', ':', '"', '?', ',', '.'], ' ', $words));
       // Remove accents from characters within the string
    
🪛 GitHub Check: build (8.4)

[warning] 84-84:
Escaped Mutant for Mutator "CastString":

@@ @@
// Apply the name fixing standards to the input string
// Since we already checked that $words is not null above, and nameFix only returns
// null when its input is null, we can safely cast to string here for PHPStan.

  •    $words = (string) self::nameFix($words);
    
  •    $words = self::nameFix($words);
       // Replace various special characters with spaces and convert the string to lowercase
       $words = strtolower(self::strReplace(['{', '}', '(', ')', '/', '\\', '@', ':', '"', '?', ',', '.'], ' ', $words));
       // Remove accents from characters within the string
    

87-89: Consistent use of self:: in a final class.

The change from static:: to self:: is appropriate for a final class since late static binding isn't needed. This improves performance slightly and communicates intent more clearly.


98-101: Improved robustness with variable assignment before trim.

Assigning the result of preg_replace() to a variable before trimming it improves readability and ensures the null coalescing operator works correctly. The ($result ?? '') approach provides a safety net against potential null values from preg_replace failure.


135-136: Consistent use of self:: in static method calls.

These changes properly align with the final class designation and improve method call consistency throughout the codebase.


144-145: Consistent static method invocation pattern.

The switch from static:: to self:: maintains consistency with the class's finality.


152-153: Consistent static method invocation pattern.

Same as before - maintaining consistent static binding approach.


184-185: Proper null coalescing for type safety.

Adding the null coalescing operator ensures the parameter to strReplace() is always a string, even if preg_replace returns null. This protects against potential type errors at runtime.


188-189: Consistent approach to null safety.

The same null coalescing pattern is properly applied here as well, maintaining consistency throughout the codebase.


209-209: Improved parameter naming consistency.

Changing $valor to $value improves naming consistency throughout the codebase. Parameter names should use clear, descriptive English terms.


220-220: Consistent use of self:: for constant access.

Using self:: for constant access in a final class is the correct approach.


231-231: Improved PHPDoc documentation.

The updated PHPDoc clearly explains the performance optimization strategy. Good documentation improves maintainability.


264-270: Improved method documentation.

The updated PHPDoc more accurately describes the method's purpose as an optimized version of str_replace. Clear documentation helps developers understand the rationale behind the method's existence.

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Improved documentation accuracy and consistency in README.md
  • Optimised string manipulation methods with static caching for better performance

Fixed

  • Removed duplicate character in accent removal array
  • Corrected method references and examples in documentation

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/StringManipulation.php (1)

84-88: Add test for early null return in searchWords()

The early return path when nameFix() returns null is not covered by existing tests according to previous review comments. This code path needs test coverage to ensure robustness.

Run the following script to check if any tests now cover this code path:

#!/bin/bash
# Check for tests that cover the early return in searchWords
rg -A 5 "testSearchWords.*nameFix.*null" tests/
rg -A 5 "searchWords.*nameFix.*null" tests/
🧹 Nitpick comments (3)
src/StringManipulation.php (3)

36-45: Excellent implementation of lazy loading pattern for accent replacements.

The new static property caches accent replacement mappings, implementing an efficient lazy loading pattern that only populates the arrays when needed. This optimization prevents recreating these arrays on every call to removeAccents().

However, the array formatting has inconsistent indentation according to the static analyzer.

For perfect alignment with PER Coding Style 2.0, consider adjusting the indentation:

    private static array $ACCENTS_REPLACEMENT = [
-        'search' => [],
-        'replace' => [],
-    ];
+        'search'  => [],
+        'replace' => [],
+    ];
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 43-43: src/StringManipulation.php#L43
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


208-214: Improved parameter naming for consistency.

Renaming the parameter from $valor to $value improves naming consistency throughout the codebase, adhering to South African English spelling conventions as mentioned in the PR objectives. The PHPDoc comment has been correctly updated to reflect this change.

Note that the static analyzer flagged an inconsistency with spacing between the parameter name and the equals sign.

For perfect alignment with PER Coding Style 2.0, consider adjusting the spacing:

-    public static function utf8Ansi(?string $value = ''): string
+    public static function utf8Ansi(?string $value=''): string
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 213-213: src/StringManipulation.php#L213
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


241-247: Well-implemented lazy initialization pattern.

This is an excellent implementation of the lazy initialization pattern. The code only populates the replacement arrays when they're first needed, which improves performance for cases where removeAccents() isn't called. The comment explaining the strict comparison is helpful.

The spread operator (...) is used effectively to merge arrays, making the code more concise and readable.

The static analyzer suggests adding a period at the end of the inline comment:

-        // Use a strict comparison instead of empty()
+        // Use a strict comparison instead of empty().
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[notice] 241-241: src/StringManipulation.php#L241
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 244-244: src/StringManipulation.php#L244
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 245-245: src/StringManipulation.php#L245
Array key not aligned correctly; expected 42 spaces but found 16

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6619fad and 8c897d2.

📒 Files selected for processing (1)
  • src/StringManipulation.php (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.php`: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID princi...

**/*.php: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and encourage FOOP techniques—such as employing immutable data, pure functions, and functional composition—to improve maintainability, testability, and performance.

  • src/StringManipulation.php
🪛 GitHub Check: Codacy Static Code Analysis
src/StringManipulation.php

[notice] 43-43: src/StringManipulation.php#L43
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 44-44: src/StringManipulation.php#L44
Array key not aligned correctly; expected 49 spaces but found 8


[notice] 45-45: src/StringManipulation.php#L45
Closing parenthesis not aligned correctly; expected 48 spaces but found 4


[notice] 213-213: src/StringManipulation.php#L213
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1


[notice] 241-241: src/StringManipulation.php#L241
Inline comments must end in full-stops, exclamation marks, or question marks


[notice] 244-244: src/StringManipulation.php#L244
Array key not aligned correctly; expected 42 spaces but found 16


[notice] 245-245: src/StringManipulation.php#L245
Array key not aligned correctly; expected 42 spaces but found 16

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: guardrails/scan
  • GitHub Check: build (8.4)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build (8.3)
🔇 Additional comments (15)
src/StringManipulation.php (15)

31-31: Good decision making the class final.

Making the class final prevents inheritance, which helps maintain the invariants of this utility class and ensures that its contract isn't violated through subclassing. This is particularly appropriate for utility classes with static methods like this one.


81-84: Good removal of redundant null check.

The explicit comment explaining the reasoning behind removing the null check is helpful. Since nameFix() only returns null when its input is null, and we've already verified that $words isn't null, this is a safe optimization.


86-88: Consistent use of self:: in a final class.

Replacing static:: with self:: for method calls is the correct approach in a final class, as it provides static binding at compile time rather than runtime binding, offering a small performance benefit.


91-91: Consistent use of self:: for method calls.

Good standardization on self:: for static method calls in a final class.


94-94: Consistent use of self:: for method calls.

Good standardization on self:: for static method calls in a final class.


96-100: Improved whitespace normalization with separate variable.

Breaking the space normalization into an intermediate variable before trimming improves readability. The null coalescing operator ensures type safety by guaranteeing a string return value even if preg_replace() fails.


128-128: Good use of fully qualified namespace for attribute.

Using the fully qualified namespace \SensitiveParameter for the attribute is a better practice than relying on imports for PHP attributes, as it makes the code more explicit and avoids potential namespace conflicts.


134-135: Consistent use of self:: for static method calls.

Good standardization on self:: for static method calls in a final class.


143-143: Consistent use of self:: for static method calls.

Good standardization on self:: for static method calls in a final class.


151-151: Consistent use of self:: for static method calls.

Good standardization on self:: for static method calls in a final class.


183-183: Improved type safety with null coalescing operator.

Adding the null coalescing operator ($lastName ?? '') ensures type safety by guaranteeing a string is passed to strReplace(), even if $lastName is null due to unforeseen circumstances.


187-187: Improved type safety with null coalescing operator.

Adding the null coalescing operator ($lastName ?? '') ensures type safety by guaranteeing a string is passed to strReplace(), even if $lastName is null due to unforeseen circumstances.


219-219: Consistent use of self:: for constant access.

Good standardization on self:: for accessing class constants in a final class.


249-251: Improved readability with intermediate variables.

Extracting the arrays to separate variables before passing them to strReplace() improves readability and makes the code easier to understand and maintain.


252-256: Efficient use of cached replacement arrays.

Good use of the cached replacement arrays when calling strReplace(). This avoids recreating these arrays on every call to removeAccents(), which is a significant performance optimization for repeated calls.

@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23

Changed

  • Standardised spelling to South African English throughout the codebase
  • Fixed documentation errors and inconsistencies in README.md
  • Removed duplicate 'ë' character in accent replacement arrays

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit 5768c3f.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Performance Optimization

The new caching mechanism for accent replacements is a good optimization, but consider adding unit tests specifically for the caching behavior to ensure it works correctly across multiple calls.

/**
 * Static property to cache accent replacement mappings for performance optimisation.
 * This is populated lazily in the removeAccents() method and reused across calls.
 *
 * @var array{search: string[], replace: string[]}
 */
private static array $ACCENTS_REPLACEMENT = [
    'search' => [],
    'replace' => [],
];
Regex Optimization

The new regex pattern for prefixes uses a single callback instead of multiple replacements, which is more efficient, but should be validated with performance benchmarks to ensure it handles all edge cases correctly.

$lastName = preg_replace_callback(
    '#\b(van|von|den|der|des|de|du|la|le)\b#i',
    static fn($matches): string => strtolower($matches[1]),
    $lastName,
);

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

- Updated data provider return type annotations to match exact array shape
- Fixed type mismatch between data providers and test method parameters
- Ensures both PHPStan and Psalm static analysis pass without errors
- Consolidated Docker testing commands into main Build & Testing section
- Emphasized Docker as the recommended testing environment
- Removed duplicate Docker testing commands section
- Added all available Docker test services with proper naming
- Clarified that Docker provides PHP 8.3 with AST extension
- laravel/pint: >=1.21.1 -> >=1.22.1
- phpstan/phpstan: >=2.1.8 -> >=2.1.17
- phpstan/phpstan-strict-rules: >=2.0.3 -> >=2.0.4
- psalm/plugin-phpunit: >=0.19.2 -> >=0.19.3
- rector/rector: >=2.0.10 -> >=2.0.16

All tests passing with updated dependencies
@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23

Changed

  • Standardised spelling to South African English throughout the codebase *
  • Fixed documentation errors and inconsistencies in README.md
  • Removed duplicate PHPDoc for removeAccents() method
  • Fixed duplicate 'ë' character in REMOVE_ACCENTS_FROM array

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit a22a42a.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Performance Optimization

The strReplace method has a new optimization for single character replacements using strtr, but there's no test for the case where search is a string and replace is an array, which could lead to unexpected behavior.

if (is_string($search) && is_string($replace) && strlen($search) === 1) {
    return strtr($subject, [$search => $replace]);
}
Potential Bug

In the nameFix method, the variable $lowerLastName is reassigned with $lastName after modifying $lastName, which could lead to unexpected behavior in the 'mac' prefix check.

    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
    $lowerLastName = $lastName;
}
Test Coverage

The test data providers have been refactored but there's no test that explicitly verifies the date validation part of isValidTimePart which is a new behavior.

{
    return [
        'midnight' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 0, 'minute' => 0, 'second' => 0], true],
        'end of day' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 23, 'minute' => 59, 'second' => 59], true],
    ];
}

/**
 * Provides invalid time parts for testing.
 *
 * @return array<string, array{0: array{year?: int, month?: int, day?: int, hour: int, minute: int, second: int}, 1: bool}>
 */
public static function provideInvalidTimeParts(): array
{
    return [
        'negative hour' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => -1, 'minute' => 0, 'second' => 0], false],
        'hour 24' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 24, 'minute' => 0, 'second' => 0], false],
        'negative minute' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 0, 'minute' => -1, 'second' => 0], false],
        'minute 60' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 0, 'minute' => 60, 'second' => 0], false],
        'negative second' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 0, 'minute' => 0, 'second' => -1], false],
        'second 60' => [['year' => 2023, 'month' => 12, 'day' => 25, 'hour' => 0, 'minute' => 0, 'second' => 60], false],
        'invalid date Feb 30' => [['year' => 2023, 'month' => 2, 'day' => 30, 'hour' => 12, 'minute' => 0, 'second' => 0], false],
        'invalid month 13' => [['year' => 2023, 'month' => 13, 'day' => 1, 'hour' => 12, 'minute' => 0, 'second' => 0], false],
    ];
}

/**
 * Provides all time parts for testing.
 *
 * @return array<string, array{0: array{year?: int, month?: int, day?: int, hour: int, minute: int, second: int}, 1: bool}>
 */
public static function provideTimeParts(): array
{
    return array_merge(
        self::provideValidTimeParts(),
        self::provideInvalidTimeParts(),
    );
}

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
CLAUDE.md (2)

13-13: Add missing article “a” for clarity
Change “ensure consistent environment” to “ensure a consistent environment” to improve readability.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~13-~13: You might be missing the article “a” here.
Context: ...Always use Docker for testing to ensure consistent environment with PHP 8.3 and AST extens...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


46-46: Include the indefinite article “an” before “empty string”
Update to “optional parameters default to an empty string” for grammatical completeness.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5768c3f and 97fe4c0.

📒 Files selected for processing (3)
  • CLAUDE.md (1 hunks)
  • composer.json (2 hunks)
  • tests/Unit/IsValidTimePartTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • composer.json
  • tests/Unit/IsValidTimePartTest.php
🧰 Additional context used
🪛 LanguageTool
CLAUDE.md

[uncategorized] ~13-~13: You might be missing the article “a” here.
Context: ...Always use Docker for testing to ensure consistent environment with PHP 8.3 and AST extens...

(AI_EN_LECTOR_MISSING_DETERMINER_A)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: guardrails/scan
  • GitHub Check: build (8.4)
  • GitHub Check: build (8.3)
🔇 Additional comments (1)
CLAUDE.md (1)

1-51: Comprehensive and well-structured development guide
The new guide clearly outlines rules, commands, and style conventions in a logical, easy-to-follow layout, aligning well with the project's contribution workflow.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~13-~13: You might be missing the article “a” here.
Context: ...Always use Docker for testing to ensure consistent environment with PHP 8.3 and AST extens...

(AI_EN_LECTOR_MISSING_DETERMINER_A)

- Added .php-cs-fixer.php with @PER-CS2.0 rule set
- Configured Codacy to use PHP CS Fixer with PER 2.0 standard
- Disabled phpcodesniffer in Codacy to avoid style conflicts
- Simplified pint.json to use only the 'per' preset
- Added .php-cs-fixer.cache to .gitignore

This ensures both Pint and Codacy use the same PER 2.0 coding standard
@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23 *

Changed

  • Standardised spelling to South African English throughout the codebase
  • Fixed documentation errors and inconsistencies in README.md
  • Improved code quality by removing duplicate code and standardising parameter naming

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit 91c3cce.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Performance Optimization

The strReplace method has been optimized for single character replacements using strtr, but the implementation might not handle all edge cases correctly, especially with overlapping replacements.

// Optimize single character replacements using strtr which is faster for this case
if (is_string($search) && is_string($replace) && strlen($search) === 1) {
    return strtr($subject, [$search => $replace]);
}
Potential Bug

In the nameFix method, there's a potential issue with the order of operations. The lowercase conversion happens after checking for 'mc' and 'mac' prefixes, which might cause inconsistent behavior.

// Convert to lowercase once for all operations
$lowerLastName = strtolower($lastName);
$mcFix = false;
$macFix = false;

// Check for 'mc' prefix without following space
if (str_contains($lowerLastName, 'mc') && preg_match('#mc(?! )#', $lowerLastName) === 1) {
    $mcFix = true;
    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
    $lowerLastName = $lastName;
}

// Check for 'mac' prefix without following space
if (str_contains($lowerLastName, 'mac') && preg_match('#mac(?! )#', $lowerLastName) === 1) {
    $macFix = true;
    $lastName = self::strReplace('mac', 'mac ', $lowerLastName);
}
Type Safety

The searchWords method includes a cast to string that might hide potential issues if nameFix returns unexpected values. Consider more explicit null handling.

$words = (string) self::nameFix($words);

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

- Explicitly disabled all PHP style checkers except php-cs-fixer
- Added .codacyignore to exclude non-source files
- Excluded tests/Benchmark from analysis as it has different requirements
- Disabled PHPMD to avoid style conflicts

This should resolve Codacy issues by ensuring only php-cs-fixer
with PER 2.0 standard is used for style checking
@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23

Changed

  • Standardised spelling to South African English throughout the codebase
  • Fixed documentation errors and inconsistencies in README.md
  • Improved code quality by removing duplicate code and standardising parameter naming

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit 49b2283.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Performance Optimization

The strReplace method has a new optimization for single character replacements using strtr, but there's no benchmark data showing the actual performance improvement. Consider adding comments with performance metrics to justify this optimization.

// Optimize single character replacements using strtr which is faster for this case
if (is_string($search) && is_string($replace) && strlen($search) === 1) {
    return strtr($subject, [$search => $replace]);
}
Potential Bug

The nameFix method now converts the string to lowercase before checking for 'mc' and 'mac' prefixes, but then immediately overwrites the lowercase version when fixing these prefixes. This could lead to unexpected behavior with mixed-case inputs.

// Convert to lowercase once for all operations
$lowerLastName = strtolower($lastName);
$mcFix = false;
$macFix = false;

// Check for 'mc' prefix without following space
if (str_contains($lowerLastName, 'mc') && preg_match('#mc(?! )#', $lowerLastName) === 1) {
    $mcFix = true;
    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
    $lowerLastName = $lastName;
}

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

- Added phpcs.xml with PER coding standard
- Enabled PHP_CodeSniffer in Codacy configuration
- Excluded specific rules that conflict with project standards
- Kept both PHP_CodeSniffer and php-cs-fixer enabled

This provides Codacy with explicit configuration files for both
supported tools to enforce PER 2.0 coding standard
@qodo-code-review
Copy link
Contributor

Changelog updates: 🔄

2025-05-23

Changed

  • Standardised spelling to South African English throughout the codebase
  • Fixed documentation errors and inconsistencies in README.md
  • Improved documentation accuracy for methods and parameters
  • Fixed duplicate PHPDoc for removeAccents() method and duplicate character in REMOVE_ACCENTS_FROM array

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

@qodo-code-review
Copy link
Contributor

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit fa25532.

Here are some key observations to aid the review process:

🔒 No security concerns identified
⚡ Recommended focus areas for review

Performance Optimization

The strReplace method has a new optimization for single character replacements using strtr, but there's no benchmark data to validate the performance improvement. Consider adding performance metrics to confirm this optimization is effective.

// Optimize single character replacements using strtr which is faster for this case
if (is_string($search) && is_string($replace) && strlen($search) === 1) {
    return strtr($subject, [$search => $replace]);
}
Potential Bug

The nameFix method now uses self::strReplace instead of static::strReplace, which could change behavior if this class is extended. Verify this change is intentional and doesn't break inheritance.

    $lastName = self::strReplace('mc', 'mc ', $lowerLastName);
    $lowerLastName = $lastName;
}

// Check for 'mac' prefix without following space
if (str_contains($lowerLastName, 'mac') && preg_match('#mac(?! )#', $lowerLastName) === 1) {
    $macFix = true;
    $lastName = self::strReplace('mac', 'mac ', $lowerLastName);
Code Duplication

The isValidTimePart method now checks date validity but doesn't reuse the existing isValidDate method. Consider refactoring to avoid duplicating date validation logic.

// First check if the date parts form a valid date
if (!checkdate($dateParts['month'], $dateParts['day'], $dateParts['year'])) {
    return false;
}

@qodo-code-review
Copy link
Contributor

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
.codacy.yaml (1)

1-2: Remove redundant YAML document start marker
The leading --- header isn’t required by Codacy and can be dropped to streamline the config.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49b2283 and fa25532.

📒 Files selected for processing (2)
  • .codacy.yaml (1 hunks)
  • phpcs.xml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • phpcs.xml
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: guardrails/scan
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
.codacy.yaml (2)

3-21: Confirm Codacy engine identifiers
Verify that phpcodesniffer and php-cs-fixer correspond exactly to Codacy’s expected engine keys (e.g. php_codesniffer vs phpcodesniffer) so your custom phpcs.xml and .php-cs-fixer.php are applied correctly.


22-36: Review exclude_paths scope
Excluding all *.yml/*.yaml files will skip analysis on YAML configs (e.g. .pre-commit-config.yaml). Ensure this broad pattern aligns with your intent—narrow it if you only mean to exclude non-source files.

@MarjovanLier MarjovanLier changed the title docs(project): Improve documentation accuracy and consistency (Changed) Performance optimisations, bug fixes, and Docker-based development setup May 23, 2025
@MarjovanLier MarjovanLier merged commit eb112d2 into main May 23, 2025
9 of 10 checks passed
@MarjovanLier MarjovanLier deleted the fix/documentation-and-spelling-updates branch May 23, 2025 19:31
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.

2 participants