{"id":15169750,"url":"https://github.com/yii2tech/ar-search","last_synced_at":"2025-10-01T02:31:46.350Z","repository":{"id":57087060,"uuid":"70786034","full_name":"yii2tech/ar-search","owner":"yii2tech","description":"Provides unified search model for Yii ActiveRecord","archived":true,"fork":false,"pushed_at":"2020-03-04T11:20:08.000Z","size":31,"stargazers_count":31,"open_issues_count":0,"forks_count":5,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-01-14T08:58:48.491Z","etag":null,"topics":["activerecord","filter","filtering","search","yii","yii2","yii2-extension"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yii2tech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["klimov-paul"],"patreon":"klimov_paul"}},"created_at":"2016-10-13T08:35:50.000Z","updated_at":"2023-10-07T00:36:02.000Z","dependencies_parsed_at":"2022-08-24T05:21:24.997Z","dependency_job_id":null,"html_url":"https://github.com/yii2tech/ar-search","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yii2tech","download_url":"https://codeload.github.com/yii2tech/ar-search/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234812848,"owners_count":18890763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activerecord","filter","filtering","search","yii","yii2","yii2-extension"],"created_at":"2024-09-27T07:22:06.334Z","updated_at":"2025-10-01T02:31:41.058Z","avatar_url":"https://github.com/yii2tech.png","language":"PHP","funding_links":["https://github.com/sponsors/klimov-paul","https://patreon.com/klimov_paul"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/yii2tech\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://avatars2.githubusercontent.com/u/12951949\" height=\"100px\"\u003e\n    \u003c/a\u003e\n    \u003ch1 align=\"center\"\u003eActiveRecord Search Model Extension for Yii2\u003c/h1\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\nThis extension provides unified search model for Yii ActiveRecord.\n\nFor license information check the [LICENSE](LICENSE.md)-file.\n\n[![Latest Stable Version](https://img.shields.io/packagist/v/yii2tech/ar-search.svg)](https://packagist.org/packages/yii2tech/ar-search)\n[![Total Downloads](https://img.shields.io/packagist/dt/yii2tech/ar-search.svg)](https://packagist.org/packages/yii2tech/ar-search)\n[![Build Status](https://travis-ci.org/yii2tech/ar-search.svg?branch=master)](https://travis-ci.org/yii2tech/ar-search)\n\n\nInstallation\n------------\n\nThe preferred way to install this extension is through [composer](http://getcomposer.org/download/).\n\nEither run\n\n```\nphp composer.phar require --prefer-dist yii2tech/ar-search\n```\n\nor add\n\n```json\n\"yii2tech/ar-search\": \"*\"\n```\n\nto the require section of your composer.json.\n\n\nUsage\n-----\n\nThis extension provides unified search model for Yii ActiveRecord via special model class -\n`\\yii2tech\\ar\\search\\ActiveSearchModel`.\n\nThis model is able to fetch its attributes, validation rules and filtering logic from the 'slave'\nsource ActiveRecord model specified via `\\yii2tech\\ar\\search\\ActiveSearchModel::$model`.\nThus you do not need to declare a separated model class for searching and define a filter logic.\nFor example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item'\n]);\n$dataProvider = $searchModel-\u003esearch(Yii::$app-\u003erequest-\u003equeryParams);\n```\n\n`ActiveSearchModel` picks all 'safe' attributes of the 'slave' model and use them as own attributes.\nThus you can use any attribute, which is marked as 'safe' in related ActiveRecord model in the scope\nof this class. For example:\n\n```php\n\u003c?php\n\nnamespace app\\models;\n\n// ActiveRecord to be searched:\nclass Item extends \\yii\\db\\ActiveRecord\n{\n    public function rules()\n    {\n        return [\n            [['name', 'status', 'price'], 'required'],\n            ['name', 'string'],\n            ['status', 'integer'],\n            ['price', 'number'],\n        ];\n    }\n}\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\n\n// Create search model for declared ActiveRecord:\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item'\n]);\n\n// safe attributes of `Item` are inherited:\n$searchModel-\u003ename = 'Paul';\n$searchModel-\u003eprice = 10.5;\n```\n\nInherited attributes may be used while composing web forms, which should collect filter data.\nFor example:\n\n```php\n\u003c?php\nuse yii2tech\\ar\\search\\ActiveSearchModel;\nuse yii\\widgets\\ActiveForm;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item'\n]);\n?\u003e\n\u003c?php $form = ActiveForm::begin(); ?\u003e\n\n\u003c?= $form-\u003efield($model, 'name')-\u003etextInput() ?\u003e\n\u003c?= $form-\u003efield($model, 'price')-\u003etextInput() ?\u003e\n...\n\n\u003c?php ActiveForm::end(); ?\u003e\n```\n\nAttribute labels and hints are also inherited from the 'slave' model.\n\nThe main method of `\\yii2tech\\ar\\search\\ActiveSearchModel` is `search()`. It loads filter attributes\nfrom given data array, validates them an creates a `\\yii\\data\\ActiveDataProvider` instance applying\nown attributes as a query filter condition.\n\n`ActiveSearchModel` uses a sophisticated logic for the query filtering, based on the attribute types,\nspecified by `\\yii2tech\\ar\\search\\ActiveSearchModel::$searchAttributeTypes`, which value is extracted\nfrom `\\yii2tech\\ar\\search\\ActiveSearchModel::$model` by default and filter operators list, specified via\n`\\yii2tech\\ar\\search\\ActiveSearchModel::$filterOperators`.\nBy default `\\yii\\db\\QueryInterface::andFilterWhere()` will be used for the filter composition. For the\n'string' attributes it will be used with 'like' operator. For 'integer' and 'float' ('double') method\n`andFilterCompare()` will be used, if it is available.\n\n**Heads up!** Do not abuse `ActiveSearchModel` usage. It has been designed to cover only the simplest\ncases, when search logic is trivial. You should always create a separated search model in case, it\nrequires complex logic of composition of the search query.\n\n\n## Adjusting Data Provider \u003cspan id=\"adjusting-data-provider\"\u003e\u003c/span\u003e\n\nYou may want to change some settings of the data provider, created by the `search()` method: change\npagination or sort settings and so on. You can do this via `\\yii2tech\\ar\\search\\ActiveSearchModel::$dataProvider`.\nFor example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item',\n    'dataProvider' =\u003e [\n        'class' =\u003e 'yii\\data\\ActiveDataProvider',\n        'pagination' =\u003e [\n            'defaultPageSize' =\u003e 40\n        ],\n    ],\n]);\n$dataProvider = $searchModel-\u003esearch(Yii::$app-\u003erequest-\u003equeryParams);\necho $dataProvider-\u003epagination-\u003edefaultPageSize; // outputs `40`\n```\n\n\n## Adjusting Search Query \u003cspan id=\"adjusting-search-query\"\u003e\u003c/span\u003e\n\nYou may use `\\yii2tech\\ar\\search\\ActiveSearchModel::EVENT_AFTER_CREATE_QUERY` event to adjust the search query instance\nadding relation eager loading or permanent conditions. For example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\nuse yii2tech\\ar\\search\\ActiveSearchEvent;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item',\n]);\n$searchModel-\u003eon(ActiveSearchModel::EVENT_AFTER_CREATE_QUERY, function(ActiveSearchEvent $event) {\n    $event-\u003equery\n        -\u003ewith(['category'])\n        -\u003eandWhere(['status' =\u003e 1]);\n});\n```\n\nYou may also specify query object directly via `\\yii2tech\\ar\\search\\ActiveSearchModel::$dataProvider`. For example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\nuse yii\\data\\ActiveDataProvider;\nuse app\\models\\Item;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e Item::className(),\n    'dataProvider' =\u003e function () {\n        $query = Item::find()\n            -\u003ewith(['category'])\n            -\u003eandWhere(['status' =\u003e 1]);\n\n        return ActiveDataProvider(['query' =\u003e $query]);\n    },\n]);\n```\n\n\n## Filter Operators \u003cspan id=\"filter-operators\"\u003e\u003c/span\u003e\n\nYou can control the operators to be used for the query filtering via `\\yii2tech\\ar\\search\\ActiveSearchModel::$filterOperators`.\nIt defines a mapping between the attribute type and the operator to be used with `\\yii\\db\\QueryInterface::andFilterWhere()`.\nEach value can be a scalar operator name or a PHP callback, accepting query instance, attribute name and value.\nFor example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item',\n    'filterOperators' =\u003e [\n        ActiveSearchModel::TYPE_STRING =\u003e '=', // use strict comparison for the string attributes\n        ActiveSearchModel::TYPE_INTEGER =\u003e function (\\yii\\db\\ActiveQueryInterface $query, $attribute, $value) {\n            if ($attribute === 'commentsCount') {\n                $query-\u003eandHaving(['commentsCount' =\u003e $value]);\n            } else {\n                $query-\u003eandFilterWhere([$attribute =\u003e $value]);\n            }\n        },\n    ],\n]);\n```\n\n`ActiveSearchModel` allows filtering for the attributes using `andFilterCompare()` method of the query (for example:\n`\\yii\\db\\Query::andFilterCompare()`), which allows specifying filter value in format: `{operator}{value}` (for\nexample: `\u003e10`, `\u003c=100` and so on). The list of attribute names, for which usage of such comparison is allowed is controlled\nby `\\yii2tech\\ar\\search\\ActiveSearchModel::$compareAllowedAttributes`. For example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\n\n$searchModel = new ActiveSearchModel([\n    'model' =\u003e 'app\\models\\Item',\n    'compareAllowedAttributes' =\u003e [\n        'price' // allow compare for 'price' only, excluding such fields like 'categoryId', 'status' and so on.\n    ],\n]);\n```\n\nYou can set `compareAllowedAttributes` to `*`, which indicates any float or integer attribute will be allowed for comparison.\n\n\u003e Note: `\\yii2tech\\ar\\search\\ActiveSearchModel::$filterOperators` take precedence over `\\yii2tech\\ar\\search\\ActiveSearchModel::$compareAllowedAttributes`.\n\n\n## Working Without 'Slave' Model \u003cspan id=\"working-without-model\"\u003e\u003c/span\u003e\n\nAlthough in most cases setup of `\\yii2tech\\ar\\search\\ActiveSearchModel::$model` is a quickest way to configure `ActiveSearchModel`\ninstance, it is not mandatory. You can avoid setup of the 'slave' model and configure all search related properties\ndirectly. For example:\n\n```php\n\u003c?php\n\nuse yii2tech\\ar\\search\\ActiveSearchModel;\nuse yii\\data\\ActiveDataProvider;\nuse app\\models\\Item;\n\n$searchModel = new ActiveSearchModel([\n    'searchAttributeTypes' =\u003e [\n        'id' =\u003e ActiveSearchModel::TYPE_INTEGER,\n        'name' =\u003e ActiveSearchModel::TYPE_STRING,\n        'price' =\u003e ActiveSearchModel::TYPE_FLOAT,\n    ],\n    'rules' =\u003e [\n        ['id', 'integer'],\n        ['name', 'string'],\n        ['price', 'number'],\n    ],\n    'compareAllowedAttributes' =\u003e [],\n    'dataProvider' =\u003e function () {\n        $query = Item::find()\n            -\u003ewith(['category'])\n            -\u003eandWhere(['status' =\u003e 1]);\n\n        return ActiveDataProvider(['query' =\u003e $query]);\n    },\n]);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyii2tech%2Far-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-search/lists"}