Skip to content
Snippets Groups Projects
Commit 181ab1e3 authored by Erich's avatar Erich Committed by GitHub
Browse files

Merge pull request #4 from civicrm/master

merge from core
parents ac17ad83 5dc77d8c
No related branches found
No related tags found
No related merge requests found
# CiviCRM developer documentation
# CiviCRM Developer Guide
```bash
git clone https://github.com/civicrm/civicrm-dev-docs
cd civicrm-dev-docs
mkdocs serve
```
- [Read published version](http://docs.civicrm.org/dev/en/master)
- [Learn how to edit](https://docs.civicrm.org/dev/en/master/documentation/#how-to-edit)
This will likely be merged with the `civicrm-core` repo at some point.
# See also
* Download mkdocs: http://mkdocs.org/
* Browse published dev docs: http://docs.civicrm.org/dev/en/master
* Review general info about CiviCRM docs: https://github.com/civicrm/civicrm-docs
This Developer Guide will likely be merged into the
[civicrm-core](https://github.com/civicrm/civicrm-core/) repo at some point.
\ No newline at end of file
# Advanced patterns
[]( FIXME remove this banner after review)
>> NOTE: Some of these instruction maybe deprecated and superceded by better
>> approaches.
## Web Services
There are three options to create an ajax or web-service callback:
- **Full control:**Add a basic page. Remove the parent::run() call
from the run() function, and at the bottom of the run() function,
perform your own output (eg "*echo json\_encode($data)*") and then
short-circuit processing (eg "*CRM\_Utils\_System::civiExit()*") so
that neither Smarty nor the CMS modify the output.
- **Using ajax helpers (CiviCRM 4.5 and above**): Generate a page with
civix as above. Build your data in the run() function. If the
client-side request includes *snippet=json* in the url, just append
your data to *$this-\>ajaxResponse* array and the rest will happen
automatically. If not, you can directly call
CRM\_Core\_Page\_AJAX::returnJsonResponse() at the bottom of the run
function. See [Ajax Pages and
Forms](/confluence/display/CRMDOC/Ajax+Pages+and+Forms)
documentation.
- **Using the API:** Add an API function using `civix`.
The API function can be called with the API's [AJAX
Interface](http://wiki.civicrm.org/confluence/display/CRMDOC/AJAX+Interface).
This automatically handles issues like encoding and decoding the
request/response.
## Standalone PHP scripts
Instead of creating a standalone script, consider one of these options:
- Add an API function (using the instructions above). The API function
can be called many different ways – cv, PHP, REST, AJAX, CLI, Drush,
Smarty, cron, etc. CiviCRM used to include a number of standalone
scripts – many of these have been migrated to API functions because
this approach is simpler and more flexible.
- Add a basic page (using the instructions above). At the bottom of
the run() function, call "*CRM\_Utils\_System::civiExit()*" to
short-circuit theming and CMS processing.
Creating a pure standalone PHP script is a tricky proposition and likely to be
brittle compared with the above.
If the script is truly standalone and
does not require any services from the CRM or CMS, then you can just add a
new `.php` file to the extension... but it won't have access to CiviCRM's
APIs, databases, classes, etc. If the standalone script needs those
services, then it will need to ***bootstrap*** CiviCRM and the CMS. This
is challenging for several reasons:
- The bootstrap mechanics are different in each CMS (Drupal, Joomla,
etc).
- The bootstrap mechanics are different for single-site installations
and multi-site installations
- To initiate a bootstrap from a script, one needs to determine the
local-path to the CiviCRM settings. However, the local-path of the
script is entirely independent of the local-path to the settings –
these are determined at the discretion of the site administrator.
If you really need to do it, it's theoretically possibly to emulate an
example like
"[bin/deprecated/EmailProcessor.php](http://svn.civicrm.org/civicrm/branches/v4.1/bin/deprecated/EmailProcessor.php)".
The results will likely be difficult for downstream users to
install/use.
## Cron jobs
One can add an API function (using the instructions above) and create a
schedule record. In CiviCRM 4.3, the schedule record can be
automatically created; to do this, call "civix
[generate:api](http://generateapi)" with the option "–schedule Daily"
(or "-schedule Hourly", etc). CiviCRM will make a best-effort to meet
the stated schedule.
In CiviCRM 4.2, one can use APIs as cron jobs, but the schedule record
won't be created automatically. The site administrator must manually
insert a scheduling record by navigating to "Administer =\> System
Settings =\> Scheduled Jobs".
......@@ -14,8 +14,41 @@ This section covers how to write extensions. See the [extension life cycle
page](/extend-stages) for background on the publishing and review process for
[published extensions](https://civicrm.org/extensions).
## Extension Names
All extension names follow the same convention as Java package names – they
look like reversed domain names. (e.g. `com.example.myextension`). For
module-extensions, the last word in the module name will be the module's
*short-name*. The short-name *must* be unique. It is possible to pick a
different short-name, but that requires extra work.
## Pre-Requisites
- Have basic knowledge of PHP, Unix, and object-oriented programming
- Install ***civix v14.01*** or newer. For instructions, see
[https://github.com/totten/civix/](https://github.com/totten/civix/)
. This wiki page assumes that "civix" is installed and registered in
the PATH.
- Configure an extensions directory. For instructions, see
[Extensions](http://wiki.civicrm.org/confluence/display/CRMDOC/Extensions).
This wiki page assumes the directory is "/var/www/extensions", but
you should adapt as appropriate.
Your extensions directory must be under the CMS root directory so
that civix can find and bootstrap the CMS. Otherwise, it will fail
with an error like "Sorry, could not locate bootstrap.inc" on most
operations.
- The user account you use to develop the module must have permission
to read all CMS files, including configuration files, and write to
the extensions directory.
For example, Debian's drupal7 package saves database configuration
to /etc/drupal/7/sites/default/dbconfig.php, which is only readable
by the www-data user. You will need to make this file readable by
your development user account for civix to work.
## General overview
[]( fixme paragraph this section into above notes )
If you haven't already, you need to configure a local directory to store
extensions.
For instructions, see
......
Coming soon!
# Civix
>> ![information](../img/info.png)
Note: This page started
[here in the wiki](https://wiki.civicrm.org/confluence/display/CRMDOC/Create+a+Module+Extension).
We have not yet transferred all of the script snipets, so you may wish to
peruse this page as well.
## Introduction
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/).
In order to verify that all your configuration is correct ping CiviCRM 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.
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.:
```bash
civix help civicrm:ping
```
## Generating a skeletal extension
To generate a skeletal extension module, we will use `civix generate:module`
and pass in the name for our extension. See [here](./basics/#extension-names)
for details of naming conventions.
Start with:
```bash
cd $YOUR_EXTENSIONS_DIR
civix generate:module --help
```
Then use a command like this:
```bash
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](./files).
The command attempts to autodetect 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](http://wiki.civicrm.org/confluence/display/CRMDOC/Extension+Reference).
Now that you have created your extension, you need to activate it by navigating
to:
**Administer » System Settings » Manage Extensions**
or
**Administer » Customize Data and Screens » Manage Extensions.**
For more detailed instructions, see
[Extensions](http://wiki.civicrm.org/confluence/display/CRMDOC/Extensions).
## Add features
There are many different features that you can add to a module-extension
at your discretion. A few possibilities:
### Add a basic web 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:
```bash
civix generate:page --help
```
Generally you will only need to supply the PHP class name and web-path,
for example:
```bash
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/docsv2/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.
>> ![information](../img/info.png)
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.
**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](/confluence/display/CRMDOC/In-Place+Field+Editing) API.
### Add a basic web form
>> ![danger](../img/danger.png)
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](/confluence/display/CRMDOC/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".
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
```
This creates three files:
- `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](http://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference).
- `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/docsv2/en/).
The auto-generated code for the controller and view demonstrate a few
basic operations, such as adding a <SELECT\> element to the form.
>> ![information](../img/info.png)
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 database upgrader, installer and uninstaller
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 arguements:
```bash
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.
- 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.
>> ![information](../img/info.png)
The "upgrader" class is a wrapper for
[hook\_civicrm\_upgrade](/confluence/display/CRMDOC43/Hook+Reference)
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.
>> ![danger](../img/danger.png)
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](http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference).
This allows your triggers to coexist with triggers from other modules.
### Add a 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.
Once again `civix` will give the details of options and arguments with this
command:
```bash
civix help generate:case-type
```
This reports that civix expects a <Label> argurment and an optional name:
```bash
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](/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 exends 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:
>> ![information](../img/info.png)
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:
```bash
civix help generate:custom-xml
```
So to created your XML for a custom data group ID of 7:
```bash
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)).
#### Extending an subtype
<!-- This section still is not really clear to me.
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
### Add a hook function
CiviCRM
[hook functions](http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference)
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
/**
* Implementation of hook_civicrm_post
*/
function myextension_civicrm_post($op, $objectName, $objectId, &$objectRef) {
switch ($objectName) {
case 'Contribution':
$file = '/tmp/contributions.log';
$message = strtr("Performed \"@op\" at @time on contribution #@id\n", array(
'@op' => $op,
'@time' => date('Y-m-d H:i:s'),
'@id' => $objectId,
));
file_put_contents($file, $message, FILE_APPEND);
break;
default:
// nothing to do
}
}
```
>> ![information](../img/info.png)
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](http://wiki.civicrm.org/confluence/display/CRMDOC/Resource+Reference).
### Add a 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.
To to see the available report generation options acitivate the `civix` help:
```bash
civix generate:report --help
```
To create a new report specify the report PHP class name and the CiviCRM component, for example:
```bash
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](http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference)
and the
[API](http://wiki.civicrm.org/confluence/display/CRMDOC/API+Reference).
- `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](http://wiki.civicrm.org/confluence/display/CRMDOC/CiviReport+Reference).
- `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
```
### Add a custom search
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:
```bash
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](http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference)
and the
[API](http://wiki.civicrm.org/confluence/display/CRMDOC/API+Reference).
- `CRM/Myextension/Form/Search/MySearch.php` contains the
form-builder and query-builder for the custom search.
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.
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.
### Add an API function
The [CiviCRM API](../api/general)
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:
```bash
civix help generate:api
```
>> ![information](../img/info.png)
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.
You can make your API code with a command in this pattern:
```bash
civix generate:api NewEntity NewAction
```
This creates one file:
- `api/v3/NewEntity/NewAction.php` provides the API function.
that the parameters and return values must be processed in a
particular way (as demonstrated by the auto-generated file).
<!-- fixme - clarify is this 4.3 and later? -->
For use with CiviCRM 4.3, 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.
### Add a new entity
>> ![danger](../img/danger.png)
This functionality is considered "experimental and incomplete".
You may have a need to create a new entity that does not exist in
CiviCRM. For this, you can use the command `civix generate:entity`
- Pick a name for your entity. In some places, CiviCRM expects a
*FirstLetterCapitalizedName*, in others, an *underscore\_name*. Be
absolutely consistent in your naming, because CiviCRM needs to
translate between those two naming conventions.
- Run `civix generate:entity <name of entity>` (entity name should be
FirstLetterCapitalized here). This creates a skeletal file for your
XML schema, your BAO, and your API. It does NOT create a skeletal
SQL file to create your table or DAO files at this time.
- Edit the XML schema in the "xml" folder to match the fields you
want. Minimal documentation is available
[here](https://wiki.civicrm.org/confluence/display/CRMDOC/Database+Reference),
but you are better off looking at the [existing XML
schemata](https://github.com/civicrm/civicrm-core/tree/master/xml/schema).
- Create a DAO file. For now, civix does not handle this. You can
create this by hand. Alternatively, use [this
technique](http://civicrm.stackexchange.com/a/3536/12). Copy your
XML schema into a development copy of CiviCRM. Edit Schema.xml to
include your XML file, then from the xml folder, run
`php ./GenCode.php` (In CiviCRM 4.7.12+, run
`<civiroot>/bin/setup.sh -g` instead). This will generate a DAO file
for you in the CiviCRM core code; copy it into the
CRM/<Entityname\>/DAO folder of your extension.
- Currently, `civix` does not generate the SQL to create and
drop your table(s). You can create these by hand, or, if
you used the `<civiroot>/bin/setup.sh -g` technique to create your
DAO, SQL will have been generated for you in
`<civiroot>/sql/civicrm.mysql`. Once you have the SQL statements for
creating and dropping your SQL tables, create
`auto_install.sql` and `auto_uninstall.sql`
respectively in your 'sql/' folder. CiviCRM will run them
automatically on install if you generated an upgrader. Note that
using `auto_install.sql` and `auto_uninstall.sql`
is not best practice if you have multiple statements in each file,
since you cannot error check each statement separately.
<!-- fixme update and clarify -->
- Run `civix generate:upgrader` from within your extension.
- Define your entity using
[hook\_civicrm\_entityTypes](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes).
### Add a unit-test class
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.
>> ![information](../img/info.png)
Before preparing unit-tests with extensions, you must first
[configure you personal testing sandbox](/confluence/display/CRM/Setting+up+your+personal+testing+sandbox+HOWTO) and enable your extension on the sandbox.
Explore the full options with:
```bash
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*:
```bash
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).
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:
- 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)
>> ![danger](../img/danger.png)
The following instructions are deprecated. Updated instructions coming soon.
```bash
# Check if civix can connect to the civi api
civix civicrm:ping
# Look at your current config
civix config:get
# Tell civix where to read the civicrm.settings.php
# EG. For Drupal
civix config:set civicrm_api3_conf_path /your/path/to/sites/default
```
To run this test-class, change to your extension folder and call "civix
test":
```bash
civix test CRM_Myextension_MyTest
```
Coming soon!
# Extension files
The [civix](./civix) command line tool will generate the following structure
for you:
- ***info.xml*** is a manifest that describes your extension – the
name, license, version number, etc. You should edit most information
in this file.
- ***myextension.php*** stores source code for all your hooks. It
includes a few default hook implementations which will make
development easier. You can add and remove hooks as you wish. (Note:
This file name is different in each module – it is based the
module's *[short-name](./basics/#extension-names)*.)
- ***myextension.civix.php*** contains auto-generated helper
functions. These deal with common problems like registering your
module in the template include-path. `civix` may automatically
overwrite this file, so generally do not edit it.
In addition, it creates some empty directories. These directories are
reminiscent of the directory structure in CiviCRM core:
- ***CRM/Myextension/*** stores PHP class files. Classes in this
folder should be prefixed with "CRM\_Myextension\_"
- ***templates/*** stores Smarty templates
- ***xml/*** stores XML configuration files (such as URL routes)
- ***build/*** stores exportable .zip files
# Troubleshooting
If you are struggling, the best thing to do is reach out to the
[CiviCRM community](../basics/community).
If you cannot find the answer in this guide or by searching in the
[CiviCRM StackExchange site](http://civicrm.stackexchange.com/)
then please [ask](http://civicrm.stackexchange.com/questions/ask). Asking
questions on StackExchange not only helps you but may well help others who
follow you.
That said, this is a small list of some of the commoner problems extension
writers encounter.
## Extension not doing anything
[]( ###### arguably this list should be removed altogether?? #### )
Q: I've created the files and edited them but I don't see the expected
changes.
A: Did you install and enable your extension?
(<site\>/civicrm/admin/extensions?reset=1)
## Civix error messages
Q: I get Error: "Cannot instantiate API client -- please set connection
options in parameters.yml"
A: You might have missed the step about setting
'civicrm\_api3\_conf\_path'
([https://github.com/totten/civix/](https://github.com/totten/civix/)),
or it didn't get set properly for some reason.
Q: I've tried to generate a page/report/search/upgrader/etc with civix
but it's not working.
A: For all of the various types, you must first run
[generate:module](http://generatemodule), and then \`cd\` into the
folder (e.g. com.example.myextension) before running one of the
other \`generate:\` commands.
docs/img/check.png

1.14 KiB

docs/img/danger.png

1.09 KiB

docs/img/info.png

871 B

# CiviCRM Developer Guide
!!! warning "Notice"
This guide is not yet complete.
As of early 2017 we are actively working to migrate content in from the
[wiki]. Read more about this [migration process][migration], including how
to help out!
[wiki]: http://wiki.civicrm.org/confluence/display/CRMDOC/Develop
[migration]: https://wiki.civicrm.org/confluence/display/CRMDOC/Content+migration+from+wiki+to+Developer+Guide
[CiviCRM](https://civicrm.org) is an open-source application. The code can be
poked, prodded, twisted, and hacked. It can be customized, extended, and
collaboratively developed. This documentation tells you how to do that.
......@@ -23,39 +33,4 @@ for use by people that are familiar with CiviCRM development.
for specific details on editing this documentation (and others using
mkdocs). You can also learn how to read these docs off-line!
## Migration of content is in progress
As of early 2017 we are actively working to migrate content from the [wiki] to
this guide. Read more about this [migration process][migration], including how
to help out!
[wiki]: http://wiki.civicrm.org/confluence/display/CRMDOC/Develop
[migration]: https://wiki.civicrm.org/confluence/display/CRMDOC/Content+migration+from+wiki+to+Developer+Guide
## Other sources of information
As an open-source project, CiviCRM is managed by an international community of
developers and activists. Help from these people can be found in the following
ways:
- Our [chat rooms](https://chat.civicrm.org/) and
[mailing lists](http://lists.civicrm.org/lists/info/civicrm-dev) are great
places to say hello and discuss CiviCRM issues with others.
- If you need help, your best bet is probably our
[stack exchange Q+A site](http://civicrm.stackexchange.com/).
- If you've identified a problem, you can file issues on our
[issue](http://issues.civicrm.org/) on our issue tracker or fix the issue
and submit a pull request on
[Github](https://github.com/civicrm/civicrm-core/).
- If you've written an extension, please share it in our
[extensions directory](https://civicrm.org).
- Use the [wiki](http://wiki.civicrm.org/confluence/display/CRM/CiviCRM+Wiki)
to share drafts, notes, and specs.
- And don't forget you are always welcome to come to a
[real world event](https://civicrm.org/events) like a conference meet-up
or sprint.
$(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
);
}
});
......@@ -32,10 +32,17 @@ platforms.
## Hyperlinks
- A basic hyperlink
- A basic hyperlink (in a sentence)
Try [CiviCRM](https://civicrm.org) for your database.
- An internal hyperlink on mkdocs (4 different ways that all work)
[extensions](/extensions/basics)
[extensions](/extensions/basics.md)
[extensions](extensions/basics)
[extensions](extensions/basics.md)
- With long URLs, the following syntax is better.
See [this issue][CRM-19799] for more details.
......@@ -85,7 +92,10 @@ This is a second.
#### Heading 4
```
Alternate syntax (only works for h1 and h2):
The above syntax is [called](http://pandoc.org/MANUAL.html#headers)
"ATX style headers" in markdown terminology, and is preferred my most.
An alternate syntax called "setext style headers" works for h1 and h2 as
follows:
```md
Heading 1
......@@ -272,7 +282,43 @@ mkdocs**:
- More list items
````
## Admonitions
### Types
!!! note
I am a "note" admonition.
!!! tip
I am a "tip" admonition.
!!! warning
I am a "warning" admonition.
!!! danger
I am a "danger" admonition.
Other types
- "hint", "important" (visually identical to "tip")
- "attention", "caution" (visually identical to "warning")
- "error" (visually identical to "danger")
### Syntax
Simple example:
```md
!!! note
This feature is only available as of CiviCRM 4.5.
```
Add a custom title (make sure to quote the title):
```md
!!! danger "Don't try this at home!"
Stand back. I'm about to try science!
```
## Images
......
......@@ -3,6 +3,10 @@ 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
markdown_extensions:
- markdown.extensions.admonition
pages:
- Home: index.md
- Basics:
......@@ -25,8 +29,10 @@ pages:
- All Available Hooks: hooks-db.md
- Writing Extensions:
- Basics: extensions/basics.md
# - civix: extensions/civix.md
# - Anatomy of Files: extensions/files.md
- Using civix: extensions/civix.md
- Anatomy of Files: extensions/files.md
- Advanced Patterns: extensions/advanced.md
- Troubleshooting: extensions/troubleshooting.md
# - Using hooks: extensions/using-hooks.md
# - Customizing Screens: extensions/customize-screens.md
# - Creating Pages: Forms/extensions/create-page.md
......
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