Skip to content
Snippets Groups Projects
Commit 846da36a authored by mattwire's avatar mattwire
Browse files

Update version

parent 8fb2e6d9
No related branches found
No related tags found
1 merge request!241Stripe Import extension
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
<author>Matthew Wire (MJW Consulting)</author> <author>Matthew Wire (MJW Consulting)</author>
<email>mjw@mjwconsult.co.uk</email> <email>mjw@mjwconsult.co.uk</email>
</maintainer> </maintainer>
<releaseDate>2024-01-23</releaseDate> <releaseDate>2024-03-19</releaseDate>
<version>6.11-dev</version> <version>6.11-dev</version>
<develStage>beta</develStage> <develStage>beta</develStage>
<compatibility> <compatibility>
<ver>5.65</ver> <ver>5.68</ver>
</compatibility> </compatibility>
<comments>Original Author: Joshua Walker (drastik) - Drastik by Design. <comments>Original Author: Joshua Walker (drastik) - Drastik by Design.
Jamie Mcclelland (ProgressiveTech) did a lot of the 5.x compatibility work. Jamie Mcclelland (ProgressiveTech) did a lot of the 5.x compatibility work.
......
<?php
/**
* The "setting-admin" mixin defines a standard idiom for managing extension settings:
*
* 1. Create a permission "administer {myext}" ("Administer {My Extension}").
* 2. Create a page "civicrm/admin/setting/{myext}" (via `CRM_Admin_Form_Generic`)
* 3. Assign all settings from "{myext}" to appear on the page.
* 4. Create a link "Administer > System Settings" to "{My Extension} Settings"
*
* (The values of "{myext}" and "{My Extension}" come from info.xml's `<file>` and `<name>`.)
*
* If you don't like the defaults, then there are a few override points:
*
* - If you manually create permission "administer {myext}", then your label/description takes precedence.
* - If you manually register route "civicrm/admin/setting/{myext}", then your definition takes precedence.
* - If you manually configure a setting with `settings_page`, then that setting will move to the other page.
* (To make a hidden setting, specify `settings_page => []`.)
* - If you manually add "civicrm/admin/setting/{myext}" to the menu, then your link takes precedence.
*
* Additionally, there is experimental support for overrides in info.xml. (Respected by v1.0.0 but not guaranteed future.)
*
* <civix><setting-page-title>My Custom Title</setting-page-title></civix>
*
* #####################################################################
* NOTE: setting-admin@1.0 is a civix-only backport revised for broader compatibility. Differences:
*
* - Don't register hooks with the `&` prefix.
* - Don't call `_ts()`. Use `$ts()` trick ourselves.
* - Omit some type-hints.
* - Use separate namespace for EVERY PATCH-VERSION. Prevent conflicts when using polyfill-based loading.
* - Downstream cannot rely on namespace-names/class-names. That's fine. These particular classes are internal helpers.
*
* The mainline release is setting-admin@1.1+.
* #####################################################################
*
* @mixinName setting-admin
* @mixinVersion 1.0.1
* @since 5.68
*/
namespace Civi\Mixin\SettingAdminV1_0_1;
use Civi;
class About {
/**
* @var \CRM_Extension_MixInfo
*/
private $mixInfo;
/**
* @var \CRM_Extension_Info
*/
private $info;
/**
* @param \CRM_Extension_MixInfo $mixInfo
*/
public static function instance($mixInfo): About {
$about = new About();
$about->mixInfo = $mixInfo;
$about->info = \CRM_Extension_System::singleton()->getMapper()->keyToInfo($mixInfo->longName);
return $about;
}
public function getPath(): string {
return 'civicrm/admin/setting/' . $this->mixInfo->shortName;
}
public function getPerm(): string {
return 'administer ' . $this->mixInfo->shortName;
}
public function getLabel(): string {
return $this->info->label ? \ts($this->info->label, ['domain' => $this->info->key]) : $this->info->key;
}
public function getPageTitle(): string {
// Changing the title any other way is slightly annoying because you have to override both route+nav.
// It might be nice if one (route or menu) reliably inherited its title from the other...
if (!empty($this->info->civix['setting-page-title'])) {
return $this->info->civix['setting-page-title'];
// Could call _ts(..., [domain=>...]), but translation appears to happen at another level,
// and double-translation might confuse multilingual.
}
return ts('%1 Settings', [1 => $this->getLabel()]);
}
public function getRoute(): array {
return [
'title' => $this->getPageTitle(),
'page_callback' => 'CRM_Admin_Form_Generic',
'access_arguments' => [['administer CiviCRM', $this->getPerm()], 'or'],
'adminGroup' => 'System Settings',
'desc' => \ts($this->info->description ?: ''),
];
}
public function getNavigation(): array {
return [
'label' => $this->getPageTitle(),
'name' => sprintf('%s_setting_admin', $this->mixInfo->shortName),
'url' => $this->getPath() . '?reset=1',
// 'icon' => 'crm-i fa-wrench', // None of the other "System Settings" have icons, so we don't.
// 'permission' => ['administer CiviCRM', $this->getPerm()],
'permission' => "administer CiviCRM,{$this->getPerm()}",
'permission_operator' => 'OR',
];
}
}
class Nav {
/**
* Visit all items in the nav-tree.
*
* @param array $items
* @param callable $callback
* function(array &$item): mixed
* To short-circuit execution, the callback should return a non-null value.
* @return string|null
* Return NULL by default. If the walk was short-circuited, then return that value.
*/
public static function walk(&$items, callable $callback) {
foreach ($items as &$item) {
$result = $callback($item);
if ($result !== NULL) {
return $result;
}
if (!empty($item['child'])) {
$result = static::walk($item['child'], $callback);
if ($result !== NULL) {
return $result;
}
}
}
return NULL;
}
}
/**
* @param \CRM_Extension_MixInfo $mixInfo
* @param \CRM_Extension_BootCache $bootCache
*/
return function ($mixInfo, $bootCache) {
// Register the setting page ("civicrm/admin/setting/{myext}").
Civi::dispatcher()->addListener('hook_civicrm_alterMenu', function ($e) use ($mixInfo) {
if (!$mixInfo->isActive()) {
return;
}
$about = About::instance($mixInfo);
if (!isset($e->items[$about->getPath()])) {
$e->items[$about->getPath()] = $about->getRoute();
}
}, -1000);
// Define a permission "administer {myext}"
Civi::dispatcher()->addListener('hook_civicrm_permission', function ($e) use ($mixInfo) {
if (!$mixInfo->isActive()) {
return;
}
$about = About::instance($mixInfo);
$perm = 'administer ' . $mixInfo->shortName;
if (!isset($e->permissions[$perm])) {
$e->permissions[$perm] = ts('%1: Administer settings', [1 => $about->getLabel()]);
}
}, -1000);
// Any settings with "group=={myext}" should be added to our setting page (unless overridden).
// By default, 'weight' is based on the order-of-declaration (spaced out with increments of 10).
Civi::dispatcher()->addListener('hook_civicrm_alterSettingsMetaData', function($e) use ($mixInfo) {
if (!$mixInfo->isActive()) {
return;
}
$weight = 1000;
$weightInterval = 10;
foreach ($e->settingsMetaData as &$setting) {
if (($setting['group'] ?? '') === $mixInfo->shortName) {
if (!array_key_exists('settings_pages', $setting)) {
$setting['settings_pages'][$mixInfo->shortName] = [
'weight' => $weight,
];
$weight += $weightInterval;
}
}
}
}, -1000);
// Add navigation-item ('civicrm/admin/setting/{myext}') unless you've already done so.
Civi::dispatcher()->addListener('hook_civicrm_navigationMenu', function ($e) use ($mixInfo) {
if (!$mixInfo->isActive()) {
return;
}
$about = About::instance($mixInfo);
$newItem = $about->getNavigation() + ['active' => 1];
// Skip if we're already in the menu. (Ignore optional suffix `?reset=1`)
$found = Nav::walk($e->menu, function(&$item) use ($about) {
if (!isset($item['attributes']['url'])) {
return NULL;
}
return strpos($item['attributes']['url'], $about->getPath()) === 0 ? 'found' : NULL;
});
if ($found) {
return;
}
Nav::walk($e->menu, function(&$item) use ($newItem) {
if ($item['attributes']['name'] === 'System Settings') {
$item['child'][] = ['attributes' => $newItem];
return 'done';
}
});
}, -1000);
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment