Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Search Text Transformer Laravel Package

becklyn/search-text-transformer

Converts HTML into clean, searchable plain text for indexing with search engines like Elasticsearch. Use SearchTextTransformer to strip tags and normalize content, making page text suitable for full‑text search and highlighting.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require becklyn/search-text-transformer
    

    Add to composer.json if using a monorepo or custom package.

  2. First Use Case: Transform a simple HTML snippet in a Laravel controller or service:

    use Becklyn\SearchText\SearchTextTransformer;
    
    $transformer = new SearchTextTransformer();
    $cleanText = $transformer->transform("<p>Hello, <strong>world</strong>!</p>");
    // Output: "Hello, world!"
    
  3. Where to Look First:

    • README.md: For basic usage and test format.
    • tests/fixtures/: Real-world examples of HTML-to-text transformations.
    • SearchTextTransformer.php: Core logic and method signatures.

Implementation Patterns

Usage Patterns

  1. Service Container Integration (Laravel): Bind the transformer to an interface for testability and dependency injection:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton(SearchTextTransformerInterface::class, function ($app) {
            return new SearchTextTransformer();
        });
    }
    

    Use in controllers/services:

    use Illuminate\Support\Facades\App;
    
    $transformer = App::make(SearchTextTransformerInterface::class);
    $cleanText = $transformer->transform($htmlContent);
    
  2. Facade for Convenience: Create a facade to simplify usage:

    // app/Facades/SearchText.php
    namespace App\Facades;
    
    use Illuminate\Support\Facades\Facade;
    
    class SearchText extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return 'searchTextTransformer';
        }
    }
    

    Register in AppServiceProvider:

    $this->app->bind('searchTextTransformer', function ($app) {
        return new SearchTextTransformer();
    });
    

    Usage:

    use App\Facades\SearchText;
    
    $cleanText = SearchText::transform($html);
    
  3. Artisan Command for Batch Processing: Transform large datasets via CLI:

    // app/Console/Commands/TransformSearchText.php
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use App\Facades\SearchText;
    
    class TransformSearchText extends Command
    {
        protected $signature = 'search:text-transform {--model= : Model to process}';
        protected $description = 'Transform HTML content to searchable text';
    
        public function handle()
        {
            $model = $this->option('model');
            $records = $model::all();
    
            foreach ($records as $record) {
                $record->searchable_text = SearchText::transform($record->html_content);
                $record->save();
            }
    
            $this->info("Transformed {$records->count()} records.");
        }
    }
    
  4. Event Listeners for Real-Time Transformation: Hook into model events to transform content on-the-fly:

    // app/Listeners/TransformHtmlContent.php
    namespace App\Listeners;
    
    use App\Facades\SearchText;
    
    class TransformHtmlContent
    {
        public function handle($event)
        {
            $event->model->searchable_text = SearchText::transform($event->model->html_content);
        }
    }
    

    Register in EventServiceProvider:

    protected $listen = [
        'eloquent.saved: App\Models\BlogPost' => [
            'App\Listeners\TransformHtmlContent',
        ],
    ];
    
  5. Elasticsearch Integration: Use the transformer in a custom ingest pipeline or application-side:

    // Example: Pre-process before sending to Elasticsearch
    $elasticClient = app('elasticsearch');
    $blogPost = BlogPost::find(1);
    
    $document = [
        'title' => $blogPost->title,
        'content' => SearchText::transform($blogPost->html_content),
        'url' => route('blog.post', $blogPost),
    ];
    
    $elasticClient->index('blog_posts', $blogPost->id, $document);
    

Workflows

  1. Batch Indexing Workflow:

    • Use the Artisan command to transform and update a search index.
    • Schedule via cron for nightly processing:
      * 3 * * * php artisan search:text-transform --model=BlogPost
      
  2. Real-Time Search Workflow:

    • Transform content during model events or API requests.
    • Store transformed text in a searchable_text column for fast queries.
  3. Hybrid Approach:

    • Transform new/updated content in real-time.
    • Batch-transform legacy content separately to avoid downtime.

Integration Tips

  1. Testing:

    • Extend the package’s test suite with domain-specific fixtures (e.g., tests/fixtures/blog_posts.test).
    • Example fixture:
      --TEST--
      Transform blog post HTML into searchable text.
      --HTML--
      <article>
          <h1>Getting Started with Laravel</h1>
          <p>Laravel is a <strong>PHP framework</strong>...</p>
      </article>
      --EXPECT--
      Getting Started with Laravel
      Laravel is a PHP framework...
      
  2. Customization:

    • Override the transformer’s logic by extending the class:
      class CustomSearchTextTransformer extends SearchTextTransformer
      {
          public function transform($html)
          {
              $text = parent::transform($html);
              // Add custom logic (e.g., preserve headings)
              return $this->preserveHeadings($text);
          }
      
          protected function preserveHeadings($text)
          {
              // Custom implementation
              return $text;
          }
      }
      
  3. Performance:

    • Cache transformed results if the same HTML is processed repeatedly:
      $cacheKey = 'search_text_' . md5($html);
      $cleanText = Cache::remember($cacheKey, now()->addHours(1), function () use ($html) {
          return SearchText::transform($html);
      });
      
  4. Error Handling:

    • Fallback to a simpler parser for malformed HTML:
      try {
          return SearchText::transform($html);
      } catch (\Exception $e) {
          return strip_tags($html); // Fallback
      }
      

Gotchas and Tips

Pitfalls

  1. Malformed HTML:

    • The transformer may fail or produce unexpected results with invalid HTML.
    • Fix: Use a try-catch block or validate HTML before transformation:
      if (!libxml_use_internal_errors(true)) {
          throw new \RuntimeException("Failed to validate HTML.");
      }
      $dom = new \DOMDocument();
      $dom->loadHTML($html);
      libxml_clear_errors();
      
  2. Nested or Complex HTML:

    • Tables, iframes, or deeply nested structures may not transform as expected.
    • Fix: Extend the transformer or use DOMDocument for complex cases:
      $dom = new \DOMDocument();
      $dom->loadHTML($html);
      $text = '';
      foreach ($dom->getElementsByTagName('body') as $node) {
          $text .= $this->nodeToText($node);
      }
      
  3. Scripts and Styles:

    • The transformer strips scripts and styles by default, which may remove critical content.
    • Fix: Customize the transformer to preserve specific scripts/styles if needed.
  4. Performance with Large Datasets:

    • Transforming thousands of records synchronously can time out.
    • Fix: Use Laravel queues or batch processing:
      BlogPost::chunk(100, function ($posts) {
          foreach ($posts as $post) {
              $post->searchable_text = SearchText::transform($post->html_content);
          }
          BlogPost::whereIn('id', $posts->pluck('id'))->update(['searchable_text' => \DB::raw('searchable_text')]);
      });
      
  5. Last Release (2022):

    • The package is no longer actively maintained.
    • Fix: Monitor for updates or fork the repository if critical changes are needed.

Debugging

  1. Log Raw and Transformed Text: Add debug logging to inspect transformations:

    \Log::debug('Raw HTML:', ['html' => $html]);
    $cleanText = SearchText::transform($html);
    \Log::debug('Transformed Text:', ['text' => $cleanText]);
    
  2. Test Edge Cases: Use the package’s test format to validate transformations:

    --HTML--
    <div><script>alert('test');</script><p>Content</p></div>
    --EXPECT--
    Content
    
  3. Profile Performance: Benchmark transformation time for large HTML payloads:

    $start = microtime(true);
    $cleanText = SearchText::transform($largeHtml);
    $time = microtime(true) - $start;
    \Log::info("Transformation time: {$time}s");
    

Config Quirks

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor