Skip to content
Snippets Groups Projects
Commit 89f85391 authored by dvhirst's avatar dvhirst :older_man_tone1: Committed by GitHub
Browse files

Update civix.md

Reading for content; editing for consistency.
parent b8ed0a37
No related branches found
No related tags found
No related merge requests found
......@@ -2,27 +2,21 @@
## Introduction
The [`civix`](https://github.com/totten/civix/) command-line tool is the
community-endorsed method for building your CiviCRM extensions.
The [`civix`](https://github.com/totten/civix/) command-line tool is the community-endorsed method for building your CiviCRM extensions.
Follow the installation instructions in the
[GitHub repository](https://github.com/totten/civix/).
Follow the installation instructions in the [GitHub repository](https://github.com/totten/civix/).
After fulfilling the [Pre-Requisites](/extensions/index.md#pre-requisites), you can verify that all your configuration is correct by running the following command from
within your extensions directory with:
After fulfilling the [Pre-Requisites](/extensions/index.md#pre-requisites), you can verify that all your configuration is correct by running the following command from within your extensions directory with:
```bash
civix civicrm:ping
```
This command should reply with "Ping successful".
If the ping is unsuccessful, re-read the civix README.md and do the
post-installation configuration.
This command should reply with "Ping successful". If the ping is unsuccessful, re-read the civix README.md and do the post-installation configuration.
It is also useful to examine the output of the `civix help` command to read
about what `civix` can do for you.
It is also useful to examine the output of the `civix help` command to read about what `civix` can do for you.
Help is available on individual commands, e.g.:
Help is available on individual commands, e.g.,:
```bash
civix help civicrm:ping
......@@ -30,9 +24,7 @@ civix help civicrm:ping
## Generating a skeletal extension {:#generate-module}
To generate a skeletal extension module, we will use `civix generate:module`
and pass in the name for our extension. See [here](/extensions/index.md#extension-names)
for details of naming conventions.
To generate a skeletal extension module, we will use `civix generate:module` and pass in the name for our extension. See [here](/extensions/index.md#extension-names) for details of naming conventions.
Start with:
......@@ -47,22 +39,13 @@ Then use a command like this:
civix generate:module com.example.myextension --license=AGPL-3.0
```
This command will report that it has created three files, following the
[standard extension structure](/extensions/structure.md).
This command will report that it has created three files, following the [standard extension structure](/extensions/structure.md).
The command attempts to auto-detect authorship information (your name and
email address) by reading your
[`git`](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)
configuration. If this fails or is
otherwise incorrect, then you may pass explicit values with `--author`
and `--email`.
The command attempts to auto-detect authorship information (your name and email address) by reading your [`git`](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup) configuration. If this fails or is otherwise incorrect, then you may pass explicit values with `--author` and `--email`.
You can now update your `info.xml`. This file initially contains some
examples and placeholders which you need to fix. You can edit most of these
fields intuitively. If you need detailed specifications, see [Extension Reference](/extensions/index.md).
You can now update your `info.xml`. This file initially contains some examples and placeholders which you need to fix. You can edit most of these fields intuitively. If you need detailed specifications, see [Extension Reference](/extensions/index.md).
Now that you have created your extension, you need to activate it by navigating
to:
Now that you have created your extension, you need to activate it by navigating to:
**Administer » System Settings » Manage Extensions**
......@@ -70,20 +53,15 @@ or
**Administer » Customize Data and Screens » Manage Extensions.**
For more detailed instructions, see
[Extensions](/extensions/index.md).
For more detailed instructions, see [Extensions](/extensions/index.md).
## Add features
There are many different features that you can add to a module-extension
at your discretion. A few possibilities:
There are many different features that you can add to a module-extension at your discretion. A few possibilities:
### Add a basic web page {:#generate-page}
CiviCRM uses a typical web-MVC architecture. To implement a basic web
page, you must create a PHP controller class, create a Smarty template
file, and create a routing rule. You can create the appropriate files by
calling `civix generate:page`
CiviCRM uses a typical web-MVC architecture. To implement a basic web page, you must create a PHP controller class, create a Smarty template file, and create a routing rule. You can create the appropriate files by calling `civix generate:page`.
Once again you can review the output of this command to see the available options:
......@@ -91,8 +69,7 @@ Once again you can review the output of this command to see the available option
civix generate:page --help
```
Generally you will only need to supply the PHP class name and web-path,
for example:
Generally you will only need to supply the PHP class name and web-path, for example:
```bash
civix generate:page MyPage civicrm/my-page
......@@ -100,50 +77,27 @@ civix generate:page MyPage civicrm/my-page
This creates three files:
- `xml/Menu/myextension.xml` defines request-routing rules and
associates the controller ("CRM_Myextension_Page_Greeter") with
the web path `civicrm/my-page`.
- `CRM/Myextension/Page/MyPage.php` is the controller which
coordinates any parsing, validation, business-logic, or database
operations.
- `templates/CRM/Myextension/Page/MyPage.tpl` is loaded
automatically after the controller executes. It defines the markup
that is eventually displayed. For more information on the syntax of
this file, see
[the smarty guide](http://www.smarty.net/docs/en/).
The auto-generated code for the controller and view demonstrate a few
basic operations, such as passing data from the controller to the view.
- `xml/Menu/myextension.xml` defines request-routing rules and associates the controller ("CRM_Myextension_Page_Greeter") with the web path `civicrm/my-page`.
- `CRM/Myextension/Page/MyPage.php` is the controller which coordinates any parsing, validation, business-logic, or database operations.
- `templates/CRM/Myextension/Page/MyPage.tpl` is loaded automatically after the controller executes. It defines the markup that is eventually displayed. For more information on the syntax of this file, see [the smarty guide](http://www.smarty.net/docs/en/).
The auto-generated code for the controller and view demonstrate a few basic operations, such as passing data from the controller to the view.
!!! note
After adding or modifying a route in the XML file, you must reset
CiviCRMs "menu cache". Do this in a web browser by visiting
`/civicrm/menu/rebuild?reset=1` or by running
`drush cc civicrm` if using Drupal & Drush.
After adding or modifying a route in the XML file, you must reset CiviCRMs "menu cache". Do this in a web browser by visiting `/civicrm/menu/rebuild?reset=1` or, if using Drupal & Drush, by running `drush cc civicrm`.
**Edit In Place**
If the data on the page is read and updated through the API, then you
may want to consider using the
[in-place editing](/framework/ui.md#in-place-field-editing) API.
If the data on the page is read and updated through the API, then you may want to consider using the [in-place editing](/framework/ui.md#in-place-field-editing) API.
### Add a basic web form {:#generate-form}
!!! caution
The form system is not well documented and may undergo significant
revision after the CiviCRM 4.x series. In general, migrating basic pages
will be easier than migrating basic forms, so you may want
to consider building your data-input interface using basic pages, the AJAX
API, and the
[in-place editing](/framework/ui.md#in-place-field-editing) API.
The form system is not well documented and may undergo significant revision after the CiviCRM 4.x series. In general, migrating basic pages will be easier than migrating basic forms, so you may want to consider building your data-input interface using basic pages, the AJAX API, and the [in-place editing](/framework/ui.md#in-place-field-editing) API.
CiviCRM uses a typical web-MVC architecture. To implement a basic web
form, you must create a PHP controller class, create a Smarty template
file, and create a routing rule. You can create the appropriate files by
calling `civix generate:form`.
CiviCRM uses a typical web-MVC architecture. To implement a basic web form, you must create a PHP controller class, create a Smarty template file, and create a routing rule. You can create the appropriate files by calling `civix generate:form`.
The form generation command has similar arguments to `civix generate:page`,
requiring a class name and a web route:
The form generation command has similar arguments to `civix generate:page`, requiring a class name and a web route:
```bash
civix generate:form FavoriteColor civicrm/favcolor
......@@ -151,34 +105,22 @@ civix generate:form FavoriteColor civicrm/favcolor
This creates three files:
- `xml/Menu/myextension.xml` defines request-routing rules and
associates the controller `CRM_Myextension_Form_FavoriteColor`
- `xml/Menu/myextension.xml` defines request-routing rules and associates the controller `CRM_Myextension_Form_FavoriteColor`
with the web path `civicrm/favcolor`.
- `CRM/Myextension/Form/FavoriteColor.php` is the controller which
coordinates any parsing, validation, business-logic, or database
operations. For more details on how this class works, see [QuickForm
Reference](/framework/quickform/index.md).
- `templates/CRM/Myextension/Form/FavoriteColor.tpl` is loaded
automatically after the controller executes. It defines the markup
that is eventually displayed. For more information on the syntax of
this file, see
[the smarty guide](http://www.smarty.net/docs/en/).
The auto-generated code for the controller and view demonstrate a few
basic operations, such as adding a `<select>` element to the form.
- `CRM/Myextension/Form/FavoriteColor.php` is the controller which coordinates any parsing, validation, business-logic, or database operations. For more details on how this class works, see [QuickForm Reference](/framework/quickform/index.md).
- `templates/CRM/Myextension/Form/FavoriteColor.tpl` is loaded automatically after the controller executes. It defines the markup that is eventually displayed. For more information on the syntax of this file, see [the smarty guide](http://www.smarty.net/docs/en/).
The auto-generated code for the controller and view demonstrate a few basic operations, such as adding a `<select>` element to the form.
!!! note
After adding or modifying a route in the XML file, you must reset
CiviCRMs "menu cache". This can be done in a web browser by visiting
`/civicrm/menu/rebuild?reset=1`
After adding or modifying a route in the XML file, you must reset CiviCRMs "menu cache". This can be done in a web browser by visiting `/civicrm/menu/rebuild?reset=1`.
### Add a new entity {:#generate-entity}
!!! caution
!!! caution
This functionality is considered "experimental and incomplete".
If you want your extension to store data in the database, then you will need
to create a new entity. For this, you can use the command `civix generate:entity`
If you want your extension to store data in the database, then you will need to create a new entity. For this, you can use the command `civix generate:entity`.
1. Pick a name for your entity.
......@@ -238,12 +180,7 @@ to create a new entity. For this, you can use the command `civix generate:entity
### Add a database upgrader, installer and uninstaller {:#generate-upgrader}
If your module requires creating or maintaining SQL tables, then you
should create a class for managing database upgrades. The upgrader adds
a class for managing installs and upgrades but you then need to edit the file
comment out the various upgrade and uninstall functions
to make it work. Generally your install script belongs in an `sql/` folder
in the root of your extension with a name like 'install'
If your module requires creating or maintaining SQL tables, then you should create a class for managing database upgrades. The upgrader adds a class for managing installs and upgrades but you then need to edit the file comment out the various upgrade and uninstall functions to make it work. Generally your install script belongs in an `sql/` folder in the root of your extension with a name like 'install'.
This `civix` command does not require arguments:
......@@ -253,47 +190,28 @@ civix generate:upgrader
This creates two files and one directory:
- `CRM/Myextension/Upgrader.php` stores a series of upgrade
functions based on a function naming pattern similar to
Drupal's
[hook_update_N](http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_update_N/7).
After examining the file's comments for example upgrade functions
you can then write your own.
- `CRM/Myextension/Upgrader/Base.php` contains helper functions
and adapters which make it easier to write the upgrader. This file
may be overwritten from time-to-time to provide new helpers or
adapters.
- `CRM/Myextension/Upgrader.php` stores a series of upgrade functions based on a function naming pattern similar to
Drupal's [hook_update_N](http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_update_N/7). After examining the file's comments for example upgrade functions you can then write your own.
- `CRM/Myextension/Upgrader/Base.php` contains helper functions and adapters which make it easier to write the upgrader. This file may be overwritten from time-to-time to provide new helpers or adapters.
- sql
After reviewing the examples and creating your own upgrade functions,
you can execute the upgrades through the web interface by visiting the
"Manage Extensions" screen. This screen will display an alert with an
action-link to perform the upgrades.
After reviewing the examples and creating your own upgrade functions, you can execute the upgrades through the web interface by visiting the "Manage Extensions" screen. This screen will display an alert with an action-link to perform the upgrades.
!!! note
The "upgrader" class is a wrapper for
[hook_civicrm_upgrade](/hooks/hook_civicrm_upgrade.md)
which aims to be easy-to-use for developers with Drupal experience. If
you need to organize the upgrade logic differently, then consider
providing your own implementation of hook_civicrm_upgrade.
The "upgrader" class is a wrapper for [hook_civicrm_upgrade](/hooks/hook_civicrm_upgrade.md) which aims to be easy-to-use for developers with Drupal experience. If you need to organize the upgrade logic differently, then consider providing your own implementation of hook_civicrm_upgrade.
!!! caution
Only use the upgrade system to manage new SQL
tables. Do not manipulate core schema.
Only use the upgrade system to manage new SQL tables. Do not manipulate core schema.
If you need to create triggers on core SQL tables, use
[hook_civicrm_triggerInfo](/hooks/hook_civicrm_triggerInfo.md).
This allows your triggers to coexist with triggers from other modules.
If you need to create triggers on core SQL tables, use [hook_civicrm_triggerInfo](/hooks/hook_civicrm_triggerInfo.md). This allows your triggers to coexist with triggers from other modules.
### Add a case type {:#generate-case-type}
*(from CiviCRM v4.4+)*
If you want to develop a custom case-type for CiviCase, then you can
generate a skeletal CiviCase XML file.
If you want to develop a custom case-type for CiviCase, then you can generate a skeletal CiviCase XML file.
Once again `civix` will give the details of options and arguments with this
command:
Once again `civix` will give the details of options and arguments with this command:
```bash
civix help generate:case-type
......@@ -307,42 +225,25 @@ civix generate:case-type "Volunteer Training" Training
This creates two files:
- `xml/case/Training.xml` defines the roles, activity types, and
timelines associated with the new case type. For more in depth
discussion of CiviCase XML, see
[CiviCase Configuration](https://wiki.civicrm.org/confluence/display/CRMDOC/CiviCase+Configuration).
- `alltypes.civix.php`(which may already exist) defines
implementations of various hooks (notably hook_civicrm_caseTypes).
- `xml/case/Training.xml` defines the roles, activity types, and timelines associated with the new case type. For more in depth discussion of CiviCase XML, see [CiviCase Configuration](https://wiki.civicrm.org/confluence/display/CRMDOC/CiviCase+Configuration).
- `alltypes.civix.php`(which may already exist) defines implementations of various hooks (notably hook_civicrm_caseTypes).
### Add custom fields
*(from CiviCRM v4.4+)*
Your extension can create one or more sets of custom
fields at installation. There are two
methods depending on whether the custom data set extends an entity
(e.g. "Individual" – without any specific subtype)
or extends a specific subtype of an entity.
(e.g. Activities of type 'Volunteer')
Your extension can create one or more sets of custom fields at installation. There are two methods depending on whether the custom data set extends an entity (e.g. "Individual" – without any specific subtype) or extends a specific subtype of an entity, (e.g. Activities of type 'Volunteer').
#### Extending a base entity
This is the simplest scenario.
Start by creating a custom fields using the web interface and then export
them for use with the extension:
This is the simplest scenario. Start by creating a custom fields using the web interface and then export them for use with the extension:
!!! note
Before you begin verify that civix is connected to your instance of
CiviCRM by running `civix civicrm:ping`.
- On your development instance of CiviCRM, create the new custom
fields using the web interface. Note the unique ID of the custom data
group (also known as the "Custom Fieldset", "CustomGroup" or
"civicrm_custom_group")
- Create an XML file with `civix generate:custom-xml`
specifying the custom-data group ID.
- Create an upgrader file with `civix generate:upgrader` to
load the XML file during installation.
Before you begin verify that civix is connected to your instance of CiviCRM by running `civix civicrm:ping`.
- On your development instance of CiviCRM, create the new custom fields using the web interface. Note the unique ID of the custom data group (also known as the "Custom Fieldset", "CustomGroup" or "civicrm_custom_group").
- Create an XML file with `civix generate:custom-xml` specifying the custom-data group ID.
- Create an upgrader file with `civix generate:upgrader` to load the XML file during installation.
Check the full range of options with the `civix` help command:
......@@ -356,56 +257,33 @@ So to created your XML for a custom data group ID of 7:
civix generate:custom-xml --data=7
```
Most of the [CiviHR](https://github.com/civicrm/civihr/tree/master) modules rely on the first approach (e.g.:
[Upgrader/Base.php](https://github.com/civicrm/civihr/blob/master/hrqual/CRM/HRQual/Upgrader/Base.php#L244) and
[auto_install.xml](https://github.com/civicrm/civihr/blob/master/hrqual/xml/auto_install.xml)).
Most of the [CiviHR](https://github.com/civicrm/civihr/tree/master) modules rely on the first approach (e.g.: [Upgrader/Base.php](https://github.com/civicrm/civihr/blob/master/hrqual/CRM/HRQual/Upgrader/Base.php#L244) and [auto_install.xml](https://github.com/civicrm/civihr/blob/master/hrqual/xml/auto_install.xml)).
#### Extending an subtype
<!-- This section still is not really clear to me. (Erich Schulz)
Is this really about sub-types in an OO sense?? or subtypes in as a base
entity of a particular type as defined by its properties?
-->
The automatic export does not work too well when the
custom-data group extends a specific subtype. The
"HR Emergency Contact" extension provides and example that creates
a custom-data group that describes
Relationships with type "Emergency Contact". Internally, Civi uses
"relationship type IDs", but those are not portable. As a quick
work-around, this extension uses Smarty:
([HREmerg/Upgrader.php](https://github.com/civicrm/civihr/blob/master/hremerg/CRM/HREmerg/Upgrader.php#L14)
and
[hremerg-customdata.xml.tpl](https://github.com/civicrm/civihr/blob/master/hremerg/templates/hremerg-customdata.xml.tpl#L11)).
To create this extension, the author used `civix generate:custom-data` and
then:
1. Renamed the `xml/auto_install.xml` to
`templates/hremerg-customdata.xml.tpl`
2. Changed the value of `<extends_entity_column_value>` in the
`.tpl file` using a variable instead of a hard-coded type ID.
3. Added logic in the upgrader to create the relationship type
4. Added logic in the upgrader to evaluate the Smarty template
<!-- This section still is not really clear to me. (Erich Schulz) Is this really about sub-types in an OO sense?? or subtypes in as a base entity of a particular type as defined by its properties? -->
The automatic export does not work too well when the custom-data group extends a specific subtype. The "HR Emergency Contact" extension provides and example that creates a custom-data group that describes Relationships with type "Emergency Contact". Internally, Civi uses "relationship type IDs", but those are not portable. As a quick work-around, this extension uses Smarty: ([HREmerg/Upgrader.php](https://github.com/civicrm/civihr/blob/master/hremerg/CRM/HREmerg/Upgrader.php#L14) and [hremerg-customdata.xml.tpl](https://github.com/civicrm/civihr/blob/master/hremerg/templates/hremerg-customdata.xml.tpl#L11)).
To create this extension, the author used `civix generate:custom-data` and then:
1. Renamed the `xml/auto_install.xml` to `templates/hremerg-customdata.xml.tpl`
1. Changed the value of `<extends_entity_column_value>` in the `.tpl file` using a variable instead of a hard-coded type ID.
1. Added logic in the upgrader to create the relationship type.
1. Added logic in the upgrader to evaluate the Smarty template.
#### Accessing Custom Fields
For setting and getting custom field values in hooks, you need to know the field
ID of the custom field(s) you want to work with. You'll then access these
fields as "custom_<ID>". So if you have a field holding a custom value whose
ID in the civicrm_custom_field table is 34, you'll use "custom_34" to access it.
For setting and getting custom field values in hooks, you need to know the field ID of the custom field(s) you want to work with. You'll then access these fields as "custom_<ID>". So if you have a field holding a custom value whose ID in the civicrm_custom_field table is 34, you'll use "custom_34" to access it.
To get a custom field ID given the custom field name and custom group name,
you can use the following code:
To get a custom field ID given the custom field name and custom group name, you can use the following code:
```php
require_once 'CRM/Core/BAO/CustomField.php';
$customFieldID = CRM_Core_BAO_CustomField::getCustomFieldID($field, $group);
```
Once you have the ID(s), you'll want to use the setValues and getValues
functions in the CRM/Core/BAO/CustomValueTable.php file. Here are a couple
of examples of their use:
Once you have the ID(s), you'll want to use the setValues and getValues functions in the CRM/Core/BAO/CustomValueTable.php file. Here are a couple of examples of their use:
Setting values:
......@@ -424,33 +302,15 @@ $values = CRM_Core_BAO_CustomValueTable::getValues($params);
```
!!! caution
Note that custom field values may not always be available when you
might expect.
For instance, you can't retrieve custom field values in the 'create'
operation in the _pre and _post hooks, because the custom field values
haven't been stored yet. However, you can retrieve values in the 'edit'
operation.
Note that custom field values may not always be available when you might expect. For instance, you can't retrieve custom field values in the 'create' operation in the _pre and _post hooks, because the custom field values haven't been stored yet. However, you can retrieve values in the 'edit' operation.
### Add a hook function
CiviCRM
[hook functions](/hooks/index.md)
allow extensions to run extra logic as
part of the normal CiviCRM processing. For example,
`hook_civicrm_buildForm()` allows a module to run logic whenever a
web-form is displayed, and `hook_civicrm_post()` allows a module to
run logic after any entity is saved.
Hook function names follow the Drupal convention of being
the module's short-name concatenated to the hook name. This strict but simple
naming convention is what allows the CiviCRM core to locate your hook
functions and call them at the appropriate times.
For example, if our module's main file is
`myextension.php` and we want to use `hook_civicrm_post()`
to write to a log file every time a contribution is saved, then our function must be called `myextension_civicrm_post()`:
To implement a hook, add a function to the module's main `.php`
file created earlier with `civix generate:module`:
CiviCRM [hook functions](/hooks/index.md) allow extensions to run extra logic as part of the normal CiviCRM processing. For example, `hook_civicrm_buildForm()` allows a module to run logic whenever a web-form is displayed, and `hook_civicrm_post()` allows a module to run logic after any entity is saved.
Hook function names follow the Drupal convention of being the module's short-name concatenated to the hook name. This strict but simple naming convention is what allows the CiviCRM core to locate your hook functions and call them at the appropriate times. For example, if our module's main file is `myextension.php` and we want to use `hook_civicrm_post()` to write to a log file every time a contribution is saved, then our function must be called `myextension_civicrm_post()`.
To implement a hook, add a function to the module's main `.php` file created earlier with `civix generate:module`:
```php
/**
......@@ -474,25 +334,15 @@ function myextension_civicrm_post($op, $objectName, $objectId, &$objectRef) {
```
!!! note
When you first created the skeletal project, several hook functions were
auto-generated in `myextension.php`. These functions are usually about
one line long – they simply delegate the work to another function. For
example `myextension_civicrm_config()` delegates work to
`_myextension_civix_civicrm_config()`. You should feel free to add
more code to `myextension_civicrm_config()`, but you should preserve
the call to `_myextension_civix_civicrm_config()`. <!-- fixme! why?? -->
When you first created the skeletal project, several hook functions were auto-generated in `myextension.php`. These functions are usually about one line long – they simply delegate the work to another function. For example `myextension_civicrm_config()` delegates work to `_myextension_civix_civicrm_config()`. You should feel free to add more code to `myextension_civicrm_config()`, but you should preserve the call to `_myextension_civix_civicrm_config()`. <!-- fixme! why?? -->
### Add a resource file
To include static resources such as stylesheets, Javascript files, or
images place them in your extension directory. To load
the files at runtime, see the examples in the [Resource Reference](/framework/resources.md).
To include static resources such as stylesheets, Javascript files, or images place them in your extension directory. To load the files at runtime, see the examples in the [Resource Reference](/framework/resources.md).
### Add a report {:#generate-report}
CiviReport enables developers to define new business reports using
customizable SQL logic and form layouts.
If another existing report is close to your needs you may copy and modify it.
CiviReport enables developers to define new business reports using customizable SQL logic and form layouts. If another existing report is close to your needs you may copy and modify it.
To to see the available report generation options activate the `civix` help:
......@@ -508,29 +358,14 @@ civix generate:report MyReport CiviContribute
This creates three files:
- `CRM/Myextension/Form/Report/MyReport.mgd.php` stores metadata
about the report in a format based on
[hook_civicrm_managed](/hooks/hook_civicrm_managed.md)
and the
[API](/api/index.md).
- `CRM/Myextension/Form/Report/MyReport.php` contains the
form-builder and query-builder for the report. For details about its
structure, see the [CiviReport
Reference](/framework/civireport.md).
- `templates/CRM/Myextension/Form/Report/MyReport.tpl` contains
the report's HTML template. This template usually delegates
responsibility to a core template and does not need to be edited.
If one of the existing reports is close to meeting
your needs, but requires further PHP or SQL customization, you may
simply make a new report based on that report.
To copy a report, find the class-name of the original report within the
`civicrm/CRM/Report/Form/` directory in the CiviCRM repository.
Then run the `civix generate:report` command using the copy option
from with your extension directory.
For example, this command will copy the activity report in the class
`CRM_Report_Form_Activity` to a new report within your extension:
- `CRM/Myextension/Form/Report/MyReport.mgd.php` stores metadata about the report in a format based on [hook_civicrm_managed](/hooks/hook_civicrm_managed.md) and the [API](/api/index.md).
- `CRM/Myextension/Form/Report/MyReport.php` contains the form-builder and query-builder for the report. For details about its
structure, see the [CiviReport Reference](/framework/civireport.md).
- `templates/CRM/Myextension/Form/Report/MyReport.tpl` contains the report's HTML template. This template usually delegates responsibility to a core template and does not need to be edited.
If one of the existing reports is close to meeting your needs, but requires further PHP or SQL customization, you may simply make a new report based on that report. To copy a report, find the class-name of the original report within the `civicrm/CRM/Report/Form/` directory in the CiviCRM repository. Then run the `civix generate:report` command using the copy option from with your extension directory.
For example, this command will copy the activity report in the class `CRM_Report_Form_Activity` to a new report within your extension:
```bash
civix generate:report --copy CRM_Report_Form_Activity MyActivity Contact
......@@ -538,14 +373,13 @@ civix generate:report --copy CRM_Report_Form_Activity MyActivity Contact
### Add a custom search {:#generate-search}
CiviCRM enables developers to define new search forms using customizable
SQL logic and form layouts. Use this command to get started:
CiviCRM enables developers to define new search forms using customizable SQL logic and form layouts. Use this command to get started:
```bash
civix help generate:search
```
Then you could generate your basic search code for a `MySearch` class with:
Then you could generate your basic search code for a `MySearch` class with:
```bash
civix generate:search MySearch
......@@ -553,39 +387,28 @@ civix generate:search MySearch
This command will create two files:
- `CRM/Myextension/Form/Search/MySearch.mgd.php` stores metadata
about the custom search. The format of the file is based on
[hook_civicrm_managed](/hooks/hook_civicrm_managed.md)
and the
[API](/api/index.md).
- `CRM/Myextension/Form/Search/MySearch.php` contains the
form-builder and query-builder for the custom search.
- `CRM/Myextension/Form/Search/MySearch.mgd.php` stores metadata about the custom search. The format of the file is based on
[hook_civicrm_managed](/hooks/hook_civicrm_managed.md) and the [API](/api/index.md).
- `CRM/Myextension/Form/Search/MySearch.php` contains the form-builder and query-builder for the custom search.
#### Copying an existing search
If one of the existing searches is close to
meeting your needs you may copy it instead and then customise the
If one of the existing searches is close to meeting your needs you may copy it instead and then customise the
PHP, SQL and templates.
To make a new search based on an existing search first determine the name of
the original search class within the `civicrm/CRM/Contact/Form/Search/Custom`
directory of CiviCRM source tree. Then run the `generate:search` command from
within your module directory.
To make a new search based on an existing search first determine the name of the original search class within the `civicrm/CRM/Contact/Form/Search/Custom` directory of CiviCRM source tree. Then run the `generate:search` command from within your module directory.
For example, the zipcode search is in the class
`CRM_Contact_Form_Search_Custom_ZipCodeRange`, so you can copy it with:
For example, the zipcode search is in the class `CRM_Contact_Form_Search_Custom_ZipCodeRange`, so you can copy it with:
```bash
civix generate:search --copy CRM_Contact_Form_Search_Custom_ZipCodeRange MySearch
```
The "copy" option will create either two or three files depending
on whether the original search screen defines its own Smarty template.
The "copy" option will create either two or three files depending on whether the original search screen defines its own Smarty template.
#### Using your search
1. Disable and re-enable your extension.
1. Go to **Search > Custom Searches...** and find your new custom search listed at the bottom.
#### Building your custom search
......@@ -597,13 +420,7 @@ See this (somewhat outdated) [wiki page](https://wiki.civicrm.org/confluence/dis
### Add an API function {:#generate-api}
The [CiviCRM API](/api/index.md)
provides a way to expose functions for use by other developers. API
functions allow implementing AJAX interfaces (using the
cj().crmAPI() helper), and they can also be called via REST, PHP,
Smarty, Drush CLI, and more. Each API requires a two-part name: an
entity name (such as "Contact", "Event", or "MyEntity") and an action
name (such as "Create" or "MyAction").
The [CiviCRM API](/api/index.md) provides a way to expose functions for use by other developers. API functions allow implementing AJAX interfaces (using the cj().crmAPI() helper), and they can also be called via REST, PHP, Smarty, Drush CLI, and more. Each API requires a two-part name: an entity name (such as "Contact", "Event", or "MyEntity") and an action name (such as "Create" or "MyAction").
Get started by accessing the `civix` help:
......@@ -612,10 +429,7 @@ civix help generate:api
```
!!! note
Action names must be lowercase. The javascript helpers `CRM.api()` and
`CRM.api3()` force actions to be lowercase. This issues does not present
itself in the API Explorer or when the api action is called via PHP,
REST, or SMARTY.
Action names must be lowercase. The javascript helpers `CRM.api()` and `CRM.api3()` force actions to be lowercase. This issue does not present itself in the API Explorer or when the api action is called via PHP, REST, or SMARTY.
You can make your API code with a command in this pattern:
......@@ -625,32 +439,23 @@ civix generate:api NewEntity NewAction
This creates one file:
- `api/v3/NewEntity/NewAction.php` provides the API function.
that the parameters and return values must be processed in a
particular way (as demonstrated by the auto-generated file).
- `api/v3/NewEntity/NewAction.php` provides the API function. Note that the parameters and return values must be processed in a particular way (as demonstrated by the auto-generated file).
For use with CiviCRM 4.3 and later, you can also add the `–schedule` option (e.g.
`–schedule Hourly`). This will create another file:
For use with CiviCRM 4.3 and later, you can also add the `–schedule` option (e.g., `–schedule Hourly`). This will create another file:
- `api/v3/NewEntity/NewAction.mgd.php` provides the scheduling
record that will appear in the CiviCRM's job-manager.
- `api/v3/NewEntity/NewAction.mgd.php` provides the scheduling record that will appear in the CiviCRM's job-manager.
!!! tip
Read more about the [API architecture](/framework/api-architecture.md) for help writing your custom API.
### Add a unit-test class {:#generate-test}
Unit-testing is essential to maintain quality-control over
your extension. When developing a test case for a CiviCRM extension, it
is useful to run the test case within an active, clean CiviCRM
environment. The combined CiviCRM `civix` testing tools will automate this as
long as you follow a few basic conventions.
Unit-testing is essential to maintain quality-control over your extension. When developing a test case for a CiviCRM extension, it is useful to run the test case within an active, clean CiviCRM environment. The combined CiviCRM `civix` testing tools will automate this as long as you follow a few basic conventions.
The following steps will create and run a test in your extension.
!!! note
Before preparing unit-tests with extensions, you must first
[configure you personal testing sandbox](https://wiki.civicrm.org/confluence/display/CRM/Setting+up+your+personal+testing+sandbox+HOWTO) and enable your extension on the sandbox.
Before preparing unit-tests with extensions, you must first [configure you personal testing sandbox](https://wiki.civicrm.org/confluence/display/CRM/Setting+up+your+personal+testing+sandbox+HOWTO) and enable your extension on the sandbox.
Explore the full options with:
......@@ -658,9 +463,7 @@ Explore the full options with:
civix help generate:test
```
To create a skeletal test-class choose a class name in
your extension's namespace (*CRM_Myextension*) that ends with the
word *Test*:
To create a skeletal test-class choose a class name in your extension's namespace (*CRM_Myextension*) that ends with the word *Test*:
```bash
civix generate:test CRM_Myextension_MyTest
......@@ -669,20 +472,14 @@ civix generate:test CRM_Myextension_MyTest
This creates a new directory and a new PHP file:
- `tests/phpunit` is the base directory for all test classes.
- `tests/phpunit/CRM/Myextension/MyTest.php` is the actual test
class. It should be written according to the conventions of
[PHPUnit](http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html).
- `tests/phpunit/CRM/Myextension/MyTest.php` is the actual test class. It should be written according to the conventions of [PHPUnit](http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html).
To make sure you can run the test civix needs to know where the CiviCRM base install is located.
To make sure you can run the test civix needs to know where the CiviCRM
base install is:
The skeletal test class does not do anything useful. For more details on how to write a test class:
The skeletal test class does not do anything useful. For more details on
how to write a test class:
- Read [PHP Unit Manual: Writing Tests for PHPUnit.](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html).
- Review the example code in [org.civicrm.exampletests](https://github.com/totten/org.civicrm.exampletests).
- Read [PHP Unit Manual: Writing Tests for
PHPUnit.](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html)
- Review the example code in
[org.civicrm.exampletests](https://github.com/totten/org.civicrm.exampletests)
To run the tests see the instructions [for running PHPUnit tests](/testing/phpunit.md#running-tests).
To run the tests see the instructions
[for running PHPUnit tests](/testing/phpunit.md#running-tests).
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment