diff --git a/content-migration/hooks/fetch-wiki-caches b/content-migration/hooks/fetch-wiki-caches
new file mode 100755
index 00000000..17d8d0e8
--- /dev/null
+++ b/content-migration/hooks/fetch-wiki-caches
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+ $hooks) {
+ foreach ($hooks as $hook) {
+ $hook_name = $hook['name'];
+ if ( file_exists($hook_name) ) {
+ echo "SKIPPING: $hook_name (already cached)";
+ }
+ else {
+ echo "DOWNLOADING: $hook_name" . PHP_EOL;
+ system("curl '$wiki_url/$hook_name' > '$hook_name'");
+ }
+ echo PHP_EOL;
+ }
+}
+
+echo "DONE" . PHP_EOL;
+
+
diff --git a/content-migration/hooks/hooks-by-category.php b/content-migration/hooks/hooks-by-category.php
new file mode 100644
index 00000000..30931c8f
--- /dev/null
+++ b/content-migration/hooks/hooks-by-category.php
@@ -0,0 +1,133 @@
+ [
+ ['name' => "hook_civicrm_copy", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_custom", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_managed", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_merge", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_post", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_pre", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_trigger_info", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_referenceCounts", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_postSave_table_name", 'is_deprecated' => false],
+ ],
+ "Extension lifecycle" => [
+ ['name' => "hook_civicrm_disable", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_enable", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_install", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_uninstall", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_upgrade", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_postInstall", 'is_deprecated' => false],
+ ],
+ "Form" => [
+ ['name' => "hook_civicrm_alterContent", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_buildForm", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_postProcess", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_validateForm", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterTemplateFile", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_preProcess", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_idsException", 'is_deprecated' => false],
+ ],
+ "GUI" => [
+ ['name' => "hook_civicrm_buildAmount", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_caseSummary", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_customFieldOptions", 'is_deprecated' => true],
+ ['name' => "hook_civicrm_dashboard", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_links", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_navigationMenu", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_pageRun", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_searchColumns", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_searchTasks", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_summary", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_summaryActions", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_tabs", 'is_deprecated' => true],
+ ['name' => "hook_civicrm_xmlMenu", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_tabset", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_dashboard_defaults", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_contact_get_displayname", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_fieldOptions", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterMenu", 'is_deprecated' => false],
+ ],
+ "Mail" => [
+ ['name' => "hook_civicrm_alterMailParams", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_emailProcessor", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_emailProcessorContact", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_mailingGroups", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_postEmailSend", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterMailer", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_unsubscribeGroups", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterMailContent", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_postMailing", 'is_deprecated' => false],
+ ],
+ "Permission" => [
+ ['name' => "hook_civicrm_aclGroup", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_aclWhereClause", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterAPIPermissions", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_permission_check", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_permission", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_selectWhereClause", 'is_deprecated' => false],
+ ],
+ "Uncategorized" => [
+ ['name' => "hook_civicrm_alterCalculatedMembershipStatus", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterBarcode", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterBadge", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterPaymentProcessorParams", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterSettingsFolders", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterSettingsMetaData", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_apiWrappers", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_buildStateProvinceForCountry", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_config", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_contactListQuery", 'is_deprecated' => true],
+ ['name' => "hook_civicrm_cron", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_dupeQuery", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_export", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_import", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_membershipTypeValues", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_tokens", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_tokenValues", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_queryObjects", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_check", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_optionValues", 'is_deprecated' => true],
+ ['name' => "hook_civicrm_coreResourceList", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_angularModules", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_container", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_crudLink", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_fileSearches", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_notePrivacy", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_eventDiscount", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_recent", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_unhandledException", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterMailingLabelParams", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_geocoderFormat", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_alterLogTables", 'is_deprecated' => false],
+ ],
+ "Case" => [
+ ['name' => "hook_civicrm_caseChange", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_caseTypes", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_post_case_merge", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_pre_case_merge", 'is_deprecated' => false],
+ ],
+ "Batch" => [
+ ['name' => "hook_civicrm_batchItems", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_batchQuery", 'is_deprecated' => false],
+ ],
+ "Entity" => [
+ ['name' => "hook_civicrm_entityTypes", 'is_deprecated' => false],
+ ],
+ "CiviRules" => [
+ ['name' => "hook_civirules_alter_trigger_data", 'is_deprecated' => false],
+ ['name' => "hook_civirules_logger", 'is_deprecated' => false],
+ ],
+ "Profile" => [
+ ['name' => "hook_civicrm_buildProfile", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_buildUFGroupsForModule", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_processProfile", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_searchProfile", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_validateProfile", 'is_deprecated' => false],
+ ['name' => "hook_civicrm_viewProfile", 'is_deprecated' => false],
+ ],
+ "Report" => [
+ ['name' => "hook_civicrm_alterReportVar", 'is_deprecated' => false],
+ ],
+];
\ No newline at end of file
diff --git a/content-migration/hooks/migrate-hooks b/content-migration/hooks/migrate-hooks
new file mode 100755
index 00000000..6d6584ab
--- /dev/null
+++ b/content-migration/hooks/migrate-hooks
@@ -0,0 +1,64 @@
+#!/usr/bin/env php
+ $hooks) {
+ foreach ($hooks as $hook) {
+ $hook_name = $hook['name'];
+ $markdown_file = "$hook_name.md";
+ $html = "$cache_dir/$hook_name";
+ if ( file_exists($html) && !file_exists($markdown_file) ) {
+ echo "converting $hook_name ... ";
+ $conv_output_array = array();
+ $conv_status = 1;
+ exec("webpage2md $html", $conv_output_array, $conv_status);
+ if( $conv_status == 0 ) {
+ $conv_output = implode("\n",$conv_output_array);
+ $conv_output = clean_markdown($conv_output);
+ file_put_contents($markdown_file, $conv_output);
+ echo "done" . PHP_EOL;
+ }
+ else {
+ echo "ERROR CONVERTING $hook_name" . PHP_EOL;
+ echo "$conv_output";
+ }
+ }
+ else if ( !file_exists($html) ) {
+ echo "WARNING: $hook_name not yet fetched" . PHP_EOL;
+ }
+ else if ( file_exists($markdown_file) ) {
+ echo "ignoring $hook_name (markdown file already exists)" . PHP_EOL;
+ }
+ }
+}
+
+
+
+
diff --git a/content-migration/hooks/print-nav-yaml b/content-migration/hooks/print-nav-yaml
new file mode 100755
index 00000000..5b3e69c2
--- /dev/null
+++ b/content-migration/hooks/print-nav-yaml
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+ $hooks) {
+ echo " - $category hooks:" . PHP_EOL;
+ foreach ($hooks as $hook) {
+ $hook_name = $hook['name'];
+ if ( $hook['is_deprecated'] ) {
+ $menu_name = "$hook_name";
+ }
+ else {
+ $menu_name = $hook_name;
+ }
+ echo " - $menu_name: hooks/$hook_name.md" . PHP_EOL;
+ }
+}
diff --git a/content-migration/hooks/print-redirects b/content-migration/hooks/print-redirects
new file mode 100755
index 00000000..c70687d7
--- /dev/null
+++ b/content-migration/hooks/print-redirects
@@ -0,0 +1,11 @@
+#!/usr/bin/env php
+ $hooks) {
+ foreach ($hooks as $hook) {
+ $hook_name = $hook['name'];
+ echo "$hook_name hooks/$hook_name" . PHP_EOL;
+ }
+}
diff --git a/content-migration/hooks/wiki_cache/.gitignore b/content-migration/hooks/wiki_cache/.gitignore
new file mode 100644
index 00000000..86d0cb27
--- /dev/null
+++ b/content-migration/hooks/wiki_cache/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
\ No newline at end of file
diff --git a/docs/hooks-db.md b/docs/hooks-db.md
deleted file mode 100644
index 19b12574..00000000
--- a/docs/hooks-db.md
+++ /dev/null
@@ -1,554 +0,0 @@
-# All Available Hooks
-
-This page provides official documentation on the specifics of each hook
-available within CiviCRM.
-
-**This page is currently incomplete**. Info needs to be moved from this
-[wiki page](https://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference)
-
-# hook_civicrm_copy
-
-This hook is called after a CiviCRM object (Event, ContributionPage, Profile) has been copied
-
-* Parameters:
- * $objectName - the name of the object that is being copied (Event, ContributionPage, UFGroup)
- * $object - reference to the copied object
-
-* Returns:
- * null
-
-* Definition/Example:
-```
-hook_civicrm_copy( $objectName, &$object )
-```
-
-
-# hook_civicrm_custom
-This hook is called AFTER the db write on a custom table
-
-* Parameters
-
- * string $op - the type of operation being performed
- * string $groupID - the custom group ID
- * object $entityID - the entityID of the row in the custom table
- * array $params - the parameters that were sent into the calling function
-
-* Returns:
- * null - the return value is ignored
-
-* Definition/Example:
-
-```
-/**
- * This example generates a custom contact ID (year + number, ex: 20080000001)
- */
-
-function MODULENAME_civicrm_custom( $op, $groupID, $entityID, &$params ) {
- if ( $op != 'create' && $op != 'edit' ) {
- return;
- }
-
- if ($groupID == 1) {
- $needs_update = false;
- $tableName = CRM_Core_DAO::getFieldValue( 'CRM_Core_DAO_CustomGroup',
- $groupID,
- 'table_name' );
-
-
- $sql = "SELECT member_id_4 FROM $tableName WHERE entity_id = $entityID";
- $dao = CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
-
- if (! $dao->fetch()) {
- $needs_update = true;
- }
-
- // Value may also be empty. i.e. delete the value in the interface to reset the field.
- if (! $dao->member_id_4) {
- $needs_update = true;
- }
-
- if ($needs_update) {
- $member_id = date('Y') . sprintf('%07d', $entityID);
-
- $sql = "UPDATE $tableName SET member_id_4 = $member_id WHERE entity_id = $entityID";
- CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
- }
- }
-}
-
-```
-
-# hook_civicrm_managed
-
-This hook allows a module to declare a list of 'managed' entities using the CiviCRM API - a managed entity will be automatically inserted, updated, deactivated, and deleted in tandem with enabling, disabling, and uninstalling the module. The hook is called periodically during cache-clear operations.
-
-For more background, see [API and the Art of Installation](http://civicrm.org/blogs/totten/api-and-art-installation).
-
-* Parameters
-
- * array $entities - the list of entity declarations; each declaration is an array with these following keys:
- * 'module': string; for module-extensions, this is the fully-qualifed name (e.g. "com.example.mymodule"); for Drupal modules, the name is prefixed by "drupal" (e.g. "drupal.mymodule")
- * 'name': string, a symbolic name which can be used to track this entity (Note: Each module creates its own namespace)
- * 'entity': string, an entity-type supported by the CiviCRM API (Note: this currently must be an entity which supports the 'is_active' property)
- * 'params': array, the entity data as supported by the CiviCRM API
- * 'update' (v4.5+): string, a policy which describes when to update records
- * 'always' (default): always update the managed-entity record; changes in $entities will override any local changes (eg by the site-admin)
- * 'never': never update the managed-entity record; changes made locally (eg by the site-admin) will override changes in $entities
- * 'cleanup' (v4.5+): string, a policy which describes whether to cleanup the record when it becomes orphaned (ie when $entities no longer references the record)
- * 'always' (default): always delete orphaned records
- * 'never': never delete orphaned records
- * 'unused': only delete orphaned records if there are no other references to it in the DB. (This is determined by calling the API's "getrefcount" action.)
-
-* Returns
-
- * void - the return value is ignored
-
-* Definition/Example:
-
-```
-/**
- * Declare a report-template which should be activated whenever this module is enabled
- */
-function modulename_civicrm_managed(&$entities) {
- $entities[] = array(
- 'module' => 'com.example.modulename',
- 'name' => 'myreport',
- 'entity' => 'ReportTemplate',
- 'params' => array(
- 'version' => 3,
- 'label' => 'Example Report',
- 'description' => 'Longish description of the example report',
- 'class_name' => 'CRM_Modulename_Report_Form_Sybunt',
- 'report_url' => 'mymodule/mysbunt',
- 'component' => 'CiviContribute',
- ),
- );
-}
-```
-
-# hook_civicrm_merge
-
-This hook allows modification of the data used to perform merging of duplicates. This can be useful if your custom module has added its own tables related to CiviCRM contacts.
-Availability
-
-This hook was first available in CiviCRM 3.2.3.
-
-* Parameters
-
- * $type the type of data being passed (cidRefs|eidRefs|relTables|sqls)
- * $data the data, which depends on the value of $type (see Details)
- * $mainId contact_id of the contact that survives the merge (only when $type == 'sqls')
- * $otherId contact_id of the contact that will be absorbed and deleted (only when $type == 'sqls')
- * $tables when $type is "sqls", an array of tables as it may have been handed to the calling function
-
-* Details
-
-The contents of $data will vary based on the $type of data being passed:
-
-* relTables:
-
- an array of tables used for asking user which elements to merge, as used at civicrm/contact/merge; each table in the array has this format:
-
- `'rel_table_UNIQUE-TABLE-NICKNAME' => array(
- 'title' => ts('TITLE'),
- 'tables' => array('TABLE-NAME' [, ...]),
- 'url' => CRM_Utils_System::url(PATH, QUERY),
- )`
-
-* sqls:
- a one-dimensional array of SQL statements to be run in the final merge operation;
- These SQL statements are run within a single transaction.
-* cidRefs:
- an array of tables and their fields referencing civicrm_contact.contact_id explicitely;
-
- each table in the array has this format:
- `'TABLE-NAME' => array('COLUMN-NAME' [, ...])`
-* eidRefs:
- an array of tables and their fields referencing civicrm_contact.contact_id with entity_id;
-
- each table in the array has this format:
- `'TABLE-NAME' => array('entity_table-COLUMN-NAME' => 'entity_id-COLUMN-NAME')`
-
-
-* Definition/Example:
-```
-hook_civicrm_merge ( $type, &$data, $mainId = NULL, $otherId = NULL, $tables = NULL )
-```
-```
-/* In this example we assume our module has created its own tables to store extra data on CiviCRM contacts:
- * Table civitest_foo stores a relationship between two contacts, and contains the two relevant columns:
- * civitest_foo.contact_id and civitest_foo.foo_id, both of which are foreign keys to civicrm_contact.id
- * Table civitest_bar stores extra properties for contacts, and contains one relevant column:
- * civitest_bar.contact_id is a foreign key to civicrm_contact.id
- *
- * This hook ensures that data in these two tables is included in CiviCRM merge operations.
- */
-function civitest_civicrm_merge ( $type, &$data, $mainId = NULL, $otherId = NULL, $tables = NULL ) {
-
- // If you are using Drupal and you use separate DBs for Drupal and CiviCRM, use the following to prefix
- // your tables with the name of the Drupal database.
- global $db_url;
- if (!empty($db_url) {
- $db_default = is_array($db_url) ? $db_url['default'] : $db_url;
- $db_default = ltrim(parse_url($db_default, PHP_URL_PATH), '/');
- }
- else {
- $db_default = '';
- }
-
- switch ($type) {
- case 'relTables':
- // Allow user to decide whether or not to merge records in `civitest_foo` table
- $data['rel_table_foo'] = array(
- 'title' => ts('Foos'), // Title as shown to user for this type of data
- 'tables' => array($db_default .'civitest_foo'), // Name of database table holding these records
- 'url' => CRM_Utils_System::url('civicrm/civitest/foo', 'action=browse&cid=$cid'),
- // URL to view this data for this contact,
- // in this case using CiviCRM's native URL utility
- // NOTE: '$cid' will be replaced with correct
- // CiviCRM contact ID.
- );
- break;
-
- case 'cidRefs':
- // Add references to civitest_foo.contact_id, and civitest_foo.foo_id, both of which
- // are foreign keys to civicrm_contact.id. By adding this to $data, records in this
- // table will be automatically included in the merge.
- $data[$db_default . 'civitest_foo'] = array('contact_id', 'foo_id');
- break;
-
- case 'eidRefs':
- // Add references to civitest_bar table, which is keyed to civicrm_contact.id
- // using `bar_entity_id` column, when `entity_table` is equal to 'civicrm_contact'. By
- // adding this to $data, records in this table will be automatically included in
- // the merge.
- $data[$db_default . 'civitest_bar'] = array('entity_table' => 'bar_entity_id');
- break;
-
- case 'sqls':
- // Note that this hook can be called twice with $type = 'sqls': once with $tables
- // and once without. In our case, SQL statements related to table `civitest_foo`
- // will be listed in $data when $tables is set; SQL statements related to table
- // `civitest_bar` will be listed in $data when $tables is NOT set. The deciding
- // factor here is that `civitest_foo` was referenced above as part of the 'relTables'
- // data, whereas `civitest_bar` was not.
- if ($tables) {
- // Nothing to do in our case. In some cases, you might want to find and
- // modify existing SQL statements in $data.
- } else {
- // Nothing to do in our case. In some cases, you might want to find and
- // modify existing SQL statements in $data.
- }
- break;
-
- }
-}
-
-```
-
-# hook_civicrm_post
-
-This hook is called after a db write on some core objects.
-
-pre and post hooks are useful for developers building more complex applications and need to perform operations before CiviCRM takes action. This is very applicable when you need to maintain foreign key constraints etc (when deleting an object, the child objects have to be deleted first).
-
-* Parameters
-
- * $op - operation being performed with CiviCRM object. Can have the following values:
- * 'view' : The CiviCRM object is going to be displayed
- * 'create' : The CiviCRM object is created (or contacts are being added to a group)
- * 'edit' : The CiviCRM object is edited
- * 'delete' : The CiviCRM object is being deleted (or contacts are being removed from a group)
-
- * 'trash': The contact is being moved to trash (Contact objects only)
- * 'restore': The contact is being restored from trash (Contact objects only)
-
- * $objectName - can have the following values:
- * 'Activity'
- * 'Address'
- * 'Case'
- * 'Campaign' (from 4.6)
- * 'Contribution'
- * 'ContributionRecur'
- * 'CRM_Mailing_DAO_Spool'
- * 'Email'
- * 'Event'
- * 'EntityTag'
- * 'Individual'
- * 'Household'
- * 'Organization'
- * 'Grant'
- * 'Group'
- * 'GroupContact'
- * 'LineItem'
- * 'Membership'
- * 'MembershipPayment'
- * 'Participant'
- * 'ParticipantPayment'
- * 'Phone'
- * 'Pledge'
- * 'PledgePayment'
- * 'Profile' (while this is not really an object, people have expressed an interest to perform an action when a profile is created/edited)
- * 'Relationship'
- * 'Tag'
- * 'UFMatch' (when an object is linked to a CMS user record, at the request of GordonH. A UFMatch object is passed for both the pre and post hooks)
-
- * $objectId - the unique identifier for the object. tagID in case of EntityTag
- * $objectRef - the reference to the object if available. For case of EntityTag it is an array of (entityTable, entityIDs)
-
-* Returns
-
- * None
-
-* Definition/Example:
-```
-hook_civicrm_post( $op, $objectName, $objectId, &$objectRef )
-```
-Here is a simple example that will send you an email whenever an INDIVIDUAL Contact is either Added, Updated or Deleted:
-
-Create a new folder called example_sendEmailOnIndividual in this directory /drupal_install_dir/sites/all/modules/civicrm/drupal/modules/ and then put the following two files in that directory (change the email addresses to yours).
-
-```
-FILE #1 /drupal_install_dir/sites/all/modules/civicrm/drupal/modules/example_sendEmailOnIndividual/example_endEmailOnIndividual.info
-```
-```
-name = Example Send Email On Individual
-description = Example that will send an email when an Individual Contact is Added, Updated or Deleted.
-dependencies[] = civicrm
-package = CiviCRM
-core = 7.x
-version = 1.0
-```
-```
-FILE #2 /drupal_install_dir/sites/all/modules/civicrm/drupal/modules/example_sendEmailOnIndividual/example_sendEmailOnIndividual.module
-```
-
-```
-display_name."\n";
- $send_an_email = true;
- } else if ($op == 'edit' && $objectName == 'Individual') {
- $email_sbj .= "- EDITED contact";
- $email_msg .= $objectRef->display_name."\n";
- $send_an_email = true;
- } else if ($op == 'delete' && $objectName == 'Individual') {
- $email_sbj .= "- DELETED contact";
- $email_msg .= $objectRef->display_name."\n";
- $email_msg .= 'Phone: '.$objectRef->phone."\n";
- $email_msg .= 'Email: '.$objectRef->email."\n";
- $send_an_email = true;
- }
-
- if ($send_an_email) {
- mail($email_to, $email_sbj, $email_msg, "From: ".$email_from);
- }
-
-}//end FUNCTION
-?>
-```
-
-Once the files are in the directory, you need to login to Drupal admin, go to Modules and enable our new module and click Save. Now go and edit a contact and you should get an email!
-
-
-# hook_civicrm_postSave_table_name
-
-This hook is called after writing to a database table that has an associated DAO. This includes core tables but not custom tables or log tables.
-
-* Parameters
-
- * $dao: The object that has been saved
-
-* Definition/Example:
-```
-hook_civicrm_postSave_[table_name]($dao)
-```
-```
-hook_civicrm_postSave_civicrm_contact($dao) {
- $contact_id = $dao->id;
- // 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.
-}
-```
-
-# hook_civicrm_pre
-
-This hook is called before a db write on some core objects. This hook does not allow the abort of the operation, use a form hook instead.
-
-We suspect the pre hook will be useful for developers building more complex applications and need to perform operations before CiviCRM takes action. This is very applicable when you need to maintain foreign key constraints etc (when deleting an object, the child objects have to be deleted first). Another good use for the pre hook is to see what is changing between the old and new data.
-
-* Parameters
-
- * $op - operation being performed with CiviCRM object. Can have the following values:
- * 'view' : The CiviCRM object is going to be displayed
- * 'create' : The CiviCRM object is created (or contacts are being added to a group)
- * 'edit' : The CiviCRM object is edited
- * 'delete' : The CiviCRM object is being deleted (or contacts are being removed from a group)
- * 'trash': The contact is being moved to trash (Contact objects only)
- * 'restore': The contact is being restored from trash (Contact objects only)
-
- * $objectName - can have the following values:
- * 'Individual'
- * 'Household'
- * 'Organization'
- * 'Group'
- * 'GroupContact'
- * 'Relationship'
- * 'Activity'
- * 'Contribution'
- * 'Profile' (while this is not really an object, people have expressed an interest to perform an action when a profile is created/edited)
- * 'Membership'
- * 'MembershipPayment'
- * 'Event'
- * 'Participant'
- * 'ParticipantPayment'
- * 'UFMatch' (when an object is linked to a CMS user record, at the request of GordonH. A UFMatch object is passed for both the pre and post hooks)
- * PledgePayment
- * ContributionRecur
- * Pledge
- * CustomGroup
- * 'Campaign' (from 4.6)
- * $id is the unique identifier for the object if available
- * &$params are the parameters passed
-
-* Returns
-
- * None
-
-* Definition/Example
-```
-hook_civicrm_pre($op, $objectName, $id, &$params)
-```
-
-
-# hook_civicrm_referenceCounts
-
-This hook is called to determine the reference-count for a record. For example, when counting references to the activity type "Phone Call", one would want a tally that includes:
-
-* The number of activity records which use "Phone Call"
-* The number of surveys which store data in "Phone Call" records
-* The number of case-types which can embed "Phone Call" records
-
-The reference-counter will automatically identify references stored in the CiviCRM SQL schema, including:
-
-* Proper SQL foreign-keys (declared with an SQL constraint)
-* Soft SQL foreign-keys that use the "entity_table"+"entity_id" pattern
-* Soft SQL foreign-keys that involve an OptionValue
-
-However, if you have references to stored in an external system (such as XML files or Drupal database), then you may want write a custom reference-counters.
-
-* Parameters
-
- * $dao: **CRM_Core_DAO**, the item for which we want a reference count
- * $refCounts: **array**, each item in the array is an array with keys:
- * name: **string**, eg "sql:civicrm_email:contact_id"
- * type: **string**, eg "sql"
- * count: **int**, eg "5" if there are 5 email addresses that refer to $dao
-
-* Returns
-
- * None
-
-* Definition/Examples:
-
-```
-hook_civicrm_referenceCounts($dao, &$refCounts)
-```
-
-Suppose we've written a module ("familytracker") which relies on the "Child Of" relationship-type. Now suppose an administrator considered deleting "Child Of" == we might want to determine if anything depends on "Child Of" and display a warning about possible breakage. This code would allow the "familytracker" to increase the reference-count for "Child Of".
-
-```
-name_a_b == 'Child Of') {
- $refCounts[] = array(
- 'name' => 'familytracker:childof',
- 'type' => 'familytracker',
- 'count' => 1,
- );
- }
-}
-```
-
-
-# hook_civicrm_trigger_info
-
-efine MYSQL Triggers. Using the hooks causes them not to clash with core or other extension triggers. They are compiled into one trigger with core triggers.
-
-Once the function is create, a trigger rebuild will have to be done to create the new trigger
-
-`http://yoursite/civicrm/menu/rebuild&reset=1&triggerRebuild=1`
-
-```
-/**
- * hook_civicrm_triggerInfo()
- *
- * Add trigger to update custom region field based on postcode (using a lookup table)
- *
- * Note that we have hard-coded a prioritisation of location types into this (since it's customer specific code
- * and unlikely to change)
- *
- * @param array $info (reference) array of triggers to be created
- * @param string $tableName - not sure how this bit works
- *
- **/
-
-function regionfields_civicrm_triggerInfo(&$info, $tableName) {
- $table_name = 'civicrm_value_region_13';
- $customFieldID = 45;
- $columnName = 'region_45';
- $sourceTable = 'civicrm_address';
- $locationPriorityOrder = '1, 3, 5, 2, 4, 6'; // hard coded prioritisation of addresses
- $zipTable = 'CANYRegion';
- if(civicrm_api3('custom_field', 'getcount', array('id' => $customFieldID, 'column_name' => 'region_45', 'is_active' => 1)) == 0) {
- return;
- }
-
- $sql = "
- REPLACE INTO `$table_name` (entity_id, $columnName)
- SELECT * FROM (
- SELECT contact_id, b.region
- FROM
- civicrm_address a INNER JOIN $zipTable b ON a.postal_code = b.zip
- WHERE a.contact_id = NEW.contact_id
- ORDER BY FIELD(location_type_id, $locationPriorityOrder )
- ) as regionlist
- GROUP BY contact_id;
-";
-$sql_field_parts = array();
-
-$info[] = array(
- 'table' => $sourceTable,
- 'when' => 'AFTER',
- 'event' => 'INSERT',
- 'sql' => $sql,
- );
-$info[] = array(
- 'table' => $sourceTable,
- 'when' => 'AFTER',
- 'event' => 'UPDATE',
- 'sql' => $sql,
- );
- // For delete, we reference OLD.contact_id instead of NEW.contact_id
-$sql = str_replace('NEW.contact_id', 'OLD.contact_id', $sql);
-$info[] = array(
- 'table' => $sourceTable,
- 'when' => 'AFTER',
- 'event' => 'DELETE',
- 'sql' => $sql,
- );
-}
-
-```
\ No newline at end of file
diff --git a/docs/hook.md b/docs/hooks.md
similarity index 100%
rename from docs/hook.md
rename to docs/hooks.md
diff --git a/docs/hooks/hook_civicrm_aclGroup.md b/docs/hooks/hook_civicrm_aclGroup.md
new file mode 100644
index 00000000..8225b951
--- /dev/null
+++ b/docs/hooks/hook_civicrm_aclGroup.md
@@ -0,0 +1,33 @@
+# hook_civicrm_aclGroup
+
+## Description
+
+This hook is called when composing the ACL to restrict access to civicrm
+entities (civicrm groups, profiles and events). NOTE: In order to use
+this hook you must uncheck "View All Contacts" AND "Edit All Contacts"
+in Drupal Permissions for the user role you want to limit. You can then
+go into CiviCRM and grant permission to Edit or View "All Contacts" or
+"Certain Groups". See the Forum Topic at:
+[http://forum.civicrm.org/index.php/topic,14595.0.html](http://forum.civicrm.org/index.php/topic,14595.0.html)
+for more information.
+
+## Definition
+
+ hook_civicrm_aclGroup( $type, $contactID, $tableName, &$allGroups, &$currentGroups )
+
+## Parameters
+
+- $type the type of permission needed
+- $contactID the contactID for whom the check is made
+- $tableName the tableName which is being permissioned
+- $allGroups the set of all the objects for the above table
+- $currentGroups the set of objects that are currently permissioned
+ for this contact . This array will be modified by the hook
+
+## Returns
+
+- null - the return value is ignored
+
+## Example
+
+Check [HRD Module](http://svn.civicrm.org/hrd/trunk/drupal/hrd.module)
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_aclWhereClause.md b/docs/hooks/hook_civicrm_aclWhereClause.md
new file mode 100644
index 00000000..f0f85df8
--- /dev/null
+++ b/docs/hooks/hook_civicrm_aclWhereClause.md
@@ -0,0 +1,85 @@
+# hook_civicrm_aclWhereClause
+
+## Description
+
+This hook is called when composing the ACL where clause to restrict
+visibility of contacts to the logged in user.
+
+Note that this hook is called only when filling up the
+civicrm_acl_contact_cache table, and not every time a contact SELECT
+query is performed. Those will join onto the
+civicrm_acl_contact_cache table.
+
+*NB: This hook will not be called at all if the logged in user has
+access to the "edit all contacts" permission.*
+
+## Definition
+
+ hook_civicrm_aclWhereClause( $type, &$tables, &$whereTables, &$contactID, &$where )
+
+## Parameters
+
+- $type - type of permission needed
+- array $tables - (reference ) add the tables that are needed for the
+ select clause
+- array $whereTables - (reference ) add the tables that are needed
+ for the where clause
+- int $contactID - the contactID for whom the check is made
+- string $where - the currrent where clause
+
+## Returns
+
+- void
+
+## Example
+
+ function civitest_civicrm_aclWhereClause( $type, &$tables, &$whereTables, &$contactID, &$where ) {
+ if ( ! $contactID ) {
+ return;
+ }
+
+ $permissionTable = 'civicrm_value_permission';
+ $regionTable = 'civicrm_value_region';
+ $fields = array( 'electorate' => 'Integer',
+ 'province' => 'Integer',
+ 'branch' => 'Integer' );
+
+ // get all the values from the permission table for this contact
+ $keys = implode( ', ', array_keys( $fields ) );
+ $sql = "
+ SELECT $keys
+ FROM {$permissionTable}
+ WHERE entity_id = $contactID
+ ";
+ $dao = CRM_Core_DAO::executeQuery( $sql,
+ CRM_Core_DAO::$_nullArray );
+ if ( ! $dao->fetch( ) ) {
+ return;
+ }
+
+ $tables[$regionTable] = $whereTables[$regionTable] =
+ "LEFT JOIN {$regionTable} regionTable ON contact_a.id = regionTable.entity_id";
+
+ $clauses = array( );
+ foreach( $fields as $field => $fieldType ) {
+ if ( ! empty( $dao->$field ) ) {
+ if ( strpos( CRM_Core_DAO::VALUE_SEPARATOR, $dao->$field ) !== false ) {
+ $value = substr( $dao->$field, 1, -1 );
+ $values = explode( CRM_Core_DAO::VALUE_SEPARATOR, $value );
+ foreach ( $values as $v ) {
+ $clauses[] = "regionTable.{$field} = $v";
+ }
+ } else {
+ if ( $fieldType == 'String' ) {
+ $clauses[] = "regionTable.{$field} = '{$dao->$field}'";
+ } else {
+ $clauses[] = "regionTable.{$field} = {$dao->$field}";
+ }
+ }
+ }
+ }
+
+ if ( ! empty( $clauses ) ) {
+ $where .= ' AND (' . implode( ' OR ', $clauses ) . ')';
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterAPIPermissions.md b/docs/hooks/hook_civicrm_alterAPIPermissions.md
new file mode 100644
index 00000000..4deca4d4
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterAPIPermissions.md
@@ -0,0 +1,74 @@
+# hook_civicrm_alterAPIPermissions
+
+## Description
+
+This hook is called when API 3 permissions are checked and 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).
+
+Note that if a given entity/action permissions are unset, the default
+‘access CiviCRM’ permission is enforced.
+
+Note also that the entity in $permissions array use the camel case
+syntax (e.g. $permissions['option_group']['get'] = ... and not
+$permissions['OptionGroup']['get'] = ...)
+
+## Definition
+
+ hook_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions)
+
+## Parameters
+
+- string $entity the API entity (like contact)
+- string $action the API action (like get)
+- array &$params the API parameters
+- array &$permisisons the associative permissions array (probably to
+ be altered by this hook)
+
+## Returns
+
+- null
+
+## Availability
+
+- This hook was first available in CiviCRM 3.4.1
+
+## Example
+
+ /**
+ * alterAPIPermissions() hook allows you to change the permissions checked when doing API 3 calls.
+ */
+ function civitest_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions)
+ {
+ // skip permission checks for contact/create calls
+ // (but keep the ones for email, address, etc./create calls)
+ // note: unsetting the below would require the default ‘access CiviCRM’ permission
+ $permissions['contact']['create'] = array();
+
+ // enforce ‘view all contacts’ check for contact/get, but do not test ‘access CiviCRM’
+ $permissions['contact']['get'] = array('view all contacts');
+
+ // add a new permission requirement for your own custom API call
+ // (if all you want to enforce is ‘access CiviCRM’ you can skip the below altogether)
+ $permissions['foo']['get'] = array('access CiviCRM', 'get all foos');
+
+ // allow everyone to get info for a given event; also – another way to skip permissions
+ if ($entity == 'event' and $action == 'get' and $params['title'] == 'CiviCon 2038') {
+ $params['check_permissions'] = false;
+ }
+ }
+
+## Notes on Example
+
+When developing an extension with custom API, this code is placed
+directly in the API php file that you have created. In this case the
+extension would be named CiviTest. The API function for the GET would be
+: function civicrm_api3_civi_test_get(); The alterAPIPermissions
+function is prefixed with the full extension name, all lowercase,
+followed by "_civicrm_alterAPIPermissions".
+
+There seems to be a bit of inconsistency between civiCRM 4.2.6 and
+civiCRM 4.2.13. See attached screen.\
+
+
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterBadge.md b/docs/hooks/hook_civicrm_alterBadge.md
new file mode 100644
index 00000000..e45e8cf4
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterBadge.md
@@ -0,0 +1,62 @@
+# hook_civicrm_alterBadge
+
+## Description
+
+This hook allows one to modify the content and format of the name
+badges. Available in 4.5+.
+
+## Definition
+
+ hook_civicrm_alterBadge($labelName, &$label, &$format, &$participant);
+
+## Parameters
+
+- $labelName - a string containing the name of the Badge format
+ being used
+- $label - the CRM_Badge_BAO_Badge object, contains
+ $label->pdf object
+- $format - the $formattedRow array used to create the
+ badges--contains information like font and positioning
+ - there is one entry for each element (6 in total, as you can see
+ here /civicrm/admin/badgelayout?action=update&id=1&reset=1) with
+ array of values for each element. Each array has the following
+ keys: token, value, text_alignment, font_style (bold, italic,
+ normal), font_size, font_name (the options for each key are
+ the options that are available on this screen:
+ civicrm/admin/badgelayout?action=update&id=1&reset=1), for
+ example:
+
+ \
+ token => {participant.participant_role}
+
+ text_alignment => C
+
+ font_style => bold
+
+ font_size => 20
+
+ font_name => courier
+
+ value => Staff
+
+
+
+- $participant - array of token values for participant that will
+ be displayed on badge, includes contact_id
+
+## Returns
+
+## Example
+
+
+
+ function hook_civicrm_alterBadge($labelName, &$label, &$format, &$participant) {
+ if ($labelName == 'My Custom Badge') {
+ // change the font size for contact_id=12
+ if ($participant['contact_id']==12){
+ foreach ($format['token'] as $valueFormat){
+ $valueFormat['font_size'] = 10;
+ }
+ }
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterBarcode.md b/docs/hooks/hook_civicrm_alterBarcode.md
new file mode 100644
index 00000000..bd98866d
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterBarcode.md
@@ -0,0 +1,31 @@
+# hook_civicrm_alterBarcode
+
+## Description
+
+This hook allows one to modify the content that is encoded in barcode.
+Available in 4.4+.
+
+## Definition
+
+ hook_civicrm_alterBarcode( &$data, $type='barcode' $context='name_badge' );
+
+## Parameters
+
+- $data - is an associated array with all token values and some
+ additional info
+ - $data['current_value'] - this will hold default value set by
+ CiviCRM
+- $type - type of barcode ( barcode or qrcode )
+- $context - currently this functionality is implemented only for
+ name badges, hence context=name_badge
+
+## Returns
+
+## Example
+
+ function hook_civicrm_alterBarcode(&$data, $type, $context ) {
+ if ($type == 'barcode' && $context == 'name_badge') {
+ // change the encoding of barcode
+ $data['current_value'] = $data['event_id'] . '-' . $data['participant_id'] . '-' . $data['contact_id'];
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterCalculatedMembershipStatus.md b/docs/hooks/hook_civicrm_alterCalculatedMembershipStatus.md
new file mode 100644
index 00000000..d6afc82a
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterCalculatedMembershipStatus.md
@@ -0,0 +1,73 @@
+# hook_civicrm_alterCalculatedMembershipStatus
+
+## Description
+
+This hook is called when calculating the membership status - e.g on a
+form or in the cron job that rolls over statuses
+
+## Definition
+
+`hook_civicrm_alterCalculatedMembershipStatus(&$membershipStatus, $arguments, $membership) {`{.java
+.plain}
+
+## Parameters
+
+ * $membershipStatus the calculated membership status array
+
+ * $arguments arguments used in the calculation
+
+ * $membership the membership array from the calling function
+
+## Added
+
+4.5., 4.4.10
+
+## Notes
+
+Although the membership array is passed through to the hooks no work has
+gone into ensuring the consistency of the data in the membership array
+so far - it was added to the parameters on the basis that it was easy to
+think of a use case (e.g requiring approval) but not tested against a
+current use case
+
+## Examples
+
+Extend Grace period to one year for membership types 14, 15 & 16
+
+ /**
+
+ * Implementation of hook_civicrm_alterCalculatedMembershipStatus
+
+ * Set membership status according to membership type
+
+ * @param array $membershipStatus the calculated membership status array
+
+ * @param array $arguments arguments used in the calculation
+
+ * @param array $membership the membership array from the calling function
+
+ */
+
+ function membershipstatus_civicrm_alterCalculatedMembershipStatus(&$membershipStatus, $arguments, $membership) {
+
+ //currently we are hardcoding a rule for membership type ids 14, 15, & 16
+
+ if(empty($arguments['membership_type_id']) || !in_array($arguments['membership_type_id'], array(14, 15, 16))) {
+
+ return;
+
+ }
+
+ $statusDate = strtotime($arguments['status_date']);
+
+ $endDate = strtotime($arguments['end_date']);
+
+ $graceEndDate = strtotime('+ 12 months', $endDate);
+
+ if($statusDate > $endDate && $statusDate <= $graceEndDate) {
+
+ $membershipStatus['name'] = 'Grace';
+
+ $membershipStatus['id'] = 8;
+
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterContent.md b/docs/hooks/hook_civicrm_alterContent.md
new file mode 100644
index 00000000..c6d23f1f
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterContent.md
@@ -0,0 +1,40 @@
+# hook_civicrm_alterContent
+
+## Description
+
+This hook is invoked after all the content of a CiviCRM form or page is
+generated. It allows for direct manipulation of the generated content.
+
+## Definition
+
+ hook_civicrm_alterContent( &$content, $context, $tplName, &$object )
+
+## Parameters
+
+- string $content - previously generated content
+- string $context - context of content - page or form
+- string $tplName - the file name of the tpl
+- object $object - a reference to the page or form object
+
+## Returns
+
+## Example
+
+ /**
+ * Alter fields for an event registration to make them into a demo form.
+ */
+ function example_civicrm_alterContent( &$content, $context, $tplName, &$object ) {
+ if($context == "form") {
+ if($tplName == "CRM/Event/Form/Registration/Register.tpl") {
+ if($object->_eventId == 1) {
+ $content = "
Below is an example of an event registration.
".$content;
+ $content = str_replace("Above is an example of an event registration";
+ }
+ }
+ }
+ }
+
+!!! tip
+ While this hook is included in the Form related hooks section it can be used to alter almost all generated content.
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterLogTables.md b/docs/hooks/hook_civicrm_alterLogTables.md
new file mode 100644
index 00000000..f6daa477
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterLogTables.md
@@ -0,0 +1,72 @@
+# hook_civicrm_alterLogTables
+
+## Description
+
+This hook allows you to amend the specification of the log tables to be
+created when logging is turned on. 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.
+
+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.
+
+
+
+There is, however, a function that will convert Archive tables to log
+tables (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.
+
+## Availability
+
+This hook was first available in CiviCRM 4.7.7.
+
+## Definition
+
+
+
+ ---------------------------------------------------------------
+ `hook_`{.java .plain}civicrm_alterLogTables(&$logTableSpec)
+ ---------------------------------------------------------------
+
+
+
+## Parameters
+
+- @param array $logTableSpec\
+ \
+ \
+
+## Example
+
+ This defines all tables as INNODB and adds indexes.
+
+ https://github.com/eileenmcnaughton/nz.co.fuzion.innodbtriggers
+
+ /**
+ * Implements hook_alterLogTables().
+ *
+ * @param array $logTableSpec
+ */
+ function innodbtriggers_civicrm_alterLogTables(&$logTableSpec) {
+ $contactReferences = CRM_Dedupe_Merger::cidRefs();
+ foreach (array_keys($logTableSpec) as $tableName) {
+ $contactIndexes = array();
+ $logTableSpec[$tableName]['engine'] = 'INNODB';
+ $logTableSpec[$tableName]['engine_config'] = 'ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4';
+ $contactRefsForTable = CRM_Utils_Array::value($tableName, $contactReferences, array());
+ foreach ($contactRefsForTable as $fieldName) {
+ $contactIndexes['index_' . $fieldName] = $fieldName;
+ }
+ $logTableSpec[$tableName]['indexes'] = array_merge(array(
+ 'index_id' => 'id',
+ 'index_log_conn_id' => 'log_conn_id',
+ 'index_log_date' => 'log_date',
+ ), $contactIndexes);
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterMailContent.md b/docs/hooks/hook_civicrm_alterMailContent.md
new file mode 100644
index 00000000..1febfbbf
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterMailContent.md
@@ -0,0 +1,18 @@
+# hook_civicrm_alterMailContent
+
+## Description
+
+This hook is called after getting the content of the mail and before
+tokenizing it.
+
+## Definition
+
+ hook_civicrm_alterMailContent(&$content)
+
+## Parameters
+
+- $content - fields that include the content of the mail
+
+## Details
+
+- $content - fields include: html, text, subject
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterMailParams.md b/docs/hooks/hook_civicrm_alterMailParams.md
new file mode 100644
index 00000000..422122ff
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterMailParams.md
@@ -0,0 +1,34 @@
+# hook_civicrm_alterMailParams
+
+## Description
+
+This hook is called when an email is about to be sent by CiviCRM.
+
+## Definition
+
+ hook_civicrm_alterMailParams(&$params, $context)
+
+## Parameters
+
+- $params - the mailing params array
+- $context - the contexts of the hook call are:
+ - "civimail" for when sending an email using civimail,
+ - "singleEmail" for when sending a single email,
+ - "messageTemplate" for when sending an email using a message
+ template
+
+## Details
+
+- $params array fields include: groupName, from, toName, toEmail,
+ subject, cc, bcc, text, html, returnPath, replyTo, headers,
+ attachments (array)
+- If you want to abort the mail from being sent, set the boolean
+ abortMailSend to true in the params array
+
+re: the changes made today with regard to the context – I think
+"singleEmail" should be changed to "activity" – indicating it's
+triggered during the send email activity – which may be to one or more
+contacts. while "singleEmail" could be interpreted as... a single email
+to multiple people... the terminology is confusing. I think it's better
+to condition on the actual object type (an activity) as the other
+parameter options already do.
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterMailer.md b/docs/hooks/hook_civicrm_alterMailer.md
new file mode 100644
index 00000000..22d27922
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterMailer.md
@@ -0,0 +1,66 @@
+# hook_civicrm_alterMailer
+
+## Description
+
+This hook is called when CiviCRM prepares an email driver class to
+handle outbound message delivery.
+
+Introduced in CiviCRM v4.4.
+
+## Definition
+
+ hook_civicrm_alterMailer(&$mailer, $driver, $params)
+
+## Parameters
+
+- object**$mailer** -The default mailer produced by normal
+ configuration; a PEAR "Mail" class (like those returned by
+ Mail::factory)
+
+- string **$driver** - The type of the default $mailer (eg "smtp",
+ "sendmail", "mock", "CRM_Mailing_BAO_Spool")
+
+- array **$params** - The default config options used to construct
+ $mailer
+
+## Example
+
+ /**
+ * Implementation of hook_civicrm_alterMailer
+ *
+ * Replace the normal mailer with our custom mailer
+ */
+ function example_civicrm_alterMailer(&$mailer, $driver, $params) {
+ $mailer = new ExampleMailDriver();
+ }
+
+ /**
+ * Outbound mailer which writes messages to a log file
+ *
+ * For better examples, see PEAR Mail.
+ *
+ * @see Mail_null
+ * @see Mail_mock
+ * @see Mail_sendmail
+ * @see Mail_smtp
+ */
+ class ExampleMailDriver {
+ /**
+ * Send an email
+ */
+ function send($recipients, $headers, $body) {
+ // Write mail out to a log file instead of delivering it
+ $data = array(
+ 'recipients' => $recipients,
+ 'headers' => $headers,
+ 'body' => $body,
+ );
+ file_put_contents('/tmp/outbound-mail.log', json_encode($data), FILE_APPEND);
+ }
+ }
+
+[Jon Goldberg](https://wiki.civicrm.org/confluence/display/~palantejon), good catch spotting a
+discrepancy in the naming. However, I've switched the docs back to say
+"alterMailer" because that was the downstream/consumable interface. More
+discussion a
+[https://github.com/civicrm/civicrm-core/pull/7500](https://github.com/civicrm/civicrm-core/pull/7500)
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterMailingLabelParams.md b/docs/hooks/hook_civicrm_alterMailingLabelParams.md
new file mode 100644
index 00000000..cad6a2c0
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterMailingLabelParams.md
@@ -0,0 +1,73 @@
+# hook_civicrm_alterMailingLabelParams
+
+## Description
+
+This hook is called to alter the parameters used to generate mailing
+labels. To be added in CiviCRM 4.1 or later.
+
+## Definition
+
+ function hook_civicrm_alterMailingLabelParams( &$args )
+
+## Parameters
+
+- $args: reference to the associative array of arguments that are
+ about to be used to generate mailing labels
+-
+
+
+
+ @param array $args an array of the args for the tcpdf MultiCell api call with the variable names below converted into string keys
+ (ie $w become 'w' as the first key for $args).
+ If ishtml is set true, then a subset of the args will be passed to the tcdpdf writeHTMLCell api call instead.
+
+ float $w Width of cells. If 0, they extend up to the right margin of the page.
+ float $h Cell minimum height. The cell extends automatically if needed.
+ string $txt String to print
+ mixed $border Indicates if borders must be drawn around the cell block. The value can
+ be either
+ a number:
+ 0: no border (default)
+ 1: frame or
+ a string containing some or all of the following characters (in any order):
+ L: left
+ T: top
+ R: right
+ B: bottom
+ string $align Allows to center or align the text. Possible values are:
+ L or empty string: left align
+ C: center
+ R: right align
+ J: justification (default value when $ishtml=false)
+ int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
+ int $ln Indicates where the current position should go after the call. Possible values are:
+ 0: to the right
+ 1: to the beginning of the next line DEFAULT
+ 2: below
+ float $x x position in user units
+ float $y y position in user units
+ boolean $reseth if true reset the last cell height (default true).
+ int $stretch stretch carachter mode:
+ 0 = disabled
+ 1 = horizontal scaling only if necessary
+ 2 = forced horizontal scaling
+ 3 = character spacing only if necessary
+ 4 = forced character spacing
+ boolean $ishtml set to true if $txt is HTML content (default = false).
+ boolean $autopadding if true, uses internal padding and automatically adjust it to account for line width.
+ float $maxh maximum height. It should be >= $h and less then remaining space to the bottom of the page,
+ or 0 for disable this feature. This feature works only when $ishtml=false.
+
+NB: not all html tags are supported, not all style parameters are
+supported, and improperly constructed html tends to lead to errors and
+crashes.
+
+## Returns
+
+- null
+
+## Example
+
+ function mymodule_civicrm_alterMailingLabelParams( &$args ) {
+ $args['ishtml'] = true;
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterMenu.md b/docs/hooks/hook_civicrm_alterMenu.md
new file mode 100644
index 00000000..5e8f42e4
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterMenu.md
@@ -0,0 +1,53 @@
+# hook_civicrm_alterMenu
+
+## Description
+
+This hook is called when building CiviCRM's list of HTTP routes. This
+hook should be used when you want to register custom paths or URLS. You
+will need to visit /civicrm/menu/rebuild?reset=1 to pick
+up your additions.
+
+Added in CiviCRM 4.7.11.
+
+
+
+!!! note "Comparison of Related Hooks"
+ This is one of three related hooks. The hooks:
+
+ - [hook_civicrm_navigationMenu](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_navigationMenu) manipulates the navigation bar at the top of every screen
+ - [hook_civicrm_alterMenu](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterMenu) manipulates the list of HTTP routes (using PHP arrays)
+ - [hook_civicrm_xmlMenu](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu) manipulates the list of HTTP routes (using XML files)
+
+
+
+
+
+## Definition
+
+ hook_civicrm_alterMenu(&$items)
+
+## Parameters
+
+- *"$items*" the array of HTTP routes, keyed by relative path. Each
+ includes some combination of properties:
+ - "*page_callback*": This should refer to a page/controller class
+ ("*CRM_Example_Page_Example*") or a static function
+ ("*CRM_Example_Page_AJAX::foobar*").
+ - "*access_callback*": (usually omitted)
+ - "*access_arguments*": Description of required permissions. Ex:
+ *array(array('access CiviCRM'), 'and')*
+
+## Returns
+
+- null
+
+## Example
+
+
+
+ function EXAMPLE_civicrm_alterMenu(&$items) {
+ $items['civicrm/my-page'] = array(
+ 'page_callback' => 'CRM_Example_Page_AJAX::foobar',
+ 'access_arguments' => array(array('access CiviCRM'), "and"),
+ );
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterPaymentProcessorParams.md b/docs/hooks/hook_civicrm_alterPaymentProcessorParams.md
new file mode 100644
index 00000000..f7c251d1
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterPaymentProcessorParams.md
@@ -0,0 +1,32 @@
+# hook_civicrm_alterPaymentProcessorParams
+
+## Description
+
+This hook is called during the processing of a contribution after the
+payment processor has control, but just before the CiviCRM processor
+specific code starts a transaction with the back-end payments server
+(e.g., PayPal, Authorized.net, or Moneris). It allows you to modify the
+parameters passed to the back end so that you can pass custom
+parameters, or use features of your back-end that CiviCRM does not
+"know" about.
+
+## Definition
+
+ Code Block
+
+ hook_civicrm_alterPaymentProcessorParams($paymentObj,&$rawParams, &$cookedParams);
+
+## Parameters
+
+- $paymentObj - instance of payment class of the payment processor
+ invoked
+- $rawParams - the associative array passed by CiviCRM to the
+ processor
+- $cookedParams - the associative array of parameters as translated
+ into the processor's API.
+
+## Returns
+
+## Example
+
+ function civitest_civicrm_alterPaymentProcessorParams($paymentObj, &$rawParams, &$cookedParams) { if ($paymentObj->class_name == Payment_Dummy ) { $employer = empty($rawParams['custom_1']) ? '' : $rawParams['custom_1']; $occupation = empty($rawParams['custom_2']) ? '' : $rawParams['custom_2']; $cookedParams['custom'] = "$employer|$occupation"; } else if ($paymentObj->class_name == Payment_AuthorizeNet) { //Actual translation for one application: //Employer > Ship to Country (x_ship_to_country) //Occupation > Company (x_company) //Solicitor > Ship-to First Name (x_ship_to_first_name) //Event > Ship-to Last Name (x_ship_to_last_name) //Other > Ship-to Company (x_ship_to_company) $cookedParams['x_ship_to_country'] = $rawParams['custom_1']; $cookedParams['x_company'] = $rawParams['custom_2']; $cookedParams['x_ship_to_last_name'] = $rawParams['accountingCode']; //for now $country_info = da_core_fetch_country_data_by_crm_id($rawParams['country-1']); $cookedParams['x_ship_to_company'] = $country_info['iso_code']; } elseif ($paymentObj->billing_mode == 2) { // Express Checkout $cookedParams['desc'] = $rawParams['eventName']; $cookedParams['custom'] = $rawParams['eventId']; }}
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterReportVar.md b/docs/hooks/hook_civicrm_alterReportVar.md
new file mode 100644
index 00000000..c32ff446
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterReportVar.md
@@ -0,0 +1,95 @@
+# hook_civicrm_alterReportVar
+
+## Description
+
+This hook is used to add / modify display columns, filters ..etc
+
+## Definition
+
+ alterReportVar($varType, &$var, &$object) {
+
+## Parameters
+
+- $varType - a string containing the value "columns", "rows", or
+ "sql", depending on where the hook is called.
+- &$var - a mixed var containing the columns, rows, or SQL, depending
+ on where the hook is called
+- &$object - a reference to the CRM_Report_Form object.
+
+## Returns
+
+- null
+
+## Example
+
+From the [Mandrill Transaction
+Email](https://github.com/JMAConsulting/biz.jmaconsulting.mte)
+extension, this code checks to see if this is a mailing
+bounce/open/clicks/detail report. If so, it uses mailing data stored in
+a custom table "civicrm_mandrill_activity", and sets the SQL and
+columns appropriately.
+
+ /**
+ * Implementation of hook_civicrm_alterReportVar
+ */
+ function mte_civicrm_alterReportVar($varType, &$var, &$object) {
+ $instanceValue = $object->getVar('_instanceValues');
+ if (!empty($instanceValue) &&
+ in_array(
+ $instanceValue['report_id'],
+ array(
+ 'Mailing/bounce',
+ 'Mailing/opened',
+ 'Mailing/clicks',
+ 'mailing/detail',
+ )
+ )
+ ) {
+ if ($varType == 'sql') {
+ if (array_key_exists('civicrm_mailing_mailing_name', $var->_columnHeaders)) {
+ $var->_columnHeaders['civicrm_mandrill_activity_id'] = array(
+ 'type' => 1,
+ 'title' => 'activity',
+ );
+ $var->_columnHeaders['civicrm_mailing_id'] = array(
+ 'type' => 1,
+ 'title' => 'mailing id',
+ );
+ $var->_select .= ' , civicrm_mandrill_activity.activity_id as civicrm_mandrill_activity_id, mailing_civireport.id as civicrm_mailing_id ';
+
+ $from = $var->getVar('_from');
+ $from .= ' LEFT JOIN civicrm_mandrill_activity ON civicrm_mailing_event_queue.id = civicrm_mandrill_activity.mailing_queue_id';
+ $var->setVar('_from', $from);
+ if ($instanceValue['report_id'] == 'Mailing/opened') {
+ $var->_columnHeaders['opened_count'] = array(
+ 'type' => 1,
+ 'title' => ts('Opened Count'),
+ );
+ $var->_select .= ' , count(DISTINCT(civicrm_mailing_event_opened.id)) as opened_count';
+ $var->_groupBy = ' GROUP BY civicrm_mailing_event_queue.id';
+ }
+ }
+ }
+ if ($varType == 'rows') {
+ $mail = new CRM_Mailing_DAO_Mailing();
+ $mail->subject = "***All Transactional Emails***";
+ $mail->url_tracking = TRUE;
+ $mail->forward_replies = FALSE;
+ $mail->auto_responder = FALSE;
+ $mail->open_tracking = TRUE;
+ $mail->find(true);
+ if (array_key_exists('civicrm_mailing_mailing_name', $object->_columnHeaders)) {
+ foreach ($var as $key => $value) {
+ if (!empty($value['civicrm_mandrill_activity_id']) && $mail->id == $value['civicrm_mailing_id']) {
+ $var[$key]['civicrm_mailing_mailing_name_link'] = CRM_Utils_System::url(
+ 'civicrm/activity',
+ "reset=1&action=view&cid={$value['civicrm_contact_id']}&id={$value['civicrm_mandrill_activity_id']}"
+ );
+ $var[$key]['civicrm_mailing_mailing_name_hover'] = ts('View Transactional Email');
+ }
+ }
+ unset($object->_columnHeaders['civicrm_mandrill_activity_id'], $object->_columnHeaders['civicrm_mailing_id']);
+ }
+ }
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterSettingsFolders.md b/docs/hooks/hook_civicrm_alterSettingsFolders.md
new file mode 100644
index 00000000..53585fcf
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterSettingsFolders.md
@@ -0,0 +1,22 @@
+# hook_civicrm_alterSettingsFolders
+
+## Description
+
+The [Settings](https://wiki.civicrm.org/confluence/display/CRMDOC/Settings+Reference) subsystem
+provides metadata about many of CiviCRM's internal settings by scanning
+for files matching "settings/*.setting.php" (e.g.
+[settings/Core.setting.php](https://github.com/civicrm/civicrm-core/blob/4.3/settings/Core.setting.php)).
+This hook allows modules and extensions to scan for settings in
+additional folders.
+
+## Availability
+
+This hook was introduced in CiviCRM v4.3.0 and v4.2.10.
+
+## Definition
+
+ hook_civicrm_alterSettingsFolders(&$metaDataFolders)
+
+## Parameters
+
+- @param array $metaDataFolders list of directory paths
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterSettingsMetaData.md b/docs/hooks/hook_civicrm_alterSettingsMetaData.md
new file mode 100644
index 00000000..fa6bddde
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterSettingsMetaData.md
@@ -0,0 +1,8 @@
+# hook_civicrm_alterSettingsMetaData
+
+hook_civicrm_alterSettingsMetaData($settingsMetadata, $domainID,
+$profile);
+
+
+
+This describes available settings
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_alterTemplateFile.md b/docs/hooks/hook_civicrm_alterTemplateFile.md
new file mode 100644
index 00000000..ac520681
--- /dev/null
+++ b/docs/hooks/hook_civicrm_alterTemplateFile.md
@@ -0,0 +1,70 @@
+# hook_civicrm_alterTemplateFile
+
+## Description
+
+This hook is invoked while selecting the tpl file to use to render the
+page
+
+## Definition
+
+ hook_civicrm_alterTemplateFile($formName, &$form, $context, &$tplName)
+
+
+
+## Parameters
+
+- string $formname -name of the form
+- object $form (reference) for object
+- string $context page or form
+- string $tplName - the file name of the tpl - alter this to alter
+ the file in use
+
+## Returns
+
+## Example
+
+
+
+ /**
+ * Alter tpl file to include a different tpl file based on contribution/financial type
+ * (if one exists). It will look for
+ * templates/CRM/Contribute/Form/Contribution/Type2/Main.php
+ * where the form has a contribution or financial type of 2
+ * @param string $formName name of the form
+ * @param object $form (reference) form object
+ * @param string $context page or form
+ * @param string $tplName (reference) change this if required to the altered tpl file
+ */
+ function tplbytype_civicrm_alterTemplateFile($formName, &$form, $context, &$tplName) {
+ $formsToTouch = array(
+ 'CRM_Contribute_Form_Contribution_Main' => array('path' => 'CRM/Contribute/Form/Contribution/', 'file' => 'Main'),
+
+ 'CRM_Contribute_Form_Contribution_Confirm' => array('path' =>
+ 'CRM/Contribute/Form/Contribution', 'file' => 'Confirm'),
+
+ 'CRM_Contribute_Form_Contribution_ThankYou' => array('path' =>
+ 'CRM/Contribute/Form/Contribution', 'file' => 'ThankYou'),
+ );
+
+
+ if(!array_key_exists($formName, $formsToTouch)) {
+ return;
+ }
+ if(isset($form->_values['financial_type_id'])) {
+ $type = 'Type' . $form->_values['financial_type_id'];
+ }
+ if(isset($form->_values['contribution_type_id'])) {
+ $type = 'Type' . $form->_values['contribution_type_id'];
+ }
+ if(empty($type)) {
+ return;
+ }
+ $possibleTpl = $formsToTouch[$formName]['path'] . $type . '/' . $formsToTouch[$formName]['file']. '.tpl';
+ $template = CRM_Core_Smarty::singleton();
+ if ($template->template_exists($possibleTpl)) {
+ $tplName = $possibleTpl;
+ }
+ }
+
+!!! tip
+ While this hook is included in the Form related hooks section it can be used to alter almost all generated content.
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_angularModules.md b/docs/hooks/hook_civicrm_angularModules.md
new file mode 100644
index 00000000..914dc37f
--- /dev/null
+++ b/docs/hooks/hook_civicrm_angularModules.md
@@ -0,0 +1,39 @@
+# hook_civicrm_angularModules
+
+## Description
+
+EXPERIMENTAL: This hook generates a list of Angular modeules. It allows
+one to register additional Angular modules.
+
+## Availability
+
+This hook is available in CiviCRM 4.5+. It may use features only
+available in CiviCRM 4.6+.
+
+## Definition
+
+ angularModules(&$angularModules)
+
+## Parameters
+
+- &$angularModules - an array containing a list of all Angular
+ modules.
+
+## Returns
+
+- null
+
+## Example
+
+ function mymod_civicrm_angularModules(&$angularModules) {
+ $angularModules['myAngularModule'] = array(
+ 'ext' => 'org.example.mymod',
+ 'js' => array('js/myAngularModule.js'),
+ );
+ $angularModules['myBigAngularModule'] = array(
+ 'ext' => 'org.example.mymod',
+ 'js' => array('js/part1.js', 'js/part2.js'),
+ 'css' => array('css/myAngularModule.css'),
+ 'partials' => array('partials/myBigAngularModule'),
+ );
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_apiWrappers.md b/docs/hooks/hook_civicrm_apiWrappers.md
new file mode 100644
index 00000000..16f910aa
--- /dev/null
+++ b/docs/hooks/hook_civicrm_apiWrappers.md
@@ -0,0 +1,59 @@
+# hook_civicrm_apiWrappers
+
+## Description
+
+This hook allows to add (or remove, but probably not a good idea)
+wrappers to be called before and after the api call.
+
+A wrapper is a class that implement two methods to alter the params sent
+to the api and the results returned.
+
+Introduced in CiviCRM 4.4.0.
+
+## Definition
+
+ /**
+ * Implements hook_civicrm_apiWrappers
+ */
+ function myextension_civicrm_apiWrappers(&$wrappers, $apiRequest) {
+ //&apiWrappers is an array of wrappers, you can add your(s) with the hook.
+ // You can use the apiRequest to decide if you want to add the wrapper (eg. only wrap api.Contact.create)
+ if ($apiRequest['entity'] == 'Contact' && $apiRequest['action'] == 'create') {
+ $wrappers[] = new CRM_Myextension_APIWrapper();
+ }
+ }
+
+
+
+## Wrapper class
+
+The wrapper is an object that contains two methods fromApiInput and
+toApiInput, that allows to modify the params before doing the api call
+and the result after. \
+ It's quite similar to the pre/post hooks in principle.
+
+To take advantage of CiviCRM's php autoloader, this file should be named
+path/to/myextension/CRM/Myextension/APIWrapper.php
+
+ class CRM_Myextension_APIWrapper implements API_Wrapper {
+ /**
+ * the wrapper contains a method that allows you to alter the parameters of the api request (including the action and the entity)
+ */
+ public function fromApiInput($apiRequest) {
+ if ('Invalid' == CRM_Utils_Array::value('contact_type', $apiRequest['params'])) {
+ $apiRequest['params']['contact_type'] = 'Individual';
+ }
+ return $apiRequest;
+ }
+
+ /**
+ * alter the result before returning it to the caller.
+ */
+ public function toApiOutput($apiRequest, $result) {
+ if (isset($result['id'], $result['values'][$result['id']]['display_name'])) {
+ $result['values'][$result['id']]['display_name_munged'] = 'MUNGE! ' . $result['values'][$result['id']]['display_name'];
+ unset($result['values'][$result['id']]['display_name']);
+ }
+ return $result;
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_batchItems.md b/docs/hooks/hook_civicrm_batchItems.md
new file mode 100644
index 00000000..e776524e
--- /dev/null
+++ b/docs/hooks/hook_civicrm_batchItems.md
@@ -0,0 +1,26 @@
+# hook_civicrm_batchItems
+
+## Description
+
+This hook is called when a CSV batch export file is about to be
+generated. Notice that this hook will be called in per batch bases, e.g.
+if 3 batches are going to be exported in the same CSV then this hook
+will be called three times regarding each batch.
+
+## Definition
+
+ hook_civicrm_batchItems(&$results, &$items)
+
+## Parameters
+
+- $results - the query result for the current batch that is being
+ processed
+- $items - the entries of financial items that will actually become
+ the records on the CSV (still per batch based)
+
+## Hints
+
+- This hook can be used together with hook_civicrm_batchQuey to add/
+ modify the information in CSV batch exports
+- You can loop through the two parameters to modify per financial
+ item. This can even be used to filter financial items.
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_batchQuery.md b/docs/hooks/hook_civicrm_batchQuery.md
new file mode 100644
index 00000000..23c51151
--- /dev/null
+++ b/docs/hooks/hook_civicrm_batchQuery.md
@@ -0,0 +1,23 @@
+# hook_civicrm_batchQuery
+
+## Description
+
+This hook is called when the query of CSV batch export is generated,\
+ so hook implementers can provide their own query objects which
+alters/extends original query.
+
+## Definition
+
+ hook_civicrm_batchQuery( &$query )
+
+## Parameters
+
+- $query - A string of SQL Query\
+ \
+
+## Example
+
+
+ function hook_civicrm_batchQuery(&$query) {
+ $query = "SELECT * FROM civicrm_financial_item";
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_buildAmount.md b/docs/hooks/hook_civicrm_buildAmount.md
new file mode 100644
index 00000000..1f11c6f0
--- /dev/null
+++ b/docs/hooks/hook_civicrm_buildAmount.md
@@ -0,0 +1,89 @@
+# hook_civicrm_buildAmount
+
+## Description
+
+This hook is called when building the amount structure for a
+Contribution or Event Page. It allows you to modify the set of radio
+buttons representing amounts for contribution levels and event
+registration fees.
+
+## Definition
+
+ hook_civicrm_buildAmount( $pageType, &$form, &$amount )
+
+## Parameters
+
+- $pageType - is this a 'contribution', 'event', or 'membership'
+- $form - reference to the form object
+- $amount - the amount structure to be displayed
+
+## Returns
+
+- null
+
+## Example
+
+ function civitest_civicrm_buildAmount(
+ $pageType,
+ &$form,
+ &$amount
+ ) {
+ //sample to modify priceset fee
+ $priceSetId = $form->get( 'priceSetId' );
+ if ( !empty( $priceSetId ) ) {
+ $feeBlock =& $amount;
+ // if you use this in sample data, u'll see changes in
+ // contrib page id = 1, event page id = 1 and
+ // contrib page id = 2 (which is a membership page
+ if (!is_array( $feeBlock ) || empty( $feeBlock ) ) {
+ return;
+ }
+ //in case of event we get eventId,
+ //so lets apply hook for eventId = 1
+ if ( $pageType == 'event' && $form->_eventId != 1 ) {
+ return;
+ }
+ //in case of contrbution
+ //for online case we get page id so we could apply for specific
+ if ( $pageType == 'contribution' ) {
+ if ( !in_array(
+ get_class( $form ),
+ array( 'CRM_Contribute_Form_Contribution', 'CRM_Contribute_Form_Contribution_Main')
+ )
+ ) {
+ return;
+ }
+ }
+ if ($pageType == 'membership') {
+ // give a discount of 20% to everyone
+ foreach ( $feeBlock as &$fee ) {
+ if ( !is_array( $fee['options'] ) ) {
+ continue;
+ }
+ foreach ( $fee['options'] as &$option ) {
+ //for sample lets modify first option from all fields.
+ $option['amount'] = $option['amount'] * 0.8;
+ $option['label'] .= ' - ' . ts( 'Get a 20% discount since you know this hook' );
+ }
+ }
+ } else {
+ // unconditionally modify the first option to be a $100 fee
+ // to show our power!
+ foreach ( $feeBlock as &$fee ) {
+ if ( !is_array( $fee['options'] ) ) {
+ continue;
+ }
+ foreach ( $fee['options'] as &$option ) {
+ //for sample lets modify first option from all fields.
+ $option['amount'] = 100;
+ $option['label'] = ts( 'Power of hooks' );
+ break;
+ }
+ }
+ }
+ }
+ }
+
+It may be me... but I'm pretty sure that this documentation needs to be
+updated because since 4.2 everything is in a price set... This code
+doesn't actually work to my knowledge.
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_buildForm.md b/docs/hooks/hook_civicrm_buildForm.md
new file mode 100644
index 00000000..5420a0e8
--- /dev/null
+++ b/docs/hooks/hook_civicrm_buildForm.md
@@ -0,0 +1,104 @@
+# hook_civicrm_buildForm
+
+## Description
+
+This hook is invoked when building a CiviCRM form. This hook should also
+be used to set the default values of a form element, to change form
+elements attributes, or even to add new fields to a form.
+
+## Definition
+
+ hook_civicrm_buildForm($formName, &$form)
+
+## Parameters
+
+- string $formName - the name of the form
+- object $form - reference to the form object
+
+## Returns
+
+## Example
+
+ /**
+ * Implements hook_civicrm_buildForm().
+ *
+ * Set a default value for an event price set field.
+ *
+ * @param string $formName
+ * @param CRM_Core_Form $form
+ */
+ function example_civicrm_buildForm($formName, &$form) {
+ if ($formName == 'CRM_Event_Form_Registration_Register') {
+ if ($form->getAction() == CRM_Core_Action::ADD) {
+ $defaults['price_3'] = '710';
+ $form->setDefaults($defaults);
+ }
+ }
+ }
+
+
+
+
+
+!!! tip
+ To access useful values in your hook_civicrm_buildForm function, consider the following:
+
+ $myPid = CRM_Utils_Array::value('pid', $_GET, '0'); // setting 0 as default if 'pid' is not found
+ $myEid = CRM_Utils_Array::value('eid', $_GET, '0'); // setting 0 as default if 'pid' is not found
+ $form->getVar( '_gid' );
+ $form->setVar( '_gid', VALUE ); // sets the variable
+
+
+\
+ Change a price set field to be required for a specific event.
+
+ function example_civicrm_buildForm($formName, &$form) {
+ if ($formName == 'CRM_Event_Form_Registration_Register') {
+ if ($form->_eventId == EVENT_ID) {
+ $form->addRule('price_3', ts('This field is required.'), 'required');
+ }
+ }
+ }
+
+!!! tip
+ With the QuickForms system that CiviCRM uses, you need to do two things to make fields appear:
+ 1. You need to create the element in the form, which is what you can do in the buildForm() hook,\
+ 2. You need to modify the Smarty template used to display the form so it contains the generated HTML for the new form element.
+
+ The later can be achieved by:
+
+ - overriding the core CiviCRM template with a new one (either in the custom templates directory, or within the templates directory of an extension),
+ - or dynamically inserting a template part in the page through the Regions API.\
+
+ This is demonstrated in the next example.
+
+ NOTE: the Regions API is only available if the template contains Regions in the first place - this is not the case with the Inline edit forms! You will then need to either add fake form elements, or modify existing elements' attributes to reach your goals.\
+
+
+
+**Add and reposition a form field**
+
+ /// FILE: mymodule/mymodule.module
+ function mymodule_civicrm_buildForm($formName, &$form) {
+ if (($formName == 'CRM_Contribute_Form_Contribution_Main') && ($form->getVar('_id') == 2)) {
+ // Assumes templates are in a templates folder relative to this file
+ $templatePath = realpath(dirname(__FILE__)."/templates");
+ // Add the field element in the form
+ $form->add('text', 'testfield', ts('Test field'));
+ // dynamically insert a template block in the page
+ CRM_Core_Region::instance('page-body')->add(array(
+ 'template' => "{$templatePath}/testfield.tpl"
+ ));
+ }
+ }
+
+ /// FILE: mymodule/templates/testfield.tpl
+ {* template block that contains the new field *}
+
+
Test field:
+
{$form.testfield.html}
+
+ {* reposition the above block after #someOtherBlock *}
+
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_buildProfile.md b/docs/hooks/hook_civicrm_buildProfile.md
new file mode 100644
index 00000000..1899d8e1
--- /dev/null
+++ b/docs/hooks/hook_civicrm_buildProfile.md
@@ -0,0 +1,39 @@
+# hook_civicrm_buildProfile
+
+## Description
+
+This hook is called while preparing a profile form.
+
+## Definition
+
+ buildProfile($name)
+
+## Parameters
+
+- $name - the (machine readable) name of the profile.
+
+## Returns
+
+- null
+
+Can someone say a little more about the purpose of this hook? It's not
+immediately obvious how I can use this. I could do something like this:
+
+
+
+ function myext_civicrm_buildProfile($name) {
+
+ if ($name === 'MyTargetedProfile) {
+
+ CRM_Core_Resources::singleton()->addScriptFile('org.example.myext', 'some/fancy.js', 100);
+
+ }
+
+ }
+
+
+
+... but it would be way more useful if the hook also received a form
+object so developers could alter the fields. I seem to recall that
+hook_civicrm_buildForm() doesn't get fired for profiles – is that
+right?
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_buildStateProvinceForCountry.md b/docs/hooks/hook_civicrm_buildStateProvinceForCountry.md
new file mode 100644
index 00000000..bac4c579
--- /dev/null
+++ b/docs/hooks/hook_civicrm_buildStateProvinceForCountry.md
@@ -0,0 +1,55 @@
+# hook_civicrm_buildStateProvinceForCountry
+
+## Description
+
+This hook is called during the ajax callback that is used to build the
+options that display in the State/Province select widget for a specific
+country, and can be used to alter the list of State/Province options for
+particular countries.
+
+## Definition
+
+ hook_civicrm_buildStateProvinceForCountry( $countryID, &$states )
+
+## Parameters
+
+- @param string $countryID Country ID for which State/Province data
+ is being looked up
+- @param array $states array of State/Province data relating to
+ country being looked up (keys = State/Province ID, values =
+ State/Province name)
+
+## Returns
+
+- null
+
+## Availability
+
+- Available since 4.1
+
+## Example
+
+The example below reorders the Irish State list so that Dublin is at the
+top of the list (by default, Dublin would be placed in the list in
+alphabetical order.
+
+ /*
+ * Implements hook_civicrm_buildStateProvinceForCountry().
+ *
+ * Reorder the dublin states so that Dublin is at the top and dublin sub
+ * states are ordered nicely.
+ */
+ function ourclient_civicrm_buildStateProvinceForCountry( $countryID, &$states ) {
+ // First separate out the Dublin options.
+ $topStates = array();
+ foreach ($states as $key => $value) {
+ if (preg_match('/Dublin/', $value)) {
+ $topStates[$key] = $value;
+ }
+ else {
+ $otherStates[$key] = $value;
+ }
+ }
+ ksort($topStates);
+ $states = $topStates + $otherStates;
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_buildUFGroupsForModule.md b/docs/hooks/hook_civicrm_buildUFGroupsForModule.md
new file mode 100644
index 00000000..88386e94
--- /dev/null
+++ b/docs/hooks/hook_civicrm_buildUFGroupsForModule.md
@@ -0,0 +1,30 @@
+# hook_civicrm_buildUFGroupsForModule
+
+## Description
+
+This hook is called when ufgroups (profiles) are being built for a
+module.
+
+The most common use case for this hook is to edit which profiles are
+visible on the Contact Dashboard or (Drupal) user registration page
+based on arbitrary criteria (e.g. whether the contact has a particular
+contact subtype).
+
+## Availability
+
+This hook is available in CiviCRM 4.1+.
+
+## Definition
+
+ buildUFGroupsForModule($moduleName, &$ufGroups)
+
+## Parameters
+
+- $moduleName - a string containing the module name (e.g. "User
+ Registration", "User Account", "Profile", "CiviEvent").
+- &$ufGroups - an array of ufgroups (profiles) available for the
+ module.
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_caseChange.md b/docs/hooks/hook_civicrm_caseChange.md
new file mode 100644
index 00000000..707d8498
--- /dev/null
+++ b/docs/hooks/hook_civicrm_caseChange.md
@@ -0,0 +1,25 @@
+# hook_civicrm_caseChange
+
+## Description
+
+This hook fires whenever a record in a case changes.
+
+See also the documentation for [CiviCase
+Util](https://wiki.civicrm.org/confluence/display/HR/CiviCase+Util).
+
+## Availability
+
+This hook is available in CiviCRM 4.5+.
+
+## Definition
+
+ function caseChange(\Civi\CCase\Analyzer $analyzer)
+
+## Parameters
+
+- $analyzer - A bundle of data about the case (such as the case and
+ activity records).
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_caseSummary.md b/docs/hooks/hook_civicrm_caseSummary.md
new file mode 100644
index 00000000..8dc88b85
--- /dev/null
+++ b/docs/hooks/hook_civicrm_caseSummary.md
@@ -0,0 +1,100 @@
+# hook_civicrm_caseSummary
+
+## Description
+
+This hook is called when the manage case screen is displayed. It allows
+the injection of label/value pairs which are rendered inside divs
+underneath the existing summary table.
+
+## Definition
+
+ hook_civicrm_caseSummary( $caseID )
+
+## Parameters
+
+- string $caseID - the case ID
+
+## Returns
+
+- array - an array where the key is a custom id that can be used for
+ CSS styling the div and the value is an array with 'label' and
+ 'value' elements.
+
+## Example
+
+ array( 'label' => ts('Some Date'),
+ 'value' => '2009-02-11',
+ ),
+ 'some_other_id' => array( 'label' => ts('Some String'),
+ 'value' => ts('Coconuts'),
+ ),
+ );
+ */
+
+ // More realistic example, but will return nothing unless you have these activities in your database.
+ // TIP: Put these queries into methods in a custom class. You will likely want to re-use them elsewhere, such as in a CiviReport.
+
+ // This query finds the earliest date of return to modified duties in a workplace disability case.
+ $params = array( 1 => array( $caseID, 'Integer' ) );
+ $sql = "SELECT min(activity_date_time) as mindate
+ FROM civicrm_activity a
+ INNER JOIN civicrm_case_activity ca on a.id=ca.activity_id
+ LEFT OUTER JOIN civicrm_option_group og on og.name='activity_type'
+ LEFT OUTER JOIN civicrm_option_value ov on
+ (og.id=ov.option_group_id AND ov.name='Return to modified duties')
+ WHERE ca.case_id=%1
+ AND ov.value=a.activity_type_id
+ LIMIT 1";
+ $modrtw = CRM_Core_DAO::singleValueQuery( $sql, $params );
+
+ // This query returns the current status of the medical consent as determined by
+ // the presence or absence of related activities.
+ $sql = "SELECT CASE WHEN count(received.case_id) > 0 THEN 'Received'
+ WHEN count(sent.case_id) > 0 AND DATEDIFF(CURRENT_TIMESTAMP, sent.activity_date_time) > 14 THEN 'Overdue'
+ WHEN count(sent.case_id) > 0 THEN 'Sent'
+ ELSE 'Not Sent'
+ END
+ FROM
+ (SELECT ca.case_id, a1.activity_date_time FROM civicrm_activity a1
+ INNER JOIN civicrm_case_activity ca on a1.id=ca.activity_id
+ LEFT OUTER JOIN civicrm_option_group og on og.name='activity_type'
+ LEFT OUTER JOIN civicrm_option_value ov on
+ (og.id=ov.option_group_id AND ov.name='Send Consent Letter')
+ WHERE ca.case_id=%1
+ AND ov.value=a1.activity_type_id
+ LIMIT 1
+ ) AS sent
+
+ LEFT OUTER JOIN
+
+ (SELECT ca2.case_id FROM civicrm_activity a2
+ INNER JOIN civicrm_case_activity ca2 on a2.id=ca2.activity_id
+ LEFT OUTER JOIN civicrm_option_group og2 on og2.name='activity_type'
+ LEFT OUTER JOIN civicrm_option_value ov2 on
+ (og2.id=ov2.option_group_id AND ov2.name='File Received Consent')
+ WHERE ca2.case_id=%1
+ AND ov2.value=a2.activity_type_id
+ LIMIT 1
+ ) AS received
+ ON received.case_id=sent.case_id";
+
+ $mcstat = CRM_Core_DAO::singleValueQuery( $sql, $params );
+
+ return array('modrtw' => array( 'label' => ts('Mod RTW:'),
+ 'value' => $modrtw,
+ ),
+ 'mcstat' => array( 'label' => ts('Consent Status:'),
+ 'value' => ts($mcstat),
+ ),
+ );
+
+ Put this in css/extras.css:
+
+ #caseSummary {display: table;}
+ #modrtw {display: table-row; border: 1px solid #999999; width: 200px;}
+ #mcstat {display: table-row; border: 1px solid #999999; border-left: 0; width: 200px;}
+ #caseSummary label {display: table-cell;}
+ #caseSummary div {display: table-cell; padding-left: 5px; padding-right: 5px;}
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_caseTypes.md b/docs/hooks/hook_civicrm_caseTypes.md
new file mode 100644
index 00000000..5e09b413
--- /dev/null
+++ b/docs/hooks/hook_civicrm_caseTypes.md
@@ -0,0 +1,40 @@
+# hook_civicrm_caseTypes
+
+## Description
+
+This hook defines available CiviCRM case types.
+
+Note that this hook is actually an adapter
+for [hook_civicrm_managed](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed)
+, so any case Type defined inside this hook will be automatically
+inserted, updated, deactivated, and deleted in tandem with enabling,
+disabling, and uninstalling the module. For more background, see [API
+and the Art of
+Installation](http://civicrm.org/blogs/totten/api-and-art-installation).
+
+## Definition
+
+ hook_civicrm_caseTypes(&$caseTypes)
+
+## Parameters
+
+- array **$caseTypes**list of case types; each item is an array with
+ keys:
+ - **'module'**: string; for module-extensions, this is the
+ fully-qualifed name (e.g. "*com.example.mymodule*"); for Drupal
+ modules, the name is prefixed by "drupal" (e.g.
+ *"drupal.mymodule*")
+ - **'name'**: string, a symbolic name which can be used to track
+ this entity
+ - **'file'**: string, the path to the XML file which defines the
+ case-type
+
+## Example
+
+ function civitest_civicrm_caseTypes(&$caseTypes) {
+ $caseTypes['MyCase'] = array(
+ 'module' => 'org.example.mymodule',
+ 'name' => 'MyCase',
+ 'file' => __DIR__ . '/MyCase.xml',
+ );
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_check.md b/docs/hooks/hook_civicrm_check.md
new file mode 100644
index 00000000..1428877a
--- /dev/null
+++ b/docs/hooks/hook_civicrm_check.md
@@ -0,0 +1,53 @@
+# hook_civicrm_check
+
+## Description
+
+This hook is called by CiviCRM's "System Check" api
+(CRM_Utils_Check::checkAll). 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).
+
+Typically your extension would add results by appending one or more
+CRM_Utils_Check_Message objects to the $messages array. Constructing
+a CRM_Utils_Check_Message requires the following parameters:
+
+- **Unique identifier:**A unique string for this type of message (no
+ two messages in the array may have the same identifier).
+- **Description: **Long description html string
+- **Title: **Short title plain text string
+- **Severity: **A [PSR-3 string](http://www.php-fig.org/psr/psr-3/).
+- **Icon:** A [font-awesome
+ icon](https://fortawesome.github.io/Font-Awesome/icons/) string
+ (optional).
+
+Introduced in CiviCRM v4.6.3.
+
+## Definition
+
+ hook_civicrm_check(&$messages)
+
+## Parameters
+
+- [CRM_Utils_Check_Message]** $messages**
+
+## Example
+
+ /**
+ * Implementation of hook_civicrm_check
+ *
+ * Add a check to the status page/System.check results if $snafu is TRUE.
+ */
+ function mymodule_civicrm_check(&$messages) {
+ $snafu = TRUE;
+ if ($snafu) {
+ $messages[] = new CRM_Utils_Check_Message(
+ 'mymodule_snafu',
+ ts('Situation normal, all funnied up'),
+ ts('SNAFU'),
+ \Psr\Log\LogLevel::CRITICAL,
+ 'fa-flag'
+ )
+ // Optionally add extended help
+ ->addHelp(ts('This text will appear in a help bubble if the user clicks on the help icon.'));
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_config.md b/docs/hooks/hook_civicrm_config.md
new file mode 100644
index 00000000..fa9fbb67
--- /dev/null
+++ b/docs/hooks/hook_civicrm_config.md
@@ -0,0 +1,30 @@
+# hook_civicrm_config
+
+## Description
+
+This hook is called soon after the CRM_Core_Config object has ben
+initialized. You can use this hook to modify the config object and hence
+behavior of CiviCRM dynamically.
+
+## Definition
+
+ hook_civicrm_config( &$config )
+
+## Parameters
+
+- $config the config object
+
+## Example
+
+ function civitest_civicrm_config( &$config ) {
+ $civitestRoot = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
+
+ // fix php include path
+ $include_path = $civitestRoot . PATH_SEPARATOR . get_include_path( );
+ set_include_path( $include_path );
+
+ // fix template path
+ $templateDir = $civitestRoot . 'templates' . DIRECTORY_SEPARATOR;
+ $template =& CRM_Core_Smarty::singleton( );
+ array_unshift( $template->template_dir, $templateDir );
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_contactListQuery.md b/docs/hooks/hook_civicrm_contactListQuery.md
new file mode 100644
index 00000000..d75ceab9
--- /dev/null
+++ b/docs/hooks/hook_civicrm_contactListQuery.md
@@ -0,0 +1,69 @@
+# hook_civicrm_contactListQuery
+
+## Description
+
+!!! warning "Deprecation Notice"
+ This hook is called in very few places in version 4.5+ because most contact reference fields have been migrated to go through the api instead of constructing an ad-hoc query. It will be removed in a future version.
+
+ For a substitute, see [hook_civicrm_apiWrappers](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_apiWrappers).
+
+
+Use this hook to populate the list of contacts returned by Contact
+Reference custom fields. By default, Contact Reference fields will
+search on and return all CiviCRM contacts. If you want to limit the
+contacts returned to a specific group, or some other criteria - you can
+override that behavior by providing a SQL query that returns some subset
+of your contacts. The hook is called when the query is executed to get
+the list of contacts to display.
+
+## Definition
+
+ hook_civicrm_contactListQuery( &$query, $name, $context, $id )
+
+## Parameters
+
+- $query - the query that will be executed (input and output
+ parameter)**; It's important to realize that the ACL clause is built
+ prior to this hook being fired, so your query will ignore any ACL
+ rules that may be defined.**Your query must return two columns:\
+ - the contact 'data' to display in the autocomplete dropdown
+ (usually contact.sort_name - aliased as 'data')
+ - the contact IDs
+- $name - the name string to execute the query against (this is the
+ value being typed in by the user)
+- $context - the context in which this ajax call is being made (for
+ example: 'customfield', 'caseview')
+
+- $id - the id of the object for which the call is being made. For
+ custom fields, it will be the custom field id
+
+## Notes
+
+!!! tip
+ To find the context for a given contactListQuery widget, use firebug console and type in a few letters. You'll see a GET command that looks like this (and includes the context= parameter):[http://drupal.demo.civicrm.org/civicrm/ajax/contactlist?context=caseview&s=ada&limit=10×tamp=1273015964778](http://drupal.demo.civicrm.org/civicrm/ajax/contactlist?context=caseview&s=ada&limit=10×tamp=1273015964778)
+
+
+## Examples
+
+This example limits contacts in my contact reference field lookup
+(custom field id=4) to a specific group (group id=5)
+
+ // Connect the hook to your Contact Reference custom field using the field ID (field id=4 in this case)
+ if ( $context == 'customfield' &&
+ $id == 4 ) {
+ // Now construct the query to select only the contacts we want
+ // The query must return two columns - contact data, and contact id
+ $query = "
+ SELECT c.sort_name as data, c.id
+ FROM civicrm_contact c, civicrm_group_contact cg
+ WHERE c.sort_name LIKE '$name%'
+ AND cg.group_id IN ( 5 )
+ AND cg.contact_id = c.id
+ AND cg.status = 'Added'
+ ORDER BY c.sort_name ";
+ }
+
+ }
+
+[More examples and sample module code in this forums
+thread.](http://forum.civicrm.org/index.php/topic,24550.0.html)
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_contact_get_displayname.md b/docs/hooks/hook_civicrm_contact_get_displayname.md
new file mode 100644
index 00000000..13eb17a7
--- /dev/null
+++ b/docs/hooks/hook_civicrm_contact_get_displayname.md
@@ -0,0 +1,33 @@
+# hook_civicrm_contact_get_displayname
+
+## Description
+
+This hook is called to retrieve the display name of a contact. You can
+use this hook to return a custom display name.
+
+Probably you won't need this hook but in some case it might be useful.
+For example you want to show who is a manager of an organisation but you
+don't want to store this in the database.
+
+## Definition
+
+ civicrm_contact_get_displayname(&$display_name, $contactId, $objContact)
+
+## Parameters
+
+- &$disply_name - the current display name, you can change the
+ display name by changing the contents of this parameter
+- $contactId - Contact ID
+- $objContact - The contact BAO
+
+## Returns
+
+- null
+
+## Example
+
+Below an example of showing the contact ID after the display name
+
+ function myextension_civicrm_contact_get_displayname(&$display_name, $contactId, $objContact) {
+ $display_name = $display_name . ' - '.$contactId;
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_container.md b/docs/hooks/hook_civicrm_container.md
new file mode 100644
index 00000000..3f251eae
--- /dev/null
+++ b/docs/hooks/hook_civicrm_container.md
@@ -0,0 +1,40 @@
+# hook_civicrm_container
+
+## Description
+
+This hook modifies the CiviCRM container - add new services, parameters,
+extensions, etc.
+
+Tip: 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').
+
+## Availability
+
+This hook is available in CiviCRM 4.7+.
+
+## Definition
+
+ container(\Symfony\Component\DependencyInjection\ContainerBuilder $container)
+
+## Parameters
+
+- $container - An object of type
+ \Symfony\Component\DependencyInjection\ContainerBuilder. See
+ [here](http://symfony.com/doc/current/components/dependency_injection/index.html).
+
+## Returns
+
+- null
+
+## Example
+
+ use Symfony\Component\Config\Resource\FileResource;
+ use Symfony\Component\DependencyInjection\Definition;
+
+ function mymodule_civicrm_container($container) {
+ $container->addResource(new FileResource(__FILE__));
+ $container->setDefinition('mysvc', new Definition('My\Class', array()));
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_copy.md b/docs/hooks/hook_civicrm_copy.md
new file mode 100644
index 00000000..b212f29b
--- /dev/null
+++ b/docs/hooks/hook_civicrm_copy.md
@@ -0,0 +1,20 @@
+# hook_civicrm_copy
+
+## Description
+
+This hook is called after a CiviCRM object (Event, ContributionPage,
+Profile) has been copied
+
+## Definition
+
+ hook_civicrm_copy( $objectName, &$object )
+
+## Parameters
+
+- $objectName - the name of the object that is being copied (Event,
+ ContributionPage, UFGroup)
+- $object - reference to the copied object
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_coreResourceList.md b/docs/hooks/hook_civicrm_coreResourceList.md
new file mode 100644
index 00000000..b0955724
--- /dev/null
+++ b/docs/hooks/hook_civicrm_coreResourceList.md
@@ -0,0 +1,46 @@
+# hook_civicrm_coreResourceList
+
+## Description
+
+This hook is called when the list of core js/css resources is about to
+be processed. Implementing this hook gives you the opportunity to modify
+the list prior to the resources being added, or add your own.
+
+Added in v4.6.6.
+
+See [Resource Reference](https://wiki.civicrm.org/confluence/display/CRMDOC/Resource+Reference)
+for more information.
+
+## Parameters
+
+$list: an array of items about to be added to the page. Items in the
+list may be:
+
+- A string ending in .js
+- A string ending in .css
+- An array of settings (will be added to the javascript CRM object).
+
+$region: target region of the page - normally this is "html-header"
+
+## Example
+
+ /**
+ * Implements hook_coreResourceList
+ *
+ * @param array $list
+ * @param string $region
+ */
+ function myextension_civicrm_coreResourceList(&$list, $region) {
+ // Prevent navigation.css from loading
+ $cssWeDontWant = array_search('css/navigation.css', $list);
+ unset($list[$cssWeDontWant]);
+
+ // Add some css of our own to the page
+ // Note that if the file we want to add is outside civicrm directory (e.g. in an extension) we can't just append it to the list
+ // But we can add it directly, which is what happens to items in this list anyway.
+ Civi::resources()
+ ->addStyleFile('myextension', 'css/my_style.css', 0, $region);
+
+ // Add a setting - in this example we override the CKEditor config file location
+ $list[] = array('config' => array('CKEditorCustomConfig' => Civi::resources()->getUrl('org.foo.myextension', 'js/my-ckeditor-config.js')));
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_cron.md b/docs/hooks/hook_civicrm_cron.md
new file mode 100644
index 00000000..a7d4754e
--- /dev/null
+++ b/docs/hooks/hook_civicrm_cron.md
@@ -0,0 +1,36 @@
+# hook_civicrm_cron
+
+## Description
+
+This hook is called everytime the CiviCRM scheduler is polled. The
+timing and frequency with which this is called will vary depending on
+the system configuration.
+
+Introduced in CiviCRM v4.3.
+
+!!! note "This is a low-level approach"
+ 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"](https://wiki.civicrm.org/confluence/display/CRMDOC/Create+a+Module+Extension#CreateaModuleExtension-Howdoesoneaddacronjob)
+
+
+
+
+## Definition
+
+ hook_civicrm_cron($jobManager)
+
+## Parameters
+
+- CRM_Core_JobManager** $jobManager**
+
+## Example
+
+ /**
+ * Implementation of hook_civicrm_cron
+ *
+ * Flag records in a custom table as dirty if they are over 2 days old.
+ * Rerunning this logic at various times throughout the day should be safe
+ * because there are no guarantees about when it will run.
+ */
+ function example_civicrm_cron($jobManager) {
+ CRM_Core_DAO::executeQuery('UPDATE my_table SET is_dirty = 1 WHERE last_modified < adddate(now(), "-2 day")');
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_crudLink.md b/docs/hooks/hook_civicrm_crudLink.md
new file mode 100644
index 00000000..9e4c6c7b
--- /dev/null
+++ b/docs/hooks/hook_civicrm_crudLink.md
@@ -0,0 +1,45 @@
+# hook_civicrm_crudLink
+
+## Description
+
+Generate a default CRUD URL for an entity.
+
+## Availability
+
+This hook is available in CiviCRM 4.5+.
+
+## Definition
+
+ crudLink($spec, $bao, &$link)
+
+## Parameters
+
+- $spec - An array with keys:
+
+ - action: int, eg CRM_Core_Action::VIEW or
+ CRM_Core_Action::UPDATE
+ - entity_table: string
+ - entity_id: int
+- $bao CRM_Core_DAO
+
+- $link - An array.
+
+
+
+ To define the link, add these keys to $link:
+
+- title: string
+
+- path: string
+
+- query: array
+
+- url: string (used in lieu of "path"/"query")
+
+ Note: if making "url" CRM_Utils_System::url(), set $htmlize=false
+
+
+
+## Returns
+
+- mixed
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_custom.md b/docs/hooks/hook_civicrm_custom.md
new file mode 100644
index 00000000..6b9ff9cb
--- /dev/null
+++ b/docs/hooks/hook_civicrm_custom.md
@@ -0,0 +1,60 @@
+# hook_civicrm_custom
+
+## Description
+
+This hook is called AFTER the db write on a custom table
+
+## Definition
+
+ hook_civicrm_custom( $op, $groupID, $entityID, &$params )
+
+## Parameters
+
+- string $op - the type of operation being performed
+- string $groupID - the custom group ID
+- object $entityID - the entityID of the row in the custom table
+- array $params - the parameters that were sent into the calling
+ function
+
+## Returns
+
+- null - the return value is ignored
+
+## Example
+
+ /**
+ * This example generates a custom contact ID (year + number, ex: 20080000001)
+ */
+
+ function MODULENAME_civicrm_custom( $op, $groupID, $entityID, &$params ) {
+ if ( $op != 'create' && $op != 'edit' ) {
+ return;
+ }
+
+ if ($groupID == 1) {
+ $needs_update = false;
+ $tableName = CRM_Core_DAO::getFieldValue( 'CRM_Core_DAO_CustomGroup',
+ $groupID,
+ 'table_name' );
+
+
+ $sql = "SELECT member_id_4 FROM $tableName WHERE entity_id = $entityID";
+ $dao = CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
+
+ if (! $dao->fetch()) {
+ $needs_update = true;
+ }
+
+ // Value may also be empty. i.e. delete the value in the interface to reset the field.
+ if (! $dao->member_id_4) {
+ $needs_update = true;
+ }
+
+ if ($needs_update) {
+ $member_id = date('Y') . sprintf('%07d', $entityID);
+
+ $sql = "UPDATE $tableName SET member_id_4 = $member_id WHERE entity_id = $entityID";
+ CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
+ }
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_customFieldOptions.md b/docs/hooks/hook_civicrm_customFieldOptions.md
new file mode 100644
index 00000000..25e760c9
--- /dev/null
+++ b/docs/hooks/hook_civicrm_customFieldOptions.md
@@ -0,0 +1,78 @@
+# hook_civicrm_customFieldOptions
+
+## Description
+
+!!! warning "Deprecated"
+ This hook is deprecated in 4.7 in favor of [hook_civicrm_fieldOptions](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_fieldOptions). Use that instead for modifying all option lists, not limited to custom fields.
+
+
+## Definition
+
+ hook_civicrm_customFieldOptions( $fieldID, &$options, $detailedFormat = false )
+
+## Parameters
+
+- $fieldID - the custom field ID
+- $options - the current set of options for that custom field. You
+ can add/remove existing options. **Important: This array may contain
+ meta-data about the field that is needed elsewhere, so it is
+ important to be careful to not overwrite the array. Only
+ add/edit/remove the specific field options you intend to affect.**
+- $detailedFormat - if true, the options are in an ID => array (
+ 'id' => ID, 'label' => label, 'value' => value ) format
+
+## Returns
+
+- null
+
+## Example
+
+ function civitest_civicrm_customFieldOptions($fieldID, &$options, $detailedFormat = false ) {
+ if ( $fieldID == 1 || $fieldID == 2 ) {
+ if ( $detailedFormat ) {
+ $options['fake_id_1'] = array( 'id' => 'fake_id_1',
+ 'value' => 'XXX',
+ 'label' => 'XXX' );
+ $options['fake_id_2'] = array( 'id' => 'fake_id_2',
+ 'value' => 'YYY',
+ 'label' => 'YYY' );
+ } else {
+ $options['XXX'] = 'XXX';
+ $options['YYY'] = 'YYY';
+ }
+ }
+ }
+
+This syntax may be more convenient if you are a managing differing sets
+of options for different fields:
+
+ function EXAMPLE_civicrm_customFieldOptions($fieldID, &$options, $detailedFormat = false ) {
+ switch ($fieldID) {
+ case 1:
+ case 2:
+ $detailed_options['fake_id_1'] = array( 'id' => 'fake_id_1',
+ 'value' => 'Xvalue',
+ 'label' => 'Xlabel' );
+ $detailed_options['fake_id_2'] = array( 'id' => 'fake_id_2',
+ 'value' => 'Yvalue',
+ 'label' => 'Ylabel' );
+ break;
+
+ case 3:
+ $detailed_options['fake_id_1'] = array( 'id' => 'fake_id_1',
+ 'value' => 'Avalue',
+ 'label' => 'Alabel' );
+ $detailed_options['fake_id_2'] = array( 'id' => 'fake_id_2',
+ 'value' => 'Bvalue',
+ 'label' => 'Blabel' );
+ break;
+ }
+
+ if (isset($detailed_options) && !$detailedFormat ) {
+ foreach ($detailed_options AS $key => $choice) {
+ $options[$choice['value']] = $choice['label'];
+ }
+ } else {
+ $options += $detailed_options;
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_dashboard.md b/docs/hooks/hook_civicrm_dashboard.md
new file mode 100644
index 00000000..bf7b57a6
--- /dev/null
+++ b/docs/hooks/hook_civicrm_dashboard.md
@@ -0,0 +1,44 @@
+# hook_civicrm_dashboard
+
+## Description
+
+This hook is called when rendering the dashboard page. This hook can be
+used to add content to the dashboard page.
+
+## Definition
+
+ hook_civicrm_dashboard( $contactID, &$contentPlacement = self::DASHBOARD_BELOW )
+
+## Parameters
+
+- $contactID the contactID for whom the dashboard is being generated
+- $contentPlacement (output parameter) where should the hook content
+ be displayed relative to the activity list. One of
+ CRM_Utils_Hook::DASHBOARD_BELOW,
+ CRM_Utils_Hook::DASHBOARD_ABOVE,
+ CRM_Utils_Hook::DASHBOARD_REPLACE. Default is to add content
+ BELOW the standard dashboard Activities listing. DASHBOARD_REPLACE
+ replaces the standard Activities listing with the provided content.
+
+## Returns
+
+- the HTML to include in the dashboard
+
+## Example
+
+ function civitest_civicrm_dashboard( $contactID, &$contentPlacement ) {
+ // REPLACE Activity Listing with custom content
+ $contentPlacement = 3;
+ return array( 'Custom Content' => "Here is some custom content: $contactID",
+ 'Custom Table' => "
+
+ ";
+
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_summaryActions.md b/docs/hooks/hook_civicrm_summaryActions.md
new file mode 100644
index 00000000..3c231e78
--- /dev/null
+++ b/docs/hooks/hook_civicrm_summaryActions.md
@@ -0,0 +1,54 @@
+# hook_civicrm_summaryActions
+
+## Description
+
+This hook allows User to customize context menu Actions on Contact
+Summary Page.
+
+## Definition
+
+ hook_civicrm_summaryActions( &$actions, $contactID )
+
+## Parameters
+
+- `$actions` Array of all Actions in contextMenu. Each action item is
+ itself an array that can contain the items below **(this is not the
+ full list)**:\
+ \
+ - `title:` the text that appears in the action menu
+ - `weight:` a number defining the "weight" - i.e where should the
+ item sit in the action menu
+ - `ref:` this is appended to the string "crm-action-record-" and
+ becomes the list items CSS class (each action is a `li` element)
+ - `key:` this is the array key that identifies the action
+ - `href:` a URL that you want the link to navigate to
+ - `permissions:` an array that contains permissions a user must
+ have in order to use this action\
+ \
+- `$contactID` contactID for the summary page.
+
+## Example
+
+**Removing some action items**
+
+ function civitest_civicrm_summaryActions( &$actions, $contactID ){
+ $customizeActions = array('contribution', 'note', 'rel');
+ foreach( $actions as $key => $value ) {
+ if( in_array( $key, $customizeActions ) ) {
+ unset( $actions[$key] );
+ }
+ }
+ }
+
+**Add an item to the action list**
+
+ function mymodulename_civicrm_summaryActions(&$actions, $contactID)
+ {
+ $actions['casework'] = array(
+ 'title' => 'Record casework',
+ 'weight' => 999,
+ 'ref' => 'record-casework',
+ 'key' => 'casework',
+ 'href' => '/casework/recording_form
+ );
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_tabs.md b/docs/hooks/hook_civicrm_tabs.md
new file mode 100644
index 00000000..54bedd78
--- /dev/null
+++ b/docs/hooks/hook_civicrm_tabs.md
@@ -0,0 +1,47 @@
+# hook_civicrm_tabs
+
+## Description
+
+!!! warning "Deprecation Notice"
+ This hook has been deprecated in 4.7.
+
+ For a substitute, see [hook_civicrm_tabset](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_tabset)
+
+
+This hook is called when composing the tabs to display when viewing a
+contact
+
+## Definition
+
+ hook_civicrm_tabs( &$tabs, $contactID )
+
+## Parameters
+
+- $tabs - the array of tabs that will be displayed
+- $contactID - the contactID for whom the view is being rendered
+
+## Returns
+
+- null - the return value is ignored
+
+## Example
+
+ function civitest_civicrm_tabs( &$tabs, $contactID ) {
+
+ // unset the contribition tab, i.e. remove it from the page
+ unset( $tabs[1] );
+
+ // let's add a new "contribution" tab with a different name and put it last
+ // this is just a demo, in the real world, you would create a url which would
+ // return an html snippet etc.
+ $url = CRM_Utils_System::url( 'civicrm/contact/view/contribution',
+ "reset=1&snippet=1&force=1&cid=$contactID" );
+ // $url should return in 4.4 and prior an HTML snippet e.g. '
....';
+ // in 4.5 and higher this needs to be encoded in json. E.g. json_encode(array('content' => ));
+ // or CRM_Core_Page_AJAX::returnJsonResponse($content) where $content is the html code
+ // 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.
+ $tabs[] = array( 'id' => 'mySupercoolTab',
+ 'url' => $url,
+ 'title' => 'Contribution Tab Renamed',
+ 'weight' => 300 );
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_tabset.md b/docs/hooks/hook_civicrm_tabset.md
new file mode 100644
index 00000000..280c5932
--- /dev/null
+++ b/docs/hooks/hook_civicrm_tabset.md
@@ -0,0 +1,112 @@
+# hook_civicrm_tabset
+
+## Description
+
+This hook is called when composing the tabs interface used for contacts,
+contributions and events.
+
+
+## Definition
+
+ hook_civicrm_tabset($tabsetName, &$tabs, $context)
+
+## Parameters
+
+- $tabset - name of the screen or visual element
+
+- $tabs - the array of tabs that will be displayed
+
+- $context - extra data about the screen or context in which the
+ tab is used
+
+
+
+## Returns
+
+- null - the return value is ignored
+
+## Example
+
+ function civitest_civicrm_tabset($tabsetName, &$tabs, $context) {
+ //check if the tab set is Event manage
+ if ($tabsetName == 'civicrm/event/manage') {
+ if (!empty($context)) {
+ $eventID = $context['event_id'];
+ $url = CRM_Utils_System::url( 'civicrm/event/manage/volunteer',
+ "reset=1&snippet=5&force=1&id=$eventID&action=update&component=event" );
+ //add a new Volunteer tab along with url
+ $tab['volunteer'] = array(
+ 'title' => ts('Volunteers'),
+ 'link' => $url,
+ 'valid' => 1,
+ 'active' => 1,
+ 'current' => false,
+ );
+ }
+ else {
+ $tab['volunteer'] = array(
+ 'title' => ts('Volunteers'),
+ 'url' => 'civicrm/event/manage/volunteer',
+ );
+ }
+ //Insert this tab into position 4
+ $tabs = array_merge(
+ array_slice($tabs, 0, 4),
+ $tab,
+ array_slice($tabs, 4)
+ );
+ }
+
+ //check if the tabset is Contribution Page
+ if ($tabsetName == 'civicrm/admin/contribute') {
+ if (!empty($context['contribution_page_id'])) {
+ $contribID = $context['contribution_page_id'];
+ $url = CRM_Utils_System::url( 'civicrm/admin/contribute/newtab',
+ "reset=1&snippet=5&force=1&id=$contribID&action=update&component=contribution" );
+ //add a new Volunteer tab along with url
+ $tab['newTab'] = array(
+ 'title' => ts('newTab'),
+ 'link' => $url,
+ 'valid' => 1,
+ 'active' => 1,
+ 'current' => false,
+ );
+ }
+ if (!empty($context['urlString']) && !empty($context['urlParams'])) {
+ $tab[] = array(
+ 'title' => ts('newTab'),
+ 'name' => ts('newTab'),
+ 'url' => $context['urlString'] . 'newtab',
+ 'qs' => $context['urlParams'],
+ 'uniqueName' => 'newtab',
+ );
+ }
+ //Insert this tab into position 4
+ $tabs = array_merge(
+ array_slice($tabs, 0, 4),
+ $tab,
+ array_slice($tabs, 4)
+ );
+ }
+
+ //check if the tabset is Contact Summary Page
+ if ($tabsetName == 'civicrm/contact/view') {
+ // unset the contribition tab, i.e. remove it from the page
+ unset( $tabs[1] );
+ $contactId = $context['contact_id'];
+ // let's add a new "contribution" tab with a different name and put it last
+ // this is just a demo, in the real world, you would create a url which would
+ // return an html snippet etc.
+ $url = CRM_Utils_System::url( 'civicrm/contact/view/contribution',
+ "reset=1&snippet=1&force=1&cid=$contactID" );
+ // $url should return in 4.4 and prior an HTML snippet e.g. '
....';
+ // in 4.5 and higher this needs to be encoded in json. E.g. json_encode(array('content' => ));
+ // or CRM_Core_Page_AJAX::returnJsonResponse($content) where $content is the html code
+ // 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.
+ $tabs[] = array( 'id' => 'mySupercoolTab',
+ 'url' => $url,
+ 'title' => 'Contribution Tab Renamed',
+ 'weight' => 300,
+ );
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_tokenValues.md b/docs/hooks/hook_civicrm_tokenValues.md
new file mode 100644
index 00000000..1b1a4ca1
--- /dev/null
+++ b/docs/hooks/hook_civicrm_tokenValues.md
@@ -0,0 +1,28 @@
+# hook_civicrm_tokenValues
+
+## Description
+
+This hook is called to get all the values for the tokens registered. Use
+it to overwrite or reformat existing token values, or supply the values
+for custom tokens you have defined in
+[hook_civicrm_tokens](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_tokens).\
+ See [this
+article](https://civicrm.org/blog/colemanw/create-your-own-tokens-for-fun-and-profit) for
+usage examples.
+
+## Definition
+
+ hook_civicrm_tokenValues(&$values, $cids, $job = null, $tokens = array(), $context = null)
+
+## Parameters
+
+- $values - array of values, keyed by contact id
+- $cids - array of contactIDs that the system needs values for.
+- $job - the job_id
+- $tokens - tokens used in the mailing - use this to check whether a
+ token is being used and avoid fetching data for unneeded tokens
+- $context - the class name
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_tokens.md b/docs/hooks/hook_civicrm_tokens.md
new file mode 100644
index 00000000..cbf2a03e
--- /dev/null
+++ b/docs/hooks/hook_civicrm_tokens.md
@@ -0,0 +1,35 @@
+# hook_civicrm_tokens
+
+## Description
+
+This hook is called to allow custom tokens to be defined. Their values
+will need to be supplied by
+[hook_civicrm_tokenValues](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_tokenValues).\
+ See [this
+article](http://civicrm.org/blogs/colemanw/create-your-own-tokens-fun-and-profit)
+for usage examples.
+
+## Definition
+
+ hook_civicrm_tokens( &$tokens )
+
+## Parameters
+
+- $tokens: reference to the associative array of custom tokens that
+ are available to be used in mailings and other contexts. This will
+ be an empty array unless an implementation of hook_civicrm_tokens
+ adds items to it. Items should be added in the format:\
+ \
+
+ $tokens['date'] = array(
+ 'date.date_short' => ts("Today's Date: short format"),
+ 'date.date_med' => ts("Today's Date: med format"),
+ 'date.date_long' => ts("Today's Date: long format"),
+ );
+ $tokens['party'] = array(
+ 'party.balloons' => ts("Number of balloons"),
+ );
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_trigger_info.md b/docs/hooks/hook_civicrm_trigger_info.md
new file mode 100644
index 00000000..99591a65
--- /dev/null
+++ b/docs/hooks/hook_civicrm_trigger_info.md
@@ -0,0 +1,126 @@
+# hook_civicrm_trigger_info
+
+Define MYSQL Triggers. Using the hooks causes them not to clash with
+core or other extension triggers. They are compiled into one trigger
+with core triggers.
+
+Once the function is create, a trigger rebuild will have to be done to
+create the new trigger
+
+http//yoursite/civicrm/menu/rebuild&reset=1&triggerRebuild=1
+
+ /**
+
+ * hook_civicrm_triggerInfo()
+
+ *
+
+ * Add trigger to update custom region field based on postcode (using a lookup table)
+
+ *
+
+ * Note that we have hard-coded a prioritisation of location types into this (since it's customer specific code
+
+ * and unlikely to change)
+
+ *
+
+ * @param array $info (reference) array of triggers to be created
+
+ * @param string $tableName - not sure how this bit works
+
+ *
+
+ **/
+
+
+
+ function regionfields_civicrm_triggerInfo(&$info, $tableName) {
+
+ $table_name = 'civicrm_value_region_13';
+
+ $customFieldID = 45;
+
+ $columnName = 'region_45';
+
+ $sourceTable = 'civicrm_address';
+
+ $locationPriorityOrder = '1, 3, 5, 2, 4, 6'; // hard coded prioritisation of addresses
+
+ $zipTable = 'CANYRegion';
+
+ if(civicrm_api3('custom_field', 'getcount', array('id' => $customFieldID, 'column_name' => 'region_45', 'is_active' => 1)) == 0) {
+
+ return;
+
+ }
+
+
+
+ $sql = "
+
+ REPLACE INTO `$table_name` (entity_id, $columnName)
+
+ SELECT * FROM (
+
+ SELECT contact_id, b.region
+
+ FROM
+
+ civicrm_address a INNER JOIN $zipTable b ON a.postal_code = b.zip
+
+ WHERE a.contact_id = NEW.contact_id
+
+ ORDER BY FIELD(location_type_id, $locationPriorityOrder )
+
+ ) as regionlist
+
+ GROUP BY contact_id;
+
+ ";
+
+ $sql_field_parts = array();
+
+
+
+ $info[] = array(
+
+ 'table' => $sourceTable,
+
+ 'when' => 'AFTER',
+
+ 'event' => 'INSERT',
+
+ 'sql' => $sql,
+
+ );
+
+ $info[] = array(
+
+ 'table' => $sourceTable,
+
+ 'when' => 'AFTER',
+
+ 'event' => 'UPDATE',
+
+ 'sql' => $sql,
+
+ );
+
+ // For delete, we reference OLD.contact_id instead of NEW.contact_id
+
+ $sql = str_replace('NEW.contact_id', 'OLD.contact_id', $sql);
+
+ $info[] = array(
+
+ 'table' => $sourceTable,
+
+ 'when' => 'AFTER',
+
+ 'event' => 'DELETE',
+
+ 'sql' => $sql,
+
+ );
+
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_unhandledException.md b/docs/hooks/hook_civicrm_unhandledException.md
new file mode 100644
index 00000000..f6a44a7e
--- /dev/null
+++ b/docs/hooks/hook_civicrm_unhandledException.md
@@ -0,0 +1,25 @@
+# hook_civicrm_unhandledException
+
+## Description
+
+This hook fires when an unhandled exception (fatal error) occurs.
+
+A use case is to show an alternative page to donors rather than a fatal
+error screen if a fatal error occurs during a donation.
+
+## Availability
+
+This hook is available in CiviCRM 4.6+.
+
+## Definition
+
+ unhandledException($exception, $request = NULL)
+
+## Parameters
+
+- $exception - An object of type CRM_Core_Exception Exception.
+- $request - Reserved for future use.
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_uninstall.md b/docs/hooks/hook_civicrm_uninstall.md
new file mode 100644
index 00000000..cc11c46d
--- /dev/null
+++ b/docs/hooks/hook_civicrm_uninstall.md
@@ -0,0 +1,16 @@
+# hook_civicrm_uninstall
+
+## Description
+
+This hook is called when an extension is uninstalled. To be specific,
+when its status changes from ***disabled*** to ***uninstalled******.***
+Each module will receive hook_civicrm_uninstall during its own
+uninstallation (but not during the uninstallation of unrelated modules).
+
+## Parameters
+
+- None
+
+## Returns
+
+- Void
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_unsubscribeGroups.md b/docs/hooks/hook_civicrm_unsubscribeGroups.md
new file mode 100644
index 00000000..3dd1bd64
--- /dev/null
+++ b/docs/hooks/hook_civicrm_unsubscribeGroups.md
@@ -0,0 +1,45 @@
+# hook_civicrm_unsubscribeGroups
+
+## Description
+
+This hook is called when CiviCRM recieves a request to unsubscribe a
+user from a mailing
+
+Introduced in CiviCRM v4.2
+
+## Definition
+
+ hook_civicrm_unsubscribeGroups($op, $mailingId, $contactId, &$groups, &$baseGroups)
+
+## Parameters
+
+- - string $op - hard coded to be unsubscribe
+
+ - int $mailingId - the id of the mailing sent that originated
+ this unsubscribe request
+ - int $contactId - the id of the contact that wishes to be
+ unsubscribed
+ - array $groups - the list of groups that the contact will be
+ removed from
+ - array $baseGroups - the list of base groups (for smart
+ mailings) that the contact will be removed from
+
+## Example
+
+ function civitest_civicrm_unsubscribeGroups( $op, $mailingId, $contactId, &$groups, &$baseGroups ) {
+ // do the below for even mailing ids only
+ // in a real implementation, you will have some logic to restrict what mailings
+ // you want to handle the unsub via a different patch
+ // this hook basically redirects you to a custom unsubscribe page
+ // thanx to parvez @ veda consulting for this example
+ if ($op == 'unsubscribe' && $mailingId % 2 == 0) {
+ $oConfig = CRM_Core_Config::singleton();
+ $sUnsubscribeRedirectUrl = $oConfig->unsubscribe_redirect_url;
+ if ( !empty( $sUnsubscribeRedirectUrl ) ) {
+ CRM_Utils_System::redirect( $sUnsubscribeRedirectUrl );
+ } else {
+ CRM_Core_Error::statusBounce( 'Unsubscribe URL has not been set.' );
+ }
+ CRM_Utils_System::civiExit();
+ }
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_upgrade.md b/docs/hooks/hook_civicrm_upgrade.md
new file mode 100644
index 00000000..bfe05e68
--- /dev/null
+++ b/docs/hooks/hook_civicrm_upgrade.md
@@ -0,0 +1,27 @@
+# hook_civicrm_upgrade
+
+## Description
+
+This hook is called when an administrator visits the "Manage Extensions"
+screen to determine if there are any pending upgrades. As of version
+4.7, it is also called periodically by [CiviCRM's system status
+utility](https://docs.civicrm.org/user/en/stable/initial-set-up/civicrm-system-status/).
+
+If there are upgrades, and if the administrator chooses to execute them,
+the hook is called a second time to construct a list of upgrade tasks.
+
+## Definition
+
+ hook_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL)
+
+## Parameters
+
+- $op - the type of operation being performed; 'check' or 'enqueue'
+- $queue - (for 'enqueue') the modifiable list of pending up upgrade
+ tasks
+
+## Returns
+
+- For 'check' operations, return array(bool) (TRUE if an upgrade is
+ required)
+- For 'enqueue' operations, return void
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_validateForm.md b/docs/hooks/hook_civicrm_validateForm.md
new file mode 100644
index 00000000..e42a2f2a
--- /dev/null
+++ b/docs/hooks/hook_civicrm_validateForm.md
@@ -0,0 +1,92 @@
+# hook_civicrm_validateForm
+
+## Description
+
+Validation of forms. This hook was introduced in v4.2
+
+## Definition
+
+ /**
+ * Implements hook_civicrm_validateForm().
+ *
+ * @param string $formName
+ * @param array $fields
+ * @param array $files
+ * @param CRM_Core_Form $form
+ * @param array $errors
+ */
+ hook_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors)
+
+## Parameters
+
+- $formName - Name of the form being validated, you will typically
+ use this to do different things for different forms.
+- $fields - Array of name value pairs for all 'POST'ed form values
+- $files - Array of file properties as sent by PHP POST protocol
+- $form - Reference to the civicrm form object. This is useful if you
+ want to retrieve any values that we've constructed in the form
+- $errors - Reference to the errors array. All errors will be added
+ to this array
+
+## Returns
+
+N/A
+
+## Example
+
+ function MODULENAME_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) {
+ // sample implementation
+ if ($formName == 'CRM_Contact_Form_Contact') {
+ // ensure that external identifier is present and valid
+ $externalID = CRM_Utils_Array::value( 'external_identifier', $fields );
+ if (! $externalID ) {
+ $errors['external_identifier'] = ts( 'External Identifier is a required field' );
+ }
+ elseif (! myCustomValidatorFunction($externalID)) {
+ $errors['external_identifier'] = ts( 'External Identifier is not valid' );
+ }
+ }
+ return;
+
+ }
+
+ function MYMODULE_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) {
+ if ($formName == 'CRM_Contact_Form_Contact') {
+ foreach ($fields['address'] as $key => $address) {
+ //if country is set to UK or is empty, check for UK postcode formatting
+ if (empty($address['country_id']) || $address['country_id'] == 1226) {
+ $postcode = str_replace(' ', '', strtoupper($address['postal_code']));
+ $preg = "/^([A-PR-UWYZ]([0-9]([0-9]|[A-HJKSTUW])?|[A-HK-Y][0-9]([0-9]|[ABEHMNPRVWXY])?)[0-9][ABD-HJLNP-UW-Z]{2}|GIR0AA)$/";
+ $match = preg_match($preg, $postcode) ? true : false;
+ if (!$match) {
+ $errors['address[' . $key . '][postal_code]'] = ts('Postcode is not a valid UK postcode');
+ }
+ }
+ }
+ }
+ return;
+ }
+
+You can also manipulate validation errors set by CiviCRM. For example,
+to unset a validation error triggered by CiviCRM:
+
+ $form->setElementError('some_field_name', NULL);
+
+
+Note that only errors set by CiviCRM will appear in the $errors array.
+Errors set by the underlying form system, e.g. for required fields, can
+not be unset here.
+
+
+
+The hook is intended for validation rather than altering form values.
+However, should you need to alter submitted values you need to access
+the controller container object - ie
+
+ $data = &$form->controller->container(); $data['values']['Main'][$fieldName] = $newvalue;
+
+In this case the form is 'Main' - in the Contribution Page flow.
+
+> getAttribute('name');
+>
+> Probably works to get the name
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_validateProfile.md b/docs/hooks/hook_civicrm_validateProfile.md
new file mode 100644
index 00000000..b961c48a
--- /dev/null
+++ b/docs/hooks/hook_civicrm_validateProfile.md
@@ -0,0 +1,17 @@
+# hook_civicrm_validateProfile
+
+## Description
+
+This hook is called while validating a profile form submission.
+
+## Definition
+
+ validateProfile($name)
+
+## Parameters
+
+- $name - the (machine readable) name of the profile.
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_viewProfile.md b/docs/hooks/hook_civicrm_viewProfile.md
new file mode 100644
index 00000000..3e3636f7
--- /dev/null
+++ b/docs/hooks/hook_civicrm_viewProfile.md
@@ -0,0 +1,17 @@
+# hook_civicrm_viewProfile
+
+## Description
+
+This hook is called while preparing a read-only profile screen.
+
+## Definition
+
+ viewProfile($name)
+
+## Parameters
+
+- $name - the (machine readable) name of the profile.
+
+## Returns
+
+- null
\ No newline at end of file
diff --git a/docs/hooks/hook_civicrm_xmlMenu.md b/docs/hooks/hook_civicrm_xmlMenu.md
new file mode 100644
index 00000000..f3456913
--- /dev/null
+++ b/docs/hooks/hook_civicrm_xmlMenu.md
@@ -0,0 +1,64 @@
+# hook_civicrm_xmlMenu
+
+## Description
+
+This hook is called when building CiviCRM's menu structure, which is
+used to render urls in CiviCRM. This hook should be used when you want
+to register your custom module url's in CiviCRM. You will need to visit
+/civicrm/menu/rebuild?reset=1 to pick up your additions.
+
+!!! note "Comparison of Related Hooks"
+ This is one of three related hooks. The hooks:
+
+ - [hook_civicrm_navigationMenu](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_navigationMenu) manipulates the navigation bar at the top of every screen
+ - [hook_civicrm_alterMenu](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterMenu) manipulates the list of HTTP routes (using PHP arrays)
+ - [hook_civicrm_xmlMenu](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu) manipulates the list of HTTP routes (using XML files)
+
+
+
+## Definition
+
+ hook_civicrm_xmlMenu( &$files )
+
+## Parameters
+
+- $files the array for files used to build the menu. You can append
+ or delete entries from this file. You can also override menu items
+ defined by CiviCRM Core.
+
+## Returns
+
+- null
+
+## Example
+
+Here's how you can override an existing menu item. First create an XML
+file like this, and place it in the same folder as your hook
+implementation:
+
+
+
+
+
+
+
+\
+ Drupal developers can define 'my custom permission' using
+[hook_perm](http://api.drupal.org/api/function/hook_perm) . Then create
+a hook implementation like this:
+
+ function EXAMPLE_civicrm_xmlMenu( &$files ) {
+ $files[] = dirname(__FILE__)."/my_file_name_above.xml";
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civirules_alter_trigger_data.md b/docs/hooks/hook_civirules_alter_trigger_data.md
new file mode 100644
index 00000000..277b8e69
--- /dev/null
+++ b/docs/hooks/hook_civirules_alter_trigger_data.md
@@ -0,0 +1,31 @@
+# hook_civirules_alter_trigger_data
+
+## Description
+
+This hook is called for altering the trigger data object just before a
+trigger is triggered.
+
+## Definition
+
+ hook_civirules_alter_trigger_data(CRM_Civirules_TriggerData_TriggerData &$triggerData )
+
+## Returns
+
+- null
+
+## Example
+
+
+
+ /**
+ * Implements hook_civirules_alter_trigger_data
+ *
+ * Adds custom data to the trigger data object
+ */
+ function civirules_civirules_alter_trigger_data(CRM_Civirules_TriggerData_TriggerData &$triggerData) {
+
+ //also add the custom data which is passed to the pre hook (and not the post)
+
+ CRM_Civirules_Utils_CustomDataFromPre::addCustomDataToTriggerData($triggerData);
+
+ }
\ No newline at end of file
diff --git a/docs/hooks/hook_civirules_logger.md b/docs/hooks/hook_civirules_logger.md
new file mode 100644
index 00000000..df74af51
--- /dev/null
+++ b/docs/hooks/hook_civirules_logger.md
@@ -0,0 +1,25 @@
+# hook_civirules_logger
+
+## Description
+
+This hook is called for return an object to do logging in CiviRules. The
+object should be instance of \Psr\Log\LoggerInterface or null if you
+want to disable the logging
+
+## Definition
+
+ hook_civirules_logger(\Psr\Log\LoggerInterface &$logger=null)
+
+## Returns
+
+- null
+
+## Example
+
+The example below returns a database logger for civirules.
+
+ function civiruleslogger_civirules_logger(\Psr\Log\LoggerInterface &$logger=null) {
+ if (empty($logger)) {
+ $logger = new CRM_Civiruleslogger_DatabaseLogger();
+ }
+ }
\ No newline at end of file
diff --git a/docs/js/custom.js b/docs/js/custom.js
deleted file mode 100644
index bdaab5f0..00000000
--- a/docs/js/custom.js
+++ /dev/null
@@ -1,26 +0,0 @@
-$(function() {
-
- // Automatically scroll the navigation menu to the active element
- // https://github.com/civicrm/civicrm-dev-docs/issues/21
- $.fn.isFullyWithinViewport = function(){
- var viewport = {};
- viewport.top = $(window).scrollTop();
- viewport.bottom = viewport.top + $(window).height();
- var bounds = {};
- bounds.top = this.offset().top;
- bounds.bottom = bounds.top + this.outerHeight();
- return ( ! (
- (bounds.top <= viewport.top) ||
- (bounds.bottom >= viewport.bottom)
- ) );
- };
- if( !$('li.toctree-l1.current').isFullyWithinViewport() ) {
- $('.wy-nav-side')
- .scrollTop(
- $('li.toctree-l1.current').offset().top -
- $('.wy-nav-side').offset().top -
- 60
- );
- }
-
-});
diff --git a/mkdocs.yml b/mkdocs.yml
index ae7df86f..664c33a8 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -2,12 +2,16 @@ site_name: CiviCRM Developer Guide
repo_url: https://github.com/civicrm/civicrm-dev-docs
site_description: A guide for CiviCRM developers.
site_author: The CiviCRM community
-theme: readthedocs
-extra_javascript:
- - js/custom.js
+theme: material
markdown_extensions:
- - markdown.extensions.admonition
- - markdown.extensions.attr_list
+ - attr_list
+ - admonition
+ - codehilite(guess_lang=false)
+ - toc(permalink=true)
+ - pymdownx.superfences
+ - pymdownx.inlinehilite
+ - pymdownx.tilde
+ - pymdownx.betterem
pages:
- Home: index.md
- Basics:
@@ -70,11 +74,127 @@ pages:
# CiviMail: /reference/civimail.md # page-tree = NEED_NEW_PAGE
# CiviReport: /reference/civireport.md # page-tree = NEED_NEW_PAGE
# Payment Processing: /reference/payment.md # page-tree = NEED_NEW_PAGE
-- Hooks:
- - Using hooks: hook.md # page-tree = NEED_PAGE_MOVE to /hooks/usage.md
- MISC TO REORGANIZE OR DELETE:
- Extensions files: extensions/files.md
- - Some of the hooks: hooks-db.md
- Requirements: requirements.md
- Develop: develop.md
- hookref-old: hookref-old.md
+- Hooks:
+ - Using hooks: hooks.md # page-tree = NEED_PAGE_MOVE to /hooks/usage.md
+ - Database hooks:
+ - hook_civicrm_copy: hooks/hook_civicrm_copy.md
+ - hook_civicrm_custom: hooks/hook_civicrm_custom.md
+ - hook_civicrm_managed: hooks/hook_civicrm_managed.md
+ - hook_civicrm_merge: hooks/hook_civicrm_merge.md
+ - hook_civicrm_post: hooks/hook_civicrm_post.md
+ - hook_civicrm_pre: hooks/hook_civicrm_pre.md
+ - hook_civicrm_trigger_info: hooks/hook_civicrm_trigger_info.md
+ - hook_civicrm_referenceCounts: hooks/hook_civicrm_referenceCounts.md
+ - hook_civicrm_postSave_table_name: hooks/hook_civicrm_postSave_table_name.md
+ - Extension lifecycle hooks:
+ - hook_civicrm_disable: hooks/hook_civicrm_disable.md
+ - hook_civicrm_enable: hooks/hook_civicrm_enable.md
+ - hook_civicrm_install: hooks/hook_civicrm_install.md
+ - hook_civicrm_uninstall: hooks/hook_civicrm_uninstall.md
+ - hook_civicrm_upgrade: hooks/hook_civicrm_upgrade.md
+ - hook_civicrm_postInstall: hooks/hook_civicrm_postInstall.md
+ - Form hooks:
+ - hook_civicrm_alterContent: hooks/hook_civicrm_alterContent.md
+ - hook_civicrm_buildForm: hooks/hook_civicrm_buildForm.md
+ - hook_civicrm_postProcess: hooks/hook_civicrm_postProcess.md
+ - hook_civicrm_validateForm: hooks/hook_civicrm_validateForm.md
+ - hook_civicrm_alterTemplateFile: hooks/hook_civicrm_alterTemplateFile.md
+ - hook_civicrm_preProcess: hooks/hook_civicrm_preProcess.md
+ - hook_civicrm_idsException: hooks/hook_civicrm_idsException.md
+ - GUI hooks:
+ - hook_civicrm_buildAmount: hooks/hook_civicrm_buildAmount.md
+ - hook_civicrm_caseSummary: hooks/hook_civicrm_caseSummary.md
+ - hook_civicrm_customFieldOptions: hooks/hook_civicrm_customFieldOptions.md
+ - hook_civicrm_dashboard: hooks/hook_civicrm_dashboard.md
+ - hook_civicrm_links: hooks/hook_civicrm_links.md
+ - hook_civicrm_navigationMenu: hooks/hook_civicrm_navigationMenu.md
+ - hook_civicrm_pageRun: hooks/hook_civicrm_pageRun.md
+ - hook_civicrm_searchColumns: hooks/hook_civicrm_searchColumns.md
+ - hook_civicrm_searchTasks: hooks/hook_civicrm_searchTasks.md
+ - hook_civicrm_summary: hooks/hook_civicrm_summary.md
+ - hook_civicrm_summaryActions: hooks/hook_civicrm_summaryActions.md
+ - hook_civicrm_tabs: hooks/hook_civicrm_tabs.md
+ - hook_civicrm_xmlMenu: hooks/hook_civicrm_xmlMenu.md
+ - hook_civicrm_tabset: hooks/hook_civicrm_tabset.md
+ - hook_civicrm_dashboard_defaults: hooks/hook_civicrm_dashboard_defaults.md
+ - hook_civicrm_contact_get_displayname: hooks/hook_civicrm_contact_get_displayname.md
+ - hook_civicrm_fieldOptions: hooks/hook_civicrm_fieldOptions.md
+ - hook_civicrm_alterMenu: hooks/hook_civicrm_alterMenu.md
+ - Mail hooks:
+ - hook_civicrm_alterMailParams: hooks/hook_civicrm_alterMailParams.md
+ - hook_civicrm_emailProcessor: hooks/hook_civicrm_emailProcessor.md
+ - hook_civicrm_emailProcessorContact: hooks/hook_civicrm_emailProcessorContact.md
+ - hook_civicrm_mailingGroups: hooks/hook_civicrm_mailingGroups.md
+ - hook_civicrm_postEmailSend: hooks/hook_civicrm_postEmailSend.md
+ - hook_civicrm_alterMailer: hooks/hook_civicrm_alterMailer.md
+ - hook_civicrm_unsubscribeGroups: hooks/hook_civicrm_unsubscribeGroups.md
+ - hook_civicrm_alterMailContent: hooks/hook_civicrm_alterMailContent.md
+ - hook_civicrm_postMailing: hooks/hook_civicrm_postMailing.md
+ - Permission hooks:
+ - hook_civicrm_aclGroup: hooks/hook_civicrm_aclGroup.md
+ - hook_civicrm_aclWhereClause: hooks/hook_civicrm_aclWhereClause.md
+ - hook_civicrm_alterAPIPermissions: hooks/hook_civicrm_alterAPIPermissions.md
+ - hook_civicrm_permission_check: hooks/hook_civicrm_permission_check.md
+ - hook_civicrm_permission: hooks/hook_civicrm_permission.md
+ - hook_civicrm_selectWhereClause: hooks/hook_civicrm_selectWhereClause.md
+ - Uncategorized hooks:
+ - hook_civicrm_alterCalculatedMembershipStatus: hooks/hook_civicrm_alterCalculatedMembershipStatus.md
+ - hook_civicrm_alterBarcode: hooks/hook_civicrm_alterBarcode.md
+ - hook_civicrm_alterBadge: hooks/hook_civicrm_alterBadge.md
+ - hook_civicrm_alterPaymentProcessorParams: hooks/hook_civicrm_alterPaymentProcessorParams.md
+ - hook_civicrm_alterSettingsFolders: hooks/hook_civicrm_alterSettingsFolders.md
+ - hook_civicrm_alterSettingsMetaData: hooks/hook_civicrm_alterSettingsMetaData.md
+ - hook_civicrm_apiWrappers: hooks/hook_civicrm_apiWrappers.md
+ - hook_civicrm_buildStateProvinceForCountry: hooks/hook_civicrm_buildStateProvinceForCountry.md
+ - hook_civicrm_config: hooks/hook_civicrm_config.md
+ - hook_civicrm_contactListQuery: hooks/hook_civicrm_contactListQuery.md
+ - hook_civicrm_cron: hooks/hook_civicrm_cron.md
+ - hook_civicrm_dupeQuery: hooks/hook_civicrm_dupeQuery.md
+ - hook_civicrm_export: hooks/hook_civicrm_export.md
+ - hook_civicrm_import: hooks/hook_civicrm_import.md
+ - hook_civicrm_membershipTypeValues: hooks/hook_civicrm_membershipTypeValues.md
+ - hook_civicrm_tokens: hooks/hook_civicrm_tokens.md
+ - hook_civicrm_tokenValues: hooks/hook_civicrm_tokenValues.md
+ - hook_civicrm_queryObjects: hooks/hook_civicrm_queryObjects.md
+ - hook_civicrm_check: hooks/hook_civicrm_check.md
+ - hook_civicrm_optionValues: hooks/hook_civicrm_optionValues.md
+ - hook_civicrm_coreResourceList: hooks/hook_civicrm_coreResourceList.md
+ - hook_civicrm_angularModules: hooks/hook_civicrm_angularModules.md
+ - hook_civicrm_container: hooks/hook_civicrm_container.md
+ - hook_civicrm_crudLink: hooks/hook_civicrm_crudLink.md
+ - hook_civicrm_fileSearches: hooks/hook_civicrm_fileSearches.md
+ - hook_civicrm_notePrivacy: hooks/hook_civicrm_notePrivacy.md
+ - hook_civicrm_eventDiscount: hooks/hook_civicrm_eventDiscount.md
+ - hook_civicrm_recent: hooks/hook_civicrm_recent.md
+ - hook_civicrm_unhandledException: hooks/hook_civicrm_unhandledException.md
+ - hook_civicrm_alterMailingLabelParams: hooks/hook_civicrm_alterMailingLabelParams.md
+ - hook_civicrm_geocoderFormat: hooks/hook_civicrm_geocoderFormat.md
+ - hook_civicrm_alterLogTables: hooks/hook_civicrm_alterLogTables.md
+ - Case hooks:
+ - hook_civicrm_caseChange: hooks/hook_civicrm_caseChange.md
+ - hook_civicrm_caseTypes: hooks/hook_civicrm_caseTypes.md
+ - hook_civicrm_post_case_merge: hooks/hook_civicrm_post_case_merge.md
+ - hook_civicrm_pre_case_merge: hooks/hook_civicrm_pre_case_merge.md
+ - Batch hooks:
+ - hook_civicrm_batchItems: hooks/hook_civicrm_batchItems.md
+ - hook_civicrm_batchQuery: hooks/hook_civicrm_batchQuery.md
+ - Entity hooks:
+ - hook_civicrm_entityTypes: hooks/hook_civicrm_entityTypes.md
+ - CiviRules hooks:
+ - hook_civirules_alter_trigger_data: hooks/hook_civirules_alter_trigger_data.md
+ - hook_civirules_logger: hooks/hook_civirules_logger.md
+ - Profile hooks:
+ - hook_civicrm_buildProfile: hooks/hook_civicrm_buildProfile.md
+ - hook_civicrm_buildUFGroupsForModule: hooks/hook_civicrm_buildUFGroupsForModule.md
+ - hook_civicrm_processProfile: hooks/hook_civicrm_processProfile.md
+ - hook_civicrm_searchProfile: hooks/hook_civicrm_searchProfile.md
+ - hook_civicrm_validateProfile: hooks/hook_civicrm_validateProfile.md
+ - hook_civicrm_viewProfile: hooks/hook_civicrm_viewProfile.md
+ - Report hooks:
+ - hook_civicrm_alterReportVar: hooks/hook_civicrm_alterReportVar.md
+
diff --git a/redirects/wiki-crmdoc.txt b/redirects/wiki-crmdoc.txt
index eb7964f4..24a33f38 100644
--- a/redirects/wiki-crmdoc.txt
+++ b/redirects/wiki-crmdoc.txt
@@ -7,4 +7,107 @@ Recommendations basics/planning
The+codebase core/architecture
Debugging+for+developers dev-tools/debugging
Create+a+Module+Extension extensions/civix
+hook_civicrm_copy hooks/hook_civicrm_copy
+hook_civicrm_custom hooks/hook_civicrm_custom
+hook_civicrm_managed hooks/hook_civicrm_managed
+hook_civicrm_merge hooks/hook_civicrm_merge
+hook_civicrm_post hooks/hook_civicrm_post
+hook_civicrm_pre hooks/hook_civicrm_pre
+hook_civicrm_trigger_info hooks/hook_civicrm_trigger_info
+hook_civicrm_referenceCounts hooks/hook_civicrm_referenceCounts
+hook_civicrm_postSave_table_name hooks/hook_civicrm_postSave_table_name
+hook_civicrm_disable hooks/hook_civicrm_disable
+hook_civicrm_enable hooks/hook_civicrm_enable
+hook_civicrm_install hooks/hook_civicrm_install
+hook_civicrm_uninstall hooks/hook_civicrm_uninstall
+hook_civicrm_upgrade hooks/hook_civicrm_upgrade
+hook_civicrm_postInstall hooks/hook_civicrm_postInstall
+hook_civicrm_alterContent hooks/hook_civicrm_alterContent
+hook_civicrm_buildForm hooks/hook_civicrm_buildForm
+hook_civicrm_postProcess hooks/hook_civicrm_postProcess
+hook_civicrm_validateForm hooks/hook_civicrm_validateForm
+hook_civicrm_alterTemplateFile hooks/hook_civicrm_alterTemplateFile
+hook_civicrm_preProcess hooks/hook_civicrm_preProcess
+hook_civicrm_idsException hooks/hook_civicrm_idsException
+hook_civicrm_buildAmount hooks/hook_civicrm_buildAmount
+hook_civicrm_caseSummary hooks/hook_civicrm_caseSummary
+hook_civicrm_customFieldOptions hooks/hook_civicrm_customFieldOptions
+hook_civicrm_dashboard hooks/hook_civicrm_dashboard
+hook_civicrm_links hooks/hook_civicrm_links
+hook_civicrm_navigationMenu hooks/hook_civicrm_navigationMenu
+hook_civicrm_pageRun hooks/hook_civicrm_pageRun
+hook_civicrm_searchColumns hooks/hook_civicrm_searchColumns
+hook_civicrm_searchTasks hooks/hook_civicrm_searchTasks
+hook_civicrm_summary hooks/hook_civicrm_summary
+hook_civicrm_summaryActions hooks/hook_civicrm_summaryActions
+hook_civicrm_tabs hooks/hook_civicrm_tabs
+hook_civicrm_xmlMenu hooks/hook_civicrm_xmlMenu
+hook_civicrm_tabset hooks/hook_civicrm_tabset
+hook_civicrm_dashboard_defaults hooks/hook_civicrm_dashboard_defaults
+hook_civicrm_contact_get_displayname hooks/hook_civicrm_contact_get_displayname
+hook_civicrm_fieldOptions hooks/hook_civicrm_fieldOptions
+hook_civicrm_alterMenu hooks/hook_civicrm_alterMenu
+hook_civicrm_alterMailParams hooks/hook_civicrm_alterMailParams
+hook_civicrm_emailProcessor hooks/hook_civicrm_emailProcessor
+hook_civicrm_emailProcessorContact hooks/hook_civicrm_emailProcessorContact
+hook_civicrm_mailingGroups hooks/hook_civicrm_mailingGroups
+hook_civicrm_postEmailSend hooks/hook_civicrm_postEmailSend
+hook_civicrm_alterMailer hooks/hook_civicrm_alterMailer
+hook_civicrm_unsubscribeGroups hooks/hook_civicrm_unsubscribeGroups
+hook_civicrm_alterMailContent hooks/hook_civicrm_alterMailContent
+hook_civicrm_postMailing hooks/hook_civicrm_postMailing
+hook_civicrm_aclGroup hooks/hook_civicrm_aclGroup
+hook_civicrm_aclWhereClause hooks/hook_civicrm_aclWhereClause
+hook_civicrm_alterAPIPermissions hooks/hook_civicrm_alterAPIPermissions
+hook_civicrm_permission_check hooks/hook_civicrm_permission_check
+hook_civicrm_permission hooks/hook_civicrm_permission
+hook_civicrm_selectWhereClause hooks/hook_civicrm_selectWhereClause
+hook_civicrm_alterCalculatedMembershipStatus hooks/hook_civicrm_alterCalculatedMembershipStatus
+hook_civicrm_alterBarcode hooks/hook_civicrm_alterBarcode
+hook_civicrm_alterBadge hooks/hook_civicrm_alterBadge
+hook_civicrm_alterPaymentProcessorParams hooks/hook_civicrm_alterPaymentProcessorParams
+hook_civicrm_alterSettingsFolders hooks/hook_civicrm_alterSettingsFolders
+hook_civicrm_alterSettingsMetaData hooks/hook_civicrm_alterSettingsMetaData
+hook_civicrm_apiWrappers hooks/hook_civicrm_apiWrappers
+hook_civicrm_buildStateProvinceForCountry hooks/hook_civicrm_buildStateProvinceForCountry
+hook_civicrm_config hooks/hook_civicrm_config
+hook_civicrm_contactListQuery hooks/hook_civicrm_contactListQuery
+hook_civicrm_cron hooks/hook_civicrm_cron
+hook_civicrm_dupeQuery hooks/hook_civicrm_dupeQuery
+hook_civicrm_export hooks/hook_civicrm_export
+hook_civicrm_import hooks/hook_civicrm_import
+hook_civicrm_membershipTypeValues hooks/hook_civicrm_membershipTypeValues
+hook_civicrm_tokens hooks/hook_civicrm_tokens
+hook_civicrm_tokenValues hooks/hook_civicrm_tokenValues
+hook_civicrm_queryObjects hooks/hook_civicrm_queryObjects
+hook_civicrm_check hooks/hook_civicrm_check
+hook_civicrm_optionValues hooks/hook_civicrm_optionValues
+hook_civicrm_coreResourceList hooks/hook_civicrm_coreResourceList
+hook_civicrm_angularModules hooks/hook_civicrm_angularModules
+hook_civicrm_container hooks/hook_civicrm_container
+hook_civicrm_crudLink hooks/hook_civicrm_crudLink
+hook_civicrm_fileSearches hooks/hook_civicrm_fileSearches
+hook_civicrm_notePrivacy hooks/hook_civicrm_notePrivacy
+hook_civicrm_eventDiscount hooks/hook_civicrm_eventDiscount
+hook_civicrm_recent hooks/hook_civicrm_recent
+hook_civicrm_unhandledException hooks/hook_civicrm_unhandledException
+hook_civicrm_alterMailingLabelParams hooks/hook_civicrm_alterMailingLabelParams
+hook_civicrm_geocoderFormat hooks/hook_civicrm_geocoderFormat
+hook_civicrm_alterLogTables hooks/hook_civicrm_alterLogTables
+hook_civicrm_caseChange hooks/hook_civicrm_caseChange
+hook_civicrm_caseTypes hooks/hook_civicrm_caseTypes
+hook_civicrm_post_case_merge hooks/hook_civicrm_post_case_merge
+hook_civicrm_pre_case_merge hooks/hook_civicrm_pre_case_merge
+hook_civicrm_batchItems hooks/hook_civicrm_batchItems
+hook_civicrm_batchQuery hooks/hook_civicrm_batchQuery
+hook_civicrm_entityTypes hooks/hook_civicrm_entityTypes
+hook_civirules_alter_trigger_data hooks/hook_civirules_alter_trigger_data
+hook_civirules_logger hooks/hook_civirules_logger
+hook_civicrm_buildProfile hooks/hook_civicrm_buildProfile
+hook_civicrm_buildUFGroupsForModule hooks/hook_civicrm_buildUFGroupsForModule
+hook_civicrm_processProfile hooks/hook_civicrm_processProfile
+hook_civicrm_searchProfile hooks/hook_civicrm_searchProfile
+hook_civicrm_validateProfile hooks/hook_civicrm_validateProfile
+hook_civicrm_viewProfile hooks/hook_civicrm_viewProfile
+hook_civicrm_alterReportVar hooks/hook_civicrm_alterReportVar