├── .github
└── workflows
│ └── stale.yml
├── .gitignore
├── LICENSE.txt
├── README.md
├── TODO.md
├── bin
└── hook-summary.py
├── docs
├── api
│ ├── index.md
│ ├── interfaces.md
│ ├── v3
│ │ ├── actions.md
│ │ ├── chaining.md
│ │ ├── changes.md
│ │ ├── custom-data.md
│ │ ├── examples.md
│ │ ├── joins.md
│ │ ├── options.md
│ │ ├── usage.md
│ │ └── wp-rest.md
│ └── v4
│ │ ├── actions.md
│ │ ├── architecture.md
│ │ ├── chaining.md
│ │ ├── changes.md
│ │ ├── custom-data.md
│ │ ├── differences-with-v3.md
│ │ ├── joins.md
│ │ └── usage.md
├── basics
│ ├── community.md
│ ├── planning.md
│ ├── requirements.md
│ └── skills.md
├── core
│ ├── contributing.md
│ ├── hacking.md
│ ├── pr-review.md
│ ├── release-process.md
│ └── verify-fix.md
├── documentation
│ ├── extensions.md
│ ├── index.md
│ ├── markdown.md
│ └── style-guide.md
├── extensions
│ ├── advanced.md
│ ├── civix.md
│ ├── cms-specific.md
│ ├── index.md
│ ├── info-xml.md
│ ├── lifecycle.md
│ ├── packaging.md
│ ├── payment-processors
│ │ ├── create.md
│ │ ├── index.md
│ │ └── types.md
│ ├── publish.md
│ ├── structure.md
│ └── troubleshooting.md
├── financial
│ ├── financialentities.md
│ ├── orderAPI.md
│ ├── overview.md
│ └── paymentAPI.md
├── framework
│ ├── ajax.md
│ ├── angular
│ │ ├── changeset.md
│ │ ├── files.md
│ │ ├── index.md
│ │ ├── loader.md
│ │ └── quickstart.md
│ ├── asset-builder.md
│ ├── backbone.md
│ ├── bootstrap.md
│ ├── cache.md
│ ├── civimail.md
│ ├── civireport.md
│ ├── codebase.md
│ ├── database
│ │ ├── index.md
│ │ ├── schema-definition.md
│ │ ├── schema-design.md
│ │ └── transactions.md
│ ├── filesystem.md
│ ├── pseudoconstant.md
│ ├── queues
│ │ └── index.md
│ ├── quickform
│ │ ├── entityref.md
│ │ └── index.md
│ ├── region.md
│ ├── resources.md
│ ├── routing.md
│ ├── setting.md
│ ├── setup
│ │ ├── getting-started.md
│ │ ├── index.md
│ │ ├── new-installer.md
│ │ ├── new-plugin.md
│ │ └── plugins.md
│ ├── templates
│ │ ├── customizing.md
│ │ ├── extending-smarty.md
│ │ └── index.md
│ ├── theme.md
│ ├── token.md
│ ├── ui.md
│ └── upgrade.md
├── hooks
│ ├── changes.md
│ ├── hook_civicrm_aclGroup.md
│ ├── hook_civicrm_aclWhereClause.md
│ ├── hook_civicrm_activeTheme.md
│ ├── hook_civicrm_alterAPIPermissions.md
│ ├── hook_civicrm_alterAdminPanel.md
│ ├── hook_civicrm_alterAngular.md
│ ├── hook_civicrm_alterBadge.md
│ ├── hook_civicrm_alterBarcode.md
│ ├── hook_civicrm_alterCalculatedMembershipStatus.md
│ ├── hook_civicrm_alterContent.md
│ ├── hook_civicrm_alterCustomFieldDisplayValue.md
│ ├── hook_civicrm_alterEntityRefParams.md
│ ├── hook_civicrm_alterExternUrl.md
│ ├── hook_civicrm_alterLocationMergeData.md
│ ├── hook_civicrm_alterLogTables.md
│ ├── hook_civicrm_alterMailContent.md
│ ├── hook_civicrm_alterMailParams.md
│ ├── hook_civicrm_alterMailer.md
│ ├── hook_civicrm_alterMailingLabelParams.md
│ ├── hook_civicrm_alterMailingRecipients.md
│ ├── hook_civicrm_alterMenu.md
│ ├── hook_civicrm_alterPaymentProcessorParams.md
│ ├── hook_civicrm_alterReportVar.md
│ ├── hook_civicrm_alterSettingsFolders.md
│ ├── hook_civicrm_alterSettingsMetaData.md
│ ├── hook_civicrm_alterTemplateFile.md
│ ├── hook_civicrm_alterUFFields.md
│ ├── hook_civicrm_angularModules.md
│ ├── hook_civicrm_apiWrappers.md
│ ├── hook_civicrm_batchItems.md
│ ├── hook_civicrm_batchQuery.md
│ ├── hook_civicrm_buildAmount.md
│ ├── hook_civicrm_buildAsset.md
│ ├── hook_civicrm_buildForm.md
│ ├── hook_civicrm_buildProfile.md
│ ├── hook_civicrm_buildStateProvinceForCountry.md
│ ├── hook_civicrm_buildUFGroupsForModule.md
│ ├── hook_civicrm_caseChange.md
│ ├── hook_civicrm_caseSummary.md
│ ├── hook_civicrm_caseTypes.md
│ ├── hook_civicrm_check.md
│ ├── hook_civicrm_config.md
│ ├── hook_civicrm_contactListQuery.md
│ ├── hook_civicrm_contact_get_displayname.md
│ ├── hook_civicrm_container.md
│ ├── hook_civicrm_copy.md
│ ├── hook_civicrm_coreResourceList.md
│ ├── hook_civicrm_cron.md
│ ├── hook_civicrm_crudLink.md
│ ├── hook_civicrm_custom.md
│ ├── hook_civicrm_customFieldOptions.md
│ ├── hook_civicrm_customPre.md
│ ├── hook_civicrm_dashboard.md
│ ├── hook_civicrm_dashboard_defaults.md
│ ├── hook_civicrm_disable.md
│ ├── hook_civicrm_dupeQuery.md
│ ├── hook_civicrm_emailProcessor.md
│ ├── hook_civicrm_emailProcessorContact.md
│ ├── hook_civicrm_enable.md
│ ├── hook_civicrm_entityRefFilters.md
│ ├── hook_civicrm_entityTypes.md
│ ├── hook_civicrm_eventDiscount.md
│ ├── hook_civicrm_export.md
│ ├── hook_civicrm_fieldOptions.md
│ ├── hook_civicrm_fileSearches.md
│ ├── hook_civicrm_findDuplicates.md
│ ├── hook_civicrm_geocoderFormat.md
│ ├── hook_civicrm_getAssetUrl.md
│ ├── hook_civicrm_idsException.md
│ ├── hook_civicrm_import.md
│ ├── hook_civicrm_inboundSMS.md
│ ├── hook_civicrm_install.md
│ ├── hook_civicrm_links.md
│ ├── hook_civicrm_mailingGroups.md
│ ├── hook_civicrm_managed.md
│ ├── hook_civicrm_membershipTypeValues.md
│ ├── hook_civicrm_merge.md
│ ├── hook_civicrm_navigationMenu.md
│ ├── hook_civicrm_notePrivacy.md
│ ├── hook_civicrm_optionValues.md
│ ├── hook_civicrm_pageRun.md
│ ├── hook_civicrm_permission.md
│ ├── hook_civicrm_permission_check.md
│ ├── hook_civicrm_post.md
│ ├── hook_civicrm_postCommit.md
│ ├── hook_civicrm_postEmailSend.md
│ ├── hook_civicrm_postIPNProcess.md
│ ├── hook_civicrm_postInstall.md
│ ├── hook_civicrm_postJob.md
│ ├── hook_civicrm_postMailing.md
│ ├── hook_civicrm_postProcess.md
│ ├── hook_civicrm_postSave_table_name.md
│ ├── hook_civicrm_post_case_merge.md
│ ├── hook_civicrm_pre.md
│ ├── hook_civicrm_preJob.md
│ ├── hook_civicrm_preProcess.md
│ ├── hook_civicrm_pre_case_merge.md
│ ├── hook_civicrm_processProfile.md
│ ├── hook_civicrm_queryObjects.md
│ ├── hook_civicrm_recent.md
│ ├── hook_civicrm_referenceCounts.md
│ ├── hook_civicrm_searchColumns.md
│ ├── hook_civicrm_searchProfile.md
│ ├── hook_civicrm_searchTasks.md
│ ├── hook_civicrm_selectWhereClause.md
│ ├── hook_civicrm_summary.md
│ ├── hook_civicrm_summaryActions.md
│ ├── hook_civicrm_tabs.md
│ ├── hook_civicrm_tabset.md
│ ├── hook_civicrm_themes.md
│ ├── hook_civicrm_tokenValues.md
│ ├── hook_civicrm_tokens.md
│ ├── hook_civicrm_triggerInfo.md
│ ├── hook_civicrm_unhandledException.md
│ ├── hook_civicrm_uninstall.md
│ ├── hook_civicrm_unsubscribeGroups.md
│ ├── hook_civicrm_upgrade.md
│ ├── hook_civicrm_validate.md
│ ├── hook_civicrm_validateForm.md
│ ├── hook_civicrm_validateProfile.md
│ ├── hook_civicrm_viewProfile.md
│ ├── hook_civicrm_xmlMenu.md
│ ├── index.md
│ ├── list.md
│ └── usage
│ │ ├── drupal.md
│ │ ├── extension.md
│ │ ├── joomla.md
│ │ ├── symfony.md
│ │ └── wordpress.md
├── img
│ ├── APIv4-action-inheritance.svg
│ ├── APIv4-entity-inheritance.svg
│ ├── Api4-PHP-Styles.svg
│ ├── CMS_URL.png
│ ├── CiviCRM.png
│ ├── Jenkis_Show_Results.png
│ ├── api-or-example.png
│ ├── financial
│ │ └── FinancialAccount.png
│ ├── gitlab-reference.png
│ ├── index.md
│ ├── inheritance-community-chest.jpg
│ ├── mysql_workbench_civicrm_country_foreign_keys.png
│ ├── mysql_workbench_civicrm_country_tables.png
│ ├── quickform-lifecycle.png
│ ├── repository-access.png
│ └── security-inputs-and-outputs.svg
├── index.md
├── security
│ ├── access.md
│ ├── index.md
│ ├── inputs.md
│ ├── outputs.md
│ ├── permissions.md
│ └── reporting.md
├── standards
│ ├── database.md
│ ├── index.md
│ ├── javascript.md
│ ├── php.md
│ ├── review.md
│ └── review
│ │ ├── template-del-1.0.md
│ │ ├── template-mc-1.0.md
│ │ └── template-word-1.0.md
├── testing
│ ├── codeception.md
│ ├── continuous-integration.md
│ ├── index.md
│ ├── karma.md
│ ├── manual.md
│ ├── phpunit.md
│ ├── protractor.md
│ ├── qunit.md
│ ├── selenium.md
│ └── upgrades.md
├── tools
│ ├── buildkit.md
│ ├── civi-test-run.md
│ ├── civibuild.md
│ ├── cividist.md
│ ├── civilint.md
│ ├── debugging.md
│ ├── git.md
│ ├── index.md
│ ├── issue-tracking.md
│ ├── jenkins.md
│ ├── phpstorm.md
│ └── universe.md
└── translation
│ ├── database.md
│ ├── extensions.md
│ └── index.md
├── mkdocs.yml
└── redirects
├── internal.txt
├── wiki-crm.txt
└── wiki-crmdoc.txt
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: "0 * * * *"
6 |
7 | jobs:
8 | stale:
9 |
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/stale@v3
14 | with:
15 | repo-token: ${{ secrets.GITHUB_TOKEN }}
16 | stale-issue-message: 'This issue has had no activity in 60 days and has been marked as stale, it will not be closed.'
17 | stale-pr-message: 'This pull request has had no activity in 60 days and has been marked as stale, it will not be closed.'
18 | stale-issue-label: 'no-issue-activity'
19 | stale-pr-label: 'no-pr-activity'
20 | days-before-stale: 60
21 | days-before-close: -1
22 | exempt-issue-labels: 'awaiting-approval,work-in-progress'
23 | exempt-pr-labels: 'awaiting-approval,work-in-progress'
24 | remove-stale-when-updated: 'True'
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | site
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CiviCRM Developer Guide
2 |
3 | * **Issues have moved to https://lab.civicrm.org/documentation/docs/dev/-/issues**
4 | * **Submit new merge/pull requests at https://lab.civicrm.org/documentation/docs/dev**
5 |
6 | A documentation guide for people who develop with/for [CiviCRM](https://civicrm.org).
7 |
8 | - [Read published version](http://docs.civicrm.org/dev/en/master)
9 | - [Learn how to edit](https://docs.civicrm.org/dev/en/master/documentation/#how-to-edit)
10 |
11 | # Docs Infrastructure Links
12 |
13 | - [Docs Publisher system and issue queue](https://lab.civicrm.org/documentation/docs-publisher)
14 | - [Docs Book definitions for the Docs Publisher](https://lab.civicrm.org/documentation/docs-books)
15 | - [Docs Working Group meta issue queue](https://lab.civicrm.org/documentation/meta)
16 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # TODO
2 |
3 | ## Documentation structure
4 |
5 | * Where should we store deprecated documentation? Should we include it at all?
6 | * Should we rename `develop.md` (`core/develop.md` vs `extension/develop.md`?)
7 |
8 | ## Style Guide
9 | * Add guide for using footnotes
10 |
11 | ## Tasks
12 |
13 | * Finish importing [GitHub for CiviCRM](https://wiki.civicrm.org/confluence/display/CRMDOC43/GitHub+for+CiviCRM) to `develop.md` and `develop-deprecated.md`.
14 |
15 | ## Extension questions
16 |
17 | * How do I include Composer libraries in my CiviCRM extension?
18 | * Should I add the `vendor/` directory to Git?
19 | * How do I release my extension?
20 | * How do I provide downloadable .zip files from Github (which are working builds)?
21 |
--------------------------------------------------------------------------------
/bin/hook-summary.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import yaml
4 | import re
5 | from os.path import dirname, abspath, join
6 |
7 | PROJECT_ROOT = dirname(dirname(abspath(__file__)))
8 | DOCS_ROOT = join(PROJECT_ROOT, 'docs/')
9 | MKDOCS_YAML_FILE = join(PROJECT_ROOT, 'mkdocs.yml')
10 | OUTPUT_FILE = join(DOCS_ROOT, 'hooks/', 'list.md')
11 | HEADER = """# All hooks
12 |
13 |
20 |
21 |
22 | This is an overview list of all available hooks, listed by category.
23 | """
24 |
25 | def findBetween( s, first, last ):
26 | start = s.index( first ) + len( first )
27 | end = s.index( last, start )
28 | return s[start:end]
29 |
30 | def getSummary(hookFile):
31 | content = open(join(DOCS_ROOT + hookFile), 'r').read()
32 | summary = findBetween(content, '## Summary', '##')
33 | summary = re.sub('This hook (is)?(was)?', '', summary)
34 | summary = re.sub('\s+', ' ', summary).strip()
35 | if not (summary.endswith('.')):
36 | summary = summary + '.'
37 | return summary
38 |
39 | output = f = open(OUTPUT_FILE, 'w')
40 | with open(MKDOCS_YAML_FILE, 'r') as f:
41 | doc = yaml.load(f)
42 | pages = doc["nav"]
43 | for section in pages:
44 | if "Hooks" in section:
45 | hookSection = section.get("Hooks")
46 |
47 | output.write(HEADER)
48 |
49 | for section in hookSection:
50 | categoryHooks = list()
51 | category, hookList = section.popitem()
52 | if isinstance(hookList, list):
53 | for hookDetails in hookList:
54 | hookName = hookDetails.iterkeys().next()
55 | if re.match("^()?hook_civicrm_*", hookName):
56 | categoryHooks.append(hookDetails)
57 |
58 | if len(categoryHooks) > 0:
59 | output.write('\n## {}\n\n'.format(category))
60 | for hookDetails in categoryHooks:
61 | hookName, hookFile = hookDetails.popitem()
62 | summary = getSummary(hookFile)
63 | hookNameForLink = hookFile.replace('hooks/', '')
64 | output.write('* **[{}]({})** - {}\n'.format(hookName, hookNameForLink, summary))
65 |
--------------------------------------------------------------------------------
/docs/api/v3/actions.md:
--------------------------------------------------------------------------------
1 | # APIv3 Actions
2 |
3 | Most entities support the following actions:
4 |
5 | ## create
6 |
7 | Insert or update one record. (Note: If an `id` is specified, then an
8 | existing record will be modified.)
9 |
10 | ## delete
11 |
12 | Delete one record. (Note: Requires an explicit `id`. Note: if you
13 | want to skip the 'recycle bin' for entities that support undelete (e.g.
14 | contacts) you should set `$param['skip_undelete'] => 1);`
15 |
16 | ## get
17 |
18 | Search for records
19 |
20 | ## getsingle
21 |
22 | Search for records and return the first or only match. (Note: This
23 | returns the record in a simplified format which is easy to use)
24 |
25 | ## getvalue
26 | Does a `getsingle` and returns a single value - you need to also set
27 | `$param['return'] => 'fieldname'`.
28 |
29 | ## getcount
30 | Search for records and return the quantity. (Note: In many cases in
31 | early versions queries are limited to 25 so this may not always be
32 | accurate)
33 |
34 | ## getrefcount
35 |
36 | Counts the number of references to a record
37 |
38 | ## getfields
39 |
40 | Fetch entity metadata, i.e. the list of fields supported by the entity
41 |
42 | ## getlist
43 |
44 | Used for autocomplete lookups by the
45 | [entityRef](./../../framework/quickform/entityref.md) widget
46 |
47 | ## getoptions
48 |
49 | Returns the options for a specified field e.g.
50 | ```php
51 | civicrm_api3(
52 | 'Contact',
53 | 'getoptions',
54 | array('field' => 'gender_id')
55 | );
56 | ```
57 |
58 | returns
59 |
60 | ```php
61 | array(
62 | 1 => 'Female',
63 | 2 => 'Male',
64 | 3 => 'Transgender'
65 | )
66 | ```
67 |
68 | ## replace
69 |
70 | Replace an old set of records with a new or modified set of records.
71 | (For example, replace the set of "Phone" numbers with a different set of
72 | "Phone" numbers.).
73 |
74 | Warning - REPLACE includes an implicit delete - use with care & test well
75 | before using in productions
76 |
77 | ## getunique
78 |
79 | Returns all unique fields (other than 'id' field) for a given entity.
80 | ```php
81 | civicrm_api3('Contribution', 'getunique');
82 | ```
83 |
84 | return
85 |
86 | ```php
87 | {
88 | "is_error": 0,
89 | "version": 3,
90 | "count": 2,
91 | "values": {
92 | "UI_contrib_trxn_id": [
93 | "trxn_id"
94 | ],
95 | "UI_contrib_invoice_id": [
96 | "invoice_id"
97 | ]
98 | }
99 | }
100 | ```
101 |
102 | ## setvalue
103 |
104 | **Deprecated.** Use the create action with the param 'id' instead.
105 |
106 | ## update
107 |
108 | **Deprecated.** Use the create action with the param 'id' instead.
109 |
--------------------------------------------------------------------------------
/docs/api/v3/chaining.md:
--------------------------------------------------------------------------------
1 | # APIv3 Chaining
2 |
3 | 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`.
4 |
5 | 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:
6 |
7 | - [APIChainedArray.php](https://github.com/civicrm/civicrm-core/blob/master/api/v3/examples/Contact/APIChainedArray.ex.php)
8 | - [APIChainedArrayFormats.php](https://github.com/civicrm/civicrm-core/blob/master/api/v3/examples/Contact/APIChainedArrayFormats.ex.php)
9 | - [APIChainedArrayValuesFromSiblingFunction.php](https://github.com/civicrm/civicrm-core/blob/master/api/v3/examples/Contact/APIChainedArrayValuesFromSiblingFunction.ex.php)
10 |
11 | Note that there are a few supported syntaxes:
12 |
13 | ```php
14 | civicrm_api('Contact', 'create', array(
15 | 'version' => 3,
16 | 'contact_type' => 'Individual',
17 | 'display_name' => 'BA Baracus',
18 | 'api.website.create' => array('url' => 'example.com'),
19 | ));
20 | ```
21 |
22 | is the same as
23 |
24 | ```php
25 | civicrm_api('Contact', 'create', array(
26 | 'version' => 3,
27 | 'contact_type' => 'Individual',
28 | 'display_name' => 'BA Baracus',
29 | 'api.website' => array('url' => 'example.com'),
30 | ));
31 | ```
32 |
33 | If you have 2 websites to create you can pass them as ids after the `.`
34 | or an array
35 |
36 | ```php
37 | civicrm_api('Contact', 'create', array(
38 | 'version' => 3,
39 | 'contact_type' => 'Individual',
40 | 'display_name' => 'BA Baracus',
41 | 'api.website.create' => array('url' => 'example.com'),
42 | 'api.website.create.2' => array('url' => 'example.org'),
43 | ));
44 | ```
45 |
46 | or
47 |
48 | ```php
49 | civicrm_api('Contact', 'create', array(
50 | 'version' => 3,
51 | 'contact_type' => 'Individual',
52 | 'display_name' => 'BA Baracus',
53 | 'api.website.create' => array(
54 | array('url' => 'example.com'),
55 | array('url' => 'example.org'),
56 | ),
57 | ));
58 | ```
59 |
60 | The format you use on the way in will dictate the format on the way out.
61 |
62 | Currently this supports any entity and it will convert to `entity_id` - i.e. a PledgePayment inside a contribution will receive the `contribution_id` from the outer call.
63 |
--------------------------------------------------------------------------------
/docs/api/v3/custom-data.md:
--------------------------------------------------------------------------------
1 | # APIv3 and Custom Data
2 |
3 | Custom data attached to entities is referenced by `custom_N` where `N` is the unique numerical ID for the custom data field.
4 |
5 | To set a custom field, or find entities with custom fields of a particular value, you typically use a parameter like this:
6 |
7 | ```php
8 | $params['custom_N'] = 'value';
9 | ```
10 |
11 | To return custom data for an entity, especially when using the CustomValue API, you typically pass a param like the following:
12 |
13 | ```php
14 | $params['return.custom_N'] = 1;
15 | ```
16 |
17 | *or (depending on which API entity you are querying)*
18 |
19 | ```php
20 | $params['return'] = 'custom_N';
21 | ```
22 |
23 | *or*
24 |
25 | ```php
26 | $params['return'] = 'custom_N,custom_O,custom_P';
27 | ```
28 |
29 | For setting custom date fields, (ie CustomValue create), date format is `YmdHis`, for example: `20050425000000`.
30 |
31 | 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,
32 | which vary for each API entity and function.
33 |
34 | ## Custom Value get
35 |
36 | If developers want to get all custom data related to a particular entity. The best method is to do a `CustomValue.get` API Call.
37 |
38 | ```php
39 | $result = civicrm_api3('CustomValue', 'get', array('entity_id' => 1));
40 | ```
41 |
42 | A sample output would be like the following
43 |
44 | ```php
45 | {
46 | "is_error":0,
47 | "undefined_fields":["return_child:child_name"],
48 | "version":3,
49 | "count":1,
50 | "id":2,
51 | "values":[
52 | {
53 | "entity_id":"1",
54 | "latest":"Bam Bam",
55 | "id":"2",
56 | "308":"Pebbles Flintstone",
57 | "309":"Bam Bam"
58 | }
59 | ] }
60 | ```
61 |
62 | For entities other than the Contact Entity you can use an alternate notation to the `custom_n` to specify the custom fields you wish to return. You can use `custom_group_name:custom_field_name`. Read carefully the documentation and parameters in `CustomValue.php` for more alternatives and details.
63 |
64 | !!! note
65 | When retrieving custom data for contact entity, it will only return one value in the case of a multiple custom group set whereas for other entities (e.g. Address, or using the `CustomValue.get` API) you will get all custom data records that relate to the relevant entity
66 |
67 | 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.
68 |
69 | 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
70 |
71 | ```php
72 | $result = civicrm_api3(
73 | 'Contact',
74 | 'create',
75 | array('id' = 2, 'custom_2' => array('a', 'c'))
76 | );
77 | ```
78 |
--------------------------------------------------------------------------------
/docs/api/v3/examples.md:
--------------------------------------------------------------------------------
1 | # APIv3 Examples
2 |
3 | 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.
4 |
5 | ## Location of Examples
6 |
7 | 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 `/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.
8 |
9 | ## Creating a New Example
10 |
11 | If you find that there is an API call or similar or perhaps a parameter for an API call that you feel is missing an example for that would be useful to the community, you can create a new example in the following way:
12 |
13 | 1. Find the relevant API test file e.g. `tests/phpunit/api/v3/MembershipTest.php`
14 | 2. Write your unit test with the API call that you want to create an Example of, however rather than using `$this->callAPISuccess` use `$this->callAPIAndDocument`. The Call API and Document function should be called similar to the following
15 |
16 | ```php
17 | $description = "This demonstrates setting a custom field through the API.";
18 | $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, $description);
19 | ```
20 |
21 | 3. Find in `tests/phpunit/CiviTest/CiviUnitTestCase.php` Find the function `documentMe` and comment out the if (defined) statement.
22 | 4. Run the test suite locally for that test e.g. `./tools/scripts/phpunit 'api_v3_MembershipTest'`.
23 | 5. Commit results including changes in the Examples dir and open a pull request.
24 |
--------------------------------------------------------------------------------
/docs/api/v3/joins.md:
--------------------------------------------------------------------------------
1 | # API Joins
2 |
3 | An API "get" action will typically return only the values of the entity
4 | requested. However, there are times when it is advantageous to returned
5 | data from a related entity. For instance, when querying the API for email
6 | addresses, you may want to return the name of the associated contact from the
7 | Contact entity.
8 |
9 | The CiviCRM API supports two methods of returning data from associated entities;
10 | API Joins and [APIv3 Chaining](../v3/chaining.md). API joins provide higher
11 | performance by making a single SQL query with a
12 | [SQL join](https://dev.mysql.com/doc/refman/5.7/en/join.html), and are
13 | generally preferable to API chaining where available.
14 |
15 | ## Using an API Join
16 |
17 | To use a join in an API call, specify the name of the field on which the
18 | join happens, a period, and the name of the field to reference.
19 |
20 | For instance, to search for all primary emails, returning the email and joining
21 | to also return the contact's display name:
22 | ```php
23 | $result = civicrm_api3('Email', 'get', array(
24 | 'return' => array("email", "contact_id.display_name"),
25 | 'is_primary' => 1,
26 | ));
27 | ```
28 |
29 | Alternatively, to return email addresses of everyone whose last name is Smith
30 | by joining to the Contact entity:
31 | ```php
32 | $result = civicrm_api3('Email', 'get', array(
33 | 'contact_id.last_name' => "Smith",
34 | ));
35 | ```
36 |
37 | You can join multiple times in one query. For instance, to return a list of
38 | events, displaying their name, the name of the related campaign, and that
39 | campaign's type:
40 | ```php
41 | $result = civicrm_api3('Event', 'get', array(
42 | 'return' => array("title", "campaign_id.name", "campaign_id.campaign_type_id"),
43 | ));
44 | ```
45 | !!! tip
46 | Joins are available only with the [get](../v3/actions.md#get),
47 | [getsingle](../v3/actions.md#getsingle), and [getcount](../v3/actions.md#getcount)
48 | actions.
49 |
50 | ## Identifying fields eligible for a join
51 |
52 | It is possible to join an entity to any other entity if the
53 | [xml schema](../../framework/database/schema-definition.md)
54 | identifies a [foreign key](../../framework/database/schema-definition.md#table-foreignKey) or
55 | a [pseudoconstant](../../framework/database/schema-definition.md#table-field-pseudoconstant). The [getfields](../v3/actions.md#getfields) action identifies
56 | fields that are eligible for an API join.
57 |
58 | !!! warning
59 | For historical reasons, some entities have a non-standard API in APIv3
60 | in order to handle more complicated operations. Those entities - 'Contact',
61 | 'Contribution', 'Pledge', and 'Participant' - can be joined to from another
62 | table, but you can not join to other tables from them. This limitation will
63 | be removed in APIv4.
64 |
--------------------------------------------------------------------------------
/docs/api/v4/actions.md:
--------------------------------------------------------------------------------
1 | # APIv4 Actions
2 |
3 | *Most entities support the following actions:*
4 |
5 | ## Get
6 |
7 | Search for records based on query parameters.
8 |
9 | ## Create
10 |
11 | Insert new records into the database.
12 |
13 | ## Update
14 |
15 | Update one or more records in the database based on query parameters.
16 |
17 | ## Save
18 |
19 | Create or update one or more records. Passing an `id` determines that an existing record will be updated.
20 |
21 | ## Replace
22 |
23 | Replace an existing set of records with a new or modified set of records. For example, replace a group of "Phone" numbers for a given contact.
24 |
25 | !!! warning
26 | Replace includes an implicit delete action - use with care & test well before using in production.
27 |
28 | ## Delete
29 |
30 | Delete one or more records based on query parameters.
31 |
32 | ## GetFields
33 |
34 | Fetch entity metadata, i.e. the list of fields supported by the entity. Optionally include custom fields; optionally load the option-lists for fields.
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/api/v4/chaining.md:
--------------------------------------------------------------------------------
1 | # APIv4 Chaining
2 |
3 | Chaining lets you perform multiple 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. Likewise you can ask for all activities or all contributions to be returned when you do a `get`.
4 |
5 | ## Supported Syntaxes:
6 |
7 | Object Oriented way
8 |
9 | ```php
10 | $results = \Civi\Api4\Contact::create()
11 | ->addValue('contact_id', 'Individual')
12 | ->addValue('display_name', 'BA Baracus')
13 | ->addChain('create_website', \Civi\Api4\Website::create()->setValues(['contact_id' => '$id', 'url' => 'example.com']))
14 | ->execute();
15 | ```
16 |
17 | Traditional:
18 |
19 | ```php
20 | civicrm_api('Contact', 'create', [
21 | 'version' => 4,
22 | 'values' => [
23 | 'contact_type' => 'Individual',
24 | 'display_name' => 'BA Baracus',
25 | ],
26 | 'chain' => [
27 | 'create_website', ['Website', 'create', ['values' => ['url' => 'example.com', 'contact_id' => '$id']]],
28 | ],
29 | ]);
30 | ```
31 |
32 | If you have 2 websites to create you can pass them as separate key => array pairs just specify a unique array key in the chain array.
33 |
34 | Object Oriented way
35 |
36 | ```php
37 | $results = \Civi\Api4\Contact::create()
38 | ->addValue('contact_id', 'Individual')
39 | ->addValue('display_name', 'BA Baracus')
40 | ->addChain('first_website', \Civi\Api4\Website::create()->setValues(['contact_id' => '$id', 'url' => 'example1.com']))
41 | ->addChain('second_website', \Civi\Api4\Website::create()->setValues(['contact_id' => '$id', 'url' => 'example2.com']))
42 | ->execute();
43 | ```
44 |
45 | Traditional:
46 |
47 | ```php
48 | civicrm_api('Contact', 'create', [
49 | 'version' => 4,
50 | 'values' => [
51 | 'contact_type' => 'Individual',
52 | 'display_name' => 'BA Baracus',
53 | ],
54 | 'chain' => [
55 | 'first website', ['Website', 'create', ['values' => ['url' => 'example1.com', 'contact_id' => '$id']]],
56 | 'second_website', ['Website', 'create', ['values' => ['url' => 'example2.com', 'contact_id' => '$id']]],
57 | ],
58 | ]);
59 | ```
60 |
61 | ## Back-references
62 |
63 | Note the use of '$id' in the examples above. Any field returned by the outer call can be passed down to a chained call by prefixing it with a dollar sign. Even the results of other chains can be accessed in this way.
64 |
--------------------------------------------------------------------------------
/docs/api/v4/changes.md:
--------------------------------------------------------------------------------
1 | # APIv4 Changelog
2 |
3 | *This page lists additions to the APIv4 with each new release of CiviCRM Core.*
4 |
5 | Also see: [Differences Between Api v3 and v4](../v4/differences-with-v3.md) and [Hooks Changelog](../../hooks/changes.md).
6 |
7 | ## CiviCRM 5.29
8 |
9 | ### 5.29.0
10 |
11 | Added `target_contact_id` and `assignee_contact_id` to `Activity.create` in the API explorer. Each can take an array of contact IDs. This feature existed before version 5.29.0 but was previously not discoverable in the explorer.
12 |
13 | For more information see the [commit to CiviCRM Core](https://github.com/civicrm/civicrm-core/commit/8c6a5fd64b)
14 |
15 | ## CiviCRM 5.23
16 |
17 | ### 5.23 Added PaymentProcessor and PaymentProcessorType APIv4 Entities
18 |
19 | See [CiviCRM core pull request 15624](https://github.com/civicrm/civicrm-core/pull/15624)
20 |
21 | ### 5.23 `$index` param supports array input
22 |
23 | CiviCRM 5.23 supports two new modes for the `$index` param - associative and non-associative array. See [CiviCRM Core PR #16257](https://github.com/civicrm/civicrm-core/pull/16257)
24 |
25 | ### 5.23 Converts field values to correct data type
26 |
27 | The api historically returns everything as a raw string from the query instead of converting it to the correct variable type (bool, int, float). As of CiviCRM 5.23 this is fixed for all DAO-based entities. See [CiviCRM Core PR #16274](https://github.com/civicrm/civicrm-core/pull/16274)
28 |
29 | ### 5.23 Selects only relevant contact fields by default
30 |
31 | The Contact entity in CiviCRM is divided into 3 major types: Individuals, Households and Organizations.
32 | Not all contact fields apply to all contact types, e.g. the `sic_code` field is only used by Organizations,
33 | and the `first_name` and `last_name` fields are only used by Individuals.
34 |
35 | In CiviCRM 5.23 the schema has been augmented with metadata about which fields belong to which contact type, and Api4 now uses this
36 | metadata to select only relevant fields. E.g. fetching a household with the api will not return the `first_name` or `organization_name` fields
37 | as those will always be `null`.
38 |
39 | ### 5.23 Get actions support selecting fields by * wildcard
40 |
41 | The `select` param now supports the `*` wildcard character for matching field names.
42 | See [CiviCRM Core PR #16302](https://github.com/civicrm/civicrm-core/pull/16302).
43 |
44 | ### 5.23 Delete/Update do not throw error when 0 items found
45 |
46 | For consistency across all "batch-style" actions that update/delete records based on a query,
47 | the `Delete` and `Update` actions now simply return an empty result if no matches are found to act upon.
48 | Previously they would throw an exception, which was similar to APIv3 behavior but inconsistent with other
49 | APIv4 batch actions and SQL in general. See [CiviCRM Core PR #16374](https://github.com/civicrm/civicrm-core/pull/16374).
50 |
--------------------------------------------------------------------------------
/docs/api/v4/custom-data.md:
--------------------------------------------------------------------------------
1 | # APIv4 and Custom Data
2 |
3 | CiviCRM has a flexible custom data system which allows nearly any entity to be extended. It comes in two distinct flavors: Single-record and Multi-record.
4 | For more background see the user guide chapter: [Creating Custom Fields](https://docs.civicrm.org/user/en/latest/organising-your-data/creating-custom-fields/).
5 |
6 | ## Single-Record Custom Data
7 |
8 | Because single-record fields extend an entity 1-to-1, the API treats the custom fields as an extension of the regular fields.
9 | For example, normally an Event has fields like `id`, `title`, `start_date`, `end_date`, etc.
10 | Adding a custom group named "Event_Extra" and a field named "Room_number" would be accessible from the API as "Event_Extra.Room_number".
11 | You would retrieve it and set it as if it were any other field.
12 |
13 | !!! tip
14 | The `name` of a field is not to be confused with the `label`. The API refers to custom groups/fields by name and not user-facing labels which are subject to translation and alteration.
15 |
16 | ## Multi-Record Custom Data
17 |
18 | Multiple record custom data sets are treated by the API as entities, which work similarly to other entities attached to contacts (Phone, Email, Address, etc.). For example, creating a multi-record set named "Work_History" could then be accessed via the API as an entity named "Custom_Work_History" (traditional style) or via the `CustomValue` php class (OO style). Creating a record would be done like so:
19 |
20 | **PHP (traditional):**
21 | ```php
22 | civicrm_api4('Custom_Work_History', 'create', [
23 | 'values': ['entity_id': 202, 'Test_Field': 555]
24 | ]);
25 | ```
26 | **Javascript:**
27 | ```javascript
28 | CRM.api4('Custom_Work_History', 'create', {
29 | values: {"entity_id":202, "Test_Field":555}
30 | });
31 | ```
32 |
33 | **PHP (OO):** Note that the object-oriented style uses the `CustomValue` class:
34 |
35 | ```php
36 | \Civi\Api4\CustomValue::create('Work_History')
37 | ->addValue('entity_id', 202)
38 | ->addValue('Test_Field', 555)
39 | ->execute();
40 | ```
41 |
42 | ## Field Types and I/O Formats
43 |
44 | New custom fields can be configured to store different types of data (Text, Date, Number, URL, etc.). In most cases the I/O format via the api will be a string, however there are a few exceptions:
45 |
46 | - **Date fields:** Input format is anything understood by `strtotime`, e.g. "now" or "-1 week" or "2020-12-25". Output format is the ISO string "YYYY-MM-DD HH:MM:SS".
47 | - **Checkbox/multi-select fields:** I/O format is an array of option values.
48 |
49 | ## Try It Out
50 |
51 | Once you have created some custom data in your system, look for it in the API Explorer. Single-record data will appear as fields on the entities they extend, and multi-record data will appear in the list of entities.
52 |
53 | !!! tip
54 | In the Api Explorer look for your multi-record custom entities under "C" alphabetically as they all start with the prefix "Custom_".
55 |
--------------------------------------------------------------------------------
/docs/basics/requirements.md:
--------------------------------------------------------------------------------
1 | # Development requirements
2 |
3 | ## Languages and Services
4 |
5 | * Required
6 | - Unix-like environment (Linux, OS X, or a virtual machine)
7 | - [PHP v7.0+](http://php.net/) including the following extensions: `bcmath curl gd gettext imap intl imagick json mbstring openssl pdo_mysql phar posix soap zip`
8 | - [MySQL v5.7.5+](http://mysql.com/) or [MariaDB 10.0.2+](https://mariadb.org/), including both client and server
9 | - [NodeJS v8+](https://nodejs.org/)
10 | - [Git](https://git-scm.com/)
11 | * Recommended (for `civibuild` / `amp`):
12 | - Apache HTTPD v2.2 or v2.4 including the `mod_rewrite` module and, on SUSE, possibly `mod_access_compat` (This list may not be exhaustive.)
13 |
14 | ## Command Line
15 |
16 | There are many ways to install MySQL, PHP, and other dependencies -- for example, `apt-get` and `yum` can download packages automatically; `php.net` and `mysql.com` provide standalone installers; and MAMP/XAMPP provide bundled installers.
17 |
18 | Civi development should work with most packages -- with a priviso: ***the command-line must support standard command names*** (eg `git`, `php`, `node`, `mysql`, `mysqldump`, etc).
19 |
20 | Some environments (e.g. most Linux distributions) are configured properly out-of-the-box. Other environments (e.g. MAMP and XAMPP) may require configuring the `PATH`.
21 |
22 |
23 |
24 | ## Buildkit
25 |
26 | The developer docs reference a large number of developer tools, such as `drush` (the Drupal command line), `civix` (the CiviCRM code-generator), and `karma` (the Javascript tester).
27 |
28 | Many of these tools are commonly used by web developers, so you may have already installed a few. You could install all the tools individually -- but that takes a lot of work.
29 |
30 | [civicrm-buildkit](../tools/buildkit.md) provides a script which downloads the full collection.
31 |
--------------------------------------------------------------------------------
/docs/core/hacking.md:
--------------------------------------------------------------------------------
1 | ## When should I edit core CiviCRM?
2 |
3 | !!! danger
4 | Most of the time, editing the core codebase directly is not the recommended way for developers to customise and extend CiviCRM. CiviCRM has multiple releases per year so direct edits to the core codebase will create upgrade issues for you. There are other recommended ways for the majority of scenarios: extensions, the APIs, and hooks.
5 |
6 | To help you decide, here are a couple of principles:
7 |
8 | - Bug fixes should always be applied to core. See [Contributing to Core](contributing.md) for details.
9 | - Some (but not all) enhancements to existing features may be best applied to core, especially if they would be useful to others.
10 | - New features should generally be packed as [Extensions](../extensions/index.md).
11 | - If you aren't familiar with CiviCRM, by far the best way to get a sense if you should be editing core is by [talking with the CiviCRM developer community](../basics/community.md#collaboration-tools).
12 |
--------------------------------------------------------------------------------
/docs/extensions/cms-specific.md:
--------------------------------------------------------------------------------
1 | # CMS-specific extensions development
2 |
3 | When developing a native CiviCRM extension, sometimes you want to provide extra functionality for specific CMS platforms. This page provides instructions for doing so, where available.
4 |
5 | ## WordPress
6 |
7 | ### Shortcodes
8 |
9 | Here's an example of a WordPress shortcode:
10 |
11 | ```text
12 | [civicrm component="contribution" id="2" mode="live" discount="pkpwpabs7" hijack="0"]
13 | ```
14 |
15 | Here's some code that an extension can use to receive data from the custom shortcode attribute and act on it:
16 |
17 | ```php
18 | if ( function_exists( 'add_filter' ) ) {
19 | add_filter( 'civicrm_shortcode_preprocess_atts', 'extensionprefix_amend_args', 10, 2 );
20 | add_filter( 'civicrm_shortcode_get_data', 'extensionprefix_amend_data', 10, 3 );
21 | }
22 |
23 | /**
24 | * Filter the CiviCRM shortcode arguments.
25 | *
26 | * Modify the attributes that the 'civicrm' shortcode allows. The attributes
27 | * that are injected (and their values) will become available in the $_REQUEST
28 | * and $_GET arrays.
29 | *
30 | * @param array $args Existing shortcode arguments
31 | * @param array $shortcode_atts Shortcode attributes
32 | * @return array $args Modified shortcode arguments
33 | */
34 | function extensionprefix_amend_args( $args, $shortcode_atts ) {
35 |
36 | // our custom attribute name & default
37 | $name = 'discount';
38 | $default = 'foo';
39 |
40 | // add either passed value or default
41 | if ( array_key_exists($name, $shortcode_atts) ) {
42 | $args[$name] = $shortcode_atts[$name];
43 | } else {
44 | $args[$name] = $default;
45 | }
46 |
47 | return $args;
48 |
49 | }
50 |
51 | /**
52 | * Filter the CiviCRM shortcode data array.
53 | *
54 | * Let's add some arbitrary text to the pre-rendered shortcode's description to
55 | * indicate that this extension has something to say.
56 | *
57 | * @param array $data Existing shortcode data
58 | * @param array $atts Shortcode attributes array
59 | * @param array $args Shortcode arguments array
60 | * @return array $data Modified shortcode data
61 | */
62 | function extensionprefix_amend_data( $data, $atts, $args ) {
63 |
64 | // our custom attribute name
65 | $name = 'discount';
66 |
67 | // add some arbitrary text to pre-rendered shortcode
68 | if ( array_key_exists($name, $atts) ) {
69 | $data['text'] .= ' ' . ts('Discount code: ') . $atts[$name];
70 | }
71 |
72 | return $data;
73 |
74 | }
75 | ```
76 |
77 | In addition, more sophisticated plugins and extensions can also filter the parameters passed the the CiviCRM API when there are multiple shortcodes present. This would allow them to retrieve additional (or alternative) data for display in the pre-rendered shortcode.
78 |
--------------------------------------------------------------------------------
/docs/extensions/troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | If you are struggling, the best thing to do is reach out to the [CiviCRM community](../basics/community.md).
4 |
5 | If you cannot find the answer in this guide or by searching in the [CiviCRM StackExchange site](http://civicrm.stackexchange.com/) then please [ask](http://civicrm.stackexchange.com/questions/ask). Asking questions on StackExchange not only helps you but may well help others who follow you.
6 |
7 | That said, this is a small list of some of the commoner problems extension writers encounter.
8 |
9 | ## Extension not doing anything
10 |
11 |
12 |
13 | Q: I've created the files and edited them but I don't see the expected changes.
14 |
15 | A: Did you install and enable your extension? (/civicrm/admin/extensions?reset=1)
16 |
17 | ## Civix error messages
18 |
19 | Q: I get Error: "Cannot instantiate API client -- please set connection options in parameters.yml"
20 |
21 | A: You might have missed the step about setting 'civicrm\_api3\_conf\_path' ([https://github.com/totten/civix/](https://github.com/totten/civix/)), or it didn't get set properly for some reason.
22 |
23 | Q: I've tried to generate a page/report/search/upgrader/etc with civix but it's not working.
24 |
25 | A: For all of the various types, you must first run [generate:module](civix.md#generate-module), and then \`cd\` into the folder (e.g. com.example.myextension) before running one of the other \`generate:\` commands.
26 |
27 | ## Out-of-date templates
28 |
29 | Many of the generators in `civix` rely on helpers and stubs defined in `.php` or `.civix.php`. If you
30 | run `civix generate:*` on an older extension and have trouble with the generated code, then review [UPGRADE.md](https://github.com/totten/civix/blob/master/UPGRADE.md)
31 | for (a) general upgrade procedures and (b) a list of specific changes that could require manual attention.
32 |
--------------------------------------------------------------------------------
/docs/financial/overview.md:
--------------------------------------------------------------------------------
1 | !!! abstract
2 | This area of CiviCRM code and documentation is a work-in-progress. Not all features
3 | will be documented and the core code underlying this area may change from version
4 | to version.
5 |
6 | The financial subsystem in civicrm encompasses:
7 |
8 | - contributions
9 | - recurring contributions
10 | - payments
11 | - refunds
12 | - prices
13 | - discounts
14 | - premiums (things given away to contacts who donate a lot)
15 | - accounting information
16 | - integrations with payment processors
17 | - integrations with accounting systems
18 |
19 | There are strong relationships between the financial area of CiviCRM and memberships, event registrations, and pledges.
20 |
21 | Due to the importance of data integrity, the tight coupling of related business operations, and large number of tables in the implementation, there is a strong focus on using higher level business APIs rather than lower level table oriented operations.
22 |
23 | Key concepts include:
24 |
25 | - order (sometimes called invoice)
26 | - line item
27 | - bookkeeping entries which encompass at a minimum a debit and credit financial account, an amount and a date
28 | - financial account, which corresponds to an account in a financial system's (like QuickBooks) chart of accounts
29 | - financial type, which organisations can use to categorise their contributions (like "Donation") for their own management purposes (e.g. "Donation for X"), accounting purposes (which financial accounts are used) and regulartory requirements (e.g. to identify taxable contributions)
30 |
31 | The main purpose of this documentation is to support
32 |
33 | - non-core systems for creating orders, eg a Drupal webform or WordPress Caldera Forms replacement of CiviCRM Contribution and Event Pages.
34 | - payment processor integrations in all of their variety.
35 |
--------------------------------------------------------------------------------
/docs/financial/paymentAPI.md:
--------------------------------------------------------------------------------
1 | !!! abstract
2 | This area of CiviCRM code and documentation is a work-in-progress. Not all features
3 | will be documented and the core code underlying this area may change from version
4 | to version.
5 |
6 | ## Payment API
7 |
8 | Historically, one recorded a payment against a contribution by changing its payment status, for example from Pending to Completed.
9 |
10 | It is now best practice to use the Payment.create API call.
11 |
12 | Note that paymentprocessor.pay handles the communication with a payment processor to instigate a payment. Similarly, paymentprocessor.refund handles the communication with a payment processor to instigate a refund.
13 |
14 | After a contribution has been created, for example using the best practice Order.create API call, use the Payment.create API action to
15 |
16 | * record a payment against the contribution - either fully or partially paying the contribution amount
17 | * record a refund against the contribution
18 |
19 | Use the Payment.cancel api to reverse a refunded payment.
20 |
21 |
--------------------------------------------------------------------------------
/docs/framework/angular/changeset.md:
--------------------------------------------------------------------------------
1 | # AngularJS: Changesets
2 |
3 | !!! caution "Work in progress"
4 |
5 | This documentation is still a work in progress.
6 |
7 | The [Quick Start](quickstart.md) and [Loader](loader.md) provide examples of
8 | creating *new* screens. But what if you need to alter an *existing* screen?
9 | CiviCRM allows third-parties to define *changesets* which programmatically
10 | manipulate Angular content before sending it to the client.
11 |
12 | ## Background
13 |
14 | Most AngularJS tutorials focus on idealized projects where a single
15 | developer or product-owner exercises full authority over their application.
16 | But CiviCRM is an _ecosystem_ with a range of stakeholders, including many
17 | developers (authoring indpendent extensions) and administrators (managing
18 | independent deployments with independent configurations).
19 |
20 | ...
21 |
22 | ## Hooks
23 |
24 | * **[hook_civicrm_alterAngular](../../hooks/hook_civicrm_alterAngular.md)** - Alter the definition of some Angular HTML partials.
25 |
26 | ## Example
27 |
28 | ```php
29 | function mailwords_civicrm_alterAngular(\Civi\Angular\Manager $angular) {
30 | $changeSet = \Civi\Angular\ChangeSet::create('inject_mailwords')
31 | // ->requires('crmMailing', 'mailwords')
32 | ->alterHtml('~/crmMailing/BlockSummary.html',
33 | function (phpQueryObject $doc) {
34 | $doc->find('.crm-group')->append('
35 |
36 |
37 |
38 | ');
39 | });
40 | $angular->add($changeSet);
41 | }
42 | ```
43 |
44 | ```
45 | cv ang:html:list
46 | cv ang:html:show
47 | cv ang:html:show --diff
48 | ```
49 |
--------------------------------------------------------------------------------
/docs/framework/setup/index.md:
--------------------------------------------------------------------------------
1 | !!! note "Status of `install` and `setup` subsystems"
2 |
3 | The CiviCRM `setup` subsystem is a refactored/rewritten version of the older `install` subsystem.
4 | There is a Gitlab issue for [tracking the migration from `install` to `setup`](https://lab.civicrm.org/dev/core/issues/1615).
5 |
6 | The CiviCRM `setup` subsystem facilitates installation and configuration. It aims to support multiple installers, such
7 | as a generic CLI (`cv core:install` and `cv core:uninstall`), a generic web-based installer, and specialized/scripted installers
8 | for different environments and use-cases.
9 |
10 | Key features:
11 |
12 | * The subsystem can be used by other projects -- such as `cv`, `civicrm-drupal`, `civicrm-wordpress` -- to provide an installation process.
13 | * It is a *leap*. It can coexist with the old installer.
14 | * _Example_: The `civicrm-wordpress` integration is phasing-in support for the new installer. By default, it uses the old installer. If you create a file `civicrm/.use-civicrm-setup`, then it will use the new installer.
15 | * It has minimal external dependencies. (The codebase for CiviCRM and its dependencies must be available -- but nothing else is needed.)
16 |
17 | General design:
18 |
19 | * Installers call a high-level API ([Civi\Setup](https://github.com/civicrm/civicrm-core/tree/master/setup/src/Setup.php)) which supports all major installation tasks/activities -- such as:
20 | * Check system requirements (`$setup->checkRequirements()`)
21 | * Check installation status (`$setup->checkInstalled()`)
22 | * Install data files (`$setup->installFiles()`)
23 | * Install database (`$setup->installDatabase()`)
24 | * A *data-model* ([Civi\Setup\Model](https://github.com/civicrm/civicrm-core/tree/master/setup/src/Setup/Model.php)) lists all the standard configuration parameters. This data-model is available when executing each task. For example, it includes:
25 | * The path to CiviCRM's code (`$model->srcPath`)
26 | * The system language (`$model->lang`)
27 | * The DB credentials (`$model->db`)
28 | * Each major task corresponds to an [*event*](https://github.com/civicrm/civicrm-core/tree/master/setup/src/Setup/Event) -- such as:
29 | * `civi.setup.checkRequirements`
30 | * `civi.setup.checkInstalled`
31 | * `civi.setup.installFiles`
32 | * `civi.setup.installDatabase`
33 | * *Plugins* (`plugins/*/*.civi-setup.php`) work with the model and the events. For example:
34 | * The plugin `init/WordPress.civi-setup.php` runs during initialization (`civi.setup.init`). It reads the WordPress config (e.g.`get_locale()` and `DB_HOST`) then updates the model (`$model->lang` and `$model->db`).
35 | * The plugin `installDatabase/SetLanguage.civi-setup.php` runs when installing the database (`civi.setup.installDatabase`). It reads the `$model->lang` and updates various Civi settings.
36 |
37 |
--------------------------------------------------------------------------------
/docs/framework/setup/plugins.md:
--------------------------------------------------------------------------------
1 | Plugins in `civicrm/setup/plugins/*/*.civi-setup.php` are automatically
2 | detected and loaded. The simplest way to manage plugins is adding and
3 | removing files from this folder.
4 |
5 | However, you may find it useful to manage plugins programmatically. For
6 | example, the `civicrm-drupal` integration or the `civicrm-wordpress`
7 | integration might refine the installation process by:
8 |
9 | * Adding a new plugin
10 | * Removing a default plugin
11 |
12 | To programmatically manage plugins, take note of the
13 | `\Civi\Setup::init(...)` function. It accepts an argument,
14 | `$pluginCallback`, which can edit the plugin list.
15 |
16 | For example, this would add a custom plugin named `ExtraJoompralInstallPlugin`:
17 |
18 | ```php
19 | plugins_dir, __DIR__ . '/relative/path/to/custom/plugin/directory');
19 | }
20 | ```
21 |
22 | Then in that custom plugin directory, you can place whatever Smarty
23 | plugins you need.
24 |
25 | You can also use this trick to change other Smarty behavior, such as
26 | whether it can evaluate PHP placed directly in templates. For instance:
27 |
28 | ```php
29 | function yourmodule_civicrm_config(&$config) {
30 | $smarty = CRM_Core_Smarty::singleton();
31 |
32 | // allow the explode() php function to be used as a "modifier" in Smarty templates
33 | array_push($smarty->security_settings['MODIFIER_FUNCS'], 'explode');
34 | }
35 | ```
36 |
37 | However, be very careful with these settings – if you don't know what
38 | you're doing, you can open security holes or create a mess of code
39 | that's difficult to maintain.
40 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_aclGroup.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_aclGroup
2 |
3 | ## Summary
4 |
5 | This hook is called when composing the ACL to restrict access to civicrm
6 | entities (civicrm groups, profiles and events).
7 |
8 | ## Notes
9 |
10 | In order to use this hook you must uncheck "View All Contacts" AND "Edit All Contacts"
11 | in Drupal Permissions for the user role you want to limit. You can then
12 | go into CiviCRM and grant permission to Edit or View "All Contacts" or
13 | "Certain Groups". See the Forum Topic at:
14 | [http://forum.civicrm.org/index.php/topic,14595.0.html](http://forum.civicrm.org/index.php/topic,14595.0.html)
15 | for more information.
16 |
17 | ## Definition
18 |
19 | hook_civicrm_aclGroup( $type, $contactID, $tableName, &$allGroups, &$currentGroups )
20 |
21 | ## Parameters
22 |
23 | - $type the type of permission needed
24 | - $contactID the contactID for whom the check is made
25 | - $tableName the tableName which is being permissioned
26 | - $allGroups the set of all the objects for the above table
27 | - $currentGroups the set of objects that are currently permissioned
28 | for this contact . This array will be modified by the hook
29 |
30 | ## Returns
31 |
32 | - null - the return value is ignored
33 |
34 | ## Example
35 |
36 | Check [HRD Module](http://svn.civicrm.org/hrd/trunk/drupal/hrd.module)
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_activeTheme.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_activeTheme
2 |
3 | ## Summary
4 |
5 | The activeTheme hook determines which theme is active.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_activeTheme( &$theme, $context)
10 |
11 | ## Parameters
12 |
13 | - parameter string $theme
14 | The identifier for the theme. Alterable.
15 | Ex: 'greenwich'.
16 | - parameter array $context
17 | Information about the current page-request. Includes some mix of:
18 | - page: the relative path of the current Civi page (Ex: 'civicrm/dashboard').
19 | - themes: an instance of the Civi\Core\Themes service.
20 |
21 | ## Returns
22 |
23 | - null
24 |
25 | ## Availability
26 |
27 | - This hook was first available in CiviCRM 5.16
28 |
29 | ## Example
30 |
31 | ```php
32 | /*
33 | * Set which theme is active.
34 | */
35 |
36 | function civitest_civicrm_activeTheme( &$theme, $context ) {
37 | $theme = 'civielection';
38 | }
39 | ```
40 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterAPIPermissions.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterAPIPermissions
2 |
3 | ## Summary
4 |
5 | This hook is called when API 3 permissions are checked.
6 |
7 | ## Notes
8 |
9 | This hook can alter the `$permissions` structure from `CRM/Core/DAO/permissions.php` (as well as the API `$params` array) based on the `$entity` and `$action` (or unconditionally).
10 |
11 | !!! Note
12 | If a given entity/action permissions are unset, the default
13 | "administer CiviCRM" permission is enforced.
14 |
15 |
16 | ## Definition
17 |
18 | ```php
19 | hook_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions)
20 | ```
21 |
22 | ## Parameters
23 |
24 | - string `$entity` - the API entity (like contact)
25 | - string `$action` - the API action (like get)
26 | - array `&$params` - the API parameters
27 | - array `&$permisisons` - the associative permissions array (probably to
28 | be altered by this hook)
29 | - Note: the entity in `$permissions` array use the camel case
30 | syntax (e.g. `$permissions['option_group']['get'] = ...` and not
31 | `$permissions['OptionGroup']['get'] = ...`)
32 |
33 | ## Returns
34 |
35 | - null
36 |
37 | ## Availability
38 |
39 | - This hook was first available in CiviCRM 3.4.1
40 |
41 | ## Example
42 |
43 | The `alterAPIPermissions` function is prefixed with the full extension name, all lowercase,
44 | followed by `_civicrm_alterAPIPermissions`. For an extension "CiviTest" the hook
45 | would be placed in the `civitest.php` file and might look like:
46 |
47 | ```php
48 | function civitest_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions)
49 | {
50 | // skip permission checks for contact/create calls
51 | // (but keep the ones for email, address, etc./create calls)
52 | // note: unsetting the below would require the default ‘access CiviCRM’ permission
53 | $permissions['contact']['create'] = array();
54 |
55 | // enforce ‘view all contacts’ check for contact/get, but do not test ‘access CiviCRM’
56 | $permissions['contact']['get'] = array('view all contacts');
57 |
58 | // add a new permission requirement for your own custom API call
59 | // (if all you want to enforce is ‘access CiviCRM’ you can skip the below altogether)
60 | $permissions['foo']['get'] = array('access CiviCRM', 'get all foos');
61 |
62 | // allow everyone to get info for a given event; also – another way to skip permissions
63 | if ($entity == 'event' and $action == 'get' and $params['title'] == 'CiviCon 2038') {
64 | $params['check_permissions'] = false;
65 | }
66 | }
67 | ```
68 |
69 | The API function for the "get" action for the new custom API entity called "Foo" would be
70 | `function civicrm_api3_foo_get();`.
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterAdminPanel.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterAdminPanel
2 |
3 | ## Summary
4 |
5 | This hook is invoked after all the panels and items on Administer CiviCRM screen have been
6 | generated and allows for direct manipulation of these items and panels.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_alterAdminPanel(&adminPanel)
11 |
12 | ## Parameters
13 |
14 | - array adminPanel - array of panels on Adminster CiviCRM screen
15 |
16 | ## Returns
17 |
18 | ## Example
19 |
20 | /**
21 | * Alter panels on administer CiviCRM screen
22 | */
23 | function example_civicrm_alterAdminPanel(&$adminPanel) {
24 | // don't want to show Multi Site Settings to users as a configuration option
25 | unset($adminPanel['System_Settings']['fields']['weight}.Multi Site Settings']);
26 | }
27 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterAngular.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterAngular
2 |
3 | ## Summary
4 |
5 | This hook alters the definition of some AngularJS HTML partials and allows you to inject [AngularJS changesets](../framework/angular/changeset.md).
6 |
7 | ## Availability
8 |
9 | This hook is available in CiviCRM 4.7.21 and later.
10 |
11 | ## Definition
12 |
13 | hook_civicrm_alterAngular(&$angular)
14 |
15 | ## Parameters
16 |
17 | - array `$angular` - `\Civi\Angular\Manager`
18 |
19 | ## Example
20 |
21 | ```php
22 | function example_civicrm_alterAngular($angular) {
23 | $angular->add(\Civi\Angular\ChangeSet::create('mychanges')
24 | ->alterHtml('~/crmMailing/EditMailingCtrl/2step.html', function(phpQueryObject $doc) {
25 | $doc->find('[ng-form="crmMailingSubform"]')->attr('cat-stevens', 'ts(\'wild world\')');
26 | })
27 | );
28 | }
29 | ```
30 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterBadge.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterBadge
2 |
3 | ## Summary
4 |
5 | This hook allows you to modify the content and format of name badges.
6 |
7 | ## Availability
8 |
9 | Available in 4.5+.
10 |
11 | ## Definition
12 |
13 | hook_civicrm_alterBadge($labelName, &$label, &$format, &$participant);
14 |
15 | ## Parameters
16 |
17 | - $labelName - a string containing the name of the Badge format
18 | being used
19 | - $label - the CRM_Badge_BAO_Badge object, contains
20 | $label->pdf object
21 | - $format - the $formattedRow array used to create the
22 | badges--contains information like font and positioning
23 | - there is one entry for each element (6 in total, as you can see
24 | here /civicrm/admin/badgelayout?action=update&id=1&reset=1) with
25 | array of values for each element. Each array has the following
26 | keys: token, value, text_alignment, font_style (bold, italic,
27 | normal), font_size, font_name (the options for each key are
28 | the options that are available on this screen:
29 | civicrm/admin/badgelayout?action=update&id=1&reset=1), for
30 | example:
31 |
32 | \
33 | token => {participant.participant_role}
34 |
35 | text_alignment => C
36 |
37 | font_style => bold
38 |
39 | font_size => 20
40 |
41 | font_name => courier
42 |
43 | value => Staff
44 |
45 |
46 |
47 | - $participant - array of token values for participant that will
48 | be displayed on badge, includes contact_id
49 |
50 | ## Returns
51 |
52 | ## Example
53 |
54 |
55 |
56 | function hook_civicrm_alterBadge($labelName, &$label, &$format, &$participant) {
57 | if ($labelName == 'My Custom Badge') {
58 | // change the font size for contact_id=12
59 | if ($participant['contact_id']==12){
60 | foreach ($format['token'] as $valueFormat){
61 | $valueFormat['font_size'] = 10;
62 | }
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterBarcode.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterBarcode
2 |
3 | ## Summary
4 |
5 | This hook allows you to modify the content that is encoded in barcode.
6 |
7 | ## Availability
8 |
9 | Available in 4.4+.
10 |
11 | ## Definition
12 |
13 | hook_civicrm_alterBarcode( &$data, $type='barcode', $context='name_badge' );
14 |
15 | ## Parameters
16 |
17 | - $data - is an associated array with all token values and some
18 | additional info
19 | - $data['current_value'] - this will hold default value set by
20 | CiviCRM
21 | - $type - type of barcode ( barcode or qrcode )
22 | - $context - currently this functionality is implemented only for
23 | name badges, hence context=name_badge
24 |
25 | ## Returns
26 |
27 | ## Example
28 |
29 | function hook_civicrm_alterBarcode(&$data, $type, $context ) {
30 | if ($type == 'barcode' && $context == 'name_badge') {
31 | // change the encoding of barcode
32 | $data['current_value'] = $data['event_id'] . '-' . $data['participant_id'] . '-' . $data['contact_id'];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterCalculatedMembershipStatus.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterCalculatedMembershipStatus
2 |
3 | ## Summary
4 |
5 | This hook is called when calculating the membership status.
6 |
7 | ## Notes
8 |
9 | Examples of when this hook is called include:
10 |
11 | * on a form
12 | * in the cron job that rolls over statuses
13 |
14 | ## Definition
15 |
16 | hook_civicrm_alterCalculatedMembershipStatus(&$membershipStatus, $arguments, $membership)
17 |
18 | ## Parameters
19 |
20 | * $membershipStatus the calculated membership status array
21 | * $arguments arguments used in the calculation
22 | * $membership the membership array from the calling function
23 |
24 | ## Added
25 |
26 | 4.5., 4.4.10
27 |
28 | ## Notes
29 |
30 | Although the membership array is passed through to the hooks no work has
31 | gone into ensuring the consistency of the data in the membership array
32 | so far - it was added to the parameters on the basis that it was easy to
33 | think of a use case (e.g requiring approval) but not tested against a
34 | current use case
35 |
36 | ## Examples
37 |
38 | Extend Grace period to one year for membership types 14, 15 & 16
39 |
40 | /**
41 |
42 | * Implementation of hook_civicrm_alterCalculatedMembershipStatus
43 |
44 | * Set membership status according to membership type
45 |
46 | * @param array $membershipStatus the calculated membership status array
47 |
48 | * @param array $arguments arguments used in the calculation
49 |
50 | * @param array $membership the membership array from the calling function
51 |
52 | */
53 |
54 | function membershipstatus_civicrm_alterCalculatedMembershipStatus(&$membershipStatus, $arguments, $membership) {
55 |
56 | //currently we are hardcoding a rule for membership type ids 14, 15, & 16
57 |
58 | if(empty($arguments['membership_type_id']) || !in_array($arguments['membership_type_id'], array(14, 15, 16))) {
59 |
60 | return;
61 |
62 | }
63 |
64 | $statusDate = strtotime($arguments['status_date']);
65 |
66 | $endDate = strtotime($arguments['end_date']);
67 |
68 | $graceEndDate = strtotime('+ 12 months', $endDate);
69 |
70 | if($statusDate > $endDate && $statusDate <= $graceEndDate) {
71 |
72 | $membershipStatus['name'] = 'Grace';
73 |
74 | $membershipStatus['id'] = 8;
75 |
76 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterContent.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterContent
2 |
3 | ## Summary
4 |
5 | This hook is invoked after all the content of a CiviCRM form or page is
6 | generated and allows for direct manipulation of the generated content.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_alterContent( &$content, $context, $tplName, &$object )
11 |
12 | ## Parameters
13 |
14 | - string $content - previously generated content
15 | - string $context - context of content - page or form
16 | - string $tplName - the file name of the tpl
17 | - object $object - a reference to the page or form object
18 |
19 | ## Returns
20 |
21 | ## Example
22 |
23 | /**
24 | * Alter fields for an event registration to make them into a demo form.
25 | */
26 | function example_civicrm_alterContent( &$content, $context, $tplName, &$object ) {
27 | if($context == "form") {
28 | if($tplName == "CRM/Event/Form/Registration/Register.tpl") {
29 | if($object->_eventId == 1) {
30 | $content = "
Below is an example of an event registration.
".$content;
31 | $content = str_replace("Above is an example of an event registration
";
34 | }
35 | }
36 | }
37 | }
38 |
39 | !!! tip
40 | While this hook is included in the Form related hooks section it can be used to alter almost all generated content.
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterCustomFieldDisplayValue.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterCustomFieldDisplayValue
2 |
3 | ## Summary
4 |
5 | This hook allows modification of custom field value for an entity eg Individual, Contribution etc before its displayed on screen. This might be useful if you want to alter the value of the custom field that's being displayed on the screen based on some condition.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_alterCustomFieldDisplayValue(&$displayValue, $value, $entityId, $fieldInfo) {
10 |
11 | ## Parameters
12 |
13 | - $displayValue - String that will be displayed on screen.
14 | - $value - Value from the database for the entity id.
15 | - $entityId - Entity Id.
16 | - $fieldInfo - Array having details of custom field like name, label, custom_group_id etc.
17 |
18 | ## Returns
19 |
20 | - null
21 |
22 | ## Example
23 |
24 | ```php
25 | /**
26 | * Implementation of hook_civicrm_alterCustomFieldDisplayValue
27 | */
28 | function extension_civicrm_alterCustomFieldDisplayValue(&$displayValue, $value, $entityId, $fieldInfo) {
29 | if ($fieldInfo['name'] == 'alter_cf_field') {
30 | $displayValue = 'New value';
31 | }
32 | }
33 | ```
34 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterEntityRefParams.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterEntityRefParams
2 |
3 | ## Summary
4 |
5 | This hook is called when an `entityRef` field is rendered in a form, which allows you to modify the parameters used to fetch options for this kind of field.
6 |
7 | ## Availability
8 |
9 | This hook is available in CiviCRM 4.7.28 and later.
10 |
11 | ## Definition
12 |
13 | hook_civicrm_alterEntityRefParams(&$params, $formName)
14 |
15 | ## Parameters
16 |
17 | - array `$params` - parameters of entityRef field
18 | - string `$formName` - form name
19 |
20 | ## Example
21 |
22 | ```php
23 | function myextension_civicrm_alterEntityRefParams(&$params, $formName) {
24 | // use your custom API to fetch tags of your choice on specific form say on 'New Individual'
25 | if ($formName == 'CRM_Contact_Form_Contact' && $params['entity'] == 'tag') {
26 | $params['entity'] = 'my_tags';
27 | $params['api'] = array('params' => array('parent_id' => 292));
28 | }
29 | // ...
30 | }
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterLocationMergeData.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterLocationMergeData
2 |
3 | ## Summary
4 |
5 | This hook allows you to alter the location information that will be moved from
6 | the duplicate contact to the master contact.
7 |
8 | ## Availability
9 |
10 | This hook was first available in CiviCRM 4.7.10.
11 |
12 | ## Definition
13 |
14 | ```php
15 | hook_civicrm_alterLocationMergeData(&$blocksDAO, $mainId, $otherId, $migrationInfo)
16 | ```
17 |
18 | ## Parameters
19 |
20 | * array `$blocksDAO`: Array of location DAO objects. Formatted as follows:
21 |
22 | ```php
23 | [
24 | 'email' => [
25 | 'delete' => ['id' => object],
26 | 'update' => ['id' => object],
27 | ],
28 | 'address' => [
29 | 'delete' => ['id' => object],
30 | 'update' => ['id' => object],
31 | ],
32 | ]
33 | ```
34 |
35 | * int `$mainId`: Contact ID of the contact that survives the merge.
36 | * int `$otherId`: Contact ID of the contact that will be absorbed and deleted.
37 | * array `$migrationInfo`: Calculated migration info.
38 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterLogTables.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterLogTables
2 |
3 | ## Summary
4 |
5 | This hook allows you to amend the specification of the log tables to be
6 | created when logging is turned on.
7 |
8 | ## Notes
9 |
10 | You can adjust the specified tables and the engine and define indexes and exceptions. Note that CiviCRM creates log tables according to the specification at the point of creation. It does not update them if you change the specification, except with regards to adding additional tables. Tables are never automatically dropped.
11 |
12 | Turning logging on and off will cause any adjustments to the exceptions to be enacted as that information is in the triggers not the log tables, which are recreated.
13 |
14 | There is, however, a function that will convert log tables from Archive to INNODB (one way) if the hook is in play. This has to be done deliberately by calling the `system.updatelogtables` api and it can be a slow process.
15 |
16 | ## Availability
17 |
18 | This hook was first available in CiviCRM 4.7.7.
19 |
20 | ## Definition
21 |
22 | hook_civicrm_alterLogTables(&$logTableSpec)
23 |
24 | ## Parameters
25 |
26 | - @param array $logTableSpec
27 |
28 | ## Example
29 |
30 | This defines all tables as INNODB and adds indexes.
31 |
32 | https://github.com/eileenmcnaughton/nz.co.fuzion.innodbtriggers
33 |
34 | /**
35 | * Implements hook_alterLogTables().
36 | *
37 | * @param array $logTableSpec
38 | */
39 | function innodbtriggers_civicrm_alterLogTables(&$logTableSpec) {
40 | $contactReferences = CRM_Dedupe_Merger::cidRefs();
41 | foreach (array_keys($logTableSpec) as $tableName) {
42 | $contactIndexes = array();
43 | $logTableSpec[$tableName]['engine'] = 'INNODB';
44 | $logTableSpec[$tableName]['engine_config'] = 'ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4';
45 | $contactRefsForTable = CRM_Utils_Array::value($tableName, $contactReferences, array());
46 | foreach ($contactRefsForTable as $fieldName) {
47 | $contactIndexes['index_' . $fieldName] = $fieldName;
48 | }
49 | $logTableSpec[$tableName]['indexes'] = array_merge(array(
50 | 'index_id' => 'id',
51 | 'index_log_conn_id' => 'log_conn_id',
52 | 'index_log_date' => 'log_date',
53 | ), $contactIndexes);
54 | }
55 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterMailContent.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterMailContent
2 |
3 | ## Summary
4 |
5 | This hook is called after getting the content of the mail and before
6 | tokenizing it.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_alterMailContent(&$content)
11 |
12 | ## Parameters
13 |
14 | - $content - fields that include the content of the mail
15 |
16 | ## Details
17 |
18 | $content - fields include: html, text, subject, groupName, valueName, messageTemplateID, mailingID, campaign_id, template_type.
19 | Note that this hook is fired when:
20 |
21 | * creating mailings through the traditional BAO mailer (standard CiviMail)
22 | * creating mailings through FlexMailer (used by Mosaico)
23 | * sending emails using message templates, in CRM_Core_BAO_MessageTemplate
24 |
25 | In the latter case there is inherently no mailingID or template_type, so these will not be supplied. Similarly in the 2 former cases the messageTemplateID is not supplied.
26 |
27 | ## Example
28 |
29 | ```php
30 | /**
31 | * Implement hook_civicrm_alterMailContent
32 | *
33 | * Replace invoice template with custom content from file
34 | */
35 | function mail_civicrm_alterMailContent(&$content) {
36 | if (CRM_Utils_Array::value('valueName', $content) == 'contribution_invoice_receipt') {
37 | $path = CRM_Core_Resources::singleton()->getPath('org.myorg.invoice');
38 | $html = file_get_contents($path.'/msg/contribution_invoice_receipt.html.tpl');
39 | $content['html'] = $html;
40 | }
41 | }
42 | ```
43 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterMailParams.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterMailParams
2 |
3 | ## Summary
4 |
5 | This hook is called when an email is being prepared for sending by CiviCRM.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_alterMailParams(&$params, $context)
10 |
11 | ## Parameters
12 |
13 | - $params - the mailing params array
14 | - $context - the contexts of the hook call are:
15 | - "civimail" for when sending an email using CiviMail,
16 | - "flexmailer" for when sending an email using CiviMail and
17 | [FlexMailer](https://civicrm.org/extensions/flexmailer)
18 | (e.g. for Mosaico),
19 | - "singleEmail" for when sending a single email,
20 | - "messageTemplate" for when sending an email using a message
21 | template
22 |
23 | ## Details
24 |
25 | - $params array fields include: groupName, from, toName, toEmail,
26 | subject, cc, bcc, text, html, returnPath, replyTo, headers (array),
27 | attachments (array), and possibly others depending on context.
28 | - If you want to abort the mail from being sent, set the boolean
29 | abortMailSend to true in the params array
30 | - Note that this hook is called twice when sending a message template, once
31 | early in the message generation (before tokens are applied, with the context
32 | `messageTemplate`) and then later from `CRM_Utils_Mail::send()` with the
33 | context `singleEmail`.
34 |
35 |
36 | ## Adding custom headers to the email
37 |
38 | You can add custom headers by appending to `$params['headers']`. Example:
39 |
40 | ```php
41 | $params['headers']['X-My-Header'] = 'my header value';
42 | ```
43 |
44 | The `headers` key may not exist in the `$params` array when passed into the hook.
45 |
46 | For CiviMail based emails you can also add headers by simply adding a key
47 | directly to the `$params` array, however as CiviMail also supports the above, so
48 | it might be safer to use the `headers` key when adding headers as this is
49 | supported across all methods.
50 |
51 | Study the source before atttempting to set or unset non-custom headers this way!
52 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterMailer.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterMailer
2 |
3 | ## Summary
4 |
5 | This hook is called when CiviCRM prepares an email driver class to
6 | handle outbound message delivery.
7 |
8 | ## Availability
9 |
10 | Introduced in CiviCRM v4.4.
11 |
12 | ## Definition
13 |
14 | hook_civicrm_alterMailer(&$mailer, $driver, $params)
15 |
16 | ## Parameters
17 |
18 | - object**$mailer** -The default mailer produced by normal
19 | configuration; a PEAR "Mail" class (like those returned by
20 | Mail::factory)
21 |
22 | - string **$driver** - The type of the default $mailer (eg "smtp",
23 | "sendmail", "mock", "CRM_Mailing_BAO_Spool")
24 |
25 | - array **$params** - The default config options used to construct
26 | $mailer
27 |
28 | ## Example
29 |
30 | /**
31 | * Implementation of hook_civicrm_alterMailer
32 | *
33 | * Replace the normal mailer with our custom mailer
34 | */
35 | function example_civicrm_alterMailer(&$mailer, $driver, $params) {
36 | $mailer = new ExampleMailDriver();
37 | }
38 |
39 | /**
40 | * Outbound mailer which writes messages to a log file
41 | *
42 | * For better examples, see PEAR Mail.
43 | *
44 | * @see Mail_null
45 | * @see Mail_mock
46 | * @see Mail_sendmail
47 | * @see Mail_smtp
48 | */
49 | class ExampleMailDriver {
50 | /**
51 | * Send an email
52 | */
53 | function send($recipients, $headers, $body) {
54 | // Write mail out to a log file instead of delivering it
55 | $data = array(
56 | 'recipients' => $recipients,
57 | 'headers' => $headers,
58 | 'body' => $body,
59 | );
60 | file_put_contents('/tmp/outbound-mail.log', json_encode($data), FILE_APPEND);
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterMailingLabelParams.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterMailingLabelParams
2 |
3 | ## Summary
4 |
5 | This hook is called to alter the parameters used to generate mailing
6 | labels.
7 |
8 | ## Availability
9 |
10 | CiviCRM 4.1 or later
11 |
12 | ## Definition
13 |
14 | function hook_civicrm_alterMailingLabelParams( &$args )
15 |
16 | ## Parameters
17 |
18 | - $args: reference to the associative array of arguments that are
19 | about to be used to generate mailing labels
20 | -
21 |
22 |
23 |
24 | @param array $args an array of the args for the tcpdf MultiCell api call with the variable names below converted into string keys
25 | (ie $w become 'w' as the first key for $args).
26 | If ishtml is set true, then a subset of the args will be passed to the tcdpdf writeHTMLCell api call instead.
27 |
28 | float $w Width of cells. If 0, they extend up to the right margin of the page.
29 | float $h Cell minimum height. The cell extends automatically if needed.
30 | string $txt String to print
31 | mixed $border Indicates if borders must be drawn around the cell block. The value can
32 | be either
33 | a number:
34 | 0: no border (default)
35 | 1: frame or
36 | a string containing some or all of the following characters (in any order):
37 | L: left
38 | T: top
39 | R: right
40 | B: bottom
41 | string $align Allows to center or align the text. Possible values are:
42 | L or empty string: left align
43 | C: center
44 | R: right align
45 | J: justification (default value when $ishtml=false)
46 | int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
47 | int $ln Indicates where the current position should go after the call. Possible values are:
48 | 0: to the right
49 | 1: to the beginning of the next line DEFAULT
50 | 2: below
51 | float $x x position in user units
52 | float $y y position in user units
53 | boolean $reseth if true reset the last cell height (default true).
54 | int $stretch stretch carachter mode:
55 | 0 = disabled
56 | 1 = horizontal scaling only if necessary
57 | 2 = forced horizontal scaling
58 | 3 = character spacing only if necessary
59 | 4 = forced character spacing
60 | boolean $ishtml set to true if $txt is HTML content (default = false).
61 | boolean $autopadding if true, uses internal padding and automatically adjust it to account for line width.
62 | float $maxh maximum height. It should be >= $h and less then remaining space to the bottom of the page,
63 | or 0 for disable this feature. This feature works only when $ishtml=false.
64 |
65 | NB: not all html tags are supported, not all style parameters are
66 | supported, and improperly constructed html tends to lead to errors and
67 | crashes.
68 |
69 | ## Returns
70 |
71 | - null
72 |
73 | ## Example
74 |
75 | function mymodule_civicrm_alterMailingLabelParams( &$args ) {
76 | $args['ishtml'] = true;
77 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterMailingRecipients.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterMailingRecipients
2 |
3 | ## Summary
4 |
5 | This hook is called to allow the user to alter the mailing recipients after they have been constructed.
6 |
7 | ### Notes
8 |
9 | !!! Note
10 | This hook is called two times, once at the start and once at the end of mail recipients
11 | building, identified by $context as 'pre' or 'post' respectively
12 |
13 | ## Availability
14 |
15 | This hook was first available in CiviCRM 4.7.32
16 |
17 | ## Definition
18 |
19 | ```php
20 | function hook_civicrm_alterMailingRecipients(&$mailingObject, &$criteria, $context);
21 | ```
22 |
23 | ## Parameters
24 |
25 | - object `$mailingObject` - reference to CRM_Mailing_DAO_Mailing object
26 | - array `$criteria` - the criteria in terms of SQL fragments Array(string $name => CRM_Utils_SQL_Select $criterion) to manipulate mailing recipients
27 | - string `$context` - contain 'pre' or 'post' value to indicate when the hook is fired
28 |
29 | ## Returns
30 |
31 | - null
32 |
33 | ## Example
34 | ```php
35 | function mymodule_civicrm_alterMailingRecipients(&$mailingObject, &$criteria, $context) {
36 | // fetch all emails marked is_bulkmail only AND consider only those contacts which are tagged with Volunteer
37 | if ($context == 'pre') {
38 | // criteria to choose email which are only used for mass mailing
39 | $criteria['location_filter'] = CRM_Utils_SQL_Select::fragment()->where("civicrm_email.is_bulkmail = 1");
40 | // criteria to choose contacts which are tagged 'Volunteer'
41 | $criteria['tag_filter'] = CRM_Utils_SQL_Select::fragment()
42 | ->join('civicrm_entity_tag', "INNER JOIN civicrm_entity_tag et ON et.entity_id = civicrm_contact.id AND et.entity_table = 'civicrm_contact'")
43 | ->join('civicrm_tag', "INNER JOIN civicrm_tag t ON t.id = et.tag_id")
44 | ->where("t.name = 'Volunteer'");
45 | // criteria to change order by to use is_bulkmail
46 | $criteria['order_by'] = CRM_Utils_SQL_Select::fragment()->orderBy('civicrm_email.is_bulkmail')
47 | }
48 | }
49 | ```
50 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterMenu.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterMenu
2 |
3 | ## Summary
4 |
5 | This hook is called when building CiviCRM's list of HTTP routes and should be used when you want to register custom paths or URLS.
6 |
7 | ## Notes
8 |
9 | !!! note "Comparison of Related Hooks"
10 | This is one of three related hooks. The hooks:
11 |
12 | - [hook_civicrm_navigationMenu](hook_civicrm_navigationMenu.md) manipulates the navigation bar at the top of every screen
13 | - [hook_civicrm_alterMenu](hook_civicrm_alterMenu.md) manipulates the list of HTTP routes (using PHP arrays)
14 | - [hook_civicrm_xmlMenu](hook_civicrm_xmlMenu.md) manipulates the list of HTTP routes (using XML files)
15 |
16 | !!! tip "Applying changes"
17 |
18 | Menu data is cached. After making a change to the menu data, [clear the system cache](../tools/debugging.md#clearing-the-cache).
19 |
20 | ## Availability
21 |
22 | Added in CiviCRM 4.7.11.
23 |
24 |
25 | ## Definition
26 |
27 | hook_civicrm_alterMenu(&$items)
28 |
29 | ## Parameters
30 |
31 | - *"$items*" the array of HTTP routes, keyed by relative path. Each
32 | includes some combination of properties:
33 | - "*page_callback*": This should refer to a page/controller class
34 | ("*CRM_Example_Page_Example*") or a static function
35 | ("*CRM_Example_Page_AJAX::foobar*").
36 | - "*access_callback*": (usually omitted)
37 | - "*access_arguments*": Description of required permissions. Ex:
38 | *array(array('access CiviCRM'), 'and')*
39 | - "*ids_arguments*": This array defines any [page-specific PHPIDS exceptions](hook_civicrm_xmlMenu.md#xml-ids). It includes any of these three child elements:
40 | - "*json*": Array of input fields which may contain JSON data.
41 | - "*html*": Array of input fields which may contain HTML data.
42 | - "*exceptions*": Array of input fields which are completely exempted from PHPIDS.
43 |
44 | ## Returns
45 |
46 | - null
47 |
48 | ## Example
49 |
50 |
51 |
52 | function EXAMPLE_civicrm_alterMenu(&$items) {
53 | $items['civicrm/my-page'] = array(
54 | 'page_callback' => 'CRM_Example_Page_AJAX::foobar',
55 | 'access_arguments' => array(array('access CiviCRM'), "and"),
56 | );
57 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterPaymentProcessorParams.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterPaymentProcessorParams
2 |
3 | ## Summary
4 |
5 | This hook allows you to modify parameters passed to the payment processor.
6 |
7 | ## Notes
8 |
9 | This hook is called during the processing of a contribution after the
10 | payment processor has control, but before the CiviCRM processor-specific code starts a transaction with the back-end payment server (e.g. Authorize.net).
11 |
12 | With this hook, you can pass custom parameters, or use features of your back-end that CiviCRM does not "know" about.
13 |
14 | ## Definition
15 |
16 | hook_civicrm_alterPaymentProcessorParams($paymentObj,&$rawParams, &$cookedParams);
17 |
18 | ## Parameters
19 |
20 | - $paymentObj - instance of payment class of the payment processor
21 | invoked
22 | - $rawParams - the associative array passed by CiviCRM to the
23 | processor
24 | - $cookedParams - the associative array of parameters as translated
25 | into the processor's API.
26 |
27 | ## Returns
28 |
29 | ## Example
30 |
31 | function civitest_civicrm_alterPaymentProcessorParams($paymentObj, &$rawParams, &$cookedParams) {
32 | if ($paymentObj->class_name == Payment_Dummy ) {
33 | $employer = empty($rawParams['custom_1']) ? '' : $rawParams['custom_1'];
34 | $occupation = empty($rawParams['custom_2']) ? '' : $rawParams['custom_2'];
35 | $cookedParams['custom'] = "$employer|$occupation"; }
36 | else if ($paymentObj->class_name == Payment_AuthorizeNet) {
37 | //Actual translation for one application:
38 | //Employer > Ship to Country (x_ship_to_country)
39 | //Occupation > Company (x_company)
40 | //Solicitor > Ship-to First Name (x_ship_to_first_name)
41 | //Event > Ship-to Last Name (x_ship_to_last_name)
42 | //Other > Ship-to Company (x_ship_to_company)
43 | $cookedParams['x_ship_to_country'] = $rawParams['custom_1'];
44 | $cookedParams['x_company'] = $rawParams['custom_2'];
45 | $cookedParams['x_ship_to_last_name'] = $rawParams['accountingCode'];
46 | //for now
47 | $country_info = da_core_fetch_country_data_by_crm_id($rawParams['country-1']);
48 | $cookedParams['x_ship_to_company'] = $country_info['iso_code'];
49 | }
50 | elseif ($paymentObj->billing_mode == 2) {
51 | // Express Checkout
52 | $cookedParams['desc'] = $rawParams['eventName'];
53 | $cookedParams['custom'] = $rawParams['eventId'];
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterSettingsFolders.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterSettingsFolders
2 |
3 | ## Summary
4 |
5 | This hook allows modules and extensions to scan for settings in
6 | additional folders.
7 |
8 | ## Notes
9 |
10 | The [Settings](../framework/setting.md) subsystem
11 | provides metadata about many of CiviCRM's internal settings by scanning
12 | for files matching "settings/*.setting.php" (e.g.
13 | [settings/Core.setting.php](https://github.com/civicrm/civicrm-core/blob/4.3/settings/Core.setting.php)).
14 |
15 | ## Availability
16 |
17 | This hook was introduced in CiviCRM v4.3.0 and v4.2.10.
18 |
19 | ## Definition
20 |
21 | hook_civicrm_alterSettingsFolders(&$metaDataFolders)
22 |
23 | ## Parameters
24 |
25 | - @param array $metaDataFolders list of directory paths
26 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterSettingsMetaData.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterSettingsMetaData
2 |
3 | ## Summary
4 |
5 | This hook is called when Settings have been loaded from the xml.
6 | It is an opportunity for hooks to alter the data.
7 |
8 | ## Definition
9 |
10 | alterSettingsMetaData(&$settingsMetaData, $domainID, $profile)
11 |
12 | ## Parameters
13 |
14 | - @param array $settingsMetaData Settings Metadata.
15 | - @param int $domainID
16 | - @param mixed $profile
17 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterTemplateFile.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterTemplateFile
2 |
3 | ## Summary
4 |
5 | This hook is invoked while selecting the tpl file to use to render the
6 | page.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_alterTemplateFile($formName, &$form, $context, &$tplName)
11 |
12 |
13 |
14 | ## Parameters
15 |
16 | - string $formname -name of the form
17 | - object $form (reference) for object
18 | - string $context page or form
19 | - string $tplName - the file name of the tpl - alter this to alter
20 | the file in use
21 |
22 | ## Returns
23 |
24 | ## Example
25 |
26 |
27 |
28 | /**
29 | * Alter tpl file to include a different tpl file based on contribution/financial type
30 | * (if one exists). It will look for
31 | * templates/CRM/Contribute/Form/Contribution/Type2/Main.php
32 | * where the form has a contribution or financial type of 2
33 | * @param string $formName name of the form
34 | * @param object $form (reference) form object
35 | * @param string $context page or form
36 | * @param string $tplName (reference) change this if required to the altered tpl file
37 | */
38 | function tplbytype_civicrm_alterTemplateFile($formName, &$form, $context, &$tplName) {
39 | $formsToTouch = array(
40 | 'CRM_Contribute_Form_Contribution_Main' => array('path' => 'CRM/Contribute/Form/Contribution/', 'file' => 'Main'),
41 |
42 | 'CRM_Contribute_Form_Contribution_Confirm' => array('path' =>
43 | 'CRM/Contribute/Form/Contribution', 'file' => 'Confirm'),
44 |
45 | 'CRM_Contribute_Form_Contribution_ThankYou' => array('path' =>
46 | 'CRM/Contribute/Form/Contribution', 'file' => 'ThankYou'),
47 | );
48 |
49 |
50 | if(!array_key_exists($formName, $formsToTouch)) {
51 | return;
52 | }
53 | if(isset($form->_values['financial_type_id'])) {
54 | $type = 'Type' . $form->_values['financial_type_id'];
55 | }
56 | if(isset($form->_values['contribution_type_id'])) {
57 | $type = 'Type' . $form->_values['contribution_type_id'];
58 | }
59 | if(empty($type)) {
60 | return;
61 | }
62 | $possibleTpl = $formsToTouch[$formName]['path'] . $type . '/' . $formsToTouch[$formName]['file']. '.tpl';
63 | $template = CRM_Core_Smarty::singleton();
64 | if ($template->template_exists($possibleTpl)) {
65 | $tplName = $possibleTpl;
66 | }
67 | }
68 |
69 | !!! tip
70 | While this hook is included in the Form related hooks section it can be used to alter almost all generated content.
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_alterUFFields.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_alterUFFIelds
2 |
3 | ## Summary
4 |
5 | This hook allows for the modification of the available fields that are permissible for use within a profile. This might be useful for when you have an extension that has defined it's own entities or it is seeking to permit a core component that doesn't show up in profiles by default e.g. Grants
6 |
7 | ## Definition
8 |
9 | hook_civicrm_alterUFFields(&$fields) {
10 |
11 | ## Parameters
12 |
13 | - $fields - a multidimential array of Entities and their fields.
14 | For each field contained within the array there are at the following properties
15 | - name
16 | - title
17 | - export
18 | - import
19 | - hasLocationType
20 | - field_type - Entity of the field
21 | - other field keys as returned by entity.getfields
22 |
23 | ## Returns
24 |
25 | - null
26 |
27 | ## Example
28 |
29 | ```php
30 | /**
31 | * Implementation of hook_civicrm_alterUFFIelds
32 | */
33 | function mte_civicrm_alterUFFields(&$fields) {
34 | // Include grant fields in the permissible array
35 | $fields['Grant'] = CRM_Grant_DAO_Grant::export();
36 | }
37 | ```
38 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_angularModules.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_angularModules
2 |
3 | ## Summary
4 |
5 | This hook generates a list of AngularJS modules and allows you to register additional AngularJS modules. It is currently **experimental**.
6 |
7 | ## Availability
8 |
9 | This hook is available in CiviCRM 4.5+. It may use features only
10 | available in CiviCRM 4.6+.
11 |
12 | ## Definition
13 |
14 | ```php
15 | angularModules(&$angularModules)
16 | ```
17 |
18 | ## Parameters
19 |
20 | * `&$angularModules` - an array containing a list of all Angular modules. The key for each item is the name of the module. The value for each item is an array with the following key/value pairs:
21 |
22 | * `'ext' =>`*`(string)`* - The name of the CiviCRM extension which has the source-code.
23 | * `'js' =>`*`(array)`* - List of Javascript files. May use the wildcard (`*`). Relative to the extension.
24 | * `'css' =>`*`(array)`* - List of CSS files. May use the wildcard (`*`). Relative to the extension.
25 | * `'partials' =>`*`(array)`* - List of HTML folders. Relative to the extension.
26 | * `'settings' =>`*`(array)`* - Runtime data to export from PHP to JS.
27 | * This is mapped to the JS global (Ex: `array("foo"=>"bar")`, which would be available as `CRM.myModule.foo`.
28 | * `'requires' =>`*`(array)`* - List of AngularJS modules required by this module.
29 | * Default: `array()`.
30 | * CiviCRM 4.7.21+
31 | * `'basePages' =>`*`(array)`* - Unconditionally load this module onto the given Angular pages.
32 | * If omitted, the default is `array('civicrm/a')`. This provides backward compatibility with behavior since `v4.6+`.
33 | * For a utility that should only be loaded on-demand, use `array()`.
34 | * For a utility that should be loaded in all pages use, `array('*')`.
35 | * CiviCRM 4.7.21+
36 |
37 | ## Returns
38 |
39 | * `null`
40 |
41 | ## Example
42 |
43 | ```php
44 | function mymod_civicrm_angularModules(&$angularModules) {
45 | $angularModules['myAngularModule'] = array(
46 | 'ext' => 'org.example.mymod',
47 | 'js' => array('js/myAngularModule.js'),
48 | );
49 | $angularModules['myBigAngularModule'] = array(
50 | 'ext' => 'org.example.mymod',
51 | 'requires' => array('ngRoute', 'crmUi'),
52 | 'basePages' => array('civicrm/a'),
53 | 'js' => array('js/part1.js', 'js/part2.js'),
54 | 'css' => array('css/myAngularModule.css'),
55 | 'partials' => array('partials/myBigAngularModule'),
56 | 'settings' => array(
57 | 'foo' => 'bar',
58 | ),
59 | );
60 | }
61 | ```
62 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_batchItems.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_batchItems
2 |
3 | ## Summary
4 |
5 | This hook is called when a CSV batch export file is about to be
6 | generated.
7 |
8 | ## Notes
9 |
10 | Notice that this hook will be called in per batch bases, e.g.
11 | if 3 batches are going to be exported in the same CSV then this hook
12 | will be called three times regarding each batch.
13 |
14 | ## Definition
15 |
16 | ```php
17 | hook_civicrm_batchItems(&$results, &$items)
18 | ```
19 |
20 | ## Parameters
21 |
22 | - `$results` - the query result for the current batch that is being processed
23 | - `$items` - the entries of financial items that will actually become the records on the CSV (still per batch based)
24 |
25 | ## Hints
26 |
27 | - This hook can be used together with `hook_civicrm_batchQuery` to add/modify the information in CSV batch exports
28 | - You can loop through the two parameters to modify per financial item. This can even be used to filter financial items.
29 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_batchQuery.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_batchQuery
2 |
3 | ## Summary
4 |
5 | This hook is called when the query of CSV batch export is generated
6 |
7 | ## Notes
8 |
9 | With this hook you can provide your own query objects which alter or extend the original query.
10 |
11 | ## Definition
12 |
13 | hook_civicrm_batchQuery( &$query )
14 |
15 | ## Parameters
16 |
17 | - $query - A string of SQL Query
18 |
19 | ## Example
20 |
21 |
22 | function hook_civicrm_batchQuery(&$query) {
23 | $query = "SELECT * FROM civicrm_financial_item";
24 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_buildAmount.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_buildAmount
2 |
3 | ## Summary
4 |
5 | This hook is called when building the amount structure for a
6 | Contribution or Event Page, allowing you to modify the set of radio
7 | buttons representing amounts for contribution levels and event
8 | registration fees.
9 |
10 | ## Definition
11 |
12 | hook_civicrm_buildAmount( $pageType, &$form, &$amount )
13 |
14 | ## Parameters
15 |
16 | - $pageType - is this a 'contribution', 'event', or 'membership'
17 | - $form - reference to the form object
18 | - $amount - the amount structure to be displayed
19 |
20 | ## Returns
21 |
22 | - null
23 |
24 | ## Example
25 | For an extension that implements this hook see: https://github.com/mattwire/uk.org.som.proratamembership
26 |
27 | function proratamembership_civicrm_buildAmount($pageType, &$form, &$amount) {
28 | if (!empty($form->get('mid'))) {
29 | // Don't apply pro-rated fees to renewals
30 | return;
31 | }
32 | //sample to modify priceset fee
33 | $priceSetId = $form->get('priceSetId');
34 | if (!empty($priceSetId)) {
35 | $feeBlock = &$amount;
36 | if (!is_array($feeBlock) || empty($feeBlock)) {
37 | return;
38 | }
39 | if ($pageType == 'membership') {
40 | // pro-rata membership per month
41 | // membership year is from 1st Jan->31st Dec
42 | // Subtract 1/12 per month so in Jan you pay full amount,
43 | // in Dec you pay 1/12
44 | // 12 months in year, min 1 month so subtract current numeric month from 13 (gives 12 in Jan, 1 in December)
45 | $monthNum = date('n');
46 | $monthsToPay = 13-$monthNum;
47 | foreach ($feeBlock as &$fee) {
48 | if (!is_array($fee['options'])) {
49 | continue;
50 | }
51 | foreach ($fee['options'] as &$option) {
52 | // We only have one amount for each membership, so this code may be overkill,
53 | // as it checks every option displayed (and there is only one).
54 | if ($option['amount'] > 0) {
55 | // Only pro-rata paid memberships!
56 | $option['amount'] = $option['amount'] * ($monthsToPay / 12);
57 | if ($monthsToPay == 1) {
58 | $option['label'] .= ' - Pro-rata: Dec only';
59 | }
60 | elseif ($monthsToPay < 12) {
61 | $dateObj = DateTime::createFromFormat('!m', $monthNum);
62 | $monthName = $dateObj->format('M');
63 | $option['label'] .= ' - Pro-rata: ' . $monthName . ' to Dec';
64 | }
65 | }
66 | }
67 | }
68 | // FIXME: Somewhere between 4.7.15 and 4.7.23 the above stopped working and we have to do the following to make the confirm page show the correct amount.
69 | $form->_priceSet['fields'] = $feeBlock;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_buildAsset.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_buildAsset
2 |
3 | ## Summary
4 |
5 | This hook fires whenever the system builds a semi-dynamic asset.
6 |
7 | ## Notes
8 |
9 | For more discussion, see [AssetBuilder](../framework/asset-builder.md).
10 |
11 | ## Definition
12 |
13 | hook_civicrm_buildAsset($asset, $params, &$mimeType, &$content)
14 |
15 | ## Parameters
16 |
17 | * `$asset` (string): the logical file name of an asset (ex: `hello-world.json`)
18 | * `$params` (array): an optional set of parameters describing how to build the asset
19 | * `$mimeType` (string, output): the MIME type of the asset (ex: `application/json`)
20 | * `$content` (string, output): the full content of the asset
21 |
22 | ## Returns
23 |
24 | * null
25 |
26 | ## Example
27 |
28 | ```php
29 | function mymodule_civicrm_buildAsset($asset, $params, &$mimeType, &$content) {
30 | if ($asset === 'hello-world.json') {
31 | $mimeType = 'application/json';
32 | $content = json_encode(array('hello', 'world'));
33 | }
34 | }
35 | ```
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_buildProfile.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_buildProfile
2 |
3 | ## Summary
4 |
5 | This hook is called while preparing a profile form. This form allows for extension authors to add various scripts onto the profile pages. Note that `hook_civicrm_buildForm` is not fired for profile pages
6 |
7 | ## Definition
8 |
9 | buildProfile($profileName)
10 |
11 | ## Parameters
12 |
13 | - $profileName - the (machine readable) name of the profile.
14 |
15 | ## Returns
16 |
17 | - null
18 |
19 | ```php
20 | function myext_civicrm_buildProfile($profileName) {
21 | if ($profileName === 'MyTargetedProfile) {
22 | CRM_Core_Resources::singleton()->addScriptFile('org.example.myext', 'some/fancy.js', 100);
23 | }
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_buildStateProvinceForCountry.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_buildStateProvinceForCountry
2 |
3 | ## Summary
4 |
5 | This hook is called during the ajax callback that is used to build the
6 | options that display in the State/Province select widget for a specific
7 | country, and can be used to alter the list of State/Province options for
8 | particular countries.
9 |
10 | ## Definition
11 |
12 | hook_civicrm_buildStateProvinceForCountry( $countryID, &$states )
13 |
14 | ## Parameters
15 |
16 | - @param string $countryID Country ID for which State/Province data
17 | is being looked up
18 | - @param array $states array of State/Province data relating to
19 | country being looked up (keys = State/Province ID, values =
20 | State/Province name)
21 |
22 | ## Returns
23 |
24 | - null
25 |
26 | ## Availability
27 |
28 | - Available since 4.1
29 |
30 | ## Example
31 |
32 | The example below reorders the Irish State list so that Dublin is at the
33 | top of the list (by default, Dublin would be placed in the list in
34 | alphabetical order.
35 |
36 | /*
37 | * Implements hook_civicrm_buildStateProvinceForCountry().
38 | *
39 | * Reorder the dublin states so that Dublin is at the top and dublin sub
40 | * states are ordered nicely.
41 | */
42 | function ourclient_civicrm_buildStateProvinceForCountry( $countryID, &$states ) {
43 | // First separate out the Dublin options.
44 | $topStates = array();
45 | foreach ($states as $key => $value) {
46 | if (preg_match('/Dublin/', $value)) {
47 | $topStates[$key] = $value;
48 | }
49 | else {
50 | $otherStates[$key] = $value;
51 | }
52 | }
53 | ksort($topStates);
54 | $states = $topStates + $otherStates;
55 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_buildUFGroupsForModule.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_buildUFGroupsForModule
2 |
3 | ## Summary
4 |
5 | This hook is called when ufgroups (profiles) are being built for a
6 | module.
7 |
8 | ## Notes
9 |
10 | The most common use case for this hook is to edit which profiles are
11 | visible on the Contact Dashboard or (Drupal) user registration page
12 | based on arbitrary criteria (e.g. whether the contact has a particular
13 | contact subtype).
14 |
15 | ## Availability
16 |
17 | This hook is available in CiviCRM 4.1+.
18 |
19 | ## Definition
20 |
21 | buildUFGroupsForModule($moduleName, &$ufGroups)
22 |
23 | ## Parameters
24 |
25 | - $moduleName - a string containing the module name (e.g. "User
26 | Registration", "User Account", "Profile", "CiviEvent").
27 | - &$ufGroups - an array of ufgroups (profiles) available for the
28 | module.
29 |
30 | ## Returns
31 |
32 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_caseChange.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_caseChange
2 |
3 | ## Summary
4 |
5 | This hook fires whenever a record in a case changes.
6 |
7 | ## Notes
8 |
9 | See also the documentation for [CiviCase Util](https://wiki.civicrm.org/confluence/display/HR/CiviCase+Util).
10 |
11 | ## Availability
12 |
13 | This hook is available in CiviCRM 4.5+.
14 |
15 | ## Definition
16 |
17 | function caseChange(\Civi\CCase\Analyzer $analyzer)
18 |
19 | ## Parameters
20 |
21 | - $analyzer - A bundle of data about the case (such as the case and
22 | activity records).
23 |
24 | ## Returns
25 |
26 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_caseTypes.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_caseTypes
2 |
3 | ## Summary
4 |
5 | This hook defines available case types.
6 |
7 | ## Notes
8 |
9 | Note that this hook is actually an adapter
10 | for [hook_civicrm_managed](hook_civicrm_managed.md), so any case
11 | type defined inside this hook will be automatically
12 | inserted, updated, deactivated, and deleted in tandem with enabling,
13 | disabling, and uninstalling the module. For more background, see [API
14 | and the Art of
15 | Installation](http://civicrm.org/blogs/totten/api-and-art-installation).
16 |
17 | ## Definition
18 |
19 | hook_civicrm_caseTypes(&$caseTypes)
20 |
21 | ## Parameters
22 |
23 | - array **$caseTypes**list of case types; each item is an array with
24 | keys:
25 | - **'module'**: string; for module-extensions, this is the
26 | fully-qualifed name (e.g. "*com.example.mymodule*"); for Drupal
27 | modules, the name is prefixed by "drupal" (e.g.
28 | *"drupal.mymodule*")
29 | - **'name'**: string, a symbolic name which can be used to track
30 | this entity
31 | - **'file'**: string, the path to the XML file which defines the
32 | case-type
33 |
34 | ## Example
35 |
36 | function civitest_civicrm_caseTypes(&$caseTypes) {
37 | $caseTypes['MyCase'] = array(
38 | 'module' => 'org.example.mymodule',
39 | 'name' => 'MyCase',
40 | 'file' => __DIR__ . '/MyCase.xml',
41 | );
42 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_check.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_check
2 |
3 | ## Summary
4 |
5 | This hook is called by the "System Check" api.
6 |
7 | ## Notes
8 |
9 | This runs on a regular basis (currently once a day, as well as whenever the status page is visited or `System.check` API is called).
10 |
11 | Typically your extension would add results by appending one or more
12 | `CRM_Utils_Check_Message` objects to the $messages array. Constructing
13 | a `CRM_Utils_Check_Message` requires the following parameters:
14 |
15 | - **Name:** A unique string for this type of message (no two messages in the array may have the same name).
16 | This will be the name given to a StatusPreference record if your message is hushed or disabled.
17 | - **Description:** Long description html string
18 | - **Title:** Short title plain text string
19 | - **Severity:** A [PSR-3 string](http://www.php-fig.org/psr/psr-3/).
20 | - **Icon:** A [font-awesome icon](https://fortawesome.github.io/Font-Awesome/icons/) string (optional).
21 |
22 | See `CRM_Utils_Check::checkAll` for more details about the system check api.
23 |
24 | ## Availability
25 |
26 | Introduced in CiviCRM v4.6.3.
27 |
28 | ## Definition
29 |
30 | hook_civicrm_check(&$messages)
31 |
32 | ## Parameters
33 |
34 | - **`&$messages`** `CRM_Utils_Check_Message[]`: Array of messages your hook can append to
35 | - **`$statusNames`** `array|null`: If only certain checks were requested, check this array and return early if your messages are not called for.
36 | - **`$includeDisabled`** `bool`: If your hook skips disabled checks (which it should!) this param tells you to bypass your skippage.
37 |
38 | ## Example
39 |
40 | /**
41 | * Implementation of hook_civicrm_check
42 | *
43 | * Add a check to the status page/System.check results if $snafu is TRUE.
44 | */
45 | function mymodule_civicrm_check(&$messages, $statusNames, $includeDisabled) {
46 |
47 | // Early return if $statusNames doesn't call for our check
48 | if ($statusNames && !in_array('mymoduleSnafu', $statusNames)) {
49 | return;
50 | }
51 |
52 | // If performing your check is resource-intensive, consider bypassing if disabled
53 | if (!$includeDisabled) {
54 | $disabled = \Civi\Api4\StatusPreference::get()
55 | ->setCheckPermissions(FALSE)
56 | ->addWhere('is_active', '=', FALSE)
57 | ->addWhere('domain_id', '=', 'current_domain')
58 | ->addWhere('name', '=', 'mymoduleSnafu')
59 | ->execute()->count();
60 | if ($disabled) {
61 | return;
62 | }
63 | }
64 |
65 | $snafu = (1 + 1 == 2); // Perform check here
66 |
67 | if ($snafu) {
68 | $messages[] = new CRM_Utils_Check_Message(
69 | 'mymoduleSnafu',
70 | ts('Situation normal, all funnied up'),
71 | ts('SNAFU Found'),
72 | \Psr\Log\LogLevel::WARNING,
73 | 'fa-flag'
74 | )
75 | // Optionally add extended help
76 | ->addHelp(ts('This text will appear in a help bubble if the user clicks on the help icon.'));
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_config.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_config
2 |
3 | ## Summary
4 |
5 | This hook is called soon after the `CRM_Core_Config` object has been
6 | initialized.
7 |
8 | ## Notes
9 |
10 | You can use this hook to modify the config object and hence
11 | behavior of CiviCRM dynamically.
12 |
13 | ## Definition
14 |
15 | hook_civicrm_config( &$config )
16 |
17 | ## Parameters
18 |
19 | - $config the config object
20 |
21 | ## Example
22 |
23 | function civitest_civicrm_config( &$config ) {
24 | $civitestRoot = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
25 |
26 | // fix php include path
27 | $include_path = $civitestRoot . PATH_SEPARATOR . get_include_path( );
28 | set_include_path( $include_path );
29 |
30 | // fix template path
31 | $templateDir = $civitestRoot . 'templates' . DIRECTORY_SEPARATOR;
32 | $template =& CRM_Core_Smarty::singleton( );
33 | array_unshift( $template->template_dir, $templateDir );
34 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_contact_get_displayname.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_contact_get_displayname
2 |
3 | ## Summary
4 |
5 | This hook is called to retrieve the display name of a contact, allowing you to return a custom display name.
6 |
7 | ## Notes
8 |
9 | Probably you won't need this hook but in some case it might be useful.
10 | For example you want to show who is a manager of an organisation but you
11 | don't want to store this in the database.
12 |
13 | ## Definition
14 |
15 | civicrm_contact_get_displayname(&$display_name, $contactId, $objContact)
16 |
17 | ## Parameters
18 |
19 | - &$display_name - the current display name, you can change the
20 | display name by changing the contents of this parameter
21 | - $contactId - Contact ID
22 | - $objContact - The contact BAO
23 |
24 | ## Returns
25 |
26 | - null
27 |
28 | ## Example
29 |
30 | Below an example of showing the contact ID after the display name
31 |
32 | function myextension_civicrm_contact_get_displayname(&$display_name, $contactId, $objContact) {
33 | $display_name = $display_name . ' - '.$contactId;
34 | }
35 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_container.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_container
2 |
3 | ## Summary
4 |
5 | This hook modifies the CiviCRM container allowing you to add new services, parameters,
6 | extensions, etc.
7 |
8 | ## Notes
9 |
10 | !!! tip
11 | The container configuration will be compiled/cached. The default cache behavior is aggressive. When you first implement the hook, be sure to flush the cache. Additionally, you should relax caching during development. In `civicrm.settings.php`, set `define('CIVICRM_CONTAINER_CACHE', 'auto')`.
12 |
13 | !!! note
14 | As of CiviCRM version 5.27 CiviCRM now uses Symfony v3.4 or v4.4. There is an important change which is that in v3.3 Symfony services are now considered by default to be private. To ensure backwards compatibility you just need to add `->setPublic(TRUE)` after your definition in your code. This will make the service public as was the default originally in the Symfony 2.x series. If you don't need the service to be public, you can omit this.
15 |
16 | ## Availability
17 |
18 | This hook is available in CiviCRM 4.7+.
19 |
20 | ## Definition
21 |
22 | hook_civicrm_container(\Symfony\Component\DependencyInjection\ContainerBuilder $container)
23 |
24 | ## Parameters
25 |
26 | - $container - An object of type
27 | \Symfony\Component\DependencyInjection\ContainerBuilder. See
28 | [here](http://symfony.com/doc/current/components/dependency_injection/index.html).
29 |
30 | ## Returns
31 |
32 | - null
33 |
34 | ## Example
35 |
36 | ```php
37 | use Symfony\Component\Config\Resource\FileResource;
38 | use Symfony\Component\DependencyInjection\Definition;
39 |
40 | function mymodule_civicrm_container($container) {
41 | $container->addResource(new FileResource(__FILE__));
42 | $container->setDefinition('mysvc', new Definition('My\Class', array()))->setPublic(TRUE);
43 | }
44 | ```
45 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_copy.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_copy
2 |
3 | ## Summary
4 |
5 | This hook is called after a CiviCRM object (Event, ContributionPage,
6 | Profile) has been copied.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_copy( $objectName, &$object )
11 |
12 | ## Parameters
13 |
14 | - $objectName - the name of the object that is being copied (Event,
15 | ContributionPage, UFGroup)
16 | - $object - reference to the copied object
17 |
18 | ## Returns
19 |
20 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_coreResourceList.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_coreResourceList
2 |
3 | ## Summary
4 |
5 | This hook is called when the list of core js/css resources is about to
6 | be processed, giving you the opportunity to modify
7 | the list prior to the resources being added, or add your own.
8 |
9 | ## Notes
10 |
11 | Added in v4.6.6.
12 |
13 | See [Resource Reference](../framework/resources.md)
14 | for more information.
15 |
16 | ## Definition
17 |
18 | ```php
19 | hook_civicrm_coreResourceList(&$list, $region)
20 | ```
21 |
22 | ## Parameters
23 |
24 | * `$list` - an array of items about to be added to the page. Items in the
25 | list may be:
26 |
27 | * A string ending in `.js`
28 | * A string ending in `.css`
29 | * An array of settings (will be added to the javascript CRM object).
30 |
31 | * `$region` - target region of the page - normally this is `"html-header"`
32 |
33 | ## Example
34 |
35 |
36 | ```php
37 | function myextension_civicrm_coreResourceList(&$list, $region) {
38 | // Prevent navigation.css from loading
39 | $cssWeDontWant = array_search('css/navigation.css', $list);
40 | unset($list[$cssWeDontWant]);
41 |
42 | // Add some css of our own to the page.
43 | // Note that if the file we want to add is outside civicrm directory
44 | // (e.g. in an extension) we can't just append it to the list.
45 | // But we can add it directly, which is what happens to items in this list anyway.
46 | Civi::resources()->addStyleFile('org.example.myextension', 'css/my_style.css', 0, $region);
47 |
48 | // Add a setting - in this example we override the CKEditor config file location
49 | $myCKEConfFile = Civi::resources()->getUrl('org.example.myextension', 'js/my-ckeditor-config.js');
50 | $list[] = ['config' => ['CKEditorCustomConfig' => ['default' => $myCKEConfFile]]];
51 | }
52 | ```
53 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_cron.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_cron
2 |
3 | ## Summary
4 |
5 | This hook is called every time the CiviCRM scheduler is polled.
6 |
7 | ## Notes
8 |
9 | The timing and frequency with which this is called will vary depending on
10 | the system configuration.
11 |
12 | Introduced in CiviCRM v4.3.
13 |
14 | !!! note "This is a low-level approach"
15 | There are two ways to build on top of the CiviCRM scheduler. **hook_civicrm_cron** is a low-level approach which calls your code with an unpredictable schedule – in some systems, it could be once a day; in others, once every minute, every 5 minutes, every hour, every 2 hours, ad nauseum. You must ensure that your code will behave well in all these situations. Alternatively, the **Job API** is a higher-level approach by which you may register scheduled jobs ("Daily", "Hourly", etc), and the scheduler will make a best effort to match the declared scheduler. See, e.g., ["Create a Module Extension: How does one add a cron job"](../extensions/advanced.md##cron-jobs)
16 |
17 |
18 | ## Definition
19 |
20 | hook_civicrm_cron($jobManager)
21 |
22 | ## Parameters
23 |
24 | - CRM_Core_JobManager** $jobManager**
25 |
26 | ## Example
27 |
28 | /**
29 | * Implementation of hook_civicrm_cron
30 | *
31 | * Flag records in a custom table as dirty if they are over 2 days old.
32 | * Rerunning this logic at various times throughout the day should be safe
33 | * because there are no guarantees about when it will run.
34 | */
35 | function example_civicrm_cron($jobManager) {
36 | CRM_Core_DAO::executeQuery('UPDATE my_table SET is_dirty = 1 WHERE last_modified < adddate(now(), "-2 day")');
37 | }
38 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_crudLink.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_crudLink
2 |
3 | ## Summary
4 |
5 | Generate a default CRUD URL for an entity.
6 |
7 | ## Availability
8 |
9 | This hook is available in CiviCRM 4.5+.
10 |
11 | ## Definition
12 |
13 | crudLink($spec, $bao, &$link)
14 |
15 | ## Parameters
16 |
17 | - $spec - An array with keys:
18 |
19 | - action: int, eg CRM_Core_Action::VIEW or
20 | CRM_Core_Action::UPDATE
21 | - entity_table: string
22 | - entity_id: int
23 | - $bao CRM_Core_DAO
24 |
25 | - $link - An array.
26 |
27 |
28 |
29 | To define the link, add these keys to $link:
30 |
31 | - title: string
32 |
33 | - path: string
34 |
35 | - query: array
36 |
37 | - url: string (used in lieu of "path"/"query")
38 |
39 | Note: if making "url" CRM_Utils_System::url(), set $htmlize=false
40 |
41 |
42 |
43 | ## Returns
44 |
45 | - mixed
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_custom.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_custom
2 |
3 | ## Summary
4 |
5 | This hook is called *after* the database write on a custom table.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_custom( $op, $groupID, $entityID, &$params )
10 |
11 | ## Parameters
12 |
13 | - string $op - the type of operation being performed
14 | - string $groupID - the custom group ID
15 | - object $entityID - the entityID of the row in the custom table
16 | - array $params - the parameters that were sent into the calling
17 | function
18 |
19 | ## Returns
20 |
21 | - null - the return value is ignored
22 |
23 | ## Example
24 |
25 | /**
26 | * This example generates a custom contact ID (year + number, ex: 20080000001)
27 | */
28 |
29 | function MODULENAME_civicrm_custom( $op, $groupID, $entityID, &$params ) {
30 | if ( $op != 'create' && $op != 'edit' ) {
31 | return;
32 | }
33 |
34 | if ($groupID == 1) {
35 | $needs_update = false;
36 | $tableName = CRM_Core_DAO::getFieldValue( 'CRM_Core_DAO_CustomGroup',
37 | $groupID,
38 | 'table_name' );
39 |
40 |
41 | $sql = "SELECT member_id_4 FROM $tableName WHERE entity_id = $entityID";
42 | $dao = CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
43 |
44 | if (! $dao->fetch()) {
45 | $needs_update = true;
46 | }
47 |
48 | // Value may also be empty. i.e. delete the value in the interface to reset the field.
49 | if (! $dao->member_id_4) {
50 | $needs_update = true;
51 | }
52 |
53 | if ($needs_update) {
54 | $member_id = date('Y') . sprintf('%07d', $entityID);
55 |
56 | $sql = "UPDATE $tableName SET member_id_4 = $member_id WHERE entity_id = $entityID";
57 | CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_customPre.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_customPre
2 |
3 | ## Summary
4 |
5 | This hook is called *before* the database write on a custom table.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_customPre($op, $groupID, $entityID, &$params)
10 |
11 | ## Parameters
12 |
13 | - string $op - the type of operation being performed
14 | - string $groupID - the custom group ID
15 | - object $entityID - the entityID of the row in the custom table
16 | - array $params - the parameters that were sent into the calling function
17 |
18 | ## Returns
19 |
20 | - null - the return value is ignored
21 |
22 | ## Example
23 |
24 | /**
25 | * This example compares the submitted value of a field with its current value
26 | */
27 | function MODULENAME_civicrm_customPre($op, $groupID, $entityID, &$params) {
28 | foreach ($params as $field) {
29 | if ($field['column_name'] == 'pipeline_stage') {
30 | //get existing value
31 | try {
32 | $existingValue = civicrm_api3('Contact', 'getvalue', [
33 | 'id' => $field['entity_id'],
34 | 'return' => "custom_{$field['custom_field_id']}",
35 | ]);
36 |
37 | if ($existingValue != $field['value']) {
38 | //create Activity to record the change
39 | }
40 | }
41 | catch (CiviCRM_API3_Exception $e) {}
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_dashboard.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_dashboard
2 |
3 | ## Summary
4 |
5 | This hook is called when rendering the dashboard page and can be
6 | used to add content to the dashboard page.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_dashboard( $contactID, &$contentPlacement = self::DASHBOARD_BELOW )
11 |
12 | ## Parameters
13 |
14 | - $contactID the contactID for whom the dashboard is being generated
15 | - $contentPlacement (output parameter) where should the hook content
16 | be displayed relative to the activity list. One of
17 | CRM_Utils_Hook::DASHBOARD_BELOW,
18 | CRM_Utils_Hook::DASHBOARD_ABOVE,
19 | CRM_Utils_Hook::DASHBOARD_REPLACE. Default is to add content
20 | BELOW the standard dashboard Activities listing. DASHBOARD_REPLACE
21 | replaces the standard Activities listing with the provided content.
22 |
23 | ## Returns
24 |
25 | - the HTML to include in the dashboard
26 |
27 | ## Example
28 | ```php
29 | function civitest_civicrm_dashboard($contactID, &$contentPlacement) {
30 | // REPLACE Activity Listing with custom content
31 | $contentPlacement = 3;
32 | $content = array(
33 | 'Custom Content' => "Here is some custom content: $contactID",
34 | 'Custom Table' => "
35 |
36 |
Contact Name
Date
37 |
Foo
Bar
38 |
Goo
Tar
39 |
",
40 | );
41 | return $content;
42 | }
43 | ```
44 | ### CiviTest example
45 | ```php
46 | function civitest_civicrm_dashboard_defaults($availableDashlets, &$defaultDashlets){
47 | $contactID = CRM_Core_Session::singleton()->get('userID');
48 | $defaultDashlets[] = array(
49 | 'dashboard_id' => 3,
50 | 'is_active' => 1,
51 | 'column_no' => 1,
52 | 'contact_id' => $contactID,
53 | );
54 | }
55 | ```
56 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_dashboard_defaults.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_dashboard_defaults
2 |
3 | ## Summary
4 |
5 | This hook is called while a contact views their dashboard for the first time and can be used to enable or disable the set of default dashlets.
6 |
7 |
8 | ## Definition
9 |
10 | hook_civicrm_dashboard_defaults($availableDashlets, &$defaultDashlets);
11 |
12 | ## Parameters
13 |
14 | - $availableDashlets - list of dashlets
15 | - $defaultDashlets - list of existing default dashlets
16 |
17 | ## Returns
18 |
19 | ## Example
20 |
21 | get('userID');
24 | $defaultDashlets[] = array(
25 | 'dashboard_id' => 3,
26 | 'is_active' => 1,
27 | 'column_no' => 1,
28 | 'contact_id' => $contactID,
29 | );
30 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_disable.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_disable
2 |
3 | ## Summary
4 |
5 | This hook is called when an extension is disabled.
6 |
7 | ## Notes
8 |
9 | To be specific, this hook is called when
10 | an extension's status changes from ***enabled*** to ***disabled**.* Each module
11 | will receive `hook_civicrm_disable` during its own disablement (but not
12 | during the disablement of unrelated modules).
13 |
14 | ## Parameters
15 |
16 | - None
17 |
18 | ## Returns
19 |
20 | - Void
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_emailProcessor.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_emailProcessor
2 |
3 | ## Summary
4 |
5 | This hook is called after *each* email has been processed by the script
6 | `bin/EmailProcessor.php`.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_emailProcessor( $type, &$params, $mail, &$result, $action = null )
11 |
12 | ## Parameters
13 |
14 | - @param string $type type of mail processed: 'activity' OR 'mailing'
15 | - @param array &$params the params that were sent to the CiviCRM API
16 | function
17 | - @param object $mail the mail object which is an ezcMail class
18 | - @param array &$result the result returned by the api call
19 | - @param string $action (optional ) the requested action to be
20 | performed if the types was 'mailing'
21 |
22 | ## Returns
23 |
24 | - null
25 |
26 | ## Availability
27 |
28 | This hook was first available in CiviCRM 3.4.0
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_emailProcessorContact.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_emailProcessorContact
2 |
3 | ## Summary
4 |
5 | This hook is called by the Email Processor when deciding which
6 | contact to create an activitity for recording an inbound email.
7 |
8 | ## Notes
9 |
10 | You can use this hook to choose a different
11 | contact or decide whether it should create contacts.
12 |
13 | ## Definition
14 |
15 | hook_civicrm_emailProcessorContact($email, $contactID, &$result)
16 |
17 | ## Parameters
18 |
19 | - @param string $email - the email address
20 | - @param int $contactID - the contactID that matches this email address, IF it exists
21 | - @param array $result (reference) has two fields:
22 | - contactID - the new (or same) contactID
23 | - action - 3 possible values:
24 | - `CRM_Utils_Mail_Incoming::EMAILPROCESSOR_CREATE_INDIVIDUAL` - create a new contact record
25 | - `CRM_Utils_Mail_Incoming::EMAILPROCESSOR_OVERRIDE` - use the new contactID
26 | - `CRM_Utils_Mail_Incoming::EMAILPROCESSOR_IGNORE` - skip this email address
27 |
28 | ## Returns
29 |
30 | - null
31 |
32 | ## Availability
33 |
34 | This hook was first available in CiviCRM 4.1.0
35 |
36 | ## Example
37 |
38 | ```php
39 | function civitest_civicrm_emailProcessorContact($email, $contactID, &$result) {
40 | require_once 'CRM/Utils/Mail/Incoming.php';
41 |
42 | // first split the email into name and domain
43 | // really simple, definitely wrong implementation
44 | list($mailName, $mailDomain) = CRM_Utils_System::explode('@', $email, 2);
45 |
46 | // we are doing all our checks based on mailDomain, so if empty
47 | // return and let EmailProcessor do its own thing
48 | if (empty($mailDomain)) {
49 | return;
50 | }
51 |
52 | define('FILE_TO_ORG_ALWAYS_TAG', 'MyTag1');
53 | $orgID = _civitest_find_org_with_tag(FILE_TO_ORG_ALWAYS_TAG, $mailDomain);
54 | if ($orgID) {
55 | $result = array(
56 | 'contactID' => $orgID,
57 | 'action' => CRM_Utils_Mail_Incoming::EMAILPROCESSOR_OVERRIDE,
58 | );
59 | return;
60 | }
61 |
62 | // if we already have a match, we will
63 | // return and let EmailProcessor do its own thing
64 | if ($contactID) {
65 | return;
66 | }
67 |
68 | // Orgs with this tag will have same-domain emails filed on them only if it
69 | // passes through the ALWAYS tag check without finding a match, AND it does
70 | // not match an individual.
71 | define('FILE_TO_ORG_INDIVIDUAL_UNMATCHED_TAG', 'MyTag2');
72 | $orgID = _civitest_find_org_with_tag(FILE_TO_ORG_INDIVIDUAL_UNMATCHED_TAG, $mailDomain);
73 | if ($orgID) {
74 | $result = array(
75 | 'contactID' => $orgID,
76 | 'action' => CRM_Utils_Mail_Incoming::EMAILPROCESSOR_OVERRIDE);
77 | return;
78 | }
79 |
80 | $result = array('action' => CRM_Utils_Mail_Incoming::EMAILPROCESSOR_CREATE_INDIVIDUAL);
81 | }
82 | ```
83 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_enable.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_enable
2 |
3 | ## Summary
4 |
5 | This hook is called when an extension is re-enabled.
6 |
7 | ## Notes
8 |
9 | To be specific, this hook is called when an extension's
10 | status changes from ***disabled*** to ***enabled.***
11 |
12 | It is *NOT* called when the status changes from ***uninstalled*** to
13 | ***enabled***. Each module will receive `hook_civicrm_enable` during its
14 | own re-enablement (but not during the re-enablement of unrelated
15 | modules).
16 |
17 | For more background, see also [API and the Art of
18 | Installation](http://civicrm.org/blogs/totten/api-and-art-installation).
19 |
20 | ## Parameters
21 |
22 | - None
23 |
24 | ## Returns
25 |
26 | - Void
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_entityRefFilters.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_entityRefFilters
2 |
3 | ## Summary
4 |
5 | This hook is called when filters and create links for entityRef field is build.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_entityRefFilters(&$filters, &$links)
10 |
11 | ## Parameters
12 |
13 | - array $filters - reference to list of filters
14 | - array $links - reference to list of create links
15 |
16 | ## Returns
17 |
18 | ## Example
19 |
20 | /**
21 | * Implements hook_civicrm_entityRefFilters().
22 | *
23 | * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityRefFilters
24 | */
25 | function modulename_civicrm_entityRefFilters(&$filters, &$links) {
26 | // Add New Staff link on entityRef field of contact
27 | $links['Contact'][] = [
28 | 'label' => ts('New Staff'),
29 | 'url' => CRM_Utils_System::url('/civicrm/profile/create', 'reset=1&context=dialog&gid=5'),
30 | 'type' => 'Individual',
31 | 'icon' => 'fa-user',
32 | ];
33 |
34 | // Add Do not email filter on contact entity ref field.
35 | $filters['Contact'][] = [
36 | 'key' => 'do_not_email',
37 | 'value' => ts('Do Not Email'),
38 | ];
39 | // Add Marital status filter on contact entity ref field.
40 | $filters['Contact'][] = [
41 | 'key' => 'custom_2',
42 | 'value' => ts('Marital status'),
43 | ];
44 |
45 | // Add custom field of address as filter on contact entity ref field.
46 | $filters['Contact'][] = [
47 | 'key' => 'custom_34',
48 | 'value' => ts('Belongs to'),
49 | 'entity' => 'Address',
50 | ];
51 | }
52 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_entityTypes.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_entityTypes
2 |
3 | ## Summary
4 |
5 | This hook is used to declare a new type of entity, for example a booking extension might want to declare a *Resource* entity.
6 |
7 | ## Notes
8 |
9 | [See this tutorial](../extensions/civix.md#generate-entity) for a more complete description of creating new types of entities.
10 |
11 | ## Definition
12 |
13 | ```php
14 | hook_civicrm_entityTypes(&$entityTypes)
15 | ```
16 |
17 | ## Parameters
18 |
19 | * `$entityTypes` is a two-dimensional associative array. Each element in the array has:
20 |
21 | * A **key** which is the DAO name of the entity as a string (e.g. `'CRM_Report_DAO_Instance'`), although this has not always been enforced.
22 |
23 | * A **value** which is an associative with the following elements:
24 |
25 | * `'name'`: *string, required* - a unique short name (e.g. `"ReportInstance"`)
26 |
27 | * `'class'`: *string, required* - a PHP DAO class (e.g.`"CRM_Report_DAO_Instance"`)
28 |
29 | * `'table'`: *string, required* - a SQL table name (e.g. `"civicrm_report_instance"`)
30 |
31 | * `'fields_callback'`: *array, optional* - a list of callback functions which can modify the DAO field metadata. `function($class, &$fields)` Added circa 4.7.11+
32 |
33 | * `'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+
34 |
35 |
36 | ## Returns
37 |
38 | * null
39 |
40 | ## Examples
41 |
42 | ### Add new entities
43 |
44 | This example is taken from CiviVolunteer [here](https://github.com/civicrm/org.civicrm.volunteer/blob/eafc2b0c3966a492a3080ac70abe06cbd960a00e/volunteer.php#L333).
45 |
46 | ```php
47 | /**
48 | * Implements hook_civicrm_apiWrappers().
49 | */
50 | function volunteer_civicrm_entityTypes(&$entityTypes) {
51 | $entityTypes[] = array(
52 | 'name' => 'VolunteerNeed',
53 | 'class' => 'CRM_Volunteer_DAO_Need',
54 | 'table' => 'civicrm_volunteer_need',
55 | );
56 | $entityTypes[] = array(
57 | 'name' => 'VolunteerProject',
58 | 'class' => 'CRM_Volunteer_DAO_Project',
59 | 'table' => 'civicrm_volunteer_project',
60 | );
61 | $entityTypes[] = array(
62 | 'name' => 'VolunteerProjectContact',
63 | 'class' => 'CRM_Volunteer_DAO_ProjectContact',
64 | 'table' => 'civicrm_volunteer_project_contact',
65 | );
66 | }
67 | ```
68 |
69 | ### Alter metadata for existing entities
70 |
71 | This functionality was added in (approximately) v4.7.11.
72 |
73 | ```php
74 | /**
75 | * Implements hook_civicrm_apiWrappers().
76 | */
77 | function apilogging_civicrm_entityTypes(&$entityTypes) {
78 | $entityTypes['CRM_Contact_DAO_Contact']['fields_callback'][]
79 | = function ($class, &$fields) {
80 | unset($fields['created_date']['export']);
81 | };
82 | }
83 | ```
84 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_eventDiscount.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_eventDiscount
2 |
3 | ## Summary
4 |
5 | This hook allows you to apply a customized discount to an event
6 | registration.
7 |
8 | ## Notes
9 |
10 | !!! caution
11 | This hook is outdated - notable, CiviDiscount does not make use of it.
12 |
13 | ## Definition
14 |
15 | eventDiscount(&$form, &$params)
16 |
17 | ## Parameters
18 |
19 | - &$form - An object of type CRM_Event_Form_Registration_Confirm.
20 | - &$params - An array containing $form->_params.
21 |
22 | ## Returns
23 |
24 | - mixed
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_fieldOptions.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_fieldOptions
2 |
3 | ## Summary
4 |
5 | This hook allows you to dynamically modify the option list for any field (including custom fields).
6 |
7 | ## Definition
8 |
9 | hook_civicrm_fieldOptions($entity, $field, &$options, $params)
10 |
11 | ## Parameters
12 |
13 | - **$entity** (string): API entity e.g. 'Contact', 'Email',
14 | 'Contribution'
15 | - **$field** (string): Name of field e.g. 'phone_type_id',
16 | 'custom_12'
17 | - **$options** (array): Array of key=>label options. Your hook may
18 | modify these at will.
19 | - **$params** (array): Parameters sent to the pseudoconstant lookup
20 | function. Especially noteworthy among them is *context*.
21 |
22 | ## See Also
23 |
24 | See [Pseudoconstant (option list) Reference](../framework/pseudoconstant.md)
25 | for more information about how option lists work and the *context*
26 | parameter.
27 |
28 | ## Example
29 |
30 | function example_civicrm_fieldOptions($entity, $field, &$options, $params) {
31 | if ($entity == 'Case' && $field == 'case_type_id') {
32 | if (!CRM_Core_Permission::check('access all cases and activities')) {
33 | // Remove access to certain case types for non-authorized users
34 | unset($options[3], $options[5]);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_fileSearches.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_fileSearches
2 |
3 | ## Summary
4 |
5 | This hook allows you to add a reference to a file search service (e.g. Solr).
6 |
7 | ## Availability
8 |
9 | This hook is available in CiviCRM 4.5+.
10 |
11 | ## Definition
12 |
13 | function fileSearches(&$fileSearches)
14 |
15 | ## Parameters
16 |
17 | - &$fileSearches - an array whose elements are all of type
18 | CRM_Core_FileSearchInterface.
19 |
20 | ## Returns
21 |
22 | - mixed
23 |
24 | ## Example
25 |
26 | function apachesolr_civiAttachments_civicrm_fileSearches(&$fileSearches) {
27 | require_once __DIR__ . '/DrupalSolrCiviAttachmentSearch.php';
28 | $fileSearches[] = new DrupalSolrCiviAttachmentSearch();
29 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_geocoderFormat.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_geocoderFormat
2 |
3 | ## Summary
4 |
5 | This hook allows you to manipulate the Address object during geocoding,
6 | for instance to extract additional fields from the geocoder's returned
7 | XML.
8 |
9 | ## Availability
10 |
11 | This hook was first available in CiviCRM 4.7.7.
12 |
13 | ## Definition
14 |
15 | hook_civicrm_geocoderFormat($geoProvider, &$values, $xml)
16 |
17 | ## Parameters
18 |
19 | - @param string $geoProvider - A short name for the geocoder. Core
20 | geocoders are 'Google' and 'Yahoo.'
21 | - @param array $values - The address that was passed to the geocoder.
22 | - @param SimpleXMLElement $xml - The response from the geocoder.
23 |
24 |
25 |
26 |
27 |
28 | ## Details
29 |
30 | ## Example
31 |
32 | **Populate the "county ID" field when using the Google geoprovider.**
33 |
34 | function countylookup_civicrm_geocoderFormat($geoProvider, &$values, $xml) {
35 | if($geoProvider !== 'Google') {
36 | exit;
37 | }
38 | foreach ($xml->result->address_component as $test) {
39 | $type = (string) $test->type[0];
40 | if ($type == 'administrative_area_level_1') {
41 | $stateName = (string) $test->long_name;
42 | }
43 | if ($type == 'administrative_area_level_2') {
44 | $countyName = (string) $test->long_name;
45 | }
46 | }
47 | // Take off the word "County".
48 | $countyName = trim(str_replace('County', '', $countyName));
49 | // For < 4.7 compatibility, do 2 API calls instead of a join
50 | $result = civicrm_api3('StateProvince', 'get', array(
51 | 'return' => array("id"),
52 | 'name' => $stateName,
53 | ));
54 | $state_province_id = $result['id'];
55 | $result = civicrm_api3('County', 'get', array(
56 | 'sequential' => 1,
57 | 'state_province_id' => $state_province_id,
58 | // 'state_province_id.name' => $stateName,
59 | 'name' => $countyName,
60 | ));
61 | $countyId = $result['id'];
62 | $values['county_id'] = $countyId;
63 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_getAssetUrl.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_getAssetUrl
2 |
3 | ## Summary
4 |
5 | This hook is called when building a link to a semi-static asset, allowing you to modify the params the asset will be built with.
6 |
7 | ## Notes
8 |
9 | For more discussion, see [AssetBuilder](../framework/asset-builder.md).
10 |
11 | ## Definition
12 |
13 | hook_civicrm_getAssetUrl(&$asset, &$params)
14 |
15 | ## Parameters
16 |
17 | * `$asset` (string): the logical file name of an asset (ex: `hello-world.json`)
18 | * `$params` (array): an optional set of parameters describing how to build the asset
19 |
20 | ## Returns
21 |
22 | * null
23 |
24 | ## Example
25 |
26 | ```php
27 | function mymodule_civicrm_getAssetUrl(&$asset, &$params) {
28 | if ($asset === 'hello-world.json') {
29 | $params['planet'] = 'Earth';
30 | }
31 | }
32 | ```
33 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_idsException.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_idsException
2 |
3 | ## Summary
4 |
5 | This hook allows you to modify the list of form or page paths where
6 | submitted data should not be sent through PHPIDS, the intrusion
7 | detection system (IDS).
8 |
9 | ## Notes
10 |
11 | This is one of two ways to bypass the IDS. The other is a CMS-level permission "skip IDS check".
12 |
13 | ## Definition
14 |
15 | hook_civicrm_idsException(&$skip)
16 |
17 | ## Parameters
18 |
19 | - $skip - an array of paths that should be skipped.
20 |
21 | The initial value of $skip is defined in CRM_Core_IDS::check(), which
22 | is where this hook is invoked.
23 |
24 | ## Returns
25 |
26 | - null
27 |
28 | ## Example
29 |
30 | /**
31 | * Implementation of hook_civicrm_idsException().
32 | *
33 | * Prevent values on my form from being processed by the IDS
34 | */
35 | function myextension_civicrm_idsException(&$skip) {
36 | $skip[] = 'civicrm/myform';
37 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_inboundSMS.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_inboundSMS
2 |
3 | ## Summary
4 |
5 | This hook is called when an inbound SMS has been received, processed by the
6 | provider extension, but not matched or processed by CiviSMS.
7 |
8 | ## Availability
9 |
10 | 4.7.21+
11 |
12 | ## Definition
13 |
14 | ```php
15 | hook_civicrm_inboundSMS(&$message)
16 | ```
17 |
18 | ## Parameters
19 |
20 | * `CRM_SMS_Message` Object `$message` - The SMS Message
21 |
22 |
23 | ## Examples
24 |
25 | Alter the incoming SMS From number to match how phone numbers are stored in the database
26 |
27 | ```php
28 | function myextension_civicrm_inboundSMS(&$message) {
29 | // Alter the sender phone number to match the format used in database
30 | $message->from = str_replace('+614', '04', $message->from);
31 | }
32 | ```
33 |
34 | Automatically add contacts to a group if the message contains 'SUBSCRIBE'
35 |
36 | ```php
37 | function myextension_civicrm_inboundSMS(&$message) {
38 | // Add contact to group if message contains keyword
39 | if (stripos($message->body, 'SUBSCRIBE') !== false) {
40 | $escapedFrom = CRM_Utils_Type::escape($message->from, 'String');
41 | $message->fromContactID = CRM_Core_DAO::singleValueQuery('SELECT contact_id FROM civicrm_phone JOIN civicrm_contact ON civicrm_contact.id = civicrm_phone.contact_id WHERE !civicrm_contact.is_deleted AND phone LIKE "%' . $escapedFrom . '"');
42 | if ($message->fromContactID) {
43 | CRM_Contact_BAO_GroupContact::AddContactsToGroup(
44 | array($message->fromContactID), 5, 'SMS', 'Added'
45 | );
46 | }
47 | }
48 | }
49 | ```
50 |
51 | Send an automatic response to incoming messages
52 |
53 | ```php
54 | function myextension_civicrm_inboundSMS(&$message) {
55 | // Send an automatic response
56 | $provider = CRM_SMS_Provider::singleton(array('provider_id' => 1));
57 | $provider->send($message->from, array('To' => $message->from), 'Thank you for your message', NULL, NULL);
58 | }
59 | ```
60 |
61 | Implement custom logic to match the message to the sender
62 |
63 | ```php
64 | function myextension_civicrm_inboundSMS(&$message) {
65 | // Implement custom matching logic
66 | // If there are multiple contacts with the phone number, preference the one that has been sent an SMS most recently
67 | $escapedFrom = CRM_Utils_Type::escape($message->from, 'String');
68 | $message->fromContactID = CRM_Core_DAO::singleValueQuery("
69 | SELECT civicrm_contact.id FROM civicrm_phone
70 | JOIN civicrm_contact ON civicrm_contact.id = civicrm_phone.contact_id
71 | LEFT JOIN civicrm_activity_contact ON civicrm_activity_contact.contact_id = civicrm_contact.id
72 | AND civicrm_activity_contact.record_type_id = 3
73 | LEFT JOIN civicrm_activity ON civicrm_activity.id = civicrm_activity_contact.activity_id
74 | AND civicrm_activity.activity_type_id = 4
75 | WHERE !civicrm_contact.is_deleted
76 | AND phone LIKE \"%" . $escapedFrom . "\"
77 | ORDER BY civicrm_activity.activity_date_time DESC"
78 | );
79 | }
80 | ```
81 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_install.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_install
2 |
3 | ## Summary
4 |
5 | This hook is called when an extension is installed.
6 |
7 | ## Notes
8 |
9 | To be specific, this hook is called when an extension's
10 | status changes from ***uninstalled*** to ***enabled***
11 |
12 | It is *NOT* called when an extension moves from ***disabled*** to ***enabled***
13 | (but `hook_civicrm_enable` is called at this event). Each module will
14 | receive `hook_civicrm_install` during its own installation (but not
15 | during the installation of unrelated modules).
16 |
17 | For more background, see [API and the Art of
18 | Installation](http://civicrm.org/blogs/totten/api-and-art-installation).
19 |
20 | ## Parameters
21 |
22 | - None
23 |
24 | ## Returns
25 |
26 | - Void
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_mailingGroups.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_mailingGroups
2 |
3 | ## Summary
4 |
5 | This hook is called when composing a mailing allowing you to include or exclude
6 | other groups as needed.
7 |
8 | ## Definition
9 |
10 | ```php
11 | hook_civicrm_mailingGroups(&$form, &$groups, &$mailings)
12 | ```
13 |
14 | ## Parameters
15 |
16 | - object `$form` - the form object for which groups / mailings being displayed
17 |
18 | - array `$groups` - the list of groups being included / excluded
19 |
20 | - array `$mailings` - the list of mailings being included / excluded
21 |
22 | ## Returns
23 |
24 | - `NULL` - the return value is ignored
25 |
26 | ## Example
27 |
28 | ```php
29 | function civitest_civicrm_mailingGroups( &$form, &$groups, &$mailings ) {
30 |
31 | // unset group id 4
32 | unset( $groups[4] );
33 |
34 | // add a fictitious mailing
35 | $mailings[1] = 'This mailing does not exist';
36 | }
37 | ```
38 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_membershipTypeValues.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_membershipTypeValues
2 |
3 | ## Summary
4 |
5 | This hook is called when composing the array of membership types and
6 | their costs during a membership registration (new or renewal).
7 |
8 | ## Notes
9 |
10 | The hook is called on initial page load and also reloaded after submit ([PRG
11 | pattern](https://en.wikipedia.org/wiki/Post/Redirect/Get)). You can use it to alter the membership types when first
12 | loaded, or after submission (for example if you want to gather data in
13 | the form and use it to alter the fees).
14 |
15 | ## Definition
16 |
17 | ```php
18 | hook_civicrm_membershipTypeValues(&$form, &$membershipTypeValues)
19 | ```
20 |
21 | ## Parameters
22 |
23 | - object `$form` - the form object that is presenting the page
24 | - array `$membershipTypeValues` - the membership types and their amounts
25 |
26 | ## Examples
27 |
28 | Give a 50% discount to some memberships in the sample data
29 |
30 | ```php
31 | function civitest_civicrm_membershipTypeValues(&$form, &$membershipTypeValues) {
32 | $membershipTypeValues[1]['name'] = 'General (50% discount)';
33 | $membershipTypeValues[1]['minimum_fee'] = '50.00';
34 |
35 | $membershipTypeValues[2]['name'] = 'Student (50% discount)';
36 | $membershipTypeValues[2]['minimum_fee'] = '25.00';
37 | }
38 | ```
39 |
40 | Modify specific fee values
41 |
42 | ```php
43 | function mymodule_civicrm_membershipTypeValues(&$form, &$membershipTypeValues) {
44 | foreach ($membershipTypeValues as &$values) {
45 | if ($values['name'] == 'General') {
46 | $values['minimum_fee'] = "5.55";
47 | }
48 | if ($values['name'] == 'Student') {
49 | $values['minimum_fee'] = "2.22";
50 | }
51 | }
52 | }
53 | ```
54 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_notePrivacy.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_notePrivacy
2 |
3 | ## Summary
4 |
5 | This hook provides a way to override the default privacy behavior for
6 | notes.
7 |
8 | ## Notes
9 |
10 | If a user has the "View All Notes" permission, this hook is bypassed.
11 |
12 | See also [this blog
13 | post](https://civicrm.org/blogs/allenshaw/adding-privacy-and-comments-civicrm-notes).
14 |
15 | ## Availability
16 |
17 | This hook is available in CiviCRM 3.3+.
18 |
19 | ## Definition
20 |
21 | ```php
22 | hook_civicrm_notePrivacy(&$noteValues)
23 | ```
24 |
25 | ## Parameters
26 |
27 | - array `$noteValues` - The values from an object of type
28 | `CRM_Core_DAO_Note`, converted to an array.
29 |
30 | ## Returns
31 |
32 | - `NULL`
33 |
34 | ## Example
35 |
36 | ```php
37 | function civitest_civicrm_notePrivacy(&$noteValues) {
38 | /* CiviCRM will check for existence of $note['notePrivacy_hidden'].
39 | * If this value is not set, CiviCRM will show or display the note
40 | * based on the default, which is to display private notes only to
41 | * the note author.
42 | * If this value is set, CiviCRM will hide the note if the value is
43 | * TRUE, and display the note if the value is FALSE.
44 | */
45 | if ($noteValues['is_private']) {
46 | if ($my_business_rules_say_so) {
47 | $noteValues['notePrivacy_hidden'] = TRUE;
48 | }
49 | else {
50 | $noteValues['notePrivacy_hidden'] = FALSE;
51 | }
52 | }
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_optionValues.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_optionValues
2 |
3 | ## Summary
4 |
5 | This hook was deprecated in 4.7 in favor of [hook_civicrm_fieldOptions](hook_civicrm_fieldOptions.md).
6 |
7 | ## Notes
8 |
9 | This hook is called after a option group is loaded. You can use this
10 | hook to add/remove options from the option group.
11 |
12 | Use [hook_civicrm_fieldOptions](hook_civicrm_fieldOptions.md) instead for modifying all option lists, not limited to items in the `civicrm_option_values` table.
13 |
14 | ## Definition
15 |
16 | ```php
17 | hook_civicrm_optionValues(&$options, $groupName)
18 | ```
19 |
20 | ## Parameters
21 |
22 | - array `$options` - the current set of options
23 | - string `$groupName` - the name of the option group
24 |
25 | ## Returns
26 |
27 | - `NULL`
28 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_pageRun.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_pageRun
2 |
3 | ## Summary
4 |
5 | This hook is called before a CiviCRM page is rendered.
6 |
7 |
8 | ## Notes
9 |
10 | This does **not** execute on every CiviCRM *page* in the
11 | general sense. CiviCRM's pages are classified as either 'Forms' or
12 | 'Pages', and this only runs on pages classified as 'Pages'. If you are
13 | not sure if a particular page is a Page, test it by adding some
14 | temporary debug code to `/CRM/Utils/Hook.php`
15 |
16 | ## Definition
17 |
18 | hook_civicrm_pageRun( &$page )
19 |
20 | ## Parameters
21 |
22 | - $page the page being rendered
23 |
24 | ## Returns
25 |
26 | - null
27 |
28 | ## Example
29 |
30 | The example below is for the enhanced tags extension. In this extension
31 | a coordinator can be assigned to a CiviCRM tag. In the pageRun hook
32 | below the coordinators are added to an array which is sent to the page
33 | template
34 |
35 | function enhancedtags_civicrm_pageRun(&$page) {
36 | $pageName = $page->getVar('_name');
37 | if ($pageName == 'CRM_Admin_Page_Tag') {
38 | /*
39 | * retrieve all tag enhanced data and put in array with tag_id as index
40 | */
41 | $enhancedTags = CRM_Enhancedtags_BAO_TagEnhanced::getValues(array());
42 | $coordinators = array();
43 | foreach ($enhancedTags as $enhancedTag) {
44 | $coordinators[$enhancedTag['tag_id']] = CRM_Enhancedtags_BAO_TagEnhanced::getCoordinatorName($enhancedTag['coordinator_id']);
45 | }
46 | $page->assign('coordinators', $coordinators);
47 | }
48 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_postEmailSend.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_postEmailSend
2 |
3 | ## Summary
4 |
5 | This hook is called when an email has been successfully sent by CiviCRM,
6 | but not on an error.
7 |
8 |
9 | ## Notes
10 |
11 | This is only triggered by activity emails, not bulk mailings.
12 |
13 | ## Definition
14 |
15 | hook_civicrm_postEmailSend( &$params )
16 |
17 | ## Parameters
18 |
19 | - $params the mailing params
20 |
21 | ## Details
22 |
23 | - $params array fields include: groupName, from, toName, toEmail,
24 | subject, cc, bcc, text, html, returnPath, replyTo, headers,
25 | attachments (array)
26 |
27 | ## Example
28 |
29 | /**
30 | * Implementation of hook_civicrm_postEmailSend( )
31 | * Update the status of activity created in hook_civicrm_alterMailParams, and add target_contact_id
32 | */
33 | function mte_civicrm_postEmailSend(&$params) {
34 | // check if an activityId was added in hook_civicrm_alterMailParams
35 | // if so, update the activity's status and add a target_contact_id
36 | if(CRM_Utils_Array::value('activityId', $params)){
37 | $activityParams = array(
38 | 'id' => $params['activityId'],
39 | 'status_id' => 2,
40 | 'version' => 3,
41 | 'target_contact_id' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Email', $params['toEmail'], 'contact_id', 'email'),
42 | );
43 | $result = civicrm_api( 'activity','create',$activityParams );
44 | }
45 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_postIPNProcess.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_postIPNProcess
2 |
3 | ## Summary
4 |
5 | This hook allows you to do custom processing of IPN Data following CiviCRM processing.
6 |
7 | ## Notes
8 |
9 | This hook as present only calls when CiviCRM has successfully processed the IPN.
10 |
11 | With this hook you can take any of the data including custom data stored via hook_civicrm_alterPaymentProcessorParms into the IPN.
12 |
13 | ## Definition
14 |
15 | hook_civicrm_postIPNProcess(&$IPNData);
16 |
17 | ## Parameters
18 |
19 | - $IPNData - Array of IPN data recieved from a payment processor.
20 |
21 | ## Returns
22 |
23 | ## Example
24 |
25 | ```php
26 | function civitest_civicrm_postIPNProcess(&$IPNData) {
27 | if (!empty($IPNData['custom'])) {
28 | $customParams = json_decode($IPNData['custom'], TRUE);
29 | if (!empty($customParams['gaid'])) {
30 | // trigger GA event id for e-commerce tracking.
31 | }
32 | }
33 | }
34 | ```
35 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_postInstall.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_postInstall
2 |
3 | ## Summary
4 |
5 | This hook is called immediately after an extension is installed.
6 |
7 | ## Notes
8 |
9 | - Unlike most CiviCRM hooks, hook_civicrm_postInstall is defined not
10 | in CRM_Utils_Hook but in CRM_Extension_Manager_Module.
11 | - Each module will receive hook_civicrm_postInstall after its own
12 | installation (but not following the installation of unrelated
13 | modules).
14 |
15 | ## Definition
16 |
17 | hook_civicrm_postInstall()
18 |
19 | ## Parameters
20 |
21 | - None
22 |
23 | ## Returns
24 |
25 | - Void
26 |
27 | ## Example
28 |
29 | This hook may be useful as a final installation step. Use it to perform
30 | tasks which depend on something that is a product of the installation
31 | itself.
32 |
33 | For example, as of civix version 16.9.0, it is used to record the schema
34 | version number (i.e., which upgrade_N methods have run) in the
35 | civicrm_extension table. This step has to be performed in
36 | hook_civicrm_postInstall because the record doesn't yet exist to be
37 | updated in hook_civicrm_install.
38 |
39 | Another potential use is to act on settings or managed entities that are
40 | created during the installation (but not necessarily in order that you
41 | want them to be created):
42 |
43 | function hook_civicrm_postInstall() {
44 | $customFieldId = civicrm_api3('CustomField', 'getvalue', array(
45 | 'return' => array("id"),
46 | 'name' => "customFieldCreatedViaManagedHook",
47 | ));
48 | civicrm_api3('Setting', 'create', array(
49 | 'myWeirdFieldSetting' => array('id' => $customFieldId, 'weirdness' => 1),
50 | ));
51 | }
52 |
53 |
54 |
55 |
56 |
57 |
58 | \
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_postJob.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_postJob
2 |
3 | ## Summary
4 |
5 | This hook is called after a scheduled job is executed or was interrupted by an exception.
6 |
7 | ## Notes
8 |
9 | We suspect this hook will be useful for developers who want to monitor the execution time of scheduled jobs or check whether a job is stuck (started but never ends). It can also be used to monitor the execution status of jobs. It is useful in combination with the hook `hook_civicrm_preJob`.
10 |
11 | ## Definition
12 |
13 | ```php
14 | hook_civicrm_postJob($job, $params, $result)
15 | ```
16 |
17 | ## Parameters
18 |
19 | - $job - instance of CRM_Core_DAO_Job, the executed job
20 | - $params - array of arguments given to the job
21 | - $result - It can be:
22 | + the array returned by the API call of the job
23 | + the exception that interrupted the execution of the job
24 |
25 | ## Return
26 | None
27 |
28 | ## Example
29 |
30 | ```php
31 | function sencivity_civicrm_postJob($job, $params, $result) {
32 | if ($result['is_error']) {
33 | CRM_Core_Error::debug_log_message("Job $job->name failed!");
34 | }
35 | }
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_postMailing.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_postMailing
2 |
3 | ## Summary
4 |
5 | This hook is called at the successful completion of a bulk mailing done through CiviMail.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_postMailing( $mailingId )
10 |
11 | ## Parameters
12 |
13 | - $mailingId : the ID for the mailing
14 |
15 | ## Example
16 |
17 | /**
18 | * Implementation of hook_civicrm_postMailing()
19 | */
20 | function myextension_civicrm_postMailing($mailingId) {
21 | $report = CRM_Mailing_BAO_Mailing::report($mailingId);
22 | if (!empty($report['created_id'])) {
23 | // Store activity in mailing creator's record
24 | $params = array(
25 | 'status_id' => 2,
26 | 'target_contact_id' => $report['created_id'],
27 | 'source_contact_id' => 1,
28 | 'activity_type_id' => 1,
29 | 'subject' => "Mailing $mailingId has completed.",
30 | 'activity_date_time' => 'now',
31 | );
32 | civicrm_api3('Activity', 'create', $params);
33 | }
34 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_postSave_table_name.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_postSave_table_name
2 |
3 | ## Summary
4 |
5 | This hook is called after writing to a database table that has an
6 | associated DAO, including core tables but not custom tables or log
7 | tables.
8 |
9 | ## Parameters
10 |
11 | $dao: The object that has been saved
12 |
13 | ## Definition
14 |
15 | `hook_civicrm_postSave_[table_name]($dao)`
16 |
17 | ## Example
18 |
19 | hook_civicrm_postSave_civicrm_contact($dao) {
20 | $contact_id = $dao->id;
21 | // Do something with this contact, but be careful not to create an infinite loop if you update it via the api! This hook will get called again with every update.
22 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_post_case_merge.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_post_case_merge
2 |
3 | ## Summary
4 |
5 | This hook is called after a case merge happens.
6 |
7 | ## Notes
8 |
9 | A case merge is when two cases are merged or when a case is reassigned to another client.
10 |
11 | Added in CIviCRM 4.5
12 |
13 | ## Definition
14 |
15 | civicrm_post_case_merge($mainContactId, $mainCaseId, $otherContactId, $otherCaseId, $changeClient)
16 |
17 | ## Parameters
18 |
19 | - $mainContactId - Contact ID of the new case (if set already)
20 | - $mainCaseId - Case ID of the new case (if set already)
21 | - $otherContactId - Contact ID of the original case
22 | - $otherCaseId - Case ID of the original case
23 | - $changeClient - boolean if this function is called to change
24 | clients
25 |
26 | ## Return
27 |
28 | - Returns null
29 |
30 | ## Example
31 |
32 | In this example we want to move the linked documents of a case to the
33 | new case.
34 |
35 | function documents_civicrm_post_case_merge($mainContactId, $mainCaseId = NULL, $otherContactId = NULL, $otherCaseId = NULL, $changeClient = FALSE) {
36 | $repo = CRM_Documents_Entity_DocumentRepository::singleton();
37 | if (!empty($mainCaseId) && !empty($otherCaseId)) {
38 | $docs = $repo->getDocumentsByCaseId($otherCaseId);
39 | $case = civicrm_api('Case', 'getsingle', array('id' => $otherCaseId, 'version' => 3));
40 | foreach($docs as $doc) {
41 | $doc->addCaseId($mainCaseId);
42 | if ($changeClient) {
43 | $doc->removeCaseId($otherCaseId); //remove the old case
44 | }
45 | foreach($case['client_id'] as $cid) {
46 | $doc->addContactId($cid);
47 | }
48 | $repo->persist($doc);
49 | }
50 | }
51 | }
52 |
53 |
54 |
55 | ## See also
56 |
57 | [hook_civicrm_pre_case_merge](hook_civicrm_pre_case_merge.md)
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_preJob.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_preJob
2 |
3 | ## Summary
4 |
5 | This hook is called before a scheduled job is executed.
6 |
7 | ## Notes
8 |
9 | This hook does not allow aborting the job execution or modifying its parameters.
10 |
11 | We suspect this hook will be useful for developers who want to monitor the execution time of scheduled jobs or check whether a job is stuck (started but never ends). It is useful in combination with the hook `hook_civicrm_postJob`.
12 |
13 | ## Definition
14 |
15 | ```php
16 | hook_civicrm_preJob($job, $params)
17 | ```
18 |
19 | ## Parameters
20 |
21 | - $job - instance of CRM_Core_DAO_Job, the job to be executed
22 | - $params - array of arguments to be given to the job
23 |
24 | ## Return
25 | None
26 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_preProcess.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_preProcess
2 |
3 | ## Summary
4 |
5 | This hook can be used to modify the behavior of a form before the
6 | `buildQuickForm` call.
7 |
8 |
9 | ## Notes
10 |
11 | There are some known issues with exception
12 | handling: [https://issues.civicrm.org/jira/browse/CRM-15683](https://issues.civicrm.org/jira/browse/CRM-15683).
13 |
14 | ## Definition
15 |
16 | hook_civicrm_preProcess($formName, &$form)
17 |
18 |
19 | ## Parameters
20 |
21 | - string $formName - the name of the form
22 | - object $form - reference to the form object
23 |
24 | ## Returns
25 |
26 | - null - the return value is ignored
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_pre_case_merge.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_pre_case_merge
2 |
3 | ## Summary
4 |
5 | This hook is called before a case merge happens.
6 |
7 | ## Notes
8 |
9 | A case merge is
10 | when two cases are merged or when a case is reassigned to another
11 | client.
12 |
13 | Added in CiviCRM 4.5
14 |
15 | ## Definition
16 |
17 | civicrm_pre_case_merge($mainContactId, $mainCaseId, $otherContactId, $otherCaseId, $changeClient)
18 |
19 | ## Parameters
20 |
21 | - $mainContactId - Contact ID of the new case (if set already)
22 | - $mainCaseId - Case ID of the new case (if set already)
23 | - $otherContactId - Contact ID of the original case
24 | - $otherCaseId - Case ID of the original case
25 | - $changeClient - boolean if this function is called to change
26 | clients
27 |
28 | ## Return
29 |
30 | - Returns null
31 |
32 | ## Example
33 |
34 | See for an example the documentation of the
35 | [hook_civicrm_post_case_merge](hook_civicrm_post_case_merge.md)
36 |
37 | ## See also
38 |
39 | [hook_civicrm_post_case_merge](hook_civicrm_post_case_merge.md)
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_processProfile.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_processProfile
2 |
3 | ## Summary
4 |
5 | This hook is called when processing a valid profile form submission (e.g. for "civicrm/profile/create" or "civicrm/profile/edit").
6 |
7 | ## Definition
8 |
9 | processProfile($profileName)
10 |
11 | ## Parameters
12 |
13 | - $profileName - the (machine readable) name of the profile.
14 |
15 | !!! Tip
16 | In SQL, this corresponds to the "name" column of table "civicrm_uf_group"
17 |
18 | ## Returns
19 |
20 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_queryObjects.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_queryObjects
2 |
3 | ## Summary
4 |
5 | This hook is called while building the core search query, allowing you to provide your own query objects which alter or extend the core search.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_queryObjects(&$queryObjects, $type = 'Contact')
10 |
11 | ## Parameters
12 |
13 | - $queryObjects - An array of Query Objects
14 | - $type - Search Context \
15 | \
16 |
17 | ## Example
18 |
19 | /** Taken from civiHR:/hrjob/hrjob.php **/
20 |
21 | function hrjob_civicrm_queryObjects(&$queryObjects, $type) {
22 | if ($type == 'Contact') {
23 | $queryObjects[] = new CRM_HRJob_BAO_Query();
24 | }
25 | elseif ($type == 'Report') {
26 | $queryObjects[] = new CRM_HRJob_BAO_ReportHook();
27 | }
28 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_recent.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_recent
2 |
3 | ## Summary
4 |
5 | This hook is called before storing recently viewed items.
6 |
7 | ## Definition
8 |
9 | recent(&$recentArray)
10 |
11 | ## Parameters
12 |
13 | - $recentArray - An array of recently viewed or processed items, for
14 | in place modification.
15 |
16 | ## Returns
17 |
18 | - array
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_referenceCounts.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_referenceCounts
2 |
3 | ## Summary
4 |
5 | This hook is called to determine the reference-count for a record.
6 |
7 | ## Notes
8 |
9 | For example, when counting references to the activity type "Phone Call", one
10 | would want a tally that includes:
11 |
12 | - The number of activity records which use "Phone Call"
13 | - The number of surveys which store data in "Phone Call" records
14 | - The number of case-types which can embed "Phone Call" records
15 |
16 | The reference-counter will automatically identify references stored in
17 | the CiviCRM SQL schema, including:
18 |
19 | - Proper SQL foreign-keys (declared with an SQL constraint)
20 | - Soft SQL foreign-keys that use the "entity_table"+"entity_id"
21 | pattern
22 | - Soft SQL foreign-keys that involve an OptionValue
23 |
24 | However, if you have references to stored in an external system (such as
25 | XML files or Drupal database), then you may want write a custom
26 | reference-counters.
27 |
28 | ## Definition
29 |
30 | hook_civicrm_referenceCounts($dao, &$refCounts)
31 |
32 | ## Parameters
33 |
34 | - $dao: ***CRM_Core_DAO***, the item for which we want a reference
35 | count
36 | - $refCounts: ***array***, each item in the array is an array with
37 | keys:
38 | - name: ***string***, eg
39 | "sql:civicrm_email:contact_id"
40 | - type: ***string***, eg "sql"
41 | - count: ***int***, eg "5" if there are 5 email addresses that
42 | refer to $dao
43 |
44 | ## Returns
45 |
46 | - None
47 |
48 | ## Example
49 |
50 | Suppose we've written a module ("familytracker") which relies on the
51 | "Child Of" relationship-type. Now suppose an administrator considered
52 | deleting "Child Of" -- we might want to determine if anything depends on
53 | "Child Of" and display a warning about possible breakage. This code
54 | would allow the "familytracker" to increase the reference-count for
55 | "Child Of".
56 |
57 | name_a_b == 'Child Of') {
60 | $refCounts[] = array(
61 | 'name' => 'familytracker:childof',
62 | 'type' => 'familytracker',
63 | 'count' => 1,
64 | );
65 | }
66 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_searchProfile.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_searchProfile
2 |
3 | ## Summary
4 |
5 | This hook is called while preparing a list of contacts (based on a
6 | profile).
7 |
8 | ## Definition
9 |
10 | searchProfile($profileName)
11 |
12 | ## Parameters
13 |
14 | - $profileName - the (machine readable) name of the profile.
15 |
16 | ## Returns
17 |
18 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_searchTasks.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_searchTasks
2 |
3 | ## Summary
4 |
5 | This hook is called to display the list of actions allowed after doing a
6 | search, allowing you to inject additional actions or to remove existing actions.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_searchTasks( $objectType, &$tasks )
11 |
12 | ## Parameters
13 |
14 | - $objectType - the object for this search - activity, campaign,
15 | case, contact, contribution, event, grant, membership, and pledge
16 | are supported.
17 | - $tasks - the current set of tasks for that custom field. You can
18 | add/remove existing tasks. Each task is an array with a title (eg
19 | 'title' => ts( 'Add Contacts to Group')) and a class (eg 'class'
20 | => 'CRM_Contact_Form_Task_AddToGroup'). Optional result
21 | (boolean) may also be provided. Class can be an array of classes
22 | (not sure what that does :( ). The key for new Task(s) should not
23 | conflict with the keys for core tasks of that $objectType, which
24 | can be found in CRM/$objectType/Task.php.
25 |
26 | ## Returns
27 |
28 | - null
29 |
30 | ## Example (Disable an existing task)
31 |
32 | function civitest_perm () {
33 | return array(
34 | 'access add contacts to group search action'
35 | );
36 | }
37 |
38 |
39 | function civitest_civicrm_searchTasks($objectType, &$tasks ) {
40 | if ( $objectType == 'contact' ) {
41 | // remove the action from the contact search results if the user doesn't have the permission
42 | if (! user_access( 'access add contacts to group search action' )) {
43 | unset($tasks[CRM_Core_Task::GROUP_ADD]);
44 | }
45 | }
46 | }
47 |
48 | ## Example (Add a new task)
49 |
50 | function smsconversation_civicrm_searchTasks( $objectName, &$tasks ){
51 | if($objectName == 'contact'){
52 | $tasks[] = [
53 | 'title' => 'SMS - schedule a conversation',
54 | 'class' => 'CRM_SmsConversation_Form_ScheduleMultiple'
55 | ];
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_selectWhereClause.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_selectWhereClause
2 |
3 | ## Summary
4 |
5 | This hook is called when executing a SELECT query.
6 |
7 | ## Notes
8 |
9 | The hook is called
10 | once for each entity in the query, allowing you to add (or remove)
11 | restrictions specific to that entity. Note that this hook will only be
12 | invoked for API calls if check_permissions is set to 1. It will be
13 | bypassed for API calls that do not set this parameter.
14 |
15 | This hook is new in 4.7 and coverage is limited. The Case entity is
16 | fully covered by this hook; selecting cases via api, ui, or searches
17 | will all invoke this hook. Most other entities are covered when being
18 | selected via api but not in the UI or searches.
19 |
20 | This hook is part of a general permissions refactoring which is not yet
21 | complete.
22 |
23 | The Contact entity is fully covered
24 | by [hook_civicrm_aclWhereClause](hook_civicrm_aclWhereClause.md)
25 | and that is the recommended hook for limiting access to contacts. For
26 | other entities, we need to increase coverage of this hook by using the
27 | api internally instead of directly executing sql, and by standardizing
28 | searches to use these permissions.
29 |
30 | ## Definition
31 |
32 | hook_civicrm_selectWhereClause($entity, &$clauses)
33 |
34 | ## Parameters
35 |
36 | - string $entity - name of entity being selected - follows api naming
37 | conventions (Contact, EntityTag, etc.)
38 | - array $clauses - (reference) array of clauses keyed by field\
39 | Uses the format array('field_name' => array('operator
40 | condition'))
41 |
42 | ## Returns
43 |
44 | - void
45 |
46 | ## Example
47 |
48 | function example_civicrm_selectWhereClause($entity, &$clauses) {
49 | // Restrict access to cases by type
50 | if ($entity == 'Case') {
51 | $clauses['case_type_id'][] = 'IN (1,2,3)';
52 | }
53 | }
54 |
55 | If your condition depends on joining onto another table, use a subquery,
56 | like so:
57 |
58 | function example_civicrm_selectWhereClause($entity, &$clauses) {
59 | // Restrict access to emails by contact type
60 | if ($entity == 'Email') {
61 | $clauses['contact_id'][] = "IN (SELECT id FROM civicrm_contact WHERE contact_type = 'Individual')";
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_summary.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_summary
2 |
3 | ## Summary
4 |
5 | This hook is called when the contact summary is rendered, allowing you to modify the summary with your own content.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_summary( $contactID, &$content, &$contentPlacement = CRM_Utils_Hook::SUMMARY_BELOW )
10 |
11 | ## Parameters
12 |
13 | - $contactID the contactID for whom the contact summary is being
14 | generated
15 | - $contentPlacement (output parameter) where should the hook content
16 | be displayed relative to the exiting content. One of
17 | CRM_Utils_Hook::SUMMARY_BELOW, CRM_Utils_Hook::SUMMARY_ABOVE,
18 | CRM_Utils_Hook::SUMMARY_REPLACE. Default is to add content BELOW
19 | default contact summary content.
20 |
21 | ## Example
22 |
23 | function civitest_civicrm_summary( $contactID, &$content, &$contentPlacement ) {
24 | // REPLACE default Contact Summary with your customized content
25 | $contentPlacement = CRM_Utils_Hook::SUMMARY_REPLACE;
26 | $content = "
27 |
28 |
Hook Data
29 |
Data 1
30 |
Data 2
31 |
32 | ";
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_summaryActions.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_summaryActions
2 |
3 | ## Summary
4 |
5 | This hook allows you to customize the context menu actions on the Contact
6 | Summary Page.
7 |
8 | ## Definition
9 |
10 | hook_civicrm_summaryActions( &$actions, $contactID )
11 |
12 | ## Parameters
13 |
14 | - `$actions` Array of all Actions in contextMenu. Each action item is
15 | itself an array that can contain the items below **(this is not the
16 | full list)**:\
17 | \
18 | - `title:` the text that appears in the action menu
19 | - `weight:` a number defining the "weight" - i.e where should the
20 | item sit in the action menu
21 | - `ref:` this is appended to the string "crm-action-record-" and
22 | becomes the list items CSS class (each action is a `li` element)
23 | - `key:` this is the array key that identifies the action
24 | - `href:` a URL that you want the link to navigate to
25 | - `permissions:` an array that contains permissions a user must
26 | have in order to use this action\
27 | \
28 | - `$contactID` contactID for the summary page.
29 |
30 | ## Example
31 |
32 | **Removing some action items**
33 |
34 | function civitest_civicrm_summaryActions( &$actions, $contactID ){
35 | $customizeActions = array('contribution', 'note', 'rel');
36 | foreach( $actions as $key => $value ) {
37 | if( in_array( $key, $customizeActions ) ) {
38 | unset( $actions[$key] );
39 | }
40 | }
41 | }
42 |
43 | **Add an item to the action list**
44 |
45 | function mymodulename_civicrm_summaryActions(&$actions, $contactID)
46 | {
47 | $actions['casework'] = array(
48 | 'title' => 'Record casework',
49 | 'weight' => 999,
50 | 'ref' => 'record-casework',
51 | 'key' => 'casework',
52 | 'href' => '/casework/recording_form
53 | );
54 | }
55 |
56 | **Add an item to the third column of action list**
57 |
58 | function mymodulename_civicrm_summaryActions(&$actions, $contactID)
59 | {
60 | $actions['otherActions']['casework'] = array(
61 | 'title' => 'Record casework',
62 | 'weight' => 999,
63 | 'ref' => 'record-casework',
64 | 'key' => 'casework',
65 | 'href' => '/casework/recording_form
66 | );
67 | }
68 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_tabs.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_tabs
2 |
3 | ## Summary
4 |
5 | This hook was deprecated in 4.7 in favor of [hook_civicrm_tabset](hook_civicrm_tabset.md).
6 |
7 | ## Notes
8 |
9 | This hook is called when composing the tabs to display when viewing a
10 | contact
11 |
12 | ## Definition
13 |
14 | hook_civicrm_tabs( &$tabs, $contactID )
15 |
16 | ## Parameters
17 |
18 | - $tabs - the array of tabs that will be displayed
19 | - $contactID - the contactID for whom the view is being rendered
20 |
21 | ## Returns
22 |
23 | - null - the return value is ignored
24 |
25 | ## Example
26 |
27 | function civitest_civicrm_tabs( &$tabs, $contactID ) {
28 |
29 | // unset the contribition tab, i.e. remove it from the page
30 | unset( $tabs[1] );
31 |
32 | // let's add a new "contribution" tab with a different name and put it last
33 | // this is just a demo, in the real world, you would create a url which would
34 | // return an html snippet etc.
35 | $url = CRM_Utils_System::url( 'civicrm/contact/view/contribution',
36 | "reset=1&snippet=1&force=1&cid=$contactID" );
37 | // $url should return in 4.4 and prior an HTML snippet e.g. '
....';
38 | // in 4.5 and higher this needs to be encoded in json. E.g. json_encode(array('content' => ));
39 | // or CRM_Core_Page_AJAX::returnJsonResponse($content) where $content is the html code
40 | // in the first cases you need to echo the return and then exit, if you use CRM_Core_Page method you do not need to worry about this.
41 | $tabs[] = array( 'id' => 'mySupercoolTab',
42 | 'url' => $url,
43 | 'title' => 'Contribution Tab Renamed',
44 | 'weight' => 300 );
45 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_themes.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_themes
2 |
3 | ## Summary
4 |
5 | This hook is called when building a list of available themes for use within CiviCRM.
6 |
7 | ## Definition
8 |
9 | hook_civicrm_themes( &$themes )
10 |
11 | ## Parameters
12 |
13 | - array $themes - array of theme information
14 | - ext: string (required)
15 | The full name of the extension which defines the theme.
16 | Ex: "org.civicrm.themes.greenwich".
17 | - title: string (required)
18 | Visible title.
19 | - help: string (optional)
20 | Description of the theme's appearance.
21 | - url_callback: mixed (optional)
22 | A function ($themes, $themeKey, $cssExt, $cssFile) which returns the URL(s) for a CSS resource.
23 | Returns either an array of URLs or PASSTHRU.
24 | Ex: \Civi\Core\Themes\Resolvers::simple (default)
25 | Ex: \Civi\Core\Themes\Resolvers::none
26 | - prefix: string (optional)
27 | A prefix within the extension folder to prepend to the file name.
28 | - search_order: array (optional)
29 | A list of themes to search.
30 | Generally, the last theme should be "*fallback*" (Civi\Core\Themes::FALLBACK).
31 | - excludes: array (optional)
32 | A list of files (eg "civicrm:css/bootstrap.css" or "$ext:$file") which should never
33 | be returned (they are excluded from display). - object being imported (for now Contact
34 |
35 | ## Returns
36 |
37 | - null
38 |
39 | ## Availability
40 |
41 | - This hook was first available in CiviCRM 5.16
42 |
43 | ## Example
44 |
45 | A minimal example:
46 |
47 | ```php
48 | /*
49 | * A theme is a set of CSS files which are loaded on CiviCRM pages.
50 | */
51 | function civitest_civicrm_themes( &$themes ) {
52 | $themes['civielection'] = [
53 | 'title' => 'civielection theme',
54 | 'ext' => 'au.org.greens.civielection',
55 | ];
56 | }
57 | ```
58 |
59 | A more detailed example
60 |
61 | ```php
62 | /*
63 | * A theme is a set of CSS files which are loaded on CiviCRM pages.
64 | */
65 | function civitest_civicrm_themes( &$themes ) {
66 | $themes['civielection'] = [
67 | 'title' => 'civielection theme',
68 | 'ext' => 'au.org.greens.civielection',
69 | 'name' => 'civielection',
70 | 'url_callback' => '\\Civi\\Core\\Themes\\Resolvers::simple',
71 | 'search_order' => [
72 | 0 => 'civielection',
73 | 1 => Civi\Core\Themes::FALLBACK,
74 | ],
75 | 'prefix' => 'election',
76 | 'excludes' => ['bootstrap.css'],
77 | ];
78 | }
79 | ```
80 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_tokenValues.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_tokenValues
2 |
3 | ## Summary
4 |
5 | This hook is called to get all the values for the tokens registered.
6 |
7 | ## Notes
8 |
9 | Use it to overwrite or reformat existing token values, or supply the values
10 | for custom tokens you have defined in
11 | [hook_civicrm_tokens](hook_civicrm_tokens.md). See [this
12 | article](https://civicrm.org/blog/colemanw/create-your-own-tokens-for-fun-and-profit) for
13 | usage examples.
14 |
15 | ## Definition
16 |
17 | ```php
18 | hook_civicrm_tokenValues(&$values, $cids, $job = null, $tokens = [], $context = null)
19 | ```
20 |
21 | ## Parameters
22 |
23 | - $values - array of values, keyed by contact id
24 | - $cids - array of contactIDs that the system needs values for.
25 | - $job - the job_id
26 | - $tokens - tokens used in the mailing - use this to check whether a
27 | token is being used and avoid fetching data for unneeded tokens
28 | - $context - the class name
29 |
30 | ## Returns
31 |
32 | - null
33 |
34 | ## Example
35 |
36 | ```php
37 | function customtokens_civicrm_tokenValues(&$values, $cids, $job = null, $tokens = [], $context = null) {
38 | $group = 'team';
39 | if(isset($tokens[$group])) {
40 | $token = 'team_number';
41 | if (!customtokens_isTokenRequested($tokens, $group, $token)) {
42 | return;
43 | }
44 |
45 | foreach ($cids as $cid) {
46 | // get team (employer) id
47 | $individualResult = civicrm_api3('Contact', 'getsingle', [
48 | 'return' => ["current_employer_id"],
49 | 'contact_id' => $cid,
50 | ]);
51 |
52 | // if there is a team (employer) id, get team number for the team (employer)
53 | if(!$individualResult['is_error'] && isset($individualResult['current_employer_id']) && strlen($individualResult['current_employer_id'])){
54 |
55 | $teamResult = civicrm_api3('Contact', 'getsingle', [
56 | 'return' => ["custom_70"],
57 | 'id' => $individualResult['current_employer_id'],
58 | ]);
59 |
60 | // if there is a team number, display it as the token
61 | if(!$teamResult['is_error'] && isset($teamResult['custom_70'])) {
62 | $values[$cid]['team.team_number'] = $teamResult['custom_70'];
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
69 | /**
70 | * "Send an Email" and "CiviMail" send different parameters to the tokenValues hook (in CiviCRM 5.x).
71 | * This works around that.
72 | *
73 | * @param array $tokens
74 | * @param string $group
75 | * @param string $token
76 | *
77 | * @return bool
78 | */
79 | function customtokens_isTokenRequested($tokens, $group, $token) {
80 | // CiviMail sets $tokens to the format:
81 | // [ 'group' => [ 'token_name' => 1 ] ]
82 | // "Send an email" sets $tokens to the format:
83 | // [ 'group' => [ 0 => 'token_name' ] ]
84 | if (array_key_exists($token, $tokens[$group]) || in_array($token, $tokens[$group])) {
85 | return TRUE;
86 | }
87 | return FALSE;
88 | }
89 | ```
90 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_tokens.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_tokens
2 |
3 | ## Summary
4 |
5 | This hook is called to allow custom tokens to be defined.
6 |
7 | ## Notes
8 |
9 | The token values
10 | will need to be supplied by
11 | [hook_civicrm_tokenValues](hook_civicrm_tokenValues.md).
12 |
13 | See [this article](https://civicrm.org/blog/colemanw/create-your-own-tokens-for-fun-and-profit)
14 | for usage examples.
15 |
16 | ## Definition
17 |
18 | ```php
19 | hook_civicrm_tokens(&$tokens)
20 | ```
21 |
22 | ## Parameters
23 |
24 | - $tokens: reference to the associative array of custom tokens that
25 | are available to be used in mailings and other contexts. This will
26 | be an empty array unless an implementation of hook_civicrm_tokens
27 | adds items to it. Items should be added in this format:
28 |
29 | ```php
30 | $tokens['date'] = [
31 | 'date.date_short' => ts("Today's Date: short format"),
32 | 'date.date_med' => ts("Today's Date: med format"),
33 | 'date.date_long' => ts("Today's Date: long format"),
34 | ];
35 | $tokens['party'] = [
36 | 'party.balloons' => ts("Number of balloons"),
37 | ];
38 | ```
39 |
40 | ## Returns
41 |
42 | - null
43 |
44 | ## Example
45 |
46 | ```php
47 | function customtokens_civicrm_tokens(&$tokens) {
48 | $tokens['team'] = [
49 | 'team.team_number' => 'Team number',
50 | ];
51 | }
52 | ```
53 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_triggerInfo.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_triggerInfo
2 |
3 | ## Summary
4 |
5 | This hook allows you to define MySQL triggers.
6 |
7 | ## Notes
8 |
9 | Using the hooks causes them not to clash with
10 | core or other extension triggers. They are compiled into one trigger
11 | with core triggers.
12 |
13 | !!! note
14 | Once the function is created, visit the following URL to rebuild triggers
15 | and create to create the new trigger:
16 |
17 | `http://example.com/civicrm/menu/rebuild?reset=1&triggerRebuild=1`
18 |
19 |
20 | ## Definition
21 |
22 | ```php
23 | hook_civicrm_triggerInfo(&$info, $tableName)
24 | ```
25 |
26 | ## Parameters
27 |
28 | * array `$info` - array of triggers to be created
29 | * string `$tableName` - not sure how this bit works
30 |
31 |
32 |
33 | ## Returns
34 |
35 | - ??
36 |
37 |
38 | ## Example
39 |
40 | Add trigger to update custom region field based on postcode (using a lookup
41 | table)
42 |
43 | Note that this example uses hard-coded a prioritisation of location types
44 | (since it was customer specific code and unlikely to change).
45 |
46 | ```php
47 | function regionfields_civicrm_triggerInfo(&$info, $tableName) {
48 | $table_name = 'civicrm_value_region_13';
49 | $customFieldID = 45;
50 | $columnName = 'region_45';
51 | $sourceTable = 'civicrm_address';
52 | $locationPriorityOrder = '1, 3, 5, 2, 4, 6'; // hard coded prioritisation of addresses
53 | $zipTable = 'CANYRegion';
54 | if(civicrm_api3('custom_field', 'getcount', array('id' => $customFieldID, 'column_name' => 'region_45', 'is_active' => 1)) == 0) {
55 | return;
56 | }
57 |
58 | $sql = "
59 | REPLACE INTO `$table_name` (entity_id, $columnName)
60 | SELECT * FROM (
61 | SELECT contact_id, b.region
62 | FROM
63 | civicrm_address a INNER JOIN $zipTable b ON a.postal_code = b.zip
64 | WHERE a.contact_id = NEW.contact_id
65 | ORDER BY FIELD(location_type_id, $locationPriorityOrder )
66 | ) as regionlist
67 | GROUP BY contact_id;
68 | ";
69 | $sql_field_parts = array();
70 |
71 | $info[] = array(
72 | 'table' => $sourceTable,
73 | 'when' => 'AFTER',
74 | 'event' => 'INSERT',
75 | 'sql' => $sql,
76 | );
77 | $info[] = array(
78 | 'table' => $sourceTable,
79 | 'when' => 'AFTER',
80 | 'event' => 'UPDATE',
81 | 'sql' => $sql,
82 | );
83 | // For delete, we reference OLD.contact_id instead of NEW.contact_id
84 | $sql = str_replace('NEW.contact_id', 'OLD.contact_id', $sql);
85 | $info[] = array(
86 | 'table' => $sourceTable,
87 | 'when' => 'AFTER',
88 | 'event' => 'DELETE',
89 | 'sql' => $sql,
90 | );
91 | }
92 | ```
93 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_unhandledException.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_unhandledException
2 |
3 | ## Summary
4 |
5 | This hook fires when an unhandled exception (fatal error) occurs.
6 |
7 | ## Notes
8 |
9 | A use case is to show an alternative page to donors rather than a fatal
10 | error screen if a fatal error occurs during a donation.
11 |
12 | ## Availability
13 |
14 | This hook is available in CiviCRM 4.6+.
15 |
16 | ## Definition
17 |
18 | unhandledException($exception, $request = NULL)
19 |
20 | ## Parameters
21 |
22 | - $exception - An object of type CRM_Core_Exception Exception.
23 | - $request - Reserved for future use.
24 |
25 | ## Returns
26 |
27 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_uninstall.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_uninstall
2 |
3 | ## Summary
4 |
5 | This hook is called when an extension is uninstalled.
6 |
7 | ## Notes
8 |
9 | To be specific, when its status changes from ***disabled*** to ***uninstalled***.
10 |
11 | Each module will receive `hook_civicrm_uninstall` during its own
12 | uninstallation (but not during the uninstallation of unrelated modules).
13 |
14 | ## Parameters
15 |
16 | - None
17 |
18 | ## Returns
19 |
20 | - Void
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_unsubscribeGroups.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_unsubscribeGroups
2 |
3 | ## Summary
4 |
5 | This hook is called when CiviCRM receives a request to unsubscribe a
6 | user from a mailing.
7 |
8 | ## Availability
9 |
10 | Introduced in CiviCRM v4.2
11 |
12 | ## Definition
13 |
14 | hook_civicrm_unsubscribeGroups($op, $mailingId, $contactId, &$groups, &$baseGroups)
15 |
16 | ## Parameters
17 |
18 | - - string $op - hard coded to be unsubscribe
19 |
20 | - int $mailingId - the id of the mailing sent that originated
21 | this unsubscribe request
22 | - int $contactId - the id of the contact that wishes to be
23 | unsubscribed
24 | - array $groups - the list of groups that the contact will be
25 | removed from
26 | - array $baseGroups - the list of base groups (for smart
27 | mailings) that the contact will be removed from
28 |
29 | ## Example
30 |
31 | function civitest_civicrm_unsubscribeGroups( $op, $mailingId, $contactId, &$groups, &$baseGroups ) {
32 | // do the below for even mailing ids only
33 | // in a real implementation, you will have some logic to restrict what mailings
34 | // you want to handle the unsub via a different patch
35 | // this hook basically redirects you to a custom unsubscribe page
36 | // thanx to parvez @ veda consulting for this example
37 | if ($op == 'unsubscribe' && $mailingId % 2 == 0) {
38 | $oConfig = CRM_Core_Config::singleton();
39 | $sUnsubscribeRedirectUrl = $oConfig->unsubscribe_redirect_url;
40 | if ( !empty( $sUnsubscribeRedirectUrl ) ) {
41 | CRM_Utils_System::redirect( $sUnsubscribeRedirectUrl );
42 | } else {
43 | CRM_Core_Error::statusBounce( 'Unsubscribe URL has not been set.' );
44 | }
45 | CRM_Utils_System::civiExit();
46 | }
47 | }
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_upgrade.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_upgrade
2 |
3 | ## Summary
4 |
5 | This hook is called when an administrator visits the "Manage Extensions"
6 | screen to determine if there are any pending upgrades.
7 |
8 | ## Notes
9 |
10 | As of version 4.7, it is also called periodically by [CiviCRM's system status
11 | utility](https://docs.civicrm.org/user/en/stable/initial-set-up/civicrm-system-status/).
12 |
13 | If there are upgrades, and if the administrator chooses to execute them,
14 | the hook is called a second time to construct a list of upgrade tasks.
15 |
16 | ## Definition
17 |
18 | hook_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL)
19 |
20 | ## Parameters
21 |
22 | - $op - the type of operation being performed; 'check' or 'enqueue'
23 | - $queue - (for 'enqueue') the modifiable list of pending up upgrade
24 | tasks
25 |
26 | ## Returns
27 |
28 | - For 'check' operations, return array(bool) (TRUE if an upgrade is
29 | required)
30 | - For 'enqueue' operations, return void
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_validate.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_validate
2 |
3 | ## Summary
4 |
5 | **(Removed)** This hook is invoked during all CiviCRM form validation. An array of errors
6 | detected is returned. Else we assume validation succeeded.
7 |
8 | ## Availability
9 |
10 | This hook was **removed in v4.7**.
11 |
12 | ## Definition
13 |
14 | ```php
15 | hook_civicrm_validate($formName, &$fields, &$files, &$form)
16 | ```
17 | ## Parameters
18 |
19 | * string `$formName` - The name of the form.
20 | * array `&$fields` - the POST parameters as filtered by QF
21 | * array `&$files` - the FILES parameters as sent in by POST
22 | * array `&$form` - the form object
23 |
24 | ## Returns
25 |
26 | * mixed - formRule hooks return a boolean or an array of error messages which display a QF Error
27 |
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_validateProfile.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_validateProfile
2 |
3 | ## Summary
4 |
5 | This hook is called while validating a profile form submission.
6 |
7 | ## Definition
8 |
9 | validateProfile($profileName)
10 |
11 | ## Parameters
12 |
13 | - $profileName - the (machine readable) name of the profile.
14 |
15 | ## Returns
16 |
17 | - null
--------------------------------------------------------------------------------
/docs/hooks/hook_civicrm_viewProfile.md:
--------------------------------------------------------------------------------
1 | # hook_civicrm_viewProfile
2 |
3 | ## Summary
4 |
5 | This hook is called while preparing a read-only profile screen.
6 |
7 | ## Definition
8 |
9 | viewProfile($profileName)
10 |
11 | ## Parameters
12 |
13 | - $profileName - the (machine readable) name of the profile.
14 |
15 | ## Returns
16 |
17 | - null
--------------------------------------------------------------------------------
/docs/hooks/usage/drupal.md:
--------------------------------------------------------------------------------
1 | The Drupal documentation has great information about
2 | [hooks in general][drupal-hooks],
3 | [configuration to enable hooks for your module][hooks-config],
4 | and [this guide][hooks-intro] on starting out with hooks.
5 |
6 | In order to start using hooks with a Drupal-based CiviCRM installation, you or
7 | your administrator needs to do the following:
8 |
9 | 1. Create a file with the extension .info (for instance, myhooks.info)
10 | containing the following lines. Replace the example text in the first 2
11 | lines with something appropriate for your organization, and assign 7.x
12 | to core if you use Drupal 7.
13 |
14 | name = My Organization's Hooks
15 | description = Module containing the CiviCRM hooks for my organization
16 | dependencies[] = civicrm
17 | package = CiviCRM
18 | core = 7.x
19 | version = 7.x-1.0
20 |
21 | 2. Create a new file with the extension *.module* (for instance,
22 | *myhooks.module*) to hold your PHP functions.
23 | 3. Upload both the *.info* and *.module* files to the server running CiviCRM,
24 | creating a new directory for them under */sites/all/modules* (for
25 | instance, */sites/all/modules/myhooks/*) inside your Drupal installation.
26 | The directory name you create should be short and contain only lowercase
27 | letters, digits, and underlines without spaces.
28 | 4. Enable your new hooks module through the Drupal administration page.
29 |
30 | Additionally, if you are using Drupal and add a new hook to an existing module,
31 | you will need to clear the cache for the hook to start operating. One way of
32 | doing this is by visiting the page Admin > Build > Modules.
33 |
34 | ## Inspecting Hooks
35 |
36 | The documentation about hooks can be somewhat abstract, and it sometimes
37 | helps to see interactively how the hooks run.
38 |
39 | - If you use Drupal, then you can inspect some hooks by installing
40 | these two Drupal modules:
41 | - [devel](http://drupal.org/project/devel)
42 | - [civicrm\_developer](https://github.com/eileenmcnaughton/civicrm_developer)
43 |
44 | [drupal-hooks]: https://www.drupal.org/docs/7/creating-custom-modules/understanding-the-hook-system-for-drupal-modules
45 | [hooks-config]: https://www.drupal.org/docs/7/creating-custom-modules/telling-drupal-about-your-module
46 | [hooks-intro]: https://www.drupal.org/docs/7/creating-custom-modules/writing-comments-and-implementing-your-first-hook
--------------------------------------------------------------------------------
/docs/img/CMS_URL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/CMS_URL.png
--------------------------------------------------------------------------------
/docs/img/CiviCRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/CiviCRM.png
--------------------------------------------------------------------------------
/docs/img/Jenkis_Show_Results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/Jenkis_Show_Results.png
--------------------------------------------------------------------------------
/docs/img/api-or-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/api-or-example.png
--------------------------------------------------------------------------------
/docs/img/financial/FinancialAccount.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/financial/FinancialAccount.png
--------------------------------------------------------------------------------
/docs/img/gitlab-reference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/gitlab-reference.png
--------------------------------------------------------------------------------
/docs/img/index.md:
--------------------------------------------------------------------------------
1 | This folder contains images for the CiviCRM demo documentation.
2 |
--------------------------------------------------------------------------------
/docs/img/inheritance-community-chest.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/inheritance-community-chest.jpg
--------------------------------------------------------------------------------
/docs/img/mysql_workbench_civicrm_country_foreign_keys.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/mysql_workbench_civicrm_country_foreign_keys.png
--------------------------------------------------------------------------------
/docs/img/mysql_workbench_civicrm_country_tables.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/mysql_workbench_civicrm_country_tables.png
--------------------------------------------------------------------------------
/docs/img/quickform-lifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/quickform-lifecycle.png
--------------------------------------------------------------------------------
/docs/img/repository-access.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/civicrm/civicrm-dev-docs/4693cbeec0027b6203eceb5f8603f2f48e4490db/docs/img/repository-access.png
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # CiviCRM Developer Guide
2 |
3 | [CiviCRM](https://civicrm.org) is an open-source application. The code can be poked, prodded, twisted, and hacked. It can be customized, extended, and collaboratively developed. This documentation tells you how to do that.
4 |
5 | It starts with a high level introduction to get you familiar with CiviCRM development. It covers setting up your development environment, checking whether or not you actually need to implement your own custom code (i.e. you can't achieve what you want through configuration or installing an already existing extension), best practice ways to extend CiviCRM (a.k.a. how to write an extension), things you should know before you start hacking on core, and best practice for testing.
6 |
7 | The guide also includes detailed references for tools and subsystems of CiviCRM. These cover topics like the API and hook system and are intended for use by people that are familiar with CiviCRM development.
8 |
9 | ## Editing this guide
10 |
11 | * This guide is made with MkDocs and stored in a [GitHub repository](https://github.com/civicrm/civicrm-dev-docs).
12 | * See the "[Writing Documentation](documentation/index.md)" section in this guide for specific details on editing this guide.
13 |
14 | ## Credits
15 |
16 | This guide is collaboratively written by the CiviCRM community, with facilitation from the [Documentation Working Group](https://civicrm.org/working-groups/documentation).
17 |
--------------------------------------------------------------------------------
/docs/security/access.md:
--------------------------------------------------------------------------------
1 | # Access Control in CiviCRM
2 |
3 | ## Introduction
4 |
5 | CiviCRM has a system of Access Control Lists (ACLs) which allow administrators to customise what information groups of their users are able to see. ACLs work alongside the system of permissions set out by CiviCRM which is integrated in the Content Management System's Permissions structure.
6 |
7 | ## Context
8 |
9 | Access Control is used to control access to CiviCRM data and functionality. This is done through Access Control Lists (ACL's). An ACL consists of:
10 |
11 | 1. A Role that has permission to do this operation ('Administrator', 'Team Leader'),
12 | 2. An Operation (e.g. 'View' or 'Edit'), and
13 | 3. A set of Data that the operation can be performed on (e.g. a group of contacts)
14 |
15 | Example: there may be a role called "Team Leaders" that can "Edit" all the contacts within the "Active Volunteers Group"
16 |
17 | ## Within Code
18 |
19 | Much of the ACL control process happens within the `CRM/ACL/Api.php` file and `CRM/ACL/BAO/Acl.php` file. These files demonstrate how the ACL is used to add clauses to the WHERE statement of queries that are generated within CiviCRM. Many of these functions will be called from within the relevant CMS system files in `CRM/Utils/System/xxx.php` where xxx is the UF name of your CMS. e.g. Drupal 7 is Drupal, Drupal 8 is Drupal8 etc. These functions are usually checked at run time and are very low level.
20 |
21 | ## Extending ACLs
22 |
23 | There are a few ACL hooks that allow developers in their extension to extend the implementation of various ACLs for their own purposes.
24 |
25 | - [`hook_civicrm_aclGroup`](../hooks/hook_civicrm_aclGroup.md) This hook alters what entities (e.g. CiviCRM Groups, CiviCRM Events) an end user is able to see.
26 |
27 | - [`hook_civicrm_aclWhereClause`](../hooks/hook_civicrm_aclWhereClause.md) This hook adds extra SQL statements when the ACL contact cache table is to be filled up. Depending on how frequently your ACL cache is cleared this may become taxing on your database.
28 |
29 | - [`hook_civicrm_selectWhereClause`](../hooks/hook_civicrm_selectWhereClause.md) This hook was introduced in 4.7 and allows you to add specific restrictions or remove restrictions when querying specific entities. This is different to `hook_civicrm_aclWhereClause` because that only deals with contacts and limiting of contacts and also `hook_civicrm_selectWhereClause` is run every time a select query for that entity is run.
30 |
31 | It should be noted that especially with `hook_civicrm_selectWhereClause` there is little CiviCRM Core test coverage on these items so it is always very important that administrators test their own ACLs when testing any upgrade to CiviCRM.
32 |
--------------------------------------------------------------------------------
/docs/security/reporting.md:
--------------------------------------------------------------------------------
1 | # Reporting a Security Vulnerability
2 |
3 | ## Introduction
4 |
5 | CiviCRM Core Team and Security Team are responsible for fixing reported security issues within [supported CiviCRM versions](https://civicrm.org/download). Security releases will only be made for those versions with active CiviCRM support, at which point [Security Advisories](https://civicrm.org/advisory) will be issued.
6 |
7 | ## Release Timing.
8 |
9 | CiviCRM maintains two security release windows, they are the first and third Wednesday of every month US/PDT Timezone. Having a release window doesn't mean that a release will occur, but it does allow for site administrators to be conscious of when there may be a security update.
10 |
11 | ## Reporting a Security bug
12 |
13 | CiviCRM maintains an email address [security@civicrm.org](mailto:security@civicrm.org) as the primary mechanism for reporting security issues. When you report an issue, please include all possible information that would help the Security Team replicate and help solve the issue. Unless you request anonymity, you will be credited for your role in reporting the issue as well as any other roles you take in resolving it.
14 |
15 | ## Security Policy
16 |
17 | CiviCRM has a publicly available [Security Policy](https://civicrm.org/security) which details these points and goes into some further detail around our security practices.
18 |
--------------------------------------------------------------------------------
/docs/standards/database.md:
--------------------------------------------------------------------------------
1 | # Database standards
2 |
3 | The following standards apply to the database layer in CiviCRM:
4 |
5 | 1. Every BAO will have a create function. This will be called by the API & form layer.
6 | 1. The create function will take a single params array.
7 | 1. Depending on the parameters passed in, the create function will perform any additional actions like creating activities.
8 | 1. The create function will call hooks.
9 | 1. We are moving away from the `$ids` array being included.
10 | 1. The add function (if it exists) will be internal to the BAO layer.
11 | 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.
12 | 1. The delete action will take any additional tasks like deleting additional objects (generally done by code).
13 | 1. The delete action will take an array including `['id']`.
14 | 1. The api will call the `del` action & fall back onto delete. It is recommended that the form layer call the API.
15 |
--------------------------------------------------------------------------------
/docs/standards/review/template-word-1.0.md:
--------------------------------------------------------------------------------
1 | (*CiviCRM Review Template WORD-1.2*)
2 |
3 |
4 |
5 | * General standards
6 | * ([`r-explain`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-explain)) __Undecided__
7 | * ([`r-user`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-user)) __Undecided__:
8 | * ([`r-doc`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-doc)) __Undecided__
9 | * ([`r-run`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-run)) __Undecided__:
10 | * Developer standards
11 | * ([`r-tech`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-tech)) __Undecided__:
12 | * ([`r-code`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-code)) __Undecided__
13 | * ([`r-maint`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-maint)) __Undecided__
14 | * ([`r-test`](https://docs.civicrm.org/dev/en/latest/standards/review/#r-test)) __Undecided__
15 |
--------------------------------------------------------------------------------
/docs/testing/codeception.md:
--------------------------------------------------------------------------------
1 | !!! tip "Setup"
2 |
3 | The test suites require a small amount of [setup](../testing/index.md#setup). If your system was created via [buildkit](../tools/buildkit.md) and
4 | [civibuild](../tools/civibuild.md), then it was handled automatically.
5 |
6 | TODO
--------------------------------------------------------------------------------
/docs/testing/karma.md:
--------------------------------------------------------------------------------
1 | !!! tip "Setup"
2 |
3 | The test suites require a small amount of [setup](index.md#setup). If your system was created via [buildkit](../tools/buildkit.md) and
4 | [civibuild](../tools/civibuild.md), then it was handled automatically.
5 |
6 | [Karma] is a Javascript testing tool which executes [Jasmine] tests on the command-line.
7 | It was introduced in Civi v4.6 in tandem with several AngularJS-based UIs.
8 |
9 | [Buildkit](../tools/buildkit.md) includes a copy of `karma`. Alternatively,
10 | you can download it by running `npm install` in the `civicrm` directory.
11 |
12 | ## Running Karma
13 |
14 | If you're actively working on Javascript files or Karma tests, then you can
15 | start `karma` in a *watch* mode. Any time you save a change to disk, it
16 | will automatically re-execute the tests.
17 |
18 | ```bash
19 | $ cd /path/to/civicrm
20 | $ karma start
21 | ```
22 |
23 | ## Running Karma (Other ways)
24 |
25 | You can also run the karma tests as they would be run by [Jenkins](continuous-integration.md) using [civi-test-run](../tools/civi-test-run.md).
26 |
27 | [Karma]: https://karma-runner.github.io/1.0/index.html
28 | [Jasmine]: https://jasmine.github.io/2.1/introduction.html
29 |
--------------------------------------------------------------------------------
/docs/testing/protractor.md:
--------------------------------------------------------------------------------
1 | !!! tip "Setup"
2 |
3 | The test suites require a small amount of [setup](index.md#setup). If your system was created via [buildkit](../tools/buildkit.md) and
4 | [civibuild](../tools/civibuild.md), then it was handled automatically.
5 |
6 | TODO
--------------------------------------------------------------------------------
/docs/testing/selenium.md:
--------------------------------------------------------------------------------
1 | !!! tip "Setup"
2 |
3 | The test suites require a small amount of [setup](index.md#setup). If your system was created via [buildkit](../tools/buildkit.md) and
4 | [civibuild](../tools/civibuild.md), then it was handled automatically.
5 |
6 | Web tests ensure the overall system is working as expected – that is, ensuring
7 | that the right things happen when you click on the right buttons.
8 |
9 | Examples of web tests include that the event confirmation screen is displayed
10 | when I hit the register for an event button, or that all 23 contacts are
11 | displayed when I search for contacts that live in France.
12 |
13 | You can record tests using the Selenium IDE which you can download from the
14 | [Selenium website](http://seleniumhq.org/). Web tests should be recorded using an
15 | instance of CiviCRM that has standard sample data.
16 |
17 | To ensure consistency, all tests should be carried out using the standard
18 | CiviCRM sample data.
19 |
20 | ## Setup
21 |
22 | [buildkit](../tools/buildkit.md) should be installed. You will also need Java and Firefox.
23 |
24 | ## Running the Web Tests
25 |
26 | 1. Open two terminals
27 |
28 | 2. From Terminal 1: Launch the Selenium service
29 | ```bash
30 | $ cd /path/to/civicrm
31 | $ cd packages/SeleniumRC/
32 | $ bash selenium.sh
33 | Runnning selenium-server-2.35.0
34 | Mar 06, 2015 8:58:22 PM org.openqa.grid.selenium.GridLauncher main
35 | INFO: Launching a standalone server
36 | ```
37 |
38 | 3. From Terminal 2: Run the tests
39 | ```bash
40 | $ cd /path/to/civicrm
41 | $ cd tools
42 | $ ./scripts/phpunit WebTest_AllTests
43 | ```
44 |
45 | ## See Also
46 |
47 | - [Selenium documentation](http://seleniumhq.org/docs/)
48 | - [Selenium reference](http://release.seleniumhq.org/selenium-core/1.0.1/reference.html)
49 |
--------------------------------------------------------------------------------
/docs/testing/upgrades.md:
--------------------------------------------------------------------------------
1 | Upgrade tests provide a basic sanity check on the DB upgrade logic –
2 | they ensure that the upgrade process does not cause a crash when upgrading
3 | from an older version.
4 |
5 | They are suitable for checking issues in the DB upgrade logic –
6 | but do not check for issues in the administrative experience or in the
7 | CMS-integration.
8 |
9 | Upgrade tests are run daily on the Jenkins [continuous integration](continuous-integration.md) server.
10 |
11 | Locally you can use [civi-test-run](../tools/civi-test-run.md) to run the same upgrade tests as Jenkins would.
12 |
--------------------------------------------------------------------------------
/docs/tools/civi-test-run.md:
--------------------------------------------------------------------------------
1 | # civi-test-run
2 |
3 | `civi-test-run` is a script which runs one or more test suites locally. It is compatible with `civibuild`-based deployments.
4 |
5 | ## Installation
6 |
7 | `civi-test-run` is included within [buildkit](buildkit.md).
8 |
9 | ## Usage
10 |
11 | Run without arguments to see the exact usage:
12 |
13 | ```bash
14 | $ civi-test-run
15 | ```
16 |
17 | ## Test types
18 |
19 | The test type is one of:
20 |
21 | - `all` - Run all standard CiviCRM test suites
22 | - `karma` - Run the KarmaJS test suite
23 | - `phpunit-api` - Run the `api_v3` test suite
24 | - `phpunit-civi` - Run the `Civi/` test suite
25 | - `phpunit-crm` - Run the `CRM` test suite
26 | - `phpunit-e2e` - Run the `E2E` test suite
27 | - `upgrade` - Run the upgrade test suite
28 |
--------------------------------------------------------------------------------
/docs/tools/cividist.md:
--------------------------------------------------------------------------------
1 | ## CiviDist
2 |
3 | `cividist` generates a website with tarballs built from the official git repos ([civicrm-core.git](https://github.com/civicrm/civicrm-core.git), [civicrm-packages.git](https://github.com/civicrm/civicrm-packages.git), etc). It manages the CiviCRM [nightly builds](http://dist.civicrm.org).
4 |
5 | If you wish to run `cividist` with your own repos, you will need to do the some initial setup and then periodically build new tarballs.
6 |
7 | `cividist` expects that branch names match across all repos (e.g. the `4.6` branch in `civicrm-core.git` must match the `4.6` branch in `civicrm-packages.git`). If you use a non-standard branch name, it must exist in all repos.
8 |
9 | ## Setup: Make the web root
10 |
11 | ```
12 | civibuild create dist --url http://dist.localhost
13 | ```
14 |
15 | ## Setup: Register your forks
16 |
17 | !!! note
18 | If you use forks, you should do so consistently across all repos (even if you don't have any customizations on one repo or another). The goal is to consistently name the `remote`s and `branch`es across all repos.
19 |
20 | ```
21 | cd build/dist/src
22 | git remote add myfork https://github.com/myfork/civicrm-core.git
23 |
24 | cd build/dist/src/drupal
25 | git remote add myfork https://github.com/myfork/civicrm-drupal.git
26 |
27 | cd build/dist/src/packages
28 | git remote add myfork https://github.com/myfork/civicrm-packages.git
29 |
30 | cd build/dist/src/joomla
31 | git remote add myfork https://github.com/myfork/civicrm-joomla.git
32 |
33 | cd build/dist/src/WordPress
34 | git remote add myfork https://github.com/myfork/civicrm-wordpress.git
35 | ```
36 |
37 | ## Setup: Permissions
38 |
39 | If your system has specific permission requirements, then apply the permissions as you normally would. For example, if you use chgrp and and set all files as group-writable:
40 |
41 | ```
42 | sudo git config --system core.filemode false
43 | sudo chgrp -R mygroup build/dist
44 | sudo chmod -R g+w build/dist
45 | ```
46 |
47 | ## Periodic: Update tarballs
48 |
49 | This will retrieve the latest code from the remote alias (eg `myfork`) and build new build tarballs:
50 |
51 | ```
52 | cd build/dist
53 | env GIT_REMOTE=myfork cividist update
54 | cividist build myfork/4.6
55 | ```
56 |
57 | By default the tarballs will have the date in the name. If you don't want this you can add a FILE_SUFFIX e.g., to this command as used by Fuzion to a) use a remote called 'fuzion', b) use the branch 4.6.4rc1 from those repos & c) output using filenames like civicrm-4.6.5-drupal-nightly.tar.gz
58 |
59 | ```
60 | env FILE_SUFFIX=nightly cividist build fuzion/4.6.4rc1
61 | ```
62 |
63 | You can also build multiple tarballs with one command, e.g.
64 |
65 | ```
66 | cividist build myfork/4.5 myfork/4.6 myfork/master
67 | ```
68 |
69 | ## Periodic: Cleanup old/orphaned tarballs
70 |
71 | ```
72 | cd build/dist
73 | cividist prune
74 | ```
75 |
--------------------------------------------------------------------------------
/docs/tools/civilint.md:
--------------------------------------------------------------------------------
1 | Civilint is a thin wrapper which calls jshint and PHP_CodeSniffer (with the coder ruleset).
2 |
3 | Code-style tests ensure a consistent layout across all of the codebase, and they also identify some unsafe or confusing coding patterns. While working on a patch, you should run civilint to determine if the pending changes comply with style guides.
4 |
5 | Note that civilint may be invoked a few different ways:
6 |
7 | ```bash
8 | # (no arguments) – Check style of any uncommitted changes.
9 | civilint
10 |
11 | # Check style of a specific file (or list of files).
12 | civilint some/file.php
13 |
14 | # Check your last commit
15 | git diff --name-only HEAD~1 | civilint -
16 |
17 | # Check for changes in your branch (compared to master)
18 | git diff --name-only master | civilint -
19 | ```
20 |
21 | See also:
22 |
23 | - [CiviCRM Coding Standards](../standards/php.md)
24 | - [CiviCRM Javascript Standards](../standards/javascript.md)
25 | - [Drupal Coding Standards](https://www.drupal.org/docs/develop/standards/coding-standards)
26 | - [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer)
27 | - [coder](https://github.com/civicrm/coder)
28 | - [jshint](http://jshint.com/)
29 |
--------------------------------------------------------------------------------
/docs/tools/jenkins.md:
--------------------------------------------------------------------------------
1 | # Jenkins continuous integration
2 |
3 | Pull-requests are tested automatically with build-bot software called [Jenkins](https://jenkins.io/) which runs on [test.civicrm.org](http://test.civicrm.org/). Key things to know:
4 |
5 | * If you are a new contributor, the tests may be placed on hold pending a cursory review. One of the administrators will post a comment like `jenkins, ok to test` or `jenkins, add to whitelist`.
6 | * The pull-request will have a colored dot indicating its status:
7 | * **Yellow**: The automated tests are running.
8 | * **Red**: The automated tests have failed.
9 | * **Green**: The automated tests have passed.
10 | * If the automated test fails, click on the red dot to investigate details. Check for information in:
11 | * The initial summary. Ordinarily, this will list test failures and error messages.
12 | * The console output. If the test-suite encountered a significant error (such as a PHP crash), the key details will only appear in the console.
13 | * __Tip__: Sometimes, the console output is pretty long (several hundred KB). This usually means that a majority of tests ran, but there's a failure mixed in somewhere. View the full log and search for the word `EXITCODE`; this should normally appear as blank or 0. The first non-empty `EXITCODE` should be close to the problem.
14 | * __Tip__: Sometimes, the console output is relatively short (a page or two). You might look for evidence of one of these typical problems:
15 | * A network service (such as `github.com` or `packagist.org`) was unavailable. These are usually corrected quickly without any action. Try running the test again.
16 | * The pull-request is based on an old version of the codebase, and it cannot be applied cleanly with `git apply` or `git scan am`. Rebasing the PR branch should resolve this.
17 | * On the test node, a local resource (such as disk-space, RAM, or inode count) was exhausted. If the failure was recent (past few hours), seek help on [the infrastructure channel](https://chat.civicrm.org/civicrm/channels/infrastructure). If the failure occurred a few hours or days ago, try running the test again.
18 | * Some part of the build/test toolchain needs attention. For example, a test script may have been changed without supporting an edge-case; or a tool like `bower` or `npm` may need to be upgraded. Seek help on `infrastructure`.
19 | * Code-style tests are executed first. If the code-style in this patch is inconsistent, the remaining tests will be skipped.
20 | * The primary tests may take 20-120 min to execute. This includes the following suites: `api_v3_AllTests`, `CRM_AllTests`, `Civi\AllTests`, `civicrm-upgrade-test`, and `karma`
21 | * There are a handful of unit tests which are time-sensitive and which fail sporadically. See: https://forum.civicrm.org/index.php?topic=36964.0
22 | * The web test suite (`WebTest_AllTests`) takes several hours to execute. [It runs separately -- after the PR has been merged.](https://test.civicrm.org/job/CiviCRM-WebTest-Matrix/)
23 |
24 | For detailed discussion about automated tests, see [Testing](../testing/index.md)
25 |
--------------------------------------------------------------------------------
/docs/translation/extensions.md:
--------------------------------------------------------------------------------
1 | # Extensions Translation
2 |
3 | For developing a CiviCRM extension in a way that can be translated, all the best practices described in the [Internationalisation for Developers](index.md) page apply. This page describes special considerations that need to be taken into account for extensions.
4 |
5 | See also: ["Extension translation" wiki in the Translation project](https://lab.civicrm.org/dev/translation/wikis/extension-translation).
6 |
7 | ## For translators: Translating strings on Transifex
8 |
9 | There is a separate project on Transifex to translate extensions. Each extension has its own "resource". Therefore, when a translator joins a translation team, they can translate all extensions. We didn't see a need to separate each extension in a separate project, because each extension should have only one translation (`.po`) file.
10 |
11 | See:
12 |
13 | Translation strings are sent to Transifex when the extension is "ready for automatic distribution". See: [Publishing Extensions](../extensions/publish.md).
14 |
15 | ## For administrators: Download translation files for extensions
16 |
17 | The easiest way to download translations for extensions is to use the [l10nupdate](https://github.com/cividesk/com.cividesk.l10n.update/) extension.
18 |
19 | ## For developers: Correct usage of the `E::ts()` function
20 |
21 | In PHP, Smarty, and JS code, the convention is to perform translations using the `E::ts()` helper function. This is the same as in core code — with the additional requirement that one must specify the "domain" so that the translation engine can use the correct dictionary (`.mo` file) at run-time.
22 |
23 | !!! note "New in civix 17.08"
24 | `E::ts()` was added to civix 17.08. The civix file may need to be regenerated. You can read more about it in the [civix upgrade notes](https://github.com/totten/civix/blob/master/UPGRADE.md#upgrade-to-v17081-the-big-e). Extensions may still use the old syntax using `ts()` with the `domain` argument.
25 |
26 | !!! note "`E::ts()` and `ts()`"
27 | `E::ts()` is recommended, but it won't fallback to core. (it might in JS, but not in PHP because we don't have a way to detect if gettext translated or not)
28 |
29 | PHP:
30 |
31 | ```php
32 | use CRM_Myextension_ExtensionUtil as E;
33 |
34 | class CRM_Myextension_Form_Example {
35 | function example() {
36 | $string = E::ts('Hello, %1', array(
37 | 1 => $display_name,
38 | ));
39 | }
40 | }
41 | ```
42 |
43 | Smarty templates:
44 |
45 | ```smarty
46 | {crmScope extensionKey='org.example.myextension'}
47 |