| 1 |
mjordaan |
1 |
<?php namespace ProcessWire;
|
|
|
2 |
|
|
|
3 |
/**
|
|
|
4 |
* ProcessWire Module Interface
|
|
|
5 |
*
|
|
|
6 |
* Provides the base interfaces required by modules.
|
|
|
7 |
*
|
|
|
8 |
* ProcessWire 3.x, Copyright 2018 by Ryan Cramer
|
|
|
9 |
* https://processwire.com
|
|
|
10 |
*
|
|
|
11 |
* #pw-summary Module is the primary PHP interface for module types in ProcessWire.
|
|
|
12 |
* #pw-body =
|
|
|
13 |
* The Module interface doesn't actually require any specific methods,
|
|
|
14 |
* (other than the `className()` method) but is required as an interface
|
|
|
15 |
* to state your intention to ProcessWire that your class is to be used
|
|
|
16 |
* as a Module. As a result, all methods are optional, but including the
|
|
|
17 |
* Module interface is not. You must also provide a means by which ProcessWire
|
|
|
18 |
* can query information about your module. More on that below.
|
|
|
19 |
*
|
|
|
20 |
* ### Implementing the Module interface
|
|
|
21 |
*
|
|
|
22 |
* Below is how you indicate a PHP class is a ProcessWire Module:
|
|
|
23 |
*
|
|
|
24 |
* ~~~~~
|
|
|
25 |
* <?php namespace ProcessWire;
|
|
|
26 |
* class HelloWorld extends WireData implements Module {
|
|
|
27 |
* // your class implementation
|
|
|
28 |
* }
|
|
|
29 |
* ~~~~~
|
|
|
30 |
*
|
|
|
31 |
* Modules should either extend the `WireData` class, or if they are a
|
|
|
32 |
* predefined type already recognized by ProcessWire, they should extend
|
|
|
33 |
* the base class of that type (or another module based upon it). Base
|
|
|
34 |
* module types include:
|
|
|
35 |
*
|
|
|
36 |
* - `AdminTheme`
|
|
|
37 |
* - `Fieldtype`
|
|
|
38 |
* - `FileCompilerModule`
|
|
|
39 |
* - `FileValidatorModule`
|
|
|
40 |
* - `Inputfield`
|
|
|
41 |
* - `ModuleJS`
|
|
|
42 |
* - `PageAction`
|
|
|
43 |
* - `Process`
|
|
|
44 |
* - `Textformatter`
|
|
|
45 |
* - `WireAction`
|
|
|
46 |
* - `WireMail`
|
|
|
47 |
* - `WireSessionHandler`
|
|
|
48 |
*
|
|
|
49 |
* ### Requirements for Modules
|
|
|
50 |
*
|
|
|
51 |
* 1. Must provide a means of getting information about the module.
|
|
|
52 |
* This can be with a static `getModuleInfo()` method, or with
|
|
|
53 |
* a `ModuleName.info.php` file or a `ModuleName.info.json` file.
|
|
|
54 |
*
|
|
|
55 |
* 2. Must provide a `className()` method that returns the module
|
|
|
56 |
* class name. All Wire derived objects already do this, so
|
|
|
57 |
* you don't have to provide it unless your Module does not
|
|
|
58 |
* descend from a ProcessWire class. We recommend that your
|
|
|
59 |
* modules extend the Wire or WireData class.
|
|
|
60 |
*
|
|
|
61 |
* 3. If you have a `__construct()` method, it must not require any
|
|
|
62 |
* particular arguments.
|
|
|
63 |
*
|
|
|
64 |
* 4. If your module is configurable, it must also fulfill the
|
|
|
65 |
* `ConfigurableModule` interface.
|
|
|
66 |
*
|
|
|
67 |
* ### Optional methods
|
|
|
68 |
*
|
|
|
69 |
* - `__construct()` - Called before module config is populated.
|
|
|
70 |
*
|
|
|
71 |
* - `init()` - Called after module config is populated.
|
|
|
72 |
*
|
|
|
73 |
* - `ready()` - Called after init(), after API ready. Note that ready() applies to 'autoload' modules only.
|
|
|
74 |
*
|
|
|
75 |
* - `install()` - Called when module is installed.
|
|
|
76 |
*
|
|
|
77 |
* - `uninstall()` - Called when module is uninstalled.
|
|
|
78 |
*
|
|
|
79 |
* - `upgrade($fromVersion, $toVersion)` - Called on version change.
|
|
|
80 |
*
|
|
|
81 |
* - `isAutoload()` - Returns a boolean indicating whether the module should be loaded at boot.
|
|
|
82 |
* Can also be specified as a property in module information.
|
|
|
83 |
*
|
|
|
84 |
* - `isSingular()` - Returns a boolean indicating whether the module is limited to one instance or not.
|
|
|
85 |
* Can also be specified as a property in module information.
|
|
|
86 |
*
|
|
|
87 |
* - `getModuleInfo()` - A static method that returns an array of module information.
|
|
|
88 |
*
|
|
|
89 |
* These methods are outlined in more detail further down on this page.
|
|
|
90 |
*
|
|
|
91 |
* -----------------------------------------------------------------
|
|
|
92 |
*
|
|
|
93 |
* ## Module Information
|
|
|
94 |
*
|
|
|
95 |
* Modules must have some way to communicate information about
|
|
|
96 |
* themselves to ProcessWire. This is done by providing an
|
|
|
97 |
* associative array containing this module information. One
|
|
|
98 |
* of the following implementations is required:
|
|
|
99 |
*
|
|
|
100 |
* 1. `getModuleInfo()` static method in your module class that returns an array.
|
|
|
101 |
* 2. `YourModuleClass.info.php` file that populates an `$info` array.
|
|
|
102 |
* 3. `YourModuleClass.info.json` file that contains an `info` object.
|
|
|
103 |
*
|
|
|
104 |
* Each of these are demonstrated below:
|
|
|
105 |
*
|
|
|
106 |
* **1) Static getModuleInfo() method:**
|
|
|
107 |
* ~~~~~
|
|
|
108 |
* public static function getModuleInfo() {
|
|
|
109 |
* return array(
|
|
|
110 |
* 'title' => 'Your Module Title',
|
|
|
111 |
* 'version' => 1,
|
|
|
112 |
* 'author' => 'Your Name',
|
|
|
113 |
* 'summary' => 'Description of what this module does and who made it.',
|
|
|
114 |
* 'href' => 'http://www.domain.com/info/about/this/module/',
|
|
|
115 |
* 'autoload' => false, // set to true if module should auto-load at boot
|
|
|
116 |
* 'requires' => array(
|
|
|
117 |
* 'HelloWorld>=1.0.1',
|
|
|
118 |
* 'PHP>=5.4.1',
|
|
|
119 |
* 'ProcessWire>=2.4.1'
|
|
|
120 |
* ),
|
|
|
121 |
* 'installs' => array('Module1', 'Module2', 'Module3'),
|
|
|
122 |
* );
|
|
|
123 |
* }
|
|
|
124 |
* ~~~~~
|
|
|
125 |
*
|
|
|
126 |
* **2) YourModuleClass.info.php file:**
|
|
|
127 |
* Your file should populate an `$info` variable with an array exactly like
|
|
|
128 |
* described for #1 above, i.e.
|
|
|
129 |
*
|
|
|
130 |
* ~~~~~
|
|
|
131 |
* $info = array(
|
|
|
132 |
* 'title' => 'Your Module Title',
|
|
|
133 |
* 'version' => 1,
|
|
|
134 |
* // and so on, like the static version above
|
|
|
135 |
* );
|
|
|
136 |
* ~~~~~
|
|
|
137 |
*
|
|
|
138 |
* **3) YourModuleClass.info.json file:**
|
|
|
139 |
* Your JSON file should contain nothing but an object/map of the module info:
|
|
|
140 |
*
|
|
|
141 |
* ~~~~~
|
|
|
142 |
* {
|
|
|
143 |
* "title": "Your Module Title",
|
|
|
144 |
* "version": 1
|
|
|
145 |
* }
|
|
|
146 |
* ~~~~~
|
|
|
147 |
* Note: The example JSON above just shows "title" and "version", but you would
|
|
|
148 |
* likely add more than that as needed, like shown in the static version above.
|
|
|
149 |
*
|
|
|
150 |
* -----------------------------------------------------------------
|
|
|
151 |
*
|
|
|
152 |
* ## Module information properties
|
|
|
153 |
*
|
|
|
154 |
* ### Required info properties
|
|
|
155 |
*
|
|
|
156 |
* - `title` (string): The module's title.
|
|
|
157 |
*
|
|
|
158 |
* - `version` (int|string): An integer or string that indicates the version number.
|
|
|
159 |
*
|
|
|
160 |
* - `summary` (string): Summary text of the module (1 sentence recommended).
|
|
|
161 |
*
|
|
|
162 |
* ### Optional info properties
|
|
|
163 |
*
|
|
|
164 |
* - `href` (string): URL to more information about the module.
|
|
|
165 |
*
|
|
|
166 |
* - `requires` (array|string): Array or CSV string of module class names that are required by this
|
|
|
167 |
* module in order to install.
|
|
|
168 |
*
|
|
|
169 |
* - **Requires Module version:** If a particular version of the module is required, then specify an operator
|
|
|
170 |
* and version number after the module name, like this: "HelloWorld>=1.0.1".
|
|
|
171 |
*
|
|
|
172 |
* - **Requires PHP version:** If a particular version of PHP is required, then specify "PHP" as the module name
|
|
|
173 |
* followed by an operator and required version number, like this: "PHP>=5.6.0".
|
|
|
174 |
*
|
|
|
175 |
* - **Requires ProcessWire version:** If a particular version of ProcessWire is required, then specify
|
|
|
176 |
* ProcessWire followed by an operator and required version number, like this: "ProcessWire>=2.4.1".
|
|
|
177 |
*
|
|
|
178 |
* - `installs` (array|string): Array or CSV string of module class names that this module will handle install
|
|
|
179 |
* and uninstall for.
|
|
|
180 |
* This causes ProcessWire's dependency checker to ignore them and it is assumed your module will handle
|
|
|
181 |
* them. If your module does not handle them, ProcessWire will automatically install/uninstall them
|
|
|
182 |
* immediately after your module.
|
|
|
183 |
*
|
|
|
184 |
* - `permanent` (boolean): This property is intended for only for core modules. When true, a module cannot be uninstalled.
|
|
|
185 |
*
|
|
|
186 |
* - `permission` (string): Name of permission required of a user before ProcessWire will load the module (for non-superusers).
|
|
|
187 |
* Note that ProcessWire will not install this permission if it doesn't yet exist. To have it installed automatically,
|
|
|
188 |
* see the _permissions_ option below this.
|
|
|
189 |
*
|
|
|
190 |
* - `permissions` (array): Array of permissions that ProcessWire will install (and uninstall) automatically.
|
|
|
191 |
* Permissions should be in the format: array('permission-name' => 'Permission description').
|
|
|
192 |
*
|
|
|
193 |
* - `icon` (string): Optional icon name to represent this module.
|
|
|
194 |
* Currently uses [font-awesome](http://fortawesome.github.io/Font-Awesome/) icon names.
|
|
|
195 |
* Omit the "fa-" part, leaving just the icon name.
|
|
|
196 |
*
|
|
|
197 |
* - `singular` (boolean): Is only one instance of this module allowed? (default=auto-detect).
|
|
|
198 |
* This is good for any module that you want to eliminate the possibility of multiple instances
|
|
|
199 |
* running at once. For instance, modules that become API variables are typically singular, whereas
|
|
|
200 |
* something like an Inputfield module would not be singular. When not specified, modules that extend an
|
|
|
201 |
* existing base type typically inherit the singular setting from the module they extend.
|
|
|
202 |
*
|
|
|
203 |
* - `autoload` (boolean|string|callable|int): Should this module load automatically at boot? (default=false).
|
|
|
204 |
* This is good for modules that attach hooks or that need to otherwise load on every single
|
|
|
205 |
* request. Autoload is typically specified as a boolean true or false. Below are the different ways
|
|
|
206 |
* autoload can be specified:
|
|
|
207 |
*
|
|
|
208 |
* - **Boolean:** Specify true or false to indicate the module should either always autoload (true)
|
|
|
209 |
* or never autoload (false).
|
|
|
210 |
*
|
|
|
211 |
* - **Selector string:** The module will be automatically loaded only if the current page matches the
|
|
|
212 |
* selector string. For example, a selector string of `template=admin` would mean the module will
|
|
|
213 |
* only autoload in the admin side of ProcessWire.
|
|
|
214 |
*
|
|
|
215 |
* - **Callable function:** The module will automatically load only if the given callable function
|
|
|
216 |
* returns true.
|
|
|
217 |
*
|
|
|
218 |
* - **Integer:** If given integer 2 or higher, it will autoload the module before other autoload
|
|
|
219 |
* modules (in /site/modules/). Higher numbers autoload before lower numbers.
|
|
|
220 |
*
|
|
|
221 |
* - `searchable` (string): When present, indicates that module implements a search() method
|
|
|
222 |
* consistent with the SearchableModule interface. The value of the 'searchable' property should
|
|
|
223 |
* be the name that the search results are referred to, using ascii characters of a-z, 0-9, and
|
|
|
224 |
* underscore. See the SearchableModule interface in this file for more details.
|
|
|
225 |
*
|
|
|
226 |
* -----------------------------------------------------------------------------------------------
|
|
|
227 |
*
|
|
|
228 |
* ## Module Methods
|
|
|
229 |
*
|
|
|
230 |
* ### __construct()
|
|
|
231 |
*
|
|
|
232 |
* This method is called by PHP immediately when the module is instantiated, and before any
|
|
|
233 |
* configuration data has been populated to the module. This method must not have any required
|
|
|
234 |
* arguments. This method is a good place for populating default configuration values or any
|
|
|
235 |
* other initialization you want to occur before ProcessWire sees it or populates anything to it.
|
|
|
236 |
* Your construct method should not assume that the module will actually be executed, as
|
|
|
237 |
* ProcessWire may instantiate a module for informational reasons.
|
|
|
238 |
*
|
|
|
239 |
* ### init()
|
|
|
240 |
*
|
|
|
241 |
* This method is called after `__construct()` and after any configuration data has been populated
|
|
|
242 |
* to the module. It is called before the module is handed over to the requester. This is a good
|
|
|
243 |
* place to perform any initialization that requires configuration data and can be a good place to
|
|
|
244 |
* attach hooks.
|
|
|
245 |
*
|
|
|
246 |
* ### ready()
|
|
|
247 |
*
|
|
|
248 |
* This method is used only by _autoload_ modules. It is called when the entire ProcessWire API
|
|
|
249 |
* is ready to use. This may be preferable to the `init()` method for autoload modules because
|
|
|
250 |
* they are loaded and init()'d at boot, when everything else is loading too. The ready() method
|
|
|
251 |
* is called once the boot has completed and all API variables are ready to use, but before any
|
|
|
252 |
* page has been rendered. This makes it an excellent place to attach hooks.
|
|
|
253 |
*
|
|
|
254 |
* ### isSingular()
|
|
|
255 |
*
|
|
|
256 |
* Indicates whether only one instance of a module is allowed to exist in memory.
|
|
|
257 |
* If this method is not present, it will be auto-determined based on module type. If it is provided
|
|
|
258 |
* in the module information array (discussed above) that will override this method.
|
|
|
259 |
*
|
|
|
260 |
* This method exists primarily so that base module types may specify a singular state and have it
|
|
|
261 |
* automatically inherit to any modules extending the type. If you are not extending a base module
|
|
|
262 |
* type then you can implement this method, or you can provide it in your module info array.
|
|
|
263 |
*
|
|
|
264 |
* A module that returns TRUE is referred to as a "singular" module, because there will never be any more
|
|
|
265 |
* than a single instance of the module running.
|
|
|
266 |
*
|
|
|
267 |
* Return TRUE if this module is a single reusable instance, returning the same instance on every
|
|
|
268 |
* call from Modules. Return FALSE if this module should return a new instance on every call from Modules.
|
|
|
269 |
*
|
|
|
270 |
* - Singular modules will have their instance active for the entire request after instantiated.
|
|
|
271 |
* - Non-singular modules return a new instance on every `$modules->get("YourModule")` call.
|
|
|
272 |
* - Modules that attach hooks are usually singular.
|
|
|
273 |
* - Modules that may have multiple instances (like `Inputfield` modules) should _not_be singular.
|
|
|
274 |
*
|
|
|
275 |
* If you are having trouble deciding whether to make your module singular or not, be sure to read
|
|
|
276 |
* the documentation below for the `isAutoload()` method, because if your module is 'autoload' then
|
|
|
277 |
* it's probably also 'singular'.
|
|
|
278 |
*
|
|
|
279 |
* ### isAutoload()
|
|
|
280 |
*
|
|
|
281 |
* Should this module be automatically loaded at boot?
|
|
|
282 |
* If this method is not present, it will be auto-determined based on module type. If it is provided
|
|
|
283 |
* in the module information array (discussed above) that will override this method.
|
|
|
284 |
*
|
|
|
285 |
* This method exists primarily so that base module types may specify an autoload state and have it
|
|
|
286 |
* automatically inherit to any modules extending the type. If you are not extending a base module
|
|
|
287 |
* type then you can implement this method, or you can provide it in your module info array.
|
|
|
288 |
*
|
|
|
289 |
* A module that returns TRUE is referred to as an "autoload" module, because it automatically loads as
|
|
|
290 |
* part of ProcessWire's boot process. Autoload modules load before PW attempts to handle the web request.
|
|
|
291 |
*
|
|
|
292 |
* Return TRUE if this module is automatically loaded at runtime.
|
|
|
293 |
* Return FALSE if this module must be requested via `$modules->get('ModuleName')` method before it is loaded.
|
|
|
294 |
*
|
|
|
295 |
* Modules that are intended to attach hooks in the application typically should be autoload because
|
|
|
296 |
* they listen in to classes rather than have classes call upon them. If they weren't autoloaded, then
|
|
|
297 |
* they might never get to attach their hooks.
|
|
|
298 |
*
|
|
|
299 |
* Modules that shouldn't be autoload are those that may or may not be needed at runtime, for example
|
|
|
300 |
* `Fieldtype` and `Inputfield` modules.
|
|
|
301 |
*
|
|
|
302 |
* _As a side note, I can't think of any reason why a non-singular module would ever be autoload. The fact that
|
|
|
303 |
* an autoload module is automatically loaded as part of PW's boot process implies it's probably going to be the
|
|
|
304 |
* only instance running. So if you've decided to make your module 'autoload', then is safe to assume you've
|
|
|
305 |
* also decided your module will also be singular (if that helps anyone reading this)._
|
|
|
306 |
*
|
|
|
307 |
* ### install()
|
|
|
308 |
*
|
|
|
309 |
* This method is called when the module is first installed. If implemented, install() methods typically are
|
|
|
310 |
* defined hookable as `public function ___install()`.
|
|
|
311 |
*
|
|
|
312 |
* The method should prepare the environment with anything else needed by the module, such as newly created
|
|
|
313 |
* fields, pages, templates, etc. or installation of other modules.
|
|
|
314 |
*
|
| 22 |
mjordaan |
315 |
* If the install() method determines that the module cannot be installed for some reason, it should
|
| 1 |
mjordaan |
316 |
* throw a `WireException.`
|
|
|
317 |
*
|
|
|
318 |
* ### uninstall()
|
|
|
319 |
*
|
|
|
320 |
* This method is called when the module is uninstalled. If implemented, uninstall() methods typically are
|
|
|
321 |
* defined hookable as `public function ___uninstall()`.
|
|
|
322 |
*
|
|
|
323 |
* This method should undo everything done by the install() method, or undo anything created by the module,
|
|
|
324 |
* restoring the system back to the state that it was in before the module was installed.
|
|
|
325 |
*
|
|
|
326 |
* If the uninstall() method determines that it cannot proceed for some reason, it should throw
|
|
|
327 |
* a `WireException`.
|
|
|
328 |
*
|
|
|
329 |
* ### upgrade($fromVersion, $toVersion)
|
|
|
330 |
*
|
|
|
331 |
* This method is called when a version change is detected. This method should make any adjustments needed
|
|
|
332 |
* to support the module from one version to another. The previous known version ($fromVersion) and new
|
|
|
333 |
* version ($toVersion) are provided as arguments.
|
|
|
334 |
*
|
|
|
335 |
* If implemented, upgrade() methods typically are defined hookable as `public function ___upgrade(...)`.
|
|
|
336 |
* If the upgrade cannot proceed for some reason, this method should throw a `WireException`.
|
|
|
337 |
*
|
|
|
338 |
*
|
|
|
339 |
*
|
|
|
340 |
*
|
|
|
341 |
* #pw-body
|
|
|
342 |
*
|
|
|
343 |
* The following methods may or may not be implemented, all are optional:
|
|
|
344 |
*
|
|
|
345 |
* #pw-method void install() Called when module is installed.
|
|
|
346 |
* #pw-method void uninstall() Called when module is uninstalled.
|
|
|
347 |
* #pw-method void upgrade($fromVersion, $toVersion) Called when a version change is detected for the module.
|
|
|
348 |
* #pw-method array getModuleInfo() Static method that returns array of module info (not required if module implements an info file instead).
|
|
|
349 |
* #pw-method void init() Called when the module is loaded, immediately after any configuration data has been populated to it.
|
|
|
350 |
* #pw-method void ready() For autoload modules only, called when the ProcessWire API is ready to use.
|
|
|
351 |
* #pw-method void setConfigData(array $data) Modules may optionally provide this method to receive config data from ProcessWire.
|
|
|
352 |
* #pw-method bool isSingular() #pw-internal
|
|
|
353 |
* #pw-method bool isAutoload() #pw-internal
|
|
|
354 |
*
|
|
|
355 |
*
|
|
|
356 |
*/
|
|
|
357 |
|
|
|
358 |
interface Module {
|
|
|
359 |
|
|
|
360 |
/**
|
|
|
361 |
* Return an array of module information
|
|
|
362 |
*
|
|
|
363 |
* @return array
|
|
|
364 |
*
|
|
|
365 |
* public static function getModuleInfo();
|
|
|
366 |
*
|
|
|
367 |
*/
|
|
|
368 |
|
|
|
369 |
/**
|
|
|
370 |
* Method to initialize the module.
|
|
|
371 |
*
|
|
|
372 |
* While the method is required, if you don't need it, then just leave the implementation blank.
|
|
|
373 |
*
|
|
|
374 |
* This is called after ProcessWire's API is fully ready for use and hooks. It is called at the end of the
|
|
|
375 |
* bootstrap process. This is before PW has started retrieving or rendering a page. If you need to have the
|
|
|
376 |
* API ready with the $page ready as well, then see the ready() method below this one.
|
|
|
377 |
*
|
|
|
378 |
* public function init();
|
|
|
379 |
*
|
|
|
380 |
*/
|
|
|
381 |
|
|
|
382 |
/**
|
|
|
383 |
* Method called when API is fully ready and the $page is determined and set, but before a page is rendered.
|
|
|
384 |
*
|
|
|
385 |
* Optional and only called if it exists in the module.
|
|
|
386 |
*
|
|
|
387 |
* public function ready();
|
|
|
388 |
*
|
|
|
389 |
*/
|
|
|
390 |
|
|
|
391 |
/**
|
|
|
392 |
* Return this object’s class name
|
|
|
393 |
*
|
|
|
394 |
* If your Module descends from Wire, or any of it's derivatives (as would usually be the case),
|
|
|
395 |
* then you don't need to implement this method as it's already present.
|
|
|
396 |
*
|
|
|
397 |
* @param array|bool|null $options Optionally an option or boolean for 'namespace' option:
|
|
|
398 |
* - `lowercase` (bool): Specify true to make it return hyphenated lowercase version of class name
|
|
|
399 |
* - `namespace` (bool): Specify false to omit namespace from returned class name. Default=true.
|
|
|
400 |
* - Note: when lowercase=true option is specified, the namespace=false option is required.
|
|
|
401 |
* @return string
|
|
|
402 |
* @see Wire::className()
|
|
|
403 |
*
|
|
|
404 |
*/
|
|
|
405 |
public function className($options = null);
|
|
|
406 |
|
|
|
407 |
/**
|
|
|
408 |
* Perform any installation procedures specific to this module, if needed.
|
|
|
409 |
*
|
|
|
410 |
* The Modules class calls this install method right after performing the install.
|
|
|
411 |
*
|
|
|
412 |
* If this method throws an exception, PW will catch it, remove it from the installed module list, and
|
|
|
413 |
* report that the module installation failed. You may specify details about why with the exception, i.e.
|
|
|
414 |
* throw new WireException("Can't install because of ...");
|
|
|
415 |
*
|
|
|
416 |
* This method is OPTIONAL, which is why it's commented out below.
|
|
|
417 |
*
|
|
|
418 |
* public function ___install();
|
|
|
419 |
*
|
|
|
420 |
*/
|
|
|
421 |
|
|
|
422 |
/**
|
|
|
423 |
* Perform any uninstall procedures specific to this module, if needed.
|
|
|
424 |
*
|
|
|
425 |
* It calls this uninstall method right before completing the uninstall.
|
|
|
426 |
*
|
|
|
427 |
* This method is OPTIONAL, which is why it's commented out below.
|
|
|
428 |
*
|
|
|
429 |
* public function ___uninstall();
|
|
|
430 |
*
|
|
|
431 |
*/
|
|
|
432 |
|
|
|
433 |
/**
|
|
|
434 |
* Called when a version change is detected on the module
|
|
|
435 |
*
|
|
|
436 |
* public function ___upgrade($fromVersion, $toVersion);
|
|
|
437 |
*
|
|
|
438 |
*/
|
|
|
439 |
|
|
|
440 |
/**
|
|
|
441 |
* Is this module intended to be only a single instance?
|
|
|
442 |
*
|
|
|
443 |
* @return bool
|
|
|
444 |
*
|
|
|
445 |
* public function isSingular();
|
|
|
446 |
*
|
|
|
447 |
*/
|
|
|
448 |
|
|
|
449 |
/**
|
|
|
450 |
* Is this module automatically loaded at runtime?
|
|
|
451 |
*
|
|
|
452 |
* @return bool
|
|
|
453 |
*
|
|
|
454 |
* public function isAutoload();
|
|
|
455 |
*
|
|
|
456 |
*/
|
|
|
457 |
}
|
|
|
458 |
|
|
|
459 |
/**
|
|
|
460 |
* Standard module interface with all methods.
|
|
|
461 |
*
|
|
|
462 |
* This interface is not intended to be used for anything other than for code hinting purposes.
|
|
|
463 |
*
|
|
|
464 |
*/
|
|
|
465 |
interface _Module {
|
|
|
466 |
|
|
|
467 |
public function install();
|
|
|
468 |
public function uninstall();
|
|
|
469 |
public function upgrade($fromVersion, $toVersion);
|
|
|
470 |
|
|
|
471 |
/** @return array */
|
|
|
472 |
public static function getModuleInfo();
|
|
|
473 |
|
|
|
474 |
public function init();
|
|
|
475 |
|
|
|
476 |
public function ready();
|
|
|
477 |
|
|
|
478 |
public function setConfigData(array $data);
|
|
|
479 |
|
|
|
480 |
/** @return bool */
|
|
|
481 |
public function isSingular();
|
|
|
482 |
|
|
|
483 |
/** @return bool */
|
|
|
484 |
public function isAutoload();
|
|
|
485 |
|
|
|
486 |
/**
|
|
|
487 |
* @param InputfieldWrapper|array|null $data
|
|
|
488 |
* @return InputfieldWrapper
|
|
|
489 |
*
|
|
|
490 |
*/
|
|
|
491 |
public function getModuleConfigInputfields($data = null);
|
|
|
492 |
|
|
|
493 |
/**
|
|
|
494 |
* @return array
|
|
|
495 |
*
|
|
|
496 |
*/
|
|
|
497 |
public function getModuleConfigArray();
|
|
|
498 |
}
|
|
|
499 |
|
|
|
500 |
/**
|
|
|
501 |
* Interface SearchableModule
|
|
|
502 |
*
|
|
|
503 |
* Interface for modules that implement a method and expected array return value
|
|
|
504 |
* for completing basic text searches (primarily for admin search engine).
|
|
|
505 |
*
|
|
|
506 |
* It is optional to add this interface to "implements" section of the module class definition.
|
|
|
507 |
* However, you must specify a "searchable: name" property in your getModuleInfo() method in
|
|
|
508 |
* order for ProcessWire to recognize the module is searchable. See below for more info:
|
|
|
509 |
*
|
|
|
510 |
* ~~~~~~
|
|
|
511 |
* public static function getModuleInfo() {
|
|
|
512 |
* return array(
|
|
|
513 |
* 'searchable' => 'name',
|
|
|
514 |
*
|
|
|
515 |
* // You'll need the above 'searchable' property returned by your getModuleInfo().
|
|
|
516 |
* // The value of 'name' should be the name by which search results should be referred to
|
|
|
517 |
* // if the user wants to limit the search to this module. For instance, if your module
|
|
|
518 |
* // was called “ProcessWidgets”, you’d probably choose the name “widgets” for this.
|
|
|
519 |
* // If the module represents an API variable, the name should be the same as the API variable.
|
|
|
520 |
* // ...
|
|
|
521 |
* );
|
|
|
522 |
* }
|
|
|
523 |
* ~~~~~
|
|
|
524 |
*
|
|
|
525 |
*/
|
|
|
526 |
interface SearchableModule {
|
|
|
527 |
|
|
|
528 |
/**
|
|
|
529 |
* Search for items containing $text and return an array representation of them
|
|
|
530 |
*
|
|
|
531 |
* You may also implement this method as hookable, i.e. ___search(), but note that you’ll
|
|
|
532 |
* want to skip the "implements SearchableModule" in your class definition.
|
|
|
533 |
*
|
|
|
534 |
* Must return PHP array in the format below. For each item in the 'items' array, Only the 'title'
|
|
|
535 |
* and 'url' properties are required for each item (the rest are optional).
|
|
|
536 |
*
|
|
|
537 |
* $result = array(
|
|
|
538 |
* 'title' => 'Title of these items',
|
|
|
539 |
* 'total' => 999, // total number of items found, or omit if pagination not supported or active
|
|
|
540 |
* 'url' => '', // optional URL to view all items, or omit for a PW-generated one
|
|
|
541 |
* 'properties' => array(), // optional list of supported search properties, only looked for if $options['info'] === true;
|
|
|
542 |
* 'items' => array(
|
|
|
543 |
* [0] => array(
|
|
|
544 |
* 'id' => 123, // Unique ID of item (optional)
|
|
|
545 |
* 'name' => 'Name of item', // (optional)
|
|
|
546 |
* 'title' => 'Title of item', // (*required)
|
|
|
547 |
* 'subtitle' => 'Secondary/subtitle of item', // (optional)
|
|
|
548 |
* 'summary' => 'Summary or description of item', // (optional)
|
|
|
549 |
* 'url' => 'URL to view or edit the item', // (*required)
|
|
|
550 |
* 'icon' => 'Optional icon name to represent the item, i.e. "gear" or "fa-gear"', // (optional)
|
|
|
551 |
* 'group' => 'Optionally group with other items having this group name, overrides $result[title]', // (optional)
|
|
|
552 |
* 'status' => int, // refers to Page status, omit if not a Page item (optional)
|
|
|
553 |
* 'modified' => int, // modified date of item as unix timestamp (optional)
|
|
|
554 |
* [1] => array(
|
|
|
555 |
* ...
|
|
|
556 |
* ),
|
|
|
557 |
* ),
|
|
|
558 |
* );
|
|
|
559 |
*
|
|
|
560 |
* PLEASE NOTE:
|
|
|
561 |
* When ProcessWire calls this method, if the module is not already loaded (autoload),
|
|
|
562 |
* it instantiates the module but DOES NOT call the init() or ready() methods. That’s because the
|
|
|
563 |
* search method is generally self contained. If you need either of those methods to be called,
|
|
|
564 |
* and your module is not autoload, you should call the method(s) from your search() method.
|
|
|
565 |
*
|
|
|
566 |
* About the optional “properties” index:
|
|
|
567 |
* If ProcessWire calls your search() method with $options['info'] == true; then it is likely wanting to see
|
|
|
568 |
* what properties are available for search. For instance, properties for a Module search might be:
|
|
|
569 |
* [ 'name', 'title', 'summary' ]. Implementation of the properties index is optional, and for PW’s informational
|
|
|
570 |
* purposes only.
|
|
|
571 |
*
|
|
|
572 |
* @param string $text Text to search for
|
|
|
573 |
* @param array $options Options array provided to search() calls:
|
|
|
574 |
* - `edit` (bool): True if any 'url' returned should be to edit rather than view items, where access allows. (default=true)
|
|
|
575 |
* - `multilang` (bool): If true, search all languages rather than just current (default=true).
|
|
|
576 |
* - `start` (int): Start index (0-based), if pagination active (default=0).
|
|
|
577 |
* - `limit` (int): Limit to this many items, or 0 for no limit. (default=0).
|
|
|
578 |
* - `type` (string): If search should only be of a specific type, i.e. "pages", "modules", etc. then it is
|
|
|
579 |
* specified here. This corresponds with the getModuleInfo()['searchable'] name or item 'group' property.
|
|
|
580 |
* Note that ProcessWire won’t call your search() method if the type cannot match this search.
|
|
|
581 |
* - `operator` (string): Selector operator type requested, if more than one is supported (default is %=).
|
|
|
582 |
* - `property` (string): If search should limit to a particular property/field, it is named here.
|
|
|
583 |
* - `verbose` (bool): True if output can optionally be more verbose, false if not. (default=false)
|
|
|
584 |
* - `debug` (bool): True if DEBUG option was specified in query. (default=false)
|
|
|
585 |
* - `help` (bool): True if we are just querying for help/info and are not using the search results. (default=false)
|
|
|
586 |
* @return array
|
|
|
587 |
*
|
|
|
588 |
*/
|
|
|
589 |
public function search($text, array $options = array());
|
|
|
590 |
}
|
|
|
591 |
|