Dorokhov.codes

Settings API

The WooCommerce Settings API is used by shipping methods and payment gateways to display, save and load options.

To use it we should extend our class from WC_Payment_Gateway or WC_Settings_API.

Settings on the setting screens are specified in the $form_fields property. Here’s an example:

$this->form_fields = [
 'title' => [
      'title'       => __( 'Title', 'woocommerce' ),
      'type'        => 'text',
      'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
      'default'     => __( 'PayPal', 'woocommerce' )
  ],
 'description' => [
      'title'       => __( 'Description', 'woocommerce' ),
      'type'        => 'textarea',
      'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ),
      'default'     => __("Pay via PayPal; you can pay with your credit card if you don't have a PayPal account", 'woocommerce')
   ]
];

Format for the options (including default values):

'option_name' => [
     'title'        => 'Title for your option shown on the settings page',
     'description'  => 'Description for your option shown on the settings page',
     'type'         => 'text|password|textarea|checkbox|select|multiselect',
     'default'      => 'Default value for the option',
     'class'        => 'Class for the input',
     'css'          => 'CSS rules added line to the input',
     'label'        => 'Label', // checkbox only
     'options'      => [
          'key' => 'value'
     ] // array of options for select/multiselects only
]

There is a method which is used to fill $form_fields: init_form_fields().

function init_form_fields() {
    $this->form_fields = [...];
}

Render the admin settings page

The WC_Settings_API class has a method admin_options() which output the admin options table:

/**
 * Output the admin options table.
 */
public function admin_options() {
    echo '<table class="form-table">' . $this->generate_settings_html( $this->get_form_fields(), false ) . '</table>'; // WPCS: XSS ok.
}

As we can see, HTML itself is formed inside the generate_settings_html method:

/**
 * Generate Settings HTML.
 * Generate the HTML for the fields on the "settings" screen.
 */
public function generate_settings_html( $form_fields = array(), $echo = true ) {
    // ...
}

So we can override these methods to change the page.

Saving options

There’s a method process_admin_options() of the WC_Settings_API class which does all necessary operations to store the options.

So in order to make our settings page work we have to add this action to either woocommerce_update_options_payment_gateways or woocommerce_update_options_shipping_methods hook.

add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
add_action('woocommerce_update_options_shipping_methods_' . $this->id, [$this, 'process_admin_options']);

All the options will be serialized and saved into wp_options table with the name woocommerce_{ID}_settings, where {ID} is $this->id.

Load options from the database

There’s a function init_settings() from the WC_Settings_API class that gets options from the database and store them in an instance (in the $settings property).

After that we can use these options to populate the properties, for example:

$this->title        = $this->settings['title'];
$this->description  = $this->settings['description'];

But there’s also a method get_option() in the WC_Settings_API class that is used for getting values from $settings. So we should do it like:

$this->title        = $this->get_option('title')
$this->description  = $this->get_option('description');

Enhanced selects

'class' => 'wc-enhanced-select',