{"id":21894758,"url":"https://github.com/zumba/swivel-cake","last_synced_at":"2025-04-15T16:03:13.901Z","repository":{"id":30972758,"uuid":"34530968","full_name":"zumba/swivel-cake","owner":"zumba","description":"CakePHP plugin for Zumba\\Swivel","archived":false,"fork":false,"pushed_at":"2020-11-10T20:02:02.000Z","size":55,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":35,"default_branch":"master","last_synced_at":"2024-11-18T10:55:21.428Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zumba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-24T17:01:51.000Z","updated_at":"2020-11-10T20:01:04.000Z","dependencies_parsed_at":"2022-08-22T20:41:05.902Z","dependency_job_id":null,"html_url":"https://github.com/zumba/swivel-cake","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zumba%2Fswivel-cake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zumba%2Fswivel-cake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zumba%2Fswivel-cake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zumba%2Fswivel-cake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zumba","download_url":"https://codeload.github.com/zumba/swivel-cake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226922335,"owners_count":17703763,"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":[],"created_at":"2024-11-28T13:27:59.385Z","updated_at":"2024-11-28T13:28:00.121Z","avatar_url":"https://github.com/zumba.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CakePHP Plugin for Zumba ***Swivel***\n\n[Zumba Swivel](https://github.com/zumba/swivel) is a library that allows PHP applications to\nmanage features to multiple users via buckets. It consists with 10 buckets, allowing the same\ncode have up to 10 different behaviors.\n\nThis plugin is a bridge between CakePHP and Swivel. It provides a helper, component and\nbehavior classes to be used in your CakePHP application.\n\n## Installation\n\nYou can install Swivel Cake into your project using [composer](http://getcomposer.org).\nFor existing applications you can add the following to your `composer.json` file:\n\n```\n    \"require\": {\n        \"zumba/swivel-cake\": \"1.*\"\n    }\n```\n\nAnd run `php composer.phar update`\n\n## Loading the Plugin\n\nAfter installing, you should tell your application to load the plugin:\n\n```php\nCakePlugin::load('Swivel', ['bootstrap' =\u003e true]);\n```\n\n## Configuration\n\nThe plugin has default configurations and is ready to use. However, you can customize\nsome of the configurations.\n\n| Configuration | Default Value | Description |\n| ------------- | ------------- | ----------- |\n| Cookie.enabled | `true` | If cookie should be set at all |\n| Cookie.name   | `Swivel_Bucket` | Cookie name used to store the client bucket number. |\n| Cookie.expire | `0` | Expiration, in seconds, of the cookie. Setting 0 means a session cookie. |\n| Cookie.path | `/` | Cookie's path. |\n| Cookie.domain | `env('HTTP_HOST')` | Domain name used for the cookie. |\n| Cookie.secure | `false` | If cookie can be only used in secure transmissions, ie. HTTPS |\n| Cookie.httpOnly | `false` | If cookie can be accessed via other sources other than HTTP, ie. JavaScript |\n| BucketIndex | `null` | Defines the user's bucket. Leaving null it will auto-generate a number between 1 and 10. |\n| LoaderAlias | `SwivelManager` | Name that will be used to store the instance on Cake's `ClassRegistry`. |\n| Logger | `null` | Instance to receive the logs. Setting to `null` will make the log be discarded. |\n| Metrics | `null` | Metrics instance. |\n| ModelAlias | `Swivel.SwivelFeature` | Model name that will provide the swivel mapping configuration. |\n\nTo set custom configurations, you need to create a file in `APP/Config/swivel.php` and set the fields you\nwant to override. Here is the default configuration file:\n\n```php\n\u003c?php\n\n$config = [\n    'Swivel' =\u003e [\n        'Cookie' =\u003e [\n            'enabled' =\u003e true,\n            'name' =\u003e 'Swivel_Bucket',\n            'expire' =\u003e 0,\n            'path' =\u003e '/',\n            'domain' =\u003e env('HTTP_HOST'),\n            'secure' =\u003e false,\n            'httpOnly' =\u003e false\n        ],\n        'BucketIndex' =\u003e null,\n        'LoaderAlias' =\u003e 'SwivelManager',\n        'Logger' =\u003e null,\n        'Metrics' =\u003e null,\n        'ModelAlias' =\u003e 'Swivel.SwivelFeature',\n    ]\n];\n```\n\nLet's say for an example that you want to reserve one bucket for your testing and give the other 9\nbuckets to your customers, you can do something like this:\n```php\n\u003c?php\n\n// Saving bucket 1 for internal testing\n$bucketIndex = isset($_COOKIE['Swivel_Bucket']) ? $_COOKIE['Swivel_Bucket'] : mt_rand(2, 10);\n\n$config = [\n    'Swivel' =\u003e [\n        'BucketIndex' =\u003e $bucketIndex\n    ]\n];\n```\n\n## Loading Feature List\n\nIn order to Swivel to work, you need to specify which features are enabled for each bucket.\n\n### Loading Feature via Database\n\nThe default behavior from swivel-cake is to load the features from database. This is done via\nthe built-in class `Swivel.SwivelFeature`. This class However expects the table `swivel_buckets`\nto exist in your `default` database configuration.\n\nThis is the minimum table structure:\n```sql\nCREATE TABLE `swivel_features` (\n  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n  `slug` varchar(255) NOT NULL,\n  `buckets` varchar(20) NOT NULL DEFAULT '1,2,3,4,5,6,7,8,9,10',\n  PRIMARY KEY (`id`),\n  UNIQUE KEY `slug_UNIQUE` (`slug`)\n);\n```\n\nFeel free to add more fields if you want. For example, at Zumba we have the field modified\nthat automatically auto-update when we change the buckets configuration. If you rename one\nof the pre-defined fields you will have to extends the plugin model and update accordingly.\n\nNote the buckets are in a string field, separated by comma. You should not add spaces between\nthe numbers.\n\n### Loading via Custom Source\n\nYou can also load the feature list from any other source, ie. from a webservice that you\nuse to share across all your apps.\n\nIn order to do that, create a model and make this model to implement `SwivelModelInterface`\ninterface. Example, I will call my model `MySwivelFeature`:\n\n```php\n\u003c?php\nApp::uses('AppModel', 'Model');\nApp::uses('SwivelModelInterface', 'Swivel.Lib');\n\nclass SwivelFeature extends AppModel implements SwivelModelInterface {\n    public $useTable = false;\n\n    public function getMapData()\n    {\n        // @todo Load data from some source\n        // @todo Format this data in a KEY/VALUE array, where KEY is the feature\n        // and VALUE is the buckets in an array format, ie [1, 2, 3]\n        // @todo Return the formatted data\n        return [\n            'FeatureA' =\u003e [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],\n            'FeatureB' =\u003e [1, 2, 3],\n            'FeatureC' =\u003e [2, 4, 6, 8, 10],\n        ];\n    }\n}\n```\n\n## Using\n\nEither the component, behavior and helper implement the methods `forFeature` and `invoke`,\nwhich are part of swivel. You can check the details of these methods in\n[Swivel's documentation](https://github.com/zumba/swivel#zumbaswivelmanager).\n\nTo exemplify in CakePHP application:\n\n```php\n\u003c?php\n\nclass UsersController extends AppController\n{\n    public $components = ['Swivel.Swivel'];\n    public $uses = ['User', 'MyCoolWidget'];\n\n    public function index()\n    {\n        $this-\u003eset('users', $this-\u003eUser-\u003efind(/* ... */));\n        $this-\u003eSwivel-\u003einvoke('MyCoolWidget', function() {\n            return $this-\u003eset('widget', $this-\u003eMyCoolWidget-\u003efind(/* ... */));\n        });\n    }\n\n    public function view($id = null)\n    {\n        $this-\u003eSwivel-\u003eforFeature('Redesign')\n            -\u003eaddBehavior('userView', [$this, 'renderNewView'], [$id])\n            -\u003edefaultBehavior([$this, 'renderOldView'], [$id])\n            -\u003eexecute();\n    }\n\n    protected function renderOldView($id)\n    {\n        // @todo implement\n        $this-\u003erender('oldView');\n    }\n\n    protected function renderNewView($id)\n    {\n        // @todo implement\n        $this-\u003erender('newView');\n    }\n}\n```\n\nThis is just an example of how you can use the plugin in the controller, but\nyou can also use it on your models and views.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzumba%2Fswivel-cake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzumba%2Fswivel-cake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzumba%2Fswivel-cake/lists"}