--- /dev/null
+<?php
+use CRM_Shimmy_ExtensionUtil as E;
+
+return [
+ 'shimmy_example' => [
+ 'group_name' => 'Shimmy Preferences',
+ 'group' => 'shimmy',
+ 'name' => 'shimmy_example',
+ 'type' => 'String',
+ 'html_type' => 'select',
+ 'html_attributes' => [
+ 'class' => 'crm-select2',
+ ],
+ 'pseudoconstant' => [
+ 'callback' => 'CRM_Shimmy_Utils::getExampleOptions',
+ ],
+ 'default' => 'first',
+ 'add' => '4.7',
+ 'title' => E::ts('Shimmy editor layout'),
+ 'is_domain' => 1,
+ 'is_contact' => 0,
+ 'description' => E::ts('What is a shimmy example?'),
+ 'help_text' => NULL,
+ 'settings_pages' => ['shimmy' => ['weight' => 10]],
+ ],
+];
--- /dev/null
+<?php
+
+namespace Civi\Shimmy\Mixins;
+
+/**
+ * Assert that the `settings/*.setting.php` mixin is working properly.
+ *
+ * This class defines the assertions to run when installing or uninstalling the extension.
+ * It use called as part of E2E_Shimmy_LifecycleTest.
+ *
+ * @see E2E_Shimmy_LifecycleTest
+ */
+class SettingsTest extends \PHPUnit\Framework\Assert {
+
+ public function testPreConditions($cv) {
+ $this->assertFileExists(static::getPath('/settings/Shimmy.setting.php'), 'The shimmy extension must have a Menu XML file.');
+ }
+
+ public function testInstalled($cv) {
+ // The menu item is registered...
+ $items = $cv->api4('Setting', 'getFields', ['where' => [['name', '=', 'shimmy_example']], 'loadOptions' => TRUE]);
+ $this->assertEquals('shimmy_example', $items[0]['name']);
+ $this->assertEquals('select', $items[0]['html_type']);
+ $this->assertEquals('First example', $items[0]['options']['first']);
+ $this->assertEquals('Second example', $items[0]['options']['second']);
+
+ // And it supports reading/writing...
+ $cv->api3('Setting', 'revert', ['name' => 'shimmy_example']); /* FIXME: Prior installations don't cleanup... */
+ $value = $cv->api3('Setting', 'getvalue', ['name' => 'shimmy_example']);
+ $this->assertEquals('first', $value);
+ $r = $cv->api3('Setting', 'create', ['shimmy_example' => 'second']);
+ $this->assertEquals(0, $r['is_error']);
+ $value = $cv->api3('Setting', 'getvalue', ['name' => 'shimmy_example']);
+ $this->assertEquals('second', $value);
+ }
+
+ public function testDisabled($cv) {
+ $items = $cv->api4('Setting', 'getFields', ['where' => [['name', '=', 'shimmy_example']], 'loadOptions' => TRUE]);
+ $this->assertEmpty($items);
+
+ $value = $cv->api3('Setting', 'getvalue', ['name' => 'shimmy_example']);
+ $this->assertEquals('second', $value);
+ }
+
+ public function testUninstalled($cv) {
+ $items = $cv->api4('Setting', 'getFields', ['where' => [['name', '=', 'shimmy_example']], 'loadOptions' => TRUE]);
+ $this->assertEmpty($items);
+
+ // Uninstall should probably drop old settings, but it hasn't traditionally, so we won't check for the moment.
+ // FIXME // $value = cv('ev \'return Civi::settings()->get("shimmy_example");\'', 'raw');
+ // FIXME // $this->assertEquals('null', trim($value));
+ }
+
+ protected static function getPath($suffix = ''): string {
+ return dirname(__DIR__, 2) . $suffix;
+ }
+
+}
--- /dev/null
+<?php
+
+/**
+ * Auto-register "settings/*.setting.php" files.
+ *
+ * @mixinName setting-php
+ * @mixinVersion 1.0.0
+ *
+ * @param CRM_Extension_MixInfo $mixInfo
+ * On newer deployments, this will be an instance of MixInfo. On older deployments, Civix may polyfill with a work-a-like.
+ * @param \CRM_Extension_BootCache $bootCache
+ * On newer deployments, this will be an instance of MixInfo. On older deployments, Civix may polyfill with a work-a-like.
+ */
+return function ($mixInfo, $bootCache) {
+
+ /**
+ * @param \Civi\Core\Event\GenericHookEvent $e
+ * @see CRM_Utils_Hook::alterSettingsFolders()
+ */
+ Civi::dispatcher()->addListener('hook_civicrm_alterSettingsFolders', function ($e) use ($mixInfo) {
+ // When deactivating on a polyfill/pre-mixin system, listeners may not cleanup automatically.
+ if (!$mixInfo->isActive()) {
+ return;
+ }
+
+ $settingsDir = $mixInfo->getPath('settings');
+ if (!in_array($settingsDir, $e->settingsFolders) && is_dir($settingsDir)) {
+ $e->settingsFolders[] = $settingsDir;
+ }
+ });
+
+};