From 0a5d33a151e89648ab9fc7f495c909d29fb3767a Mon Sep 17 00:00:00 2001 From: Earl Miles <merlin@logrus.com> Date: Tue, 13 Jan 2009 18:07:56 +0000 Subject: [PATCH] Update plugins to be able to easily handle the $module.views.inc style of includes. --- delegator/plugins/tasks/node_view.inc | 9 ++++ help/plugins-api.html | 46 +++++++++++++++++++ help/plugins-creating.html | 3 +- includes/plugins.inc | 64 +++++++++++++++++++++++++++ plugins/access/node_access.inc | 2 +- 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 help/plugins-api.html diff --git a/delegator/plugins/tasks/node_view.inc b/delegator/plugins/tasks/node_view.inc index 827a2cc7..a02cb0ef 100644 --- a/delegator/plugins/tasks/node_view.inc +++ b/delegator/plugins/tasks/node_view.inc @@ -1,6 +1,15 @@ <?php // $Id$ +/** + * @file + * Handle the 'node view' override task. + * + * This plugin overrides node/%node and reroutes it to the delegator, where + * a list of tasks can be used to service this request based upon criteria + * supplied by access plugins. + */ + /** * Specialized implementation of hook_delegator_tasks(). See api-task.html for * more information. diff --git a/help/plugins-api.html b/help/plugins-api.html new file mode 100644 index 00000000..24a69e80 --- /dev/null +++ b/help/plugins-api.html @@ -0,0 +1,46 @@ +<!-- $Id$ --> + +APIs are a form of plugins that are tightly associated with a module. Instead of a module providing any number of plugins, each module provides only one file for an API and this file can contain hooks that the module should invoke. + +Modules support this API by implementing hook_ctools_plugin_api($module, $api). If they support the API, they return a packet of data: + +function mymodule_ctools_plugin_api($module, $api) { + if ($module == 'some module' && $api = 'some api') { + return array( + 'version' => The minimum API version this system supports. If this API version is incompatible then the .inc file will not be loaded. + 'path' => Where to find the file. Optional; if not specified it will be the module's directory. + 'file' => an alternative version of the filename. If not specified it will be $module.$api.inc + ); + } +} + +This implementation must be in the .module file. + +Modules utilizing this can invole ctools_plugin_api_include() in order to ensure all modules that support the API will have their files loaded as necessary. It's usually easiest to create a small helper function like this: + +define('MYMODULE_MINIMUM_VERSION', 1); +define('MYMODULE_VERSION', 1); + +function mymodule_include_api() { + ctools_include('plugins'); + return ctools_plugin_api_include('mymodule', 'myapi', MYMODULE_MINIMUM_VERSION, MYMODULE_VERSION); +} + +Using a define will ensure your use of version numbers is consistent and easy to update when you make API changes. You can then use the usual module_invoke type commands: + +mymodule_include_api(); +module_invoke('myhook', $data); + +If you need to pass references, this construct is standard: + +foreach (mymodule_include_api() as $module => $info) { + $function = $module . '_hookname'; + // Just because they implement the API and include a file does not guarantee they implemented + // a hook function! + if (!function_exists($function)) { + continue; + } + + // Typically array_merge() is used below if data is returned. + $result = $function($data1, $data2, $data3); +} \ No newline at end of file diff --git a/help/plugins-creating.html b/help/plugins-creating.html index ca020442..54c11c14 100644 --- a/help/plugins-creating.html +++ b/help/plugins-creating.html @@ -44,4 +44,5 @@ General feature for callbacks: 'function' => 'function_name' ), - Using ctools_plugin_get_function() or ctools_plugin_load_function() will take advantage. \ No newline at end of file + Using ctools_plugin_get_function() or ctools_plugin_load_function() will take advantage. + diff --git a/includes/plugins.inc b/includes/plugins.inc index 61235643..fce5132e 100644 --- a/includes/plugins.inc +++ b/includes/plugins.inc @@ -9,6 +9,70 @@ * necessary. */ +/** + * Load a group of API files. + * + * This will ask each module if they support the given API, and if they do + * it will load the specified file name. The API and the file name + * coincide by design. + * + * This function invokes hook_ctools_api. This invokation is statically + * cached, so feel free to call it as often per page run as you like, it + * will cost very little. + * + * @param $owner + * The name of the module that controls the API. + * @param $api + * The name of the api. The api name forms the file name: + * $module.$api.inc + * @param $minimum_version + * The lowest version API that is compatible with this one. If a module + * reports its API as older than this, its files will not be loaded. This + * should never change during operation. + * @param $current_version + * The current version of the api. If a module reports its minimum API as + * higher than this, its files will not be loaded. This should never change + * during operation. + * + * @return + * The API information, in case you need it. + */ +function ctools_plugin_api_include($owner, $api, $minimum_version, $current_version) { + static $cache = array(); + if (!isset($cache[$owner][$api])) { + $cache[$owner][$api] = array(); + foreach (module_implements('ctools_plugin_api') as $module) { + $function = $module . '_ctools_plugin_api'; + $info = $function(); + if (!isset($info['version'])) { + continue; + } + + // Only process if version is between minimum and current, inclusive. + if ($info['version'] >= $minimum_version && $info_version <= $current_version) { + if (!isset($info['path'])) { + $info['path'] = drupal_get_path('module', $module); + } + if (!isset($info['file'])) { + $info['file'] = "$module.$api.inc"; + } + $cache[$owner][$api][$module] = $info; + } + } + + // Now that we have a list, do our includes. + foreach ($cache[$owner][$api] as $module => $info) { + if (file_exists("./$info[path]/$info[file]")) { + $cache[$owner][$api][$module]['included'] = TRUE; + require_once "./$info[path]/$info[file]"; + } + } + + } + + return $cache[$module][$api]; +} + /** * Fetch a group of plugins by name. * diff --git a/plugins/access/node_access.inc b/plugins/access/node_access.inc index 55a9cc62..bf5393ce 100644 --- a/plugins/access/node_access.inc +++ b/plugins/access/node_access.inc @@ -11,7 +11,7 @@ */ function ctools_node_access_ctools_access() { $args['node_access'] = array( - 'title' => t("Node access"), + 'title' => t("Operation"), 'description' => t('Control access with built in Drupal node access test.'), 'callback' => 'ctools_node_access_ctools_access_check', 'default' => array('type' => 'view'), -- GitLab