{"id":15169741,"url":"https://github.com/yii2tech/ar-dynattribute","last_synced_at":"2025-10-01T02:31:43.670Z","repository":{"id":57087027,"uuid":"66558022","full_name":"yii2tech/ar-dynattribute","owner":"yii2tech","description":"Provide ActiveRecord dynamic attributes stored into the single field in serialized state","archived":true,"fork":false,"pushed_at":"2019-07-03T10:58:51.000Z","size":25,"stargazers_count":45,"open_issues_count":0,"forks_count":12,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-13T18:48:20.187Z","etag":null,"topics":["activerecord","dynamic","dynamic-attributes","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":"2016-08-25T12:59:33.000Z","updated_at":"2023-10-07T23:59:11.000Z","dependencies_parsed_at":"2022-08-24T22:50:51.200Z","dependency_job_id":null,"html_url":"https://github.com/yii2tech/ar-dynattribute","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-dynattribute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-dynattribute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-dynattribute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yii2tech%2Far-dynattribute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yii2tech","download_url":"https://codeload.github.com/yii2tech/ar-dynattribute/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234812835,"owners_count":18890757,"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","dynamic","dynamic-attributes","yii","yii2","yii2-extension"],"created_at":"2024-09-27T07:21:54.121Z","updated_at":"2025-10-01T02:31:38.404Z","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 Dynamic Attribute Extension for Yii2\u003c/h1\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\nThis extension provides dynamic ActiveRecord attributes stored into the single field in serialized state.\n\nFor license information check the [LICENSE](LICENSE.md)-file.\n\n[![Latest Stable Version](https://poser.pugx.org/yii2tech/ar-dynattribute/v/stable.png)](https://packagist.org/packages/yii2tech/ar-dynattribute)\n[![Total Downloads](https://poser.pugx.org/yii2tech/ar-dynattribute/downloads.png)](https://packagist.org/packages/yii2tech/ar-dynattribute)\n[![Build Status](https://travis-ci.org/yii2tech/ar-dynattribute.svg?branch=master)](https://travis-ci.org/yii2tech/ar-dynattribute)\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-dynattribute\n```\n\nor add\n\n```json\n\"yii2tech/ar-dynattribute\": \"*\"\n```\n\nto the require section of your composer.json.\n\n\nUsage\n-----\n\nThis extension provides dynamic ActiveRecord attributes stored into the single field in serialized state.\nFor example: imagine we create a web site, where logged in user may customize its appearance, like changing\ncolor schema or enable/disable sidebar and so on. In order to make this customization persistent all user's\nchoices should be stored into the database. In general each view setting should have its own column in the\n'user' table. However, this is not very practical in case your application is under development and new\nsettings appear rapidly. Thus it make sense to use single text field, which will store all chosen view\nparameters in the serialized string. If new option introduced there will no necessity to change 'user' table\nschema.\nMigration for the 'user' table creation may look like following:\n\n```php\nclass m??????_??????_create_user extends \\yii\\db\\Migration\n{\n    public function up()\n    {\n        $this-\u003ecreateTable('User', [\n            'id' =\u003e $this-\u003eprimaryKey(),\n            'username' =\u003e $this-\u003estring()-\u003enotNull(),\n            'email' =\u003e $this-\u003estring()-\u003enotNull(),\n            'passwordHash' =\u003e $this-\u003estring()-\u003enotNull(),\n            // ...\n            'viewParams' =\u003e $this-\u003etext(), // field, which stores view parameters in serialized state\n        ]);\n    }\n\n    public function down()\n    {\n        $this-\u003edropTable('User');\n    }\n}\n```\n\n**Heads up!** In general such data storage approach is a **bad** practice and is not recommended to be used.\nIts main drawback is inability to use dynamic attributes in condition for the search query.\nIt is acceptable only for the attributes, which are directly set and read for single record only, and never\nused for the filter queries.\n\n\u003e Tip: you may store dynamic attributes into 'JSON' type column instead of plain text, in case you are using modern DBMS\n  with built-in JSON support (e.g. MySQL \u003e= 5.5 or PostgreSQL), however, you will have to deal with possible search\n  condition composition on your own - this extension does not provide explicit support for it.\n\nThis extension provides [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior]] ActiveRecord behavior for\nthe dynamic attributes support.\nFor example:\n\n```php\nuse yii\\db\\ActiveRecord;\nuse yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior;\n\nclass User extends ActiveRecord\n{\n    public function behaviors()\n    {\n        return [\n            'dynamicAttribute' =\u003e [\n                'class' =\u003e DynamicAttributeBehavior::className(),\n                'storageAttribute' =\u003e 'viewParams', // field to store serialized attributes\n                'dynamicAttributeDefaults' =\u003e [ // default values for the dynamic attributes\n                    'bgColor' =\u003e 'green',\n                    'showSidebar' =\u003e true,\n                ],\n            ],\n        ];\n    }\n\n    public static function tableName()\n    {\n        return 'User';\n    }\n\n    // ...\n}\n```\n\nOnce being attached [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior]] allows its owner to operate\ndynamic attributes just as regular one. On model save they will be serialized and stored into the holding\nfield. After record is fetched from database the first attempt to read the dynamic attributes will unserialize\nthem and prepare for the usage.\nFor example:\n\n```php\n$model = new User();\n// ...\n$model-\u003ebgColor = 'red';\n$model-\u003eshowSidebar = false;\n$model-\u003esave(); // 'bgColor' and 'showSidebar' are serialized and stored at 'viewParams'\necho $model-\u003eviewParams; // outputs: '{\"bgColor\": \"red\", \"showSidebar\": false}'\n\n$refreshedModel = User::findOne($model-\u003egetPrimaryKey());\necho $refreshedModel-\u003ebgColor; // outputs 'red'\necho $refreshedModel-\u003eshowSidebar; // outputs 'false'\n```\n\nYou may use dynamic attributes as the regular ActiveRecord attributes. For example: you may\nspecify the validation rules for them and obtain their values via web form.\n\n\u003e Note: keep in mind that dynamic attributes do not correspond to ActiveRecord entity fields, thus\n  some particular ActiveRecord methods like `updateAttributes()` will not work for them.\n\n\n## Default values setup \u003cspan id=\"default-values-setup\"\u003e\u003c/span\u003e\n\nAs you may note from above example, you can provide a default values for the dynamic attributes\nvia [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior::$dynamicAttributeDefaults]].\nThus once you need extra dynamic attribute for your model you can just update the `dynamicAttributeDefaults`\nlist with corresponding value, without necessity to perform any updates on your database.\n\n```php\nclass User extends ActiveRecord\n{\n    public function behaviors()\n    {\n        return [\n            'dynamicAttribute' =\u003e [\n                'class' =\u003e DynamicAttributeBehavior::className(),\n                'storageAttribute' =\u003e 'viewParams',\n                'dynamicAttributeDefaults' =\u003e [\n                    'bgColor' =\u003e 'green',\n                    'showSidebar' =\u003e true,\n                    'fontColor' =\u003e 'black', // newly added attribute\n                ],\n            ],\n        ];\n    }\n\n    // ...\n}\n\n$newModel = new User();\necho $newModel-\u003ebgColor; // outputs 'green'\necho $newModel-\u003eshowSidebar; // outputs 'true'\n\n$oldModel = User::find()-\u003eorderBy(['id' =\u003e SORT_ASC])-\u003elimit(1)-\u003eone();\necho $oldModel-\u003eviewParams; // outputs: '{\"bgColor\": \"red\", \"showSidebar\": false}'\necho $oldModel-\u003efontColor; // outputs: 'black'\n```\n\n\u003e Note: you may exclude dynamic attribute, which value equals the default one, from saving disabling\n  [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior::$saveDynamicAttributeDefaults]] option.\n\n\n## Restrict dynamic attribute list \u003cspan id=\"restrict-dynamic-attribute-list\"\u003e\u003c/span\u003e\n\nSetup of the dynamic attribute default values not only useful, but in general is necessary.\nThis list puts a restriction on the possible dynamic attribute names. Only attributes, which\nhave default value specified can be set or read from the model. This prevents the possible mistakes\ncaused by typos in the code.\nFor example:\n\n```php\n$newModel = new User();\n$newModel-\u003ebgColor = 'blue'; // works fine\n$newModel-\u003eunExistingAttribute = 10; // throws an exception!\n```\n\nHowever sometimes there is necessity of storage list of attributes, which can not be predicted.\nFor example, saving response fields from some external service.\nIn this case you can disable check performed on attribute setter using\n[[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior::$allowRandomDynamicAttribute]].\nIf it is set to `true` you will be able to setup any dynamic attribute no matter declared or not\nat `dynamicAttributeDefaults`.\n\n\u003e Note: you can also use [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior::setDynamicAttributes()]] method\n  to bypass naming restriction. This method will set all provided attributes without any checks.\n\nYou can as well control the dynamic attributes list to be actually saved using [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior::$dynamicAttributeSaveFilter]].\nIf set to `true` it will exclude any attribute, which is not listed at `dynamicAttributeDefaults` option. You may as\nwell specify it as a PHP callback, which will perform some custom filtering. This option allows you to remove obsolete\ndynamic attributes, which existed in the past, but no longer actual.\n\n\n## Serializer setup \u003cspan id=\"serializer-setup\"\u003e\u003c/span\u003e\n\nBy default [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior]] saves the dynamic attribute in JSON\nformat. However, you may setup another serializer for them via [[\\yii2tech\\ar\\dynattribute\\DynamicAttributeBehavior::$serializer]].\nThe following serializers are available withing this extension:\n\n - [[\\yii2tech\\ar\\dynattribute\\JsonSerializer]] - stores data in JSON format\n - [[\\yii2tech\\ar\\dynattribute\\PhpSerializer]] - stores data using PHP `serialize()`/`unserialize()` functions\n - [[\\yii2tech\\ar\\dynattribute\\CallbackSerializer]] - stores data via custom serialize PHP callback.\n - [[\\yii2tech\\ar\\dynattribute\\JsonExpressionSerializer]] - handles [[yii\\db\\JsonExpression]] instances, supporting usage of 'JSON' DB column types.\n\nPlease refer to the particular serializer class for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-dynattribute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyii2tech%2Far-dynattribute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyii2tech%2Far-dynattribute/lists"}