This took me way longer than I anticipated, so I thought I'd pen a fuller answer for the most minimal settings form. It assumes you're building a modern extension, generated with civix.
Step 1: define your settings
Create a settings dir in your extension's base directory, and within that create a whateveryouwant.setting.php
. Gotcha 1 is that while the directory is called settings this file must be use the singlular "setting" or it won't get picked up. But, yes, it can have multiple settings in it.
That file contains a return [ 'favourite_fruit' => [...], 'your_other_setting' => [...], ... ];
statement - see the docs
Gotcha 2: these *.setting.php
files seem to be only sourced as part of a cache clear. i.e. I learnt that using the "Flush Caches" button (or running via cv api system.flush
) not only flushes the caches, but also recreates some of them. This is different to Drupal, for instance.
Step 2: create a form for it
As Coleman suggests:
civix generate:form Settings civicrm/path/to/your/form
Note that the use of Settings
as the form class name is up to you.
Then edit the CRM/YourMod/Form/Settings.php
file. You can strip this right down to just
class CRM_YourMod_Form_Settings extends CRM_Admin_Form_Setting
{
protected $_settings = [
'favourite_fruit' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
];
public function buildQuickForm() {
parent::buildQuickForm();
$this->assign('elementNames', array_keys($this->_settings));
}
}
The $_settings
array is keyed by the names you define in your *.setting.php
. In the buildQuickForm()
function we just call the one we inherited, but then assign all our settings to the elementNames
array, because the default form created by civix
loops this array to output the elements; if you don't set this your form is empty.
You can then alter it as you need to, but thought it would be useful to have this minimal example posted, hope it helps a googler (or a duckduckgo-er).
For completeness' sake (as I use this as a reference myself!), in code you can access settings with:
$fruit = Civi::settings()->get('favourite_fruit');
And, should you need to
$fruit = Civi::settings()->set('favourite_fruit', 'lychee');