{"id":18783665,"url":"https://github.com/tomkyle/repository-persistence","last_synced_at":"2026-03-12T14:21:41.439Z","repository":{"id":221979709,"uuid":"755930340","full_name":"tomkyle/repository-persistence","owner":"tomkyle","description":"Scaffold for Repository-and-Persistence design pattern","archived":false,"fork":false,"pushed_at":"2024-08-28T18:10:33.000Z","size":250,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-10T13:51:19.501Z","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/tomkyle.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-11T14:16:09.000Z","updated_at":"2024-08-28T18:10:34.000Z","dependencies_parsed_at":"2024-03-16T11:33:08.532Z","dependency_job_id":"aadddefb-2a12-49c2-b465-b483f1ef97e6","html_url":"https://github.com/tomkyle/repository-persistence","commit_stats":null,"previous_names":["tomkyle/repository-persistence"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2Frepository-persistence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2Frepository-persistence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2Frepository-persistence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2Frepository-persistence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomkyle","download_url":"https://codeload.github.com/tomkyle/repository-persistence/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248714728,"owners_count":21149955,"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-07T20:40:03.771Z","updated_at":"2026-03-12T14:21:41.403Z","avatar_url":"https://github.com/tomkyle.png","language":"PHP","readme":"\u003ch1 align=\"center\"\u003eRepository · Persistence\u003c/h1\u003e\n\n[![Packagist](https://img.shields.io/packagist/v/tomkyle/repository-persistence.svg?style=flat)](https://packagist.org/packages/tomkyle/repository-persistence)\n[![PHP version](https://img.shields.io/packagist/php-v/tomkyle/repository-persistence.svg)](https://packagist.org/packages/tomkyle/repository-persistence)\n[![PHP Composer](https://github.com/tomkyle/repository-persistence/actions/workflows/php.yml/badge.svg)](https://github.com/tomkyle/repository-persistence/actions/workflows/php.yml) \n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)\n\n**Scaffold for Repository-and-Persistence design pattern.**\n\n---\n\n## Installation\n\n```bash\n$ composer require tomkyle/repository-persistence\n```\n\n## Setup\n\n**The repository needs a persistence.**\n\n```php \n\u003c?php\n\nuse tomkyle\\RepositoryPersistence\\Repositories\\Repository;\nuse tomkyle\\RepositoryPersistence\\Persistence;\n\n$repo = new Repository(\n\tnew Persistence\\JsonFilePersistence('path/to/json')\n);\n```\n\nIn this example, the Persistence works on a directory `path/to/json` in which the items are stored in JSON files named by their ID. — Example: **john-doe.json**\n\n```json\n{\n  \"age\": 30,\n  \"city\": \"New York\",\n  \"name\": \"John Doe\"\n}\n```\n\n## Usage\n\n**Get item.** This method may throw `\\OutOfBoundsException`\n\n```php\ntry {\n  $person = $repo-\u003eget('john-doe');\n  print_r($person);\n} \ncatch (\\OutOfBoundsException) {\n  // Not found\n}\n```\n\nOutput will be like:\n\n```text\nArray  (\n  [age] =\u003e 30\n  [city] =\u003e New York\n  [name] =\u003e John Doe\n)\n```\n\n**Find one item by criteria.** This method may return `null`.\n\n```php\n$repo-\u003efindOneBy([\n  'name' =\u003e 'John'\n]);  \n```\n\n**Get all items:**\n\n```php\n$repo-\u003efindAll();\n```\n\n**Find items by criteria**\n\n```php\n$repo-\u003efindBy([\n  'color' =\u003e 'blue'\n]);\n```\n\n**Update item**\n\n```php\n$saved = $repo-\u003esave(['id' =\u003e 43, 'name' =\u003e 'John']));\n```\n\n**Delete item**\n\n```php\n$repo-\u003edelete(43);\n```\n\n**Create new item**\n\n```php\n$saved = $repo-\u003esave(['name' =\u003e 'Angie']));\n```\n\nIf you need the new ID onbeforehand in your App controller, e.g. for redirecting the client to the new resource, you can obtain a new ID from the repo. It then looks exactly like updating, but the *Repository* implementation will figure out if the item has to be created or updated.\n\n```php\n$new_id = $repo-\u003egetNextId();\n$repo-\u003esave(['id' =\u003e $new_id, 'name' =\u003e 'Angie']));\n```\n\n\n\n---\n\n## Persistence\n\nInside a repository, the *Persistence* actually manages the data storage.\n\n### Instantiation\n\n```php\n\u003c?php\nuse tomkyle\\RepositoryPersistence\\Repositories;\nuse tomkyle\\RepositoryPersistence\\Persistence;\n\n$persistence = new Persistence\\JsonFilePersistence('path/to/json');\n$persistence = new Persistence\\YamlFilePersistence('path/to/yaml');\n```\n\n### Methods API\n\n| Method  | Parameters       | Return        | Description   |\n| ------- | ---------------- | ------------- | ------------- |\n| create  | `array` data | `string¦int` | New ID        |\n| read    | `string¦int` id | `array`       | The record    |\n| readAll |                  | array         | All records   |\n| update  | `array` data     | `int`         | Affected rows |\n| delete  | `string¦int`  | `int`         | Affected rows |\n\n### Special implementations\n\n#### FrontmatterFilePersistence\n\nIf your JSON or YAML files have frontmatters:\n\n```php\n$persistence = new Persistence\\FrontmatterFilePersistence(\n\tnew Persistence\\JsonFilePersistence('path/to/json')\n);\n```\n\n#### PersistenceChain\n\n```php\n$persistence = new Persistence\\PersistenceChain(\n\tnew Persistence\\JsonFilePersistence('path/to/json'),\n\tnew Persistence\\YamlFilePersistence('path/to/yaml')\n);\n```\n\n#### InMemoryPersistence\n\nAn empty *Persistence* you can write and read to.\n\n```php\n$persistence = new Persistence\\InMemoryPersistence();\n```\n\n#### NoPersistence\n\nMock implementation of *Persistence* that simulates data persistence operations without actually storing data. Note that *read* method will always throw `\\OutOfBoundsException` as it does not contain any data!\n\n```php\n$persistence = new Persistence\\NoPersistence();\n```\n\n\n\n---\n\n## Repository\n\nThe repository is the thing you work with in your app.\n\n```php\n\u003c?php\nuse tomkyle\\RepositoryPersistence\\Repositories\\Repository;\nuse tomkyle\\RepositoryPersistence\\Persistence; \n\n// Feed a persistence to the repo:\n$persistence = new Persistence\\InMemoryPersistence();\n$repository = new Repository($persistence)\n```\n\n### Methods API\n\n| Method    | Required Parameters   | Optional                                                 | Return              | Description  |\n| --------- | --------------------- | -------------------------------------------------------- | ------------------- | ------------ |\n| get       | `string¦int` id     |                                                          | `array¦object`     | The record   |\n| findOneBy | `array` criteria      |                                                          | `array¦object¦null` | One record   |\n| findAll   |                       |                                                          | `iterable`          | All records  |\n| findBy    | `array` criteria      | `?array` orderBy,\u003cbr /\u003e `?int` limit\u003cbr /\u003e `?int` offset | `iterable`          | Some records |\n| save      | `array¦object` entity |                                                          | `bool`              |              |\n| delete    | `array¦object` entity |                                                          | `bool`              |              |\n\n---\n\n## Development\n\n### Install requirements\n\n```bash\n$ composer install\n$ npm install\n```\n\n### Watch source and run various tests\n\nThis will watch changes inside the **src/** and **tests/** directories and run a series of tests:\n\n1. Find and run the according unit test with *PHPUnit*.\n2. Find possible bugs and documentation isses using *phpstan*. \n3. Analyse code style and give hints on newer syntax using *Rector*.\n\n```bash\n$ npm run watch\n```\n\n### Run all tests\n\nChoose to your taste:\n\n```bash\n$ npm run phpunit\n$ composer test\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomkyle%2Frepository-persistence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomkyle%2Frepository-persistence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomkyle%2Frepository-persistence/lists"}