Procházet zdrojové kódy

Add hooks to ExtensionManager (#2482)

Hooks allow to:

- add items in menus
- perform new actions at the end of FreshRSS initialization
Marien Fressinaud před 6 roky
rodič
revize
7fd88adeb0

+ 2 - 0
app/FreshRSS.php

@@ -53,6 +53,8 @@ class FreshRSS extends Minz_FrontController {
 			$ext_list = FreshRSS_Context::$user_conf->extensions_enabled;
 			Minz_ExtensionManager::enableByList($ext_list);
 		}
+
+		Minz_ExtensionManager::callHook('freshrss_init');
 	}
 
 	private static function initAuth() {

+ 3 - 0
app/layout/aside_configure.phtml

@@ -25,6 +25,8 @@
 	<li class="item<?php echo Minz_Request::controllerName() === 'extension' ? ' active' : ''; ?>">
 		<a href="<?php echo _url('extension', 'index'); ?>"><?php echo _t('gen.menu.extensions'); ?></a>
 	</li>
+	<?php echo Minz_ExtensionManager::callHook('menu_configuration_entry'); ?>
+
 	<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
 	<li class="nav-header"><?php echo _t('gen.menu.admin'); ?></li>
 	<li class="item<?php echo Minz_Request::actionName() === 'system' ? ' active' : ''; ?>">
@@ -47,5 +49,6 @@
 		<a href="<?php echo _url('update', 'index'); ?>"><?php echo _t('gen.menu.update'); ?></a>
 	</li>
 	<?php } ?>
+	<?php echo Minz_ExtensionManager::callHook('menu_admin_entry'); ?>
 	<?php } ?>
 </ul>

+ 6 - 0
app/layout/header.phtml

@@ -66,6 +66,8 @@ if (FreshRSS_Auth::accessNeedsAction()) {
 				<li class="item"><a href="<?php echo _url('configure', 'queries'); ?>"><?php echo _t('gen.menu.queries'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('user', 'profile'); ?>"><?php echo _t('gen.menu.user_profile'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('extension', 'index'); ?>"><?php echo _t('gen.menu.extensions'); ?></a></li>
+				<?php echo Minz_ExtensionManager::callHook('menu_configuration_entry'); ?>
+
 				<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
 				<li class="separator"></li>
 				<li class="dropdown-header"><?php echo _t('gen.menu.admin'); ?></li>
@@ -76,11 +78,15 @@ if (FreshRSS_Auth::accessNeedsAction()) {
 				<?php if (!Minz_Configuration::get('system')->disable_update) { ?>
 				<li class="item"><a href="<?php echo _url('update', 'index'); ?>"><?php echo _t('gen.menu.update'); ?></a></li>
 				<?php } ?>
+				<?php echo Minz_ExtensionManager::callHook('menu_admin_entry'); ?>
 				<?php } ?>
+
 				<li class="separator"></li>
 				<li class="item"><a href="<?php echo _url('stats', 'index'); ?>"><?php echo _t('gen.menu.stats'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('index', 'logs'); ?>"><?php echo _t('gen.menu.logs'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('gen.menu.about'); ?></a></li>
+				<?php echo Minz_ExtensionManager::callHook('menu_other_entry'); ?>
+
 				<li class="separator"></li>
 				<?php if (FreshRSS_Auth::accessNeedsAction()): ?>
 				<li class="item"><a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php

+ 13 - 7
docs/en/developers/03_Backend/05_Extensions.md

@@ -358,18 +358,24 @@ class HelloWorldExtension extends Minz_Extension
         $entry->_content('<h1>Hello World</h1>' . $entry->content());
         return $entry;
     }
-}    
+}
 ```
+
 The following events are available:
 
-- `entry_before_display` (`function($entry) -> Entry | null`) : will be executed every time an entry is rendered. The entry itself (instance of FreshRSS_Entry) will be passed as parameter. 
-- `entry_before_insert` (`function($entry) -> Entry | null`) : will be executed when a feed is refreshed and new entries will be imported into the database. The new entry (instance of FreshRSS_Entry) will be passed as parameter. 
-- `feed_before_insert` (`function($feed) -> Feed | null`) : will be executed when a new feed is imported into the database. The new feed (instance of FreshRSS_Feed) will be passed as parameter. 
-- `post_update` (`function(none) -> none`) : **TODO** add documentation
-- `simplepie_before_init` (`function($simplePie, $feed) -> none`) : **TODO** add documentation
+- `entry_before_display` (`function($entry) -> Entry | null`): will be executed every time an entry is rendered. The entry itself (instance of FreshRSS\_Entry) will be passed as parameter.
+- `entry_before_insert` (`function($entry) -> Entry | null`): will be executed when a feed is refreshed and new entries will be imported into the database. The new entry (instance of FreshRSS\_Entry) will be passed as parameter.
+- `feed_before_insert` (`function($feed) -> Feed | null`): will be executed when a new feed is imported into the database. The new feed (instance of FreshRSS\_Feed) will be passed as parameter.
+- `freshrss_init` (`function() -> none`): will be executed at the end of the initialization of FreshRSS, useful to initialize components or to do additional access checks
+- `menu_admin_entry` (`function() -> string`): add an entry at the end of the "Administration" menu, the returned string must be valid HTML (e.g. `<li class="item active"><a href="url">New entry</a></li>`)
+- `menu_configuration_entry` (`function() -> string`): add an entry at the end of the "Configuration" menu, the returned string must be valid HTML (e.g. `<li class="item active"><a href="url">New entry</a></li>`)
+- `menu_other_entry` (`function() -> string`): add an entry at the end of the header dropdown menu (i.e. after the "About" entry), the returned string must be valid HTML (e.g. `<li class="item active"><a href="url">New entry</a></li>`)
+- `nav_reading_modes` (`function($reading_modes) -> array | null`): **TODO** add documentation
+- `post_update` (`function(none) -> none`): **TODO** add documentation
+- `simplepie_before_init` (`function($simplePie, $feed) -> none`): **TODO** add documentation
 
 ### Writing your own configure.phtml
 
-When you want to support user configurations for your extension or simply display some information, you have to create the `configure.phtml` file. 
+When you want to support user configurations for your extension or simply display some information, you have to create the `configure.phtml` file.
 
 **TODO**

+ 34 - 1
lib/Minz/ExtensionManager.php

@@ -27,14 +27,30 @@ class Minz_ExtensionManager {
 			'list' => array(),
 			'signature' => 'OneToOne',
 		),
-		'post_update' => array(  // function(none) -> none
+		'freshrss_init' => array(  // function() -> none
 			'list' => array(),
 			'signature' => 'NoneToNone',
 		),
+		'menu_admin_entry' => array(  // function() -> string
+			'list' => array(),
+			'signature' => 'NoneToString',
+		),
+		'menu_configuration_entry' => array(  // function() -> string
+			'list' => array(),
+			'signature' => 'NoneToString',
+		),
+		'menu_other_entry' => array(  // function() -> string
+			'list' => array(),
+			'signature' => 'NoneToString',
+		),
 		'nav_reading_modes' => array(  // function($readingModes = array) -> array | null
 			'list' => array(),
 			'signature' => 'OneToOne',
 		),
+		'post_update' => array(  // function(none) -> none
+			'list' => array(),
+			'signature' => 'NoneToNone',
+		),
 		'simplepie_before_init' => array(  // function($simplePie, $feed) -> none
 			'list' => array(),
 			'signature' => 'PassArguments',
@@ -306,6 +322,23 @@ class Minz_ExtensionManager {
 		return $result;
 	}
 
+	/**
+	 * Call a hook which takes no argument and returns a string.
+	 *
+	 * The result is concatenated between each hook and the final string is
+	 * returned.
+	 *
+	 * @param string $hook_name is the hook to call.
+	 * @return a concatenated string, result of the call to all the hooks.
+	 */
+	private static function callNoneToString($hook_name) {
+		$result = '';
+		foreach (self::$hook_list[$hook_name]['list'] as $function) {
+			$result = $result . call_user_func($function);
+		}
+		return $result;
+	}
+
 	/**
 	 * Call a hook which takes no argument and returns nothing.
 	 *