kazda01/yii2-search

A simple search engine that allows the user to search for models by defined attributes and rules.

Installs: 811

Dependents: 0

Suggesters: 0

Security: 0

Stars: 2

Watchers: 2

Forks: 0

Open Issues: 1

Type:yii2-extension

dev-main 2024-03-16 17:14 UTC

This package is auto-updated.

Last update: 2024-12-16 18:51:58 UTC


README

A simple search engine that allows the user to search for models by defined attributes and rules.

Tests Total Downloads License

Search example

After specifying the rules, the user can search for multiple Models by multiple attributes at once. The results are then dynamically listed under the input. For each search result, its IdentifyingString and the name of the attribute in which a match was found is displayed. The exact match is also highlighted in bold.

Installation

The preferred way to install this extension is through composer.

composer require kazda01/yii2-search "@dev"

Usage

1. Add Module and configure search parameters

After adding the project via composer, you need to add the SearchModule in the web.php modules and configure searching parameters. If you want to have multiple different search engines (e.g. Invoice and User search engine), add the Module multiple times, ModuleID will be used for distinguishing.

The ModuleID will also be used to create the search route. The final requests will go to website.com/ModuleID/search?search=query. It is important to add the ModuleID to bootstrap so that the route is added to the UrlManager with priority over your site's routes (this action is not needed if your routes do not conflict with the search route).

return [
    ...
    'bootstrap' => ['<ModuleID>'],
    'modules' => [
        '<ModuleID>' => [
            'class' => '\kazda01\search\SearchModule',
            'searchConfig' => [
                '<ModelSearch>' => [
                    'columns' => ['<ModelAttribute>', '<ModelAttribute>'],
                    'matchTitle' => '<matchTitle>',
                    'matchText' => function($model){
                        return 'Model: ' . $model->id;
                    }
                ],
            ]
        ],
    ],
    ...
];

All available settings are described here.

2. Add Search Model classes

Search Model classes must be generated. They can be simply made by Gii CRUD generator. You can restrict what results certain users can search/display.

3. Generate search input

In a view, add this line.

<?= SearchInput::widget(['search_id' => 'main-search']); ?>

All available settings are described here.

Options

Module config

Search Config

Input widget Config

Examples

Example web.php

Search invoice-search allows all users to search

  • Invoice models by their invoice_number attribute

Search main-search allows logged in users to search

  • Invoice models by their invoice_number attribute
  • InvoiceItem models by their description attribute
  • Company models by their name, vat_id and state attribute

By clicking on Invoice result, user gets redirected to Invoice detail page.

By clicking on InvoiceItem result, user gets redirected to the detail page of Invoice which has the item.

By clicking on Company result, user gets redirected to Invoice listing with set parameter in url to filter the Invoices by Company customer.

Company results are also grouped by name, vat_id and state attributes. They are also filtered by Companies, that are recorded as a Customer on any invoice, not supplier.

return [
    ...
    'bootstrap' => ['main-search', 'invoice-search'],
    'modules' => [
        'main-search' => [
            'class' => '\kazda01\search\SearchModule',
            'allowGet' => true,
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'],
                    'actions' => ['index'], // allows only logged in users
                ],
            ],
            'searchConfig' => [
                'CompanySearch' => [
                    'columns' => ['name', 'vat_id', 'state'],
                    'matchTitle' => function(){
                        return Yii::t('app', 'Company')
                    },
                    'matchText' => function($model){
                        return $model->name . ', ' . $model->vat_id;
                    }
                    'route' => 'invoice/index',
                    'route_params' => function ($model) {
                        return ['InvoiceSearch[fk_company_customer]' => $model->name];
                    },
                    'only_if' => function ($model) {
                        return \app\models\Invoice::find()->where(['fk_company_customer' => $model->id])->count() > 0;
                    },
                    'group_by' => true,
                ],
                'InvoiceSearch' => [
                    'columns' => ['invoice_number'],
                    'matchTitle' => 'Invoice',
                    'matchText' => function($model){
                        return 'Invoice number ' . $model->invoice_number;
                    }
                ],
                'InvoiceItemSearch' => [
                    'columns' => ['description'],
                    'matchTitle' => 'Invoice item',
                    'matchText' => function($model){
                        return 'Invoice number: ' . $model->invoice->invoice_number;
                    }
                    'route' => 'invoice/view',
                    'route_params' => function ($model) {
                        return ['id' => $model->invoice->id];
                    }
                ],
            ]
        ],
        'invoice-search' => [
            'class' => '\kazda01\search\SearchModule',
            'searchConfig' => [
                'InvoiceSearch' => [
                    'columns' => ['invoice_number'],
                    'matchTitle' => 'Invoice',
                    'matchText' => function($model){
                        return 'Invoice number: ' . $model->invoice_number;
                    }
                ],
            ]
        ]
    ],
    ...
];

Example view.php

<div class="row g-0 justify-content-center">
    <?= SearchInput::widget([
        'search_id' => 'main-search',
        'placeholder' => Yii::t('app', 'Invoice number, customer name, job description..'),
        'wrapperClass' => 'col-11 col-lg-8 col-xl-7 mx-auto',
        'inputClass' => 'form-control p-2 no-outline',
    ]); ?>
</div>

License

MIT

Authors

Tests

Every push to the repository triggers the CI test pipeline. You can run them locally by running these commands in the project root directory.

vendor/bin/phpstan analyse ./src
vendor/bin/phpcs ./src --extensions=php --colors --standard=PSR12 -n
vendor/bin/phpunit tests