PHP code example of considbrs-webdev / typesense-search
1. Go to this page and download the library: Download considbrs-webdev/typesense-search library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
considbrs-webdev / typesense-search example snippets
// Re-index a post after your plugin changes data that affects the index
do_action('typesense_search/index_post', $post_id);
// Explicitly remove a post from the index
do_action('typesense_search/deindex_post', $post_id);
$doc = new IndexableDocument([
'id' => (string) $post->ID,
'title' => $post->post_title,
'url' => get_permalink($post),
// ...
]);
// Non-destructive update (returns a new instance)
$doc = $doc->with('author', get_the_author());
// Pass to Typesense
$doc->toArray();
// Add a field to every indexed post
add_filter(
'Municipio/TypesenseSearch/DocumentBuilder/build',
function (array $document, \WP_Post $post): array {
$document['author'] = get_the_author_meta('display_name', $post->post_author);
return $document;
},
10,
2
);
// Add a field only to documents of post_type "event"
add_filter(
'Municipio/TypesenseSearch/DocumentBuilder/event/build',
function (array $document, \WP_Post $post): array {
$document['event_date'] = get_post_meta($post->ID, '_event_date', true);
return $document;
},
10,
2
);
namespace MyPlugin\Search;
use TypesenseSearch\Indexing\IndexableDocument;
use TypesenseSearch\Indexing\Strategies\AbstractIndexingStrategy;
class ProductIndexingStrategy extends AbstractIndexingStrategy
{
public function getIdentifier(): string
{
return 'product';
}
public function supports(\WP_Post $post): bool
{
return $post->post_type === 'product';
}
public function shouldIndex(\WP_Post $post): bool
{
// Only index products that are in stock
return $post->post_status === 'publish'
&& get_post_meta($post->ID, '_stock_status', true) === 'instock';
}
public function buildDocument(\WP_Post $post): IndexableDocument|false
{
$price = get_post_meta($post->ID, '_price', true);
if ($price === '') {
return false; // skip products without a price
}
return new IndexableDocument([
'id' => (string) $post->ID,
'title' => $post->post_title,
'content' => wp_strip_all_tags($post->post_content),
'excerpt' => get_the_excerpt($post),
'url' => get_permalink($post),
'type' => 'product',
'type_name'=> __('Product', 'my-plugin'),
'price' => (float) $price,
]);
}
}
add_action(
'Municipio/TypesenseSearch/RegisterStrategies',
function (
\TypesenseSearch\Indexing\IndexingRegistry $registry,
\TypesenseSearch\Services\TypesenseClientService $clientService,
\TypesenseSearch\Services\SettingsRepository $settings,
\TypesenseSearch\Logger\LoggerInterface $logger
): void {
// Register before PostIndexingStrategy if your type could otherwise
// be caught by the generic post handler first.
$registry->register(new \MyPlugin\Search\ProductIndexingStrategy($clientService, $settings, $logger));
},
10, 4
);
// Prevent a specific post from being indexed without touching the meta box
add_filter(
\TypesenseSearch\Indexing\Strategies\PostIndexingStrategy::FILTER_SHOULD_INDEX,
function (bool $shouldIndex, \WP_Post $post): bool {
if ($post->post_type === 'post' && has_tag('no-index', $post)) {
return false;
}
return $shouldIndex;
},
10,
2
);
namespace MyPlugin\Search;
use TypesenseSearch\Indexing\IndexableDocument;
use TypesenseSearch\Indexing\Strategies\AbstractExternalIndexingStrategy;
class EServiceIndexingStrategy extends AbstractExternalIndexingStrategy
{
public const CRON_HOOK = 'myplugin_sync_eservices';
// ── Identity ────────────────────────────────────────────────────────────
public function getIdentifier(): string
{
return 'eservice';
}
// ── Hook registration ───────────────────────────────────────────────────
/**
* Schedule a daily WP-Cron sync and wire it to syncAll().
* Called automatically by IndexingRegistry::registerAllHooks().
*/
public function registerHooks(): void
{
add_action('init', function (): void {
if (!wp_next_scheduled(self::CRON_HOOK)) {
wp_schedule_event(time(), 'daily', self::CRON_HOOK);
}
});
add_action(self::CRON_HOOK, [$this, 'syncAll']);
}
// ── Data fetching ───────────────────────────────────────────────────────
/**
* Fetch all items from the external source.
* May return any iterable — array, Generator, or Traversable.
*/
protected function fetchItems(): iterable
{
$response = wp_remote_get('https://api.example.com/eservices', ['timeout' => 15]);
if (is_wp_error($response)) {
$this->logger->error('[EService] API error: ' . $response->get_error_message());
return [];
}
$data = json_decode(wp_remote_retrieve_body($response), true);
return $data['items'] ?? [];
}
// ── Document building ───────────────────────────────────────────────────
/**
* Convert one raw item into an IndexableDocument.
* Return false to skip the item.
*/
protected function buildDocument(mixed $item): IndexableDocument|false
{
if (empty($item['id']) || empty($item['title'])) {
return false;
}
return new IndexableDocument([
'id' => $this->getExternalId($item), // MUST be namespaced
'title' => (string) $item['title'],
'content' => (string) ($item['description'] ?? ''),
'excerpt' => (string) ($item['short_description'] ?? ''),
'url' => (string) ($item['url'] ?? ''),
'type' => 'eservice',
'type_name' => __('E-service', 'my-plugin'),
'date' => isset($item['updated_at'])
? (int) strtotime($item['updated_at'])
: 0,
]);
}
/**
* Return the namespaced Typesense document ID for a raw item.
* Must match the 'id' value set in buildDocument().
*/
protected function getExternalId(mixed $item): string
{
return 'eservice-' . $item['id'];
}
}
add_filter(
'Municipio/TypesenseSearch/placeholderMappings',
function (array $mappings): array {
// {SEARCH_HIT_DEPARTMENT} will be replaced with the value of the
// 'department' field on each Typesense hit document.
$mappings['SEARCH_HIT_DEPARTMENT'] = 'department';
return $mappings;
}
);
add_filter(
'Municipio/TypesenseSearch/hitTemplateView',
function (string $view, string $key): string {
if ($key === 'my-event') {
// Point to a view inside your theme or another plugin
return 'my-theme.search.hit-event';
}
return $view;
},
10,
2
);
// Re-index a post after your plugin changes data that should update the index.
// The post must already be published — nothing happens for drafts etc.
do_action('typesense_search/index_post', $post_id);
// Explicitly remove a post from the index.
do_action('typesense_search/deindex_post', $post_id);
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.