{"id":15169489,"url":"https://github.com/yii2tech/ar-position","last_synced_at":"2025-10-01T02:31:14.231Z","repository":{"id":57087031,"uuid":"43242436","full_name":"yii2tech/ar-position","owner":"yii2tech","description":"ActiveRecord behavior, which provides ability for custom records order setup","archived":true,"fork":false,"pushed_at":"2019-09-30T11:25:53.000Z","size":22,"stargazers_count":114,"open_issues_count":0,"forks_count":16,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-09-07T01:15:36.637Z","etag":null,"topics":["activerecord","custom","order","position","sort","yii","yii2","yii2-extension"],"latest_commit_sha":null,"homepage":null,"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":"2015-09-27T10:22:12.000Z","updated_at":"2024-11-26T06:29:58.000Z","dependencies_parsed_at":"2022-08-24T22:50:45.538Z","dependency_job_id":null,"html_url":"https://github.com/yii2tech/ar-position","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/yii2tech/ar-position","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-position","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-position/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-position/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-position/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yii2tech","download_url":"https://codeload.github.com/yii2tech/ar-position/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-position/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274592530,"owners_count":25313566,"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","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","custom","order","position","sort","yii","yii2","yii2-extension"],"created_at":"2024-09-27T07:02:08.700Z","updated_at":"2025-10-01T02:31:13.947Z","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 Position Extension for Yii2\u003c/h1\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\nThis extension provides support for ActiveRecord custom records order setup.\n\nFor license information check the [LICENSE](LICENSE.md)-file.\n\n[![Latest Stable Version](https://img.shields.io/packagist/v/yii2tech/ar-position.svg)](https://packagist.org/packages/yii2tech/ar-position)\n[![Total Downloads](https://img.shields.io/packagist/dt/yii2tech/ar-position.svg)](https://packagist.org/packages/yii2tech/ar-position)\n[![Build Status](https://travis-ci.org/yii2tech/ar-position.svg?branch=master)](https://travis-ci.org/yii2tech/ar-position)\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-position\n```\n\nor add\n\n```json\n\"yii2tech/ar-position\": \"*\"\n```\n\nto the require section of your composer.json.\n\n\nUsage\n-----\n\nThis extension provides support for custom records order setup via column-based position index.\n\nThis extension provides `\\yii2tech\\ar\\position\\PositionBehavior` ActiveRecord behavior for such solution\nsupport in Yii2. You may attach it to your model class in the following way:\n\n```php\n\u003c?php\n\nuse yii\\db\\ActiveRecord;\nuse yii2tech\\ar\\position\\PositionBehavior;\n\nclass Item extends ActiveRecord\n{\n    public function behaviors()\n    {\n        return [\n            'positionBehavior' =\u003e [\n                'class' =\u003e PositionBehavior::className(),\n                'positionAttribute' =\u003e 'position',\n            ],\n        ];\n    }\n}\n```\n\nBehavior uses the specific integer field of the database entity to set up position index.\nDue to this the database entity, which the model refers to, must contain field `positionAttribute`.\n\nIn order to display custom list in correct order you should sort it by `positionAttribute` in ascending mode:\n\n```php\n\u003c?php\n\n$records = Item::find()-\u003eorderBy(['position' =\u003e SORT_ASC])-\u003eall();\nforeach ($records as $record) {\n    echo $record-\u003eposition . ', ';\n}\n// outputs: 1, 2, 3, 4, 5,...\n```\n\n\n### Position saving \u003cspan id=\"position-saving\"\u003e\u003c/span\u003e\n\nBeing attached, behavior automatically fills up `positionAttribute` value for the new record, placing it to the end\nof the list:\n\n```php\n\u003c?php\n\necho Item::find()-\u003ecount(); // outputs: 4\n\n$item = new Item();\n$item-\u003esave();\n\necho $item-\u003eposition; // outputs: 5\n```\n\nHowever, you may setup position for the new record explicitly:\n\n```php\n\u003c?php\n\necho Item::find()-\u003ecount(); // outputs: 4\n\n$item = new Item();\n$item-\u003eposition = 2; // enforce position '2'\n$item-\u003esave();\n\necho $item-\u003eposition; // outputs: 2 !!!\n```\n\n\n### Position switching \u003cspan id=\"position-switching\"\u003e\u003c/span\u003e\n\nExisting record can be moved to another position using following methods:\n\n - `movePrev()` - moves record by one position towards the start of the list.\n - `moveNext()` - moves record by one position towards the end of the list.\n - `moveFirst()` - moves record to the start of the list.\n - `moveLast()` - moves record to the end of the list.\n - `moveToPosition()` - moves owner record to the specific position.\n\nYou may as well change record position through the attribute, provided to `positionAttribute` directly:\n\n```php\n\u003c?php\n\n$item = Item::find()-\u003eandWhere(['position' =\u003e 3])-\u003eone();\n$item-\u003eposition = 5; // switch position to '5'\n$item-\u003esave();\n```\n\n\n### Position in group \u003cspan id=\"position-in-group\"\u003e\u003c/span\u003e\n\nSometimes single database entity contains several listings, which require custom ordering, separated logically\nby grouping attributes. For example: FAQ questions may be grouped by categories, while inside single category\nquestions should be ordered manually. For this case `\\yii2tech\\ar\\position\\PositionBehavior::$groupAttributes`\ncan be used:\n\n```php\n\u003c?php\n\nuse yii\\db\\ActiveRecord;\nuse yii2tech\\ar\\position\\PositionBehavior;\n\nclass FaqQuestion extends ActiveRecord\n{\n    public function behaviors()\n    {\n        return [\n            'positionBehavior' =\u003e [\n                'class' =\u003e PositionBehavior::className(),\n                'positionAttribute' =\u003e 'position',\n                'groupAttributes' =\u003e [\n                    'categoryId' // multiple lists varying by 'categoryId'\n                ],\n            ],\n        ];\n    }\n}\n```\n\nIn this case behavior will use owner values of `groupAttributes` as additional condition for position\ncalculation and changing:\n\n```php\n\u003c?php\n\necho FaqQuestion::find()-\u003eandWhere(['categoryId' =\u003e 1])-\u003ecount(); // outputs: '4'\necho FaqQuestion::find()-\u003eandWhere(['categoryId' =\u003e 2])-\u003ecount(); // outputs: '7'\n\n$record = new FaqQuestion();\n$record-\u003ecategoryId = 1;\n$record-\u003esave();\necho $record-\u003eposition; // outputs: '5'\n\n$record = new FaqQuestion();\n$record-\u003ecategoryId = 2;\n$record-\u003esave();\necho $record-\u003eposition; // outputs: '8'\n```\n\n\n### List navigation \u003cspan id=\"list-navigation\"\u003e\u003c/span\u003e\n\nRecords with custom position order applied make a chained list, which you may navigate if necessary.\nYou may use `\\yii2tech\\ar\\position\\PositionBehavior::getIsFirst()` and `\\yii2tech\\ar\\position\\PositionBehavior::getIsLast()`\nmethods to determine if particular record is the first or last one in the list. For example:\n\n```php\n\u003c?php\n\necho Item::find()-\u003ecount(); // outputs: 10\n\n$firstItem = Item::find()-\u003eandWhere(['position' =\u003e 1])-\u003eone();\necho $firstItem-\u003egetIsFirst(); // outputs: true\necho $firstItem-\u003egetIsLast(); // outputs: false\n\n$lastItem = Item::find()-\u003eandWhere(['position' =\u003e 10])-\u003eone();\necho $lastItem-\u003egetIsFirst(); // outputs: false\necho $lastItem-\u003egetIsLast(); // outputs: true\n```\n\nHaving a particular record instance, you can always find record, which is located at next or previous position to it,\nusing `\\yii2tech\\ar\\position\\PositionBehavior::getNext()` or `\\yii2tech\\ar\\position\\PositionBehavior::getPrev()` method.\nFor example:\n\n```php\n\u003c?php\n\n$item = Item::find()-\u003eandWhere(['position' =\u003e 5])-\u003eone();\n\n$nextItem = $item-\u003efindNext();\necho $nextItem-\u003eposition; // outputs: 6\n\n$prevItem = $item-\u003efindPrev();\necho $prevItem-\u003eposition; // outputs: 4\n```\n\nYou may as well get the first and the last records in the list. For example:\n\n```php\n\u003c?php\n\necho Item::find()-\u003ecount(); // outputs: 10\n$item = Item::find()-\u003eandWhere(['position' =\u003e 5])-\u003eone();\n\n$firstItem = $item-\u003efindFirst();\necho $firstItem-\u003eposition; // outputs: 1\n\n$lastItem = $item-\u003efindLast();\necho $lastItem-\u003eposition; // outputs: 10\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-position","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyii2tech%2Far-position","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-position/lists"}