Files
old-experiments/backend/wordpress/wp-content/plugins/view-admin-as/includes/class-settings.php
2018-07-09 12:34:06 +02:00

927 lines
26 KiB
PHP

<?php
/**
* View Admin As - Class Settings
*
* @author Jory Hogeveen <info@keraweb.nl>
* @package View_Admin_As
*/
if ( ! defined( 'VIEW_ADMIN_AS_DIR' ) ) {
die();
}
/**
* Settings class that stores the VAA settings for use.
*
* @see VAA_View_Admin_As_Store
*
* @author Jory Hogeveen <info@keraweb.nl>
* @package View_Admin_As
* @since 1.7
* @version 1.8
* @uses \VAA_View_Admin_As_Base Extends class
*/
class VAA_View_Admin_As_Settings extends VAA_View_Admin_As_Base
{
/**
* The key to use for filters.
* Passed to __construct() as first parameter.
*
* @since 1.8
* @var string
*/
private $_filter_postfix = '';
/**
* Is this option for a network installation?
* Can only be set with set_for_network().
*
* @since 1.7.5
* @see \VAA_View_Admin_As_Settings::store_optionData()
* @var bool
*/
protected $for_network = false;
/**
* The user ID for whom this metadata is for.
* Can only be set with store_userMeta().
*
* @since 1.7.5
* @see \VAA_View_Admin_As_Settings::store_userMeta()
* @var int
*/
protected $for_user = null;
/**
* Database option key.
* Always starts with `vaa_`.
* Keys are parsed with underscores as spacing.
*
* @since 1.4
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @var string
*/
protected $optionKey = null;
/**
* Database option data.
*
* @since 1.4
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @var array
*/
protected $optionData = array();
/**
* User meta key for settings ans views.
* Always starts with `vaa-`.
* Keys are parsed with dashes as spacing.
*
* @since 1.3.4
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @var string
*/
protected $userMetaKey = null;
/**
* User meta value for settings ans views.
*
* @since 1.5
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @var array
*/
protected $userMeta = array();
/**
* User meta from all users.
*
* @since 1.8
* @var array
*/
protected $allUserMeta = array();
/**
* Array of default settings.
*
* @since 1.5
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @var array
*/
protected $defaultSettings = array();
/**
* Array of allowed settings.
*
* @since 1.5
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @var array
*/
protected $allowedSettings = array();
/**
* Array of default settings.
*
* @since 1.5
* @since 1.5.2 Added force_group_users.
* @since 1.6 Moved to this class from main class.
* @since 1.6.1 Added freeze_locale.
* @since 1.7 Moved to this class from store class.
* @var array
*/
protected $defaultUserSettings = array();
/**
* Array of allowed settings.
* Setting name (key) => array( values ).
*
* @since 1.5
* @since 1.5.2 Added force_group_users.
* @since 1.6 Moved to this class from main class.
* @since 1.6.1 Added freeze_locale.
* @since 1.7 Moved to this class from store class.
* @var array
*/
protected $allowedUserSettings = array();
/**
* Sets the default data.
*
* @since 1.7
* @access protected
* @param string $id Identifier for this settings instance.
* @param array $args {
* (optional) Setting arguments.
* @type array $default The default settings (option)
* @type array $allowed The allowed settings (option). Use arrays to define all possible values for a setting.
* @type array $default_user The default user settings (meta)
* @type array $allowed_user The allowed user settings (meta). Use arrays to define all possible values for a setting.
* }
*/
protected function __construct( $id, $args = array() ) {
parent::__construct();
if ( empty( $id ) || ! is_string( $id ) ) {
return null;
}
$args = wp_parse_args( $args, array(
'default' => array(),
'allowed' => array(),
'default_user' => array(),
'allowed_user' => array(),
) );
$default = $args['default'];
$allowed = $args['allowed'];
$default_user = $args['default_user'];
$allowed_user = $args['allowed_user'];
if ( 'VAA_View_Admin_As_Store' === get_class( $this ) ) {
$this->set_optionKey( 'vaa_view_admin_as' );
$this->set_optionData( array(
'db_version' => null,
'settings' => null,
) );
$this->set_userMetaKey( 'vaa-view-admin-as' );
$this->set_userMeta( array(
'settings' => null,
'views' => null,
) );
$default = array(
'view_types' => array(),
);
$allowed = array(
'view_types' => array(), // No restriction to values.
);
$default_user = array(
'admin_menu_location' => 'top-secondary',
'disable_super_admin' => true,
'force_group_users' => false,
'freeze_locale' => false,
'hide_customizer' => false,
'hide_front' => false,
'view_mode' => 'browse',
);
$allowed_user = array(
'admin_menu_location' => array( 'top-secondary', 'my-account' ),
'disable_super_admin' => array( true, false ),
'force_group_users' => array( true, false ),
'freeze_locale' => array( true, false ),
'hide_customizer' => array( true, false ),
'hide_front' => array( true, false ),
'view_mode' => array( 'browse', 'single' ),
);
// @todo Remove?
$this->add_filter( 'view_admin_as_validate_view_data_setting', array( $this, 'filter_validate_settings' ), 10, 3 );
$this->add_filter( 'view_admin_as_validate_view_data_user_setting', array( $this, 'filter_validate_settings' ), 10, 3 );
$this->add_filter( 'view_admin_as_handle_ajax_setting', array( $this, 'filter_update_settings' ), 10, 3 );
$this->add_filter( 'view_admin_as_handle_ajax_user_setting', array( $this, 'filter_update_settings' ), 10, 3 );
// Make identifier empty for the filters.
$id = '';
} else {
if ( 'view-admin-as' === sanitize_title_with_dashes( $id ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
// Translators: %1$s stands for an option key and %2$s stands for a class name.
__( 'The setting key %1$s is reserved for class %2$s', VIEW_ADMIN_AS_DOMAIN ),
$id, 'VAA_View_Admin_As_Store'
),
''
);
return;
}
$this->set_optionKey( 'vaa_' . $id );
$this->set_userMetaKey( 'vaa-' . $id );
// Append underscore to the identifier for the filters.
$id = '_' . $id;
} // End if().
$this->_filter_postfix = $id;
/**
* Set the default global settings.
*
* @since 1.7
* @param array
* @return array
*/
$this->set_defaultSettings( apply_filters( 'view_admin_as_default_global_settings' . $id, $default ) );
/**
* Set the allowed global settings.
*
* @since 1.7
* @param array {
* Settings array (key = setting name).
* @type array Array of allowed values.
* }
* @return array
*/
$this->set_allowedSettings( apply_filters( 'view_admin_as_allowed_global_settings' . $id, $allowed ) );
/**
* Set the default settings for users.
*
* @since 1.7
* @param array
* @return array
*/
$this->set_defaultUserSettings( apply_filters( 'view_admin_as_default_user_settings' . $id, $default_user ) );
/**
* Set the allowed settings for users.
*
* @since 1.7
* @param array {
* Settings array (key = setting name).
* @type array Array of allowed values.
* }
* @return array
*/
$this->set_allowedUserSettings( apply_filters( 'view_admin_as_allowed_user_settings' . $id, $allowed_user ) );
}
/**
* Validate hook for settings.
*
* @since 1.7
* @param null $null Default return (invalid).
* @param mixed $data The view data.
* @param string $key The data key.
* @return mixed
*/
public function filter_validate_settings( $null, $data, $key ) {
if ( ! empty( $data ) && ! empty( $key ) ) {
if ( 'setting' === $key ) {
return $this->validate_settings( $data, 'global', false );
}
if ( 'user_setting' === $key ) {
return $this->validate_settings( $data, 'user', false );
}
}
return $null;
}
/**
* Validate hook for settings.
*
* @since 1.7
* @since 1.7.3 Renamed from filter_store_settings().
* @param null $null Default return (invalid).
* @param mixed $data The view data.
* @param string $key The data key.
* @return mixed
*/
public function filter_update_settings( $null, $data, $key ) {
if ( ! empty( $data ) && ! empty( $key ) ) {
if ( 'setting' === $key ) {
return $this->update_settings( $data, 'global' );
}
if ( 'user_setting' === $key ) {
return $this->update_settings( $data, 'user' );
}
}
return $null;
}
/**
* Validate setting data based on allowed settings.
* Will also merge with the default settings unless third $merge parameter is false.
*
* @since 1.5
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class. Added third $merge parameter.
* @access public
*
* @param array $settings The new settings.
* @param string $type The type of settings (global / user).
* @param bool $merge Merge with defaults? (will return all settings).
* @return array|bool $settings / false
*/
public function validate_settings( $settings, $type, $merge = true ) {
if ( 'global' === $type ) {
$defaults = $this->get_defaultSettings();
$allowed = $this->get_allowedSettings();
} elseif ( 'user' === $type ) {
$defaults = $this->get_defaultUserSettings();
$allowed = $this->get_allowedUserSettings();
} else {
return false;
}
if ( $merge ) {
return $this->parse_settings( $settings, $defaults, $allowed );
}
foreach ( $settings as $setting => $value ) {
// Only pass the settings if the key and value matched the data in the allowed settings.
if ( ! array_key_exists( $setting, $allowed ) ) {
unset( $settings[ $setting ] );
}
// If setting key is allowed value is empty we don't need to validate.
if ( ! empty( $allowed[ $setting ] ) && ! in_array( $value, $allowed[ $setting ], true ) ) {
unset( $settings[ $setting ] );
}
}
return $settings;
}
/**
* Store settings based on allowed settings.
* Also merges with the default settings.
*
* @since 1.5
* @since 1.6 Moved to this class from main class.
* @since 1.7 Moved to this class from store class.
* @since 1.7.3 Renamed from store_settings().
* @access public
*
* @param array $settings The new settings.
* @param string $type The type of settings (global / user).
* @return bool
*/
public function update_settings( $settings, $type ) {
if ( 'global' === $type ) {
$current = $this->get_settings();
$defaults = $this->get_defaultSettings();
$allowed = $this->get_allowedSettings();
} elseif ( 'user' === $type ) {
$current = $this->get_userSettings();
$defaults = $this->get_defaultUserSettings();
$allowed = $this->get_allowedUserSettings();
} else {
return false;
}
if ( ! is_array( $current ) ) {
$current = $defaults;
}
$settings = apply_filters(
'view_admin_as_update_' . $type . '_settings' . $this->_filter_postfix,
$settings, $current, $defaults, $allowed
);
$settings = $this->validate_settings( $settings, $type, false );
foreach ( $settings as $setting => $value ) {
$current[ $setting ] = $value;
// Some settings need a reset.
if ( in_array( $setting, array( 'view_mode' ), true ) ) {
view_admin_as()->controller()->reset_view();
}
}
$new = $this->parse_settings( $current, $defaults, $allowed );
if ( 'global' === $type ) {
return $this->update_optionData( $new, 'settings', true );
} elseif ( 'user' === $type ) {
return $this->update_userMeta( $new, 'settings', true );
}
return false;
}
/**
* Parse the settings.
* Checks if the setting exists, removes it otherwise.
* Checks if the setting is allowed, otherwise sets it to the default value.
*
* @since 1.7
* @param array $settings The new settings.
* @param array $defaults The default settings.
* @param array $allowed The allowed settings.
* @return array
*/
public function parse_settings( $settings, $defaults, $allowed ) {
$settings = wp_parse_args( $settings, $defaults );
foreach ( $settings as $setting => $value ) {
if ( ! array_key_exists( $setting, $allowed ) ) {
// We don't have such a setting.
unset( $settings[ $setting ] );
} elseif ( ! empty( $allowed[ $setting ] ) && ! in_array( $value, $allowed[ $setting ], true ) ) {
// Set it to default if the allowed values are set and the value isn't allowed.
$settings[ $setting ] = $defaults[ $setting ];
}
}
return $settings;
}
/**
* Get the meta key results for all users.
*
* @since 1.8
* @global \wpdb $wpdb
* @return array {
* User ID's as array keys.
* @type array $meta_values The meta values. Column ID's as array keys.
* }
*/
public function get_all_user_meta() {
if ( ! empty( $this->allUserMeta ) ) {
return $this->allUserMeta;
}
global $wpdb;
$key = $this->get_userMetaKey();
// @todo Use WP_Meta_Query ?
$sql = 'SELECT * FROM ' . $wpdb->usermeta . ' WHERE meta_key = %s';
// @codingStandardsIgnoreLine >> $wpdb->prepare(), check returning false error.
$results = (array) $wpdb->get_results( $wpdb->prepare( $sql, $key ) );
$metas = array();
foreach ( $results as $key => $meta ) {
if ( ! isset( $metas[ $meta->user_id ] ) ) {
$metas[ $meta->user_id ] = array();
}
if ( ! empty( $meta->meta_value ) ) {
$metas[ $meta->user_id ][ $meta->umeta_id ] = maybe_unserialize( $meta->meta_value );
}
}
$this->allUserMeta = $metas;
return $metas;
}
/**
* Set the meta values for other users.
* Should be used together with get_all_user_meta() to get column id's.
*
* @since 1.8
* @see \VAA_View_Admin_As_Settings::get_all_user_meta()
* @param mixed $value
* @param int $user_id
* @param int $column_id
* @return bool
*/
public function update_other_user_meta( $value, $user_id, $column_id = null ) {
if ( ! $this->allUserMeta ) {
$this->get_all_user_meta();
}
// Validate settings.
$value = wp_parse_args( $value, array(
'settings' => array(),
) );
$value['settings'] = $this->validate_settings( $value['settings'], 'user', true );
if ( ! isset( $this->allUserMeta[ $user_id ] ) ) {
$column_id = 0;
$this->allUserMeta[ $user_id ] = array( $column_id => $value );
}
if ( ! is_int( $column_id ) ) {
reset( $this->allUserMeta[ $user_id ] );
$column_id = key( $this->allUserMeta[ $user_id ] );
}
$this->allUserMeta[ $user_id ][ $column_id ] = $value;
// @todo handle multiple columns.
return update_user_meta( $user_id, $this->get_userMetaKey(), $value );
}
/**
* Delete or reset all View Admin As metadata for this user.
*
* @since 1.5
* @since 1.6 Moved to this class from main class.
* @since 1.6.2 Option to remove the VAA metadata for all users.
* @since 1.7 Moved to this class from store class.
* @access public
*
* @param int|string $user_id ID of the user being deleted/removed (pass `all` for all users).
* @param \WP_User $user User object provided by the wp_login hook.
* @param bool $reset_only Only reset (not delete) the user meta.
* @return bool
*/
public function delete_user_meta( $user_id = null, $user = null, $reset_only = true ) {
/**
* Set the first parameter to `all` to remove the meta value for all users.
* @since 1.6.2
*/
if ( 'all' === $user_id ) {
return $this->delete_all_user_meta( $reset_only );
}
$id = false;
if ( is_numeric( $user_id ) ) {
// Delete hooks.
$id = (int) $user_id;
} elseif ( isset( $user->ID ) ) {
// Login/Logout hooks.
$id = (int) $user->ID;
}
if ( $id ) {
$success = true;
if ( $reset_only ) {
// Reset db metadata (returns: true on success, false on failure).
if ( get_user_meta( $id, $this->get_userMetaKey() ) ) {
$success = update_user_meta( $id, $this->get_userMetaKey(), false );
}
} else {
// Remove db metadata (returns: true on success, false on failure).
$success = delete_user_meta( $id, $this->get_userMetaKey() );
}
// Update current metadata if it is the current user.
if ( $success && (int) get_current_user_id() === $id ) {
$this->set_userMeta( false );
}
return $success;
}
// No user or metadata found, no deletion needed.
return true;
}
/**
* Delete or reset all View Admin As metadata for all users.
*
* @since 1.7
* @access public
*
* @see https://developer.wordpress.org/reference/classes/wpdb/update/
* @see https://developer.wordpress.org/reference/classes/wpdb/delete/
*
* @global \wpdb $wpdb
* @param bool $reset_only Only reset (not delete) the user meta.
* @return bool
*/
public function delete_all_user_meta( $reset_only = true ) {
global $wpdb;
if ( $reset_only ) {
// Reset.
return (bool) $wpdb->update(
$wpdb->usermeta, // table.
array( 'meta_value' => '' ), // data.
array( 'meta_key' => $this->get_userMetaKey() ) // where.
);
} else {
// Delete.
return (bool) $wpdb->delete(
$wpdb->usermeta, // table.
array( 'meta_key' => $this->get_userMetaKey() ) // where.
);
}
}
/**
* Get the option key as used in the options table.
* @return string
*/
public function get_optionKey() {
return (string) $this->optionKey;
}
/**
* Get the user meta key as used in the usermeta table.
* @return string
*/
public function get_userMetaKey() {
return (string) $this->userMetaKey;
}
/**
* Get the option data as used in the options table.
* @param string $key Key in the option array.
* @return mixed
*/
public function get_optionData( $key = null ) {
return VAA_API::get_array_data( $this->optionData, $key );
}
/**
* Get the user metadata as used in the usermeta table.
* @param string $key Key in the meta array.
* @return mixed
*/
public function get_userMeta( $key = null ) {
return VAA_API::get_array_data( $this->userMeta, $key );
}
/**
* Get the default settings.
* @param string $key Setting key.
* @return mixed
*/
public function get_defaultSettings( $key = null ) {
return VAA_API::get_array_data( $this->defaultSettings, $key );
}
/**
* Get the default user settings.
* @param string $key Setting key.
* @return mixed
*/
public function get_defaultUserSettings( $key = null ) {
return VAA_API::get_array_data( $this->defaultUserSettings, $key );
}
/**
* Get the allowed settings.
* @param string $key Setting key.
* @return array
*/
public function get_allowedSettings( $key = null ) {
return (array) VAA_API::get_array_data( $this->allowedSettings, $key );
}
/**
* Get the allowed user settings.
* @param string $key Setting key.
* @return array
*/
public function get_allowedUserSettings( $key = null ) {
return (array) VAA_API::get_array_data( $this->allowedUserSettings, $key );
}
/**
* Get the settings.
* @param string $key Setting key.
* @return mixed
*/
public function get_settings( $key = null ) {
return VAA_API::get_array_data(
$this->validate_settings(
$this->get_optionData( 'settings' ),
'global'
),
$key
);
}
/**
* Get the user settings.
* @param string $key Setting key.
* @return mixed
*/
public function get_userSettings( $key = null ) {
return VAA_API::get_array_data(
$this->validate_settings(
$this->get_userMeta( 'settings' ),
'user'
),
$key
);
}
/**
* Set the option key as used in the options table.
* @param string $val Option key.
* @return void
*/
protected function set_optionKey( $val ) {
$this->optionKey = (string) str_replace( array( ' ', '-' ), '_', sanitize_title_with_dashes( $val ) );
}
/**
* Set the option key as used in the options table.
* @param string $val Option key.
* @return void
*/
protected function set_userMetaKey( $val ) {
$this->userMetaKey = (string) sanitize_title_with_dashes( $val );
}
/**
* Set the default settings.
* @param array $val Settings.
* @param string $key (optional) Setting key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
protected function set_defaultSettings( $val, $key = null, $append = false ) {
$this->defaultSettings = VAA_API::set_array_data( $this->defaultSettings, $val, $key, $append );
}
/**
* Set the default user settings.
* @param array $val Settings.
* @param string $key (optional) Setting key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
protected function set_defaultUserSettings( $val, $key = null, $append = false ) {
$this->defaultUserSettings = VAA_API::set_array_data( $this->defaultUserSettings, $val, $key, $append );
}
/**
* Set the allowed settings.
* @param mixed $val Settings.
* @param string $key (optional) Setting key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
protected function set_allowedSettings( $val, $key = null, $append = false ) {
$this->allowedSettings = VAA_API::set_array_data( $this->allowedSettings, $val, $key, $append );
}
/**
* Set the allowed user settings.
* @param mixed $val Settings.
* @param string $key (optional) Setting key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
protected function set_allowedUserSettings( $val, $key = null, $append = false ) {
$this->allowedUserSettings = VAA_API::set_array_data( $this->allowedUserSettings, $val, $key, $append );
}
/**
* Set the settings.
* @param mixed $val Settings.
* @param string $key (optional) Setting key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
public function set_settings( $val, $key = null, $append = false ) {
$this->set_optionData(
$this->validate_settings(
VAA_API::set_array_data( $this->get_settings(), $val, $key, $append ),
'global'
),
'settings',
true
);
}
/**
* Set the user settings.
* @param mixed $val Settings.
* @param string $key (optional) Setting key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
public function set_userSettings( $val, $key = null, $append = false ) {
$this->set_userMeta(
$this->validate_settings(
VAA_API::set_array_data( $this->get_userSettings(), $val, $key, $append ),
'user'
),
'settings',
true
);
}
/**
* Set the plugin option data.
* @param mixed $val Data.
* @param string $key (optional) Data key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
public function set_optionData( $val, $key = null, $append = false ) {
$this->optionData = VAA_API::set_array_data( $this->optionData, $val, $key, $append );
}
/**
* Set the user metadata.
* @param mixed $val Data.
* @param string $key (optional) Data key.
* @param bool $append (optional) Append if it doesn't exist?
* @return void
*/
public function set_userMeta( $val, $key = null, $append = false ) {
$this->userMeta = VAA_API::set_array_data( $this->userMeta, $val, $key, $append );
}
/**
* Store the option data.
* @param bool $network Is network option?
* @since 1.7.x
*/
protected function store_optionData( $network = false ) {
$this->set_for_network( $network );
if ( $this->is_for_network() ) {
$this->set_optionData( get_site_option( $this->get_optionKey() ) );
} else {
$this->set_optionData( get_option( $this->get_optionKey() ) );
}
}
/**
* Store the user meta.
* @since 1.7.x
* @param int $user_id The user ID this metadata is for.
* @param bool $single NOT SUPPORTED YET!
*/
protected function store_userMeta( $user_id, $single = true ) {
if ( ! is_int( $user_id ) ) {
return;
}
$this->for_user = $user_id;
$this->set_userMeta( get_user_meta( $this->for_user, $this->get_userMetaKey(), true ) );
}
/**
* Update the plugin option data.
* @param mixed $val Data.
* @param string $key (optional) Data key.
* @param bool $append (optional) Append if it doesn't exist?
* @return bool
*/
public function update_optionData( $val, $key = null, $append = false ) {
$this->set_optionData( $val, $key, $append );
if ( $this->is_for_network() ) {
return update_site_option( $this->get_optionKey(), $this->get_optionData() );
}
return update_option( $this->get_optionKey(), $this->get_optionData() );
}
/**
* Update the user metadata.
* @param mixed $val Data.
* @param string $key (optional) Data key.
* @param bool $append (optional) Append if it doesn't exist?
* @return bool
*/
public function update_userMeta( $val, $key = null, $append = false ) {
$this->set_userMeta( $val, $key, $append );
return update_user_meta( $this->for_user, $this->get_userMetaKey(), $this->get_userMeta() );
}
/**
* Set whether this instance if for a network option.
* @since 1.7.x
* @param bool $bool
*/
protected function set_for_network( $bool ) {
$this->for_network = (bool) $bool;
}
/**
* Set whether this instance if for a network option.
* @since 1.7.x
* @return bool
*/
public function is_for_network() {
return (bool) $this->for_network;
}
} // End class VAA_View_Admin_As_Settings.