{"id":17689184,"url":"https://github.com/othyn/laravel-notes","last_synced_at":"2025-03-30T21:44:18.991Z","repository":{"id":65371817,"uuid":"587005084","full_name":"othyn/laravel-notes","owner":"othyn","description":"Assign notes to any model entity with ease.","archived":false,"fork":false,"pushed_at":"2023-02-02T20:44:38.000Z","size":84,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-06T02:19:33.327Z","etag":null,"topics":["composer","laravel","laravel-package","notes"],"latest_commit_sha":null,"homepage":"https://github.com/othyn/laravel-notes","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/othyn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2023-01-09T18:33:50.000Z","updated_at":"2024-11-16T02:59:22.000Z","dependencies_parsed_at":"2023-02-18T00:30:34.975Z","dependency_job_id":null,"html_url":"https://github.com/othyn/laravel-notes","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/othyn%2Flaravel-notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Flaravel-notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Flaravel-notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Flaravel-notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/othyn","download_url":"https://codeload.github.com/othyn/laravel-notes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246385395,"owners_count":20768668,"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":["composer","laravel","laravel-package","notes"],"created_at":"2024-10-24T11:46:47.752Z","updated_at":"2025-03-30T21:44:18.975Z","avatar_url":"https://github.com/othyn.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"art/logo.svg\" alt=\"logo\" width=\"200\" height=\"auto\" /\u003e\n    \u003ch1\u003eLaravel Notes\u003c/h1\u003e\n    \u003cp\u003eA centralised note store for any and all model entities. Finally, no longer a need for storing a notes field in each and every table! Ideal for system wide generic comment systems.\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003cp\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/actions/workflows/00-lint.yml\"\u003e\n            \u003cimg src=\"https://github.com/othyn/laravel-notes/actions/workflows/00-lint.yml/badge.svg\" alt=\"lint action\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/actions/workflows/10-tests.yml\"\u003e\n            \u003cimg src=\"https://github.com/othyn/laravel-notes/actions/workflows/10-tests.yml/badge.svg\" alt=\"tests action\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/actions/workflows/10-tests.yml\"\u003e\n            \u003cimg src=\"https://img.shields.io/badge/Test Coverage-100%25-green\" alt=\"coverage\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://packagist.org/packages/othyn/laravel-notes\"\u003e\n            \u003cimg src=\"https://img.shields.io/packagist/v/othyn/laravel-notes.svg?style=flat\" alt=\"packagist download\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://packagist.org/packages/othyn/laravel-notes\"\u003e\n            \u003cimg src=\"https://img.shields.io/packagist/dt/othyn/laravel-notes.svg?style=flat\" alt=\"packagist downloads count\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/graphs/contributors\"\u003e\n            \u003cimg src=\"https://img.shields.io/github/contributors/othyn/laravel-notes\" alt=\"contributors\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/network/members\"\u003e\n            \u003cimg src=\"https://img.shields.io/github/forks/othyn/laravel-notes\" alt=\"forks\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/stargazers\"\u003e\n            \u003cimg src=\"https://img.shields.io/github/stars/othyn/laravel-notes\" alt=\"stars\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/issues/\"\u003e\n            \u003cimg src=\"https://img.shields.io/github/issues/othyn/laravel-notes\" alt=\"open issues\" /\u003e\n        \u003c/a\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/blob/master/LICENSE\"\u003e\n            \u003cimg src=\"https://img.shields.io/github/license/othyn/laravel-notes\" alt=\"license\" /\u003e\n        \u003c/a\u003e\n    \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003ch4\u003e\n        \u003ca href=\"#floppy_disk-install\"\u003eInstall Latest Version\u003c/a\u003e\n        \u003cspan\u003e · \u003c/span\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/issues/new?assignees=\u0026labels=bug\u0026template=bug.yml\"\u003eReport Bug\u003c/a\u003e\n        \u003cspan\u003e · \u003c/span\u003e\n        \u003ca href=\"https://github.com/othyn/laravel-notes/issues/new?assignees=\u0026labels=enhancement\u0026template=enhancement.yml\"\u003eRequest Feature\u003c/a\u003e\n    \u003c/h4\u003e\n\u003c/div\u003e\n\n\u003c!-- Table of Contents --\u003e\n\n## :notebook_with_decorative_cover: Table of Contents\n\n- [About the Project](#star2-about-the-project)\n    - [Tech Stack](#space_invader-tech-stack)\n    - [Features](#dart-features)\n- [Install](#floppy_disk-install)\n    - [Version Matrix](#version-matrix)\n- [Usage](#hammer_and_wrench-usage)\n    - [Configuration](#wrench-configuration)\n    - [Models](#elephant-models)\n- [Contributing](#bread-contributing)\n    - [Project Tooling Quick Reference](#toolbox-project-tooling-quick-reference)\n- [Changelog](https://github.com/othyn/laravel-notes/releases)\n- [License](#warning-license)\n- [Acknowledgements](#gem-acknowledgements)\n\n\u003c!-- About the Project --\u003e\n\n## :star2: About the Project\n\nOn a recent personal project, I was finding that I was utilising a `notes` field against practically all tables, with\nthe functionality also shared. The idea being that the user could quickly leave notes against any entity in the system,\nin which centralising that saves a load of overhead in each table and repeat code. I also make use of a\nshared [Livewire table](https://github.com/rappasoft/laravel-livewire-tables) that automatically\nloads [Audit's](https://github.com/owen-it/laravel-auditing) (in which the awesome design of that package inspired\nthis one) for a given Entity when viewing it. The table is automatically injected into the rendered view determined\nautomatically by the URL slug, which was a perfect use case to replicate for the `notes` system, thus this library\nwas born.\n\n\u003c!-- TechStack --\u003e\n\n### :space_invader: Tech Stack\n\n\u003cul\u003e\n    \u003cli\u003eLanguage: \u003ca href=\"https://www.php.net/\"\u003ePHP\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003eDependency Manager: \u003ca href=\"https://getcomposer.org/\"\u003eComposer\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003eFramework: \u003ca href=\"https://laravel.com/\"\u003eLaravel\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003ePackage: \u003ca href=\"https://github.com/illuminate/support\"\u003eilluminate/support\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003ePackage: \u003ca href=\"https://github.com/orchestra/testbench\"\u003eorchestra/testbench\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003ePackage: \u003ca href=\"https://github.com/pestphp/pest\"\u003epestphp/pest\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003ePackage: \u003ca href=\"https://github.com/phpunit/phpunit\"\u003ephpunit/phpunit\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003ePackage: \u003ca href=\"https://github.com/friendsofphp/php-cs-fixer\"\u003efriendsofphp/php-cs-fixer\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003c!-- Features --\u003e\n\n### :dart: Features\n\n- Centralised note store against any Model entity\n- Saves replicating repetitive fields and functionality across many tables\n- Quickly apply the functionality to any Model with an interface and trait combo\n- Easily overridable User resolver for custom auth scenarios\n- Highly customisable and overridable\n- Up and running in minutes\n\nFuture addition ideas to play around with:\n\n- Some form of automated (customisable) injectable component for Blade and/or Livewire with backed CRUD functionality.\n- Expanding this out to quickly capture *any* set of recurring fields out across all tables with ease, could be an\n  interesting project enhancement\n\n\u003c!-- Install --\u003e\n\n## :floppy_disk: Install\n\nInstallation can be done via [Composer](https://getcomposer.org/):\n\n```sh\ncomposer require othyn/laravel-notes\n```\n\nThen publish the configuration file and migration(s) into your application scope via:\n\n```shell\n# Config\nphp artisan vendor:publish \\\n    --provider=\"Othyn\\\\LaravelNotes\\\\LaravelNotesServiceProvider\" \\\n    --tag=\"config\"\n\n# Migrations\nphp artisan vendor:publish \\\n    --provider=\"Othyn\\\\LaravelNotes\\\\LaravelNotesServiceProvider\" \\\n    --tag=\"migrations\"\n```\n\nRemember to check the default configuration aligns with your requirements (amending if necessary) and **run your\nmigrations to generate the new `notes` table!**\n\nNext you are going to want to head down to the [configuration](#wrench-configuration), so lets get started\non [usage](#hammer_and_wrench-usage)! See you there.\n\n### Version Matrix\n\nHere is the current version matrix for project supported versions of used frameworks and libraries.\n\n| Notes Version | PHP Version | Laravel Version |\n|---------------|-------------|-----------------|\n| `1.0.0`       | `^8.1`      | `^9.0`          |\n\nIf you require support for an older version of Laravel, submit an issue as we may be able to look into dropping the\nversion requirements down, as I don't think it needs to be this new. Or, feel free to submit a PR!\n\n\u003c!-- Usage --\u003e\n\n## :hammer_and_wrench: Usage\n\nLaravel Notes is simple in its implementation, to get started all you need to do is add the relevant interface and trait\ncombo the Model you wish to store notes against.\n\n### :elephant: Models\n\nSo, you want to use Laravel Notes eh? I like you, lets get cooking. All you need to do is add the relevant interface\nand trait combo the Model you wish to store notes against:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\n/**\n * What better place to store notes. \n */\nclass Fridge extends Model implements \\Othyn\\LaravelNotes\\Contracts\\Notable\n{\n    use \\Othyn\\LaravelNotes\\Traits\\Notable;\n}\n\n```\n\nThat's it!\n\nThe following methods and properties will be exposed against the model:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\n$fridge = Fridge::first();\n\n// Gets an Eloquent Collection of all Notes currently attached to the Fridge, this is a magic implementation that \n//  Laravel automagically generates based on the `notes()` relationship\n$notes = $fridge-\u003enotes;\n\n// Gets the latest Note that was attached to the Fridge\n$latestNote = $fridge-\u003elatestNote();\n\n// Gets the oldest Note that was attached to the Fridge\n$oldestNote = $fridge-\u003eoldestNote();\n\n// Create a new Note on the Fridge, with the authentication relation being automatically captured at creation if\n//  applicable, returns the created Note\n$note = $fridge-\u003enote(contents: 'Remember to buy some chocolate');\n\n// From the Note instance, you can also get the attached Notable instance, in this case the Fridge, this is a magic\n//  implementation that Laravel automagically generates based on the `notable()` relationship\n$notable = $note-\u003enotable;\n\n// From the Note instance, you can also get the attached User instance, in this case the default User implementation,\n//  this is a magic implementation that Laravel automagically generates based on the `user()` relationship\n$user = $note-\u003euser;\n```\n\nAs we are dealing with native Laravel relationships, all the usual Eloquent stuff also applies against the\nrelationship method that is used:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\n$fridge = Fridge::first();\n\n// Gets a Note by its ID on a Fridge\n$note = $fridge-\u003enotes()-\u003efind(7);\n\n// Get all Notes on the Fridge with who wrote them\n$notes = $fridge-\u003enotes()-\u003ewith('user')-\u003eget();\n```\n\nThis is what the default `Note` entity looks like, for easy property reference:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace Othyn\\LaravelNotes\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\n\n/**\n * Othyn\\LaravelNotes\\Models\\Note.\n *\n * @property int                             $id\n * @property int                             $user_id\n * @property int                             $user_type\n * @property int                             $notable_id\n * @property int                             $notable_type\n * @property string                          $contents\n * @property \\Illuminate\\Support\\Carbon|null $created_at\n * @property \\Illuminate\\Support\\Carbon|null $updated_at\n * @property \\Illuminate\\Support\\Carbon|null $deleted_at\n *\n * @mixin \\Eloquent\n */\nclass Note extends Model implements \\Othyn\\LaravelNotes\\Contracts\\Note\n{\n    use SoftDeletes;\n    use \\Othyn\\LaravelNotes\\Traits\\Note;\n\n    /**\n     * {@inheritdoc}\n     */\n    protected $guarded = [\n        'id',\n        'created_at',\n        'updated_at',\n        'deleted_at',\n    ];\n}\n```\n\nAs you can see, there is IDE type hinting baked into the Contracts and default Model to assist with method and\nproperty discovery for all of the above.\n\nIf you need to go beyond that and really turn things up to 11, lets touch on what the configuration can do for you.\n\n### :wrench: Configuration\n\nGiven we published the configuration as part of the installation, you should now have an `config/laravel-notes.php`\nfile within your project that you can edit. Below is a little detail on what each configuration option means and\nwhat it can do for you.\n\n- `note`\n    - Type: `\\Othyn\\LaravelNotes\\Contracts\\Note`\n    - Default: `\\Othyn\\LaravelNotes\\Models\\Note::class`\n    - Description:\n        - The Model instance to use to refer to a `Note`, that implements `\\Othyn\\LaravelNotes\\Contracts\\Note`.\n        - You can make use of the `\\Othyn\\LaravelNotes\\Traits\\Note` trait to implement base functionality if desired\n          in any custom implementation you make.\n- `auth.guards`\n    - Type: `array\u003cstring\u003e`\n    - Default: `['web', 'api']`\n    - Description:\n        - The Laravel Auth guards that should be polled to determine the logged in `User` to bind to the `Note`.\n- `auth.user.field_prefix`\n    - Type: `string`\n    - Default: `user`\n    - Description:\n        - The polymorphic relationship field prefix, will be used as `{field_prefix}_id` and `{field_prefix}_type`\n          within the `notes` table.\n- `auth.user.resolver`\n    - Type: `\\Othyn\\LaravelNotes\\Contracts\\UserResolver`\n    - Default: `\\Othyn\\LaravelNotes\\Resolvers\\UserResolver::class`\n    - Description:\n        - The object that should resolve the Authenticatable `Entity` that will be bound to the `Note`, the `id` of\n          the entity is all that matters.\n        - You can easily implement your own resolver using the `\\Othyn\\LaravelNotes\\Contracts\\UserResolver` contract.\n        - Must return an instance of `\\Illuminate\\Contracts\\Auth\\Authenticatable` or `null` as the user value.\n- `database.connection`\n    - Type: `string`\n    - Default: `config('database.default')`\n    - Description:\n        - The database connection that should be used for all notes related activity.\n        - When determining the default value, it will be read from the `LARAVEL_NOTES_CONNECTION` environment variable\n          first, before reading the Laravel default `database.default` config value.\n- `database.table`\n    - Type: `string`\n    - Default: `notes`\n    - Description:\n        - The database table that should be used for notes storage.\n        - When determining the default value, it will be read from the `LARAVEL_NOTES_TABLE` environment variable\n          first, before setting it to the pre-defined default value specified above.\n\nThat's it! Want to contribute? Keep reading.\n\n\u003c!-- Contributing --\u003e\n\n## :bread: Contributing\n\nSee the [contribution guide](CONTRIBUTING.md) on how to get started. Thank you for contributing!\n\n### :toolbox: Project Tooling Quick Reference\n\nThere are only a few project commands, and it's the usual stuff:\n\n```sh\n# Lets make sure things are formatted correctly.\n$ composer php-cs-fixer\n\n# Lets make sure things are still functioning as intended.\n$ composer test\n\n# Lets make sure things are still functioning as intended, this time with code coverage reporting.\n$ composer test-coverage\n```\n\nThat's about it, go make something cool and submit a PR!\n\n\u003c!-- License --\u003e\n\n## :warning: License\n\nDistributed under the MIT License. See [LICENSE](LICENSE) for more\ninformation.\n\n\u003c!-- Acknowledgments --\u003e\n\n## :gem: Acknowledgements\n\nUseful resources and libraries that have been used in the making of this project.\n\n- Readme: [Louis3797/awesome-readme-template](https://github.com/Louis3797/awesome-readme-template)\n- Readme: [ikatyang/emoji-cheat-sheet](https://github.com/ikatyang/emoji-cheat-sheet)\n- Readme: [shields.io](https://shields.io/)\n- Logo: [Tag SVG Vector 242](https://www.svgrepo.com/svg/411760/tag)\n    - From the [Cube Icon Collection](https://www.svgrepo.com/collection/cube-action-icons/)\n    - Licenced under the [CC Attribution License](https://www.svgrepo.com/page/licensing)\n- Starter: [Laravel Package Boilerplate](https://laravelpackageboilerplate.com)\n- Inspiration: [owen-it/laravel-auditing](https://github.com/owen-it/laravel-auditing)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fothyn%2Flaravel-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fothyn%2Flaravel-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fothyn%2Flaravel-notes/lists"}