{"id":19110184,"url":"https://github.com/locomotivemtl/charcoal-property","last_synced_at":"2026-02-14T00:45:36.118Z","repository":{"id":3541986,"uuid":"50054990","full_name":"locomotivemtl/charcoal-property","owner":"locomotivemtl","description":"Properties define model metadata.","archived":false,"fork":false,"pushed_at":"2023-09-28T21:37:38.000Z","size":9770,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-10-03T12:54:46.810Z","etag":null,"topics":["charcoal","json","metadata","model","php","properties"],"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/locomotivemtl.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":"2016-01-20T19:34:45.000Z","updated_at":"2021-11-02T19:27:48.000Z","dependencies_parsed_at":"2024-11-09T04:24:58.685Z","dependency_job_id":"2dc70b8f-77da-4f6a-923c-010423515979","html_url":"https://github.com/locomotivemtl/charcoal-property","commit_stats":{"total_commits":393,"total_committers":12,"mean_commits":32.75,"dds":0.6081424936386768,"last_synced_commit":"8f3403145b55c43190e447dae1c8f4dea249cc33"},"previous_names":[],"tags_count":69,"template":false,"template_full_name":null,"purl":"pkg:github/locomotivemtl/charcoal-property","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-property","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-property/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-property/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-property/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/locomotivemtl","download_url":"https://codeload.github.com/locomotivemtl/charcoal-property/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-property/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29427047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T22:20:51.549Z","status":"ssl_error","status_checked_at":"2026-02-13T22:20:49.838Z","response_time":78,"last_error":"SSL_read: 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":["charcoal","json","metadata","model","php","properties"],"created_at":"2024-11-09T04:24:01.192Z","updated_at":"2026-02-14T00:45:36.099Z","avatar_url":"https://github.com/locomotivemtl.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Charcoal Property\n=================\n\nProperties define object's metadata. They provide the building blocks of the Model's definition.\n\nProperties are defined globally for objects (_charcoal models_) in its `metadata`. They provide properties definition, storage definition and validation definition.\n\n\u003e The `metadata()` method is defined in `\\Charcoal\\Model\\DescribableInterface`.\n\u003e The `properties()` method is defined in `\\Charcoal\\Property\\DescribablePropertyInterface`.\n\n# How to install\n\nThe preferred (and only suppported) way of installing _charcoal-property_ is with **composer**:\n\n```shell\n★ composer require locomotivemtl/charcoal-property\n```\n\nFor a complete, ready-to-use project, start from the [`boilerplate`](https://github.com/locomotivemtl/charcoal-project-boilerplate):\n\n```shell\n★ composer create-project locomotivemtl/charcoal-project-boilerplate:@dev --prefer-source\n```\n\n## Dependencies\n\n-   [`PHP 5.6+`](http:///php.net)\n    -   PHP 7 is recommended for security \u0026 performance reasons.\n-   [`psr/log`](http://www.php-fig.org/psr/psr-3/)\n    -   A PSR-3 compliant logger should be provided to the various services / classes.\n-   [`locomotivemtl/charcoal-config`](https://github.com/locomotivemtl/charcoal-config)\n    -   Properties configuration and metadata.\n-   [`locomotivemtl/charcoal-core`](https://github.com/locomotivemtl/charcoal-core)\n    -   Also required for validator, model and more.\n-   [`locomotivemtl/charcoal-factory`](https://github.com/locomotivemtl/charcoal-fatory)\n    -   Dynamic object creation is provided with charcoal factories.\n-   [`locomotivemtl/charcoal-image`](https://github.com/locomotivemtl/charcoal-image)\n    -   For image manipulation.\n-   [`locomotivemtl/charcoal-translator`](https://github.com/locomotivemtl/charcoal-translator)\n    -   For localization.\n\n# Property options\n\nThe basic property interface (API) requires / provides the following members:\n\n| Name           | (V) | Type                | Description\n| -------------- | :-: | ------------------- | -----------\n| **ident**      |     | _string_            | The property idenfifier (typically, its containing object matching property name).\n| **label**      |     | _Translation_       | ...\n| **l10n**       |     | _bool_              | If true, then the data should be stored in a l10n-aware structure (be translatable).s\n| **hidden**     |     | _bool_              |\n| **multiple**   |     | _bool_              | Multiple values can be held and stored, if true.\n| **required**   |  ✓  | _bool_              |\n| **unique**     |  ✓  | _bool_              |\n| **storable**   |     | _bool_              |\n| **active**     |     | _bool_              |\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n\u003e All those methods can be accessed either via the `setData()` method or with a standard PSR-1/PSR-2 getter / setter. (`foo` would have `foo()` as a getter and `setFoo()` as a setter).\n\n### Data retrieval\n\n- To get a normalized value, use the `parseVal($val)` method.\n- To get a string-safe, displaybale value, use `displayVal($val)`.\n- To get the storage-ready format, use `storageVal($val)`.\n\n\u003e Custom data retrieval methods can be further defined in each properties. (For example, formatted date or custom color formats).\n\n## Default validation\n\nValidation is provided with a `Validator` object, from charcoal-core.\n\n-   `required`\n-   `unique`\n-   `allow_null`\n\n\u003e Validation is being rebuilt in a new `charcoal-validator` package.\n\n## Source and storage methods\n\nProperties need 4 method to integrate with a SQL source:\n\n-   `sqlEncoding()` _string_ The SQL column encoding \u0026 collation (ex: `utf8mb4`)\n-   `sqlExtra()` _string_ Raw SQL string that will be appended to\n-   `sqlType()` _string_ The SQL column type (ex: `VARCHAR(16)`)\n-   `sqlPdoType()` _integer_ The PDO column type (ex: `PDO::PARAM_STR`)\n\n\u003e  Those methods are _abstract_ and therefore must be implemented in actual properties.\n\n# Types of properties\n\n-   [Boolean](#boolean-property)\n-   [Color](#color-property)\n-   ~~Date~~\n    -   [DateTime](#datetime-property)\n    -   ~~Day~~\n    -   ~~Month~~\n    -   ~~Time~~\n    -   ~~Year~~\n-   [File](#file-property)\n    -   [Audio](#file-audio-property)\n    -   [Image](#image-property)\n    -   ~~Video~~\n-   [Lang](#lang-property)\n-   [Number](#number-property)\n    -   ~~Float~~\n    -   ~~Integer~~\n-   [Object](#object-property)\n-   [Id](#id-property)\n-   [IP](#ip-property)\n-   [String](#string-property)\n    -   [Html](#html-string-property)\n    -   [Password](#password-string-property)\n    -   [Phone](#phone-string-property)\n    -   [Text](#text-string-propery)\n-   ~~Structure~~\n    -   [MapStructure](#map-structure-property)\n    -   [ModelStructure](#model-structure-property)\n\nRetrieve\n\n## Boolean Property\n\nThe boolean property is one of the simplest possible: it simply holds boolean (`true` / `false`) values.\n\n### Boolean Property options\n\nThe boolean property adds the following concepts to the [basic property options](#basic-property-options):\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **false_label** |  -  | _Translation_       | Label, for \"true\" value.\n| **true_label**  |  -  | _Translation_       | Label, for \"false\" value.\n\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n\u003e ⚠ Boolean properties can not be multiple. (`multiple()` will always return false). Calling `setMultiple(true)` on a `boolean` property will throw an exception.\n\n## Color Property\n\nThe color property stores a color. If alpha is not supported, it is stored as an hexadecimal value (ex: `#5590BA`). If alpha is supported, it is stored as a rgba() string value (ex: `rgb(85, 144, 186, 0.5)`).\n\n### Color Property options\n\nThe boolean property adds the following concepts to the [basic property options](#basic-property-options):\n\n| Name               | (V) | Type                | Description\n| ------------------ | :-: | ------------------- | -----------\n| **support_alpha**  |  ✓  | _boolean_           | ...\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n\n## DateTime Property\n\nThe datetime property store a date (and time) value.\n\n### DateTime Property options\n\nThe datetime property adds the following concepts to the [basic property options](#basic-property-options):\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **min**         |  ✓  | _DateTime_          | Minimum date value. If 0, empty or null, then there is no minimal constraint.\n| **max**         |  ✓  | _DateTime_          | Maximum date value. If 0, empty or null, then there is no maximal constraint.\n| **format**      |     | _string_            | The date format is a string (in PHP's DateTime `format()`) that manages how to format the date value for display. Defaults to \\\"Y-m-d H:i:s\\\".\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n\u003e ⚠ DateTime properties can not be multiple. (`multiple()` will always return false). Calling `setMultiple(true)` on a `date-time` property will throw an exception.\n\n## ID Property\n\nThe ID property holds an ID, typically the main object identifier (unique index key).\n\nThe ID value can be generated by many **mode**:\n\n-   `auto-increment` is the default mode. It uses the storage engine (_mysql_) auto-increment feature to keep an auto-incrementing integer index.\n-   `uniqid` creates a 13-char string with PHP's `uniqid()` function.\n-   `uuid` creates a 36-char string (a _RFC-4122 v4_ Universally-Unique Identifier, `uuidv4`).\n\n### ID Property options\n\nThe ID property adds the following concepts to the [basic property options](#basic-property-options):\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **mode**        |     | _string_            | The ID generation mode. Can be `auto-increment`, `uniqid` or `uuid`. |\n\n\u003e ⚠ Id properties can not be multiple. (`multiple()` will always return false). Calling `setMultiple(true)` on an `id` property will throw an exception.\n\n### ID Property custom save\n\nUpon `save($val)`, the ID property auto-generates and ID if its mode is `uniqid` or `uuid`.\n\n\u003e Note: The `auto-increment` mode does not do anything on save; it relies on the storage engine / driver to implement auto-incrementation.\n\n## IP Property\n\nThe IP property holds an IP address. Only _IPv4_ addresses are supported for now.\n\nThere is 2 different storage modes for IP:\n\n-   `string` is the default mode. It stores the IP address like `192.168.1.1`.\n-   `int` stores the IP as a _signed long integer_.\n\n\u003e ⚠ Ip properties can not be multiple. (`multiple()` will always return false). Calling `setMultiple(true)` on an `ip` property will throw an exception.\n\n## File Property\n\nFile property holds an uploadable file.\n\n### Values\n\nNote that only a _relative_\u003csup\u003e1\u003c/sup\u003e file path should be stored in the database.\n\n\u003csup\u003e1\u003c/sup\u003e Relative to project's `ROOT` + the property's `upload_path`.\n\n### File Property options\n\nThe file property adds the following concepts to the [basic property options](#basic-property-options):\n\n| Name                  | (V) | Type        | Description\n| --------------------- | :-: | ----------- | -----------\n| **public_access**     |     | _bool_      | If the public access is true (default) then the file will be stored in a public filesystem. If not, then it will be stored in a private (non-web-accessible) filesystem.\n| **upload_path**       |     | _string_    | The default upload path, relative to `base_url`, where the uploaded files will be stored.\n| **overwrite**         |     | _bool_      | If true, when a target file already exists on the filesystem  it will be overwritten. If false, a new unique name will be generated (with a suffix).\n| **accepted_mimeypes** |  ✓  | _string[]_  | List of accepted mimetypes. Leave empty to accept all types (no mimetype constraint).\n| **max_filesize**      |  ✓  | _integer_   | Maximum allowed file size, in bytes. If 0, null or empty, then there are no size constraint.\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n### Additional file methods\n\n-   `mimetype()` and `setMimetype()`\n-   `filesize()` and `setFilesize()`\n-   `dataUpload()`\n-   `fileUpload()`\n\n### File Property Custom Save\n\nUpon `save($val)`, the File property attempts to upload the file or create a file from data, if necessary. The uploaded file's path (_relative_) is returned.\n\n### Specialized File properties\n\n-   [`AudioProperty`](#audio-file-property)\n-   [`ImageProperty`](#image-file-property)\n-   ~~VideoProperty~~\n\n## Audio File Property\n\nAudio property are specialized [file property](#file-property) thay may only contain audio data.\n\n### Accepted mimetypes\n\nThe `AudioProperty` extends `FileProperty` therefore provides \"accepted mimetypes\".\n\nDefault accepted mimetypes are:\n\n-   `audio/mp3`\n-   `audio/mpeg`\n-   `audio/wav`\n-   `audio/x-wav`.\n\n### Audio file Property options\n\nThe audio property adds the following concepts to the [file property options](#file-property-options):\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **min_length**  |  ✓  | _DateTime_          | Minimum audio length, in seconds. If 0, null or empty, then there is no minimal constraint.\n| **max_length**  |  ✓  | _DateTime_          | Maximum audio length, in seconds. If 0, null or empty, then there is no maximal constraint.\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n## Image File Property\n\nImage property are specialized [file property](#file-property) thay may only contain image data.\n\n### Accepted mimetypes\n\nThe `ImageProperty` extends `FileProperty` therefore provides \"accepted mimetypes\".\n\nDefault accepted mimetypes are:\n\n-   `image/gif`\n-   `image/jpg`\n-   `image/jpeg`\n-   `image/pjpeg`\n-   `image/png`\n-   `image/svg+xml`\n-   `image/webp`\n\n### Image file Property options\n\nThe audio property adds the following concepts to the [file property options](#file-property-options):\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **effects**     |  ✓  | _array_             | Array of `charcoal-image` effects options.\n\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n\n## Lang Property\n\nLanguage properties hold a language value.\n\n\u003e The `LangProperty` implements the `SelectablePropertyInterface`, but hardcode its `choices()` method to return the active language (from `[charcoal-translator](https://github.com/locomotivemtl/charcoal-translator)`).\n\n## Number Property\n\nNumber properties hold any kind of numeric data.\n\n## Object Property\n\nObject properties hold a reference to an external object of a certain type.\n\n### Values\n\nThe target's `identifer` (determined by its _obj-type_'s `key`, which is typically \"id\") is the only thing held in the value / stored in the database. When displayed (with `displayVal()`), a string representation of the object should be rendered.\n\n### Object Property options\n\nThe object property adds the following concepts to the [basic property options](#basic-property-options):\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **obj-type**    |  ✓  | _string_            | The target object's type. In a string format that can be fetched with a `ModelFactory`. |\n| **pattern**     |     | _string_            | The rendering pattern, used to display the object(s) when necessary.\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n## String Property\n\n### String Property options\n\nThe string property adds the following concepts to the basic property options:\n\n| Name            | (V) | Type                | Description\n| --------------- | :-: | ------------------- | -----------\n| **max_length**  |  ✓  | _integer_           | Maximum allowed length, in (_multibytes_) characters. |\n| **min_length**  |  ✓  | _integer_           | Minimum allowed length, in (_multibytes_) characters. |\n| **regexp**      |  ✓  | _string_            | A validation regular expression that must be matched exactly. |\n| **allow_empty** |  ✓  | _bool_              | If empty strings are allowed.\n\u003csmall\u003e(V) indicates options used in validation\u003c/small\u003e\n\n### String default data\n\nBy default, the `string` property is targetted at small string (a maximum length) of `255` characters\n\n### Specialized String properties\n\n-   [`HtmlProperty`](#html-string-property)\n-   [`PasswordProperty`](#password-string-property)\n-   [`PhoneProperty`](#phone-string-property)\n-   [`TextProperty`](#text-string-property)\n\n## Html String Property\n\nHTML properties are specialized [string property](#string-property) that may only contain HTML strings (instead of plain string).\n\n## Password String Property\n\nPassword properties are specialized [string property](#string-property) that holds (encrypted) password data.\n\nEncryption is performed with PHP's `password_hash` function.\n\n### Password Property Custom Save\n\nUpon `save($val)`, the Password property hashes (or rehashes) the password to be stored safely (encrypted).\n\n## Phone String Property\n\nPhone properties are specialized [string property](#string-property) that holds a phone number.\n\nRight now, only \"north-american\" phone number styles are supported.\n\n## Text String Property\n\nText properties are specialized [string property](#string-property) thay typically holds longer text strings.\n\n## Map Structure Property\n\nMap structure properties hold complex map structure data, which can be points (markers), lines and / or polygons.\n\n## Properties table summary, for developers\n\n| Name         | Data type | Multiple | Custom Save | Custom Parse |\n| ------------ | :-------: | :------: | :---------: | :----------: |\n| Audio        | mixed     |          |             |              |\n| Boolean      | bool      | **No**   |             |              |\n| Color        | string    |          |             | **Yes**      |\n| DateTime     | DateTime  | **No**   |             | **Yes**      |\n| File         | mixed     |          | **Yes**     |              |\n| Html         | string    |          |             |              |\n| Id           | mixed     | **No**   | **Yes**     |              |\n| Image        | mixed     |          |             |              |\n| Ip           | mixed     | **No**   |             |              |\n| Lang         | string    |          |             |              |\n| MapStructure | mixed     |          |             |              |\n| Number       | numeric   |          |             |              |\n| Object       | mixed     |          |             | **Yes**      |\n| Password     | string    |          | **Yes**     |              |\n| Phone        | string    |          |             |              |\n| String       | string    |          |             |              |\n| Structure    | mixed     |          |             | **Yes**      |\n| Text         | string    |          |             |              |\n| Url          | string    |          |             |              |\n\n# Development\n\nTo install the development environment:\n\n```shell\n★ composer install --prefer-source\n```\n\nRun the code checkers and unit tests with:\n\n```shell\n★ composer test\n```\n\n## API documentation\n\n-   The auto-generated `phpDocumentor` API documentation is available at [https://locomotivemtl.github.io/charcoal-property/docs/master/](https://locomotivemtl.github.io/charcoal-property/docs/master/)\n-   The auto-generated `apigen` API documentation is available at [https://locomotivemtl.github.io/charcoal-property/apigen/master/](https://locomotivemtl.github.io/charcoal-property/apigen/master/)\n\n## Development dependencies\n\n-   `phpunit/phpunit`\n-   `squizlabs/php_codesniffer`\n-   `satooshi/php-coveralls`\n\n## Continuous Integration\n\n| Service | Badge | Description |\n| ------- | ----- | ----------- |\n| [Travis](https://travis-ci.org/locomotivemtl/charcoal-property) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-property.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-property) | Runs code sniff check and unit tests. Auto-generates API documentaation. |\n| [Scrutinizer](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-property/) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-property/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-property/?branch=master) | Code quality checker. Also validates API documentation quality. |\n| [Coveralls](https://coveralls.io/github/locomotivemtl/charcoal-property) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-property/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-property?branch=master) | Unit Tests code coverage. |\n| [Sensiolabs](https://insight.sensiolabs.com/projects/f3bdff38-c300-4207-8342-da002e64a6e1) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/f3bdff38-c300-4207-8342-da002e64a6e1/mini.png)](https://insight.sensiolabs.com/projects/f3bdff38-c300-4207-8342-da002e64a6e1) | Another code quality checker, focused on PHP. |\n\n## Coding Style\n\nThe Charcoal-Property module follows the Charcoal coding-style:\n\n-   [_PSR-1_](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)\n-   [_PSR-2_](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)\n-   [_PSR-4_](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), autoloading is therefore provided by _Composer_.\n-   [_phpDocumentor_](http://phpdoc.org/) comments.\n-   Read the [phpcs.xml](phpcs.xml) file for all the details on code style.\n\n\u003e Coding style validation / enforcement can be performed with `composer phpcs`. An auto-fixer is also available with `composer phpcbf`.\n\n## Authors\n\n-   Mathieu Ducharme \u003cmat@locomotive.ca\u003e\n-   Chauncey McAskill \u003cchauncey@locomotive.ca\u003e\n-   Benjamin Roch \u003cbenjamin@locomotive.ca\u003e\n-   Dominic Lord \u003cdom@locomotive.ca\u003e\n-   Joel Alphonso \u003cjoel@locomotive.ca\u003e\n\n# License\n\nCharcoal is licensed under the MIT license. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocomotivemtl%2Fcharcoal-property","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocomotivemtl%2Fcharcoal-property","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocomotivemtl%2Fcharcoal-property/lists"}