danielebarchiesi@0
|
1 <p>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.</p>
|
danielebarchiesi@0
|
2
|
danielebarchiesi@0
|
3 <p>Modules support this API by implementing hook_ctools_plugin_api($module, $api). If they support the API, they return a packet of data:</p>
|
danielebarchiesi@0
|
4
|
danielebarchiesi@0
|
5 <pre>
|
danielebarchiesi@0
|
6 function mymodule_ctools_plugin_api($module, $api) {
|
danielebarchiesi@0
|
7 if ($module == 'some module' && $api = 'some api') {
|
danielebarchiesi@0
|
8 return array(
|
danielebarchiesi@0
|
9 'version' => The minimum API version this system supports. If this API version is incompatible then the .inc file will not be loaded.
|
danielebarchiesi@0
|
10 'path' => Where to find the file. Optional; if not specified it will be the module's directory.
|
danielebarchiesi@0
|
11 'file' => an alternative version of the filename. If not specified it will be $module.$api.inc
|
danielebarchiesi@0
|
12 );
|
danielebarchiesi@0
|
13 }
|
danielebarchiesi@0
|
14 }
|
danielebarchiesi@0
|
15 </pre>
|
danielebarchiesi@0
|
16
|
danielebarchiesi@0
|
17 <p>This implementation must be in the .module file.</p>
|
danielebarchiesi@0
|
18
|
danielebarchiesi@0
|
19 <p>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:</p>
|
danielebarchiesi@0
|
20
|
danielebarchiesi@0
|
21 <pre>
|
danielebarchiesi@0
|
22 define('MYMODULE_MINIMUM_VERSION', 1);
|
danielebarchiesi@0
|
23 define('MYMODULE_VERSION', 1);
|
danielebarchiesi@0
|
24
|
danielebarchiesi@0
|
25 function mymodule_include_api() {
|
danielebarchiesi@0
|
26 ctools_include('plugins');
|
danielebarchiesi@0
|
27 return ctools_plugin_api_include('mymodule', 'myapi', MYMODULE_MINIMUM_VERSION, MYMODULE_VERSION);
|
danielebarchiesi@0
|
28 }
|
danielebarchiesi@0
|
29 </pre>
|
danielebarchiesi@0
|
30
|
danielebarchiesi@0
|
31 <p>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:</p>
|
danielebarchiesi@0
|
32
|
danielebarchiesi@0
|
33 <pre>
|
danielebarchiesi@0
|
34 mymodule_include_api();
|
danielebarchiesi@0
|
35 module_invoke('myhook', $data);
|
danielebarchiesi@0
|
36 </pre>
|
danielebarchiesi@0
|
37
|
danielebarchiesi@0
|
38 <p>If you need to pass references, this construct is standard:</p>
|
danielebarchiesi@0
|
39
|
danielebarchiesi@0
|
40 <pre>
|
danielebarchiesi@0
|
41 foreach (mymodule_include_api() as $module => $info) {
|
danielebarchiesi@0
|
42 $function = $module . '_hookname';
|
danielebarchiesi@0
|
43 // Just because they implement the API and include a file does not guarantee they implemented
|
danielebarchiesi@0
|
44 // a hook function!
|
danielebarchiesi@0
|
45 if (!function_exists($function)) {
|
danielebarchiesi@0
|
46 continue;
|
danielebarchiesi@0
|
47 }
|
danielebarchiesi@0
|
48
|
danielebarchiesi@0
|
49 // Typically array_merge() is used below if data is returned.
|
danielebarchiesi@0
|
50 $result = $function($data1, $data2, $data3);
|
danielebarchiesi@0
|
51 }
|
danielebarchiesi@0
|
52 </pre>
|
danielebarchiesi@0
|
53
|
danielebarchiesi@0
|
54 <p>TODO: There needs to be a way to check API version without including anything, as a module may simply
|
danielebarchiesi@0
|
55 provide normal plugins and versioning could still matter.</p>
|