Skip to content

move tag replacement logic to reusable property #1693

@fiammybe

Description

@fiammybe

Create a small utility (e.g. DeterministicTagReplacer) that does only this:

  • Scans the input string once (no catastrophic backtracking).
  • Finds candidate tag segments deterministically (strpos/offset loop).Delegates:
    matching/validation of a tag
    replacement rendering to injected callables.

Then replaceTagDeterministic() becomes a thin wrapper that configures the helper for that specific tag type.
Why this is clean (IPF + PHP best practices)

  • Single Responsibility: scanning logic separated from tag-specific transformation.
  • Open/Closed: add new tag replacers without changing core scanner.
  • Dependency Injection: pass behavior via callable/interface, easy to test.
  • Deterministic runtime: index-based scanning avoids regex ReDoS risk.
  • Testability: unit test scanner once; unit test each tag strategy independently.
  • Type safety: strict types + explicit return signatures.

Suggested shape
libraries/ipf/text/DeterministicTagReplacer.php

<?php

declare(strict_types=1);

namespace ImpressCMS\IPF\Text;

Then in your existing class:
.../YourClass.php

private function replaceTagDeterministic(string $text): string
{
    return $this->tagReplacer->replace(
        $text,
        function (string $input, int $offset): ?array {
            // deterministic find + parse for your specific tag

Extra refinements (recommended)

Define small interfaces instead of raw callables if you want stricter IPF style:
    TagMatchStrategyInterface
    TagRenderStrategyInterface
Add guard clauses for malformed tags and always ensure cursor advances.
Keep multibyte considerations explicit (mb_*) only if your tag syntax requires it.
Add focused tests:
    no tag
    one tag
    multiple tags
    malformed/open tag
    nested-like patterns
    very long adversarial input

Metadata

Metadata

Assignees

Type

No fields configured for Task.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions