1. Go to this page and download the library: Download tobento/app-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/ */
tobento / app-search example snippets
use Tobento\App\AppFactory;
use Tobento\App\Search\InputInterface;
use Tobento\App\Search\SearchInterface;
// Create the app
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots:
$app->boot(\Tobento\App\Search\Boot\Search::class);
$app->booting();
// Implemented interfaces:
$search = $app->get(SearchInterface::class);
$input = $app->get(InputInterface::class);
// Run the app
$app->run();
use Tobento\App\Search\Filters;
use Tobento\App\Search\FiltersInterface;
use Tobento\App\Search\Input;
use Tobento\App\Search\InputInterface;
use Tobento\App\Search\Search;
use Tobento\App\Search\Searchables;
use Tobento\App\Search\SearchablesInterface;
use Tobento\App\Search\SearchInterface;
use Tobento\App\Search\SearchResultsInterface;
$search = new Search(
filters: new Filters(), // FiltersInterface
searchables: new Searchables(), // SearchablesInterface
);
var_dump($search instanceof SearchInterface);
// bool(true)
// Searching:
$searchResults = $search->search(
input: new Input(['search' => ['term' => 'foo']]), // InputInterface
);
var_dump($searchResults instanceof SearchResultsInterface);
// bool(true)
// You may get the filters:
var_dump($search->filters() instanceof FiltersInterface);
// bool(true)
// You may get the searchables:
var_dump($search->searchables() instanceof SearchablesInterface);
// bool(true)
'features' => [
new Feature\Search(
// The default views to render:
view: 'search/index',
viewSearchbar: 'search/searchbar',
viewSearchbarResults: 'search/searchbar-results',
// You may customize the searchbar input placeholder:
searchbarInputPlaceholder: 'Search...',
// If true, routes are being localized.
localizeRoute: false,
),
],
<header><?= $view->render('search.bar')
use Psr\Container\ContainerInterface;
use Tobento\App\Search\Search;
use Tobento\App\Search\Searchable;
use Tobento\App\Search\Searchables;
use Tobento\App\Search\SearchInterface;
use Tobento\App\Search\Filter;
use Tobento\App\Search\Filters;
'interfaces' => [
SearchInterface::class => static function(ContainerInterface $container): SearchInterface {
return new Search(
filters: new Filters(
new Filter\SearchTerm(name: 'search.term'),
),
searchables: new Searchables(
new Searchable\Menus($container->get(\Tobento\Service\Menu\MenusInterface::class)->menu('main')),
),
);
},
],
use Tobento\App\Search\Searchable;
use Tobento\App\Search\SearchablesInterface;
use Tobento\App\Search\SearchInterface;
$app->on(
SearchInterface::class,
static function(SearchInterface $search) use ($app): void {
// Get the searchables:
$searchables = $search->searchables();
// SearchablesInterface
// Adding a searchable:
$menu = $app->get(\Tobento\Service\Menu\MenusInterface::class)->menu('main');
$searchables->add(searchable: new Searchable\Menus(menu: $menu));
}
);
use Tobento\App\Search\Filter;
use Tobento\App\Search\FilterInterface;
use Tobento\App\Search\FiltersInterface;
use Tobento\App\Search\SearchableInterface;
use Tobento\App\Search\SearchResult;
use Tobento\App\Search\SearchResultInterface;
use Tobento\Service\Pagination\Pagination;
use Tobento\Service\Pagination\PaginationInterface;
use Tobento\Service\Pagination\UrlGenerator;
use Tobento\Service\View\ViewInterface;
class ProductsSearchable implements SearchableInterface
{
protected null|PaginationInterface $pagination = null;
public function __construct(
protected ProductRepository $repository,
protected ViewInterface $view,
protected int $priority = 0,
) {}
public function name(): string
{
return 'products';
}
public function title(): string
{
return 'Products';
}
public function priority(): int
{
return $this->priority;
}
/**
* Returns the filters.
*
* @return array<array-key, FilterInterface>
*/
public function filters(): array
{
// Configure specific products filters defining the searchable attribute on each filter:
return [
new Filter\Select(
name: 'search.product-color',
label: 'Colors',
searchable: $this->name(),
options: ['red' => 'Red', 'blue' => 'Blue'],
),
new Filter\Pagination(
name: 'search.product-page',
searchable: $this->name(),
pagination: $this->pagination(),
),
];
}
/**
* Returns the search results found.
*
* @param FiltersInterface $filters
* @return array<array-key, SearchResultInterface>
*/
public function search(FiltersInterface $filters): array
{
$where = [];
$orderBy = [];
$limit = [];
// Use the filters you wish to apply to your query:
foreach($filters as $filter) {
switch ($filter::class) {
case Filter\Select::class:
if ($filter->name() === 'search.product-color') {
// apply filter to query:
}
break;
case Filter\SearchTerm::class:
// apply filter to query:
break;
case Filter\Pagination::class:
if ($filter->name() === 'search.product-page') {
$this->pagination = $filter->pagination();
$limit = [$this->pagination->getItemsPerPage(), $this->pagination->getItemsOffset()];
}
break;
}
}
if ($filters->has('search.product-page')) {
$paginationFilter = $filters->get('search.product-page');
$paginationFilter->updatePaginationTotalItems($this->repository->count(where: $where));
$this->pagination = $paginationFilter->pagination();
$limit = [$this->pagination->getItemsPerPage(), $this->pagination->getItemsOffset()];
}
// Do the query and create the search results:
$results = [];
foreach($this->repository->findAll(where: $where, orderBy: $orderBy, limit: $limit) as $item) {
$results = new SearchResult(
searchable: $this->name(),
type: $this->title(),
title: $item->get('title'),
url: $item->get('url'),
image: $item->get('image'),
// you may add html for custom search result:
html: $this->view->render(
view: 'product/search-result',
data: $item,
),
);
}
return $results;
}
public function totalItems(): int
{
return $this->pagination()->getTotalItems();
}
public function pagination(): PaginationInterface
{
if ($this->pagination) {
return $this->pagination;
}
return $this->pagination = new Pagination(
totalItems: $this->repository->count(),
currentPage: 1,
itemsPerPage: 25,
maxPagesToShow: 6,
maxItemsPerPage: 100,
urlGenerator: (new UrlGenerator())->addPageUrl('?search[product-page]={num}'),
);
}
}
use Psr\Container\ContainerInterface;
use Tobento\App\Search\Search;
use Tobento\App\Search\Searchable;
use Tobento\App\Search\Searchables;
use Tobento\App\Search\SearchInterface;
use Tobento\App\Search\Filter;
use Tobento\App\Search\Filters;
'interfaces' => [
SearchInterface::class => static function(ContainerInterface $container): SearchInterface {
return new Search(
filters: new Filters(
new Filter\SearchTerm(name: 'search.term'),
),
searchables: new Searchables(
new Searchable\Menus($container->get(\Tobento\Service\Menu\MenusInterface::class)->menu('main')),
),
);
},
],
use Tobento\App\Search\Filter;
use Tobento\App\Search\FiltersInterface;
use Tobento\App\Search\SearchInterface;
$app->on(
SearchInterface::class,
static function(SearchInterface $search) use ($app): void {
// Get the filters:
$filters = $search->filters();
// FiltersInterface
// Adding a filter:
$filters->add(filter: new Filter\SearchTerm(name: 'search.term'));
}
);
use Tobento\App\Search\Searchable;
use Tobento\Service\Menu\MenuInterface;
$searchable = new Searchable\Menu(
menu: $menu, // MenuInterface
// Set a unique name:
name: 'menu',
// You may set a custom title:
title: 'Menu Items',
// You may set a priority:
priority: 100,
);
use Tobento\App\Search\Searchable;
use Tobento\App\Search\SearchResult;
use Tobento\App\Search\SearchResultInterface;
use Tobento\Service\Repository\RepositoryInterface;
$searchable = new Searchable\Repository(
repository: $repository, // RepositoryInterface
// Set a unique name:
name: 'products',
// Set a title:
title: 'Products',
// Define the search attributes:
searchAttributes: ['title', 'description'],
// Map the repository items to the search results:
toSearchResult: function(object $item, Searchable\Repository $searchable): SearchResultInterface {
return new SearchResult(
searchable: $searchable->name(),
type: $searchable->title(),
title: $item->get('title'),
description: $item->get('description'),
url: $item->get('url'),
image: $item->get('image'),
);
},
// You may set a priority:
priority: 100,
);
use Tobento\App\Search\Filter;
$filter = new Filter\Clear(
// Set a unique name:
name: 'search.clear',
// You may set a custom label:
label: 'Clear all',
// You may set attributes for the button element:
attributes: ['data-foo' => 'value'],
);
use Tobento\App\Search\Filter;
$filter = new Filter\Input(
// Set a unique name:
name: 'search.price.from',
// You may set a label:
label: 'Price From',
// You may set a description:
description: 'Searches prices from.',
// You may set a searchable the filter belongs to:
searchable: 'products', // or null
// You may change the default input type (text):
inputType: 'range',
// You may set attributes for the input element:
inputAttributes: ['min' => '5'],
// You may set a default input value:
inputValue: '10', // or null
// You may set a custom view to render:
view: 'search/filter',
);
use Tobento\App\Search\Filter;
$filter = new Filter\Searchables(
// Set a unique name:
name: 'search.searchables',
// You may set a custom label:
label: 'Content',
// You may set a description:
description: 'Choose the contents you wish to search.',
// You may set a custom view to render:
view: 'search/filter',
);
use Tobento\App\Search\Filter;
$filter = new Filter\SearchTerm(
// Set a unique name:
name: 'search.term',
// You may set a label:
label: 'Search',
// You may set a description:
description: 'Search for ...',
// You may set a custom placeholder text:
placeholder: 'Search ...',
// You may set a custom view to render:
view: 'search/filter',
);
use Tobento\App\Search\Filter;
$filter = new Filter\Select(
// Set a unique name:
name: 'search.colors',
// You may set a label:
label: 'Colors',
// You may set a description:
description: 'Choose any colors you wish to search for.',
// You may set a searchable the filter belongs to:
searchable: 'products', // or null
// Set the options to choose from:
options: ['blue' => 'Blue', 'red' => 'Red'],
// with optgroup options:
// options: ['Primary' => ['blue' => 'Blue']],
// You may set a default value:
selected: ['blue'],
// You may set attributes for the select element:
selectAttributes: ['multiple'],
// You may set attributes for the option elements:
optionAttributes: ['*' => ['data-foo' => 'val']],
// You may set attributes for the optgroup elements:
optgroupAttributes: ['data-foo' => 'value'],
// You may set a custom view to render:
view: 'search/filter',
);
app/config/search.php
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.