Skip to content
Snippets Groups Projects

Compare revisions

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

Source

Select target project
No results found

Target

Select target project
  • documentation/docs/dev
  • totten/dev
  • bgm/dev
  • ivan_compucorp/dev
  • seamuslee/dev
  • artfulrobot/dev
  • ufundo/dev
  • wmortada/dev
  • lucky091588/dev
  • DaveD/dev
  • jtwyman/dev
  • rukkykofi/dev
  • JonGold/dev
  • jaapjansma/developer-docs
  • alainb/dev
  • noah/dev
  • justinfreeman/dev
  • pradeep/dev
  • larssg/dev
  • eileen/dev
  • darrick/dev
  • mattwire/dev
  • colemanw/dev
  • homotechsual/dev
  • JoeMurray/dev
  • maynardsmith/dev
  • kurund/dev
  • rocxa/dev
  • AllenShaw/dev
  • bradleyt/dev
  • chrisgaraffa/dev
  • martin.w/dev
  • herbdool/dev
  • MattTrim1/dev
  • Detlev/dev
  • ErikHommel/dev
  • brienne/devdocs
  • pminf/dev
  • SarahFG/dev
  • ayduns/dev
  • JKingsnorth/dev
  • ginkgomzd/dev
  • nicol/dev
  • almeidam/dev
  • arthurm/dev
  • damilare/dev
  • semseysandor/dev
  • major/devdocs
  • usha.makoa/dev
  • yurg/dev
  • shaneonabike/dev
  • andie/dev
  • mmyriam/dev
  • gngn/dev
  • florian-dieckmann/dev
  • jade/dev
  • luke.stewart/dev
  • vinaygawade/dev
58 results
Show changes
Showing
with 1362 additions and 1318 deletions
......@@ -14,7 +14,7 @@ other technologies (such as PHP and Git, which are not CiviCRM-specific) are out
- **PHP** - the main programming language in which CiviCRM is written.
- [Language reference](http://php.net/manual/en/langref.php)
- **Git, GitHub, and GitLab** - Git is a version control system for tracking changes to source code. GitHub and GitLab are web-based tools which host git repositories and issue-tracking systems.
- See [our recommended external resources](/tools/git.md#resources)
- See [our recommended external resources](../tools/git.md#resources)
- **Command line / bash** - in general, "the command line" refers to using a text-only interface to run programs such as `civix`, `git`, and many more. Bash is the most common "shell" program used to execute these commands on Unix computers (i.e. Linux and OS X).
- [Unix command line tutorial](http://www.ee.surrey.ac.uk/Teaching/Unix/)
- *Microsoft Windows has a command line shell which functions very differently from bash. While developing CiviCRM on Windows is possible, it will be a slightly more uphill battle, for this reason and others.*
......
# How to contribute
This chapter assumes that you have identified a bug or improvement for CiviCRM where the best resolution is to [write and contribute code to core](/core/hacking.md).
This chapter assumes that you have identified a bug or improvement for CiviCRM where the best resolution is to [write and contribute code to core](hacking.md).
!!! note
This chapter will refer to a number of resources that are explained in greater depth in the [Developer Community](/basics/community.md) chapter.
This chapter will refer to a number of resources that are explained in greater depth in the [Developer Community](../basics/community.md) chapter.
## Create an issue
Creating a good issue is an important first step and often involves research, discussion, and thoughtful description. Identify your "use case" and share the budget and/or skills you plan on contributing.
[Following these comprehensive steps](/tools/issue-tracking.md#guidelines) to create your issue.
[Following these comprehensive steps](../tools/issue-tracking.md#guidelines) to create your issue.
## Document your change
Your changes might require documentation updates. Read about [when to document](/documentation/index.md#when) and [how to document](/documentation/index.md#contributing) and follow steps as necessary.
Your changes might require documentation updates. Read about [when to document](../documentation/index.md#when) and [how to document](../documentation/index.md#contributing) and follow steps as necessary.
## Write tests
Before you write any code you should write tests. You can use your plain-language description of how things should work to create automated tests for the feature.
CiviCRM comes with a variety of [testing tools](/testing/index.md) that help ensure that changes don't break existing functionality. Since CiviCRM [doesn't release code with failing tests](/tools/jenkins.md), your bug or improvement must not be covered in the existing tests. Maybe there are incomplete tests, maybe the tests aren't valid measures of the functionality, or maybe your feature lacks test coverage. Either way, you will need to write them to make sure your work doesn't get undermined by future changes.
CiviCRM comes with a variety of [testing tools](../testing/index.md) that help ensure that changes don't break existing functionality. Since CiviCRM [doesn't release code with failing tests](../tools/jenkins.md), your bug or improvement must not be covered in the existing tests. Maybe there are incomplete tests, maybe the tests aren't valid measures of the functionality, or maybe your feature lacks test coverage. Either way, you will need to write them to make sure your work doesn't get undermined by future changes.
Use your documentation to identify tests that can be run, and then write them. If you are adding functionality, you may not have the code that the test will call, but you can write your tests as if all the pages and functions exist, defining them later.
......@@ -33,21 +33,21 @@ The key in making changes is legibility: helping others see what you've changed
### Coding style
One element of legibility is literal: make your changes according to the [CiviCRM coding standards](/standards/index.md). This doesn't just make the code more readable on its own; standards make the `diff` more legible too.
One element of legibility is literal: make your changes according to the [CiviCRM coding standards](../standards/index.md). This doesn't just make the code more readable on its own; standards make the `diff` more legible too.
Each pull request is [automatically tested](/tools/jenkins.md) by `PHP_CodeSniffer` according to [the standards](https://github.com/civicrm/coder), and you should save time and test your code yourself.
Each pull request is [automatically tested](../tools/jenkins.md) by `PHP_CodeSniffer` according to [the standards](https://github.com/civicrm/coder), and you should save time and test your code yourself.
### Making commits
Follow these steps to [make high-quality commits](/tools/git.md#committing).
Follow these steps to [make high-quality commits](../tools/git.md#committing).
Once you've completed the work, revisit your documentation and tests to see if you've missed anything.
## Open a pull request
Read about [creating a pull request](/tools/git.md#pr) which includes information on writing a good subject line and minding the scope of your PR.
Read about [creating a pull request](../tools/git.md#pr) which includes information on writing a good subject line and minding the scope of your PR.
Once you submit your pull request, CiviCRM's [Jenkins server](/tools/jenkins.md) will build a copy of CiviCRM and run tests against it, beginning with `PHP_CodeSniffer`. If tests fail, you will be able to follow a link to view details.
Once you submit your pull request, CiviCRM's [Jenkins server](../tools/jenkins.md) will build a copy of CiviCRM and run tests against it, beginning with `PHP_CodeSniffer`. If tests fail, you will be able to follow a link to view details.
Other developers may comment on your code, raising questions or concerns or marking the changes as approved. This is fine, but it is important not to hide important discussion. If substantive discussion occurs in a pull request which has a separate ticket, make note of the discussion in the ticket. If a pull request is closed in favor of another, explain that in the ticket and mention the old pull request in the new one.
......@@ -57,12 +57,12 @@ The goal is that the next person working on this feature area shouldn't have to
While your pull request is reviewed, and even after it is merged, you will need to maintain your code on the site that needed the changes. There are two main techniques for this.
First, you can keep your `civicrm` directory under version control, including your changes there. If you need to upgrade while your changes are still in review, [rebase](/tools/git.md#rebase) your changes on top of the new version.
First, you can keep your `civicrm` directory under version control, including your changes there. If you need to upgrade while your changes are still in review, [rebase](../tools/git.md#rebase) your changes on top of the new version.
Alternatively, you can use a custom PHP or template override directory. While this is generally discouraged for long-term customizations of your site (extensions are better), it can be an efficient way to track short-term overrides. Just declare the path to the custom PHP and template folders in the Administer - System Settings - Directories page and copy your changed file(s) there, placing them under the same directory structure as within the `civicrm-core` repository. Note the issue number and pull request in a comment at the top of each file, and remember to check the directory each time you upgrade. Once your change is merged, just delete the override.
## Review some other code
CiviCRM works through the generosity of its users and the organizations that employ them. Now that you have a pull request open (and some experience working with the CiviCRM codebase), why not take some time to [review another pull request](/core/pr-review.md)?
CiviCRM works through the generosity of its users and the organizations that employ them. Now that you have a pull request open (and some experience working with the CiviCRM codebase), why not take some time to [review another pull request](pr-review.md)?
You'll notice that the time you spend reviewing others' code and interacting with the rest of the community will serve you well: you'll be a better CiviCRM developer, and you'll have a better product.
# Core Dependencies (Libraries)
The ***core dependencies*** are the software libraries loaded by `civicrm-core` (and distributed alongside
`civicrm-core`). These include server-side PHP libraries (such as Symfony Dispatcher) and client-side libraries (such
as jQuery).
Core dependencies are organized in two areas: [the newer `composer.json` (*preferred*)](#composer) and [the older
`civicrm-packages.git` (*deprecated*)](#packages).
??? question "How do the _Core Dependencies_ differ from the _Installation Requirements_ or the _Toolchain_?"
The words "dependency" and "requirement" are similar, but the following are technically distinct areas:
* The _core dependencies_ (such as jQuery and Symfony Dispatcher) are libraries that must be loaded by CiviCRM at runtime.
* The [_installation requirements_](https://docs.civicrm.org/installation/en/latest/general/requirements/) (such as PHP and MySQL) are pre-requisites that a system-builder must provide before installing CiviCRM.
* A [_toolchain_](../tools/buildkit.md) is a set of add-on tools (such as `drush` and `phpunit`) used to build the software. These are important for system-builders
and developers, but they are not loaded by CiviCRM at runtime.
This page focuses on the core dependencies (libraries).
<!-- What about npm's `package.json`? This is only used to download some QA tools -- not for core-dependencies. -->
## Principles
??? info "Core dependencies must have broad compatibility..."
They should work with all supported PHP versions and all UF's/CMS's (Drupal 7/8/9/10, WordPress,
Backdrop, Joomla, Standalone).
??? info "Core dependencies may (or may not) be systemically important..."
* __Example 1__: Symfony Dispatcher defines the `EventSubscriberInterface` which appears in CiviCRM developer documentation and downstream
extensions. Changes to Symfony Dispatcher could affect downstream compatibility, so they should be reviewed carefully. This is
systemically important.
* __Example 2__: `marcj/topsort` is only used internally. CiviCRM could update this library without any downstream impact.
This must be assessed on a case-by-case basis.
??? info "Patches to core dependencies should be minimized..."
It is _possible_ to apply our own patches on top of core dependencies (without upstream review). The wisdom of doing
so depends on the severity of the issue and the health of the upstream project.
In general, if upstream is active, then patches should be reviewed, revised, and released in their upstream's workflow.
However, if a patch is critical to compatibility or security, or if upstream is not maintained, then CiviCRM may
apply its own patch (until the issue is resolved upstream).
## Composer.json {:#composer}
[`composer`](https://getcomposer.org/) is the primary tool for managing CiviCRM's _core dependencies_. It is popular for PHP-based projects, and
you'll find ample resources online (such as [official documentation](https://getcomposer.org/doc/) and [unofficial
discussions](https://stackoverflow.com/questions/tagged/composer-php)).
For `civicrm-core`, there are some additional tips and guidelines for how to approach `composer`:
<a id="composer-jscss"></a>
??? info "Composer handles PHP libraries... and also JS/CSS libraries..."
As you may expect, `composer` downloads PHP libraries. In `composer.json`, these appear in the usual section (`"require":...`).
What you may not expect: it also handles JS/CSS libraries. By convention:
* JS/CSS dependencies are declared in `composer.json` underneath `"extra": {"download":{...}}`.
(See also: [civicrm/composer-downloads-plugin](https://github.com/civicrm/composer-downloads-plugin))
* JS/CSS dependencies are downloaded into the folder `bower_components/`.
Historically (circa v4.6), the JS/CSS libraries were downloaded via `node`/`bower`. It was subsequently simplified (circa v5.17) to use a
lighter and more maintainable toolchain. The folder-name was preserved within 5.x for interoperability.
<a id="composer-patches"></a>
??? info "Composer applies patches for third-party libraries..."
Core dependencies sometimes require patches for compatibility or security. When necessary, these patches
are applied via [cweagans/composer-patches](https://github.com/cweagans/composer-patches/). These patches
are declared `composer.json` under `"extra":{"patches":{...}}`
Patches must be identified with an absolute URL. This ensures compatibility with all environments, including
D7-style (*civicrm as main project*) and D8-style (*civicrm as subordinate project*).
Patch URLs should identify immutable content (with some version#, checksum, or UUID). This ensures that
consistency in tests/releases/quality-control.
Here are a few ways to make a suitable URL:
1. Paste the patch into a gist. Use the URL of the raw gist. Or...,
2. Send a PR upstream. Get it approved. Use the URL of the PR-diff. Or...,
3. Get a link to a historical patch-file that was previously bundled into civicrm-core.git. (Not applicable to new patches.)
??? info "CiviCRM might be the _main composer project_ (D7/WP/BD/J)..."
In Drupal 7, WordPress, Backdrop, and Joomla, site-builders do not traditionally run `composer` themselves.
For these environments, `civicrm-core` has its own `composer` project. This means:
* CiviCRM has complete and final discretion in how dependencies are resolved.
* The `composer.lock` from `civicrm-core` is authoritative.
* All options in `composer.json` (such as post-install scripts) are fully respected.
??? info "CiviCRM might be a _subordinate composer project_ (D8/D9/D10)..."
In Drupal 8 (and newer), site-builders typically run `composer` themselves. There is a pre-existing project, and
CiviCRM is usually added into this project:
```bash
cd /var/www/my-drupal-site
composer require civicrm/civicrm-core ...
```
For these environments, `civicrm-core` is subordinate:
* The site-builder has final discretion in how dependencies are resolved.
* The `composer.lock` from `civicrm-core` is ignored.
* Some options in `composer.json` (such as post-install scripts) are ignored.
## CiviCRM-Packages {:#packages}
Since CiviCRM v1.x, the `packages/` folder has stored a collection of manually curated dependencies. The folder
corresponds to a git repository ([`civicrm-packages.git`](https://github.com/civicrm/civicrm-packages/)).
Adding new code to `packages/` is generally deprecated, and many dependencies have switched to `composer.json`.
However, some important dependencies are still tracked in `packages/`.
??? question "Why would a dependency still reside in `civicrm-packages`?"
Each package may be different. Here are a few possible reasons:
1. Nobody has gotten around to converting it.
2. The dependency is no longer maintained by upstream. It is easier to do security and compatibility updates in this repo.
3. The dependency requires special loading rules or special conditions.
4. The dependency's file-path is important. Moving it requires coordination with other repositories/subsystems.
For more information about managing the `packages/` folder, see [civicrm-packages.git:VERSIONS](https://github.com/civicrm/civicrm-packages/blob/master/VERSIONS.php)
......@@ -5,7 +5,7 @@
To help you decide, here are a couple of principles:
- Bug fixes should always be applied to core. See [Contributing to Core](/core/contributing.md) for details.
- Bug fixes should always be applied to core. See [Contributing to Core](contributing.md) for details.
- Some (but not all) enhancements to existing features may be best applied to core, especially if they would be useful to others.
- New features should generally be packed as [Extensions](/extensions/index.md).
- If you aren't familiar with CiviCRM, by far the best way to get a sense if you should be editing core is by [talking with the CiviCRM developer community](/basics/community.md#collaboration-tools).
- New features should generally be packed as [Extensions](../extensions/index.md).
- If you aren't familiar with CiviCRM, by far the best way to get a sense if you should be editing core is by [talking with the CiviCRM developer community](../basics/community.md#collaboration-tools).
# How to review a core pull request
When someone [opens a pull request](/tools/git.md#pr) (aka "PR") on CiviCRM Core, it must be reviewed before we can merge it. Reviewing core PRs is a useful (and often much-needed) way of contributing to CiviCRM. You do not need any special access or merge rights. What you do need, is...
When someone [opens a pull request](../tools/git.md#pr) (aka "PR") on CiviCRM Core, it must be reviewed before we can merge it. Reviewing core PRs is a useful (and often much-needed) way of contributing to CiviCRM. You do not need any special access or merge rights. What you do need, is...
* [GitHub Account](https://github.com)
* A [CiviCRM Development Environment](https://github.com/civicrm/civicrm-buildkit/blob/master/doc/civibuild.md) (this might be optional, but good to have). One benefit is the ability to check out the PR in your environment.
......@@ -50,23 +50,59 @@ Confirm which branch the PR was created against. This is probably either `master
Confirm that the issue was a problem and a problem “worth solving”, generally worthy of being in core.
## Reproduce the fix
## Validate the fix
Confirm that the PR works as advertised by observing the result in the build.
Confirm that the PR works as advertised. Follow some mix of these steps:
You can either test locally or on the test server.
* Use the automatic demo-site
* Review automatic test-results
* Request additional test-results
* Apply the patch locally
### Using the test server to review
### Use the automatic demo-site
Our test server automatically creates a dedicated CiviCRM installation for every PR so that (in most cases) it's easy to review the PR without needing to set up a local installation with the fix applied. To access the test build follow these steps:
Whenever a pull-request is submitted or updated, the test server will create a new demo-site. Civibot will post a link to the "_Online demo of this PR_".
1. In the PR, find the section at the bottom of the page which says "All checks have passed"
1. Go to: "Show all checks" > "Details" > "Console Output" > "Full Log"
1. Search in page for `CMS_URL`
1. The first result should bring you to a URL which points to an installation for the build of this PR.
1. Click on the URL to go to the built site
1. To get login credentials click on "test sites" link from Civibot's (Standard links) comment on the PR
### Reviewing locally
!!! question "What if there are no demo sites?"
The demo may have expired. Demos are usually retained for a few days. But if there is a lot of activity, then it may only be a few hours.
Alternatively, the PR may have a bug that prevents installation.
In either case, proceed to the next step ("_Review automatic test-results_"). It will provide a console log and the option to retry.
### Review automatic test-results
1. In the PR timeline, find the latest commit.
2. Find the status icon (*orange dot, red X, or green checkmark*) and click on it.
3. Drill-down on the "Details".
4. This page shows a list of automatic tasks -- such as building the demo, running low-level unit-tests, running end-to-end tests, and similar.
5. Each task will have a few links available, such as:
* __Statistical summary__: If the test-suite runs normally, it will provide a report of successes and failures.
* __Console output__: Use this to monitor an active job or to identify fatal errors.
* __Retry__: Run the task again. This is useful if the test-results have expired or if the test-server went offline.
### Request additional test-results
By default, the automatic tests include one demo site and a variety of tests. However, deeper tests may be appropriate if:
* The patch involves a CiviCRM integration (such as CiviCRM-Drupal or CiviCRM-WordPress).
* The patch involves low-level code (such as the installer or the bootstrap process).
If you have permission to add labels, then you may request further tests with any of these labels:
| Label | Description |
|--|--|
| `run-backdrop` | Create a demo-site with Backdrop. Run end-to-end tests on Backdrop. |
| `run-drupal-7` | Create a demo-site with Drupal 7. Run end-to-end tests on Drupal 7. |
| `run-drupal-x` | Create a demo-site with Drupal 9/10. Run end-to-end tests on Drupal 9/10. |
| `run-wordpress` | Create a demo-site with WordPress. Run end-to-end tests on WordPress. |
| `run-extended-tests` | Run a comprehensive set of tests, including Backdrop, D7/D9/10, WordPress, and several versions of PHP-MySQL. |
| `run-distmaker` | Create a set of zip-files/tar-files which include the patch. Use these to install locally. |
Every label added will create more outputs and require additional time to complete.
### Apply the patch locally
For more complicated PRs it is sometimes helpful or necessary to manually test them within a local development installation.
......@@ -94,8 +130,8 @@ An easy way to do this is:
## Write a review as a comment
1. Evaluate the change against each of our [review standards](/standards/review.md) criteria.
1. If you like, copy-paste one of the [review templates](/standards/review.md#templates) into your comment and fill out the template.
1. Evaluate the change against each of our [review standards](../standards/review.md) criteria.
1. If you like, copy-paste one of the [review templates](../standards/review.md#templates) into your comment and fill out the template.
* If you choose not to use a template, then summarize your actions and findings, and recommend specific next steps (e.g. merging or otherwise).
1. In your comment, tag [one of the active contributors](https://github.com/civicrm/civicrm-core/graphs/contributors) (e.g. `@eileenmcnaughton`) so they will see that the PR is ready for further action.
# Review/Release Process
Releases are developed on a monthly cycle. At the start of the month, the release-manager will send an invitation to developers who have open PRs, encouraging them to participate in the release-cycle. Participation provides a way to exchange feedback with other developers, get PRs merged, and ensure the next release works -- all with a predictable timeline.
Releases are developed on a monthly cycle, with all but urgent bug and security fixes appearing in versions that are released the first Wednesday of each month. These iterate the second part of the version number. For example, 5.23.0 was released on Wednesday, March 4, 2020, 5.24.0 was released on Wednesday, April 1, 2020, and 5.25.0 was released on Wednesday, May 6, 2020.
* For a high-level summary of the release process, see the [Release Management README](https://github.com/civicrm/release-management/blob/master/README.md).
* For an example invitation, see the previous [invitation for the April-May 2016](https://github.com/civicrm/release-management/issues/1).
There is no active plan to iterate the first part of the version number. The 4.7.x series generally followed the same monthly pattern as above except that the third part of the version number was iterated each month. CiviCRM 5.0.0 followed 4.7.31 in April 2018, and the change was solely for numbering purposes: there is no substantial difference between 5.0.0 and 4.7.31 except for routine changes similar to those introduced every month. The difference from 4.7.31 to 5.0.0 is comparable to that between 4.7.30 and 4.7.31 or that between 5.0.0 and 5.1.0.
During the month, regressions and security vulnerabilities may be fixed in releases that iterate the third part of the version number. Generally speaking, security changes will only be released on the first or third Wednesday of the month, and they will be announced through [the CiviCRM website and a security announcement email list](https://civicrm.org/security). Other point releases may appear at any time.
## Timing
Monthly versions require the participation of a variety of people around the world. While there is no firm time window, and new versions have been released at all times of day, you can typically expect monthly versions to be releases late in the day in the US/Pacific time zone, which may be early Thursday in many parts of the world.
## Branches
The main branch, termed `master`, is where pull requests are typically merged. These changes will appear in the version released up to 2 months in the future.
Each monthly release is based upon a branch of the codebase that is number for the first two parts of the upcoming release number. This is branched off of `master` soon after the prior monthly release and is often termed the "Release Candidate" even though no static, numbered release candidates are generally produced.
After the monthly release, the numbered branch is retained, and any changes that will appear in point releases for that version will be merged there.
Pull requests should typically be made against `master` unless they clearly should appear in the release candidate or a point release. Situations like this usually involve regressions that newly appear in the release candidate or a very recent version. In these cases, it's not uncommon for reviewers or release managers to request two or three pull requests in tandem: one for `master`, one for the release candidate, and potentially one for the most recent release.
## Example release cycle
This system is best illustrated by the 5.24.x release cycle. The `5.24` branch was cut from `master` soon after the 5.23.0 release on March 4, 2020. A number of late changes, including urgent fixes and intra-release-candidate regressions, were merged during March. On April 1, 2020, the first Wednesday of the month, 5.24.0 was released based upon the branch as it stood that day.
Soon thereafter, the `5.25` branch was cut from `master`.
Over the next couple of weeks, a number of urgent bug fixes were merged to `5.24`, and point releases 5.24.1 and 5.24.2 were released on the 4th and 9th of the month, respectively. Security changes were merged to the branch and released on April 15, 2020, the third Wednesday of the month, as 5.24.3. Further urgent bug fixes were merged to the branch and released as 5.24.4, 5.24.5, and 5.24.6 later in the month.
All of these changes were also merged to `master` and `5.25`. On May 6, 2020, the first Wednesday of the next month, 5.25.0 was released based upon the `5.25` branch. No further changes have been merged to `5.24`, and any bugs appearing in the 5.24.x series are to be addressed in later branches and versions. Meanwhile, the `5.26` branch was cut from `master`, denoting the start of the cycle for the release to appear in June.
## Release impact
Despite having a similar numbering pattern, CiviCRM *does not* use Semantic Versioning. Each monthly version may contain any number of bug fixes, new features, deprecations, database schema changes, and API changes. Each may require site administrators to reconfigure features, manually change things prior to or after upgrading, or address problems in past upgrades.
The release notes for each monthly version contain a synopsis to highlight these considerations. The following items are noted for each version:
- **Fix security vulnerabilities?** A new monthly release will not typically fix security vulnerabilities. This is as a courtesy to site administrators so that they won't have the pressure to upgrade for security reasons while potentially facing other changed due to the upgrade. A security release will more commonly contain only the security-specific changes.
- **Change the database schema?** This highlights releases that add or remove database tables, fields, indexes or triggers. The upgrade process will manage these changes, but site administrators with unusual circumstances or direct-to-database integrations will want to take note of these changes.
- **Alter the API?** The API is intended to be a relatively stable way to integrate other systems or build customizations. A change to the API, whether through adding or deprecating entities or methods, altering the output of a method, or changing permissions for a method, will often need more attention than other changes to the software.
- **Require attention to configuration options?** Changes in the CiviCRM code will often require site administrators to revisit configuration settings that would otherwise be left alone. One common example is system workflow message templates: when the standard template for a receipt is changed, any site administrator who has edited their site's copy of the template will need to merge their site-specific changes with the changes between versions. Another is when new permissions are added: a site administrator may need to check that the appropriate users have permission to do a task that may have previously required a different permission.
- **Fix problems installing or upgrading to a previous version?** Site administrators encountering a problem installing or upgrading may use a variety of workarounds. A version that resolves these problems may require the workarounds to be undone. This is also a useful flag for those who encounter problems and revert the upgrade: they can know that their problems may have been addressed.
- **Introduce features?** Most monthly versions introduce new features, which are defined as improvements that go beyond making an existing feature behave the way it purports to.
- **Fix bugs?** Practically all monthly versions and point releases fix bugs.
## Getting your changes documented accurately
Clear documentation multiplies the impact of any improvement in code. If your change is a new feature someone might want to use, you should explain that it's there and how to use it. If you're fixing a bug, you should make it easy for others experiencing it to know that it is fixed in the new version. If your changes require a site administrator's attention just to continue using CiviCRM as they had before, it's imperative that you catch their attention.
At the very least, be sure that the intent and impact of your changes are clear for the editors of the release notes. If you need the attention of site administrators as they upgrade, you should write an upgrade message and/or system check. Finally, the user, system administrator, and developer documentation allow you to explain in-depth how to make use of your changes.
### Descriptions for release notes
The release notes for each monthly version are built upon a list of all commits since the previous monthly version. The editors of the release notes will never be able to follow all changes as they are developed, deliberated, and merged. Instead, they need to be able to understand the effect of each pull request within a minute or two and convey that in the release notes.
In a long ticket, it's sometimes hard to distinguish the initial proposal from what ultimately happened. For the editors, and for their readers who follow the link to read the details, you can't assume they have followed anything that went on. Conversations sometimes split between GitLab and a pull request (sometimes a pull request that gets closed), and sometimes key things are resolved on email or Mattermost conversations, or in person at a sprint.
An accurate title goes a long way. If a pull request fixes a bug, and the title describes the bug concisely, that is completely sufficient. If the title is "Changes to CiviContribute Component Settings not saved", and in fact the bug is that submitting that form does not save the changes, and the fix makes it so that submitting the form saves the changes, that makes for a perfect description.
If the pull request can't be completely described in the title, it's best to add a modifier indicating what details to look for. "Changes to CiviContribute Component Settings not saved for some users" or "Changes to certain fields in CiviContribute Component Settings not saved" both point to the sort of detail that the editors--and anyone skimming the release notes--would want to read more about.
The second key thing is to link all related issues and pull requests. If there's a GitLab issue that the pull request addresses, link to it. If the pull request follows on an earlier, closed one where there was a lot of discussion, link to it. If there are corresponding pull requests for other branches, link to them. The first two provide context for describing the issue or solution. The latter helps the editors be sure that the change is indeed new in that version or already introduced in an earlier point release.
Finally, especially for larger issues, review the pull request and related issue, if there is one, to make sure it's clear what has actually changed. You can edit the pull request or issue description to add a couple sentences, or if you lack permission to do that, you can add a final comment. If the issue is only partially resolved or just has groundwork laid, make it clear what has been done and what has yet to come. You might also consider whether it's appropriate to have a massive issue that will just be partially complete for the foreseeable future: maybe it's better to split it into several.
### Upgrade messages and system checks
If a site administrator might need to do something following the upgrade, add a post-upgrade message. (These are in the version-specific file in the `CRM/Upgrade/Incremental/php` folder.) You may also add a pre-upgrade message, but know that by the time a site administrator sees it, the codebase has already been swapped out. It's not realistic to expect them to revert at that point, so the effect is similar to the post-upgrade messages.
The person applying upgrades will not necessarily be in a position to make configuration changes. Whether they lack the organizational authority or simply lack the context, the person reading a post-upgrade message may not understand something you're describing or may not feel confident doing it. This is separate from something simply being technically confusing: the IT director might run the upgrade but defer to the fundraising officer for managing edits to the online contribution receipt.
Of course, some other site administrators may simply blow past the pre- and post-upgrade messages, and there's no way to go back and view them later.
There are two strategies for addressing these issues. The first is to make the information easy to find and share. Add documentation in the user or administrator guide, a helper extension like Doctor When, or simply in a clear explanation on the issue or pull request. Make the post-upgrade message something straightforward for the person running the upgrade to share with their colleagues.
The second is to assume that many site administrators will ignore the message. Instead, think through the consequences and make sure that the issue is highlighted later through help text, form validation, or a system check.
System checks are a good way to flag problems on a site. When an administrator logs in for the first time in a day or visits the system status page, problems will be visible. You can write a system check that ensures that things are configured properly, and if they are not, administrator users will be reminded.
### User, administrator, or developer documentation
When you add a new feature or resolve a bug in a way that requires some thought on the part of site administrators, writing documentation in the User Guide, System Administrator Guide, or this Developer Guide will help people understand and use it properly.
It's common to open a pull request in a documentation repository and point out that it is dependent upon unmerged changes in the code repository. Add links in both directions, and reviewers can know to merge them together.
# Verify a bug fix
!!! note "See also"
This page is about verifying a fix after it has been merged into CiviCRM core. Also see instructions on [reviewing a core pull request](/core/pr-review.md) to learn how to review fixes *before* they are merged.
This page is about verifying a fix after it has been merged into CiviCRM core. Also see instructions on [reviewing a core pull request](pr-review.md) to learn how to review fixes *before* they are merged.
Suppose you (or some like-minded spirit) [report a bug](/tools/issue-tracking.md#guidelines). With a bit of luck, someone from the community (perhaps a core developer) reproduces the bug, writes a fix, and announces gleefully: "It's fixed! It took four hours, but I did it!" Hooray! Now what? How do you get the fix running on your system? How do you verify that the fix fixed exactly your problem?
Suppose you (or some like-minded spirit) [report a bug](../tools/issue-tracking.md#guidelines). With a bit of luck, someone from the community (perhaps a core developer) reproduces the bug, writes a fix, and announces gleefully: "It's fixed! It took four hours, but I did it!" Hooray! Now what? How do you get the fix running on your system? How do you verify that the fix fixed exactly your problem?
## Step 1. Check the "Fix Version" in JIRA
......@@ -25,7 +25,7 @@ For an example, see [CRM-16501](https://issues.civicrm.org/jira/browse/CRM-16501
## Step 2. Check the proposal status in Github
When a developer prepares a fix for an issue, he submits a proposal ("PR" or "pull-request") via *github.com*. The proposal is evaluated using both [continuous integration](/testing/continuous-integration.md) and peer review. The proposal will have one of three statuses:
When a developer prepares a fix for an issue, he submits a proposal ("PR" or "pull-request") via *github.com*. The proposal is evaluated using both [continuous integration](../testing/continuous-integration.md) and peer review. The proposal will have one of three statuses:
- Open (green): The proposal has not been accepted yet. It's waiting for peer review.
- Merged (purple): The proposal has been accepted.
......
......@@ -5,38 +5,34 @@ To *read* documentation, go to [docs.civicrm.org](https://docs.civicrm.org) for
This page describes the details of the documentation systems within CiviCRM and how to contribute. We also have a more [basic overview](https://docs.civicrm.org/user/en/latest/the-civicrm-community/contributing-to-this-manual/) on how to contribute to this guide or the user guide.
!!! note "Note: the wiki is not covered here"
The [wiki](https://wiki.civicrm.org/confluence/display/CRMDOC/CiviCRM+Documentation) has historically been CiviCRM's documentation system but is being phased out as of 2017. The rest of this page describes MkDocs guides only and does not cover documentation processes that involve the wiki.
The [wiki](https://wiki.civicrm.org/confluence/display/CRMDOC/CiviCRM+Documentation) has historically been CiviCRM's documentation system but has been phased out as of 2017. The rest of this page describes MkDocs guides only and does not cover documentation processes that involve the wiki. No new documentation can be created on the wiki.
## When to document {:#when}
If you are [contributing to core](/core/contributing.md), updating documenting along with your changes is an important step to ensure the long-term usability and maintainability of CiviCRM.
If you are [contributing to core](../core/contributing.md), updating documenting along with your changes is an important step to ensure the long-term usability and maintainability of CiviCRM.
Not all changes require documentation updates. Here are some guidelines:
* Documentation should almost always accompany **new features**.
* Keep in mind that some features are user-facing (and thus require new documentation in the User Guide) whereas some features are *developer*-facing (and thus require new documentation in the Developer Guide.)
* Keep in mind that some features are *user*-facing (and thus require new documentation in the User Guide) whereas some features are *developer*-facing (and thus require new documentation in the Developer Guide.)
* Bug fixes will occasionally require documentation updates. Check existing docs to see what changes might be necessary.
!!! tip
Try writing documentation *before* writing your code! Then you have a way to organize your thoughts and measure whether the feature works.
If you are [submitting a core pull request](/tools/git.md#pr) and would like to submit accompanying doc changes, please provide comments in both pull requests for cross reference. Your docs PR will not be merged until your core PR is merged first.
If you are [submitting a core pull request](../tools/git.md#pr) and would like to submit accompanying doc changes, please provide comments in both pull requests for cross reference. Your docs PR will not be merged until your core PR is merged first.
## Guides in MkDocs
We are using [MkDocs](http://www.mkdocs.org) to produce guides. The content for each of these guides is written in [markdown](/documentation/markdown.md), stored in text files, and hosted in a repository on GitHub. Then, the guides are automatically published to [docs.civicrm.org](https://docs.civicrm.org) using our custom [publishing system](https://github.com/civicrm/civicrm-docs).
We are using [MkDocs](http://www.mkdocs.org) to produce guides. The content for each of these guides is written in [markdown](markdown.md), stored in text files, and hosted in a repository on GitLab. Then, the guides are automatically published to [docs.civicrm.org](https://docs.civicrm.org) using our custom [publishing system](https://lab.civicrm.org/documentation/docs-publisher).
### Versions
In an effort to maintain documentation anchored to specific versions of CiviCRM, some guides store separate versions of the documentation in different *branches* within the repository.
We no longer maintain version specfic documentation, we maintain *evergreen* documentation which always tracks the latest version of CiviCRM but, where appropriate indicates the version that new features and significant changes appeared in. For example:
<!-- TODO: clarify "latest" vs "stable" vs "master" -->
> From CiviCRM version 5.37.0 ReCAPTCHA configuration can be found at **Administer -> Customise Data and Screens -> ReCAPTCHA**. In earlier versions of CiviCRM this lived on the Miscellaneous Settings page.
If you're improving current documentation, please edit the `master` branch, which will be periodically merged into other branches as needed.
In rarer cases, if you have an edit that pertains to a specific version, (e.g. documentation about a feature in an *older* version of CiviCRM, which does not require documentation in the latest version), then please edit the branch corresponding to that version.
If you're improving current documentation, please edit the `master` or `main` branch.
### Languages
......@@ -50,63 +46,67 @@ We welcome contributions, small and large, to documentation!
Before diving into editing, you may find helpful information within the following resources:
- [Markdown syntax](/documentation/markdown.md) - necessary (but simple) syntax to format content
- [Markdown coding standards](/documentation/markdown.md#standards) - recommendations for markdown syntax to use
- [Style guide](/documentation/style-guide.md) - to maintain consistent language and formatting
- [Markdown syntax](markdown.md) - necessary (but simple) syntax to format content
- [Markdown coding standards](markdown.md#standards) - information on the correct markdown syntax to use
- [Style guide](style-guide.md) - to maintain consistent language and formatting
- [Documentation chat room](https://chat.civicrm.org/civicrm/channels/documentation) - live discussion, fast (most of the time) answers to your questions
- [Documentation mailing list](https://lists.civicrm.org/lists/info/civicrm-docs) - low traffic, mostly used for informational updates regarding documentation projects
### Submitting issues
The simplest way to help out is to *describe* a change that you think *should* be made by writing a new issue in the issue queue for the GitHub guide you are reading. Then someone will see your issue and act on it, hopefully fast. Each guide has its own issue queue. First find the GitHub repository for the guide (listed in the above table), then when viewing on GitHub, click on "Issues". You will need an account on GitHub to submit a new issue, but creating one is quick and free.
The simplest way to help out is to *describe* a change that you think *should* be made by writing a new issue in the issue queue for the [lab.civicrm.org](https://lab.civicrm.org/) guide you are reading. Then someone will see your issue and act on it, hopefully fast. Each guide has its own issue queue. First find the lab.civicrm.org repository of the guide, which can be found on their respective documentation guide ([User Guide](https://docs.civicrm.org/user/en/latest/), [SysAdmin Guide](https://docs.civicrm.org/sysadmin/en/latest/), [Developer Guide](https://docs.civicrm.org/dev/en/latest/)) at the right corner of the navigation bar. On viewing lab.civicrm.org, click on "Issues". You will need an account on lab.civicrm.org to submit a new issue, but creating one is quick and free.
### Editing through GitHub
### Editing through lab.civicrm.org
Please see the documentation for editing with Git in the [CiviCRM user guide](https://docs.civicrm.org/user/en/stable/the-civicrm-community/contributing-to-this-manual/#single_changes).
Please see the documentation for editing with Git in the [CiviCRM User Guide](https://docs.civicrm.org/user/en/stable/the-civicrm-community/contributing-to-this-manual/#single_changes).
### Testing locally with MkDocs {:#mkdocs}
The most advanced way to work on a guide is to use git to download all the markdown files to your computer, edit them locally, preview the changes with [MkDocs](http://mkdocs.org/), then use git to push those changes to your personal fork, and finally make a "pull request" on the main repository. This approach makes editing very fast and easy, but does require a bit of setup, and some knowledge of how git works.
1. Obtain the source files for the guide you want to edit
1. Find the repository on GitHub *(see "repository" links above, or the "GitHub" link on the bottom left of screen of the documentation you are reading)*
1. Fork the repository on GitHub.
1. Find the repository on [lab.civicrm.org](https://lab.civicrm.org) *(see the "Lab" link on the top right of screen of the documentation you are reading)*
1. Fork the repository on lab.civicrm.org.
1. Clone *your fork* of the repository to your computer
```bash
git clone https://github.com/YourGitHubUserName/civicrm-dev-docs.git
git clone https://lab.civicrm.org/YourUserName/civicrm-dev-docs.git
cd civicrm-dev-docs
```
1. *(optional)* If you have [Docker](https://www.docker.com/) installed, then at this point you can run one of the following commands and then skip to the "view the guide locally ..." step below.
1. *(optional)* If you have [Docker](https://www.docker.com/) installed, then at this point you can run one of the following commands and then skip to the "View the guide locally ..." step below.
1. For folks who have a full Docker for Windows / Mac / Linux environment, run this command:
```
docker run --rm -v "$PWD":/docs -p 8000:8000 -w /docs seanmadsen/civicrm-docker-mkdocs serve --dirtyreload -a 0.0.0.0:8000
docker run --rm -v "$PWD:/docs" -p 8000:8000 -w /docs "mjcoltd/civicrm-docker-mkdocs" serve --dirtyreload -a 0.0.0.0:8000
```
and skip to the "view the guide" step below.
and skip to the "View the guide" step below. To update this docker image periodically, run the following before the command above.
```
docker rmi mjcoltd/civicrm-docker-mkdocs
```
1. For folks who have a legacy or "Home" operating system (Windows 7, 8.1, 10 Home Premium), the situation is a bit more complex. Follow these steps:
1. For folks who have a legacy or "Home" operating system (Windows 7, 8.1, 10 Home Premium), the situation is a bit more complex. The same is true if you have implemented virtual machines on your system using Oracle VM VirtualBox or VMWare tools. These tools don't play well with native Windows HyperV virtualization. In any case, follow these steps:
1. Check that GitHub folder is in the path: ```c:\Users\<username>\Documents\...```. If it is, all is good; if not, move it there, and edit your GitHub configuration to reflect the changed location.
1. Set up a Docker-Toolbox environment (which depends on Oracle VM Box), and check that it is functioning properly (Hello-world container works).
1. Set up a Docker-Toolbox environment (which depends on Oracle VM VirtualBox), and check that it is functioning properly (Hello-world container works).
1. Review the Docker-Toolbox instance in Oracle VM VirtualBox to ensure that it has the necessary port-forwarding configuration in place. If there is no HTTP port forwarding rule, add one that specifies: Name: HTTP, Protocol: TCP, Host IP: 127.0.0.1, Host Port: 8000, Guest IP (empty), Guest Port: 8000. If this configuration is not present, all attempts to open a browser session will receive a "connection refused" error.
1. Run this command:
```
docker run --rm -v "/c/Users/<username>/Documents/GitHub/civicrm-user-guide:/docs" -p 8000:8000 -w /docs seanmadsen/civicrm-docker-mkdocs serve --dirtyreload -a 0.0.0.0:8000
docker run --rm -v "/c/Users/<username>/Documents/GitHub/civicrm-user-guide:/docs" -p 8000:8000 -w /docs mjcoltd/civicrm-docker-mkdocs serve --dirtyreload -a 0.0.0.0:8000
```
and skip to the "view the guide locally ..." step below.
and skip to the "View the guide locally ..." step below.
1. Install [pip](https://pypi.python.org/pypi/pip) (python package manager)
- OS X: `brew install python`
- Debian/Ubuntu: `sudo apt-get install python-pip python-wheel`
- OS X: `brew install python3`
- Debian/Ubuntu: `sudo apt-get install python3-pip`
1. Install MkDocs, plus the [Material theme](http://squidfunk.github.io/mkdocs-material/) and the [Pygments syntax highlighter](http://pygments.org/).
```bash
sudo pip install mkdocs mkdocs-material pygments pymdown-extensions
sudo pip install mkdocs==1.0.4 mkdocs-material==4.6.3
```
1. Serve a local copy of the guide with MkDocs
......@@ -121,11 +121,11 @@ The most advanced way to work on a guide is to use git to download all the markd
1. View the guide locally in your browser at `http://localhost:8000`.
1. Edit the [markdown](/documentation/markdown.md) with an editor of your choice. As you
1. Edit the [markdown](markdown.md) with an editor of your choice. As you
save your changes `mkdocs` will automatically reprocess the page and
refresh your browser.
1. When you are happy with your edits, use git to commit and push your changes up to your fork. Then submit a pull request on GitHub.
1. When you are happy with your edits, use git to commit and push your changes up to your fork. Then submit a pull request on lab.civicrm.org.
1. `Ctrl`-`C` will stop the MkDocs server.
......@@ -168,7 +168,7 @@ Some guides may have auto-generated content, which is summarized here.
### In the Developer Guide {:#auto-gen-dev}
This Developer Guide has an automatically-generated [list of all hooks](/hooks/list.md). To re-create this list, run the following command from the root level of the repository:
This Developer Guide has an automatically-generated [list of all hooks](../hooks/list.md). To re-create this list, run the following command from the root level of the repository:
```
./bin/tools generate:hooks-list
......@@ -184,8 +184,8 @@ All CiviCRM documentation content is licensed [CC BY-SA 3.0](https://creativecom
This is relevant when you want to copy content *out of* our documentation books.
1. Find the GitHub repository for the book that contains the content you'd like to use. (There will usually be a link to this repository at the top right of ever page.)
2. Navigate to the corresponding markdown file within GitHub (it will match the URL path of the published content).
1. Find the [lab.civicrm.org](https://lab.civicrm.org/) repository for the book that contains the content you'd like to use. (There will usually be a link to this repository at the top right of ever page.)
2. Navigate to the corresponding markdown file within lab.civicrm.org (it will match the URL path of the published content).
3. Click on "Blame" to see detailed information about content authors, line, by line.
### How to display attribution for content migrated *into* our books {:#attributing-imports}
......
......@@ -40,17 +40,17 @@ To maintain some consistency and peace of mind for documentation content editors
Valid examples:
1. `[Buildkit](/tools/buildkit.md)`
1. `[the API](/api/index.md)`
1. `[extension review process](/extensions/lifefycle.md#formal-review)`
1. `[Buildkit](../tools/buildkit.md)`
1. `[the API](../api/index.md)`
1. `[extension review process](../extensions/lifefycle.md#formal-review)`
1. `[section within this page](#that-section)`
1. `![awesome alt text](/images/awesome-screenshot.png)`
1. `![awesome alt text](../../images/awesome-screenshot.png)`
Rules:
* Use links which begin with a forward slash. (The root directory is the `docs` folder.)
* Exception: when you are linking to a section within the current page, use only the fragment which corresponds to that heading (beginning with `#`, as in example 4 above.). (Also consider [specifying a custom heading ID](#custom-heading-ids) to prevent broken links if the heading is later renamed.)
* Your link should point directly to the markdown file in the folder tree, using `..` and/or `filename.md` as appropriate.
* When you are linking to a section within the current page, use only the fragment which corresponds to that heading (beginning with `#`, as in example 4 above.). (Also consider [specifying a custom heading ID](#custom-heading-ids) to prevent broken links if the heading is later renamed.)
* Append `.md` when linking to a page.
* If you are linking to a page which is named `index.md`, then include `index.md` in the path (even though your link will technically still work if you don't).
* If you're linking to a section within a page (other than the current one), then do it as shown in example 3 above (even though some some other variants will also work).
......@@ -62,7 +62,6 @@ Reasons for these internal link standards:
* MkDocs will detect broken links when building books, but only if the links are absolute and end with `.md`.
* Using consistent syntax helps us to more easily find-and-replace links when moving pages.
## Basic inline formatting
| Code | Result | Extension required |
......@@ -155,9 +154,7 @@ line.
>same
>line.
This makes it easy to avoid very long lines in markdown code. As a rule of
thumb, keep your markdown code free of lines longer than 80 characters
where possible.
This makes it easy to avoid very long lines in markdown code however text wrapping is the job of editors and you should not insert non-paragraph line breaks to artificially shorten lines of text. Instead write your text naturally, without regard for line lengths and allow editors to handle text wrapping according to the device and display preferences of their user.
**Double line breaks** create separate paragraphs:
......@@ -568,12 +565,12 @@ Images function mostly the same as hyperlinks, but preceded by an exclamation
point and with alt text in place of the link text.
```
![Alt text](/img/CiviCRM.png)
![Alt text](../img/CiviCRM.png)
```
***Result:***
> ![Alt text](/img/CiviCRM.png)
> ![Alt text](../img/CiviCRM.png)
Note:
......
# Documentation style guide
All CiviCRM guides *(like this Developer Guide)* are intended to provide
high-quality "finished" [documentation](/documentation/index.md)
high-quality "finished" [documentation](index.md)
about CiviCRM. This Style Guide page documents the standards we wish to
uphold to ensure all guides maintain this high level of quality.
......@@ -129,7 +129,7 @@ Alternative Text (ALT Tags) should be included for every image.
### Machine-readable symbols
Machine-readable symbols (e.g. files names, classes, functions, variables, database tables, database columns, commands, etc.) should be formatted either with inline monospace or preformatted code blocks (also in monospace). See the [markdown syntax](/documentation/markdown.md#code) to use for such formatting.
Machine-readable symbols (e.g. files names, classes, functions, variables, database tables, database columns, commands, etc.) should be formatted either with inline monospace or preformatted code blocks (also in monospace). See the [markdown syntax](markdown.md#code) to use for such formatting.
### URLs
......@@ -176,7 +176,7 @@ Below are our preferred spellings of CiviCRM-specific words:
- **developer** - a computer programmer who writes code to improve or extend the functionality, stability or security of CiviCRM
- **core team**
- in the User Guide - *should be avoided* - use "CiviCRM" or "the CiviCRM community"
- in other guides - refers to the [core team](https://civicrm.org/teams/core-team)
- in other guides - refers to the [core team](https://civicrm.org/about/core-team)
### Gender neutrality
......@@ -242,25 +242,7 @@ them in the right direction when they want to know about those tasks.
### Shell Commands in documentation.
When writing shell commands in documentation as examples, for any commands that are expected to be typed out by the user a `$` should be put in front of the command. e.g.
```shell
$ cd ~/buildkit/build/drupal-demo/sites/all/modules/civicrm
$ civibuild create drupal-demo --civi-ver master --url http://localhost:8001
$ hub fork
```
The output of a shell command should not have a `$` prepended. e.g.
```shell
$ git remote -v
origin https://github.com/civicrm/civicrm-core.git (fetch)
origin https://github.com/civicrm/civicrm-core.git (push)
yourusername git@github.com:yourusername/civicrm-core.git (fetch)
yourusername git@github.com:yourusername/civicrm-core.git (push)
```
Authors should also not put any comments within the examples themselves, whereas any comments should go outside of the code block in regular paragraphs. Where possible each command should be its own comment block. When it is crucial for the user to understand the directory in which to run the command, include a separate code block before hand with a `cd` command.
Authors should not put any comments within code examples, any comments should go outside of the code block in regular paragraphs. Where possible each command should be its own block. When it is crucial for the user to understand the directory in which to run the command, include a separate code block before hand with a `cd` command.
!!! tip "Write portable shell commands"
......
......@@ -8,8 +8,8 @@
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](/framework/ajax.md) documentation.
- **Using the API:** Add an API function using `civix`. The API function can be called with the API's [AJAX Interface](/api/interfaces.md#ajax). This automatically handles issues like encoding and decoding the request/response.
- **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](../framework/ajax.md) documentation.
- **Using the API:** Add an API function using `civix`. The API function can be called with the API's [AJAX Interface](../api/v3/interfaces.md#ajax). This automatically handles issues like encoding and decoding the request/response.
## Standalone PHP scripts
......@@ -30,7 +30,7 @@ If you really need to do it, it's theoretically possibly to emulate an example l
## 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.
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](civix.md#generate-api)" 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".
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**.
!!! warning "Deprecation Notice"
The following `civix` functions are deprecated. This page contains archived documentation.
### XML-based Entities & DAOs {:#xml}
**Historical Note:** _Legacy CiviCRM schema entities were defined in `xml` files which were used to generate `DAO.php` classes.
The `civix generate:entity` now generates `.entityType.php` files instead of `xml`, and `civix generate:entity-boilerplate`
is now obsolete. Archived documentation follows:_
If you want your extension to store data in the database, then you will need to create a new entity.
1. Pick a name for your entity.
Make sure to use CamelCase here.
This creates a skeletal file for your XML schema, your BAO, and your API.
1. Edit the [XML schema definitions](../framework/entities/schema-definition.md) that you just generated (in the `xml` folder). Define your desired fields.
1. Generate your [DAO](../framework/codebase.md#dao) and SQL files.
```bash
civix generate:entity-boilerplate
```
You can safely re-run this command after you make changes to your XML schema definition. But if your schema changes require database migrations for existing installations, then you'll need to write a migration manually in addition to re-generating your boilerplate.
1. Generate a database upgrader.
```bash
civix generate:upgrader
```
Even though you're not yet creating any upgrades for your extension, you need to do this step now so that CiviCRM will pick up `auto_install.sql` and `auto_uninstall.sql` later on.
1. Re-install your extension.
```bash
cv ext:uninstall myextension
cv ext:enable myextension
```
Now your entity should be ready to use. Try it out with `cv api4 MyEntity.create` and `cv api4 MyEntity.get`. Then [add some tests](civix#generate-test).
### Add an APIv3 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 CRM.$().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").
Unfortunately Civix can only create v3 apis at the moment. Generally v4 CRUD apis are more useful since they allow your entities to be accessed from search-kit and form-builder. [relevant issue & how to manually add](https://github.com/totten/civix/pull/201)
Get started by accessing the `civix` help:
```bash
civix help generate:api
```
!!! note
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.
!!! note
The API loader is very sensitive to case on some platforms. Be careful with capitalization, underscores and multiword action names. API calls can work in one context (Mac OSX filesystem, case-insensitive) and fail in another (Linux filesystem, case-sensitive).
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 `civicrm_api3_new_entity_newaction()` and the specification function `_civicrm_api3_new_entity_newaction_spec()`. 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:
- `api/v3/NewEntity/Newaction.mgd.php` provides the scheduling record that will appear in the CiviCRM's job-manager.
When calling the API, follow these rules:
- Entity-names are UpperCamelCase
- Action-names are lowersmashedcase
- Other variations may work when you call them. Some docs/explorers may show these in cases which work. However, if you try to do the same in new code, you may get a headache.
For example: `cv api NewEntity.newaction` `civicrm_api3('NewEntity', 'newaction')`
!!! tip
Read more about [APIv4 architecture](../api/v4/architecture.md) for help writing custom APIv4 implementations.
### Add a custom search {:#generate-search}
!!! warning "Deprecation Notice"
You are discouraged from creating new custom searches using this legacy
framework. The focus is now on using [SearchKit](../searchkit/overview.md).
If you do add custom searches be sure to add unit tests and run
them regularly.
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](../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.
!!! tip "Enabling the CustomSearch Extension"
Because custom searches have been relegated to an extension and are no longer a core part of CiviCRM, you will need to require it in your `info.xml`:
```xml
<requires>
<ext>legacycustomsearches</ext>
</requires>
```
#### 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
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.
#### 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
Now you have a working custom search, but how do you make it *do* something *custom*?
If your search extends anything other than contacts you probably
need to add a function to prevent notices like this
```php
/**
* @param CRM_Utils_Sort $sort
* @param string $cacheKey
* @param int $start
* @param int $end
*
* @throws \CRM_Core_Exception
*/
public function fillPrevNextCache($sort, $cacheKey, $start = 0, $end = self::CACHE_SIZE): void {
return;
}
```
See this (extremely outdated) [wiki page](https://wiki.civicrm.org/confluence/display/CRMDOC46/Create+a+Custom-Search+Extension) for more information.
extension's `managed` directory (or when exporting Afforms, `.aff.*` files in the `ang` directory).
4. Afterwards you can optionally adjust the [`update` and `cleanup` settings](../api/v4/managed.md#update-modes) in the generated file.
Example: To export a saved search with all its related search displays and Afforms:
```bash
civix export SavedSearch 12
```
Example: To export an Afform, including its definition and layout files:
```bash
civix export Afform nameOfMyForm
```
Type `civix export -h` for more info about the command.
### Add a basic quickform 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`.
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/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 the CiviCRM user interface (**Administer>System Settings>Cleanup Caches and Update Paths**), in a web browser by visiting `/civicrm/menu/rebuild?reset=1` or, if using Drupal & Drush, by running `drush cc civicrm`.
**Test your knowledge**
A little quiz to test your knowledge:
<iframe src="https://learn.civi.be/wp-admin/admin-ajax.php?action=h5p_embed&id=9" width="608" height="300" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
### Add a Quickform Page {:#generate-form}
!!! caution
The form system (based on QuickForm) is not well documented and the CiviCRM 5.x series have seen a growing number of forms based on Afform. Consider whether creating an Afform could better suit your needs.
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](../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". Do this in the CiviCRM user interface (**Administer>System Settings>Cleanup Caches and Update Paths**), in a web browser by visiting `/civicrm/menu/rebuild?reset=1` or, if using Drupal & Drush, by running `drush cc civicrm`..
**Test your knowledge**
A little quiz to test your knowledge:
<iframe src="https://learn.civi.be/wp-admin/admin-ajax.php?action=h5p_embed&id=10" width="608" height="300" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
### Add a case type {:#generate-case-type}
_This command is now deprecated in favor of exporting a case type as a [managed entity](civix.md#export). Legacy documentation follows:_
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 argument 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](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 a report {:#generate-report}
!!! warning "CiviReport is Deprecated"
CiviReport is being phased out in favor of SearchKit.
You can often achieve what you want to achieve using SearchKit and you should only
generate CiviReports if you have determined SearchKit can't meet your use case.
In some cases you can take advantage of the [alterReportVar hook](../hooks/hook_civicrm_alterReportVar) to adjust the columns, sql, or event rows of an existing report to modify it to suit your needs instead of creating a new report. However, this is generally discouraged as changes to the report could break your extension.
To see the available report generation options activate 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](../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 within 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
```
!!! note
Copying a report like this and modifying it is likely to lead to maintenance issues similar to those related to overriding core files in an extension. In particular, bug fixes or other changes to code that you have copied will not automatically be applied to the copied code your new report. Often a better approach is to extend the class of the core report in your extension, then selectively override its functions. In the functions that you override, if possible run the original code and then just tweak the behaviour afterwards, i.e: at the beginning of `thisFn()`, call `parent::thisFn()` then add your code. For example:
```php
class CRM_myExtension_Form_Report_ExtendContributionDetails extends CRM_Report_Form_Contribute_Detail {
public function from() {
parent::from();
// your code
}
...
}
```
!!! note
To have your extension create an instance of your report template with configurations for columns, groups, filtering, etc. and then put it into the menu system, you need to make an additional entry in the `CRM/Myextension/Form/Report/MyReport.mgd.php` file. The additional entry needs some serialized data that is not easy to code but is easy to lookup for a configured report instance. So manually configure a report instance appropriately on a CiviCRM install running your extension (i.e. go to **Administer > CiviReport > Create New Report from Template**, then configure and save the instance). Then use APIv3 to get the ReportInstance values you need for your .mgd.php entry. Note that you need to specify the return fields as navigation_id is not returned by default. If you are not emailing the report, then the following should be sufficient, substituting the id for your report for 8 below:
```php
$result = civicrm_api3('ReportInstance', 'get', [
'sequential' => 1,
'return' => ["title", "report_id", "name", "description", "permission", "grouprole", "is_active", "navigation_id", "is_reserved", "form_values"],
'id' => 8,
]);
```
Add an additional array entry into your .mgd.php that includes the elements of values array, adding a module entry, eg:
```
[
'module' => 'com.example.myextension',
'name' => 'My Enhanced Contribution Detail',
...
'is_reserved' => 0,
],
```
This diff is collapsed.
# How to document your extension
So you've written an [extension](/extensions/index.md). Awesome! Now you want to add some documentation to help people use it. Great! Maybe you even want some docs for other *developers* working on it too. Very good. This page will help you set up your own documentation *guide* (just like this Developer Guide) for your extension.
So you've written an [extension](./index.md). Awesome! Now you want to add some documentation to help people use it. Great! Maybe you even want some docs for other *developers* working on it too. Very good. This page will help you set up your own documentation *guide* (just like this Developer Guide) for your extension.
!!! summary "Example"
For a fully-featured working example of extensions documentation, look at CiviVolunteer.
??? summary "Example: CiviVolunteer"
For a fully-featured working example of extension documentation we can look at CiviVolunteer.
* Read the published [CiviVolunteer guide](https://docs.civicrm.org/volunteer/en/latest/)
* Inspect the following source code to see how it's made:
......@@ -16,7 +16,7 @@ So you've written an [extension](/extensions/index.md). Awesome! Now you want to
Here are the basic steps (and each one is explained in more detail later on this page.)
1. You use the git repo for your extension to store its documentation.
* You store the content in [markdown](/documentation/markdown.md) files within a `docs` directory in your project.
* You store the content in [markdown](../documentation/markdown.md) files within a `docs` directory in your project.
* You use git branches just like you normally would, with that `docs` directory sitting there in every branch.
* You put one file at the root level of your project, `mkdocs.yml` to configure some of the high-level details of your book.
* You use MkDocs locally to preview your guide.
......@@ -32,25 +32,41 @@ Create a new file called `mkdocs.yml` in the root level of your project with the
```yaml
site_name: Your Extension Name
repo_url: https://lab.civicrm.org/extensions/yourproject
theme: material
pages:
edit_uri: https://lab.civicrm.org/extensions/yourproject_LANGUAGE/-/edit/master
site_description: 'A guide for the Your Extension Name extension.'
site_author: 'J Doe'
theme:
name:
material
nav:
- Home: index.md
markdown_extensions:
- attr_list
- admonition
- def_list
- codehilite
- toc(permalink=true)
- pymdownx.highlight:
guess_lang: False
- toc:
permalink: True
- pymdownx.superfences
- pymdownx.inlinehilite
- pymdownx.tilde
- pymdownx.betterem
- pymdownx.mark
plugins:
- search:
lang: en
```
Replace values on the first two lines with your own. Leave everything else as-is (for now).
Replace values on the first five lines with your own. The property `edit_uri` can be used if your edit URI and project repositor are not in the same place or you want to customise the `edit_uri`.
!!!caution "Edit URIs"
If you define a custom edit URI the documentation system will not adjust it, you must provide the full edit URI. For example providing an `edit_uri` of `https://lab.civicrm.org/extensions/yourproject_ES` will result in errors when editing. You must determine the correct edit URI syntax - for GitLab this is `https://lab.civicrm.org/extensions/yourproject_ES/-/edit/main`
Do not provide `edit_uri` unless you know for certain that you need a different `edit_uri` if in doubt open an issue on the [Docs Books repository](https://lab.civicrm.org/documentation/docs-books). Leave everything else as-is (for now).
## Decide what to do with your README file {:#readme}
......@@ -63,7 +79,7 @@ When creating a docs guide, you have two options for how to deal with your READM
With this option, you basically keep documentation content in the README file, and create an MkDocs guide directly from that file. The content remains on GitHub when people visit your repo, and it also gets published on docs.civicrm.org &mdash; and you only have to edit it in one place. The downside is that you have to fit everything into one page.
1. Make sure you're using [markdown](/documentation/markdown.md) formatting within the README file, and make sure the file is named `README.md`.
1. Make sure you're using [markdown](../documentation/markdown.md) formatting within the README file, and make sure the file is named `README.md`.
1. Create an MkDocs index file which is a symbolic link to your README file:
```
......@@ -84,17 +100,20 @@ With this option you have a very small README file and a separate MkDocs guide w
## Add content
Add some [markdown](/documentation/markdown.md) content in `docs/index.md`.
Add some [markdown](../documentation/markdown.md) content in `docs/index.md`.
You can add more pages by creating more markdown files and specifying these files under `pages` in `mkdocs.yml`.
??? tip "Images"
Your images should be stored in a folder named `img` inside your `docs` folder. E.g. `docs/img/useful_img_showing_stuff.png`.
!!! note
We have [markdown coding standards](/documentation/markdown.md#standards) and a documentation [style guide](/documentation/style-guide.md). Adherence to these rules within your extensions docs is recommended but not required.
We have [markdown coding standards](../documentation/markdown.md#standards) and a documentation [style guide](../documentation/style-guide.md). Adherence to these rules within your extensions docs is not currently required for publishing - it will become required in future.
## Preview your guide
Now you should be able to run `mkdocs serve` from within your project directory to start previewing your content. See [instructions here](/documentation/index.md#mkdocs) to get MkDocs set up.
Now you should be able to run `mkdocs serve` from within your project directory to start previewing your content. See [instructions here](../documentation/index.md#mkdocs) to get MkDocs set up.
## Submit your guide to our publishing system {:#submit}
......@@ -110,17 +129,29 @@ Once your guide is in good shape it's time to get it up on [docs.civicrm.org](ht
```yaml
name: Foo Bar
description: Provides a baz for every contact's bat
category: extension
langs:
en:
repo: 'https://lab.civicrm.org/extensions/foobar'
searchterms:
- provides baz
- every contact's bat
- bat
- baz
- contact
```
* There are lots of other settings you can put here if you want to have multiple languages or versions. Look at `user.yml` as an example of a guide (the User Guide) which takes advantage of all the possible settings.
* But if you want to keep it simple and just have one English edition which points to the `master` branch of your repo, then stick with the above settings.
??? note "Searching extension books."
Soon our docs-publisher will allow filtering/searching extension books this will be based on the values provided for 'tags' above.
1. Adjust `name` and `repo` to your own values
* The `name` you set here will be shown in the list of all guides on [docs.civicrm.org](https://docs.civicrm.org) as well as at the top of every page of your guide. Use whatever **long name** you've chosen for your extension, such as "Foo Bar", or "CiviFoobar". (*Don't* use a fully qualified name like "org.civicrm.foobar" because that wouldn't look so nice to visitors.)
* The `name` you set here will be shown in the list of all guides on [docs.civicrm.org](https://docs.civicrm.org) as well as at the top of every page of your guide. Use whatever **short name** you've chosen for your extension, such as "Foo Bar", or "CiviFoobar". (*Don't* use a fully qualified name like "org.civicrm.foobar" because that wouldn't look so nice to visitors.)
1. For the commit message, write something like "Add new Foobar Guide".
1. Click **Commit changes**.
......@@ -140,13 +171,13 @@ Once your guide's config is up, you can go to the following URL to ask the publi
(where `foobar` is the short name you used for your guide)
Publishing your guide manually is fine at first, but once you update the guide later, you might wish to avoid this extra step. This is why we have automatic publishing...
Publishing your guide manually is fine at first, but once you update the guide later, you might wish to avoid this extra step. This is why we have automatic publishing.
## Set up automatic publishing {:#automatic-publishing}
When you set up automatic publishing, GitLab or GitHub will tell the publishing system when content within your repo has changed, and the publishing system will re-publish your guide as necessary.
https://lab.civicrm.org/documentation/docs-publisher
See the [docs-publisher instructions](https://lab.civicrm.org/documentation/docs-publisher#setting-up-automatic-publishing) for how to set up automatic publishing on GitHub and GitLab.
Now when you make changes to your docs, those changes will be published automatically *and* you'll receive an email notification from the publishing system informing you of the status (including any errors) of the publishing process.
......
# Adding pop-up help text in your extension
In addition to simply adding help text for form fields that you have added in your extension as usual, you can also add to or replace help text for existing form fields in core. To do so, simply add a file in the same directory as the hlp file is found in core, with the name `helpfilename.extra.hlp`.
If you want to append your help text to the existing text, add the htxt to your extra help file as normal. If you want to replace the existing text with your own text, add `override=1` to your htxt, for example: `{htxt id="field_name_id" override=1}...`. This works for both the content of the help text and the title.
\ No newline at end of file
# Writing Extensions
Todo:
<!-- Todo:
- Use APIv3 and hooks. Package code in Civi extensions or CMS extensions (w/trade-offs).
- Create a CiviCRM extension developer's guide to best practices (Nicolas?)
- Create a CiviCRM extension developer's guide to best practices (Nicolas?) -->
## Introduction
**CiviCRM Extensions** are packaged pieces of functionality that extend CiviCRM's out-of-the-box functionality, independent of CMS plaform.
**CiviCRM Extensions** are packaged pieces of functionality that extend CiviCRM's out-of-the-box functionality, independent of CMS platform.
As of CiviCRM version 5.24.0 extensions are also used internally within CiviCRM to organise chunks of functionality that implement a specific feature. These extensions are part of the main CiviCRM repo and sit inside the `ext` folder. It is anticipated that over time more chunks of functionality will be moved into these core extensions, as part of our goal to make the code more readable and maintainable. Core extensions cannot be seen in the extensions UI and the structure is invisible to the end user.
There is not currently a clear guideline as to when a feature should be re-organised into a core extension but one useful guideline is whether it can be fully implemented using the extension framework. In some cases we expect to move code over to an extension over a period of time, as we disentangle the functionality from deeper in the main codebase. While it IS possible to disable a core extension through the API it is not currently a supported configuration and site builders should understand this is at their own risk.
This section covers how to write extensions.
## Extension Names
Pick a unique single word for your extension's name. Note that this name is used throughout the extension's code, e.g. function names, so it should only include characters that can be safely used in that way.
Pick a unique `snake_case` name for your extension. Note that this name is used throughout the extension's code, e.g. function names, so it should only include alphanumeric characters and underscores.
This name should be unique in the [CiviCRM Universe](../tools/universe.md), so check [civicrm.org/extensions](https://civicrm.org/extensions) to ensure the name isn't already in-use.
!!! info "Legacy naming"
Historically, extension names used to follow a convention like Java packages – they looked like reversed domain names. (e.g. `com.example.myextension`), but this is no longer the recommendation.
``` info
Historically, extension names used to follow the same convention as Java package names – they look like reversed domain names. (e.g. `com.example.myextension`), but this is no longer the recommendation.
## Pre-Requisites
- Have basic knowledge of PHP, Unix, and object-oriented programming.
- Install ***civix v14.01*** or newer. For instructions, see [Civix Documentation](/extensions/civix.md/). This page assumes that "civix" is installed and registered in the PATH.
- Configure an extensions directory. For instructions, see [Extensions](https://docs.civicrm.org/sysadmin/en/latest/customize/extensions/#installing-a-new-extension). This 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.
- Install ***civix v14.01*** or newer. For instructions, see [Civix Documentation](civix.md). This page assumes that [civix](./civix.md) is installed and registered in the PATH.
- Configure an extensions directory. For instructions, see [Extensions](https://docs.civicrm.org/sysadmin/en/latest/customize/extensions/#installing-a-new-extension). This page assumes the directory is `/var/www/extensions`and if you are using buildkit then the directory is `/buildkit/build/dmaster/web/sites/default/files/civicrm/ext`, 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.
### 0. Decide
Writing an extension is a great way to implement a new feature – but it may be unnecessary if someone else has already implemented that feature. If you're not sure, you can do a couple things:
Writing an extension is a great way to implement a new feature – but it may be unnecessary if someone else has already implemented that feature. If you're not sure, you can do a couple of things:
- Search the [Extensions Directory](http://civicrm.org/extensions) for an existing extension.
- Post about your planned extension in the [Extensions Channel](https://chat.civicrm.org/civicrm/channels/extensions).
Extensions provide a native, portable way to extend CiviCRM, but there are other ways to extend CiviCRM – such as implementing Drupal modules or Joomla plugins. If you're considering another way, look at the [Add-on Formats](/extensions/packaging.md)
Extensions provide a native, portable way to extend CiviCRM, but there are other ways to extend CiviCRM – such as implementing Drupal modules or Joomla plugins. If you're considering another way, look at the [Add-on Formats](packaging.md)
to help decide.
### 1. Install civix
Some tasks in the process of writing an extension require boilerplate code. To reduce the amount of work required to find, understand, and adapt the boilerplate code, one should install the CiviCRM extension builder, civix. Civix is a command-line tool which generates code for some common development tasks.
Some tasks in the process of writing an extension require boilerplate code. To reduce the amount of work required to find, understand, and adapt the boilerplate code, one should install the CiviCRM extension builder, `civix`. Civix is a command-line tool which generates code for some common development tasks.
> See [https://github.com/totten/civix/](https://github.com/totten/civix/)
> For more information on the boilerplate civix generates for you, in particular the extension manifest file (info.xml), [read on](/extensions/info-xml.md).
> For more information on the boilerplate civix generates for you, in particular the extension manifest file (info.xml), [read on](info-xml.md).
### 2. Develop
To get started with development, one should usually follow the steps in "[Create a Module Extension.](/extensions/civix.md#generate-module)". A module extension is the most flexible type of extension – it can define any mix of new reports, custom search screens, payment processors, and web pages; it can listen for hooks, override page-templates, and more. The coding
To get started with development, one should usually follow the steps in "[Create a Module Extension.](civix.md#generate-module)". A module extension is the most flexible type of extension – it can define any mix of new reports, custom search screens, payment processors, and web pages; it can listen for hooks, override page-templates, and more. The coding
conventions closely resemble those of CiviCRM Core and of CiviCRM-Drupal modules. Module extensions are fully supported in CiviCRM 4.2+.
### 3. Publish
......@@ -49,11 +55,11 @@ The CiviCRM ecosystem is built on the belief that non-profit organizations can s
Extension authors may make their extensions available to the larger CiviCRM community by publishing them in the [Extensions Directory](https://civicrm.org/extensions).
> See: [Publish](/extensions/publish.md)
> See: [Publish](publish.md)
Extensions which undergo a [formal review](/extensions/lifecycle.md#formal-review) may be distributed in-app. Approved extensions can be [installed directly](https://docs.civicrm.org/user/en/master/introduction/extensions/#installing-extensions) into CiviCRM via the user interface, lowering the barrier to entry for many users.
Extensions which undergo a [formal review](lifecycle.md#formal-review) may be distributed in-app. Approved extensions can be [installed directly](https://docs.civicrm.org/user/en/master/introduction/extensions/#installing-extensions) into CiviCRM via the user interface, lowering the barrier to entry for many users.
> See: [Automated Distribution](/extensions/publish.md#automated-distribution)
> See: [Automated Distribution](publish.md#automated-distribution)
## Interacting with core
......@@ -61,11 +67,28 @@ There are a number of ways in which extensions can interact with core. These are
Fully supported methods are:
* [API](/api/index.md)
* [Hooks](/hooks/index.md)
* [`Civi::cache`](/framework/cache.md)
* [API](../api/index.md)
* [Hooks](../hooks/index.md)
* [`Civi::cache`](../framework/cache.md)
* `Civi::$statics`
* [`Civi::settings`](/framework/setting.md)
* [`Civi::settings`](../framework/setting/usage.md)
* Internal Symfony listeners (e.g. `civi.api.resolve`, `civi.api.prepare`)
* Calling core functions that have been given the `@api` doc block annotation
Note that calling other core functions is on a 'buyer beware' basis and it is recommended
you avoid doing so. Some functions are explicitly marked `@internal` but in general you
should assume anything not clearly supported is unsupported.
It may be better practice to take a copy of a function rather than
call the core one if you want the functionality from a core function. If you DO decide
to call a core function that is not explicitly supported you can ensure it won't break
unexpectedly by ensuring it is covered by unit tests and that you run the tests regularly.
See also this [blog post](https://civicrm.org/blog/totten/the-static-is-dead-long-live-the-static) describing the `Civi::` facade in more detail.
### Deprecated Methods
Some methods within the CiviCRM Code base that extension developers have been relying on have now been deprecated:
* `CRM_Core_Error::fatal`
Extension authors should replace fucntion calls with either `throw new CRM_Core_Exception` or `throw new <insert CiviCRM Generated Exception>` or `CRM_Core_Error::statusBounce` if the error is being generated from a form.
This diff is collapsed.
This diff is collapsed.
# Managed Entities
## Introduction
When writing an extension, it's often necessary to insert data when the extension is enabled.
For example, *menu items*, *custom fields* or *option values* all might be needed for the extension to function.
Extensions may also want to ship with preconfigured SearchKit Displays or Afforms.
You'd want these items to be added when the extension is installed, disabled when the extension is disabled, and deleted when the extension is uninstalled.
In some cases you'd also want to allow the end-user to make changes, e.g. adjusting settings for a search display,
but allow them to revert it back to the original state defined by your extension. In other cases, e.g. a reserved
option value, you want the user to be locked out of editing or deleting it, but you do want changes made in your extension code
to update the record in the database, e.g. if you later add a `description` to the option value record.
Managed Entities provide all of this functionality with minimal coding.
## Creating a Managed Record
The recommended way to package and distribute managed records is using the [`civix export` command](civix.md#export).
## Fine-Tuning
### Update Modes
*This setting determines whether a managed record will be auto-updated after it is installed.*
*This is important to consider if the values in your `mgd.php` record might ever change in future updates to your extension.*
- **always:** Forcibly overwrite record with values from the `.mgd.php` definition with every cache-flush.
- **never:** Once installed, the record will never be updated.
- **unmodified:** Updates to the `.mgd.php` will be propagated only if the record has not been updated by the user.
In general, `always` is a good choice for records which are not meant to be updated by the user, such as reserved `OptionValues`.
In most other cases, `unmodified` is the best trade-off between allowing edits to be made by the user, and propagating updates
when changes are made to the `.mgd.php` in new versions of the extension. Changes made by the user can be undone
by the [`revert`](../api/v4/actions.md#write-actions) API action.
### Cleanup Modes
*This setting determines whether a managed record will be deleted when the extension is uninstalled.*
- **always:** Unconditionally delete the record when the extension is uninstalled.
- **never:** Once installed, the record will never be auto-deleted.
- **unused:** Determines whether any references to the record exist (e.g. if the record is an Acitity Type, do any activities exist of that type?), and only delete it if not.
### Handling possibly existing records
Normally, if the Managed system tries to add a record which already exists, it causes an error.
However, sometimes an extension author isn't sure if the item they want to distribute already exists.
For example, the 1.0 release of an extension may have used [`hook_civicrm_install`](../hooks/hook_civicrm_install.md)
to add an OptionValue. In the 2.0 release, it's decided to move it into a `mgd.php` file - what to do about existing sites
which have already installed the OptionValue?
The solution is to add [`match`](../api/v4/actions.md#write-actions) to the `params` array, declaring which fields should be compared to
see if a record exists before creating a new one. The `civix export` command automatically adds the relevant matches for an entity.
For example, an `OptionValue` will need to match on `name`, `value` and `option_group_id`. A `CustomField` will need to match on `name` and `custom_group_id`.
Without adequate parameters, the Managed system can get confused between similar entities across different parent entities,
such as `OptionValue` entities with the same value in different `OptionGroup` entities.
## Technical Details
For more technical details, see the chapter [Managed APIv4 Entities](../api/v4/managed.md).
\ No newline at end of file
This diff is collapsed.