Data Objects Reference
Data transfer objects used throughout CelerSearch.
IndexCandidate
Wrapper for items being considered for indexing.
Class: CelerSearch\DataTransfer\IndexCandidate
class IndexCandidate {
public mixed $item;
public function __construct(mixed $item);
}
Usage
Always wrap raw items in IndexCandidate when returning from index methods:
// In get_candidates()
public function get_candidates(int $page, int $batch_size): array {
$posts = get_posts([...]);
// Wrap each item
return array_map(
fn($post) => new IndexCandidate($post),
$posts
);
}
// In is_supported() and should_index()
public function is_supported(IndexCandidate $item): bool {
// Access the wrapped item
return is_a($item->item, \WP_Post::class);
}
// In get_candidate_objects()
public function get_candidate_objects(IndexCandidate $item): array {
// Unwrap to work with the item
$post = $item->item;
return [new IndexablePost((string) $post->ID, [...])];
}
IIndexableObject
Interface for objects that can be indexed.
Interface: CelerSearch\Interfaces\IIndexableObject
interface IIndexableObject {
/**
* Get the unique identifier of the object
* @return mixed
*/
public function get_id();
/**
* Get the data to be indexed
* @return array
*/
public function get_indexable_data();
}
IndexableObject
Abstract base implementing IIndexableObject.
Class: CelerSearch\Abstracts\IndexableObject
abstract class IndexableObject implements IIndexableObject {
protected string $id;
protected array $data;
public function __construct(string $id, array $data) {
$this->id = $id;
$this->data = $data;
}
public function get_id(): string {
return $this->id;
}
public function get_indexable_data(): array {
return $this->data;
}
}
Built-in Implementations
All in the CelerSearch\DataTransfer namespace, all extending IndexableObject with the same (string $id, array $data) constructor.
IndexablePost - For posts/pages/CPTs
use CelerSearch\DataTransfer\IndexablePost;
$post = new IndexablePost('123', [
'object_id' => '123',
'post_id' => 123,
'title' => 'My Post',
'content' => 'Post content...',
// ...
]);
IndexableProduct - For WooCommerce products
use CelerSearch\DataTransfer\IndexableProduct;
$product = new IndexableProduct('456', [
'object_id' => '456',
'post_id' => 456,
'post_title' => 'Product Name',
'price' => 29.99,
// ...
]);
IndexableOrder - For WooCommerce orders
use CelerSearch\DataTransfer\IndexableOrder;
$order = new IndexableOrder('order-789', [
'object_id' => 'order-789',
'order_id' => 789,
'order_total' => 99.99,
// ...
]);
Creating Custom Indexables
namespace MyPlugin\DataTransfer;
use CelerSearch\Abstracts\IndexableObject;
class IndexableEvent extends IndexableObject {
// Inherits everything from IndexableObject
// Add custom methods if needed
public function get_start_date(): int {
return $this->data['start_date'] ?? 0;
}
}
IndexConfig
Configuration for an index, as stored in the database. Wraps a plain object and exposes read accessors.
Class: CelerSearch\DataTransfer\IndexConfig
class IndexConfig {
public function __construct(object $value);
public function getId(): string; // note: string, not int
public function getName(): string;
public function getType(): string;
public function getSlug(): string;
public function getConfig(): ?object; // type-specific config (JSON-decoded)
public function getStatus(): ?string;
public function getServiceId(): ?int;
public function getTotalRemote(): ?int;
public function getTotalLocal(): ?int;
public function getCheckedAt(): ?string;
public function getSyncedAt(): ?string;
public function getCreatedAt(): ?string;
public function get($key): mixed; // arbitrary key access
public function toArray(): array;
}
Creating IndexConfig
The constructor takes a plain object (as read from the database):
use CelerSearch\DataTransfer\IndexConfig;
$config = new IndexConfig((object) [
'name' => 'My Posts Index',
'type' => 'posts',
'slug' => 'my-posts-index',
'service_id' => 1,
'config' => [
'post_types' => ['post', 'page'],
],
]);
Inside a BaseIndex subclass, the current IndexConfig is available as $this->details (or via $index->get_index_config()).
ServiceConfig
Configuration for a search service, as stored in the database.
Class: CelerSearch\DataTransfer\ServiceConfig
class ServiceConfig {
public function __construct(object $value);
public function getId(): int;
public function getName(): string;
public function getProvider(): string; // e.g. 'meilisearch'
public function getConfig(): ?object; // provider fields (url, api_key, ...)
public function getStatus(): ?string;
public function getCheckedAt(): ?string;
public function getCreatedAt(): ?string;
public function getFailureCount(): int;
public function get($key): mixed;
public function toArray(): array;
}
Connection details live inside the config object, keyed by the provider's registered fields:
use CelerSearch\DataTransfer\ServiceConfig;
$config = new ServiceConfig((object) [
'name' => 'Production Search',
'provider' => 'meilisearch',
'config' => (object) [
'url' => 'https://search.example.com',
'api_key' => 'your-api-key',
],
]);
$url = $config->getConfig()->url ?? '';
$key = $config->getConfig()->api_key ?? '';
SearchAreaConfig
Search areas are stored as plain arrays inside the celersearch_settings option:
$area = [
'id' => 'area_abc123',
'type' => 'wordpress_public_search',
'label' => 'Main Site Search',
'index_id' => 1,
'enabled' => true,
'features' => [
'autocomplete' => ['enabled' => true],
],
];
Search Area Types
| Type | Description |
|---|---|
wordpress_public_search | Frontend search forms |
woocommerce_product_search | WooCommerce product search widgets/blocks |
woocommerce_shop_browse | Shop, category, and tag archive pages |
woocommerce_orders_search | WooCommerce admin orders search |
admin_{post_type}_search | Admin list table search, one per public post type (e.g. admin_post_search, admin_page_search, admin_product_search) |
admin_media_search | Media library search |
rest_api_search | REST API search endpoint |
Third parties can add types via the celersearch_area_types filter and register their implementation class with SearchAreaRegistry::register() — see the Class Reference.
Data Flow Example
Complete flow from WordPress to your search engine:
WordPress Post (WP_Post)
↓
IndexCandidate wrapper
↓
is_supported() check
↓
should_index() check
↓
get_candidate_objects()
↓
IndexablePost (IIndexableObject)
↓
get_indexable_data()
↓
JSON to Search Engine
// 1. WordPress Post
$post = get_post(123);
// 2. Wrap in IndexCandidate
$candidate = new IndexCandidate($post);
// 3. Check support
if (!$index->is_supported($candidate)) {
return;
}
// 4. Check if should index
if (!$index->should_index($candidate)) {
return;
}
// 5. Convert to indexable objects
$objects = $index->get_candidate_objects($candidate);
// 6. Each object implements IIndexableObject
foreach ($objects as $obj) {
$id = $obj->get_id(); // '123-0'
$data = $obj->get_indexable_data(); // [...all fields...]
// 7. Send to the search engine (delegates to the index's service)
$index->sync_item($obj);
}