mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2025-12-23 21:47:44 -05:00
Add hook enums (#8036)
- add an enum to handle hook types (enum are available since PHP 8.1) - change hook calls from string value to enum value
This commit is contained in:
committed by
GitHub
parent
bf6e634e04
commit
72884813e1
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<a href="<?= _url('index', 'logs') ?>"><?= _t('gen.menu.logs') ?></a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?= Minz_ExtensionManager::callHookString('menu_configuration_entry') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::MenuConfigurationEntry) ?>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<li class="item<?= Minz_Request::actionName() === 'logs' ? ' active' : '' ?>">
|
||||
<a href="<?= _url('index', 'logs') ?>"><?= _t('gen.menu.logs') ?></a>
|
||||
</li>
|
||||
<?= Minz_ExtensionManager::callHookString('menu_admin_entry') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::MenuAdminEntry) ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<li class="item"><a href="<?= _url('configure', 'queries') ?>"><?= _t('gen.menu.queries') ?></a></li>
|
||||
<li class="item"><a href="<?= _url('extension', 'index') ?>"><?= _t('gen.menu.extensions') ?></a></li>
|
||||
<li class="item"><a href="<?= _url('configure', 'privacy') ?>"><?= _t('gen.menu.privacy') ?></a></li>
|
||||
<?= Minz_ExtensionManager::callHookString('menu_configuration_entry') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::MenuConfigurationEntry) ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
|
||||
@@ -103,7 +103,7 @@
|
||||
<?php if (!FreshRSS_Context::systemConf()->disable_update) { ?>
|
||||
<li class="item"><a href="<?= _url('update', 'index') ?>"><?= _t('gen.menu.update') ?></a></li>
|
||||
<?php } ?>
|
||||
<?= Minz_ExtensionManager::callHookString('menu_admin_entry') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::MenuAdminEntry) ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php } ?>
|
||||
@@ -117,7 +117,7 @@
|
||||
<a href="<?= _url('index', 'tos') ?>"><?= _t('index.tos.title')?></a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?= Minz_ExtensionManager::callHookString('menu_other_entry') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::MenuOtherEntry) ?>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
<div id="nav_menu_views" class="group">
|
||||
<?php
|
||||
$readingModes = FreshRSS_ReadingMode::getReadingModes();
|
||||
$readingModes = Minz_ExtensionManager::callHook('nav_reading_modes', $readingModes);
|
||||
$readingModes = Minz_ExtensionManager::callHook(Minz_HookType::NavReadingModes, $readingModes);
|
||||
if (!is_iterable($readingModes)) {
|
||||
$readingModes = FreshRSS_ReadingMode::getReadingModes();
|
||||
}
|
||||
@@ -207,7 +207,7 @@
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php $nav_menu_hooks = Minz_ExtensionManager::callHookString('nav_menu'); ?>
|
||||
<?php $nav_menu_hooks = Minz_ExtensionManager::callHookString(Minz_HookType::NavMenu); ?>
|
||||
<?php if ($nav_menu_hooks != '') { ?>
|
||||
<div id="nav_menu_hooks" class="group">
|
||||
<?= $nav_menu_hooks ?>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<?= Minz_ExtensionManager::callHookString('before_login_btn') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::BeforeLoginBtn) ?>
|
||||
|
||||
<div class="form-group form-group-actions">
|
||||
<button id="loginButton" type="submit" class="btn btn-important" disabled="disabled">
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<?= Minz_ExtensionManager::callHookString('before_login_btn') ?>
|
||||
<?= Minz_ExtensionManager::callHookString(Minz_HookType::BeforeLoginBtn) ?>
|
||||
|
||||
<div class="form-group form-group-actions">
|
||||
<?php
|
||||
|
||||
@@ -22,7 +22,7 @@ if (empty($this->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;
|
||||
|
||||
@@ -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);
|
||||
?>
|
||||
<div class="group-name"><?= _t('sub.feed.icon') ?></div>
|
||||
<div class="group-controls">
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -19,114 +19,9 @@ final class Minz_ExtensionManager {
|
||||
|
||||
/**
|
||||
* List of available hooks. Please keep this list sorted.
|
||||
* @var array<string,array{'list':array<callable>,'signature':'NoneToNone'|'NoneToString'|'OneToOne'|'PassArguments'}>
|
||||
* @var array<value-of<Minz_HookType>,array{'list':list<callable>,'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;
|
||||
|
||||
9
lib/Minz/HookSignature.php
Normal file
9
lib/Minz/HookSignature.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
enum Minz_HookSignature {
|
||||
case NoneToNone;
|
||||
case NoneToString;
|
||||
case OneToOne;
|
||||
case PassArguments;
|
||||
}
|
||||
68
lib/Minz/HookType.php
Normal file
68
lib/Minz/HookType.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
enum Minz_HookType: string {
|
||||
case ApiMisc = 'api_misc'; // function(): void
|
||||
case BeforeLoginBtn = 'before_login_btn'; // function(): string
|
||||
case CheckUrlBeforeAdd = 'check_url_before_add'; // function(string $url) -> 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!');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,6 @@ Minz_ExtensionManager::init();
|
||||
|
||||
Minz_Translate::init();
|
||||
|
||||
if (!Minz_ExtensionManager::callHookUnique('api_misc')) {
|
||||
if (!Minz_ExtensionManager::callHookUnique(Minz_HookType::ApiMisc)) {
|
||||
serviceUnavailable();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user