Custom Addons

Custom addons allow you to create simple to complex GUIs that run right inside your shop.

Custom addons have access to the ProcessWire and $padloper APIs. This makes custom adons a very powerful feature yet very flexible to suit various needs.

There is no limit to the number of custom addons you can create and add to your shop.

Develop Custom Addon

Developing a custom addon is easy. A custom addon must implement the Interface PadloperAddons. They can extend any class if they need to. A good starting point is to extend WireData. The minimum code structure for a custom addon is outlined below.

Custom Addon Code

In the examples below, we will assume a fictitious payment addon called MyAwesomeAddon.

As stated in the main addons documentation, all addons must adhere to pre-defined file structure and file naming rules. Hence, your MyAwesomeAddon will be located at /site/templates/padloper/addons/MyAwesomeAddon/*.*.

As a bare minimum, you will need the file MyAwesomeAddon.php. This file must be a PHP Class. For example:


namespace ProcessWire;


// use/require any other third-party libraries your addon class might need

/**
 *
 * MyAwesomeAddon for Padloper.
 *
 *
 */

class MyAwesomeAddon extends WireData implements PadloperAddons {

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Interface PadloperAddons

All custom addons need to implement the following public methods defined by the Interface Class PadloperAddons.

interface PadloperAddons {}
1

The file for this class can be found at /site/modules/Padloper/includes/addons/PadloperAddons.php.

getType()

This method returns the addon type. Custom addons must return the string value custom for this method.

/**
 * Returns addon type.
 *
 * Must be one of Padloper pre-defined types.
 *
 * @access public
 * @return string $type
 */
public function getType();
1
2
3
4
5
6
7
8
9

getClassName()

This method returns the name of the Class of the addon. In this example this method would return MyAwesomeAddon.

/**
 * Returns addon class name.
 *
 * @access public
 * @return string $className.
 */
public function getClassName();
1
2
3
4
5
6
7

getTitle()

This method returns the title of the addon. This will be displayed in the addons dashboard to identify the addon. In this example this method could return My Awesome Addon.

/**
 * Returns a user-friendly title of this addon.
 *
 * @access public
 * @return string $title.
 */
public function getTitle();
1
2
3
4
5
6
7

getDescription()

This method returns a brief description about the addon. This will be displayed in the addons dashboard to describe the addon. In this example this method could return:

My Awesome Addon allows you to view detailed customer insights for your shop.

/**
 * Returns short description of this addon.
 *
 * @access public
 * @return string $description.
 */
public function getDescription();
1
2
3
4
5
6
7

In addition to the above Interface requirements, all custom addons must have the following method and property.

renderViewURL

Since all custom addons need to show and optionally allow editing of the addon, they need to declare the name of the URL where the view/edit GUI will be displayed. This will be added as a URL Segment to /shop/addons/view/. In our example here, this would be /shop/addons/view/my-awesome-addon/. This value needs to be declared in the property renderViewURL.

/** @var string $this->renderViewURL */
$this->renderViewURL = 'my-awesome-addon';
1
2

Though not a requirement, it is advisable to have the value of renderViewURL be the result of a ProcessWire $sanitizer->pageName($yourAddonTitle).

render()

This method renders the markup for the backend GUI of your custom addon. This could be anything you want. It could be as simple or complex as you need. It could contain forms, be ajax powered, dynamic, for information only, leverage $padloper, etc.

/**
 * Render backend GUI markup for the custom addon.
 *
 * @access protected
 * @return string
 */
 protected function render();
1
2
3
4
5
6
7

In addition to the above required methods and property, custom addons can require additional methods and properties depending on the features of the addon. These are outlined below.

isConfigurable

This property needs to be declared for addons that save configurations. It needs to return a boolean value.

/** @var bool $this->isConfigurable */
$this->isConfigurable = true;
1
2

Please note that configurations need to be saved as JSON, i.e. key/value pairs where the keys are the setting and the value the related value for that setting.

Configurable addons will be passed the page that stores their settings as well as the string with the name of the plain textarea field that stores their settings. This is outlined below.

setAddonPage()

Configurable custom addons need to define the method setAddonPage(). This method will receive the $page that stores the addon's configurations as the first argument and the name of the plain textarea field, $addonSettingsFieldName, as the second argument. This will allow the addon developer to implement code to save and retrieve the addon's configurations from the addon page. In the example below, two class properties are set to store the addon page and the settings field name respectively.

/**
 * Get and set the associated page for this addon.
 *
 * @param Page $page The page that stores this addon's configurations.
 * @param string $addonSettingsFieldName The name of the plain textarea field to store the addon's configurations.
 * @return void
 */
public function setAddonPage(Page $page, string $addonSettingsFieldName) {
  $this->addonPage = $page;
  $this->addonSettingsFieldName = $addonSettingsFieldName;
}
1
2
3
4
5
6
7
8
9
10
11

processForm()

Custom addons that submit and process non-ajax forms need to define this method. This method will receive the InputfieldForm form as the first argument and the WireInputData input as the second argument.

Padloper will call this method when your addon submits a form. The handling and processing of the form, including specific error checking and sanitization is left to the developer to implement.

Below is an example implementation of processForm().

/**
 * Process the form submission for this addon.
 *
 * @param InputfieldForm $form The ProcessWire form object for the form.
 * @param WireInputData $input The ProcessWire input object with sent form values.
 * @return void
 */
public function processForm(InputfieldForm $form, WireInputData $input) {
  // SANITIZE FORM VALUES + CHECK FOR ERRORS
  $sanitizedValues = $this->sanitizeFormValuesAndCheckForErrors($input);
  if (!empty($sanitizedValues['form_errors'])) {
    // prepare and get error values
    // REJECT FORM: ERRORS FOUND
    return $this->getFormErrorsNotice($sanitizedValues['form_errors']);
  } else {
    // SAVE VALUES
    $this->saveMyAwesomeAddonConfigurations($sanitizedValues['ok_fields']);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Ajax Properties and Methods

isAddonUseAjax

This property needs to be declared for addons that use ajax to interact with the Padloper shop backend. It needs to return a boolean value.

/** @var bool $this->isAddonUseAjax */
$this->isAddonUseAjax = true;
1
2

setAddonAjaxEndpoint()

Configurable custom addons that use ajax need to define the method setAddonAjaxEndpoint(). This method will receive the the string value of the Padloper ajax endpoint that the addon needs to send its ajax requests to as the first argument.

Below is an example implementation of this method. In the example, a class property is set to store the ajax endpoint for use by the addon.

/**
 * Set the ajax endpoint for this addon to use.
 *
 * @param string $ajaxEndpoint The Padloper ajax endpoint.
 * @return void
 */
public function setAddonAjaxEndpoint($ajaxEndpoint) {
  $this->addonAjaxEndpoint = $ajaxEndpoint;
}
1
2
3
4
5
6
7
8
9

processAjaxForm()

Custom addons that submit and process ajax forms need to define this method. This method will receive the WireInputData input as the first argument. Padloper will call this method when your addon submits an ajax request to the setAddonAjaxEndpoint. The handling and processing of the ajax request, including specific error checking and sanitization is left to the developer to implement.

The response sent back from this method must be HTML and not JSON or other formats.

Below is an example implementation of this method.

/**
 * Process the ajax request for this addon.
 *
 * @param WireInputData $input The ProcessWire input object with sent form values.
 * @return string $out The HTML to send back to the browser.
 */
public function processAjaxForm(WireInput $input) {
  $results = $this->getRequestedProducts($input);
  $out = $this->buildResultsMarkup($results);
  return $out;
}
1
2
3
4
5
6
7
8
9
10
11

In addition, custom addons that utilise ajax-powered forms must send either an input named is_padloper_addon_ajax_post for POST ajax requests or an input named is_padloper_addon_ajax_get for GET ajax requests. Their values should resolve to a boolean true. It is recommended to implement these as hidden form inputs.