1 | <?php |
||
2 | /** |
||
3 | * @package midcom.routing |
||
4 | * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||
5 | * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||
6 | * @license http://www.gnu.org/licenses/gpl.html GNU General Public License |
||
7 | */ |
||
8 | |||
9 | namespace midcom\routing; |
||
10 | |||
11 | use midcom; |
||
12 | use midcom_admin_folder_management; |
||
13 | use midcom_admin_rcs_plugin; |
||
14 | use midcom_helper_imagepopup_viewer; |
||
15 | use midcom_admin_help_help; |
||
16 | use midgard_admin_asgard_plugin; |
||
17 | use midcom_error; |
||
18 | |||
19 | /** |
||
20 | * <b>Plugin Interface</b> |
||
21 | * |
||
22 | * This class includes a plugin system which can be used to flexibly enhance the |
||
23 | * functionality of the request classes by external sources. Your component does |
||
24 | * not have to worry about this, you just have to provide a way to register plugins |
||
25 | * to site authors. |
||
26 | * |
||
27 | * Plugins always come in "packages", which are assigned to a namespace. The namespace |
||
28 | * is used to separate various plugins from each other, it is prepended before any |
||
29 | * URL. Within a plugin you can register one or more handler classes. Each of this |
||
30 | * classes can of course define more than one request handler. |
||
31 | * |
||
32 | * A plugin class must be a descendant of midcom_baseclasses_components_handler or at |
||
33 | * least support its full interface. |
||
34 | * |
||
35 | * As outlined above, plugins are managed in a two-level hierarchy. First, there is |
||
36 | * the plugin identifier, second the class identifier. When registering a plugin, |
||
37 | * these two are specified. The request handlers obtained by the above callback are |
||
38 | * automatically expanded to match the plugin namespace. |
||
39 | * |
||
40 | * <i>Example: Plugin registration</i> |
||
41 | * |
||
42 | * <code> |
||
43 | * $this->register_plugin_namespace( |
||
44 | * '__ais', [ |
||
45 | * 'folder' => [ |
||
46 | * 'class' => 'midcom_admin_folder_management', |
||
47 | * 'config' => null, |
||
48 | * ], |
||
49 | * ] |
||
50 | * ); |
||
51 | * </code> |
||
52 | * |
||
53 | * The first argument of this call identifies the plugin namespace, the second |
||
54 | * the list of classes associated with this plugin. Each class gets its own |
||
55 | * identifier. The namespace and plugin identifier is used to construct the |
||
56 | * final plugin URL: {$anchor_prefix}/{$namespace}/{$plugin_identifier}/... |
||
57 | * This gives fully unique URL namespaces to all registered plugins. |
||
58 | * |
||
59 | * Plugin handlers always last in queue, so they won't override component handlers. |
||
60 | * Their name is prefixed with __{$namespace}-{$plugin_identifier} to ensure |
||
61 | * uniqueness. |
||
62 | * |
||
63 | * Each entry has these options: |
||
64 | * |
||
65 | * - class: The name of the class to use |
||
66 | * - config: This is an optional configuration argument, allows for customization. |
||
67 | * May be omitted, in which case it defaults to null. |
||
68 | * |
||
69 | * Once a plugin has been successfully initialized, its configuration is put |
||
70 | * into the request data: |
||
71 | * |
||
72 | * - mixed plugin_config: The configuration passed to the plugin as outlined |
||
73 | * above. |
||
74 | * - string plugin_name: The name of the plugin as defined in its config |
||
75 | * |
||
76 | * @package midcom.routing |
||
77 | */ |
||
78 | class plugin |
||
79 | { |
||
80 | /** |
||
81 | * This variable keeps track of the registered plugin namespaces. It maps namespace |
||
82 | * identifiers against plugin config lists. |
||
83 | * |
||
84 | * You have to use the viewer's register_plugin_namespace() member function during the |
||
85 | * _on_initialize event to register plugin namespaces. |
||
86 | */ |
||
87 | private static array $registry = []; |
||
88 | |||
89 | /** |
||
90 | * Create a new plugin namespace and map the configuration to it. |
||
91 | * It allows flexible, user-configurable extension of components. |
||
92 | * |
||
93 | * Only very basic testing is done to keep runtime up, currently the system only |
||
94 | * checks to prevent duplicate namespace registrations. In such a case, |
||
95 | * midcom_error will be thrown. |
||
96 | * |
||
97 | * @param string $namespace The plugin namespace, checked against $args[0] during |
||
98 | * URL parsing. |
||
99 | * @param array $config The configuration of the plugin namespace as outlined in |
||
100 | * the class introduction |
||
101 | */ |
||
102 | 6 | public static function register_namespace(string $namespace, array $config) |
|
103 | { |
||
104 | 6 | self::init(); |
|
105 | 6 | if (array_key_exists($namespace, self::$registry)) { |
|
106 | 4 | throw new midcom_error("Tried to register the plugin namespace {$namespace}, but it is already registered."); |
|
107 | } |
||
108 | 2 | self::$registry[$namespace] = $config; |
|
109 | } |
||
110 | |||
111 | 291 | public static function get_config(string $namespace, string $name) : ?array |
|
112 | { |
||
113 | 291 | self::init(); |
|
114 | 291 | if (empty(self::$registry[$namespace][$name])) { |
|
115 | 203 | return null; |
|
116 | } |
||
117 | 88 | if (empty(self::$registry[$namespace][$name]['class']) || !class_exists(self::$registry[$namespace][$name]['class'])) { |
|
118 | throw new midcom_error("Failed to load the plugin {$namespace}/{$name}, implementation class not available."); |
||
119 | } |
||
120 | 88 | return self::$registry[$namespace][$name]; |
|
121 | } |
||
122 | |||
123 | /** |
||
124 | * Register the plugin namespaces provided from MidCOM core. |
||
125 | */ |
||
126 | 291 | private static function init() |
|
127 | { |
||
128 | 291 | if (self::$registry) { |
|
0 ignored issues
–
show
|
|||
129 | 291 | return; |
|
130 | } |
||
131 | 1 | self::$registry = [ |
|
132 | 1 | '__ais' => [ |
|
133 | 1 | 'folder' => [ |
|
134 | 1 | 'class' => midcom_admin_folder_management::class, |
|
135 | 1 | ], |
|
136 | 1 | 'rcs' => [ |
|
137 | 1 | 'class' => midcom_admin_rcs_plugin::class, |
|
138 | 1 | ], |
|
139 | 1 | 'imagepopup' => [ |
|
140 | 1 | 'class' => midcom_helper_imagepopup_viewer::class, |
|
141 | 1 | ], |
|
142 | 1 | 'help' => [ |
|
143 | 1 | 'class' => midcom_admin_help_help::class, |
|
144 | 1 | ], |
|
145 | 1 | ] |
|
146 | 1 | ]; |
|
147 | |||
148 | // Load plugins registered via component manifests |
||
149 | 1 | $plugins = midcom::get()->componentloader->get_all_manifest_customdata('request_handler_plugin'); |
|
150 | 1 | $plugins['asgard'] = [ |
|
151 | 1 | 'class' => midgard_admin_asgard_plugin::class, |
|
152 | 1 | ]; |
|
153 | |||
154 | 1 | $customdata = midcom::get()->componentloader->get_all_manifest_customdata('asgard_plugin'); |
|
155 | 1 | foreach ($customdata as $component => $plugin_config) { |
|
156 | 1 | $plugins["asgard_{$component}"] = $plugin_config; |
|
157 | } |
||
158 | |||
159 | 1 | self::register_namespace('__mfa', $plugins); |
|
160 | } |
||
161 | } |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.