diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index 0b8c63bbe..fe190dc77 100644
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -55,7 +55,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$url = trim($url);
/** @var string|null $urlHooked */
- $urlHooked = Minz_ExtensionManager::callHook('check_url_before_add', $url);
+ $urlHooked = Minz_ExtensionManager::callHook(Minz_HookType::CheckUrlBeforeAdd, $url);
if ($urlHooked === null) {
throw new FreshRSS_FeedNotAdded_Exception($url);
}
@@ -106,7 +106,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
}
/** @var FreshRSS_Feed|null $feed */
- $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
+ $feed = Minz_ExtensionManager::callHook(Minz_HookType::FeedBeforeInsert, $feed);
if ($feed === null) {
throw new FreshRSS_FeedNotAdded_Exception($url);
}
@@ -465,7 +465,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$categoriesEntriesTitle = [];
foreach ($feeds as $feed) {
- $feed = Minz_ExtensionManager::callHook('feed_before_actualize', $feed);
+ $feed = Minz_ExtensionManager::callHook(Minz_HookType::FeedBeforeActualize, $feed);
if (!($feed instanceof FreshRSS_Feed)) {
continue;
}
@@ -616,10 +616,10 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$entry->_isFavorite(null); // Do not change favourite state
$entry->_isRead($mark_updated_article_unread ? false : null); //Change is_read according to policy.
if ($mark_updated_article_unread) {
- Minz_ExtensionManager::callHook('entry_auto_unread', $entry, 'updated_article');
+ Minz_ExtensionManager::callHook(Minz_HookType::EntryAutoUnread, $entry, 'updated_article');
}
- $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeInsert, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
@@ -642,7 +642,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
// If the entry has changed, there is a good chance for the full content to have changed as well.
$entry->loadCompleteContent(true);
- $entry = Minz_ExtensionManager::callHook('entry_before_update', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeUpdate, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
@@ -655,7 +655,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$id = uTimeString();
$entry->_id($id);
- $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeInsert, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
@@ -681,7 +681,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$feed->pubSubHubbubError(true);
}
- $entry = Minz_ExtensionManager::callHook('entry_before_add', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeAdd, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
@@ -911,7 +911,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
// Case of a batch refresh (e.g. cron)
$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
$databaseDAO->minorDbMaintenance();
- Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
+ Minz_ExtensionManager::callHookVoid(Minz_HookType::FreshrssUserMaintenance);
FreshRSS_feed_Controller::commitNewEntries();
$feedDAO = FreshRSS_Factory::createFeedDao();
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php
index 9f9f6b2bd..8e03299f9 100644
--- a/app/Controllers/importExportController.php
+++ b/app/Controllers/importExportController.php
@@ -478,14 +478,14 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
}
$newGuids[$entry->guid()] = true;
- $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeInsert, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
}
if (isset($existingHashForGuids['f_' . $feed_id][$entry->guid()])) {
- $entry = Minz_ExtensionManager::callHook('entry_before_update', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeUpdate, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
@@ -495,7 +495,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
} else {
$entry->_lastSeen(time());
- $entry = Minz_ExtensionManager::callHook('entry_before_add', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeAdd, $entry);
if (!($entry instanceof FreshRSS_Entry)) {
// An extension has returned a null value, there is nothing to insert.
continue;
@@ -581,7 +581,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
}
// Call the extension hook
- $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
+ $feed = Minz_ExtensionManager::callHook(Minz_HookType::FeedBeforeInsert, $feed);
if ($feed instanceof FreshRSS_Feed) {
// addFeedObject checks if feed is already in DB so nothing else to
// check here.
diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php
index 5fd925f72..1370c00c7 100644
--- a/app/Controllers/javascriptController.php
+++ b/app/Controllers/javascriptController.php
@@ -32,7 +32,7 @@ class FreshRSS_javascript_Controller extends FreshRSS_ActionController {
$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
$databaseDAO->minorDbMaintenance();
- Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
+ Minz_ExtensionManager::callHookVoid(Minz_HookType::FreshrssUserMaintenance);
$catDAO = FreshRSS_Factory::createCategoryDao();
$this->view->categories = $catDAO->listCategoriesOrderUpdate(FreshRSS_Context::userConf()->dynamic_opml_ttl_default);
diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php
index bec639b39..bd140b6d5 100644
--- a/app/Controllers/updateController.php
+++ b/app/Controllers/updateController.php
@@ -283,7 +283,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
$res = do_post_update();
}
- Minz_ExtensionManager::callHookVoid('post_update');
+ Minz_ExtensionManager::callHookVoid(Minz_HookType::PostUpdate);
if ($res === true) {
@unlink(UPDATE_FILENAME);
diff --git a/app/FreshRSS.php b/app/FreshRSS.php
index cac803329..0d433dc2b 100644
--- a/app/FreshRSS.php
+++ b/app/FreshRSS.php
@@ -66,7 +66,7 @@ class FreshRSS extends Minz_FrontController {
self::checkEmailValidated();
}
- Minz_ExtensionManager::callHookVoid('freshrss_init');
+ Minz_ExtensionManager::callHookVoid(Minz_HookType::FreshrssInit);
}
private static function initAuth(): void {
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index 7254dd513..0769762f8 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -818,12 +818,12 @@ HTML;
if (!$this->isRead()) {
if ($feed->attributeBoolean('read_upon_reception') ?? FreshRSS_Context::userConf()->mark_when['reception']) {
$this->_isRead(true);
- Minz_ExtensionManager::callHook('entry_auto_read', $this, 'upon_reception');
+ Minz_ExtensionManager::callHook(Minz_HookType::EntryAutoRead, $this, 'upon_reception');
}
if (!empty($titlesAsRead[$this->title()])) {
Minz_Log::debug('Mark title as read: ' . $this->title());
$this->_isRead(true);
- Minz_ExtensionManager::callHook('entry_auto_read', $this, 'same_title_in_feed');
+ Minz_ExtensionManager::callHook(Minz_HookType::EntryAutoRead, $this, 'same_title_in_feed');
}
}
FreshRSS_Context::userConf()->applyFilterActions($this);
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index ad1cc4393..f236cd3f3 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -387,7 +387,7 @@ SQL;
$values = array_merge($values, $ids);
$stm = $this->pdo->prepare($sql);
if ($stm !== false && $stm->execute($values)) {
- Minz_ExtensionManager::callHook('entries_favorite', $ids, $is_favorite);
+ Minz_ExtensionManager::callHook(Minz_HookType::EntriesFavorite, $ids, $is_favorite);
return $stm->rowCount();
} else {
$info = $stm === false ? $this->pdo->errorInfo() : $stm->errorInfo();
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 2b29f7b22..112da1a00 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -255,7 +255,7 @@ class FreshRSS_Feed extends Minz_Model {
$params = '';
if ($this->customFavicon()) {
$current = $this->id . Minz_User::name();
- $hookParams = Minz_ExtensionManager::callHook('custom_favicon_hash', $this);
+ $hookParams = Minz_ExtensionManager::callHook(Minz_HookType::CustomFaviconHash, $this);
$params = $hookParams !== null ? $hookParams : $current;
} else {
$params = $this->website(fallback: true) . $this->proxyParam();
@@ -579,9 +579,9 @@ class FreshRSS_Feed extends Minz_Model {
// Do not use `$simplePie->enable_cache(false);` as it would prevent caching in multiuser context
$this->clearCache();
}
- Minz_ExtensionManager::callHook('simplepie_before_init', $simplePie, $this);
+ Minz_ExtensionManager::callHook(Minz_HookType::SimplepieBeforeInit, $simplePie, $this);
$simplePieResult = $simplePie->init();
- Minz_ExtensionManager::callHook('simplepie_after_init', $simplePie, $this, $simplePieResult);
+ Minz_ExtensionManager::callHook(Minz_HookType::SimplepieAfterInit, $simplePie, $this, $simplePieResult);
if ($simplePieResult === false || $simplePie->get_hash() === '' || !empty($simplePie->error())) {
if ($simplePie->status_code() === 429) {
diff --git a/app/Models/FilterActionsTrait.php b/app/Models/FilterActionsTrait.php
index 3d8257e34..36b3682d8 100644
--- a/app/Models/FilterActionsTrait.php
+++ b/app/Models/FilterActionsTrait.php
@@ -132,7 +132,7 @@ trait FreshRSS_FilterActionsTrait {
case 'read':
if (!$entry->isRead()) {
$entry->_isRead(true);
- Minz_ExtensionManager::callHook('entry_auto_read', $entry, 'filter');
+ Minz_ExtensionManager::callHook(Minz_HookType::EntryAutoRead, $entry, 'filter');
}
break;
case 'star':
diff --git a/app/Models/ViewMode.php b/app/Models/ViewMode.php
index 54379b130..fde073097 100644
--- a/app/Models/ViewMode.php
+++ b/app/Models/ViewMode.php
@@ -51,7 +51,7 @@ final class FreshRSS_ViewMode {
$modes = self::getDefaultModes();
// Allow extensions to add their own view modes
- $extensionModes = Minz_ExtensionManager::callHook('view_modes', []);
+ $extensionModes = Minz_ExtensionManager::callHook(Minz_HookType::ViewModes, []);
if (is_array($extensionModes)) {
foreach ($extensionModes as $mode) {
if ($mode instanceof FreshRSS_ViewMode) {
diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php
index e7af7589d..b567544b3 100644
--- a/app/Services/ImportService.php
+++ b/app/Services/ImportService.php
@@ -311,7 +311,7 @@ class FreshRSS_Import_Service {
// Call the extension hook
/** @var FreshRSS_Feed|null */
- $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
+ $feed = Minz_ExtensionManager::callHook(Minz_HookType::FeedBeforeInsert, $feed);
if ($dry_run) {
if ($feed !== null) {
diff --git a/app/actualize_script.php b/app/actualize_script.php
index 2be2a117a..e64d0b707 100755
--- a/app/actualize_script.php
+++ b/app/actualize_script.php
@@ -96,7 +96,7 @@ foreach ($users as $user) {
// NB: Extensions and hooks are reinitialised there
$app->init();
- Minz_ExtensionManager::addHook('feed_before_actualize', static function (FreshRSS_Feed $feed) use ($mutexFile) {
+ Minz_ExtensionManager::addHook(Minz_HookType::FeedBeforeActualize, static function (FreshRSS_Feed $feed) use ($mutexFile) {
touch($mutexFile);
return $feed;
});
diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml
index 7413f002d..6ebf232e2 100644
--- a/app/layout/aside_configure.phtml
+++ b/app/layout/aside_configure.phtml
@@ -60,7 +60,7 @@
= _t('gen.menu.logs') ?>
- = Minz_ExtensionManager::callHookString('menu_configuration_entry') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::MenuConfigurationEntry) ?>
@@ -88,7 +88,7 @@
= _t('gen.menu.logs') ?>
- = Minz_ExtensionManager::callHookString('menu_admin_entry') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::MenuAdminEntry) ?>
diff --git a/app/layout/header.phtml b/app/layout/header.phtml
index 1e4290f98..e92b3c2ef 100644
--- a/app/layout/header.phtml
+++ b/app/layout/header.phtml
@@ -87,7 +87,7 @@
= _t('gen.menu.queries') ?>
= _t('gen.menu.extensions') ?>
= _t('gen.menu.privacy') ?>
- = Minz_ExtensionManager::callHookString('menu_configuration_entry') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::MenuConfigurationEntry) ?>
@@ -103,7 +103,7 @@
disable_update) { ?>
= _t('gen.menu.update') ?>
- = Minz_ExtensionManager::callHookString('menu_admin_entry') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::MenuAdminEntry) ?>
@@ -117,7 +117,7 @@
= _t('index.tos.title')?>
- = Minz_ExtensionManager::callHookString('menu_other_entry') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::MenuOtherEntry) ?>
diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml
index 2f09465aa..d477bff37 100644
--- a/app/layout/nav_menu.phtml
+++ b/app/layout/nav_menu.phtml
@@ -190,7 +190,7 @@
-
+
- = Minz_ExtensionManager::callHookString('before_login_btn') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::BeforeLoginBtn) ?>
- = Minz_ExtensionManager::callHookString('before_login_btn') ?>
+ = Minz_ExtensionManager::callHookString(Minz_HookType::BeforeLoginBtn) ?>
entryIdsTagNames)) {
foreach ($this->entries as $entry) {
if (!$this->internal_rendering) {
/** @var FreshRSS_Entry|null $entry */
- $entry = Minz_ExtensionManager::callHook('entry_before_display', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeDisplay, $entry);
}
if ($entry === null) {
continue;
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml
index 0666a7130..c5dae8460 100644
--- a/app/views/helpers/feed/update.phtml
+++ b/app/views/helpers/feed/update.phtml
@@ -50,7 +50,7 @@
$originalIconUrl = $this->feed->favicon();
$this->feed->_attribute('customFavicon', $currentIconUrl !== $originalIconUrl);
$this->feed->resetFaviconHash();
- $ext_url = Minz_ExtensionManager::callHook('custom_favicon_btn_url', $this->feed);
+ $ext_url = Minz_ExtensionManager::callHook(Minz_HookType::CustomFaviconBtnUrl, $this->feed);
?>
= _t('sub.feed.icon') ?>
diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml
index 2d2d2e364..2cedc20c3 100644
--- a/app/views/helpers/javascript_vars.phtml
+++ b/app/views/helpers/javascript_vars.phtml
@@ -3,7 +3,7 @@ declare(strict_types=1);
/** @var FreshRSS_View $this */
$mark = FreshRSS_Context::userConf()->mark_when;
$s = FreshRSS_Context::userConf()->shortcuts;
-$extData = Minz_ExtensionManager::callHook('js_vars', []);
+$extData = Minz_ExtensionManager::callHook(Minz_HookType::JsVars, []);
echo json_encode([
'context' => [
'anonymous' => !FreshRSS_Auth::hasAccess(),
diff --git a/app/views/index/normal.phtml b/app/views/index/normal.phtml
index cc800c3fe..1b942ae17 100644
--- a/app/views/index/normal.phtml
+++ b/app/views/index/normal.phtml
@@ -47,7 +47,7 @@ $today = @strtotime('today');
$nbEntries = 0;
foreach ($this->entries as $item):
/** @var FreshRSS_Entry|null $item */
- $item = Minz_ExtensionManager::callHook('entry_before_display', $item);
+ $item = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeDisplay, $item);
if ($item === null) {
continue;
}
diff --git a/app/views/index/reader.phtml b/app/views/index/reader.phtml
index bb957f232..49321f9f5 100644
--- a/app/views/index/reader.phtml
+++ b/app/views/index/reader.phtml
@@ -20,7 +20,7 @@ $useKeepUnreadImportant = !FreshRSS_Context::isImportant() && !FreshRSS_Context:
$nbEntries = 0;
foreach ($this->entries as $entry):
/** @var FreshRSS_Entry|null $entry */
- $entry = Minz_ExtensionManager::callHook('entry_before_display', $entry);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeDisplay, $entry);
if ($entry === null) {
continue;
}
diff --git a/app/views/index/rss.phtml b/app/views/index/rss.phtml
index 7d92bd140..7caf4cb9d 100644
--- a/app/views/index/rss.phtml
+++ b/app/views/index/rss.phtml
@@ -23,7 +23,7 @@
foreach ($this->entries as $item) {
if (!$this->internal_rendering) {
/** @var FreshRSS_Entry|null $item */
- $item = Minz_ExtensionManager::callHook('entry_before_display', $item);
+ $item = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeDisplay, $item);
if ($item === null) {
continue;
}
diff --git a/cli/actualize-user.php b/cli/actualize-user.php
index d5633766f..77254d834 100755
--- a/cli/actualize-user.php
+++ b/cli/actualize-user.php
@@ -20,13 +20,13 @@ if (!empty($cliOptions->errors)) {
$username = cliInitUser($cliOptions->user);
-Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
+Minz_ExtensionManager::callHookVoid(Minz_HookType::FreshrssUserMaintenance);
fwrite(STDERR, 'FreshRSS actualizing user “' . $username . "”…\n");
$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
$databaseDAO->minorDbMaintenance();
-Minz_ExtensionManager::callHookVoid('freshrss_user_maintenance');
+Minz_ExtensionManager::callHookVoid(Minz_HookType::FreshrssUserMaintenance);
FreshRSS_feed_Controller::commitNewEntries();
$feedDAO = FreshRSS_Factory::createFeedDao();
diff --git a/docs/en/developers/03_Backend/05_Extensions.md b/docs/en/developers/03_Backend/05_Extensions.md
index fcae42b5a..189e5d64f 100644
--- a/docs/en/developers/03_Backend/05_Extensions.md
+++ b/docs/en/developers/03_Backend/05_Extensions.md
@@ -143,8 +143,8 @@ final class HelloWorldExtension extends Minz_Extension
public function init(): void {
parent::init();
- $this->registerHook('entry_before_display', [$this, 'renderEntry']);
- $this->registerHook('check_url_before_add', [self::class, 'checkUrl']);
+ $this->registerHook(Minz_HookType::EntryBeforeDisplay, [$this, 'renderEntry']);
+ $this->registerHook(Minz_HookType::CheckUrlBeforeAdd, [self::class, 'checkUrl']);
}
public function renderEntry(FreshRSS_Entry $entry): FreshRSS_Entry {
@@ -164,7 +164,7 @@ final class HelloWorldExtension extends Minz_Extension
The following events are available:
-* `api_misc` (`function(): void`): to allow extensions to have own API endpoint
+* `api_misc` (`function(): void`): to allow extensions to have their own API endpoint
on `/api/misc.php/Extension%20Name/` or `/api/misc.php?ext=Extension%20Name`.
* `before_login_btn` (`function(): string`): Allows to insert HTML before the login button. Applies to the create button on the register page as well. Example use case is inserting a captcha widget.
* `check_url_before_add` (`function($url) -> Url | null`): will be executed every time a URL is added. The URL itself will be passed as parameter. This way a website known to have feeds which doesn’t advertise it in the header can still be automatically supported.
diff --git a/docs/fr/developers/03_Backend/05_Extensions.md b/docs/fr/developers/03_Backend/05_Extensions.md
index 18cc892be..00a229e94 100644
--- a/docs/fr/developers/03_Backend/05_Extensions.md
+++ b/docs/fr/developers/03_Backend/05_Extensions.md
@@ -197,8 +197,8 @@ final class HelloWorldExtension extends Minz_Extension
public function init(): void {
parent::init();
- $this->registerHook('entry_before_display', [$this, 'renderEntry']);
- $this->registerHook('check_url_before_add', [self::class, 'checkUrl']);
+ $this->registerHook(Minz_HookType::EntryBeforeDisplay, [$this, 'renderEntry']);
+ $this->registerHook(Minz_HookType::CheckUrlBeforeAdd, [self::class, 'checkUrl']);
}
public function renderEntry(FreshRSS_Entry $entry): FreshRSS_Entry {
diff --git a/lib/Minz/ExtensionManager.php b/lib/Minz/ExtensionManager.php
index b91a89de7..04e1806c4 100644
--- a/lib/Minz/ExtensionManager.php
+++ b/lib/Minz/ExtensionManager.php
@@ -19,114 +19,9 @@ final class Minz_ExtensionManager {
/**
* List of available hooks. Please keep this list sorted.
- * @var array,'signature':'NoneToNone'|'NoneToString'|'OneToOne'|'PassArguments'}>
+ * @var array,array{'list':list,'signature':Minz_HookSignature}>
*/
- private static array $hook_list = [
- 'api_misc' => [ // function(): void
- 'list' => [],
- 'signature' => 'NoneToNone',
- ],
- 'before_login_btn' => [ // function(): string
- 'list' => [],
- 'signature' => 'NoneToString',
- ],
- 'check_url_before_add' => [ // function($url) -> Url | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'custom_favicon_btn_url' => [ // function(FreshRSS_Feed $feed): string | null
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'custom_favicon_hash' => [ // function(FreshRSS_Feed $feed): string | null
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'entries_favorite' => [ // function(array $ids, bool $is_favorite): void
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'entry_auto_read' => [ // function(FreshRSS_Entry $entry, string $why): void
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'entry_auto_unread' => [ // function(FreshRSS_Entry $entry, string $why): void
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'entry_before_display' => [ // function($entry) -> Entry | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'entry_before_insert' => [ // function($entry) -> Entry | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'entry_before_add' => [ // function($entry) -> Entry | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'entry_before_update' => [ // function($entry) -> Entry | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'feed_before_actualize' => [ // function($feed) -> Feed | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'feed_before_insert' => [ // function($feed) -> Feed | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'freshrss_init' => [ // function() -> none
- 'list' => [],
- 'signature' => 'NoneToNone',
- ],
- 'freshrss_user_maintenance' => [ // function() -> none
- 'list' => [],
- 'signature' => 'NoneToNone',
- ],
- 'js_vars' => [ // function($vars = array) -> array | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'menu_admin_entry' => [ // function() -> string
- 'list' => [],
- 'signature' => 'NoneToString',
- ],
- 'menu_configuration_entry' => [ // function() -> string
- 'list' => [],
- 'signature' => 'NoneToString',
- ],
- 'menu_other_entry' => [ // function() -> string
- 'list' => [],
- 'signature' => 'NoneToString',
- ],
- 'nav_menu' => [ // function() -> string
- 'list' => [],
- 'signature' => 'NoneToString',
- ],
- 'nav_reading_modes' => [ // function($readingModes = array) -> array | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- 'post_update' => [ // function(none) -> none
- 'list' => [],
- 'signature' => 'NoneToNone',
- ],
- 'simplepie_after_init' => [ // function(\SimplePie\SimplePie $simplePie, FreshRSS_Feed $feed, bool $result): void
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'simplepie_before_init' => [ // function(\SimplePie\SimplePie $simplePie, FreshRSS_Feed $feed): void
- 'list' => [],
- 'signature' => 'PassArguments',
- ],
- 'view_modes' => [ // function($viewModes = array) -> array | null
- 'list' => [],
- 'signature' => 'OneToOne',
- ],
- ];
+ private static array $hook_list = [];
/** Remove extensions and hooks from a previous initialisation */
private static function reset(): void {
@@ -134,10 +29,12 @@ final class Minz_ExtensionManager {
self::$ext_list = [];
self::$ext_list_enabled = [];
self::$ext_auto_enabled = [];
- foreach (self::$hook_list as $hook_type => $hook_data) {
- $hadAny |= !empty($hook_data['list']);
- $hook_data['list'] = [];
- self::$hook_list[$hook_type] = $hook_data;
+ foreach (Minz_HookType::cases() as $hook_type) {
+ $hadAny |= !empty(self::$hook_list[$hook_type->value]['list']);
+ self::$hook_list[$hook_type->value] = [
+ 'list' => [],
+ 'signature' => $hook_type->signature(),
+ ];
}
if ($hadAny) {
gc_collect_cycles();
@@ -357,46 +254,62 @@ final class Minz_ExtensionManager {
/**
* Add a hook function to a given hook.
*
- * The hook name must be a valid one. For the valid list, see self::$hook_list
- * array keys.
+ * The hook name must be a valid one. For the valid list, see Minz_HookType enum.
*
- * @param string $hook_name the hook name (must exist).
+ * @param string|Minz_HookType $hook the hook name (must exist).
* @param callable $hook_function the function name to call (must be callable).
*/
- public static function addHook(string $hook_name, $hook_function): void {
- if (isset(self::$hook_list[$hook_name]) && is_callable($hook_function)) {
+ public static function addHook(string|Minz_HookType $hook, $hook_function): void {
+ if (null === $hook = self::extractHook($hook)) {
+ return;
+ }
+ $hook_name = $hook->value;
+
+ if (is_callable($hook_function)) {
self::$hook_list[$hook_name]['list'][] = $hook_function;
}
}
/**
- * Call functions related to a given hook.
- *
- * The hook name must be a valid one. For the valid list, see self::$hook_list
- * array keys.
- *
- * @param string $hook_name the hook to call.
- * @param mixed ...$args additional parameters (for signature, please see self::$hook_list).
- * @return mixed|void|null final result of the called hook.
+ * @param string|Minz_HookType $hook the hook or its name
+ * @return Minz_HookType|null
*/
- public static function callHook(string $hook_name, ...$args) {
- if (!isset(self::$hook_list[$hook_name])) {
- return;
+ private static function extractHook(string|Minz_HookType $hook) {
+ if ($hook instanceof Minz_HookType) {
+ return $hook;
}
+ return Minz_HookType::tryFrom($hook);
+ }
+
+ /**
+ * Call functions related to a given hook.
+ *
+ * The hook name must be a valid one. For the valid list, see Minz_HookType enum.
+ *
+ * @param string|Minz_HookType $hook the hook to call.
+ * @param mixed ...$args additional parameters (for signature, please see Minz_HookType enum).
+ * @return mixed|void|null final result of the called hook.
+ */
+ public static function callHook(string|Minz_HookType $hook, ...$args) {
+ if (null === $hook = self::extractHook($hook)) {
+ return;
+ }
+ $hook_name = $hook->value;
+
$signature = self::$hook_list[$hook_name]['signature'];
- if ($signature === 'OneToOne') {
+ if ($signature === Minz_HookSignature::OneToOne) {
return self::callOneToOne($hook_name, $args[0] ?? null);
- } elseif ($signature === 'PassArguments') {
+ } elseif ($signature === Minz_HookSignature::PassArguments) {
foreach (self::$hook_list[$hook_name]['list'] as $function) {
$result = call_user_func($function, ...$args);
if ($result !== null) {
return $result;
}
}
- } elseif ($signature === 'NoneToString') {
+ } elseif ($signature === Minz_HookSignature::NoneToString) {
return self::callHookString($hook_name);
- } elseif ($signature === 'NoneToNone') {
+ } elseif ($signature === Minz_HookSignature::NoneToNone) {
self::callHookVoid($hook_name);
}
return;
@@ -411,12 +324,17 @@ final class Minz_ExtensionManager {
*
* If a hook return a null value, the method is stopped and return null.
*
- * @param string $hook_name is the hook to call.
+ * @param string|Minz_HookType $hook is the hook to call.
* @param mixed $arg is the argument to pass to the first extension hook.
* @return mixed|null final chained result of the hooks. If nothing is changed,
* the initial argument is returned.
*/
- private static function callOneToOne(string $hook_name, mixed $arg): mixed {
+ private static function callOneToOne(string|Minz_HookType $hook, mixed $arg): mixed {
+ if (null === $hook = self::extractHook($hook)) {
+ return $arg;
+ }
+ $hook_name = $hook->value;
+
$result = $arg;
foreach (self::$hook_list[$hook_name]['list'] as $function) {
$result = call_user_func($function, $arg);
@@ -436,10 +354,15 @@ final class Minz_ExtensionManager {
* The result is concatenated between each hook and the final string is
* returned.
*
- * @param string $hook_name is the hook to call.
+ * @param string|Minz_HookType $hook is the hook to call.
* @return string concatenated result of the call to all the hooks.
*/
- public static function callHookString(string $hook_name): string {
+ public static function callHookString(string|Minz_HookType $hook): string {
+ if (null === $hook = self::extractHook($hook)) {
+ return '';
+ }
+ $hook_name = $hook->value;
+
$result = '';
foreach (self::$hook_list[$hook_name]['list'] ?? [] as $function) {
$return = call_user_func($function);
@@ -456,9 +379,14 @@ final class Minz_ExtensionManager {
* This case is simpler than callOneToOne because hooks are called one by
* one, without any consideration of argument nor result.
*
- * @param string $hook_name is the hook to call.
+ * @param string|Minz_HookType $hook is the hook to call.
*/
- public static function callHookVoid(string $hook_name): void {
+ public static function callHookVoid(string|Minz_HookType $hook): void {
+ if (null === $hook = self::extractHook($hook)) {
+ return;
+ }
+ $hook_name = $hook->value;
+
foreach (self::$hook_list[$hook_name]['list'] ?? [] as $function) {
call_user_func($function);
}
@@ -468,9 +396,14 @@ final class Minz_ExtensionManager {
* Call a hook which takes no argument and returns nothing.
* Same as callHookVoid but only calls the first extension.
*
- * @param string $hook_name is the hook to call.
+ * @param string|Minz_HookType $hook is the hook to call.
*/
- public static function callHookUnique(string $hook_name): bool {
+ public static function callHookUnique(string|Minz_HookType $hook): bool {
+ if (null === $hook = self::extractHook($hook)) {
+ throw new \RuntimeException("The “{$hook}” does not exist!");
+ }
+ $hook_name = $hook->value;
+
foreach (self::$hook_list[$hook_name]['list'] ?? [] as $function) {
call_user_func($function);
return true;
diff --git a/lib/Minz/HookSignature.php b/lib/Minz/HookSignature.php
new file mode 100644
index 000000000..bfc7410d6
--- /dev/null
+++ b/lib/Minz/HookSignature.php
@@ -0,0 +1,9 @@
+ string | null
+ case CustomFaviconBtnUrl = 'custom_favicon_btn_url'; // function(FreshRSS_Feed $feed): string | null
+ case CustomFaviconHash = 'custom_favicon_hash'; // function(FreshRSS_Feed $feed): string | null
+ case EntriesFavorite = 'entries_favorite'; // function(array $ids, bool $is_favorite): void
+ case EntryAutoRead = 'entry_auto_read'; // function(FreshRSS_Entry $entry, string $why): void
+ case EntryAutoUnread = 'entry_auto_unread'; // function(FreshRSS_Entry $entry, string $why): void
+ case EntryBeforeDisplay = 'entry_before_display'; // function(FreshRSS_Entry $entry) -> FreshRSS_Entry | null
+ case EntryBeforeInsert = 'entry_before_insert'; // function(FreshRSS_Entry $entry) -> FreshRSS_Entry | null
+ case EntryBeforeAdd = 'entry_before_add'; // function(FreshRSS_Entry $entry) -> FreshRSS_Entry | null
+ case EntryBeforeUpdate = 'entry_before_update'; // function(FreshRSS_Entry $entry) -> FreshRSS_Entry | null
+ case FeedBeforeActualize = 'feed_before_actualize'; // function(FreshRSS_Feed $feed) -> FreshRSS_Feed | null
+ case FeedBeforeInsert = 'feed_before_insert'; // function(FreshRSS_Feed $feed) -> FreshRSS_Feed | null
+ case FreshrssInit = 'freshrss_init'; // function() -> none
+ case FreshrssUserMaintenance = 'freshrss_user_maintenance'; // function() -> none
+ case JsVars = 'js_vars'; // function($vars = array) -> array | null
+ case MenuAdminEntry = 'menu_admin_entry'; // function() -> string
+ case MenuConfigurationEntry = 'menu_configuration_entry'; // function() -> string
+ case MenuOtherEntry = 'menu_other_entry'; // function() -> string
+ case NavMenu = 'nav_menu'; // function() -> string
+ case NavReadingModes = 'nav_reading_modes'; // function($readingModes = array) -> array | null
+ case PostUpdate = 'post_update'; // function(none) -> none
+ case SimplepieAfterInit = 'simplepie_after_init'; // function(\SimplePie\SimplePie $simplePie, FreshRSS_Feed $feed, bool $result): void
+ case SimplepieBeforeInit = 'simplepie_before_init'; // function(\SimplePie\SimplePie $simplePie, FreshRSS_Feed $feed): void
+ case ViewModes = 'view_modes'; // function($viewModes = array) -> array | null
+
+ public function signature(): Minz_HookSignature {
+ switch ($this) {
+ case Minz_HookType::ApiMisc:
+ case Minz_HookType::FreshrssInit:
+ case Minz_HookType::FreshrssUserMaintenance:
+ case Minz_HookType::PostUpdate:
+ return Minz_HookSignature::NoneToNone;
+ case Minz_HookType::BeforeLoginBtn:
+ case Minz_HookType::MenuAdminEntry:
+ case Minz_HookType::MenuConfigurationEntry:
+ case Minz_HookType::MenuOtherEntry:
+ case Minz_HookType::NavMenu:
+ return Minz_HookSignature::NoneToString;
+ case Minz_HookType::CheckUrlBeforeAdd:
+ case Minz_HookType::EntryBeforeDisplay:
+ case Minz_HookType::EntryBeforeInsert:
+ case Minz_HookType::EntryBeforeAdd:
+ case Minz_HookType::EntryBeforeUpdate:
+ case Minz_HookType::FeedBeforeActualize:
+ case Minz_HookType::FeedBeforeInsert:
+ case Minz_HookType::JsVars:
+ case Minz_HookType::NavReadingModes:
+ case Minz_HookType::ViewModes:
+ return Minz_HookSignature::OneToOne;
+ case Minz_HookType::CustomFaviconBtnUrl:
+ case Minz_HookType::CustomFaviconHash:
+ case Minz_HookType::EntriesFavorite:
+ case Minz_HookType::EntryAutoRead:
+ case Minz_HookType::EntryAutoUnread:
+ case Minz_HookType::SimplepieAfterInit:
+ case Minz_HookType::SimplepieBeforeInit:
+ return Minz_HookSignature::PassArguments;
+ default:
+ throw new \RuntimeException('The hook is not configured!');
+ }
+ }
+}
diff --git a/p/api/fever.php b/p/api/fever.php
index 420a17f64..76e3a4ac3 100644
--- a/p/api/fever.php
+++ b/p/api/fever.php
@@ -519,7 +519,7 @@ final class FeverAPI
foreach ($entries as $item) {
/** @var FreshRSS_Entry|null $entry */
- $entry = Minz_ExtensionManager::callHook('entry_before_display', $item);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeDisplay, $item);
if ($entry === null) {
continue;
}
diff --git a/p/api/greader.php b/p/api/greader.php
index 6b67a7451..538292f58 100644
--- a/p/api/greader.php
+++ b/p/api/greader.php
@@ -570,7 +570,7 @@ final class GReaderAPI {
$items = [];
foreach ($entries as $item) {
/** @var FreshRSS_Entry|null $entry */
- $entry = Minz_ExtensionManager::callHook('entry_before_display', $item);
+ $entry = Minz_ExtensionManager::callHook(Minz_HookType::EntryBeforeDisplay, $item);
if ($entry === null) {
continue;
}
diff --git a/p/api/misc.php b/p/api/misc.php
index fe75b5be7..928c0b6e6 100644
--- a/p/api/misc.php
+++ b/p/api/misc.php
@@ -63,6 +63,6 @@ Minz_ExtensionManager::init();
Minz_Translate::init();
-if (!Minz_ExtensionManager::callHookUnique('api_misc')) {
+if (!Minz_ExtensionManager::callHookUnique(Minz_HookType::ApiMisc)) {
serviceUnavailable();
}