Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • codeccoop/wp/plugins/wpct-plugin-abstracts
1 result
Show changes
Commits on Source (1)
...@@ -4,14 +4,57 @@ namespace WPCT_ABSTRACT; ...@@ -4,14 +4,57 @@ namespace WPCT_ABSTRACT;
if (!class_exists('\WPCT_ABSTRACT\Menu')) : if (!class_exists('\WPCT_ABSTRACT\Menu')) :
/**
* Plugin menu abstract class.
*
* @since 1.0.0
*/
abstract class Menu extends Singleton abstract class Menu extends Singleton
{ {
/**
* Handle plugin settings class name.
*
* @since 1.0.0
*
* @var string $settings_class Settings class name.
*/
protected static $settings_class = '\WPCT_ABSTRACT\Settings'; protected static $settings_class = '\WPCT_ABSTRACT\Settings';
/**
* Handle menu name.
*
* @since 1.0.0
*
* @var string $name Menu name.
*/
protected $name; protected $name;
/**
* Handle menu slug.
*
* @since 1.0.0
*
* @var string $settings_class Settings class name.
*/
protected $slug; protected $slug;
/**
* Handle plugin settings instance.
*
* @since 1.0.0
*
* @var object $settings Settings instance.
*/
protected $settings; protected $settings;
/**
* Class constructor. Set attributes and hooks to wp admin hooks.
*
* @since 1.0.0
*
* @param string $name Plugin name.
* @param string $slug Plugin textdomain.
*/
public function __construct($name, $slug) public function __construct($name, $slug)
{ {
$this->name = $name; $this->name = $name;
...@@ -27,6 +70,11 @@ if (!class_exists('\WPCT_ABSTRACT\Menu')) : ...@@ -27,6 +70,11 @@ if (!class_exists('\WPCT_ABSTRACT\Menu')) :
}); });
} }
/**
* Register plugin options page.
*
* @since 1.0.0
*/
private function add_menu() private function add_menu()
{ {
add_options_page( add_options_page(
...@@ -40,6 +88,14 @@ if (!class_exists('\WPCT_ABSTRACT\Menu')) : ...@@ -40,6 +88,14 @@ if (!class_exists('\WPCT_ABSTRACT\Menu')) :
); );
} }
/**
* Render menu page HTML.
*
* @since 1.0.0
*
* @param boolean $echo Should put render to the output buffer.
* @return string|null $render Page content.
*/
protected function render_page($echo = true) protected function render_page($echo = true)
{ {
$page_settings = $this->settings->get_settings(); $page_settings = $this->settings->get_settings();
...@@ -75,16 +131,37 @@ if (!class_exists('\WPCT_ABSTRACT\Menu')) : ...@@ -75,16 +131,37 @@ if (!class_exists('\WPCT_ABSTRACT\Menu')) :
return $output; return $output;
} }
/**
* Menu name getter.
*
* @since 1.0.0
*
* @return string $name Menu name.
*/
public function get_name() public function get_name()
{ {
return $this->name; return $this->name;
} }
/**
* Menu slug getter.
*
* @since 1.0.0
*
* @return string $slug Menu slug.
*/
public function get_slug() public function get_slug()
{ {
return $this->slug; return $this->slug;
} }
/**
* Menu settings getter.
*
* @since 1.0.0
*
* @return array $settings Plugin settings.
*/
public function get_settings() public function get_settings()
{ {
return $this->settings; return $this->settings;
......
...@@ -7,21 +7,75 @@ use ReflectionClass; ...@@ -7,21 +7,75 @@ use ReflectionClass;
if (!class_exists('\WPCT_ABSTRACT\Plugin')) : if (!class_exists('\WPCT_ABSTRACT\Plugin')) :
/**
* Plugin abstract class.
*
* @since 1.0.0
*/
abstract class Plugin extends Singleton abstract class Plugin extends Singleton
{ {
/**
* Handle plugin menu class name.
*
* @since 1.0.0
*
* @var string $menu_class Menu class name.
*/
protected static $menu_class; protected static $menu_class;
/**
* Handle plugin textdomain.
*
* @since 1.0.0
*
* @var string $textdomain Plugin text domain.
*/
public static $textdomain; public static $textdomain;
/**
* Handle plugin name.
*
* @since 1.0.0
*
* @var string $name Plugin name.
*/
public static $name; public static $name;
/**
* Handle plugin menu instance.
*
* @since 1.0.0
*
* @var object $menu Plugin menu instance.
*/
private $menu; private $menu;
/**
* Plugin initializer.
*
* @since 1.0.0
*/
abstract public function init(); abstract public function init();
/**
* Plugin activation callback.
*
* @since 1.0.0
*/
abstract public static function activate(); abstract public static function activate();
/**
* Plugin deactivation callback.
*
* @since 1.0.0
*/
abstract public static function deactivate(); abstract public static function deactivate();
/**
* Plugin constructor. Bind plugin to wp init hook and load textdomain.
*
* @since 1.0.0
*/
public function __construct() public function __construct()
{ {
if (empty(static::$name) || empty(static::$textdomain)) { if (empty(static::$name) || empty(static::$textdomain)) {
...@@ -42,16 +96,37 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) : ...@@ -42,16 +96,37 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) :
}, 10, 2); }, 10, 2);
} }
/**
* Plugin menu getter.
*
* @since 1.0.0
*
* @return object $menu Plugin menu instance.
*/
public function get_menu() public function get_menu()
{ {
return $this->menu; return $this->menu;
} }
/**
* Plugin name getter.
*
* @since 1.0.0
*
* @return string $name Plugin name.
*/
public function get_name() public function get_name()
{ {
return static::$name; return static::$name;
} }
/**
* Plugin index getter.
*
* @since 1.0.0
*
* @return string $index Plugin index file path.
*/
public function get_index() public function get_index()
{ {
$reflector = new ReflectionClass(get_class($this)); $reflector = new ReflectionClass(get_class($this));
...@@ -59,11 +134,25 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) : ...@@ -59,11 +134,25 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) :
return plugin_basename($fn); return plugin_basename($fn);
} }
/**
* Plugin textdomain getter.
*
* @since 1.0.0
*
* @return string $textdomain Plugin textdomain.
*/
public function get_textdomain() public function get_textdomain()
{ {
return static::$textdomain; return static::$textdomain;
} }
/**
* Plugin data getter.
*
* @since 1.0.0
*
* @return array $data Plugin data.
*/
public function get_data() public function get_data()
{ {
include_once(ABSPATH . 'wp-admin/includes/plugin.php'); include_once(ABSPATH . 'wp-admin/includes/plugin.php');
...@@ -76,11 +165,23 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) : ...@@ -76,11 +165,23 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) :
} }
} }
/**
* Active state getter.
*
* @since 1.0.0
*
* @return boolean $is_active Plugin active state.
*/
public function is_active() public function is_active()
{ {
return apply_filters('wpct_is_plugin_active', false, $this->get_index()); return apply_filters('wpct_is_plugin_active', false, $this->get_index());
} }
/**
* Load plugin textdomain.
*
* @since 1.0.0
*/
private function load_textdomain() private function load_textdomain()
{ {
$data = $this->get_data(); $data = $this->get_data();
...@@ -93,6 +194,15 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) : ...@@ -93,6 +194,15 @@ if (!class_exists('\WPCT_ABSTRACT\Plugin')) :
); );
} }
/**
* Load plugin mofile.
*
* @since 1.0.0
*
* @param string $mofile Plugin mofile path.
* @param string $domain Plugin textdomain.
* @return string $mofile Plugin mofile path.
*/
private function load_mofile($mofile, $domain) private function load_mofile($mofile, $domain)
{ {
if ($domain === static::$textdomain && strpos($mofile, WP_LANG_DIR . '/plugins/') === false) { if ($domain === static::$textdomain && strpos($mofile, WP_LANG_DIR . '/plugins/') === false) {
...@@ -111,8 +221,12 @@ endif; ...@@ -111,8 +221,12 @@ endif;
if (!function_exists('\WPCT_ABSTRACT\is_plugin_active')) : if (!function_exists('\WPCT_ABSTRACT\is_plugin_active')) :
add_filter('wpct_is_plugin_active', '\WPCT_ABSTRACT\is_plugin_active', 10, 2); /**
function is_plugin_active($_, $plugin_name) * Check if plugin is active
*
* @since 1.0.0
*/
function is_plugin_active($plugin_name)
{ {
include_once(ABSPATH . 'wp-admin/includes/plugin.php'); include_once(ABSPATH . 'wp-admin/includes/plugin.php');
$plugins = get_plugins(); $plugins = get_plugins();
...@@ -137,4 +251,9 @@ if (!function_exists('\WPCT_ABSTRACT\is_plugin_active')) : ...@@ -137,4 +251,9 @@ if (!function_exists('\WPCT_ABSTRACT\is_plugin_active')) :
return in_array($plugin_name, array_keys($actives)); return in_array($plugin_name, array_keys($actives));
} }
// Hooks is_plugin_active as filter.
add_filter('wpct_is_plugin_active', function ($null, $plugin_name) {
return \WPCT_ABSTRACT\is_plugin_active($plugin_name);
}, 10, 2);
endif; endif;
...@@ -2,23 +2,79 @@ ...@@ -2,23 +2,79 @@
namespace WPCT_ABSTRACT; namespace WPCT_ABSTRACT;
use Error;
if (!class_exists('\WPCT_ABSTRACT\Settings')) : if (!class_exists('\WPCT_ABSTRACT\Settings')) :
/**
* Undefined value.
*
* @since 1.0.0
*/
class Undefined class Undefined
{ {
}; };
/**
* Plugin settings abstract class.
*
* @since 1.0.0
*/
abstract class Settings extends Singleton abstract class Settings extends Singleton
{ {
/**
* Handle settings group name.
*
* @since 1.0.0
*
* @var string $group_name Settings group name.
*/
protected $group_name; protected $group_name;
/**
* Handle settings schemas.
*
* @since 1.0.0
*
* @var string $schemas Settings schemas.
*/
public static $schemas = []; public static $schemas = [];
/**
* Handle settings default values.
*
* @since 1.0.0
*
* @var string $defaults Settings default values.
*/
public static $defaults = []; public static $defaults = [];
/**
* Handle settings cached values.
*
* @since 1.0.0
*
* @var string $cache Settings cached values.
*/
private static $cache = []; private static $cache = [];
/**
* Handle settings group name.
*
* @since 1.0.0
*
* @var string $group_name Settings group name.
*/
abstract public function register(); abstract public function register();
/**
* Get setting values.
*
* @since 1.0.0
*
* @param string $group_name Settings group name.
* @param string $setting Setting name.
* @param string $field Field name.
* @return array|string $value Setting default values.
*/
public static function get_setting($group_name, $setting, $field = null) public static function get_setting($group_name, $setting, $field = null)
{ {
$default = static::get_default($group_name, $setting); $default = static::get_default($group_name, $setting);
...@@ -34,6 +90,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -34,6 +90,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return isset($setting[$field]) ? $setting[$field] : null; return isset($setting[$field]) ? $setting[$field] : null;
} }
/**
* Get setting default values.
*
* @since 1.0.0
*
* @param string $group_name Settings group name.
* @param string $setting Setting name.
* @param string $field Field name.
* @return array|string $value Setting default values.
*/
public static function get_default($group_name, $setting, $field = null) public static function get_default($group_name, $setting, $field = null)
{ {
$setting_name = $group_name . '_' . $setting; $setting_name = $group_name . '_' . $setting;
...@@ -46,6 +112,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -46,6 +112,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return isset($default[$field]) ? $default[$field] : null; return isset($default[$field]) ? $default[$field] : null;
} }
/**
* Get setting schema.
*
* @since 1.0.0
*
* @param string $group_name Settings group name.
* @param string $setting Setting name.
* @param string $field Field name.
* @return array $schema Setting or field schema.
*/
public static function get_schema($group_name, $setting, $field = null) public static function get_schema($group_name, $setting, $field = null)
{ {
$setting_name = $group_name . '_' . $setting; $setting_name = $group_name . '_' . $setting;
...@@ -59,20 +135,41 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -59,20 +135,41 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return isset($schema[$field]) ? $schema[$field] : null; return isset($schema[$field]) ? $schema[$field] : null;
} }
/**
* Class constructor. Store the group name and hooks to pre_update_option.
*
* @since 1.0.0
*
* @param string $group_name Settings group name.
*/
public function __construct($group_name) public function __construct($group_name)
{ {
$this->group_name = $group_name; $this->group_name = $group_name;
add_filter('pre_update_option', function ($value, $option, $from) { add_filter('pre_update_option', function ($value, $option, $from) {
return $this->sanitize_option($option, $value); return $this->sanitize_setting($option, $value);
}, 10, 3); }, 10, 3);
} }
/**
* Get settings group name.
*
* @since 1.0.0
*
* @return string $group_name Settings group name.
*/
public function get_group_name() public function get_group_name()
{ {
return $this->group_name; return $this->group_name;
} }
/**
* Return group settings names.
*
* @since 1.0.0
*
* @return array $names Settings names.
*/
public function get_settings() public function get_settings()
{ {
$settings = []; $settings = [];
...@@ -85,6 +182,15 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -85,6 +182,15 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return $settings; return $settings;
} }
/**
* Register setting.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param array|null $schema Setting schema.
* @defaults array $defaults Setting default values.
*/
public function register_setting($setting, $schema = null, $default = []) public function register_setting($setting, $schema = null, $default = [])
{ {
$setting_name = $this->setting_name($setting); $setting_name = $this->setting_name($setting);
...@@ -94,6 +200,7 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -94,6 +200,7 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
$default = self::get_default($this->group_name, $setting); $default = self::get_default($this->group_name, $setting);
$schema = self::get_schema($this->group_name, $setting); $schema = self::get_schema($this->group_name, $setting);
// Register setting
register_setting( register_setting(
$setting_name, $setting_name,
$setting_name, $setting_name,
...@@ -111,18 +218,21 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -111,18 +218,21 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
], ],
); );
// Cache data on option creation
add_action('add_option', function ($option, $value) use ($setting_name) { add_action('add_option', function ($option, $value) use ($setting_name) {
if ($option === $setting_name && !empty($to)) { if ($option === $setting_name && !empty($to)) {
static::$cache[$setting_name] = $value; static::$cache[$setting_name] = $value;
} }
}, 5, 2); }, 5, 2);
// Cache data on option update
add_action('update_option', function ($option, $from, $to) use ($setting_name) { add_action('update_option', function ($option, $from, $to) use ($setting_name) {
if ($option === $setting_name && !empty($to)) { if ($option === $setting_name && !empty($to)) {
static::$cache[$setting_name] = $to; static::$cache[$setting_name] = $to;
} }
}, 5, 3); }, 5, 3);
// Add settings section on admin init
add_action('admin_init', function () use ($setting_name, $setting) { add_action('admin_init', function () use ($setting_name, $setting) {
add_settings_section( add_settings_section(
$setting_name . '_section', $setting_name . '_section',
...@@ -140,6 +250,14 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -140,6 +250,14 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
}); });
} }
/**
* Register setting field.
*
* @since 1.0.0
*
* @param string $field_name Field name.
* @param string $setting Setting name.
*/
private function add_settings_field($field_name, $setting) private function add_settings_field($field_name, $setting)
{ {
$setting_name = $this->setting_name($setting); $setting_name = $this->setting_name($setting);
...@@ -158,6 +276,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -158,6 +276,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
); );
} }
/**
* Render field HTML.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param string $field Field name.
* @param string|Undefined $value Field value.
* @return string $html Input HTML.
*/
protected function field_render() protected function field_render()
{ {
$args = func_get_args(); $args = func_get_args();
...@@ -172,6 +300,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -172,6 +300,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return $this->_field_render($setting, $field, $value); return $this->_field_render($setting, $field, $value);
} }
/**
* Render field HTML.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param string $field Field name.
* @param string|Undefined $value Field value.
* @return string $html Input HTML.
*/
private function _field_render($setting, $field, $value) private function _field_render($setting, $field, $value)
{ {
$is_root = false; $is_root = false;
...@@ -193,6 +331,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -193,6 +331,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
} }
} }
/**
* Render input HTML.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param string $field Field name.
* @param string $value Field value.
* @return string $html Input HTML.
*/
protected function input_render($setting, $field, $value) protected function input_render($setting, $field, $value)
{ {
$setting_name = $this->setting_name($setting); $setting_name = $this->setting_name($setting);
...@@ -212,10 +360,6 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -212,10 +360,6 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
$is_list = is_list($default_value); $is_list = is_list($default_value);
} }
$is_bool = is_bool($default_value); $is_bool = is_bool($default_value);
// if ($is_bool) {
// $is_bool = true;
// $value = 'on' === $value;
// }
if ($is_bool) { if ($is_bool) {
return "<input type='checkbox' name='{$setting_name}[{$field}]' " . ($value ? 'checked' : '') . " />"; return "<input type='checkbox' name='{$setting_name}[{$field}]' " . ($value ? 'checked' : '') . " />";
...@@ -224,6 +368,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -224,6 +368,16 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
} }
} }
/**
* Render fieldset HTML.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param string $field Field name.
* @param array $data Setting data.
* @return string $html Fieldset HTML.
*/
private function fieldset_render($setting, $field, $data) private function fieldset_render($setting, $field, $data)
{ {
$setting_name = $this->setting_name($setting); $setting_name = $this->setting_name($setting);
...@@ -244,6 +398,15 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -244,6 +398,15 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return $fieldset; return $fieldset;
} }
/**
* Render control HTML.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param string $field Field name.
* @return string $html Control HTML.
*/
private function control_render($setting, $field) private function control_render($setting, $field)
{ {
$setting_name = $this->setting_name($setting); $setting_name = $this->setting_name($setting);
...@@ -259,85 +422,58 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) : ...@@ -259,85 +422,58 @@ if (!class_exists('\WPCT_ABSTRACT\Settings')) :
return ob_get_clean(); return ob_get_clean();
} }
/**
* Render control style tag.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @param string $field Field name.
* @return string $tag Style HTML tag with control styles.
*/
private function control_style($setting, $field) private function control_style($setting, $field)
{ {
$setting_name = $this->setting_name($setting); $setting_name = $this->setting_name($setting);
return "<style>#{$setting_name}__{$field} td td,#{$setting_name}__{$field} td th{padding:0}#{$setting_name}__{$field} table table{margin-bottom:1rem}</style>"; return "<style>#{$setting_name}__{$field} td td,#{$setting_name}__{$field} td th{padding:0}#{$setting_name}__{$field} table table{margin-bottom:1rem}</style>";
} }
/**
* Return setting full name.
*
* @since 1.0.0
*
* @param string $setting Setting name.
* @return string $setting_name Setting full name.
*/
protected function setting_name($setting) protected function setting_name($setting)
{ {
return $this->group_name . '_' . $setting; return $this->group_name . '_' . $setting;
} }
private function sanitize_option($option, $value) /**
* Sanitize setting data before database inserts.
*
* @since 1.0.0
*
* @param string $option Setting name.
* @param array $value Setting data.
* @return array $value Sanitized setting data.
*/
private function sanitize_setting($option, $value)
{ {
$settings = $this->get_settings(); $settings = $this->get_settings();
if (in_array($option, $settings)) { if (!in_array($option, $settings)) {
[$group, $setting] = explode('_', $option); return $value;
$default = Settings::get_default($group, $setting);
if (empty($value)) {
return $default;
}
$schema = Settings::get_schema($group, $setting);
try {
return $this->sanitize_object($schema, $value, $default);
} catch (Error) {
return $default;
}
} }
return $value; [$group, $setting] = explode('_', $option);
} $schema = Settings::get_schema($group, $setting);
private function sanitize_object($schema, $value, $default) if (!rest_validate_value_from_schema($value, $schema)) {
{ return new WP_Error('rest_invalid_schema', 'The setting is not schema conformant', ['value' => $value, 'schema' => $schema]);
foreach ($schema as $key => $defn) {
if (empty($value[$key])) {
if ($defn['type'] === 'boolean') {
$value[$key] = false;
} else {
$value[$key] = $default[$key];
}
} else {
if ($defn['type'] === 'array') {
$value[$key] = $this->sanitize_array($defn['items'], $value[$key], $default[$key] ?: []);
} elseif ($defn['type'] === 'object') {
$value[$key] = $this->sanitize_object($defn['properties'], $value[$key], $default[$key] ?: []);
} elseif ($defn['type'] === 'boolean') {
$value[$key] = $value[$key] === 'on';
} else {
$value[$key] = empty($value[$key]) ? $default[$key] : $value[$key];
}
}
}
foreach (array_keys($value) as $key) {
if (!in_array($key, array_keys($schema))) {
unset($value[$key]);
};
}
return $value;
}
private function sanitize_array($schema, $value, $defaults)
{
$default = null;
for ($i = 0; $i < count($value); $i++) {
$default = count($defaults) > $i ? array_shift($defaults) : $default;
if ($schema['type'] === 'array') {
$value[$i] = $this->sanitize_array($schema['items'], $value[$i], $default ?: []);
} elseif ($schema['type'] === 'object') {
$value[$i] = $this->sanitize_object($schema['properties'], $value[$i], $default ?: []);
} else {
$value[$i] = empty($value[$i]) ? $default[0] : $value[$i];
}
} }
return $value; return rest_sanitize_value_from_schema($value, $schema);
} }
} }
...@@ -345,6 +481,14 @@ endif; ...@@ -345,6 +481,14 @@ endif;
if (!function_exists('\WPCT_ABSTRACT\is_list')) : if (!function_exists('\WPCT_ABSTRACT\is_list')) :
/**
* Check if array is positional.
*
* @since 1.0.0
*
* @param array $arr Target array.
* @return boolean $is_list Result.
*/
function is_list($arr) function is_list($arr)
{ {
if (!is_array($arr)) { if (!is_array($arr)) {
......
...@@ -6,23 +6,55 @@ use Exception; ...@@ -6,23 +6,55 @@ use Exception;
if (!class_exists('\WPCT_ABSTRACT\Singleton')) : if (!class_exists('\WPCT_ABSTRACT\Singleton')) :
/**
* Singleton abstract class.
*
* @since 1.0.0
*/
abstract class Singleton abstract class Singleton
{ {
/**
* Handle singleton instances map.
*
* @since 1.0.0
*/
private static $_instances = []; private static $_instances = [];
/**
* Class contructor.
*
* @since 1.0.0
*/
protected function __construct() protected function __construct()
{ {
} }
/**
* Prevent class clonning.
*
* @since 1.0.0
*/
protected function __clone() protected function __clone()
{ {
} }
/**
* Prevent class serialization.
*
* @since 1.0.0
*/
public function __wakeup() public function __wakeup()
{ {
throw new Exception('Cannot unserialize a singleton.'); throw new Exception('Cannot unserialize a singleton.');
} }
/**
* Get class instance.
*
* @since 1.0.0
*
* @return object $instance Class instance.
*/
public static function get_instance() public static function get_instance()
{ {
$args = func_get_args(); $args = func_get_args();
......