Skip to content

V3.1.0 enhancements#42

Merged
aymanrb merged 10 commits intomasterfrom
v3.1.0-enhancements
Mar 28, 2026
Merged

V3.1.0 enhancements#42
aymanrb merged 10 commits intomasterfrom
v3.1.0-enhancements

Conversation

@aymanrb
Copy link
Copy Markdown
Owner

@aymanrb aymanrb commented Mar 22, 2026

v3.1.0-enhancements

What changed?

  • parseText() returns early on empty/whitespace input with a warning log
  • Template variable names validated as valid PCRE group identifiers; new InvalidTemplateVariableNameException
  • Prepared regex validated before return; new InvalidTemplateSyntaxException with PCRE error message
  • In-memory template cache in TemplatesHelper — no redundant disk reads on repeated parseText() calls
  • ParseResult implements \IteratorAggregate + \Countable — native foreach and count()
  • ParseResult::getOrFail() — strict accessor with non-nullable string return type
  • All log messages enriched with file path, byte size, template count, similarity flag, key count
  • PHPStan level-8 added

aymanrb and others added 10 commits March 22, 2026 19:25
When parseText() is called with an empty or whitespace-only string,
similarity matching against templates via similar_text() produces
undefined/meaningless scores and brute-force matching wastes cycles.
Return early with an empty ParseResult and log a warning instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Template variables like {%my-var%} or {%123abc%} produce invalid PCRE
named capture groups, causing silent regex failures and empty results.
Validate each variable name against /^[a-zA-Z_][a-zA-Z0-9_]*$/ in
TemplatesHelper::prepareTemplate() and throw
InvalidTemplateVariableNameException with a clear message on violation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
User-provided regex patterns in template variables (e.g. {%id:[0-9+%})
could silently produce broken PCRE and return empty results with no
indication of the root cause. After building the final pattern, run a
dummy preg_match() and throw InvalidTemplateSyntaxException with the
PCRE error message when the pattern is invalid, enabling fast failure
instead of silent data loss.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each call to parseText() previously triggered a file_get_contents() +
full regex compilation pass for every template in the directory. Add an
in-memory cache (keyed by file path) on the TemplatesHelper instance so
that subsequent parseText() calls on the same parser reuse the compiled
patterns, cutting redundant I/O and regex compilation to zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Users previously had to call getParsedRawData() to iterate over results
or countResults() for counting. ParseResult now implements \IteratorAggregate
and \Countable so it can be used directly in foreach loops and with count(),
reducing boilerplate in consumer code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
get(\$key, true) works but requires reading the boolean argument at
every call site to understand its intent. getOrFail() expresses the
strict contract directly in its name and returns a non-nullable string,
giving callers a cleaner type signature without requiring an assertion
or null-coalesce at the call site.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tch outcome

Previous log messages showed only raw JSON of extracted data and a bare
template path, making it hard to debug parsing issues in production.
Log messages now include: file path and byte size in parseFileContent(),
text length and template count with similarity mode in parseText(),
template basename on each attempt, key count on a successful match,
and an explicit no-match info log when no template fits.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exception classes had no direct tests, so their inheritance chain,
message propagation, and newly added classes (InvalidTemplateSyntaxException,
InvalidTemplateVariableNameException) were unverified. ExceptionTest covers
all exception classes for correct base-class inheritance and message
preservation. Also remove the src/Exception coverage exclusion from
phpunit.xml so exception code is now tracked in the coverage report.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ripts

PHPStan at level 8 (the strictest) is added as a dev dependency with a
phpstan.neon targeting the src/ directory. Two new composer scripts make
common quality tasks discoverable without reading docs: `composer analyse`
runs static analysis and `composer lint` checks PHP syntax across src/
and tests/. This catches type errors, dead code, and unsafe operations
before they reach CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
composer.lock is not appropriate for libraries as it is ignored by
consumers and gives a false sense of reproducibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@aymanrb aymanrb force-pushed the v3.1.0-enhancements branch from b707c90 to 14c3379 Compare March 22, 2026 19:08
@aymanrb aymanrb merged commit 18b9c33 into master Mar 28, 2026
4 checks passed
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.

1 participant