From e73adde5fb159c68e54032a950596f8510edfcb0 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 13 Jan 2023 21:10:59 -0500 Subject: [PATCH 1/2] Remove App dependency from Hook::callSingle - This was causing a circular dependency with the logger_instance hook --- doc/Addons.md | 31 ++++++++++-------------------- doc/de/Addons.md | 17 +++++++--------- src/Core/Hook.php | 11 +++++------ src/Module/Settings/Addons.php | 7 ++----- src/Module/Settings/Connectors.php | 9 +++------ src/Worker/Expire.php | 2 +- src/Worker/ForkHook.php | 4 +--- view/theme/frio/theme.php | 23 ++++++++-------------- 8 files changed, 37 insertions(+), 67 deletions(-) diff --git a/doc/Addons.md b/doc/Addons.md index 171b5681a..dbb2c501f 100644 --- a/doc/Addons.md +++ b/doc/Addons.md @@ -60,25 +60,14 @@ This *should* be 'addon/*addon_name*/*addon_name*.php' in most cases and can be `$function` is a string and is the name of the function which will be executed when the hook is called. ### Arguments -Your hook callback functions will be called with at least one and possibly two arguments +Your hook callback functions will be called with at most one argument - function _(App $a, &$b) { + function _(&$b) { } If you wish to make changes to the calling data, you must declare them as reference variables (with `&`) during function declaration. -#### $a -$a is the Friendica `App` class. -It contains a wealth of information about the current state of Friendica: - -* which module has been called, -* configuration information, -* the page contents at the point the hook was invoked, -* profile and user information, etc. - -It is recommeded you call this `$a` to match its usage elsewhere. - #### $b $b can be called anything you like. This is information specific to the hook currently being processed, and generally contains information that is being immediately processed or acted on that you can use, display, or alter. @@ -88,7 +77,7 @@ Remember to declare it with `&` if you wish to alter it. Your addon can provide user-specific settings via the `addon_settings` PHP hook, but it can also provide node-wide settings in the administration page of your addon. -Simply declare a `_addon_admin(App $a)` function to display the form and a `_addon_admin_post(App $a)` function to process the data from the form. +Simply declare a `_addon_admin()` function to display the form and a `_addon_admin_post()` function to process the data from the form.0 ## Global stylesheets @@ -102,7 +91,7 @@ function _install() } -function _head(App $a) +function _head() { \Friendica\DI::page()->registerStylesheet(__DIR__ . '/relative/path/to/addon/stylesheet.css'); } @@ -124,7 +113,7 @@ function _install() ... } -function _footer(App $a) +function _footer() { \Friendica\DI::page()->registerFooterScript(__DIR__ . '/relative/path/to/addon/script.js'); } @@ -167,9 +156,9 @@ DI::args()->get(1); // = 'arg1' DI::args()->get(2); // = 'arg2' ``` -To display a module page, you need to declare the function `_content(App $a)`, which defines and returns the page body content. -They may also contain `_post(App $a)` which is called before the `_content` function and typically handles the results of POST forms. -You may also have `_init(App $a)` which is called before `_content` and should include common logic to your module. +To display a module page, you need to declare the function `_content()`, which defines and returns the page body content. +They may also contain `_post()` which is called before the `_content` function and typically handles the results of POST forms. +You may also have `_init()` which is called before `_content` and should include common logic to your module. ## Templates @@ -209,7 +198,7 @@ Called when a user attempts to login. ### logged_in Called after a user has successfully logged in. -`$b` contains the `$a->user` array. +`$b` contains the `App->user` array. ### display_item Called when formatting a post for display. @@ -360,7 +349,7 @@ Called prior to output of profile edit page. ### profile_advanced Called when the HTML is generated for the Advanced profile, corresponding to the Profile tab within a person's profile page. `$b` is the HTML string representation of the generated profile. -The profile array details are in `$a->profile`. +The profile array details are in `App->profile`. ### directory_item Called from the Directory page when formatting an item for display. diff --git a/doc/de/Addons.md b/doc/de/Addons.md index 143e309cb..73f2aeb45 100644 --- a/doc/de/Addons.md +++ b/doc/de/Addons.md @@ -38,17 +38,14 @@ $function ist ein String und der Name der Funktion, die ausgeführt wird, wenn d Argumente --- -Deine Hook-Callback-Funktion wird mit mindestens einem und bis zu zwei Argumenten aufgerufen +Deine Hook-Callback-Funktion wird mit höchstens einem Argumenten aufgerufen - function myhook_function(App $a, &$b) { + function myhook_function(&$b) { } Wenn du Änderungen an den aufgerufenen Daten vornehmen willst, musst du diese als Referenzvariable (mit "&") während der Funktionsdeklaration deklarieren. -$a ist die Friendica "App"-Klasse, die eine Menge an Informationen über den aktuellen Friendica-Status beinhaltet, u.a. welche Module genutzt werden, Konfigurationsinformationen, Inhalte der Seite zum Zeitpunkt des Hook-Aufrufs. -Es ist empfohlen, diese Funktion "$a" zu nennen, um seine Nutzung an den Gebrauch an anderer Stelle anzugleichen. - $b kann frei benannt werden. Diese Information ist speziell auf den Hook bezogen, der aktuell bearbeitet wird, und beinhaltet normalerweise Daten, die du sofort nutzen, anzeigen oder bearbeiten kannst. Achte darauf, diese mit "&" zu deklarieren, wenn du sie bearbeiten willst. @@ -70,9 +67,9 @@ DI::args()->get(1); // = 'arg1' DI::args()->get(2); // = 'arg2' ``` -Deine Modulfunktionen umfassen oft die Funktion addon_name_content(App $a), welche den Seiteninhalt definiert und zurückgibt. -Sie können auch addon_name_post(App $a) umfassen, welches vor der content-Funktion aufgerufen wird und normalerweise die Resultate der POST-Formulare handhabt. -Du kannst ebenso addon_name_init(App $a) nutzen, was oft frühzeitig aufgerufen wird und das Modul initialisert. +Deine Modulfunktionen umfassen oft die Funktion `addon_name_content()`, welche den Seiteninhalt definiert und zurückgibt. +Sie können auch `addon_name_post()` umfassen, welches vor der content-Funktion aufgerufen wird und normalerweise die Resultate der POST-Formulare handhabt. +Du kannst ebenso `addon_name_init()` nutzen, was oft frühzeitig aufgerufen wird und das Modul initialisert. Derzeitige Hooks @@ -86,7 +83,7 @@ Derzeitige Hooks 'user_record' => die erfolgreiche Authentifizierung muss auch einen gültigen Nutzereintrag aus der Datenbank zurückgeben **'logged_in'** - wird aufgerufen, sobald ein Nutzer sich erfolgreich angemeldet hat. - $b beinhaltet den $a->Nutzer-Array + $b beinhaltet den `App->user` **'display_item'** - wird aufgerufen, wenn ein Beitrag für die Anzeige formatiert wird. @@ -122,7 +119,7 @@ Derzeitige Hooks **'profile_advanced'** - wird aufgerufen, wenn die HTML-Ausgabe für das "Advanced profile" generiert wird; stimmt mit dem "Profil"-Tab auf der Profilseite der Nutzer überein. $b ist die HTML-Ausgabe (String) des erstellten Profils - (Die Details des Profil-Arrays sind in $a->profile) + (Die Details des Profil-Arrays sind in `App->profile`) **'directory_item'** - wird von der Verzeichnisseite aufgerufen, wenn ein Item für die Anzeige formatiert wird. $b ist ein Array diff --git a/src/Core/Hook.php b/src/Core/Hook.php index 1145bd298..3167464a7 100644 --- a/src/Core/Hook.php +++ b/src/Core/Hook.php @@ -167,7 +167,7 @@ class Hook if ($hook[0] != $fork_hook[0]) { continue; } - self::callSingle(DI::app(), 'hook_fork', $fork_hook, $hookdata); + self::callSingle('hook_fork', $fork_hook, $hookdata); } if (!$hookdata['execute']) { @@ -195,7 +195,7 @@ class Hook { if (array_key_exists($name, self::$hooks)) { foreach (self::$hooks[$name] as $hook) { - self::callSingle(DI::app(), $name, $hook, $data); + self::callSingle($name, $hook, $data); } } } @@ -203,24 +203,23 @@ class Hook /** * Calls a single hook. * - * @param App $a * @param string $name of the hook to call * @param array $hook Hook data * @param string|array &$data to transmit to the callback handler * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function callSingle(App $a, string $name, array $hook, &$data = null) + public static function callSingle(string $name, array $hook, &$data = null) { // Don't run a theme's hook if the user isn't using the theme - if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/' . $a->getCurrentTheme()) === false) { + if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/' . DI::app()->getCurrentTheme()) === false) { return; } @include_once($hook[0]); if (function_exists($hook[1])) { $func = $hook[1]; - $func($a, $data); + $func($data); } else { // remove orphan hooks $condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]]; diff --git a/src/Module/Settings/Addons.php b/src/Module/Settings/Addons.php index ac2d188c0..b6ac406ba 100644 --- a/src/Module/Settings/Addons.php +++ b/src/Module/Settings/Addons.php @@ -36,15 +36,12 @@ class Addons extends BaseSettings { /** @var Database */ private $database; - /** @var App */ - private $app; - public function __construct(App $app, Database $database, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) + public function __construct(Database $database, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) { parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); $this->database = $database; - $this->app = $app; } protected function post(array $request = []) @@ -62,7 +59,7 @@ class Addons extends BaseSettings $addon_settings_forms = []; foreach ($this->database->selectToArray('hook', ['file', 'function'], ['hook' => 'addon_settings']) as $hook) { $data = []; - Hook::callSingle($this->app, 'addon_settings', [$hook['file'], $hook['function']], $data); + Hook::callSingle('addon_settings', [$hook['file'], $hook['function']], $data); if (!empty($data['href'])) { $tpl = Renderer::getMarkupTemplate('settings/addons/link.tpl'); diff --git a/src/Module/Settings/Connectors.php b/src/Module/Settings/Connectors.php index 1070355bf..7c053e168 100644 --- a/src/Module/Settings/Connectors.php +++ b/src/Module/Settings/Connectors.php @@ -49,10 +49,8 @@ class Connectors extends BaseSettings private $database; /** @var SystemMessages */ private $systemMessages; - /** @var App */ - private $app; - public function __construct(App $app, SystemMessages $systemMessages, Database $database, IManagePersonalConfigValues $pconfig, IManageConfigValues $config, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) + public function __construct(SystemMessages $systemMessages, Database $database, IManagePersonalConfigValues $pconfig, IManageConfigValues $config, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) { parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); @@ -60,7 +58,6 @@ class Connectors extends BaseSettings $this->pconfig = $pconfig; $this->database = $database; $this->systemMessages = $systemMessages; - $this->app = $app; } protected function post(array $request = []) @@ -146,7 +143,7 @@ class Connectors extends BaseSettings $connector_settings_forms = []; foreach ($this->database->selectToArray('hook', ['file', 'function'], ['hook' => 'connector_settings']) as $hook) { $data = []; - Hook::callSingle($this->app, 'connector_settings', [$hook['file'], $hook['function']], $data); + Hook::callSingle('connector_settings', [$hook['file'], $hook['function']], $data); $tpl = Renderer::getMarkupTemplate('settings/addons/connector.tpl'); $connector_settings_forms[$data['connector']] = Renderer::replaceMacros($tpl, [ @@ -160,7 +157,7 @@ class Connectors extends BaseSettings ]); } - if ($this->app->isSiteAdmin()) { + if ($this->session->isSiteAdmin()) { $diasp_enabled = $this->config->get('system', 'diaspora_enabled') ? $this->t('Built-in support for %s connectivity is enabled', $this->t('Diaspora (Socialhome, Hubzilla)')) : $this->t('Built-in support for %s connectivity is disabled', $this->t('Diaspora (Socialhome, Hubzilla)')); diff --git a/src/Worker/Expire.php b/src/Worker/Expire.php index 9e907dcfc..15a935534 100644 --- a/src/Worker/Expire.php +++ b/src/Worker/Expire.php @@ -51,7 +51,7 @@ class Expire foreach (Hook::getByName('expire') as $hook) { if ($hook[1] == $hook_function) { Logger::info('Calling expire hook', ['hook' => $hook[1]]); - Hook::callSingle($a, 'expire', $hook, $data); + Hook::callSingle('expire', $hook, $data); } } return; diff --git a/src/Worker/ForkHook.php b/src/Worker/ForkHook.php index da9fe990a..406dcd171 100644 --- a/src/Worker/ForkHook.php +++ b/src/Worker/ForkHook.php @@ -28,8 +28,6 @@ Class ForkHook { public static function execute($name, $hook, $data) { - $a = DI::app(); - - Hook::callSingle($a, $name, $hook, $data); + Hook::callSingle($name, $hook, $data); } } diff --git a/view/theme/frio/theme.php b/view/theme/frio/theme.php index 253a55ec4..05e45163f 100644 --- a/view/theme/frio/theme.php +++ b/view/theme/frio/theme.php @@ -26,18 +26,14 @@ use Friendica\App; use Friendica\Content\Text\Plaintext; -use Friendica\Content\Widget; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; -use Friendica\Model; -use Friendica\Model\Item; use Friendica\Model\Contact; +use Friendica\Model\Item; use Friendica\Model\Profile; -use Friendica\Module; -use Friendica\Util\Strings; const FRIO_SCHEME_ACCENT_BLUE = '#1e87c2'; const FRIO_SCHEME_ACCENT_RED = '#b50404'; @@ -89,10 +85,9 @@ function frio_install() * to the photo file. This function is nessesary to use colorbox * in the network stream * - * @param App $a Unused but required by hook definition * @param array $body_info The item and its html output */ -function frio_item_photo_links(App $a, &$body_info) +function frio_item_photo_links(&$body_info) { $occurence = 0; $p = Plaintext::getBoundariesPosition($body_info['html'], ''); @@ -125,10 +120,9 @@ function frio_item_photo_links(App $a, &$body_info) * to call the addToModal javascript function so this pages can * be loaded in a bootstrap modal * - * @param App $a Unused but required by the hook definition * @param array $arr Contains item data and the original photo_menu */ -function frio_item_photo_menu(App $a, &$arr) +function frio_item_photo_menu(&$arr) { foreach ($arr['menu'] as $k => $v) { if (strpos($v, 'message/new/') === 0) { @@ -147,10 +141,9 @@ function frio_item_photo_menu(App $a, &$arr) * Additionally the profile, status and photo page links will be changed * to don't open in a new tab if the contact is a friendica contact. * - * @param App $a The app data * @param array $args Contains contact data and the original photo_menu */ -function frio_contact_photo_menu(App $a, &$args) +function frio_contact_photo_menu(&$args) { $cid = $args['contact']['id']; @@ -199,7 +192,7 @@ function frio_contact_photo_menu(App $a, &$args) * @param array $nav_info The original nav info array: nav, banner, userinfo, sitelocation * @throws Exception */ -function frio_remote_nav(App $a, array &$nav_info) +function frio_remote_nav(array &$nav_info) { if (DI::mode()->has(App\Mode::MAINTENANCEDISABLED)) { // get the homelink from $_SESSION @@ -211,8 +204,8 @@ function frio_remote_nav(App $a, array &$nav_info) // since $userinfo isn't available for the hook we write it to the nav array // this isn't optimal because the contact query will be done now twice $fields = ['id', 'url', 'avatar', 'micro', 'name', 'nick', 'baseurl', 'updated']; - if ($a->isLoggedIn()) { - $remoteUser = Contact::selectFirst($fields, ['uid' => $a->getLoggedInUserId(), 'self' => true]); + if (DI::userSession()->isAuthenticated()) { + $remoteUser = Contact::selectFirst($fields, ['uid' => DI::userSession()->getLocalUserId(), 'self' => true]); } elseif (!DI::userSession()->getLocalUserId() && DI::userSession()->getRemoteUserId()) { $remoteUser = Contact::getById(DI::userSession()->getRemoteUserId(), $fields); $nav_info['nav']['remote'] = DI::l10n()->t('Guest'); @@ -253,7 +246,7 @@ function frio_remote_nav(App $a, array &$nav_info) } } -function frio_display_item(App $a, &$arr) +function frio_display_item(&$arr) { // Add follow to the item menu $followThread = []; From 45a6888647820f2e46522c631764722350ae8138 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sat, 14 Jan 2023 09:46:49 -0500 Subject: [PATCH 2/2] Update tests after removing App dependency from hook calls --- tests/Util/SampleStorageBackendInstance.php | 2 +- tests/Util/authtest/authtest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Util/SampleStorageBackendInstance.php b/tests/Util/SampleStorageBackendInstance.php index 196ef4c61..c1c2869e3 100644 --- a/tests/Util/SampleStorageBackendInstance.php +++ b/tests/Util/SampleStorageBackendInstance.php @@ -25,7 +25,7 @@ use Friendica\Core\L10n; use Friendica\Test\Util\SampleStorageBackend; use Mockery\MockInterface; -function create_instance(App $a, &$data) +function create_instance(&$data) { /** @var L10n|MockInterface $l10n */ $l10n = \Mockery::mock(L10n::class); diff --git a/tests/Util/authtest/authtest.php b/tests/Util/authtest/authtest.php index 7252b6653..ca46d53e4 100644 --- a/tests/Util/authtest/authtest.php +++ b/tests/Util/authtest/authtest.php @@ -14,7 +14,7 @@ function authtest_install() Hook::register('authenticate', 'tests/Util/authtest/authtest.php', 'authtest_authenticate'); } -function authtest_authenticate($a,&$b) +function authtest_authenticate(&$b) { $b['authenticated'] = \Friendica\Test\Util\AuthTestConfig::$authenticated; $b['user_record'] = User::getById(\Friendica\Test\Util\AuthTestConfig::$user_id);