# modRequest

A module request (aka "modRequest") is a specialized event dispatching utility designed to send data to many modules, and receive responses from each recipient module (when applicable). All server side modRequests are executed synchronously.

### Example

Where is a modRequest applicable?

Consider the page editor, provides a list of widgets that can be embedded into a content page. The page editor module needs a way to collect all the registered widgets from other modules. On the other hand, modules should be able to register a widget without assuming the page editor is even installed.

The page editor can execute a modRequest called `page_editor_get_widgets`. Other modules can register listeners for that modRequest, and define a callback for when it is executed. See creating a modRequest listener and executing a modRequest.

### Creating a ModRequest Listener

#### Register the listener

ModRequest listeners are registered inside the `init()` method of a module's `{module}Config.php` file. The first parameter of `modRequest::listen()` is the name of the request. The second parameter is the controller and method to be executed: `{controller}@{method}`.

```php
<?php
use sa\application\modRequest;
​
class MemberConfig extends moduleConfig {
    public static function init() {
        modRequest::listen('page_editor.get_widgets', 'MemberModRequestController@getMemberListWidget');
    }
}
```

#### Listener Callback

A module's modRequest listeners are generally grouped up in a dedicated modRequest controller. Notice the controller does not extend `sa\application\controller`. This special controller type does not respond to HTTP requests, so it does not need the methods offered by the base `controller` class.

The `getMemberListWidget()` method is our listener. It receives 1 parameter `$data`, which holds all the content returned by other listeners. The method simply appends its content to the array and returns the bundle. It's usually bad practice to modify the content already existing inside of `$data`.

```php
<?php
class MemberModRequestController {
    public function getMemberListWidget(array $data) {
        $data[] = array(
            'name' => 'Member List',
            'html' => '...'
        );
        
        return $data;
    }
}
```

**Parameters**

| Parameter       | Type    | Required | Default | Description                                                                                                                                                           |
| --------------- | ------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$event`        | string  | yes      |         | A unique label for the event. By convention, should only contain underscores and alphabetic characters, and be prefixed with module name.                             |
| `$action`       | string  | yes      |         | The controller and method to be executed, delimited by the `@` symbol. (e.g `PayPalModRequestController@getPaymentProcessor`)                                         |
| `$priority`     | int     | no       | 1       | A numeric weight which sets the order of which the listeners should be executed. Listeners with higher priority value will be executed first.                         |
| `$name`         | string  | no       | null    | A unique name for the specific listener. By convention, base SiteAdmin modules should give this field a value to all the listener to be overwritten by child modules. |
| `$allow_js`     | boolean | no       | false   | If true, this modRequest will be executable from the browser via the modRequest JS API.                                                                               |
| `$is_protected` | boolean |          | false   | If true, a user must be logged in to execute the modRequest.                                                                                                          |

### Executing a modRequest

```php
<?php
use sa\application\modRequest;
​
$pageEditorWidgets = modRequest::request('page_editor.get_widgets');
```

**Parameters**

| Event            | Type    | Required | Default | Description                                                                                                                               |
| ---------------- | ------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `$event`         | string  | yes      |         | A unique label for the event. By convention, should only contain underscores and alphabetic characters, and be prefixed with module name. |
| `$default`       | mixed   | no       | null    | The default data returned by the modRequest, if no listeners respond.                                                                     |
| `$data`          | mixed   | no       | null    | The default values to be sent to each listener. This value will be modified by each listener, then returned.                              |
| `$is_js_request` | boolean | no       | false   | Flag to identify if the modRequest is being sent from the browser client, or server.                                                      |

## Conventions

### ModRequests

The event label for a modRequest should adhere to the format `{module}.{action}` or `{module}.{domain}.{action}`. The label should be composed of lower case alphabetic characters. Module and action names should be delimited by underscores.

```php
// {module}.{action} example
modRequest::listen('page_editor.get_widgets')
​
// {module}.{domain}.{action} example
modRequest::listen('page_editor.navigation.get_nav_items')
```

### Listeners

ModRequest listeners should exist in a dedicated controller, which does not extend any other class. Modules with many listeners may use many modRequest controllers to organize concerns, but most modules will use a single controller. The controller name should follow the format `{domain}ModRequestController`.

```php
// Example of a generic modRequest controller
class PaymentsModRequestController {}

// Examples of specific modRequest controllers (for larger modules)
class OrdersModRequestController {}
class CustomersModRequestController {}
class ProductsModRequestController {}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.siteadministrator.com/developer-guide/advanced-topics/untitled.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
