Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Screenfeed committed Jan 12, 2021
0 parents commit cc95dc8
Show file tree
Hide file tree
Showing 16 changed files with 2,260 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
indent_size = 4

[*.{txt,md}]
trim_trailing_whitespace = false

[{*.txt}]
end_of_line = crlf

[{*.json}]
indent_style = space
trim_trailing_whitespace = false
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Directories
/.git export-ignore

# Files
/.editorconfig export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/composer.lock export-ignore
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Directories
/.vscode
/report
/vendor

# Files
.DS_Store
Thumbs.db
5 changes: 5 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ul-indent": { "indent": 4 },
"line-length": false,
"no-hard-tabs": false
}
169 changes: 169 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# AutoWPOptions

Allows to manage a set of options in WordPress.

Requires **php 5.4** and **WordPress 4.4**.

## What you will be able to do

* Decide if your set of options is network-wide or site-wide in a multisite environment,
* Obviously, get/set/delete values,
* Provide default and reset values,
* Cast, sanitize, and validate values automatically,
* Create an upgrade process.

## How to install

With composer:

```json
"require": {
"screenfeed/autowpoptions": "*"
},
```

## How to use

Create one class that extends *Sanitization\AbstractSanitization*.
This class will contain the following:

### Default values

**Required**. They are used when an option has no value yet. Their type is used to decide how to cast the values.

### Reset values

**Optional**. Reset values are used if the whole set of options does not exist yet: sometimes you may want them to be different from the default values. Default values are used for the missing reset values.
You could also use them in a "Reset Options" process for example.

### A sanitization method

**Required**. It is run for each option, when getting/updating it.

### A validation method

**Required** (but can simply return the entry if not needed). It is run once for all options on update. It allows to edit some values, depending on others for example.

### Two keywords as class properties

**Required**. They are used in hook names.

### Example

How to create an option that is stored as an array in the WordPress' options table:

* The option name is `myplugin_settings`,
* The current plugin version is `2.3`,
* The option must be network-wide on a multisite install.

```php
use Screenfeed\AutoWPOptions\Storage\WpOption;
use Screenfeed\AutoWPOptions\Options;

$option_name = 'myplugin_settings';
$network_wide = true;
$plugin_version = '2.3';

$options_sanitization = new MyOptionsSanitization( $plugin_version );
$options_storage = new WpOption( $option_name, $network_wide );
$options = new Options( $options_storage, $options_sanitization );

$foobar = $options->get( 'foobar' ); // Returns an array of positive integers.
```

The `MyOptionsSanitization` class:

* The two keywords `myplugin` and `settings` are used in hook names, like the filter `get_myplugin_settings_foobar`.

```php
use Screenfeed\AutoWPOptions\Sanitization\AbstractSanitization;

class OptionSanitization extends AbstractSanitization {

/**
* Prefix used in hook names.
*
* @var string
*/
protected $prefix = 'myplugin';

/**
* Suffix used in hook names.
*
* @var string
*/
protected $identifier = 'settings';

/**
* The default values.
* These are the "zero state" values.
* Don't use null as value.
*
* @var array<mixed>
*/
protected $default_values = [
'foobar' => [],
'barbaz' => 0,
];

/**
* Sanitizes and validates an option value. Basic casts have been made.
*
* @param string $key The option key.
* @param mixed $value The value.
* @param mixed $default The default value.
* @return mixed
*/
protected function sanitize_and_validate_value( $key, $value, $default ) {
switch ( $key ) {
case 'foobar':
return is_array( $value ) ? array_unique( array_map( 'absint', $value ) ) : [];
case 'barbaz':
return absint( $value );
}

return false;
}

/**
* Validates all options before storing them. Basic sanitization and validation have been made, row by row.
*
* @param array<mixed> $values The option value.
* @return array<mixed>
*/
protected function validate_values_on_update( array $values ) {
if ( ! in_array( $values['barbaz'], $values['foobar'], true ) ) {
$values['barbaz'] = $this->default_values['barbaz'];
}
return $values;
}
}

```

### An "upgrade process"?

The plugin version used when instanciating `MyOptionsSanitization` is stored in the option and can be used in a future plugin release for an upgrade process.
For example:

```php
$site_version = $options->get( 'version' );

if ( version_compare( $site_version, '1.2' ) < 0 ) {
$options->set( [ 'barbaz', 8 ] );
}

$options->set( [ 'version', '2.5' ] );
```

### Reserved keyworks

Don't use the following keywords as option keys, they are used internally:

* cached
* version

## Extending

You may want to store your options elsewhere than the WordPress' options table, maybe in configuration file (heck, why not). This package is built in such a way that it is possible.
To do so, you need to create a class that will replace `Screenfeed\AutoWPOptions\Storage\WpOption`, and implement `Screenfeed\AutoWPOptions\Storage\StorageInterface`.
53 changes: 53 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "screenfeed/autowpoptions",
"description": "Manage a set of WordPress options.",
"keywords": [
"wordpress",
"options"
],
"homepage": "https://github.com/Screenfeed/autowpoptions",
"license": "GPL-2.0",
"authors": [
{
"name": "Grégory Viguier",
"role": "Developer"
}
],
"type": "library",
"config": {
"sort-packages": true
},
"support": {
"issues": "https://github.com/Screenfeed/autowpoptions/issues",
"source": "https://github.com/Screenfeed/autowpoptions"
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"php": "^7.0",
"automattic/phpcs-neutron-standard": "*",
"dealerdirect/phpcodesniffer-composer-installer": "*",
"phpcompatibility/phpcompatibility-wp": "*",
"phpmetrics/phpmetrics": "*",
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "*",
"szepeviktor/phpstan-wordpress": "*",
"wp-coding-standards/wpcs": "*"
},
"autoload": {
"psr-4": {
"Screenfeed\\AutoWPOptions\\": "src/"
}
},
"scripts": {
"cs": "phpcs",
"stan": "\"vendor/bin/phpstan\" analyze --memory-limit=200M",
"metrics": "phpmetrics --config=phpmetrics.json",
"run-lints": [
"@cs",
"@stan",
"@metrics"
]
}
}
Loading

0 comments on commit cc95dc8

Please sign in to comment.