Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • documentation/docs/dev
  • totten/dev
  • bgm/dev
  • ivan_compucorp/dev
  • seamuslee/dev
  • artfulrobot/dev
  • ufundo/dev
  • wmortada/dev
  • lucky091588/dev
  • DaveD/dev
  • jtwyman/dev
  • rukkykofi/dev
  • JonGold/dev
  • jaapjansma/developer-docs
  • alainb/dev
  • noah/dev
  • justinfreeman/dev
  • pradeep/dev
  • larssg/dev
  • eileen/dev
  • darrick/dev
  • mattwire/dev
  • colemanw/dev
  • homotechsual/dev
  • JoeMurray/dev
  • maynardsmith/dev
  • kurund/dev
  • rocxa/dev
  • AllenShaw/dev
  • bradleyt/dev
  • chrisgaraffa/dev
  • martin.w/dev
  • herbdool/dev
  • MattTrim1/dev
  • Detlev/dev
  • ErikHommel/dev
  • brienne/devdocs
  • pminf/dev
  • SarahFG/dev
  • ayduns/dev
  • JKingsnorth/dev
  • ginkgomzd/dev
  • nicol/dev
  • almeidam/dev
  • arthurm/dev
  • damilare/dev
  • semseysandor/dev
  • major/devdocs
  • usha.makoa/dev
  • yurg/dev
  • shaneonabike/dev
  • andie/dev
  • mmyriam/dev
  • gngn/dev
  • florian-dieckmann/dev
  • jade/dev
  • luke.stewart/dev
  • vinaygawade/dev
58 results
Show changes
Commits on Source (1495)
Showing
with 757 additions and 231 deletions
name: Mark stale issues and pull requests
on:
schedule:
- cron: "0 * * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has had no activity in 60 days and has been marked as stale, it will not be closed.'
stale-pr-message: 'This pull request has had no activity in 60 days and has been marked as stale, it will not be closed.'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
days-before-stale: 60
days-before-close: -1
exempt-issue-labels: 'awaiting-approval,work-in-progress'
exempt-pr-labels: 'awaiting-approval,work-in-progress'
remove-stale-when-updated: 'True'
site
\ No newline at end of file
site
.idea
*~
# CiviCRM Developer Guide
* **Issues have moved to https://lab.civicrm.org/documentation/docs/dev/-/issues**
* **Submit new merge/pull requests at https://lab.civicrm.org/documentation/docs/dev**
A documentation guide for people who develop with/for [CiviCRM](https://civicrm.org).
- [Read published version](http://docs.civicrm.org/dev/en/master)
......
......@@ -19,7 +19,9 @@ HEADER = """# All hooks
-->
This is an overview list of all available hooks, listed by category.
This is an overview list of all available hooks and the event listeners that
are supported for use outside of core. Any event listeners not listed here
are not supported for use outside of core & could change without notice
"""
def findBetween( s, first, last ):
......@@ -38,8 +40,8 @@ def getSummary(hookFile):
output = f = open(OUTPUT_FILE, 'w')
with open(MKDOCS_YAML_FILE, 'r') as f:
doc = yaml.load(f)
pages = doc["pages"]
doc = yaml.load(f, Loader=yaml.FullLoader)
pages = doc["nav"]
for section in pages:
if "Hooks" in section:
hookSection = section.get("Hooks")
......@@ -51,8 +53,8 @@ for section in hookSection:
category, hookList = section.popitem()
if isinstance(hookList, list):
for hookDetails in hookList:
hookName = hookDetails.iterkeys().next()
if re.match("^(<del>)?hook_civicrm_*", hookName):
hookName = list(hookDetails)[0]
if re.match("^(<del>)?hook_civicrm_*", hookName) or re.match("^civi", hookName):
categoryHooks.append(hookDetails)
if len(categoryHooks) > 0:
......@@ -60,4 +62,5 @@ for section in hookSection:
for hookDetails in categoryHooks:
hookName, hookFile = hookDetails.popitem()
summary = getSummary(hookFile)
output.write('* **[{}](/{})** - {}\n'.format(hookName, hookFile, summary))
hookNameForLink = hookFile.replace('hooks/', '')
output.write('* **[{}]({})** - {}\n'.format(hookName, hookNameForLink, summary))
## FormBuilder Behaviors
### Overview
Simply put, a **Behavior** extends the functionality of an **entity**.
Behaviors are PHP classes written by a developer, which can be enabled in the GUI to affect how entities behave on a form.
Each Behavior class declares some configuration metadata which automatically appears in the Afform GUI. The user can
make selections to enable and configure the behavior.
To enact its functionality, a behavior class can listen to any Civi hook or event, notably `civi.afform.prefill` and `civi.afform.submit`.
These events are called for every entity on a form, and will include information such as the entity name, type, and any
behaviors that have been configured for that entity.
### Examples
A good example to emulate is the [Contact Dedupe Behavior](https://github.com/civicrm/civicrm-core/blob/master/ext/afform/core/Civi/Afform/Behavior/ContactDedupe.php).
```php
class ContactDedupe extends AbstractBehavior implements EventSubscriberInterface {
```
It starts off by extending the `AbstractBehavior` class, which makes it discoverable to Afform,
and also implementing `EventSubscriberInterface`, which is the recommended way to subscribe to events. That interface
requires a `getSubscribedEvents` function:
```php
/**
* @return array
*/
public static function getSubscribedEvents() {
return [
'civi.afform.submit' => ['onAfformSubmit', 101],
];
}
```
That registers the callback function named `onAfformSubmit` in the same class, to be called every time an Afform entity
is about to be saved.
The next 4 functions are part of the `AfformBehavior` interface, and provide enough information for the AfformAdmin GUI
to show the behavior to the user for configuration:
```php
public static function getEntities():array {
return \CRM_Contact_BAO_ContactType::basicTypes();
}
public static function getTitle():string {
return E::ts('Duplicate Matching');
}
public static function getDescription():string {
return E::ts('Update existing contact instead of creating a new one based on a dedupe rule.');
}
public static function getModes(string $entityName):array {
...
}
```
Note that `getEntities` does not simply return "Contact" because Afform considers "Individual", "Household" and "Organization"
to all be their own entities.
The `getModes` function returns an array of operation modes (in this case dedupe rules) for a particular entity type.
So if your Behavior can act on more than one entity type as this one can, pay attention to the `$entityName` parameter
and only return modes relevant to that type of entity (in this case, there are different dedupe rules for "Individual" vs
"Organization", etc).
Finally, the callback registered with `getSubscribedEvents`:
```php
public static function onAfformSubmit(AfformSubmitEvent $event) {
$entity = $event->getEntity();
$dedupeMode = $entity['contact-dedupe'] ?? NULL;
if ($event->getEntityType() !== 'Contact' || !$dedupeMode) {
return;
}
// Apply dedupe rule if contact isn't already identified
foreach ($event->records as $index => $record) {
$supportedJoins = ['Address', 'Email', 'Phone', 'IM'];
$values = $record['fields'] ?? [];
foreach ($supportedJoins as $joinEntity) {
if (!empty($record['joins'][$joinEntity][0])) {
$values += \CRM_Utils_Array::prefixKeys($record['joins'][$joinEntity][0], strtolower($joinEntity) . '_primary.');
}
}
$match = Contact::getDuplicates(FALSE)
->setValues($values)
->setDedupeRule($dedupeMode)
->execute()->first();
if (!empty($match['id'])) {
$event->setEntityId($index, $match['id']);
}
}
}
```
This function checks the `contact-dedupe` mode set by the Admin (this is a kebab-case version of the class name)
and takes action on every record being saved for that entity (normally one entity saves one record, but because of the
AfRepeat feature, entities should always be treated as if they may be multivalued).
# Afform Core
The core of the Afform extension is an AngularJS module factory. Traditionally, to [add a new AngularJS module
in CiviCRM](../framework/angular/quickstart.md), one must create an `.ang.php` file, a js module file, some
controllers, components & templates, plus a page route to bootstrap AngularJS and load the module.
Afform Core does all that for you, all you need is a template `.aff.html` file and an optional configuration `.aff.json` file.
## Creating a Form in an Extension
As an extension author, you can define a form along with its default, canonical content.
Simply create a file `ang/MYFORM.aff.html`. In this example, we create a form named `helloWorld`:
1. Make sure you're in the directory with your extension (`cd /path/to/extension`)
2. Make an `ang` directory in your extension. (`mkdir ang`)
3. Add some HTML/JS code to your `aff.html` file. `echo '<div>Hello {{routeParams.name}}</div>' > ang/helloWorld.aff.html`
4. Add some JSON config to your `aff.json` file. `echo '{"server_route": "civicrm/hello-world"}' > ang/helloWorld.aff.json`
5. Flush the caches so CiviCRM picks up the new form. `cv flush`
A few things to note:
* The `ang` folder is the typical location for AngularJS modules in CiviCRM extensions.
* We defined a route `civicrm/hello-world`. This appears in the same routing system used by CiviCRM forms. It also supports properties such as `title` (page title) and `is_public` (defaults to `false`).
* After creating a new form or file, we should flush the cache.
* If you're going to actively edit/revise the content of the file, then you should navigate to **Administer > System Settings > Debugging** and disable asset caching.
* The extension `*.aff.html` represents an AngularJS HTML document. It has access to all the general features of Angular HTML (discussed more later).
* In AngularJS, there is a distinction between a "module" (unit-of-code to be shared; usually appears as `camelCase`) and a "directive" (a custom HTML element; may appear as `camelCase` or as `kebab-case` depending on context). Afform supports a tactical simplification in which one `*.aff.html` corresponds to one eponymous module and one eponymous directive.
Now that we've created a form, we'll want to determine its URL. As with most CiviCRM forms, the URL depends on the CMS configuration. Here is an example from a local Drupal 7 site:
We can use `cv` to get full URLs for any `civicrm/*` URL like so:
* `cv url "civicrm/hello-world"` returns `http://dmaster.localhost/civicrm/hello-world`
* `cv url "civicrm/hello-world/#/?name=world"` returns `http://dmaster.localhost/civicrm/hello-world/#/?name=world`
Open the URLs and see what you get.
## Form Overrides
Afform files inside an extension (aka a _"Packaged"_ form), are considered the default state, or _"base"_.
If you fetch your form via API (e.g. the APIv4 Explorer), `civicrm_api4('Afform', 'get')` will return something like this:
```
[
{
name: "helloWorld" // this corresponds to file name minus .aff.html extensions
server_route: "civicrm/hello-world" // as defined in helloWorld.aff.json
has_base: true,
has_local: false,
...
},
...
]
```
The calculated field `'has_base'` is **`true`** because the Afform files are packaged in an extension.
`'has_local'` is **`false`** for now. However, site builders can modify your form without touching your extensnion code
simply by making a copy of the form in their local files directory. In that case the form would be considered _overridden_
and Afform would automatically use the local copy in favor of the one on your extension and the same api call would return
data from the new files with `has_local: true`.
## Form Builder Events
### `civi.afform_admin.metadata`
*Alter metadata for the Form Builder GUI*
**Since:** CiviCRM 5.50
**Type:** `GenericHookEvent`
**Params:**
- **`entities`** (array) List of entities that can be used in the Form Builder GUI. Each item has array keys:
- `name` (string)
- `label` (string)
- `icon` (string:"fa-*")
- `type` (string:"primary"|"secondary")
- `defaults` (string:js object).
- **`elements`** (array) Static elements that can be added to a form, keyed by name. Each item has array keys:
- `title` (string) Title shown in Editor
- `afform_type` (array) Form types this element is used for
- `element` (array) Default markup for this element
- `directive` (string) Specify directive name in dash format (should match `['element']['#tag']`)
- `admin_tpl` (string) Editor template. Extensions can provide their own template for editing this element type,
by adding an Angular module with base page `'civicrm/admin/afform'`.
- **`inputTypes`** (array) Form widgets used to represent a field.
- **`styles`** (array) Bootstrap3 style strings.
- **`permissions`** (array) Permissions that can be set for an Afform.
- **`dateRanges`** (array) Date range options.
### `civi.afform.prefill`
*Prefill entity data when the form is being viewed.*
**Since:** CiviCRM 5.56
**Type:** `AfformPrefillEvent`
**Methods:**
- **getAfform()**: `array`
- **getFormDataModel()**: `Civi\Afform\FormDataModel`
- **getApiRequest()**: `Civi\Api4\Action\Afform\Prefill`
- **getEntityType()**: `string`
- **getEntityName()**: `string`
- **getSecureApi4()**: `callable`
- **setEntityId(int $index, int $id)**
- **setJoinIds(int $index, string $joinEntity, array $joinIds)**
### `civi.afform.validate`
*Validate submission of an Afform.*
**Since:** CiviCRM 5.56
**Type:** `AfformValidateEvent`
**Methods:**
- **getAfform()**: `array`
- **getFormDataModel()**: `Civi\Afform\FormDataModel`
- **getApiRequest()**: `Civi\Api4\Action\Afform\Submit`
- **getEntityValues()**: `array`
- **setError(string $errorMsg)**
### `civi.afform.submit`
*Handle submission of an `<af-form>` entity (or set of entities in the case of `<af-repeat>`).*
**Since:** CiviCRM 5.31
**Type:** `AfformSubmitEvent`
**Methods:**
- **getAfform()**: `array`
- **getFormDataModel()**: `Civi\Afform\FormDataModel`
- **getApiRequest()**: `Civi\Api4\Action\Afform\Submit`
- **getEntityType()**: `string`
- **getEntityName()**: `string`
- **getRecords()**: `array`
- **getSecureApi4()**: `callable`
- **setEntityId(int $index, int $id)**
- **setRecords(array $records)**
- **setJoinIds(int $index, string $joinEntity, array $joinIds)**
Form Builder provides a flexible form interface allowing editing a variety of CiviCRM entities as well as a developer interface.
## Exposing an entity to Form Builder
### Via event listener
The Form Builder GUI can be extended via the [`civi.afform_admin.metadata`](afform-events.md) event.
This event is used for adding entities, elements, input types, etc.
### Via an Afform entityType declaration file
It is also possible to expose entities in Form Builder by adding a declaration. To do this:
1. Add the [mixin](../framework/mixin/index.md) `<mixin>afform-entity-php@1.0.0</mixin>` to your extension's `info.xml` file (note: for backward compatability with versions < 5.50 you must [add a shim](https://github.com/eileenmcnaughton/deduper/pull/26).
2. Ensure the entity in question has apiv4 CRUD entities (these get generated automatically if using [civix with an extension](https://docs.civicrm.org/dev/en/latest/step-by-step/create-entity/#4-generate-sql-dao-and-bao-files))
3. Create a php file in the following location - `afformEntities/EntityName.php` as you can see [here in the `deduper` extension](https://github.com/eileenmcnaughton/deduper/blob/master/afformEntities/ContactNamePair.php). For more complex examples [see core](https://github.com/civicrm/civicrm-core/tree/master/ext/afform/admin/afformEntities).
```php
<?php
use CRM_MyExtension_ExtensionUtil as E;
return [
'type' => 'primary',
'defaults' => "{}",
'boilerplate' => [
['#tag' => 'af-field', 'name' => 'name'],
['#tag' => 'af-field', 'name' => 'xxx'],
],
];
```
4. The boilerplate specifies the fields that are automatically added to a new Submission Form. In the example above, the fields 'name' and 'xxx' would be added.
5. An entity can be available for "Submission forms" and/or for "Field blocks". In order for the entity to be available for Submission forms, add `'type' => 'primary'` [example](https://github.com/civicrm/civicrm-core/blob/master/ext/afform/admin/afformEntities/Individual.php) or only as Field blocks, leave blank or add `'type' => 'join'` [example](https://github.com/civicrm/civicrm-core/blob/master/ext/afform/admin/afformEntities/Address.php). A Field block (or join) is only available in relation to a primary entity.
[Core afform entities](https://github.com/civicrm/civicrm-core/tree/master/ext/afform/admin/afformEntities) have examples of other parameters that can be added such as `repeat_max`, `unique_fields`, `boilerplate`, `icon`, `alterFields`, and `data` defaults. Be sure to test them out to see what works best with a custom entity.
!!! tip "Making fields available for use in Form Builder"
If an expected element for an Entity is missing from Form Builder, it's likely that `input_type` needs to be added to the field. See [Entities](../../framework/entities) for possible values.
Find the `getFields` function in the corresponding `.entityType.php` file for that Entity and add an appropriate input type.
(for older entities using legacy xml schema files, the corresponding tag would be `<html><type>` and the code generator script would need to be run after updating).
## Introduction
Form-Builder (aka `afform`) is a core extension currently in active development.
It is intended to become the main building tool for CiviCRM forms and layouts going forwards.
## Embedding
Afforms can be embedded on any CiviCRM page as Angular directives; they also can be configured to
automatically appear on the dashboard or contact summary screen. Afforms can be embedded into
other Afforms simply by including the directive for one Afform in the markup of another; Angular
dependencies will be resolved automatically.
### Embedding in Smarty Templates
*Adding Afforms to traditional Smarty-based pages or forms can be a transitional step away from legacy screens*
**PHP Code**
```php
Civi::service('angularjs.loader')
->addModules('afformMyForm');
$this->assign('myAfformVars', $optionalVars);
```
Note - to figure out what to put in 'name' look at the name in the FormBuilder listing for your form. In the above example the 'name' would be the entire 'afformMyForm' (there isn't a magic prefix).
**Template Code**
```
<crm-angular-js modules="afformMyForm">
<form id="bootstrap-theme">
<afform-my-form options='{$myAfformVars|@json_encode}'></afform-my-form>
</form>
</crm-angular-js>
```
## Afform Types
- **form**: A form which submits through the `Afform::submit` api, editable in the form-builder GUI.
- **block**: A snippet meant to be incorporated into a larger form.
- **system** (default): Non-editable forms.
- **search**: An afform with an embedded [SearchKit Display](../searchkit/displays.md) and optional search filter fields.
## Afform markup
Althought angularjs offers extensive functionality it is recommended that, where possible, CiviCRM Angular forms are written using just html and CiviCRM afform markup. The reason being that there is demand to be able to render these forms using different front end libraries (eg. React) and funding is being sought to that end. If this does proceed then the first piece of work is likely to be rendering existing FormBuilder forms via React - something that would work seamlessly if no native
angularjs markup is used.
The CiviCRM Afform markup includes
| Type | Example |Notes |
| ------ | ------ | ------ |
| form embedding markup | `<contact-basic></contact-basic>` |Embed a FormBuilder form as defined in `contactBasic.aff.html` & `contactBasic.aff.js`|
| api 3 access markup | ``` <div af-api3="af-api3="['Contact','getsingle', {id: options.contact_id}]" af-api3-ctrl="contact"> </div> ``` |Call api v3 & assign results to variable `contact`|
| api 4 access markup | ```<div af-api4="['Afform', 'get', {select: ['name','title','is_public','server_route', 'has_local', 'has_base'], orderBy: {name:'ASC'}}]" af-api4-ctrl="listCtrl"></div>``` |Call api v4 & assign results to variable `listCtrl`|
A [SearchKit Display](../searchkit/displays.md) can be embedded in an Afform.
This switches the form fields from "create" to "get" mode so they can work as search filters.
Search Displays embedded in an Afform will use the permissions of the form to determine
whether they may be viewed; if a user has access to the Afform then SearchKit will grant
permission to view the Display as well.
\ No newline at end of file
# Entity Relationship Diagrams
Entity Relationship Diagrams provide a different view into how the entities accessed through the API are related to each other.
Most of the entities in APIv4 and APIv3 are mapped directly to tables in the CiviCRM database. A few are not, notably the Order API and the Payment API.
Collected below are a number of Entity-Relationship Diagrams. The diagrams were generated by [DBeaver](https://dbeaver.io/), with notes added manually. Each foreign key relationship that is defined in the database between two tables is represented by a line connecting the tables. A table can also have a relationship with itself, for example, a parent_id field linking to a different record in the same table.
The lines do not indicate the specific fields joined by the relationship unfortunately. The solid circle at the end of a relationship line touches the table that has a foreign key referencing another table. So the solid dot indicates the 'beginning' of the relationship, and is touching the 'source' table. When the foreign key field in the souce table is defined as NOT NULL, then the other end of the relationship line will go straight into the destination table. However, if foreign key field in the source table is optional, then there is a rectangle on the end touching the destination table.
CiviCRM has a field naming convention that helps in determining which field is a foreign key to a different table. A table named civicrm_tablename1 has a field named id as its unique primary key. References from other tables to that id field are named tablename1_id. (There are a few exceptions, such as when two fields in one table reference the key of a single other table, for different purposes.)
CiviCRM has non-standard patterns that it uses to implement one table references one amongst several other tables. We term this a pseudo foreign key. In most cases there is a pair of fields, entity_table and entity_id, with entity_table containing the name of the table being referenced and entity_id representing the value of id of the record in that field being referenced. A different pattern is present in the civicrm_value_* tables that are dynamically created to store custom fields that extend various entities in CiviCRM. In that case, entity_id present in the table, and the entity_table value is found in the appropriate civicrm_custom_group.extends field.
To aid in viewing and understanding the 200+ tables in CiviCRM, each diagram collects a handful of related tables.
For convenience, here is a clickable list of the Entity-Relationship Diagrams below:
- [ACLs](#acls)
- [Activities](#activities)
- [Batches and Queues](#batches-and-queues)
- [Cases](#cases)
- [Contact Info](#contact-info)
- [Contribution Financial](#contribution-financial)
- [Contribution Page](#contribution-financial)
- [Contributions recur](#contributions-recur)
- [Custom Fields](#custom-fields)
- [Deduping](#deduping)
- [External Providers](#external-providers)
- [Groups, Tags and Campaigns](#groups-tags-and-campaigns)
- [Interfaces](#interfaces)
- [Line Items](#line-items)
- [Mailings](#mailings)
- [Participants](#participants)
- [Pledges](#pledges)
- [Price fields and Premiums](#price-fields-and-premiums)
- [Relationships](#relationships)
- [System](#system)
## ACLs
ACLs are Access Control Lists that define permissions that a user has to view data of different sorts.
![ACLs](../../img/ERDs/ACLs.png)
## Activities
![Activities](../../img/ERDs/Activities.png)
The purpose of an Activity is specific to the activity_type. There can be custom fieldset defined for Activities, including for specific types.
## Batches and Queues
![Batches and Queues](../../img/ERDs/Batches_and_Queues.png)
The queue and queue_item tables are general purpose, and helpful when long-running processes need to have a backlog of tasks. The batch table was originally created to support financial batches, both those created by navigating to Contributions > Batch Data Entry, and ones created manually at Contributions > Accounting Batches > New Batch.
## Cases
![Cases](../../img/ERDs/Cases.png)
These are the primary tables used by CiviCase, though it also makes extensive use of Activities.
## Contact Info
![Contact Info](../../img/ERDs/Contact_Info.png)
This diagram illustrates the various tables containing contact information. These tables are more normalized than some schemas in data sources that contain multiple fields for the same type of content, for example, email1 and email2 or phone1 and phone2.
## Contribution Financial
![Contribution Financial](../../img/ERDs/Contribution_Financial.png)
This diagram includes tables related to accounting information for contributions, memberships and event registrations. Double entry bookkeeping is represented by debit and credit accounts in civicrm_financial_trxn and civicrm_financial_item for most entries, and occasionally for some simple transactions by the from and to account fields in civicrm_financial_trxn. These are the authoritative entries for auditing purposes. The amount fields in civicrm_contribution and civicrm_line_item are often more convenient for some reporting purposes. However, the civicrm_contribution.financial_type_id table is a deprecated field since it cannot accurately represent transactions with multiple line items with different financial types.
## Contribution Page
![Contribution Page](../../img/ERDs/Contribution_Page.png)
This diagram includes tables that store the settings defined when useing Contributions > Manage Contribution Page, and under Contributions > Manage Price Sets.
## Contributions recur
![Contributions recur](../../img/ERDs/Contributions_recur.png)
Recurring contributions, and memberships that are paid with them, are illustrated here.
## Custom Fields
![Custom Fields](../../img/ERDs/Custom_Fields.png)
CiviCRM databases typically have many sets of custom fields defined, and many tables named civicrm_value_*.
## Deduping
![Deduping](../../img/ERDs/Deduping.png)
The dedupe_rule_group has one record per rule in the user interface at Contacts > Find and Merge Duplicate Contacts. The dedupe_rule table has one row per 'field' entry for a particular rule.
## External Providers
![External Providers](../../img/ERDs/External_Providers.png)
These tables are used to store information used to connect to some standard external services.
## Groups, Tags and Campaigns
![Groups, Tags and Campaigns](../../img/ERDs/Groups__Tags_and_Campaigns.png)
Groups, Tags and Campaigns help to segment and relate entities in CiviCRM.
## Interfaces
![Interfaces](../../img/ERDs/Interfaces.png)
These tables define some menu and navigation elements in CiviCRM and permissions for users to see them.
## Line Items
![Line Items](../../img/ERDs/Line_Items.png)
There may be one or more line items related to a contribution, and each may relate to a membership, event registration or a different purpose.
## Mailings
![Mailings](../../img/ERDs/Mailings.png)
CiviMail is a powerful bulk emailing solution. Some of the tables in this diagram relate to the content of the emails, others are used during sending, and the remainder contain information on recipients interactions with those emails.
## Participants and Events
![Participants](../../img/ERDs/Participants.png)
Participants register in events. The registrations are stored in the same tables regardless of whether the event is paid or free.
## Pledges
![Pledges](../../img/ERDs/Pledges.png)
Pledges are prototypically used during capital campaigns to store promises to donate a certain amount over a period of time through payments to be specified later. When payments are made against the pledge, it reduces the amount owing.
## Price fields and Premiums
![Price fields](../../img/ERDs/Price_fields.png)
Price fields are part of the configuration of what people can buy or donate to through a CiviCRM site. Price_field_values are the options for certain types of price_fields; other price field types like a text entry field for an amount do not require price_field_values.
Premiums are used by fundraisers to incentivize people to donate more, with products representing things like mugs or Tshirts that are given away for donating over a certain level.
## Relationships
![Relationships](../../img/ERDs/Relationships.png)
Relationships can be created between contacts. Relationship types can be used to limit which contacts can be involved in a relationship (eg only organizations can be employers and only individuals can be employees). Relationships can be used to define permissions, for example, parents can be allowed to see and edit their children's information.
## System
![System](../../img/ERDs/System.png)
This diagram includes some of the more important system tables.
# The CiviCRM API
CiviCRM has a stable, comprehensive **API** (Application Programming Interface) that can be used to access and manage data in CiviCRM. The API is the recommended way for any CiviCRM extension, CMS module or external program to interact with CiviCRM.
CiviCRM has a stable, comprehensive **API** (Application Programming Interface) for accessing and managing data.
The API is the recommended way for any extension or external program to interact with CiviCRM.
CiviCRM also uses its own API to power all new UIs and bundled extensions.
Utilizing the API is superior to accessing core functions directly (e.g.calling raw SQL, or calling functions within the BAO files) because the API offers a consistent interface to CiviCRM's features. It is designed to function predictably with every new release so as to preserve backwards compatibility of the API for several versions of CiviCRM. If you decide to use other ways to collect data (like your own SQL statements), you risk running into future problems when changes to the schema and BAO arguments inevitably occur.
Extensions can provide additional API entities or functionality. For help creating your own additions to the API, see [API Architecture](v4/architecture.md).
The best place to begin working with the API is your own *test* install of CiviCRM, using the API explorer and the API parameter list.
!!! tip "Why Use the API"
The API is superior to executing raw SQL or calling internal CiviCRM functions, because it offers consistency and stability.
It is designed to function predictably with every new release so as to preserve backwards compatibility when changes to the schema and BAO functions inevitably occur.
Using the API also ensures all hooks and events are dispatched, allowing CiviCRM business logic and 3rd party integrations to function properly.
Extensions can provide additional API functionality. For help creating your own additions to the API, see [civix generate:api](/extensions/civix.md#generate-api).
## API Versions
CiviCRM's API has major versions (APIv2, APIv3, APIv4) which are independent of the CiviCRM version. The API version is incremented more slowly in order to maintain stability within the extension ecosystem. Typically, two versions of the API are maintained concurrently (currently v3 and v4) to allow gradual transitions. New releases of CiviCRM may add features to the API but will not break backward-compatibility within an API version.
The best place to begin working with the API is your own *test* install of CiviCRM, using the API Explorer.
## API Explorer
The API explorer is a powerful GUI tool for building and executing API calls. To access it:
This is the go-to tool for both new and experienced developers. It gives detailed, interactive documentation on each entity, including the
available actions and their parameters, and will write API code for you. To access it:
1. Log in to a CiviCRM site as an administrator.
* This can even be the [demo site](http://dmaster.demo.civicrm.org/).
2. Within the CivCRM menu, go to **Support > Developer** and either **API Explorer v3** or **API Explorer v4** (URL `/civicrm/api` or `/civicrm/api4`).
2. Within the CivCRM menu, go to **Support > Developer** and either **API Explorer v4** (URL `/civicrm/api4`) or the legacy **API Explorer v3** (URL `/civicrm/api3`).
!!! warning
The API explorer actually executes real API calls. It can modify data! So if you execute a `Contact` `delete` call, it will really delete the contact. As such, any experimenting is best done within a test site.
The API Explorer executes real API calls. It can modify data! So if you execute a `Contact` `delete` call, it will really delete the contact.
As such, any experimenting is best done within a test site.
You can select the entity you want to use, for example `Contact` and the action you want to perform, for example `Get`. The API explorer will show you the specific code necessary to execute the API call you have been testing using the various API interfaces available.
To get started, select an entity, for example `Contact` and an action to perform, for example `Get`.
Use the GUI to select additional parameters to configure your API call; as you do, the API Explorer will generate code
which you can copy & paste into your PHP, Javascript, REST or CLI application.
## API parameter documentation
## API Versions
From the API explorer, you can get documentation on how to construct your API query. This is done either in the screen as you fill out the GUI to create your API call or in the v3 Explorer there are docs under the Code Docs tab which will point at the relevant aspects of the v3 code base that run the API calls.
CiviCRM's API has major versions which are independent of the CiviCRM version. The API version increments more slowly in order to maintain stability within the extension ecosystem.
Typically, two versions of the API are maintained concurrently to allow gradual transitions. New releases of CiviCRM may add features to the API but will not break backward-compatibility within an API version.
## API Examples (APIv3 Only)
- [**APIv4**](v4/usage.md) is the current stable version, with new features being actively developed.
- [**APIv3**](v3/usage.md) is minimally maintained with no new features and regression bug-fixes only.
Within the API Explorer you will be able to attain an example of the code that you should write to call the API. In APIv3, you can also access specific examples of some API calls from the Examples tab within the explorer. You can also [explore these examples on GitHub](https://github.com/civicrm/civicrm-core/tree/master/api/v3/examples).
Your code can use a combination of v3 and v4 API calls, but v4 is recommended for all new projects.
Although there are no plans at the time of this writing to remove APIv3, [upgrading existing code](v4/differences-with-v3.md) to use APIv4 is a good way to future-proof extensions.
### API examples in your extensions
## Changelog
Beginning in CiviCRM v5.8, the APIv3 explorer will now be able to show examples that are stored in your extension. The only requirement is that they are found in the same sort of directory structure as core e.g. in `<yourextension>/api/v3/examples/<entity>/<file>`
All important changes made to the API are recorded in [APIv3 changes](v3/changes.md) and [APIv4 changes](v4/changes.md).
## Changelog
## Entity Relationship Diagrams
All important changes made to the API are recorded in [APIv3 changes](/api/v3/changes.md) and [APIv4 changes](/api/v4/changes.md).
To make better use of the API, it can be helpful to have a visual understanding of the relationship between entities available in the API. [Entity Relationship Diagrams](ERDs/index.md) illustrating many of these are available as supplementary documentation to the API Explorer.
\ No newline at end of file
# APIv3 Actions
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/actions.md) is recommended.
Most entities support the following actions:
## create
......@@ -42,7 +45,7 @@ Fetch entity metadata, i.e. the list of fields supported by the entity
## getlist
Used for autocomplete lookups by the
[entityRef](/framework/quickform/entityref.md) widget
[entityRef](./../../framework/quickform/entityref.md) widget
## getoptions
......@@ -61,7 +64,7 @@ returns
array(
1 => 'Female',
2 => 'Male',
3 => 'Transgender'
3 => 'Other'
)
```
......
# APIv3 Chaining
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/chaining.md) is recommended.
It is possible to do two API calls at once with the first call feeding into the second. E.g. to create a contact with a contribution you can nest the contribution create into the contact create. Once the contact has been created it will action the contribution create using the id from the contact create as `contact_id`. Likewise you can ask for all activities or all contributions to be returned when you do a `get`.
See [api/v3/examples](https://github.com/civicrm/civicrm-core/tree/master/api/v3/examples) within the core source code for a plethora of examples (from unit tests) that use chaining. To start, look at these examples:
......
# API changes
# APIv3 Changelog
This page lists changes to CiviCRM core which affect the ways in which developers use the API.
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/changes.md) is recommended.
*This page lists additions to the APIv3 with each new release of CiviCRM Core.*
Also see: [Differences Between Api v3 and v4](../v4/differences-with-v3.md) and [Hooks Changelog](../../hooks/changes.md).
## APIv3: Framework
### 5.47 Migration from `extern/rest.php` to `civicrm/ajax/rest` {:#restendpoint}
The traditional [APIv3 REST end-point](rest.md#end-point-url), `extern/rest.php`, is not supported by some common environments and lacks some newer features.
As of v5.47, `civicrm/ajax/rest` may be used as a drop-in replacement. It supports a wider range of environments and authentication protocols.
For a minimal migration, change the URL. For a full migration, you may also change the authentication protocol.
??? question "Change URL to `civicrm/ajax/rest` (Reasons)"
1. Stop maintaining manual copy of `extern/rest.php`.
2. Improve compatibility with upgraded, migrated, or reconfigured CMS.
??? example "Change URL to `civicrm/ajax/rest` (Example)"
On the CiviCRM server, enable the extension [AuthX](../../framework/authx.md). (*Navigate to "Administer => System Settings => Extensions" and enable "AuthX".*)
On the CiviCRM client, change the URL. Suppose you were sending requests via `curl`. The old request was:
```bash
curl -X 'POST' -d 'entity=Contact&action=get&json=1&key=MY_SITE_KEY&api_key=MY_API_KEY' \
'http://example.org/sites/all/modules/civicrm/extern/rest.php'
```
The new request would be:
```bash
curl -X 'POST' -d 'entity=Contact&action=get&json=1&key=MY_SITE_KEY&api_key=MY_API_KEY' \
'http://example.org/civicrm/ajax/rest'
```
Here are a few more examples of old and new URLs:
```
/* Old URLs */
https://backdrop.example.org/modules/civicrm/extern/rest.php
https://drupal.example.org/sites/all/modules/civicrm/extern/rest.php
https://wordpresss.example.org/wp-content/plugins/civicrm/civicrm/extern/rest.php
/* New URLs */
https://backdrop.example.org/civicrm/ajax/rest
https://drupal.example.org/civicrm/ajax/rest
https://wordpress.example.org/wp-admin/admin.php?page=CiviCRM&q=civicrm/ajax/rest
```
<!-- FIXME: Can we rely on WP clean URLs for this? -->
<!-- Haven't tested Joomla. Expecting http://joomla.example.org/administrator/index.php?option=com_civicrm&task=civicrm/ajax/rest&reset=1 -->
??? question "Change authentication protocol (Reasons)"
1. __Remove dependence on `CIVICRM_SITE_KEY`. Use role-based access-control.__
AuthX does not require sharing `CIVICRM_SITE_KEY`. Instead, you configure access-control by granting or revoking permissions
(`authenticate with api key` and/or `authenticate with password`).
2. __Support username/password, JWT, and/or API key.__
API keys are great - but not always. AuthX still accepts API keys -- but it also supports JSON Web Tokens (*by default*)
and usernames/passwords (*requires opt-in*).
3. __Support more authentication flows (with more correct session-management).__
Legacy REST performed authentication with HTTP parameters (`?key=...&api_key=...`). This looked like a "stateless HTTP" style, but
it often left behind extraneous records in session-storage. AuthX supports both stateless styles (eg HTTP parameters and HTTP
headers) and stateful styles (eg HTTP login/session). Stateless styles do not leave behind extraneous records in session-storage.
4. __Support a wide range of CiviCRM end-points.__
Legacy REST authentication only supported APIv3. With AuthX, you may access any `civicrm/ajax/*` end-point.
??? example "Change authentication protocol (Example)"
Legacy REST authentication is very similar to AuthX's "HTTP Parameter" authentication. Here are the steps to switch:
1. Change the URL to `civicrm/ajax/rest`, as described earlier.
2. On the CiviCRM server, verify the settings. Navigate to "Administer => System Settings => Authentication". "HTTP
Parameter" should accept credentials of type "API Key". (*This should be enabled by default.*)
3. On the CiviCRM server, ensure that appropriate users have permission `authenticate with api key`.
4. On the CiviCRM client, remove `?key=...&api_key=...`. Add `?_authx=...`. For an API key, the value must begin with `Bearer`.
```bash
## Legacy REST authentication
curl -X 'POST' -d 'entity=Contact&action=get&json=1&key=MY_SITE_KEY&api_key=MY_API_KEY' \
'http://example.org/civicrm/ajax/rest'
## AuthX HTTP parameter authentication
curl -X 'POST' -d 'entity=Contact&action=get&json=1&_authx=Bearer+MY_API_KEY' \
'http://example.org/civicrm/ajax/rest'
```
### 5.12 Support for string 'NULL' as an accepted value for custom data fields
The API has now been changed such that when setting the value of a custom field using the API if you pass the string 'NULL' then it will set the field value to be the String NULL not the database NULL. If you want the value to be truely NULL then you need to either not pass in the value or use 'null' instead
......@@ -41,7 +139,7 @@ A field defined with the key 'serialize' (in the metadata) will be serialized on
### 4.7.17: OR Operator
Most API "get" operations (with the exception of some nonstandard entities - Contact, Contribution, Pledge & Participant) [now support the OR operator](https://issues.civicrm.org/jira/browse/CRM-20034). Use the API Explorer to see the syntax. ![Example use of API Or functionality](/img/api-or-example.png)
Most API "get" operations (with the exception of some nonstandard entities - Contact, Contribution, Pledge & Participant) [now support the OR operator](https://issues.civicrm.org/jira/browse/CRM-20034). Use the API Explorer to see the syntax. ![Example use of API Or functionality](../../img/api4/api-or-example.png)
### 4.7.13: Standardized output of EntityTag api
......@@ -74,10 +172,6 @@ A generic validate action which can be used to return an array of errors in an A
Most api "get" operations now support joining onto related entities for the filters, return values, or sort fields.
### 4.7.0: New hook_civicrm_selectWhereclause
This hook can be used to impose access limits on most entities fetched via the api by adding conditions to the where clause.
### 4.7.0: REST XML format
The encoding of some values in the XML-based API changed. [Changes](https://github.com/civicrm/civicrm-core/pull/6043).
......@@ -134,7 +228,7 @@ To detect other references, one must implement `hook_civicrm_referenceCounts` or
API action "getlist" is a wrapper for API action "get." It is used mainly for quicksearch and autocomplete widgets. A call to, for example: `CRM.api3('contact', 'getlist', {input: 'bob'})` will internally call contact.get and return a list of resuts formatted for use by the select2 widget or other autocomplete/search forms. It supports formatted description, icons or other images in the results, infinite scrolling or paging of search results, and context-aware searching.
See [EntityRef Fields documentation](/framework/quickform/entityref.md) for more info.
See [EntityRef Fields documentation](../../framework/quickform/entityref.md) for more info.
### 4.4.5: Added client-side CRM.api3() wrapper
......@@ -146,7 +240,7 @@ The new wrapper supports issuing multiple api calls in a single requestto save b
### 4.4.0: 'getoptions' action accepts additional params related to context
See [Pseudoconstant (option list) Reference](/framework/pseudoconstant.md)
See [Pseudoconstant (option list) Reference](../../framework/pseudoconstant.md)
### 4.4.0: 'getoptions' action respects 'sequential' param
......@@ -230,9 +324,9 @@ Because 'sequential' gives a more concise format, it has been made the default i
### 4.3.0: New 'getoptions' action
Fetch the options for a specified field e.g. `civicrm_api('contact', 'getoptions' array('field' => 'gender_id'));` returns `array(1 => 'Female', 2 => 'Male', 3 => 'Transgender')`
Fetch the options for a specified field e.g. `civicrm_api('contact', 'getoptions' array('field' => 'gender_id'));` returns `array(1 => 'Female', 2 => 'Male', 3 => 'Other')`
See [Pseudoconstant (option list) Reference](/framework/pseudoconstant.md)
See [Pseudoconstant (option list) Reference](../../framework/pseudoconstant.md)
### 4.3.0: Deprecating action=update
......@@ -250,7 +344,7 @@ CRM-12140: The API update action was a clunky hack (get+create) to workaround th
### 4.3.0: AJAX: cj().crmAPI() is now CRM.api()
Prior to 4.3, the syntax for [AJAX](/api/interfaces.md#AJAX) API calls was
Prior to 4.3, the syntax for [AJAX](interfaces.md#AJAX) API calls was
```javascript
cj().crmAPI('Entity', 'action', {...params...}, {
......@@ -338,7 +432,7 @@ When creating a new Case record, the "create" API previously accepted `case_type
### 4.3.0: Deprecate Constant API
Most `CRM_*_Pseudoconstant methods` (which the 'constant' api is a wrapper for) are deprecated in 4.3 and many are removed in 4.4. To future-proof your code, use the [api.getoptions](/api/v3/actions.md#getoptions) method instead of the constant api. See [Pseudoconstant (option list) Reference](/framework/pseudoconstant.md)
Most `CRM_*_Pseudoconstant methods` (which the 'constant' api is a wrapper for) are deprecated in 4.3 and many are removed in 4.4. To future-proof your code, use the [api.getoptions](../v3/actions.md#getoptions) method instead of the constant api. See [Pseudoconstant (option list) Reference](../../framework/pseudoconstant.md)
### 4.3.0: Contact get API now respects ACLS
......@@ -362,7 +456,7 @@ This API can be used to create, update and delete 'state/province' entries via t
### 4.7.7 System.updatelogtables
This api can be called to change the format of the `log_conn_id` fields to a 17 Char varchar - and to switch to using truly unique connection ids. Calling this api can also convert log tables to INNODB - using this hook [hook_civicrm_alterLogTables](/hooks/hook_civicrm_alterLogTables.md) either in your code or with the [Extension](https://github.com/eileenmcnaughton/nz.co.fuzion.innodbtriggers/blob/master/innodbtriggers.php)
This api can be called to change the format of the `log_conn_id` fields to a 17 Char varchar - and to switch to using truly unique connection ids. Calling this api can also convert log tables to INNODB - using this hook [hook_civicrm_alterLogTables](../../hooks/hook_civicrm_alterLogTables.md) either in your code or with the [Extension](https://github.com/eileenmcnaughton/nz.co.fuzion.innodbtriggers/blob/master/innodbtriggers.php)
Note that log table conversion can be slow which is why we are offering a conversion tool for the improved `log_conn_id` storage rather than springing it in an upgrade script
......@@ -510,58 +604,12 @@ You need to upgrade civix as well so it generates this new code for a custom sea
### 4.6.0: CRM_Contact_Form_Search_Interface-&gt;buildTaskList
Classes which implement this interface must implement a new method called buildTaskList. This method is responsible for building the list of actions (e.g., Add to Group) that may be performed on set of search results. It differs
from [hook_civicrm_searchTasks](/hooks/hook_civicrm_searchTasks.md) in that the hook allows a developer to specify tasks by entity (e.g., Contact, Event, etc.) whereas buildTaskList provides the ability to target a specific form. The new method takes a `CRM_Core_Form_Search` object as an argument and should return an array. Dump `CRM_Core_Form_Search()->_taskList` to learn about the format of the array. The array returned by buildTaskList will completely replace the task list.
from [hook_civicrm_searchTasks](../../hooks/hook_civicrm_searchTasks.md) in that the hook allows a developer to specify tasks by entity (e.g., Contact, Event, etc.) whereas buildTaskList provides the ability to target a specific form. The new method takes a `CRM_Core_Form_Search` object as an argument and should return an array. Dump `CRM_Core_Form_Search()->_taskList` to learn about the format of the array. The array returned by buildTaskList will completely replace the task list.
Aside from the community-maintained custom searches in `CRM/Contact/Form/Search/Custom/`, this change does not affect CiviCRM core. Custom searches which extend `CRM_Contact_Form_Search_Custom_Base` (as do those built on civix) will not be affected, as the method is implemented there.
See [CRM-15965](https://issues.civicrm.org/jira/browse/CRM-15965) for more information.
## Hooks
This section doesn't document changes to APIv3 per se – rather, it documents changes to the the [Hook](/hooks/index.md) interfaces.
### 5.11 hook_civicrm_pageRun invocation removed from CRM_Core_Page_Inline_Help
`CRM_Core_Page_Inline_Help` is the class that fetches inline documentation from `.hlp` templates to be shown in help baloons. `hook_civicrm_pageRun` normally does not run when fetching help, except in the (very rare) case that a site has been customized with an `.extra.hlp` file, which potentially causes problems because the class `CRM_Core_Page_Inline_Help` does not extend `CRM_Core_Page`. The inconsistent hook invocation [has been removed](https://github.com/civicrm/civicrm-core/commit/87bf0ec4c246b03e3e6c2ab2fb0c14664473c52b).
### 4.7.14 hook_civicrm_pre & hook_civicrm_post supports CustomField
Pre and post hooks now fire when adding, updating or deleting custom fields.
### 4.7.0 hook_civicrm_tabs deprecated
This hook is deprecated in 4.7. Use `hook_civicrm_tabset` instead.
### 4.7.0 hook_civicrm_validate removed
This hook was deprecated since v4.2 in favor of `hook_civicrm_validateForm`.
### 4.5.0: hook_civicrm_enableDisable removed
The deprecated enableDisablehook was not reliably invoked every time an entity was enabled or disabled.It was removed in 4.5. Use the standard *pre* and *post* hooks instead.
### 4.5.0: hook_civicrm_referenceCounts
The new API call "getrefcount" allows one to ask about references to a given record. Using [hook_civicrm_referenceCounts](/hooks/hook_civicrm_referenceCounts.md), a third-party developer can modify the reference-count.
### 4.4.0: Add hooks for profile forms
Added hooks for
- "civicrm/profile/view" [hook_civicrm_viewProfile](/hooks/hook_civicrm_viewProfile.md),
- "civicrm/profile" [hook_civicrm_searchProfile](/hooks/hook_civicrm_searchProfile.md),
- "civicrm/profile/edit" or "civicrm/profile/create" [hook_civicrm_buildProfile](/hooks/hook_civicrm_buildProfile.md),[hook_civicrm_validateProfile](/hooks/hook_civicrm_validateProfile.md), [hook_civicrm_processProfile](/hooks/hook_civicrm_processProfile.md)).
See also: [CRM-12865](http://issues.civicrm.org/jira/browse/CRM-12865)
### 4.4.0: hook_civicrm_searchColumns: Change of $values in profile-listings
When displaying a profile-based listing (such as "civicrm/profile?gid=XXX"), the $values represents a row/column matrix by providing an array of rows. Each row contains several cells keyed numerically, but one cell was inconsistently keyed by the string `sort_name` instead of its numeric position. The `sort_name` cell appeared early and affected the numbering of all subsequent cells. For greater consistency, the `sort_name` will now be identified numerically, and other cells will be renumbered accordingly.
### 4.4.0: hook_civicrm_buildUFGroupsForModule: Change to $ufGroups
$ufGroups provides an array of UFGroup records. In previous releases, this array always contained the same fields for each record (`id`, `title`, `is_reserved`, etc). In 4.4, the fields are usually the same, but they may vary depending on the context. See patches to [CRM-13388](http://issues.civicrm.org/jira/browse/CRM-13388)
## Other
### 4.7.0: CRM_Core_Config: Property loading
......@@ -620,7 +668,7 @@ The global variable `$civicrm_setting` is used to [override CiviCRM settings](ht
}
```
See also: [CRM-16373](htps://issues.civicrm.org/jira/browse/CRM-16373).
See also: [CRM-16373](https://issues.civicrm.org/jira/browse/CRM-16373).
### 4.7.0: bin: Removed deprecated scripts
......@@ -645,11 +693,11 @@ 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
CiviCRM 4.2+ allowed developers to inject content on a web page using the [Region](/framework/region.md) and [Resource](/framework/resources.md) APIs. CiviCRM 4.5+ introduced broad changes to the page-loading process which cause many pages to load in-situ as "snippets". This significantly improved perceived load times but caused some regressions on customized backend forms which relied on Region or Resource APIs. v4.5.3 introduces the following changes:
CiviCRM 4.2+ allowed developers to inject content on a web page using the [Region](../../framework/region.md) and [Resource](../../framework/resources.md) APIs. CiviCRM 4.5+ introduced broad changes to the page-loading process which cause many pages to load in-situ as "snippets". This significantly improved perceived load times but caused some regressions on customized backend forms which relied on Region or Resource APIs. v4.5.3 introduces the following changes:
- The `page-header`, `page-body`, and `page-footer` regions will all be processed on normal (full, standalone) pages as well as snippets (embedded AJAX pages).
- The `html-header` region is only processed on normal-pages.
......
# APIv3 and Custom Data
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/custom-data.md) is recommended.
Custom data attached to entities is referenced by `custom_N` where `N` is the unique numerical ID for the custom data field.
To set a custom field, or find entities with custom fields of a particular value, you typically use a parameter like this:
......@@ -28,7 +31,7 @@ $params['return'] = 'custom_N,custom_O,custom_P';
For setting custom date fields, (ie CustomValue create), date format is `YmdHis`, for example: `20050425000000`.
This is just a brief introduction; each API may have different requirements and allow different formats for accessing the custom data. See the [API function documentation](/api/index.md) and also read the comments and documentation in each API php file (under civicrm/CRM/api/v3 in your CiviCRM installation) for exact details,
This is just a brief introduction; each API may have different requirements and allow different formats for accessing the custom data. See the [API function documentation](../index.md) and also read the comments and documentation in each API php file (under civicrm/CRM/api/v3 in your CiviCRM installation) for exact details,
which vary for each API entity and function.
## Custom Value get
......@@ -66,12 +69,12 @@ For entities other than the Contact Entity you can use an alternate notation to
The CustomValue Entity implicitly determines what the `entity_table` variable should be when it is not supplied. If you find that the implicitly is not working out exactly, then specify the `entity_table` key.
When setting the value of custom data that is of type checkbox or multivalue it is important to note that the options need to be passed in as an array. For example, if you want to set options `a` and `c` of for custom value `2` on `contact` you should do the following
When setting the value of custom data that is of type checkbox or multivalue it is important to note that the options need to be passed in as an array. For example, if you want to set options `a` and `c` of the custom field with the ID `2` on Contact `123` you should do the following
```php
$result = civicrm_api3(
'Contact',
'CustomValue',
'create',
array('id' = 2, 'custom_2' => array('a', 'c'))
array('entity_id' => 123, 'custom_2' => array('a', 'c'))
);
```
# APIv3 Examples
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/usage.md) is recommended.
All the APIv3 Examples are generated through Tests in the CodeBase and are auto-generated from those tests so we can be certain of the code that is given.
## Location of Examples
The most current examples can be found in CiviCRM's GitHub Repo on the [Master Branch](https://github.com/civicrm/civicrm-core/tree/master/api/v3/examples). When you install CiviCRM the Examples that come with the particular version of CiviCRM you have installed can be found in `<civicrm_root>/api/v3/examples`. You will also be able to view them through the [API Explorer](/api/index.md#api-explorer) by clicking on the **Examples** tab in the Explorer.
The most current examples can be found in CiviCRM's GitHub Repo on the [Master Branch](https://github.com/civicrm/civicrm-core/tree/master/api/v3/examples). When you install CiviCRM the Examples that come with the particular version of CiviCRM you have installed can be found in `<civicrm_root>/api/v3/examples`. You will also be able to view them through the [API Explorer](../index.md#api-explorer) by clicking on the **Examples** tab in the Explorer.
## Creating a New Example
......
# API Interfaces
# APIv3 Interfaces
The API has three main interfaces along with the PHP Code that can be used to access the API.
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/usage.md) is recommended.
APIv3 has three main interfaces along with the PHP Code that can be used to access the API.
## Javascript {#javascript}
......@@ -8,27 +11,27 @@ CiviCRM provides a number of different methods to interact with the API when in
### Javascript AJAX Interface {:#ajax}
The AJAX interface is one of the more common interfaces used within CiviCRM code. The AJAX interface is most commonly seen when used in javascript code. You can get example AJAX interface code out of the [API Explorer](/api/index.md#api-explorer) as needed.
The AJAX interface is one of the more common interfaces used within CiviCRM code. The AJAX interface is most commonly seen when used in javascript code. You can get example AJAX interface code out of the [API Explorer](../index.md#api-explorer) as needed.
#### CRM.api3 / CRM.api4
#### CRM.api3
`CRM.api3` and `CRM.api4` is a javascript method produced by CiviCRM as a thin wrapper around a call to `http://example.org/civicrm/ajax/rest`. The standard format of such an API call can be found under the relevant usage sub-chapter of this documentation
`CRM.api3` is a javascript method produced by CiviCRM as a thin wrapper around a call to `http://example.org/civicrm/ajax/rest`. The standard format of such an API call can be found under the relevant usage sub-chapter of this documentation.
#### Tests
[QUnit](/testing/qunit.md) tests for `CRM.api3` can be found in [/tests/qunit/crm-api3](https://github.com/civicrm/civicrm-core/tree/master/tests/qunit/crm-api3).
[QUnit](../../testing/qunit.md) tests for `CRM.api3` can be found in [/tests/qunit/crm-api3](https://github.com/civicrm/civicrm-core/tree/master/tests/qunit/crm-api3).
You can run the tests within a web browser by visiting `/civicrm/dev/qunit/civicrm/crm-api3` within a CiviCRM [development installation](/tools/civibuild.md).
You can run the tests within a web browser by visiting `/civicrm/dev/qunit/civicrm/crm-api3` within a CiviCRM [development installation](../../tools/civibuild.md).
#### Changes
The recommended AJAX interface has changed between CiviCRM versions as follows:
The recommended AJAX interface has changed between CiviCRM versions as follows:
* version 4.2.x - `cj().crmAPI(...)`
* version 4.3.x - `CRM.api(...)`
* version 4.4.x onwards - `CRM.api3()`
For details see [APIv3 changes](/api/v3/changes.md).
For details see [APIv3 changes](changes.md).
### Javascript AngularJS crmAPI {:#angularjs}
......@@ -91,126 +94,26 @@ crmAPI.get ('contact',{contact_type:'Individual',return:'display_name,email,phon
More information can be found on the [project page](https://github.com/TechToThePeople/node-civicrm)
<a id="civicrm-extern-rest-api"></a>
<a id="wp-rest-api"></a>
<a id="keys"></a>
<a id="options-parameters-and-chaining-in-the-rest-interface"></a>
## REST Interface {:#rest}
The REST interface examples can also be found in the API Explorer as with the AJAX interface. The REST interface works very much like the AJAX interface however there is one major difference. The REST interface requires an `api_key` which is attached to the user that will be performing the action against the system and a `site_key` which is the key stored in `civicrm.settings.php`. There must also be a user account in the relevant content management system for the user associated with the API Key. The main reason for this is that the REST interface unlike the AJAX interface is designed for being accessed from an external site. The REST interface defaults to returning XML data however in your API calls you can request to have it return a JSON formatted version. When calling the REST interface you should do it as a `POST` not as a `GET` request. The only API actions that will work over the GET call would be get actions.
To use the REST interface use something along the line of
```
https://www.example.org/path/to/civi/codebase/civicrm/extern/rest.php?entity=thething&action=doit&key=your_site_key&api_key=the_user_api_key
```
Or if you wish to have it return json do the following
```
https://www.example.org/path/to/civi/codebase/civicrm/extern/rest.php?entity=thething&action=doit&key=your_site_key&api_key=the_user_api_key&json=1
```
You can also access the AJAX Interface from the REST function but only as an XHR call through the browser not as a regular page
```
http://www.example.org/civicrm/ajax/rest?entity=contact&action=get&json=1
```
More information on the security of the AJAX interface and permissions needed can be found on the [Permissions Page](/security/permissions.md) in Security.
Example Outputs from the REST Interface are as follows:
Response on searching for contact
```xml
<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Result>
<contact_id>1</contact_id>
<contact_type>Individual</contact_type>
<sort_name>Doe, John</sort_name>
<display_name>John G Doe</display_name>
<do_not_email>0</do_not_email>
<do_not_phone>0</do_not_phone>
<do_not_mail>0</do_not_mail>
<do_not_trade>0</do_not_trade>
<is_opt_out>0</is_opt_out>
<home_URL>[http://www.example.com]</home_URL>
<preferred_mail_format>Both</preferred_mail_format>
<first_name>John</first_name>
<middle_name>G</middle_name>
<last_name>Doe</last_name>
<is_deceased>0</is_deceased>
<email_id>2</email_id>
<email>jdoe@example.com</email>
<on_hold>0</on_hold>
</Result>
...
<Result>
<contact_id>N</contact_id>
<contact_type>Individual</contact_type>
<sort_name>test@example.org</sort_name>
<display_name>test@example.org</display_name>
<do_not_email>0</do_not_email>
<do_not_phone>0</do_not_phone>
<do_not_mail>0</do_not_mail>
<do_not_trade>0</do_not_trade>
<is_opt_out>0</is_opt_out>
<preferred_mail_format>Both</preferred_mail_format>
<is_deceased>0</is_deceased>
<email_id>4</email_id>
<email>test@example.org</email>
<on_hold>0</on_hold>
</Result>
</ResultSet>
```
Response to creating a new contact
```xml
<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Result>
<contact_id>4</contact_id>
<is_error>0</is_error>
</Result>
</ResultSet>
```
### Setting up API Keys {:#keys}
The CiviCRM API provides REST bindings, enabling remote applications to read and write data.
Before being able to use the REST Interface you will need to have set up the `CIVICRM_SITE_KEY` and the users `API_KEY`. There are three methods of creating API keys for users
The REST interface for remote applications is very similar to the AJAX interface for browser-based applications. Both submit API calls to an HTTP end-point.
However, for remote applications, you must explicitly deal with formatting and authenticating the HTTP requests.
!!! warning
API keys need to be unique and set on a user with appropriate [permissions](/security/permissions.md).
For more detailed information about how to work with REST API, see:
#### Manual Method
You can enter the key directly in the database. This would be done by the following
```sql
UPDATE civicrm_contact
SET api_key = "your_key_you_made_up"
WHERE id = "id_of_the_contact_you_want_to_update"
```
#### API Key Extension
There is now an [API Key Extension](https://civicrm.org/extensions/api-key) which can help manage API Keys of users. If you have enough permissions after installing the extension you will see an API Key Tab appear on the contact screens. You can then add / edit / delete API keys as necessary. To delete a key just blank the value
#### Using the API Explorer.
As per the [Stack Echange Thread](http://civicrm.stackexchange.com/questions/9945/how-do-i-set-up-an-api-key-for-a-user) It is possible to set the users API Key through the explorer.
### Options Parameters and Chaining in the REST Interface.
When using options in the REST Interface they need to be in array format. This also applies to chaining of API calls. This will mean that users will need to ensure that the arrays are properly html encoded before sending the request. Examples of using Options and Chaining are below
```
http://example.org/civicrm/extern/rest.php?entity=GroupContact&action=get&group_id=2&options[limit]=25&options[offset]=50
```
```
http://example.org/civicrm/extern/rest.php?entity=Contact&action=create&group_id=2&api.Email.replace[values][params][email]=joeblow@example.com&api.Email.replace[values][params][on_hold]=1
```
* [Sysadmin Guide: Setup: API Keys](https://docs.civicrm.org/sysadmin/en/latest/setup/api-keys/)
* [Developer Guide: APIv3 REST](rest.md)
* [Developer Guide: Framework: Authentication](../../framework/authx.md)
## Smarty API Interface
When building smarty templates you might find you may want to do lookups from the database for some reason. This maybe to get most recent contribution or other information from a contact's record if you adding templates on. The format of the Smarty API call is very similar to that of the APIv3 calls.
When building smarty templates you might find you may want to do lookups from the database for some reason. This maybe to get most recent contribution or other information from a contact's record if you adding templates on. The format of the Smarty API call is very similar to that of the APIv3 calls.
```smarty
{crmAPI entity="nameobject" method="namemethod" var="namevariable" extraparam1="aa" extraparam2="bb" sequential="1"}
......
# API Joins
# APIv3 Joins
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/implicit-joins.md) is recommended.
An API "get" action will typically return only the values of the entity
requested. However, there are times when it is advantageous to returned
......@@ -7,7 +10,7 @@ addresses, you may want to return the name of the associated contact from the
Contact entity.
The CiviCRM API supports two methods of returning data from associated entities;
API Joins and [APIv3 Chaining](/api/v3/chaining.md). API joins provide higher
API Joins and [APIv3 Chaining](../v3/chaining.md). API joins provide higher
performance by making a single SQL query with a
[SQL join](https://dev.mysql.com/doc/refman/5.7/en/join.html), and are
generally preferable to API chaining where available.
......@@ -42,22 +45,22 @@ $result = civicrm_api3('Event', 'get', array(
'return' => array("title", "campaign_id.name", "campaign_id.campaign_type_id"),
));
```
!!! tip
Joins are available only with the [get](/api/v3/actions.md#get),
[getsingle](/api/v3/actions.md#getsingle), and [getcount](/api/v3/actions.md#getcount)
!!! tip "Supported actions"
Joins are available only with the [get](../v3/actions.md#get),
[getsingle](../v3/actions.md#getsingle), and [getcount](../v3/actions.md#getcount)
actions.
## 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](/api/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
!!! warning "Not supported for every entity"
For historical reasons, some entities have a non-standard API in APIv3
in order to handle more complicated operations. Those entities - 'Contact',
'Contribution', 'Pledge', and 'Participant' - can be joined to from another
table, but you can not join to other tables from them. This limitation will
be removed in APIv4.
table, but you can not join to other tables from them.
[APIv4](../v4/implicit-joins.md) does not have this limitation.
# API Options
There are many API Options accepted by the CiviCRM API. These options allow the developer to add in more parameters to the resulting Query that is run against the database. E.g. Limit, Sort. You can explore these options using the the [API Explorer](/api/index.md#api-explorer) and the [APIv3 Examples](/api/v3/examples.md) However, some parameters are particularly dynamic or generic; these may not be explained well by the auto-generated documentation. The format for passing options as parameters using the REST interface is explained at [REST interface](/api/interfaces.md#rest).
!!! warning "APIv3 Deprecation"
API version 3 is now deprecated. [Version 4](../v4/usage.md) is recommended.
There are many API Options accepted by the CiviCRM API. These options allow the developer to add in more parameters to the resulting Query that is run against the database. E.g. Limit, Sort. You can explore these options using the the [API Explorer](../index.md#api-explorer) and the [APIv3 Examples](../v3/examples.md) However, some parameters are particularly dynamic or generic; these may not be explained well by the auto-generated documentation. The format for passing options as parameters using the REST interface is explained at [REST interface](interfaces.md#rest).
## sequential
......