Search Index & Decoupled Driver Architecture

1. High-Level Architectural Summary

Zero CMS features an advanced, 100% decoupled **Search Index and Driver Architecture**. Moving away from slow, un-indexed cross-table dynamic lookups, the system compiles searchable content into a dedicated search_index database table in real-time. This index-based search guarantees ultra-fast query execution, scales gracefully under heavy traffic, enforces strict multi-tenant boundary scoping, and supports weighted **Title-Hit Boosting** to ensure that relevance ranking prioritizes exact and partial title matches.

2. Decoupled Search Drivers

By utilizing a driver interface model, the search core is fully decoupled from the underlying index storage. This allows administrators to hot-swap search drivers based on environment variables (e.g., swapping from standard MySQL matching to Elasticsearch or Algolia) without modifying any application controller code.

# Configure active search index driver (defaults to database)
SEARCH_DRIVER=database

3. The Hybrid Block Helper Model (No N+1 Queries)

A critical architectural mandate of Zero CMS is the **absolute prevention of N+1 database queries**. When extracting search text from page-builder layouts (which are saved as structured JSON arrays of blocks), instantiating full layout renderers or calling individual database hooks for block assets would trigger a catastrophic N+1 query loop. To prevent this, Zero CMS implements a **Hybrid Block Helper Model**:

  • OOP Block Helpers: Blocks implement a standard BlockHelperInterface, acting as lightweight, in-memory data-transfer objects that extract searchable plain text from JSON attributes with zero database queries.
  • Recursive Fallback Scanner: If a custom block does not have a specialized helper class defined, the indexing engine automatically falls back to an intelligent recursive array scanner, keeping the search index 100% self-healing and backward-compatible.

4. Developer How-To: Implementing Searchable Models

4. Developer How-To: Implementing Searchable Models php
namespace Zero\Custom\Models;

class CustomBook implements Model
{
    // 1. Import Searchable Trait alongside standard active-record IsModel
    use IsModel, Searchable;

    protected static $tableName = 'custom_books';
    protected static $modelType = 'book';

    // 2. Include 'exclude_from_search' in DB and fillables
    protected static $fillable = ['title', 'content', 'status', 'exclude_from_search'];

    public $exclude_from_search = 0;
    public $status;
}

5. Developer How-To: Creating Custom Block Helpers

5. Developer How-To: Creating Custom Block Helpers php
namespace Zero\Blocks;

class ProductShowcaseBlock implements BlockHelperInterface
{
    protected array $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    /**
     * Compile plain text content from block parameters with 0 database hits.
     */
    public function getSearchableContent(): string
    {
        $parts = [];
        if (!empty($this->data['heading'])) {
            $parts[] = $this->data['heading'];
        }
        if (!empty($this->data['product_name'])) {
            $parts[] = $this->data['product_name'];
        }
        if (!empty($this->data['description'])) {
            $parts[] = strip_tags($this->data['description']);
        }
        return implode(' ', $parts);
    }
}