{"id":22555388,"url":"https://github.com/asseco-voice/laravel-custom-fields","last_synced_at":"2025-04-05T08:04:16.559Z","repository":{"id":40485365,"uuid":"276032098","full_name":"asseco-voice/laravel-custom-fields","owner":"asseco-voice","description":"Extensible Laravel models without the need for additional database attributes","archived":false,"fork":false,"pushed_at":"2024-12-09T23:45:42.000Z","size":666,"stargazers_count":48,"open_issues_count":4,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-29T07:07:36.561Z","etag":null,"topics":["database","laravel","laravel-8-package","laravel-framework","laravel-package","microservice","microservices","php"],"latest_commit_sha":null,"homepage":"","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/asseco-voice.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":"2020-06-30T07:43:51.000Z","updated_at":"2025-03-18T23:07:52.000Z","dependencies_parsed_at":"2024-02-08T00:26:48.763Z","dependency_job_id":"fbb802ff-d766-4b6e-9528-c9bb5dbf5f52","html_url":"https://github.com/asseco-voice/laravel-custom-fields","commit_stats":{"total_commits":152,"total_committers":7,"mean_commits":"21.714285714285715","dds":0.638157894736842,"last_synced_commit":"04062637398f933bf68cc425e6abcf858f876975"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-custom-fields","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-custom-fields/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-custom-fields/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-custom-fields/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asseco-voice","download_url":"https://codeload.github.com/asseco-voice/laravel-custom-fields/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247305932,"owners_count":20917208,"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":["database","laravel","laravel-8-package","laravel-framework","laravel-package","microservice","microservices","php"],"created_at":"2024-12-07T19:07:45.434Z","updated_at":"2025-04-05T08:04:16.542Z","avatar_url":"https://github.com/asseco-voice.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003ca href=\"https://see.asseco.com\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/asseco-voice/art/blob/main/evil_logo.png\" width=\"500\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n# Custom fields\n\nPurpose of this repository is to provide custom field support for any Laravel model. \n\n**Custom field** can be any field with which you wish to extend your model providing\na highly flexible model for additional fields, without the need to add new attributes \nto a DB model.\n\n## Installation\n\nRequire the package with ``composer require asseco-voice/laravel-custom-fields``.\nService provider will be registered automatically.\n\n## Setup\n\nIn order to use this repository the following must be done:\n\n1. Each model which requires custom field support MUST use ``Customizable`` trait. \n1. Run ``php artisan migrate`` to migrate package tables\n1. Run ``php artisan db:seed --class=\"Asseco\\CustomFields\\Database\\Seeders\\PlainTypeSeeder\"``\nto seed mandatory data only. \n1. You may include ``CustomFieldPackageSeeder`` within your ``DatabaseSeeder``\nseeders and have it seed mandatory data in all environments or seed all other dummy data in\nnon-production environments. \n\n## ERD\n\n![graph](erd.png)\n\n# Custom field types breakdown\n\nA single custom field can assume the form of one of three different types of custom fields, all of which \nare a polymorphic relation to custom fields table.\n\n#### Plain type\n\nPlain types are a standard single-value properties like int/string/date etc. Be sure to seed the mandatory\ndata before you go and use the package as these fields map directly to custom field value attributes depending on\ntheir type. \n\nI.e. if you say that custom field is of a plain string value, its value will be written in the string column of\na custom field values table. \n\n#### Remote type\n\nIf you'd like to fetch custom fields from some arbitrary endpoint, you can use remote type. Remote type has standard\nURL/method/headers/body attributes so that your request can be executed successfully. \n\nUsing remote type custom fields require you to define which plain types are you ultimately returning so that \npackage knows how to map the values to their attribute columns.  \n\n#### Selection type\n\nSelection types provide a set of predefined values from which you can select one or many. \n\nSelection types also require you to define which plain types are you ultimately returning so that \npackage knows how to map the values to their attribute columns.  \n\n# Defining custom fields\n\nOnce all the mandatory data is seeded you can start defining custom fields. You can do so in several \nways:\n- through ``/api/custom-fields`` CRUD controller endpoints if you wish to provide all the fields necessary\nfor defining a single custom field\n- through helper endpoints (where `plain_type` parameter is one of plain types defined in the DB. Using \ninvalid parameter will result in 404):\n    - ``/api/custom-field/plain/{plain_type}`` - for creating plain type custom-field.\n    - ``/api/custom-field/selection/{plain_type}`` - for creating selection type custom-field.\n    - ``/api/custom-field/remote`` - for creating remote type custom-field. \n    Omitting the `plain_type` attribute and hard-coding to string currently.\n- with Tinker in the console\n\nOnce a custom field is defined, you can add a value for a particular model against that custom field. \n\nI.e. if you have a ``Contact`` model, instead of adding a `car` attribute to `contacts` table, you can define\na string plain type custom field ``car`` for `Contact` model. At that point, no `Contact` has a value assigned to it.\nOnly when custom field is defined can you go and say that for example ``Contact`` with ID 5 has a Volvo.   \n\n## Custom field attributes\n\n- ``name`` - unique name of the custom field.\n- ``label`` - user-friendly name of a custom field.\n- ``placeholder`` - placeholder.\n- ``selectable`` - polymorphic attribute (`_type`, `_id`) which can assume [one of 3 available types](#custom-field-types-breakdown).\n- ``model`` - namespace of the model for which the custom field will be applicable.\n- ``required`` - is a custom field required. Default `false`.\n- ``validation_id`` - relation to [validation field](#validation).\n- ``group`` \u0026 `order` - nullable front-end friendly strings to provide grouping if needed. \n\n## Plain type attributes\n\nPlain types have only ``name`` defined. These map to `custom_field_values` table attributes so be sure \nto seed mandatory types.\n\nThis is done because of data validation on DB level as well as faster value searching. \n\nI.e. one of plain types is ``string``, and looking at `custom_field_values` migration you'll notice that\nthere is a ``string`` attribute as well.  \n\n## Selection type attributes\n\nSelection types have two tables: ``selection_types`` and `selection_values`.\n\nSelection types have defined ``plain_type_id`` which is a plain type that selection values should be mapped to.\nIt is not possible to have plain type values of mixed types. There is also a ``multiselect`` boolean which should\nindicate to front-end whether it is possible to select only one or multiple values from the list.\n\nValues table holds all values which should for a particular selection field be available to pick. There are \nstandard ``label`` and `value` fields for selections as well as `preselect` bool which should indicate to the front-end\nwhether the value should be preselected (kinda like placeholder for selection). \n\n## Remote type attributes\n\nRemote types have standard ``url, method, body, headers`` attributes to define an endpoint from where the \nfields should be fetched. \n\nYou can resolve the values on ``/api/custom-field/remote/{remote_type}/resolve`` endpoint.\n\nWhile resolving the values from an endpoint, there is also a possibility to provide ``mappings``. If set to `null` \nthe response will be returned as-is. Otherwise, there is a possibility to provide mappings \nin `localKey =\u003e remoteKey` which means that response will be remapped to JSON provided in the `mappings` field.\n\nI.e. \n```\nResponse:\n{\n    \"remote_user\": \"foo\"\n}\n\nMapping: \n{\n    \"user\": \"remote_user\"\n}\n\nResult:\n{\n    \"user\": \"foo\"\n}\n```\n\n# Using custom fields\n\nOnce you have custom fields defined, you can start assigning values to models. You can do so by hitting the \n``/api/custom-field/values`` endpoint. Be sure to provide the right value in the request (i.e. for string field\nprovide a `string` attribute in the payload) because otherwise the package will reject the value as invalid. \n\nDuring value storing, aside from value type check, you can also add [regex validation](#validation) to a custom \nfield which will be validated at that point as well.\n\n# Validation \n\nYou can provide regex validation for a custom field in a ``/pattern/`` or `pattern` format. You can assign\nit a ``name`` if needed for front-end purposes, as well as setting `generic` bool option which is also a front-end\nhelper designed to filter out most common used validations. You can set those to ``true`` and then return only \n``true`` ones in front-end dropdown.\n\n# Relationship\n\nProviding a parent-child M:M relationship on custom fields.\n\n# Form\n\nForm is a helper model for our specific [form.io](https://www.form.io/) use case.\n\nWhen creating a form, its definition will be parsed and will automatically relate\ncustom fields used on an M:M pivot table. Parsing works on [form.io](https://www.form.io/)\ndefinition only. \n\nIf you want to make your own parser, you can publish the config file and replace\n``Form`` model implementation with your form. Extend the parent model and override\n``relateCustomFieldsFromDefinition()`` function. \n\n# Extending the package\n\nPublishing the configuration will enable you to change package models as\nwell as controlling how migrations behave. If extending the model, make sure\nyou're extending the original model in your implementation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasseco-voice%2Flaravel-custom-fields","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasseco-voice%2Flaravel-custom-fields","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasseco-voice%2Flaravel-custom-fields/lists"}