{"id":28501905,"url":"https://github.com/testmonitor/eloquent-lockable","last_synced_at":"2026-02-28T23:31:06.119Z","repository":{"id":288443734,"uuid":"968120528","full_name":"testmonitor/eloquent-lockable","owner":"testmonitor","description":"Make Laravel Eloquent models read-only after they're locked. Prevents updates and deletes based on a \"locked\" attribute.","archived":false,"fork":false,"pushed_at":"2025-10-28T15:29:49.000Z","size":49,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-27T06:03:36.538Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.testmonitor.com/","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/testmonitor.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-17T14:40:44.000Z","updated_at":"2025-10-28T15:29:53.000Z","dependencies_parsed_at":"2025-04-18T05:27:19.937Z","dependency_job_id":"26a345fe-a284-4f63-b38b-8c8c9efede74","html_url":"https://github.com/testmonitor/eloquent-lockable","commit_stats":null,"previous_names":["testmonitor/eloquent-lockable"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/testmonitor/eloquent-lockable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testmonitor%2Feloquent-lockable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testmonitor%2Feloquent-lockable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testmonitor%2Feloquent-lockable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testmonitor%2Feloquent-lockable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/testmonitor","download_url":"https://codeload.github.com/testmonitor/eloquent-lockable/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testmonitor%2Feloquent-lockable/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29954955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T22:53:01.873Z","status":"ssl_error","status_checked_at":"2026-02-28T22:52:50.699Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2025-06-08T16:08:25.069Z","updated_at":"2026-02-28T23:31:06.093Z","avatar_url":"https://github.com/testmonitor.png","language":"PHP","readme":"# Eloquent Lockable\n\n[![Latest Stable Version](https://poser.pugx.org/testmonitor/eloquent-lockable/v/stable)](https://packagist.org/packages/testmonitor/eloquent-lockable)\n[![CircleCI](https://img.shields.io/circleci/project/github/testmonitor/eloquent-lockable.svg)](https://circleci.com/gh/testmonitor/eloquent-lockable)\n[![codecov](https://codecov.io/gh/testmonitor/eloquent-lockable/graph/badge.svg?token=KOVD6QX7PD)](https://codecov.io/gh/testmonitor/eloquent-lockable)\n[![StyleCI](https://styleci.io/repos/968120528/shield)](https://styleci.io/repos/968120528)\n[![License](https://poser.pugx.org/testmonitor/eloquent-lockable/license)](https://packagist.org/packages/eloquent-lockable)\n\nMake Laravel Eloquent models read-only after they're locked. Prevents updates and deletes based on a \"locked\" attribute. Includes a trait and required interface to clearly define and enforce lockable models.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [Tests](#tests)\n- [Changelog](#changelog)\n- [Contributing](#contributing)\n- [Credits](#credits)\n- [License](#license)\n\n## Installation\n\nThis package can be installed through Composer:\n\n```sh\n$ composer require testmonitor/eloquent-lockable\n```\n\nNo need to publish anything — just use the trait and you’re good to go.\n\n## Usage\n\nFirst, make sure to add a `locked` column to your model's table:\n\n```php\nSchema::table('invoices', function (Blueprint $table) {\n    $table-\u003eboolean('locked')-\u003edefault(false);\n});\n```\n\nNext, implement the Lockable trait and interface:\n\n```php\nuse Illuminate\\Database\\Eloquent\\Model;\nuse TestMonitor\\Lockable\\Traits\\Lockable;\nuse TestMonitor\\Lockable\\Contracts\\IsLockable;\n\nclass Invoice extends Model implements IsLockable\n{\n    use Lockable;\n}\n```\n\nThat's it!\n\n### Locking \u0026 Unlocking\n\nNow you can start locking and unlocking models:\n\n```php\n$invoice-\u003emarkLocked();\n$invoice-\u003emarkUnlocked();\n\n$invoice-\u003eisLocked();    // true or false\n```\n\n### Exceptions\n\nTrying to update or delete a locked model will throw a ModelLockedException.\n\n```php\ntry {\n    $invoice-\u003eupdate(['amount' =\u003e 999]);\n} catch (ModelLockedException $exception) {\n    $model = $exception-\u003egetModel();\n}\n```\n\n### Temporary Locking\n\nTemporarily lock or unlock a model using a callback:\n\n```php\n$invoice-\u003ewhileLocked(function ($model) {\n    // Model is locked inside this closure\n});\n\n$invoice-\u003ewhileUnlocked(function ($model) {\n    // Temporarily unlocked\n});\n```\n\nThese automatically restore the original lock state — even if an exception is thrown.\n\n### Retrieving Locked and Unlocked Models\n\nConvenient query scopes are provided to filter locked and unlocked models:\n\n```php\nInvoice::locked()-\u003eget();\nInvoice::unlocked()-\u003eget();\n```\n\nThese are local scopes and can be used just like any other Eloquent scope.\n\n### Configurable Lock Column\n\nWant to use a different column like archived or readonly?\n\nOverride the getLockColumn() method in your model:\n\n```php\npublic function getLockColumn(): string\n{\n    return 'archived';\n}\n```\n\n### Allow Deletion of Locked Models\n\nIf you want to allow deletion of locked models, override the canDeleteWhenLocked() method in your model:\n\n```php\npublic function canDeleteWhenLocked(): bool\n{\n    return true;\n}\n```\n\n### Allow Modifying Specific Attributes While Locked\n\nSometimes, you may want to allow certain attributes to be changed. To do this, override the getLockExceptions() method in your model:\n\n```php\npublic function getLockExceptions(): array\n{\n    return ['note'];\n}\n```\n\nOnly the attributes listed in getLockExceptions() may be modified while the model is locked.\n\n## Tests\n\nThe package contains integration tests. You can run them using PHPUnit.\n\n```\n$ vendor/bin/phpunit\n```\n\n## Changelog\n\nRefer to [CHANGELOG](CHANGELOG.md) for more information.\n\n## Contributing\n\nRefer to [CONTRIBUTING](CONTRIBUTING.md) for contributing details.\n\n## Credits\n\n- [Thijs Kok](https://www.testmonitor.com/)\n- [Stephan Grootveld](https://www.testmonitor.com/)\n- [Frank Keulen](https://www.testmonitor.com/)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Refer to the [License](LICENSE.md) for more information.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftestmonitor%2Feloquent-lockable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftestmonitor%2Feloquent-lockable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftestmonitor%2Feloquent-lockable/lists"}