Introducing WordPress Kit. Options

WordPress Kit. Options Cover

github.com/korobochkin/wp-kit
packagist.org/packages/korobochkin/wp-kit

WordPress options and functions like update_option() or get_option() is not best way to perform any operations with data. And I have a long list bellow why this functions in almost all cases useful only for performing operations with RAW data.

0. The key idea. Strings and other data types

While you writing your code you working with variables, instances (objects) or even resources. But native WordPress functions like get_option() always returns string data type. It’s because WordPress core save all option values into schema (database) as strings and then retrieve them back. This have a sense because wp_options table designed to store all types of data: numeric values, strings, arrays and objects. All of this data types can be represented only by strings (what makes WordPress core).

If you are save `bool` type it will returning as `’1′(string)`. It can be returned as `bool` type — when you don’t actually have a value for your option. Many newbie developers get confused with it.

add_option('kolya_option_name', true);
var_dump(get_option('kolya_option_name'));
// print '1'(string), not true(bool)

1. You always need to know the name of option

Each time when you need to retrieve the data you need enter your option name. It’s bad even because you always need type it by hands. There is no code editors which can autocomplete your option name.

update_option('kolya_need_manually_enter_name_each_time');
get_option('kolya_need_manually_enter_name_each_time');

In WordPress Kit you can create your instances or create predefined classes and setup names in __construct().

use Korobochkin\WPKit\Options;
class AdditionalJSURLOption extends Options\AbstractOption {
  public function __construct() {
    $this->setName('additional_js_url');
  }
}


$url = new \AdditionalJSURLOption();
wp_enqueue_script(
  $url->getName(),
  $url->get(),
  array(),
  Plugin::VERSION
);
// To save new value
$url->set('https://...');
$url->flush();

Notice: right now WordPress Kit don’t have any Dependency Injection (Service Containers) there you can store your created on the fly instances but I’m working on it.

2. Mess with option names

Options usage in different files (places) very often leads to that all options have different name style. While reviewing code by other developers I often see that different options have terrible unpredictable names.

// Bad example of options naming
get_option('my_plugin_option');
// In other plugin files
get_option('pluginSettingLogin');

You become mad after hours of trying to debug all this bad code. The good point to follow with your names is:

  1. Prefix all the names with unique string!
  2. Use single name styling (convention).

And here is a good example of how you can perfectly organize your options.

use Korobochkin\WPKit\Options;
class AdditionalJSURLOption extends Options\AbstractOption {
  public function __construct() {
    $this->setName(Plugin::NAME . '_additional_js_url');
  }
}

3. Default values.

What if you are don’t have any value for setting? It’s very common scenario when user just install your plugin. And you need a default values of your settings. But where you can store it? Many developers create options on plugin_activation action. Other developers repeat if-exists-else statements to retrieve the data in mutiple places. This is not good because sooner or later you forget to update all of this places and you product will work wrong or even trigger an PHP error.

WP Kit have default values for everything! You can describe your default value as a name in their __construct() method and just use get() method to get the value.

use Korobochkin\WPKit\Options;
class AdditionalJSURLOption extends Options\AbstractOption {
  public function __construct() {
    $this->setName(Theme::NAME . '_additional_js_url');
    $this->setDefaultValue('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js');
  }
}

// Somethere in the code
$additionalUrl= new \AdditionalJSURLOption();
$additionalUrl->get();
// If your DB have value for this option then it will be returns.
// If this option not exists then bootstrap.js url will returns.

3. Sanitizers and Validators

Another part of WordPress related to options is sanitizers. They triggered when you save your values into DB. You need create your own functions and try to validate values. WordPress core have only is_email() validator — ridiculous. What if you are need to check an url? Or string must exists in your stack of available values? With Kit you easily you can create any sanitizers and validators.

Notice: actually the rules of validation named as Constraints. And Validator – the object which performs validation via Constraints.

The easiest example of using sanitizer is setup something callable right directly in class.

namespace Korobochkin\WPKit\Options;
class BoolOption extends Options\AbstractOption {
  protected $sanitizer = array('Korobochkin\WPKit\Sanitizers\BoolSanitizer', 'sanitize');
}

Right now Kit have only Bool, Float and Integer Sanitizers. And if you are insteresting in more complex validation you need setup Constraints.

use Korobochkin\WPKit\Options;
use Symfony\Component\Validator\Constraints;
class AdditionalJSURLOption extends Options\AbstractOption {
  public function __construct() {
    $this->setName(Theme::NAME . '_additional_js_url');
    $this->setDefaultValue('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js');
  }

  public function buildConstraint() {
    return array(
      new Constraints\NotBlank(),
      new Constraints\Url()
    ));
  }
}

// Validate the link
$additionalUrl = new \AdditionalJSURLOption();
$additionalUrl->set('blahblah not the url');
$results = $additionalUrl->validate();
// or
if($additionalUrl->isValid()) {
  // do something
}

Constraints is a part of Symfony Validator library which have tons of constraints and each of them you can customize. And this constraints have more insteresting stuff inside. For example you can output error messages after validation.

if (count($errors) > 0) {
  $results = (string) $errors;
}

// or get one by one
foreach($results as $error) {
  echo $error->getCode() . ': ' . $error->getMessage();
}

Want more? Checkout the source code. Right now Kit only in alpha.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s