Skip to content
Snippets Groups Projects
Commit e3ccf5f1 authored by colemanw's avatar colemanw
Browse files

Update lots of pages to reflect new php-based schema structure

parent 63dfb09c
No related branches found
No related tags found
1 merge request!1193Update lots of pages to reflect new php-based schema structure
Showing
with 150 additions and 239 deletions
......@@ -690,7 +690,7 @@ See also: [Pull Request](https://github.com/civicrm/civicrm-core/pull/4865)
- `CRM_Core_Transaction` has traditionally used a reference-counting mechanism to combine multiple pieces of business-logic into a single transaction. In 4.6, this remains the default behavior, but one can also use nested transactions (by passing `$nested=TRUE` to the constructor). Any work done in the nested transaction can be rolled back without affecting the overall transaction.
- Prior to 4.6, the idiom for managing transactions was to call `$tx = new CRM_Core_Transaction()` and rely on the destructor to cleanup the transaction (e.g. issue the COMMIT/ROLLBACK). Unfortunately, it can be cumbersome to correctly apply this idiom when handling exceptions generated by non-Civi classes. 4.6 introduces a safer notation: `CRM_Core_Transaction::create()->run(function($tx){});` which automatically rolls back in case of an exception.
For more details, see [Transaction Reference](../../framework/database/transactions.md).
For more details, see [Transaction Reference](../../framework/transactions.md).
### 4.5.3: AJAX, Regions, and Resources
......
......@@ -50,9 +50,9 @@ $result = civicrm_api3('Event', 'get', array(
## Identifying fields eligible for a join
It is possible to join an entity to any other entity if the
[xml schema](../../framework/database/schema-definition.md)
identifies a [foreign key](../../framework/database/schema-definition.md#table-foreignKey) or
a [pseudoconstant](../../framework/database/schema-definition.md#table-field-pseudoconstant). The [getfields](../v3/actions.md#getfields) action identifies
[schema](../../framework/entities/index.md)
identifies a [foreign key](../../framework/entities/schema-definition.md#table-foreignKey) or
a [pseudoconstant](../../framework/pseudoconstant.md). The [getfields](../v3/actions.md#getfields) action identifies
fields that are eligible for an API join.
!!! warning "Not supported for every entity"
......
......@@ -100,7 +100,7 @@ If you want your extension to store data in the database, then you will need to
1. Pick a name for your entity.
* In some places, CiviCRM expects a `CamelCaseName`, in others, a `snake_case_name`. Be absolutely consistent in your naming, because CiviCRM needs to translate between those two naming conventions.
* By convention, every entity is named with `CamelCaseName`, starting with a capital letter.
* Also consider that all entity names (including yours) should be unique across all core entities as well as all extension entities (for all installed extensions). Thus in many cases it's best to prefix your entity name with the short name of your extension.
......@@ -112,29 +112,14 @@ If you want your extension to store data in the database, then you will need to
civix generate:entity MyEntity
```
Make sure to use CamelCase here.
This creates a skeletal file for your XML schema, your BAO, and your API.
1. Edit the [XML schema definitions](../framework/database/schema-definition.md) that you just generated (in the `xml` folder). Define your desired fields.
1. Generate your [DAO](../framework/codebase.md#dao) and SQL files.
This creates a skeletal file for your `entityType.php`, and a corresponding APIv4.
!!! tip Api4 Actions
By default, the generated API will inherit from a base class which includes all CRUD and metadata actions.
Read more about [APIv4 architecture](../api/v4/architecture.md) for help writing custom APIv4 actions.
```bash
civix generate:entity-boilerplate
```
You can safely re-run this command after you make changes to your XML schema definition. But if your schema changes require database migrations for existing installations, then you'll need to write a migration manually in addition to re-generating your boilerplate.
1. Generate a database upgrader.
1. Edit the `entityType.php` to define all of your entity's *fields* and other *metadata*. See documentation on [CiviCRM Entities](../framework/entities/index.md) for details.
```bash
civix generate:upgrader
```
Even though you're not yet creating any upgrades for your extension, you need to do this step now so that CiviCRM will pick up `auto_install.sql` and `auto_uninstall.sql` later on.
1. Re-install your extension.
```bash
......@@ -142,9 +127,7 @@ If you want your extension to store data in the database, then you will need to
cv ext:enable myextension
```
Now your entity should be ready to use. Try it out with `cv api4 MyEntity.create` and `cv api4 MyEntity.get`. Then [add some tests](#generate-test).
By default when you generate an entity you will be generating an APIv4 entity. To generate an APIv3 (or both) interface you need to specify `--api-version 3,4` or just `--api-version 3`. To use an APIv3 interface with cv, use `cv api3 MyEntity.create` and `cv api3 MyEntity.get`.
This will automatically create the database table for your entity. Now your entity should be ready to use. Try it out with `cv api4 MyEntity.create` and `cv api4 MyEntity.get`. Then [add some tests](#generate-test).
**Test your knowledge**
......@@ -153,66 +136,9 @@ A little quiz to test your knowledge:
<iframe src="https://learn.civi.be/wp-admin/admin-ajax.php?action=h5p_embed&id=11" width="608" height="300" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
!!! note "Troubleshooting"
- Older versions of civix may not automatically add the mixin `entity-types-php@2.0` to your `info.xml` file. Ensure that line is present.
- In order to auto-install your sql tables, your `info.xml` file must also include an `<upgrader>` tag that points to an `AutomaticUpgrader` class. The latest version of `civix` will add this for you, using the following command:
If you've generated an entity within an extension that you created with `civix` v18.01.0 or earlier, then you'll need to add this hook to your `myextension.php` file (changing `myextension` to your extension's short name).
```php
/**
* Implements hook_civicrm_entityTypes().
*
* Declare entity types provided by this module.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes
*/
function myextension_civicrm_entityTypes(&$entityTypes) {
_myextension_civix_civicrm_entityTypes($entityTypes);
}
```
(Starting from `civix` v18.02.0, this hook is automatically added when you generate a new extension.)
### Add an API function {:#generate-api}
The [CiviCRM API](../api/index.md) provides a way to expose functions for use by other developers. API functions allow implementing AJAX interfaces (using the CRM.$().crmAPI() helper), and they can also be called via REST, PHP, Smarty, Drush CLI, and more. Each API requires a two-part name: an entity name (such as "Contact", "Event", or "MyEntity") and an action name (such as "create" or "myaction").
Unfortunately Civix can only create v3 apis at the moment. Generally v4 CRUD apis are more useful since they allow your entities to be accessed from search-kit and form-builder. [relevant issue & how to manually add](https://github.com/totten/civix/pull/201)
Get started by accessing the `civix` help:
```bash
civix help generate:api
```
!!! note
Action names must be lowercase. The javascript helpers `CRM.api()` and `CRM.api3()` force actions to be lowercase. This issue does not present itself in the API Explorer or when the api action is called via PHP, REST, or SMARTY.
!!! note
The API loader is very sensitive to case on some platforms. Be careful with capitalization, underscores and multiword action names. API calls can work in one context (Mac OSX filesystem, case-insensitive) and fail in another (Linux filesystem, case-sensitive).
You can make your API code with a command in this pattern:
```bash
civix generate:api NewEntity newaction
```
This creates one file:
- `api/v3/NewEntity/Newaction.php` provides the API function `civicrm_api3_new_entity_newaction()` and the specification function `_civicrm_api3_new_entity_newaction_spec()`. Note that the parameters and return values must be processed in a particular way (as demonstrated by the auto-generated file).
For use with CiviCRM 4.3 and later, you can also add the `--schedule` option (e.g., `--schedule Hourly`). This will create another file:
- `api/v3/NewEntity/Newaction.mgd.php` provides the scheduling record that will appear in the CiviCRM's job-manager.
When calling the API, follow these rules:
- Entity-names are UpperCamelCase
- Action-names are lowersmashedcase
- Other variations may work when you call them. Some docs/explorers may show these in cases which work. However, if you try to do the same in new code, you may get a headache.
For example: `cv api NewEntity.newaction` `civicrm_api3('NewEntity', 'newaction')`
!!! tip
Read more about [APIv4 architecture](../api/v4/architecture.md) for help writing custom APIv4 implementations.
### Add a database upgrader, installer and uninstaller {:#generate-upgrader}
......@@ -397,7 +323,8 @@ To include static resources such as stylesheets, Javascript files, or images pla
### Add a report {:#generate-report}
CiviReport enables developers to define new business reports using customizable SQL logic and form layouts. This command is available if you want to create a new report. It also provides an option, if another existing report is close to your needs, to easily copy and modify it.
!!! warning "CiviReport is Deprecated"
CiviReport is being phased out in favor of SearchKit.
You can often achieve what you want to achieve using SearchKit and you should only
generate CiviReports if you have determined SearchKit can't meet your use case.
......
# CiviCRM Database Information
CiviCRM has a complex Database structure which this chapter will examine in more depth. CiviCRM for various reasons has the Schema structure of its database written out in XML files store in `xml/templates/schema` These files are used to define all Core CiviCRM tables that are installed when CiviCRM is installed. CiviCRM maintains a number of tools and scripts such as `GenCode`, `bin/setup.sh`, `bin/regen.sh`, the purpose of these tools is to update any current database with the lastest information stored in the XML files, Re-create the installation .mysql files that live in `sql/civicrm*.mysql` which are not committed to the Git Repo but found in the downloadable package. Also They update the "DAO" Files which contain a reference of what files and what relationships are there in the database.
## Tools
More documentation on tools to interact with the CiviCRM Database still to come.
### bin/regen.sh
If you are making a change that requires changes to the core schema, then in addition to any steps described at [XML Schema definition](schema-definition.md) you may need to also update the sql/civicrm_generated.mysql file, which is used when installing CiviCRM with the option to include sample data, by running bin/regen.sh.
Alternatively, you can run regen.sh on your branch [directly on Github](https://github.com/civicrm/civicrm-core/blob/master/.github/workflows/regen.yml).
If the change doesn't touch on other parts of the data or schema and doesn't affect any generated foreign key ids for example, you might be able to get away with just editing the file directly, which will avoid having to commit a lot of otherwise unrelated changes because the data in the file is semi-randomly generated. But if it is more complex or affects other parts of the file you need to use bin/regen.sh to regenerate it.
#### Setup
If you are using buildkit or have used setup.sh you may already be set up for it and may not need to do these steps.
1. While you can run this on an existing install that has the latest master code, you may either want to set up a separate install or make a backup of your database since it will get wiped. **Note: if you have your CMS and CiviCRM in the same database the CMS will get wiped too**.
1. Copy bin/setup.conf.txt to bin/setup.conf
1. Edit bin/setup.conf as needed.
1. If using Drupal, you will need drush installed and in your PATH.
1. (Optional) If you don't have /path/to/civicrm/node_modules/karma/bin in your PATH, add it. It's optional because it will still work, but you'll avoid it trying to reinstall karma. It's not used here anyway.
#### Running
1. Log out of your install if you are logged in.
1. Run bin/regen.sh from within your /path/to/civicrm folder.
It's a little difficult to verify the results by comparing to the previous file because of the deliberate randomness in the data, but you can compare the overall structure. You can also log back in to your install and check it out.
## Useful coding structures
### Only full group by
When writing direct Database queries sometimes they can cause issues due to the sql mode `ONLY_FULL_GROUP_BY` which aims to ensure that all columns in the group by / order by are in the select query and aggregated properly. If a query is particularly problematic that SQL mode can be temporarily disabled by putting a call in to `CRM_Core_DAO::disableFullGroupByMode()` before the DB query function then `CRM_Core_DAO::reenableFullGroupByMode()` immediately after. It is recommended that the original query is fixed rather than deploying this workaround however the workaround maybe the only real solution.
# CiviCRM Entities
An "entity" in CiviCRM is a persistent object (typically a sql table), with the following properties:
- **A database table:** In most cases, there is a 1-to-1 relationship between entities and tables.
- **Or other storage medium:** Some entities are stored elsewhere, for example Afforms are stored as files.
- **Fields:** Typically the columns of the database table, although extra fields (e.g. a read-only calculated value) are supported by APIv4.
- **An API:** Most entities have a corresponding api for CRUD, metadata and other actions.
## Tools
- Boilerplate code for a new entityType can be generated with [`civix generate:entity`](../../extensions/civix.md#generate-entity).
- Most entities are exposed to the CiviCRM API and can be browsed with the [API Explorer](../../api/index.md#api-explorer)
- Some [Entity-Relationship Diagrams](../../api/ERDs/index.md) are available to help with better understanding the CiviCRM database design.
## Declaration
Every entity in CiviCRM is declared via either:
1. An `.entityType.php` file loaded via `entity-types-php` mixin (recommended for most entities).
2. Or [`hook_civicrm_entityTypes`](../../hooks/hook_civicrm_entityTypes.md) (advanced use, for dynamic or generated entities, e.g. [ECK](https://civicrm.org/extensions/entity-construction-kit)).
Note: at the lowest level, `hook_civicrm_entityTypes` is the *only* way for extensions to declare entities.
But the extension mixin `entity-types-php` typically handles this automatically; it finds and loads all
`.entityType.php` files and passes their contents to the hook.
If you have an advanced use-case and need to implement [`hook_civicrm_entityTypes`](../../hooks/hook_civicrm_entityTypes.md) yourself, the data you
pass to the hook will be an array in the same format as that of an `.entityType.php` file described below, keyed by the name of the entity, plus the extra key 'module` which must contain the full_name of your extension.
## Definition
The entityType definition array can contain the following keys:
*`*` Denotes a required value*
* **`'name*'`** (`string`) - unique entity name, capitalized CamelCase (e.g. `"SearchDisplay"`)
* **`'module*'`** (`string`) - name of extension declaring the entity (only required when using `hook_civicrm_entityTypes`, the mixin passes this automatically)
* **`'table'`** (`string|null`) - a SQL table name (e.g. `"civicrm_search_display"`) (required for all entities with a sql table)
* **`'class'`** (`string|null`) - a PHP DAO class (e.g.`"CRM_Search_DAO_SearchDisplay"`) - used for backward compatibility when converting existing entities from xml/dao to `entityType.php`
* **`'getInfo'`** (`callback():array`) - Function returning entity metadata such as:
* `title` (`ts(string)`)
* `title_plural` (`ts(string)`)
* `description` (`ts(string)`)
* `log` (`boolean`)
* `add` (`string`)
* `icon` (`string`)
* `label_field` (`string`)
* **`'getPaths'`** (`callback():array`) - Function returning an array of paths at which this entity can be created, viewed, updated & deleted
* **`'getIndices'`** (`callback():array`) - Function returning an array of sql indices.
* **`'getFields'`** (`callback():array`) - Function returning an array of field definitions, keyed by field name, with possible values:
* `title` (`ts(string)`)
* `description` (`ts(string)`)
* `sql_type` (`string`)
* `input_type` (`string`)
* `data_type` (`string`)
* `required` (`boolean`)
* `localizable` (`boolean`)
* `serialize` (`int`)
* `default` (`mixed`)
* `usage` (`array`)
* `input_attrs` (`array`)
* `pseudoconstant` (`array`)
* `permission` (`array`)
* *`'fields_callback'` (deprecated)* (`array[function($class, &$fields)]`) list of callbacks to modify legacy `DAO::fields`
* *`'links_callback'` (deprecated)*: (`array[function($class, &$links)]` list of callbacks to modify legacy `DAO::getReferenceColumns`
# Database schema definition in XML
# Legacy schema definition in XML
!!! warning "Archived Legacy Information"
Prior to CiviCRM v5.74, entities (aka database tables) were defined using xml to generate php DAO files.
As of 5.75, they are now defined in `entityType.php` files. This page is for archival purposes.
## Migration from XML
Although CiviCRM no longer uses xml-generated DAO files, it will continue to support older extensions that do so.
A migration path has been added to civix to auto-convert xml schema files to the new format. See
https://github.com/totten/civix/wiki/Entity-Templates
## Archived Page
*The following is an archive of the schema xml documentation. The information is not current:*
<hr>
The database structure for core (as well as any schema defined for extensions) is defined in a series of XML files
([example](https://github.com/civicrm/civicrm-core/blob/master/xml/schema/SMS/History.xml)).
......
......@@ -24,6 +24,6 @@ When we look at CiviCRM Tables there are a few patterns that generally hold true
- Every table has a id column which is Auto Increment and therefore unique key for that table
- Columns which reference other tables generally speaking will be named in the format of `other table name` + `_id`. For example in `civicrm_country` there is `address_format_id` which indicates that is references `civicrm_address_format.id`
- Many-to-many relationships use "join tables" as intermediary tables. For example, a contact can have many activity records, and an activity can have many contact records. So the table `civicrm_activity_contact` is used as the glue because it has foreign keys to both.
- In some places CiviCRM defines schema using a construct called [PseudoConstants](schema-definition.md#table-field-pseudoconstant) which produces some slightly more complex logic
- In some places CiviCRM defines schema using a construct called [Pseudoconstants](../pseudoconstant.md) which produces some slightly more complex logic
- Lots of columns reference `civicrm_option_values` when they just need a simple (and user-configurable) list of options. For example, look at `civicrm_contribution` which has a column called `payment_instrument_id`. You'll notice there's no table called `civicrm_payment_instrument`. So in this case the `payment_instrument_id` column actually references the value column in `civicrm_option_values` (but only for records in `civicrm_option_values` with the appropriate `option_group_id`.) Here there is no foreign key, so referential integrity is managed at the application layer, not the database layer.
- Some tables use "dynamic foreign keys". For example, look at `civicrm_note` which has columns `entity_id` and `entity_table`. This is because a note can be attached to different entities (e.g. contact, contribution, etc). So two columns are used to indicate what the note references. Here again, the application layer is responsible for ensuring referential integrity, so you won't find any foreign keys.
......@@ -95,27 +95,27 @@ return [
The Supported Properties for settings are:
| property | Usage | Example Notes |
| --- | --- | --- |
| `name` | Name of this setting| This is the same as the array key. Required |
| `type` | Data type| String, Integer, Boolean (Array is discouraged as current uses of it do not have full handling and String + a serialize key addresses most uses) |
| `title` | Title (admin form)| note: use ts() or E::ts() for extensions|
| `description` | Description (admin form)| note: use ts() or E::ts() for extensions|
| `serialize`|define how an array of values are stored|ie CRM_Core_DAO::SERIALIZE_JSON is recommended. Other constants exist on the CRM_Core_DAO class|
| `default` | Default value| Value to use if setting is not set. |
| `add` | Version added to CiviCRM| |
| `html_type` | Html type (admin form)| This is the preferred way to describe the html type as it is not quick form specific. It will be used it present. Syntax is lower case. e.g 'select', 'radio', 'checkboxes', 'checkbox', 'text', 'textarea', 'entity_reference|
| `pseudoconstant`|Provides information to build a list of available options| This is the preferred methodology for lists of options and currently supports either a callback - e.g ```['callback' => 'CRM_Core_SelectValues::geoProvider']``` or an option group name [`'optionGroupName' => 'advanced_search_options'`]. The ```advanced_search_options``` would be changed to the name of your Option Group. When specifying an `optionGroupName` you can optionally specify `keyColumn` to return a column from `civicrm_option_value` to use as the key. By default the `keyColumn` is the `value` column. As of CiviCRM 5.25 arbitrary tables are also supported. The format is the same as that used for [DAO](../database/schema-definition.md#table-field-pseudoconstant)|
| `options`|provides an array of available options|This is not the preferred methodology but make make sense for very simple lists. |
| `entity_reference_options`|extra data to pass when adding an entity reference|e.g if the entity is not contact this make be needed as in `['entity' => 'group', 'select' => ['minimumInputLength' => 0]]`|
| `documentation_link`|Array of information to build the 'learn more' link| 'page' is required, if on the wiki 'resource' is also needed - e.g 'documentation_link' => ['page' => 'Multi Site Installation', 'resource' => 'wiki'],|
| `help_text` | Intended to populated. Popup Help (admin form)| note: use ts(), not working as intended as of 5.8 |
| `html_attributes` | | size, style, class, etc. |
| `validate_callback` | A string, the name of a callback function to validate the setting value. | The callback is fired whether the setting is updated via admin form or API. The callback should accept the proposed setting value as its only argument. It should return TRUE if the value is valid, otherwise FALSE. In the latter case the API request will fail (`is_error` will be set to 1 in the result). If the callback takes the value by reference, it can modify the setting value before it is saved -- it remains to be seen whether this is wise. Example: 'CRM_Utils_Rule::url' |
| `on_change` | Callback function when this setting is altered e.g when you enable a component or logging| |
| `is_domain` | Domain setting| Setting is_domain to 1 indicates that the setting applies to the entire installation (in single site mode) or to a single domain in multi-site mode. If is_domain is set to 1, then is_contact must be set to 0. |
| `is_contact` | Contact setting| Setting is_contact to 1 indicates that the setting applies to a single contact and can be different for each contact. If is_contact is set to 1, is_domain must be set to 0. |
| `settings_pages`|Metadata for presentation on settings pages|The key (or keys) are the last part of the url on the page the setting should be displayed on. Adding a weight provides sorting|
| property | Usage | Example Notes |
| --- | --- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name` | Name of this setting| This is the same as the array key. Required |
| `type` | Data type| String, Integer, Boolean (Array is discouraged as current uses of it do not have full handling and String + a serialize key addresses most uses) |
| `title` | Title (admin form)| note: use ts() or E::ts() for extensions |
| `description` | Description (admin form)| note: use ts() or E::ts() for extensions |
| `serialize`|define how an array of values are stored| ie CRM_Core_DAO::SERIALIZE_JSON is recommended. Other constants exist on the CRM_Core_DAO class |
| `default` | Default value| Value to use if setting is not set. |
| `add` | Version added to CiviCRM| |
| `html_type` | Html type (admin form)| This is the preferred way to describe the html type as it is not quick form specific. It will be used it present. Syntax is lower case. e.g 'select', 'radio', 'checkboxes', 'checkbox', 'text', 'textarea', 'entity_reference |
| `pseudoconstant`|Provides information to build a list of available options| This is the preferred methodology for lists of options and currently supports either a callback - e.g ```['callback' => 'CRM_Core_SelectValues::geoProvider']``` or an option group name [`'optionGroupName' => 'advanced_search_options'`]. The ```advanced_search_options``` would be changed to the name of your Option Group. When specifying an `optionGroupName` you can optionally specify `keyColumn` to return a column from `civicrm_option_value` to use as the key. By default the `keyColumn` is the `value` column. As of CiviCRM 5.25 arbitrary tables are also supported. The format is the same as that used for [field pseudoconstants](../pseudoconstant.md) |
| `options`|provides an array of available options| This is not the preferred methodology but make make sense for very simple lists. |
| `entity_reference_options`|extra data to pass when adding an entity reference| e.g if the entity is not contact this make be needed as in `['entity' => 'group', 'select' => ['minimumInputLength' => 0]]` |
| `documentation_link`|Array of information to build the 'learn more' link| 'page' is required, if on the wiki 'resource' is also needed - e.g 'documentation_link' => ['page' => 'Multi Site Installation', 'resource' => 'wiki'], |
| `help_text` | Intended to populated. Popup Help (admin form)| note: use ts(), not working as intended as of 5.8 |
| `html_attributes` | | size, style, class, etc. |
| `validate_callback` | A string, the name of a callback function to validate the setting value. | The callback is fired whether the setting is updated via admin form or API. The callback should accept the proposed setting value as its only argument. It should return TRUE if the value is valid, otherwise FALSE. In the latter case the API request will fail (`is_error` will be set to 1 in the result). If the callback takes the value by reference, it can modify the setting value before it is saved -- it remains to be seen whether this is wise. Example: 'CRM_Utils_Rule::url' |
| `on_change` | Callback function when this setting is altered e.g when you enable a component or logging| |
| `is_domain` | Domain setting| Setting is_domain to 1 indicates that the setting applies to the entire installation (in single site mode) or to a single domain in multi-site mode. If is_domain is set to 1, then is_contact must be set to 0. |
| `is_contact` | Contact setting| Setting is_contact to 1 indicates that the setting applies to a single contact and can be different for each contact. If is_contact is set to 1, is_domain must be set to 0. |
| `settings_pages`|Metadata for presentation on settings pages| The key (or keys) are the last part of the url on the page the setting should be displayed on. Adding a weight provides sorting |
### Deprecated Properties
......
......@@ -2,7 +2,11 @@
## Summary
This hook is used to declare a new type of entity, for example a booking extension might want to declare a *Resource* entity.
Lowest-level hook for modifying the list of system entities.
!!! warning "Advanced Use Only"
Most extensions need not implement this hook directly, as entities can be defined via `.entityType.php` files in conjunction with the `entity-types-php` mixin,
which will automatically read those files and pass their contents to this hook.
## Notes
......@@ -24,68 +28,15 @@ hook_civicrm_entityTypes(&$entityTypes)
## Parameters
* `$entityTypes` is a two-dimensional associative array. Each element in the array has:
* A **key** which is the entity name as a string (e.g. `'Report'` or `'CRM_Report_DAO_Instance'`), although this has not always been enforced.
* A **value** which is an associative with the following elements:
* `'name'`: *string, required* - a unique short name (e.g. `"ReportInstance"`)
* `'class'`: *string, required* - a PHP DAO class (e.g.`"CRM_Report_DAO_Instance"`)
* **`$entityTypes`** (`array[]`) Each item is an entity definition (array). They are keyed by the canonical name of the entity (e.g. `Activity`, `Contact`, `Participant`).
**Note:** Older versions of CiviCRM used the DAO classname as key (e.g. `'CRM_Activity_DAO_Activity'`).
* `'table'`: *string, required* - a SQL table name (e.g. `"civicrm_report_instance"`)
* `'fields_callback'`: *array, optional* - a list of callback functions which can modify the DAO field metadata. `function($class, &$fields)` Added circa 4.7.11+
* `'items_callback'`: *array, optional* - a list of callback functions which can modify the DAO foreign-key metadata. `function($class, &$links)` Added circa 4.7.11+
Each entity definition array must contain at least the keys:
- **`'name'`** `(string)` - Canonical name of entity (same as array key of the item).
- **`'module'`** `(string)` - Full name of extension declaring the entity.
For all possible values in the entity definition array, see the section on [CiviCRM Entities](../framework/entities/index.md).
## Returns
* null
## Examples
### Add new entities
This example is taken from CiviVolunteer [here](https://github.com/civicrm/org.civicrm.volunteer/blob/eafc2b0c3966a492a3080ac70abe06cbd960a00e/volunteer.php#L333).
```php
/**
* Implements hook_civicrm_entityTypes().
*/
function volunteer_civicrm_entityTypes(&$entityTypes) {
$entityTypes[] = array(
'name' => 'VolunteerNeed',
'class' => 'CRM_Volunteer_DAO_Need',
'table' => 'civicrm_volunteer_need',
);
$entityTypes[] = array(
'name' => 'VolunteerProject',
'class' => 'CRM_Volunteer_DAO_Project',
'table' => 'civicrm_volunteer_project',
);
$entityTypes[] = array(
'name' => 'VolunteerProjectContact',
'class' => 'CRM_Volunteer_DAO_ProjectContact',
'table' => 'civicrm_volunteer_project_contact',
);
}
```
### Alter metadata for existing entities
This functionality was added in (approximately) v4.7.11.
```php
/**
* Implements hook_civicrm_entityTypes().
*/
function apilogging_civicrm_entityTypes(&$entityTypes) {
$entityTypes['Contact']['fields_callback'][]
= function ($class, &$fields) {
unset($fields['created_date']['export']);
};
}
```
* void
......@@ -159,7 +159,7 @@ If that api call is run outside of a transaction, then the hooks are called:
This is presumably because Contact.create uses a transaction internally.
If that api call is run inside an explicit [transaction](../framework/database/transactions.md) then the following order is observed:
If that api call is run inside an explicit [transaction](../framework/transactions.md) then the following order is observed:
- post create email
- post create individual
......
......@@ -27,8 +27,8 @@ to implement callbacks for one or both of these events:
(e.g. the [`ActivityLinksProvider`](https://github.com/civicrm/civicrm-core/blob/master/Civi/Api4/Service/Links/ActivityLinksProvider.php)
uses this to contextually alter links based on input values.
!!! tip "More on the XML schema"
You can see where links are initially defined for entities in [XML Schema defintion](../framework/database/schema-definition.md)
!!! tip "More on the schema"
You can see where links are initially defined for entities in [Schema defintion](../framework/entities/index.md)
Search Kit treats anything within brackets like a token and replaces the value,
......
# Database standards
The following standards apply to the database layer in CiviCRM:
1. Every BAO will have a create function. This will be called by the API & form layer.
1. The create function will take a single params array.
1. Depending on the parameters passed in, the create function will perform any additional actions like creating activities.
1. The create function will call hooks.
1. We are moving away from the `$ids` array being included.
1. The add function (if it exists) will be internal to the BAO layer.
1. If any additional actions are to be done when deleting the BAO there should be a function `del` which takes the entity id as the only required parameter.
1. The delete action will take any additional tasks like deleting additional objects (generally done by code).
1. The delete action will take an array including `['id']`.
1. The api will call the `del` action & fall back onto delete. It is recommended that the form layer call the API.
# Entity standards
The following standards apply to entities in CiviCRM:
1. Declare entities via an `.entityType.php` file
2.
\ No newline at end of file
......@@ -51,7 +51,7 @@ Open `xml/schema/CRM/Myentity/MyEntity.xml` and change it to your needs. This fi
* Contact ID
* Title
See [Schema Definition](../../framework/database/schema-definition/) for an explanation of the XML file.
See [Schema Definition](../../framework/entities/schema-definition/) for an explanation of the XML file.
Our `xml/schema/CRM/Myentity/MyEntity.xml` will initially look like this, however you can delete unwanted fields (e.g. `contact_id`) and add others:
......@@ -1133,7 +1133,7 @@ Open the APIv4 file and add a `permissions()` function, following this [example
## See also
* [Civix](../../extensions/civix/)
* [Schema Definition](../../framework/database/schema-definition/) for an explanation of the XML file
* [Schema Definition](../../framework/entities/schema-definition/) for an explanation of the XML file
* [hook_civicrm_tabset](../../hooks/hook_civicrm_tabset/) for adding a new tab on the contact summary screen.
* [hook_civicrm_permission](../../hooks/hook_civicrm_permission)
* [The example extension](https://lab.civicrm.org/jaapjansma/myentity)
......
......@@ -43,7 +43,7 @@ While there are many cities where street names can officially be in multiple lan
Similarly, the first and last name of an individual may be written in different alphabets (ex: Latin and Cyrillic), but this is not a frequent use-case worth the complexity. Administrators can workaround this by creating custom fields.
In order to define a field as localizable, the [XML schema definition](../framework/database/schema-definition.md) for that field must have the following tag:
In order to define a field as localizable, the [schema definition](../framework/entities/index.md) for that field must have the following tag:
```
<localizable>true</localizable>
......@@ -143,7 +143,7 @@ VALUES (
Two use-cases:
1. An existing field in CiviCRM was not tagged in the [XML schema](../framework/database/schema-definition.md) as `<localizable>` (ex: the `title` in `civicrm_survey`, before CiviCRM 4.5). After adding the `<localize>` tag in the XML file, you must also add an upgrade snippet for existing databases. Example, from `sql/4.1.0.mysql.tpl`:
1. An existing field in CiviCRM was not tagged in the [schema](../framework/entities/index.md) as `'localizable' => TRUE` (ex: the `title` in `civicrm_survey`, before CiviCRM 4.5). After adding the `<localize>` tag in the XML file, you must also add an upgrade snippet for existing databases. Example, from `sql/4.1.0.mysql.tpl`:
```smarty
{if $multilingual}
......
......@@ -357,11 +357,11 @@ nav:
- CiviReport: framework/civireport.md
- Codebase: framework/codebase.md
- Cryptography Reference: framework/crypto.md
- Database:
- Overview: framework/database/index.md
- XML Schema definition: framework/database/schema-definition.md
- Schema Design: framework/database/schema-design.md
- Transaction Reference: framework/database/transactions.md
- Entities:
- CiviCRM Entities: framework/entities/index.md
- Schema Design: framework/entities/schema-design.md
- Migrating from Legacy XML: framework/entities/schema-definition.md
- Database Transaction Reference: framework/transactions.md
- Formatting: framework/formatting.md
- File System: framework/filesystem.md
- Import: framework/import.md
......@@ -410,7 +410,7 @@ nav:
- Coding Standards: standards/index.md
- PHP Standards: standards/php.md
- Javascript Standards: standards/javascript.md
- Database Standards: standards/database.md
- Entity Standards: standards/entity.md
- Review Standards: standards/review.md
- Review Template (DEL): standards/review/template-del-1.0.md
- Review Template (MC): standards/review/template-mc-1.0.md
......
......@@ -7,7 +7,7 @@ api/general api
hooks/hook_civicrm_trigger_info hooks/hook_civicrm_triggerInfo
testing/setup testing
testing/javascript testing/karma
framework/schema-definition framework/database/schema-definition
framework/schema-definition framework/entities/schema-definition
api/params api/v3/options
api/usage api/v3/usage
api/actions api/v3/actions
......
......@@ -173,7 +173,7 @@ Smart+group+testing testing/manual/#smart-group
Tarball+installation+testing testing/manual/#tarball
Contributing+to+CiviCRM+using+GitHub tools/git/#github
Git+Commit+Messages+for+CiviCRM tools/git/#committing
Transaction+Reference framework/database/transactions
Transaction+Reference framework/entities/transactions
Backbone+Reference framework/backbone
Extensions+and+Permissions security/permissions#extensions
Customize+Built-in+Profile+Contribution+and+Event+Registration+Screens framework/templates/customizing
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment