← All documentation
Topics

- Working with data
- Designer components
- Field controls
- Search & filtering
- Calendars
- PDF & printing
- Email
- SMS
- Notifications
- Security
- Helper functions
- JavaScript API
- Performance

# Search API – `Search` Class

The Search class gives you complete control over the search panel, advanced search, and filtering on your generated List pages. It mirrors PHPRunner's `SearchClause` object while adding a fluent interface, JSON support, and automatic integration with the Fields module's saved search settings. Every method works on a specific table and can be used inside page events (`AfterTableInit`, `BeforeDisplay`) or in any custom code.

## Contents

- Getting a Search Instance
- Setting & Getting Field Values
- Search Options
- BETWEEN Searches (Ranges)
- All Fields Search
- Custom Search SQL
- Building the WHERE Clause
- Fluent Chaining
- JSON Export & Import
- Resetting Search
- Integration with Fields Module
- Real‑World Examples

## Getting a Search Instance

Start by obtaining a `Search` object for the table you want to filter.

    use PpPhp\Core\Search;

    $srch = Search::forTable('orders');
    // All subsequent methods operate on the 'orders' table.

## Setting & Getting Field Values

When you set a field value, the field is automatically added to the search panel.

### Example 1 – Basic value set

    $srch->setFieldValue('status', 'shipped');
    echo $srch->getFieldValue('status');  // "shipped"

### Example 2 – Get a value that was never set

    $value = $srch->getFieldValue('customer_name');  // null

### Example 3 – Overwriting a value

    $srch->setFieldValue('status', 'shipped');
    $srch->setFieldValue('status', 'pending');
    echo $srch->getFieldValue('status');  // "pending"

## Search Options

Choose how the value is matched against the database. Supported options: contains, equals, starts, greater, less, between. The default is contains.

### Example 1 – Exact match

    $srch->setFieldValue('status', 'shipped')
         ->setSearchOption('status', 'equals');
    // SQL: WHERE status = 'shipped'

### Example 2 – Substring search

    $srch->setFieldValue('name', 'john')
         ->setSearchOption('name', 'contains');
    // SQL: WHERE name LIKE '%john%'

### Example 3 – Starts with

    $srch->setFieldValue('name', 'A')
         ->setSearchOption('name', 'starts');
    // SQL: WHERE name LIKE 'A%'

### Example 4 – Greater than

    $srch->setFieldValue('amount', '1000')
         ->setSearchOption('amount', 'greater');
    // SQL: WHERE amount > '1000'

### Example 5 – Reading the current option

    $option = $srch->getSearchOption('status');  // e.g. "equals"

## BETWEEN Searches (Ranges)

Use `setSecondFieldValue()` together with `between` for range queries.

    $srch->setFieldValue('price', '100')
         ->setSecondFieldValue('price', '500')
         ->setSearchOption('price', 'between');
    // SQL: WHERE price BETWEEN '100' AND '500'

## All Fields Search

Search across all searchable fields at once. The "All fields" value is combined with OR across every field that is marked as searchable in the Fields module.

    $srch->setAllFieldsValue('john');
    $all = $srch->getAllFieldsValue();   // "john"

    // The WHERE clause will contain:
    // (field1 LIKE '%john%' OR field2 LIKE '%john%' OR ...)

## Custom Search SQL

Replace the generated condition with raw SQL. Use this when you need logic that cannot be expressed through the standard options.

    $srch->setSearchSQL('status', "status IN ('shipped','pending') OR status IS NULL");
    // SQL: WHERE (status IN ('shipped','pending') OR status IS NULL)

Security note: The SQL you pass is not escaped. Only use this method with trusted, hard‑coded strings – never with raw user input.

## Building the WHERE Clause

Call `buildWhereClause()` to get a ready‑to‑use SQL snippet that you can append to your main query.

    $where = $srch->buildWhereClause();
    // Returns: " WHERE status = 'shipped' AND name LIKE '%john%'"
    //   … or an empty string if no conditions are set.

    $rows = DB::Query("SELECT * FROM orders {$where} ORDER BY id DESC");
    while ($row = $rows->fetchAssoc()) {
        echo $row['order_number'];
    }

## Fluent Chaining

All setter methods return `$this`, so you can chain them for compact code.

    $where = Search::forTable('orders')
        ->setFieldValue('status', 'shipped')
        ->setSearchOption('status', 'equals')
        ->setFieldValue('total', '100')
        ->setSecondFieldValue('total', '500')
        ->setSearchOption('total', 'between')
        ->buildWhereClause();

## JSON Export & Import

You can serialise the entire search state to JSON – perfect for AJAX endpoints that save or restore user searches.

    // Export
    $json = json_encode($srch->toArray());
    file_put_contents('saved_search.json', $json);

    // Import
    $srch = Search::fromJson(file_get_contents('saved_search.json'));
    $where = $srch->buildWhereClause();

You can also import from an array directly:

    $srch = Search::fromArray([
        'table'  => 'orders',
        'fields' => ['status' => 'shipped'],
        'options'=> ['status' => 'equals'],
    ]);
    echo $srch->buildWhereClause();  // " WHERE status = 'shipped'"

## Resetting Search

    $srch->resetSearch();
    echo $srch->isSearchStarted();   // false
    echo $srch->buildWhereClause();  // "" (empty)

## Integration with Fields Module

The Fields module lets you configure per‑field search settings (searchable, default option, etc.). The `Search` API reads these settings automatically when the Build button generates List pages, ensuring the search panel matches what you designed visually.

    // In a generated List page, the Search API already knows:
    //   - which fields appear on the search panel
    //   - the default search option for each field
    //   - whether "All fields" search is enabled
    $srch = Search::forTable('customers');
    // $srch->getSearchableFields() returns only fields marked as searchable
    // in the Fields module.

## Real‑World Examples

### Example 1 – Simple filter on a List page

    // In the List page's BeforeDisplay event
    $srch = Search::forTable('products');
    $srch->setFieldValue('category', 'Electronics');
    $srch->setSearchOption('category', 'equals');

    $where = $srch->buildWhereClause();
    $products = DB::Query("SELECT * FROM products {$where}");

### Example 2 – Advanced search with multiple fields

    $srch = Search::forTable('customers');
    $srch->setFieldValue('last_name', 'Smith')
         ->setSearchOption('last_name', 'starts');
    $srch->setFieldValue('age', '18')
         ->setSearchOption('age', 'greater');
    $srch->setFieldValue('status', 'active')
         ->setSearchOption('status', 'equals');

    $where = $srch->buildWhereClause();
    // WHERE last_name LIKE 'Smith%' AND age > '18' AND status = 'active'

### Example 3 – Save and restore a user's search

    // Save (e.g., on page unload via AJAX)
    $_SESSION['last_search'] = json_encode($srch->toArray());

    // Restore (on next page load)
    if (!empty($_SESSION['last_search'])) {
        $srch = Search::fromJson($_SESSION['last_search']);
        $where = $srch->buildWhereClause();
    }

### Example 4 – Use BETWEEN for date range

    $srch = Search::forTable('orders');
    $srch->setFieldValue('order_date', '2025-01-01')
         ->setSecondFieldValue('order_date', '2025-12-31')
         ->setSearchOption('order_date', 'between');
    // WHERE order_date BETWEEN '2025-01-01' AND '2025-12-31'

### 🔗 Related Help Topics

Database API Security API Helpers