first commit
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Framework Admin Notice Class
|
||||
* Makes instantiating a Redux object an absolute piece of cake.
|
||||
*
|
||||
* @package Redux_Framework
|
||||
* @author Kevin Provance & Dovy Paukstys
|
||||
* @subpackage Core
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Admin_Notices', false ) ) {
|
||||
|
||||
/**
|
||||
* Redux Admin Notices Class
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class Redux_Admin_Notices extends Redux_Class {
|
||||
|
||||
/**
|
||||
* WordPress admin notice array.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private static $notices = array();
|
||||
|
||||
/**
|
||||
* Redux_Admin_Notices constructor.
|
||||
*
|
||||
* @param array $parent ReduxFramework object.
|
||||
* @access public
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
add_action( 'wp_ajax_redux_hide_admin_notice', array( $this, 'ajax' ) );
|
||||
add_action( 'admin_notices', array( $this, 'notices' ), 99 );
|
||||
add_action( 'admin_init', array( $this, 'dismiss' ), 9 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display nices stored in notices array.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function notices() {
|
||||
$this->admin_notices( self::$notices );
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses admin notice
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function dismiss() {
|
||||
$this->dismiss_admin_notice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an admin notice for display.
|
||||
*
|
||||
* @param array $data Notice data.
|
||||
*/
|
||||
public static function set_notice( $data ) {
|
||||
$type = null;
|
||||
$msg = null;
|
||||
$id = null;
|
||||
$dismiss = null;
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DontExtract
|
||||
extract( $data );
|
||||
|
||||
self::$notices[ $parent->args['page_slug'] ][] = array(
|
||||
'type' => $type,
|
||||
'msg' => $msg,
|
||||
'id' => $id . '_' . $parent->args['opt_name'],
|
||||
'dismiss' => $dismiss,
|
||||
'color' => isset( $color ) ? $color : '#00A2E3',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates user dismiss option for displaying admin notices.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $notices Array of stored notices to display.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_notices( $notices = array() ) {
|
||||
global $current_user, $pagenow;
|
||||
|
||||
$core = $this->core();
|
||||
if ( isset( $_GET ) && isset( $_GET['page'] ) && $core->args['page_slug'] === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
do_action( 'redux_admin_notices_run', $core->args );
|
||||
|
||||
// Check for an active admin notice array.
|
||||
if ( ! empty( $notices ) ) {
|
||||
if ( isset( $notices[ $core->args['page_slug'] ] ) ) {
|
||||
// Enum admin notices.
|
||||
foreach ( $notices[ $core->args['page_slug'] ] as $notice ) {
|
||||
|
||||
$add_style = '';
|
||||
if ( strpos( $notice['type'], 'redux-message' ) !== false ) {
|
||||
$add_style = 'style="border-left: 4px solid ' . esc_attr( $notice['color'] ) . '!important;"';
|
||||
}
|
||||
|
||||
if ( true === $notice['dismiss'] ) {
|
||||
|
||||
// Get user ID.
|
||||
$userid = $current_user->ID;
|
||||
|
||||
if ( ! get_user_meta( $userid, 'ignore_' . $notice['id'] ) ) {
|
||||
global $wp_version;
|
||||
|
||||
// Print the notice with the dismiss link.
|
||||
if ( version_compare( $wp_version, '4.2', '>' ) ) {
|
||||
$css_id = esc_attr( $notice['id'] );
|
||||
$css_class = esc_attr( $notice['type'] ) . ' redux-notice notice is-dismissible redux-notice';
|
||||
|
||||
$nonce = wp_create_nonce( $notice['id'] . $userid . 'nonce' );
|
||||
|
||||
echo '<div ' . $add_style . ' id="' . esc_attr( $css_id ) . '" class="' . esc_attr( $css_class ) . '">'; // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
echo '<input type="hidden" class="dismiss_data" id="' . esc_attr( $css_id ) . '" value="' . esc_attr( $nonce ) . '">';
|
||||
echo '<p>' . wp_kses_post( $notice['msg'] ) . '</p>';
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo '<div ' . esc_html( $add_style ) . ' class="' . esc_attr( $notice['type'] ) . ' notice is-dismissable"><p>' . wp_kses_post( $notice['msg'] ) . ' <a href="?dismiss=true&id=' . esc_attr( $css_id ) . '">' . esc_html__( 'Dismiss', 'redux-framework' ) . '</a>.</p></div>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Standard notice.
|
||||
echo '<div ' . esc_html( $add_style ) . ' class="' . esc_attr( $notice['type'] ) . ' notice"><p>' . wp_kses_post( $notice['msg'] ) . '</a>.</p></div>';
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
$( document.body ).on(
|
||||
'click', '.redux-notice.is-dismissible .notice-dismiss', function( e ) {
|
||||
e.preventDefault();
|
||||
var $data = $( this ).parent().find( '.dismiss_data' );
|
||||
$.post(
|
||||
ajaxurl, {
|
||||
action: 'redux_hide_admin_notice',
|
||||
id: $data.attr( 'id' ),
|
||||
nonce: $data.val()
|
||||
}
|
||||
);
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clear the admin notice array.
|
||||
self::$notices[ $core->args['opt_name'] ] = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates user meta to store dismiss notice preference.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function dismiss_admin_notice() {
|
||||
global $current_user;
|
||||
|
||||
// Verify the dismiss and id parameters are present.
|
||||
if ( isset( $_GET['dismiss'] ) && isset( $_GET['id'] ) ) {
|
||||
if ( isset( $_GET['nonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_GET['nonce'] ) ), 'redux_hint_toggle' ) ) {
|
||||
if ( 'true' === $_GET['dismiss'] || 'false' === $_GET['dismiss'] ) {
|
||||
|
||||
// Get the user id.
|
||||
$userid = $current_user->ID;
|
||||
|
||||
// Get the notice id.
|
||||
$id = sanitize_text_field( wp_unslash( $_GET['id'] ) );
|
||||
$val = sanitize_text_field( wp_unslash( $_GET['dismiss'] ) );
|
||||
|
||||
// Add the dismiss request to the user meta.
|
||||
update_user_meta( $userid, 'ignore_' . $id, $val );
|
||||
}
|
||||
} else {
|
||||
wp_nonce_ays( 'redux_hint_toggle' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates user meta to store dismiss notice preference
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajax() {
|
||||
global $current_user;
|
||||
|
||||
if ( isset( $_POST['id'] ) ) {
|
||||
// Get the notice id.
|
||||
$id = explode( '&', sanitize_text_field( wp_unslash( $_POST['id'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$id = $id[0];
|
||||
|
||||
// Get the user id.
|
||||
$userid = $current_user->ID;
|
||||
|
||||
if ( ! isset( $_POST['nonce'] ) || ( isset( $_POST['nonce'] ) && ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), $id . $userid . 'nonce' ) ) ) {
|
||||
die( 0 );
|
||||
} else {
|
||||
// Add the dismiss request to the user meta.
|
||||
update_user_meta( $userid, 'ignore_' . $id, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux AJAX Save Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_AJAX_Save', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_AJAX_Save
|
||||
*/
|
||||
class Redux_AJAX_Save extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_AJAX_Save constructor.
|
||||
* array_merge_recursive_distinct
|
||||
*
|
||||
* @param object $parent ReduxFrameword object.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
add_action( 'wp_ajax_' . $this->args['opt_name'] . '_ajax_save', array( $this, 'save' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback to save the option panel values.
|
||||
*/
|
||||
public function save() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( ! isset( $_REQUEST['nonce'] ) || ( isset( $_REQUEST['nonce'] ) && ! wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['nonce'] ) ), 'redux_ajax_nonce' . $this->args['opt_name'] ) ) ) {
|
||||
echo wp_json_encode(
|
||||
array(
|
||||
'status' => esc_html__( 'Invalid security credential. Please reload the page and try again.', 'redux-framework' ),
|
||||
'action' => '',
|
||||
)
|
||||
);
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! Redux_Helpers::current_user_can( $core->args['page_permissions'] ) ) {
|
||||
echo wp_json_encode(
|
||||
array(
|
||||
'status' => esc_html__( 'Invalid user capability. Please reload the page and try again.', 'redux-framework' ),
|
||||
'action' => '',
|
||||
)
|
||||
);
|
||||
die();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['opt_name'] ) && ! empty( $_POST['opt_name'] ) && isset( $_POST['data'] ) && ! empty( $_POST['data'] ) ) {
|
||||
$redux = Redux::instance( sanitize_text_field( wp_unslash( $_POST['opt_name'] ) ) );
|
||||
|
||||
if ( ! empty( $redux->args['opt_name'] ) ) {
|
||||
|
||||
$post_data = wp_unslash( $_POST['data'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||
|
||||
// New method to avoid input_var nonsense. Thanks @harunbasic.
|
||||
$values = Redux_Functions_Ex::parse_str( $post_data );
|
||||
$values = $values[ $redux->args['opt_name'] ];
|
||||
|
||||
if ( ! empty( $values ) ) {
|
||||
try {
|
||||
if ( isset( $redux->validation_ran ) ) {
|
||||
unset( $redux->validation_ran );
|
||||
}
|
||||
|
||||
$redux->options_class->set( $redux->options_class->validate_options( $values ) );
|
||||
|
||||
$do_reload = false;
|
||||
if ( isset( $core->required_class->reload_fields ) && ! empty( $core->required_class->reload_fields ) ) {
|
||||
if ( ! empty( $core->transients['changed_values'] ) ) {
|
||||
foreach ( $core->required_class->reload_fields as $idx => $val ) {
|
||||
if ( array_key_exists( $val, $core->transients['changed_values'] ) ) {
|
||||
$do_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $do_reload || ( isset( $values['defaults'] ) && ! empty( $values['defaults'] ) ) || ( isset( $values['defaults-section'] ) && ! empty( $values['defaults-section'] ) ) || ( isset( $values['import_code'] ) && ! empty( $values['import_code'] ) ) || ( isset( $values['import_link'] ) && ! empty( $values['import_link'] ) ) ) {
|
||||
echo wp_json_encode(
|
||||
array(
|
||||
'status' => 'success',
|
||||
'action' => 'reload',
|
||||
)
|
||||
);
|
||||
die();
|
||||
}
|
||||
|
||||
$redux->enqueue_class->get_warnings_and_errors_array();
|
||||
|
||||
$return_array = array(
|
||||
'status' => 'success',
|
||||
'options' => $redux->options,
|
||||
'errors' => isset( $redux->enqueue_class->localize_data['errors'] ) ? $redux->enqueue_class->localize_data['errors'] : null,
|
||||
'warnings' => isset( $redux->enqueue_class->localize_data['warnings'] ) ? $redux->enqueue_class->localize_data['warnings'] : null,
|
||||
'sanitize' => isset( $redux->enqueue_class->localize_data['sanitize'] ) ? $redux->enqueue_class->localize_data['sanitize'] : null,
|
||||
);
|
||||
} catch ( Exception $e ) {
|
||||
$return_array = array( 'status' => $e->getMessage() );
|
||||
}
|
||||
} else {
|
||||
echo wp_json_encode(
|
||||
array(
|
||||
'status' => esc_html__( 'Your panel has no fields. Nothing to save.', 'redux-framework' ),
|
||||
)
|
||||
);
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $core->transients['run_compiler'] ) && $core->transients['run_compiler'] ) {
|
||||
$core->no_output = true;
|
||||
$temp = $core->args['output_variables_prefix'];
|
||||
// Allow the override of variables prefix for use by SCSS or LESS.
|
||||
if ( isset( $core->args['compiler_output_variables_prefix'] ) ) {
|
||||
$core->args['output_variables_prefix'] = $core->args['compiler_output_variables_prefix'];
|
||||
}
|
||||
$core->output_class->enqueue();
|
||||
$core->args['output_variables_prefix'] = $temp;
|
||||
|
||||
try {
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
$compiler_css = $core->compilerCSS; // Backward compatibility variable.
|
||||
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/compiler'
|
||||
*
|
||||
* @param array options
|
||||
* @param string CSS that get sent to the compiler hook
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/options/' . $core->args['opt_name'] . '/compiler', $core->options, $compiler_css, $core->transients['changed_values'], $core->output_variables );
|
||||
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/compiler/advanced'
|
||||
*
|
||||
* @param array options
|
||||
* @param string CSS that get sent to the compiler hook, which sends the full Redux object
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/options/' . $core->args['opt_name'] . '/compiler/advanced', $core );
|
||||
} catch ( Exception $e ) {
|
||||
$return_array = array( 'status' => $e->getMessage() );
|
||||
}
|
||||
|
||||
unset( $core->transients['run_compiler'] );
|
||||
$core->transient_class->set();
|
||||
}
|
||||
|
||||
if ( isset( $return_array ) ) {
|
||||
if ( 'success' === $return_array['status'] ) {
|
||||
$panel = new Redux_Panel( $redux );
|
||||
ob_start();
|
||||
$panel->notification_bar();
|
||||
$notification_bar = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$return_array['notification_bar'] = $notification_bar;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo wp_json_encode( apply_filters( 'redux/options/' . $core->args['opt_name'] . '/ajax_save/response', $return_array ) );
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Select2 AJAX Class
|
||||
*
|
||||
* @class Redux_AJAX_Select2
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_AJAX_Select2', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_AJAX_Select2
|
||||
*/
|
||||
class Redux_AJAX_Select2 extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_AJAX_Select2 constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework object pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
add_action( "wp_ajax_redux_{$parent->args['opt_name']}_select2", array( $this, 'ajax' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback for select2 match search.
|
||||
*/
|
||||
public function ajax() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( isset( $_REQUEST['nonce'] ) && isset( $_REQUEST['action'] ) ) {
|
||||
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ), sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) ) ) {
|
||||
wp_send_json_error( esc_html__( 'Invalid security credential. Please reload the page and try again.', 'redux-framework' ) );
|
||||
}
|
||||
|
||||
if ( ! Redux_Helpers::current_user_can( $this->parent->args['page_permissions'] ) ) {
|
||||
wp_send_json_error( esc_html__( 'Invalid user capability. Please reload the page and try again.', 'redux-framework' ) );
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['data'] ) ) {
|
||||
|
||||
$args = isset( $_REQUEST['data_args'] ) ? json_decode( sanitize_text_field( wp_unslash( $_REQUEST['data_args'] ) ), true ) : array();
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
's' => isset( $_REQUEST['q'] ) && ! empty( $_REQUEST['q'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['q'] ) ) : '',
|
||||
)
|
||||
);
|
||||
|
||||
$criteria = '';
|
||||
if ( isset( $_REQUEST['q'] ) && ! empty( $_REQUEST['q'] ) ) {
|
||||
$criteria = sanitize_text_field( wp_unslash( $_REQUEST['q'] ) );
|
||||
$args['s'] = $criteria;
|
||||
}
|
||||
|
||||
$return = $core->wordpress_data->get( sanitize_text_field( wp_unslash( $_REQUEST['data'] ) ), $args );
|
||||
|
||||
if ( is_array( $return ) && ! empty( $_REQUEST['action'] ) ) {
|
||||
if ( ! empty( $args['s'] ) ) {
|
||||
$keys = array_keys( $return );
|
||||
$values = array_values( $return );
|
||||
|
||||
$to_json = array();
|
||||
|
||||
// Search all the values.
|
||||
$search_values = preg_grep( '~' . $args['s'] . '~i', $values );
|
||||
if ( ! empty( $search_values ) ) {
|
||||
foreach ( $search_values as $id => $val ) {
|
||||
$to_json[ $keys[ $id ] ] = array(
|
||||
'id' => $keys[ $id ],
|
||||
'text' => $val,
|
||||
);
|
||||
}
|
||||
}
|
||||
// Search all the keys.
|
||||
$search_keys = preg_grep( '~' . $args['s'] . '~i', $keys );
|
||||
if ( ! empty( $search_keys ) ) {
|
||||
foreach ( $search_keys as $id => $val ) {
|
||||
$to_json[ $val ] = array(
|
||||
'id' => $val,
|
||||
'text' => $values[ $id ],
|
||||
);
|
||||
}
|
||||
}
|
||||
wp_send_json_success( array_values( $to_json ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Typography AJAX Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_AJAX_Typography', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_AJAX_Typography
|
||||
*/
|
||||
class Redux_AJAX_Typography extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_AJAX_Typography constructor.
|
||||
*
|
||||
* @param object $parent RedusFramework object.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
add_action( 'wp_ajax_redux_update_google_fonts', array( $this, 'google_fonts_update' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Google font AJAX callback
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function google_fonts_update() {
|
||||
$field_class = 'Redux_typography';
|
||||
|
||||
if ( ! class_exists( $field_class ) ) {
|
||||
$dir = str_replace( '/classes', '', Redux_Functions_Ex::wp_normalize_path( dirname( __FILE__ ) ) );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$class_file = apply_filters( 'redux-typeclass-load', $dir . '/fields/typography/class-redux-typography.php', $field_class );
|
||||
if ( $class_file ) {
|
||||
require_once $class_file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $field_class ) && method_exists( $field_class, 'google_fonts_update_ajax' ) ) {
|
||||
$f = new $field_class( array(), '', $this->parent );
|
||||
|
||||
return $f->google_fonts_update_ajax();
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,423 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Framework Args Class
|
||||
*
|
||||
* @package Redux_Framework/Classes
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Args', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Args
|
||||
*/
|
||||
class Redux_Args {
|
||||
|
||||
/**
|
||||
* Returns entire arguments array.
|
||||
*
|
||||
* @var array|mixed
|
||||
*/
|
||||
public $get = array();
|
||||
|
||||
/**
|
||||
* ReduxFramework object.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $parent = null;
|
||||
|
||||
/**
|
||||
* Switch to omit social icons if dev_mode is set to true and Redux defaults are used.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $omit_icons = false;
|
||||
|
||||
/**
|
||||
* Switch to omit support menu items if dev_mode is set to true and redux defaults are used.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $omit_items = false;
|
||||
|
||||
/**
|
||||
* Flag to force dev_mod to true if in localhost or WP_DEBUG is set to true.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $dev_mode_forced = false;
|
||||
|
||||
/**
|
||||
* Redux_Args constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework object.
|
||||
* @param array $args Global arguments array.
|
||||
*/
|
||||
public function __construct( $parent, $args ) {
|
||||
$this->parent = $parent;
|
||||
|
||||
$default = array(
|
||||
'opt_name' => '',
|
||||
'last_tab' => '',
|
||||
'menu_icon' => '',
|
||||
'menu_title' => '',
|
||||
'page_title' => '',
|
||||
'page_slug' => '',
|
||||
'page_permissions' => 'manage_options',
|
||||
'menu_type' => 'menu',
|
||||
'page_parent' => 'themes.php',
|
||||
'page_priority' => null,
|
||||
'allow_sub_menu' => true,
|
||||
'save_defaults' => true,
|
||||
'footer_credit' => '',
|
||||
'async_typography' => false,
|
||||
'disable_google_fonts_link' => false,
|
||||
'class' => '',
|
||||
'admin_bar' => true,
|
||||
'admin_bar_priority' => 999,
|
||||
'admin_bar_icon' => '',
|
||||
'help_tabs' => array(),
|
||||
'help_sidebar' => '',
|
||||
'database' => '',
|
||||
'customizer' => false,
|
||||
'global_variable' => '',
|
||||
'output' => true,
|
||||
'output_variables_prefix' => '--',
|
||||
'compiler_output_variables_prefix' => '$',
|
||||
'compiler' => true,
|
||||
'output_tag' => true,
|
||||
'output_location' => array( 'frontend' ),
|
||||
'transient_time' => '',
|
||||
'default_show' => false,
|
||||
'default_mark' => '',
|
||||
'disable_save_warn' => false,
|
||||
'open_expanded' => false,
|
||||
'hide_expand' => false,
|
||||
'network_admin' => false,
|
||||
'network_sites' => true,
|
||||
'hide_reset' => false,
|
||||
'hide_save' => false,
|
||||
'hints' => array(
|
||||
'icon' => 'el el-question-sign',
|
||||
'icon_position' => 'right',
|
||||
'icon_color' => 'lightgray',
|
||||
'icon_size' => 'normal',
|
||||
'tip_style' => array(
|
||||
'color' => 'light',
|
||||
'shadow' => true,
|
||||
'rounded' => false,
|
||||
'style' => '',
|
||||
),
|
||||
'tip_position' => array(
|
||||
'my' => 'top_left',
|
||||
'at' => 'bottom_right',
|
||||
),
|
||||
'tip_effect' => array(
|
||||
'show' => array(
|
||||
'effect' => 'slide',
|
||||
'duration' => '500',
|
||||
'event' => 'mouseover',
|
||||
),
|
||||
'hide' => array(
|
||||
'effect' => 'fade',
|
||||
'duration' => '500',
|
||||
'event' => 'click mouseleave',
|
||||
),
|
||||
),
|
||||
),
|
||||
'font_weights' => array(
|
||||
array(
|
||||
'id' => '400',
|
||||
'name' => __( 'Regular 400', 'redux-framework' ),
|
||||
),
|
||||
array(
|
||||
'id' => '400italic',
|
||||
'name' => __( 'Regular 400 Italic', 'redux-framework' ),
|
||||
),
|
||||
array(
|
||||
'id' => '700',
|
||||
'name' => __( 'Bold 700', 'redux-framework' ),
|
||||
),
|
||||
array(
|
||||
'id' => '700italic',
|
||||
'name' => __( 'Bold 700 Italic', 'redux-framework' ),
|
||||
),
|
||||
),
|
||||
'show_import_export' => true,
|
||||
'show_options_object' => true,
|
||||
'dev_mode' => true,
|
||||
'templates_path' => '',
|
||||
'ajax_save' => true,
|
||||
'use_cdn' => true,
|
||||
'cdn_check_time' => 1440,
|
||||
'options_api' => true,
|
||||
'allow_tracking' => true,
|
||||
'admin_theme' => 'wp',
|
||||
'elusive_frontend' => false,
|
||||
'pro' => array(),
|
||||
'font_display' => 'swap', // block|swap|fallback|optional.
|
||||
);
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$default = apply_filters( 'redux/pro/args/defaults', $default );
|
||||
|
||||
$args = Redux_Functions::parse_args( $args, $default );
|
||||
|
||||
$args = $this->args( $args );
|
||||
$args = $this->default_cleanup( $args );
|
||||
|
||||
if ( ! in_array( $args['font_display'], array( 'block', 'swap', 'fallback', 'optional' ), true ) ) {
|
||||
$args['font_display'] = 'swap';
|
||||
}
|
||||
if ( $args['async_typography'] ) { // TODO: Disable this for now. We'll rip it out completely shortly.
|
||||
$args['async_typography'] = false;
|
||||
}
|
||||
|
||||
$this->get = $args;
|
||||
|
||||
$this->parent->args = $args;
|
||||
|
||||
if ( 'redux_extensions_demo' !== $args['opt_name'] && 'redux_demo' !== $args['opt_name'] ) {
|
||||
$this->change_demo_defaults( $args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sanitizes global args array.
|
||||
*
|
||||
* @param array $args Global args.
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
private function args( $args ) {
|
||||
$args = $this->no_errors_please( $args );
|
||||
|
||||
$this->parent->old_opt_name = $args['opt_name'];
|
||||
|
||||
$args = $this->filters( $args );
|
||||
|
||||
if ( ! function_exists( 'wp_rand' ) ) {
|
||||
require_once ABSPATH . '/wp-includes/pluggable.php';
|
||||
}
|
||||
|
||||
$this->parent->core_instance = chr( 64 + wp_rand( 1, 26 ) ) . time() . '_' . wp_rand( 0, 1000000 );
|
||||
$this->parent->core_thread = chr( 64 + wp_rand( 1, 26 ) ) . time() . '_' . wp_rand( 0, 1000000 );
|
||||
|
||||
if ( $args['opt_name'] === $this->parent->old_opt_name ) {
|
||||
$this->parent->old_opt_name = null;
|
||||
unset( $this->parent->old_opt_name );
|
||||
}
|
||||
|
||||
// Do not save the defaults if we're on a live preview!
|
||||
if ( 'customize' === $GLOBALS['pagenow'] && isset( $_GET['customize_theme'] ) && ! empty( $_GET['customize_theme'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$args['save_defaults'] = false;
|
||||
}
|
||||
|
||||
$args = $this->shim( $args );
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filters to arg data.
|
||||
*
|
||||
* @param array $args Global args.
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
private function filters( $args ) {
|
||||
/**
|
||||
* Filter 'redux/args/{opt_name}'
|
||||
*
|
||||
* @param array $args ReduxFramework configuration
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$args = apply_filters( "redux/args/{$args['opt_name']}", $args );
|
||||
|
||||
/**
|
||||
* Filter 'redux/options/{opt_name}/args'
|
||||
*
|
||||
* @param array $args ReduxFramework configuration
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$args = apply_filters( "redux/options/{$args['opt_name']}/args", $args );
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize args that should not be empty.
|
||||
*
|
||||
* @param array $args Global args.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function no_errors_please( $args ) {
|
||||
if ( empty( $args['transient_time'] ) ) {
|
||||
$args['transient_time'] = 60 * MINUTE_IN_SECONDS;
|
||||
}
|
||||
|
||||
if ( empty( $args['footer_credit'] ) ) {
|
||||
|
||||
$footer_text = sprintf(
|
||||
/* translators: 1: Redux, 2: Link to plugin review */
|
||||
__( 'Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!', 'redux-framework' ),
|
||||
'<strong>' . __( 'Redux', 'redux-framework' ) . '</strong>',
|
||||
'<a href="https://wordpress.org/support/plugin/redux-framework/reviews/?filter=5/#new-post" target="_blank">★★★★★</a>'
|
||||
);
|
||||
$args['footer_credit'] = '<span id="footer-thankyou">' . $footer_text . '</span>';
|
||||
}
|
||||
|
||||
if ( empty( $args['menu_title'] ) ) {
|
||||
$args['menu_title'] = esc_html__( 'Options', 'redux-framework' );
|
||||
}
|
||||
|
||||
if ( empty( $args['page_title'] ) ) {
|
||||
$args['page_title'] = esc_html__( 'Options', 'redux-framework' );
|
||||
}
|
||||
|
||||
// Auto create the page_slug appropriately.
|
||||
if ( empty( $args['page_slug'] ) ) {
|
||||
if ( ! empty( $args['display_name'] ) ) {
|
||||
$args['page_slug'] = sanitize_html_class( $args['display_name'] );
|
||||
} elseif ( ! empty( $args['page_title'] ) ) {
|
||||
$args['page_slug'] = sanitize_html_class( $args['page_title'] );
|
||||
} elseif ( ! empty( $args['menu_title'] ) ) {
|
||||
$args['page_slug'] = sanitize_html_class( $args['menu_title'] );
|
||||
} else {
|
||||
$args['page_slug'] = str_replace( '-', '_', $args['opt_name'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shims for much older v3 configs.
|
||||
*
|
||||
* @param array $args Global args.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function shim( $args ) {
|
||||
/**
|
||||
* SHIM SECTION
|
||||
* Old variables and ways of doing things that need correcting. ;)
|
||||
* */
|
||||
// Variable name change.
|
||||
if ( ! empty( $args['page_cap'] ) ) {
|
||||
$args['page_permissions'] = $args['page_cap'];
|
||||
unset( $args['page_cap'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['page_position'] ) ) {
|
||||
$args['page_priority'] = $args['page_position'];
|
||||
unset( $args['page_position'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['page_type'] ) ) {
|
||||
$args['menu_type'] = $args['page_type'];
|
||||
unset( $args['page_type'] );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify to see if dev has bothered to change admin bar links and share icons from demo data to their own.
|
||||
*
|
||||
* @param array $args Global args.
|
||||
*/
|
||||
private function change_demo_defaults( $args ) {
|
||||
if ( $args['dev_mode'] || true === Redux_Helpers::is_local_host() ) {
|
||||
if ( ! empty( $args['admin_bar_links'] ) ) {
|
||||
foreach ( $args['admin_bar_links'] as $idx => $arr ) {
|
||||
if ( is_array( $arr ) && ! empty( $arr ) ) {
|
||||
foreach ( $arr as $x => $y ) {
|
||||
if ( strpos( Redux_Core::strtolower( $y ), 'redux' ) !== false ) {
|
||||
$msg = '<strong>' . esc_html__(
|
||||
'Redux Framework Notice',
|
||||
'redux-framework'
|
||||
) . ' </strong>' . esc_html__(
|
||||
'There are references to the Redux Framework support site in your config\'s ',
|
||||
'redux-framework'
|
||||
) . '<code>admin_bar_links</code> ' . esc_html__(
|
||||
'argument. This is sample data. Please change or remove this data before shipping your product.',
|
||||
'redux-framework'
|
||||
);
|
||||
|
||||
$this->omit_items = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $args['share_icons'] ) ) {
|
||||
foreach ( $args['share_icons'] as $idx => $arr ) {
|
||||
if ( is_array( $arr ) && ! empty( $arr ) ) {
|
||||
foreach ( $arr as $x => $y ) {
|
||||
if ( strpos( Redux_Core::strtolower( $y ), 'redux' ) !== false ) {
|
||||
$msg = '<strong>' . esc_html__(
|
||||
'Redux Framework Notice:',
|
||||
'redux-framework'
|
||||
) . '</strong>' . esc_html__(
|
||||
'There are references to the Redux Framework support site in your config\'s',
|
||||
'redux-framework'
|
||||
) . ' <code>share_icons</code> ' . esc_html__(
|
||||
'argument. This is sample data. Please change or remove this data before shipping your product.',
|
||||
'redux-framework'
|
||||
);
|
||||
|
||||
$this->omit_icons = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix other arg criteria that sometimes gets hosed up.
|
||||
*
|
||||
* @param array $args Global args.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function default_cleanup( $args ) {
|
||||
|
||||
// Fix the global variable name.
|
||||
if ( '' === $args['global_variable'] && false !== $args['global_variable'] ) {
|
||||
$args['global_variable'] = str_replace( '-', '_', $args['opt_name'] );
|
||||
}
|
||||
|
||||
if ( isset( $args['customizer_only'] ) && $args['customizer_only'] ) {
|
||||
$args['menu_type'] = 'hidden';
|
||||
$args['customizer'] = true;
|
||||
$args['admin_bar'] = false;
|
||||
$args['allow_sub_menu'] = false;
|
||||
}
|
||||
|
||||
// Check if the Airplane Mode plugin is installed.
|
||||
if ( class_exists( 'Airplane_Mode_Core' ) ) {
|
||||
$airplane = Airplane_Mode_Core::getInstance();
|
||||
if ( method_exists( $airplane, 'enabled' ) ) {
|
||||
if ( $airplane->enabled() ) {
|
||||
$args['use_cdn'] = false;
|
||||
}
|
||||
} elseif ( 'on' === $airplane->check_status() ) {
|
||||
$args['use_cdn'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Register an autoloader for custom mu-plugins.
|
||||
*
|
||||
* @package redux-framework
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Autoloader
|
||||
*
|
||||
* @package altis/core
|
||||
*/
|
||||
class Redux_Autoloader {
|
||||
const NS_SEPARATOR = '\\';
|
||||
|
||||
/**
|
||||
* Prefix to validate against.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* String length of the prefix.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $prefix_length;
|
||||
|
||||
/**
|
||||
* Path to validate.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Autoloader constructor.
|
||||
*
|
||||
* @param string $prefix Prefix to validate against.
|
||||
* @param string $path Path to validate.
|
||||
*/
|
||||
public function __construct( $prefix, $path ) {
|
||||
$this->prefix = $prefix;
|
||||
$this->prefix_length = strlen( $prefix );
|
||||
$this->path = trailingslashit( $path );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a class file if it matches our criteria.
|
||||
*
|
||||
* @param string $class Class to test and/or load.
|
||||
*/
|
||||
public function load( $class ) {
|
||||
|
||||
// Strip prefix from the start (ala PSR-4).
|
||||
$class = substr( $class, $this->prefix_length + 1 );
|
||||
if ( function_exists( 'mb_strtolower' ) && function_exists( 'mb_detect_encoding' ) ) {
|
||||
$class = mb_strtolower( $class, mb_detect_encoding( $class ) );
|
||||
} else {
|
||||
$class = strtolower( $class );
|
||||
}
|
||||
|
||||
$file = '';
|
||||
// Split on namespace separator.
|
||||
$last_ns_pos = strripos( $class, self::NS_SEPARATOR );
|
||||
if ( false !== $last_ns_pos ) {
|
||||
$namespace = substr( $class, 0, $last_ns_pos );
|
||||
$class = substr( $class, $last_ns_pos + 1 );
|
||||
$file = str_replace( self::NS_SEPARATOR, DIRECTORY_SEPARATOR, $namespace ) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
$file_prefix = $file;
|
||||
$file = $file_prefix . 'class-' . str_replace( '_', '-', $class ) . '.php';
|
||||
|
||||
$path = $this->path . $file;
|
||||
|
||||
if ( file_exists( $path ) ) {
|
||||
require_once $path;
|
||||
} else {
|
||||
$file = $file_prefix . 'class-redux-' . str_replace( '_', '-', $class ) . '.php';
|
||||
$path = $this->path . $file;
|
||||
|
||||
if ( file_exists( $path ) ) {
|
||||
require_once $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Framework CDN Container Class
|
||||
*
|
||||
* @author Kevin Provance (kprovance)
|
||||
* @package Redux_Framework/Classes
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_CDN', false ) ) {
|
||||
/**
|
||||
* Class Redux_CDN
|
||||
*/
|
||||
class Redux_CDN {
|
||||
|
||||
/**
|
||||
* Pointer to ReduxFramework object.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static $parent;
|
||||
|
||||
/**
|
||||
* Flag to check for set status.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $set;
|
||||
|
||||
/**
|
||||
* Check for enqueued status of style/script.
|
||||
*
|
||||
* @param string $handle File handle.
|
||||
* @param string $list Mode to check.
|
||||
* @param bool $is_script Flag for scrip/style.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function is_enqueued( $handle, $list = 'enqueued', $is_script = true ) {
|
||||
if ( $is_script ) {
|
||||
return wp_script_is( $handle, $list );
|
||||
} else {
|
||||
return wp_style_is( $handle, $list );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register script/style.
|
||||
*
|
||||
* @param string $handle File handle.
|
||||
* @param string $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param string $ver File version.
|
||||
* @param mixed $footer_or_media True or 'all'.
|
||||
* @param bool $is_script Script or style.
|
||||
*/
|
||||
private static function register( $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script = true ) {
|
||||
if ( $is_script ) {
|
||||
wp_register_script( $handle, $src_cdn, $deps, $ver, $footer_or_media );
|
||||
} else {
|
||||
wp_register_style( $handle, $src_cdn, $deps, $ver, $footer_or_media );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue script or style.
|
||||
*
|
||||
* @param string $handle File handle.
|
||||
* @param string $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param string $ver File version.
|
||||
* @param mixed $footer_or_media True or 'all'.
|
||||
* @param bool $is_script Script or style.
|
||||
*/
|
||||
private static function enqueue( $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script = true ) {
|
||||
if ( $is_script ) {
|
||||
wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $footer_or_media );
|
||||
} else {
|
||||
wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $footer_or_media );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue/Register CDN
|
||||
*
|
||||
* @param bool $register Register or enqueue.
|
||||
* @param string $handle File handle.
|
||||
* @param string $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param string $ver File version.
|
||||
* @param mixed $footer_or_media True or 'all'.
|
||||
* @param bool $is_script Script or style.
|
||||
*/
|
||||
private static function cdn( $register = true, $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script = true ) {
|
||||
$tran_key = '_style_cdn_is_up';
|
||||
if ( $is_script ) {
|
||||
$tran_key = '_script_cdn_is_up';
|
||||
}
|
||||
|
||||
$cdn_is_up = get_transient( $handle . $tran_key );
|
||||
if ( $cdn_is_up ) {
|
||||
if ( $register ) {
|
||||
self::register( $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script );
|
||||
} else {
|
||||
self::enqueue( $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script );
|
||||
}
|
||||
} else {
|
||||
|
||||
$prefix = '/' === $src_cdn[1] ? 'http:' : '';
|
||||
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||
$cdn_response = @wp_remote_get( $prefix . $src_cdn );
|
||||
|
||||
if ( is_wp_error( $cdn_response ) || 200 !== wp_remote_retrieve_response_code( $cdn_response ) ) {
|
||||
if ( class_exists( 'Redux_VendorURL' ) ) {
|
||||
$src = Redux_VendorURL::get_url( $handle );
|
||||
|
||||
if ( $register ) {
|
||||
self::register( $handle, $src, $deps, $ver, $footer_or_media, $is_script );
|
||||
} else {
|
||||
self::enqueue( $handle, $src, $deps, $ver, $footer_or_media, $is_script );
|
||||
}
|
||||
} else {
|
||||
if ( ! self::is_enqueued( $handle, 'enqueued', $is_script ) ) {
|
||||
$msg = esc_html__( 'Please wait a few minutes, then try refreshing the page. Unable to load some remotely hosted scripts.', 'redux-framework' );
|
||||
if ( self::$parent->args['dev_mode'] ) {
|
||||
// translators: %s: URL.
|
||||
$msg = sprintf( esc_html__( 'If you are developing offline, please download and install the %s plugin/extension to bypass our CDN and avoid this warning', 'redux-framework' ), '<a href="https://github.com/reduxframework/redux-vendor-support" target="_blank">Redux Vendor Support</a>' );
|
||||
}
|
||||
|
||||
// translators: %s: CDN handle.
|
||||
$msg = '<strong>' . esc_html__( 'Redux Framework Warning', 'redux-framework' ) . '</strong><br/>' . sprintf( esc_html__( '%s CDN unavailable. Some controls may not render properly.', 'redux-framework' ), $handle ) . ' ' . $msg;
|
||||
|
||||
$data = array(
|
||||
'parent' => self::$parent,
|
||||
'type' => 'error',
|
||||
'msg' => $msg,
|
||||
'id' => $handle . $tran_key,
|
||||
'dismiss' => false,
|
||||
);
|
||||
|
||||
Redux_Admin_Notices::set_notice( $data );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
set_transient( $handle . $tran_key, true, MINUTE_IN_SECONDS * self::$parent->args['cdn_check_time'] );
|
||||
|
||||
if ( $register ) {
|
||||
self::register( $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script );
|
||||
} else {
|
||||
self::enqueue( $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register/enqueue file from vendor library.
|
||||
*
|
||||
* @param bool $register Reigster or enqueue.
|
||||
* @param string $handle File handle.
|
||||
* @param string $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param string $ver File version.
|
||||
* @param mixed $footer_or_media True or 'all'.
|
||||
* @param bool $is_script Script or style.
|
||||
*/
|
||||
private static function vendor_plugin( $register = true, $handle, $src_cdn, $deps, $ver, $footer_or_media, $is_script = true ) {
|
||||
if ( class_exists( 'Redux_VendorURL' ) ) {
|
||||
$src = Redux_VendorURL::get_url( $handle );
|
||||
|
||||
if ( $register ) {
|
||||
self::register( $handle, $src, $deps, $ver, $footer_or_media, $is_script );
|
||||
} else {
|
||||
self::enqueue( $handle, $src, $deps, $ver, $footer_or_media, $is_script );
|
||||
}
|
||||
} else {
|
||||
if ( ! self::$set ) {
|
||||
// translators: %s: Vendor support URL. %s: Admin pluygins page.
|
||||
$msg = sprintf( esc_html__( 'The %1$s (or extension) is either not installed or not activated and thus, some controls may not render properly. Please ensure that it is installed and %2$s', 'redux-framework' ), '<a href="https://github.com/reduxframework/redux-vendor-support">Vendor Support plugin</a>', '<a href="' . admin_url( 'plugins.php' ) . '">' . esc_html__( 'activated.', 'redux-framework' ) . '</a>' );
|
||||
|
||||
$data = array(
|
||||
'parent' => self::$parent,
|
||||
'type' => 'error',
|
||||
'msg' => $msg,
|
||||
'id' => $handle,
|
||||
'dismiss' => false,
|
||||
);
|
||||
|
||||
Redux_Admin_Notices::set_notice( $data );
|
||||
|
||||
self::$set = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register style CDN or local.
|
||||
*
|
||||
* @param string $handle File handle.
|
||||
* @param bool $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param bool $ver File version.
|
||||
* @param string $media True or 'all'.
|
||||
*/
|
||||
public static function register_style( $handle, $src_cdn = false, $deps = array(), $ver = false, $media = 'all' ) {
|
||||
if ( empty( self::$parent ) || self::$parent->args['use_cdn'] ) {
|
||||
self::cdn( true, $handle, $src_cdn, $deps, $ver, $media, $is_script = false );
|
||||
} else {
|
||||
self::vendor_plugin( true, $handle, $src_cdn, $deps, $ver, $media, $is_script = false );
|
||||
}
|
||||
}
|
||||
|
||||
/** Register script CDN or local.
|
||||
*
|
||||
* @param string $handle File handle.
|
||||
* @param bool $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param bool $ver File version.
|
||||
* @param bool $in_footer Script in footer.
|
||||
*/
|
||||
public static function register_script( $handle, $src_cdn = false, $deps = array(), $ver = false, $in_footer = false ) {
|
||||
if ( empty( self::$parent ) || self::$parent->args['use_cdn'] ) {
|
||||
self::cdn( true, $handle, $src_cdn, $deps, $ver, $in_footer, $is_script = true );
|
||||
} else {
|
||||
self::vendor_plugin( true, $handle, $src_cdn, $deps, $ver, $in_footer, $is_script = true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue style CDN or local.
|
||||
*
|
||||
* @param string $handle File handle.
|
||||
* @param bool $src_cdn CDN source.
|
||||
* @param array $deps File deps.
|
||||
* @param bool $ver File version.
|
||||
* @param string $media Media type.
|
||||
*/
|
||||
public static function enqueue_style( $handle, $src_cdn = false, $deps = array(), $ver = false, $media = 'all' ) {
|
||||
if ( self::$parent->args['use_cdn'] ) {
|
||||
self::cdn( false, $handle, $src_cdn, $deps, $ver, $media, $is_script = false );
|
||||
} else {
|
||||
self::vendor_plugin( false, $handle, $src_cdn, $deps, $ver, $media, $is_script = false );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue script CDN or local.
|
||||
*
|
||||
* @param String $handle File handle.
|
||||
* @param bool $src_cdn CDN source.
|
||||
* @param array $deps File seps.
|
||||
* @param bool $ver File version.
|
||||
* @param bool $in_footer Script in footer.
|
||||
*/
|
||||
public static function enqueue_script( $handle, $src_cdn = false, $deps = array(), $ver = false, $in_footer = false ) {
|
||||
if ( self::$parent->args['use_cdn'] ) {
|
||||
self::cdn( false, $handle, $src_cdn, $deps, $ver, $in_footer, $is_script = true );
|
||||
} else {
|
||||
self::vendor_plugin( false, $handle, $src_cdn, $deps, $ver, $in_footer, $is_script = true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Class
|
||||
*
|
||||
* @class Redux_Class
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Class', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Class
|
||||
*/
|
||||
class Redux_Class {
|
||||
|
||||
/**
|
||||
* Poiner to ReduxFramework object.
|
||||
*
|
||||
* @var null|ReduxFramework
|
||||
*/
|
||||
public $parent = null;
|
||||
|
||||
/**
|
||||
* Global arguments array.
|
||||
*
|
||||
* @var array|mixed|void
|
||||
*/
|
||||
public $args = array();
|
||||
|
||||
/**
|
||||
* Project opt_name
|
||||
*
|
||||
* @var mixed|string
|
||||
*/
|
||||
public $opt_name = '';
|
||||
|
||||
/**
|
||||
* Redux_Class constructor.
|
||||
*
|
||||
* @param null|ReduxFramework $parent Pointer to ReduxFramework object.
|
||||
*/
|
||||
public function __construct( $parent = null ) {
|
||||
if ( null !== $parent && is_object( $parent ) ) {
|
||||
$this->parent = $parent;
|
||||
$this->args = $parent->args;
|
||||
$this->opt_name = $this->args['opt_name'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pointer to project specific ReduxFramework object.
|
||||
*
|
||||
* @return null|object|ReduxFramework
|
||||
*/
|
||||
public function core() {
|
||||
if ( isset( $this->opt_name ) && '' !== $this->opt_name ) {
|
||||
return Redux::instance( $this->opt_name );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,659 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Color Manipulator Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Colors', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Colors
|
||||
*/
|
||||
class Redux_Colors extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Sanitises a HEX value.
|
||||
* The way this works is by splitting the string in 6 substrings.
|
||||
* Each sub-string is individually sanitized, and the result is then returned.
|
||||
*
|
||||
* @param string $color The hex value of a color.
|
||||
* @param boolean $hash Whether we want to include a hash (#) at the beginning or not.
|
||||
*
|
||||
* @return string The sanitized hex color.
|
||||
*/
|
||||
public static function sanitize_hex( $color = '#FFFFFF', $hash = true ) {
|
||||
$word_colors = array(
|
||||
'aliceblue' => 'F0F8FF',
|
||||
'antiquewhite' => 'FAEBD7',
|
||||
'aqua' => '00FFFF',
|
||||
'aquamarine' => '7FFFD4',
|
||||
'azure' => 'F0FFFF',
|
||||
'beige' => 'F5F5DC',
|
||||
'bisque' => 'FFE4C4',
|
||||
'black' => '000000',
|
||||
'blanchedalmond' => 'FFEBCD',
|
||||
'blue' => '0000FF',
|
||||
'blueviolet' => '8A2BE2',
|
||||
'brown' => 'A52A2A',
|
||||
'burlywood' => 'DEB887',
|
||||
'cadetblue' => '5F9EA0',
|
||||
'chartreuse' => '7FFF00',
|
||||
'chocolate' => 'D2691E',
|
||||
'coral' => 'FF7F50',
|
||||
'cornflowerblue' => '6495ED',
|
||||
'cornsilk' => 'FFF8DC',
|
||||
'crimson' => 'DC143C',
|
||||
'cyan' => '00FFFF',
|
||||
'darkblue' => '00008B',
|
||||
'darkcyan' => '008B8B',
|
||||
'darkgoldenrod' => 'B8860B',
|
||||
'darkgray' => 'A9A9A9',
|
||||
'darkgreen' => '006400',
|
||||
'darkgrey' => 'A9A9A9',
|
||||
'darkkhaki' => 'BDB76B',
|
||||
'darkmagenta' => '8B008B',
|
||||
'darkolivegreen' => '556B2F',
|
||||
'darkorange' => 'FF8C00',
|
||||
'darkorchid' => '9932CC',
|
||||
'darkred' => '8B0000',
|
||||
'darksalmon' => 'E9967A',
|
||||
'darkseagreen' => '8FBC8F',
|
||||
'darkslateblue' => '483D8B',
|
||||
'darkslategray' => '2F4F4F',
|
||||
'darkslategrey' => '2F4F4F',
|
||||
'darkturquoise' => '00CED1',
|
||||
'darkviolet' => '9400D3',
|
||||
'deeppink' => 'FF1493',
|
||||
'deepskyblue' => '00BFFF',
|
||||
'dimgray' => '696969',
|
||||
'dimgrey' => '696969',
|
||||
'dodgerblue' => '1E90FF',
|
||||
'firebrick' => 'B22222',
|
||||
'floralwhite' => 'FFFAF0',
|
||||
'forestgreen' => '228B22',
|
||||
'fuchsia' => 'FF00FF',
|
||||
'gainsboro' => 'DCDCDC',
|
||||
'ghostwhite' => 'F8F8FF',
|
||||
'gold' => 'FFD700',
|
||||
'goldenrod' => 'DAA520',
|
||||
'gray' => '808080',
|
||||
'green' => '008000',
|
||||
'greenyellow' => 'ADFF2F',
|
||||
'grey' => '808080',
|
||||
'honeydew' => 'F0FFF0',
|
||||
'hotpink' => 'FF69B4',
|
||||
'indianred' => 'CD5C5C',
|
||||
'indigo' => '4B0082',
|
||||
'ivory' => 'FFFFF0',
|
||||
'khaki' => 'F0E68C',
|
||||
'lavender' => 'E6E6FA',
|
||||
'lavenderblush' => 'FFF0F5',
|
||||
'lawngreen' => '7CFC00',
|
||||
'lemonchiffon' => 'FFFACD',
|
||||
'lightblue' => 'ADD8E6',
|
||||
'lightcoral' => 'F08080',
|
||||
'lightcyan' => 'E0FFFF',
|
||||
'lightgoldenrodyellow' => 'FAFAD2',
|
||||
'lightgray' => 'D3D3D3',
|
||||
'lightgreen' => '90EE90',
|
||||
'lightgrey' => 'D3D3D3',
|
||||
'lightpink' => 'FFB6C1',
|
||||
'lightsalmon' => 'FFA07A',
|
||||
'lightseagreen' => '20B2AA',
|
||||
'lightskyblue' => '87CEFA',
|
||||
'lightslategray' => '778899',
|
||||
'lightslategrey' => '778899',
|
||||
'lightsteelblue' => 'B0C4DE',
|
||||
'lightyellow' => 'FFFFE0',
|
||||
'lime' => '00FF00',
|
||||
'limegreen' => '32CD32',
|
||||
'linen' => 'FAF0E6',
|
||||
'magenta' => 'FF00FF',
|
||||
'maroon' => '800000',
|
||||
'mediumaquamarine' => '66CDAA',
|
||||
'mediumblue' => '0000CD',
|
||||
'mediumorchid' => 'BA55D3',
|
||||
'mediumpurple' => '9370D0',
|
||||
'mediumseagreen' => '3CB371',
|
||||
'mediumslateblue' => '7B68EE',
|
||||
'mediumspringgreen' => '00FA9A',
|
||||
'mediumturquoise' => '48D1CC',
|
||||
'mediumvioletred' => 'C71585',
|
||||
'midnightblue' => '191970',
|
||||
'mintcream' => 'F5FFFA',
|
||||
'mistyrose' => 'FFE4E1',
|
||||
'moccasin' => 'FFE4B5',
|
||||
'navajowhite' => 'FFDEAD',
|
||||
'navy' => '000080',
|
||||
'oldlace' => 'FDF5E6',
|
||||
'olive' => '808000',
|
||||
'olivedrab' => '6B8E23',
|
||||
'orange' => 'FFA500',
|
||||
'orangered' => 'FF4500',
|
||||
'orchid' => 'DA70D6',
|
||||
'palegoldenrod' => 'EEE8AA',
|
||||
'palegreen' => '98FB98',
|
||||
'paleturquoise' => 'AFEEEE',
|
||||
'palevioletred' => 'DB7093',
|
||||
'papayawhip' => 'FFEFD5',
|
||||
'peachpuff' => 'FFDAB9',
|
||||
'peru' => 'CD853F',
|
||||
'pink' => 'FFC0CB',
|
||||
'plum' => 'DDA0DD',
|
||||
'powderblue' => 'B0E0E6',
|
||||
'purple' => '800080',
|
||||
'red' => 'FF0000',
|
||||
'rosybrown' => 'BC8F8F',
|
||||
'royalblue' => '4169E1',
|
||||
'saddlebrown' => '8B4513',
|
||||
'salmon' => 'FA8072',
|
||||
'sandybrown' => 'F4A460',
|
||||
'seagreen' => '2E8B57',
|
||||
'seashell' => 'FFF5EE',
|
||||
'sienna' => 'A0522D',
|
||||
'silver' => 'C0C0C0',
|
||||
'skyblue' => '87CEEB',
|
||||
'slateblue' => '6A5ACD',
|
||||
'slategray' => '708090',
|
||||
'slategrey' => '708090',
|
||||
'snow' => 'FFFAFA',
|
||||
'springgreen' => '00FF7F',
|
||||
'steelblue' => '4682B4',
|
||||
'tan' => 'D2B48C',
|
||||
'teal' => '008080',
|
||||
'thistle' => 'D8BFD8',
|
||||
'tomato' => 'FF6347',
|
||||
'turquoise' => '40E0D0',
|
||||
'violet' => 'EE82EE',
|
||||
'wheat' => 'F5DEB3',
|
||||
'white' => 'FFFFFF',
|
||||
'whitesmoke' => 'F5F5F5',
|
||||
'yellow' => 'FFFF00',
|
||||
'yellowgreen' => '9ACD32',
|
||||
);
|
||||
|
||||
if ( is_array( $color ) ) {
|
||||
$color = $color[0];
|
||||
}
|
||||
|
||||
// Remove any spaces and special characters before and after the string.
|
||||
$color = trim( $color );
|
||||
|
||||
// Check if the color is a standard word-color.
|
||||
// If it is, then convert to hex.
|
||||
if ( array_key_exists( $color, $word_colors ) ) {
|
||||
$color = $word_colors[ $color ];
|
||||
}
|
||||
|
||||
// Remove any trailing '#' symbols from the color value.
|
||||
$color = str_replace( '#', '', $color );
|
||||
|
||||
// If the string is 6 characters long then use it in pairs.
|
||||
if ( 3 === strlen( $color ) ) {
|
||||
$color = substr( $color, 0, 1 ) . substr( $color, 0, 1 ) . substr( $color, 1, 1 ) . substr( $color, 1, 1 ) . substr( $color, 2, 1 ) . substr( $color, 2, 1 );
|
||||
}
|
||||
|
||||
$substr = array();
|
||||
for ( $i = 0; $i <= 5; $i ++ ) {
|
||||
$default = ( 0 === $i ) ? 'F' : ( $substr[ $i - 1 ] );
|
||||
$substr[ $i ] = substr( $color, $i, 1 );
|
||||
$substr[ $i ] = ( false === $substr[ $i ] || ! ctype_xdigit( $substr[ $i ] ) ) ? $default : $substr[ $i ];
|
||||
}
|
||||
|
||||
$hex = implode( '', $substr );
|
||||
|
||||
return ( ! $hash ) ? $hex : '#' . $hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if string is a hex.
|
||||
*
|
||||
* @param string $hex_code Hex string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function is_hex( $hex_code = '' ) {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
||||
return @preg_match( '/^[a-f0-9]{2,}$/i', strtolower( $hex_code ) ) && ! ( strlen( $hex_code ) & 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes RGBA color.
|
||||
*
|
||||
* @param string $value RGBA value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_rgba( $value ) {
|
||||
// If empty or an array return transparent.
|
||||
if ( empty( $value ) || is_array( $value ) ) {
|
||||
return 'rgba(0,0,0,0)';
|
||||
}
|
||||
|
||||
// If string does not start with 'rgba', then treat as hex
|
||||
// sanitize the hex color and finally convert hex to rgba.
|
||||
if ( false === strpos( $value, 'rgba' ) ) {
|
||||
return self::get_rgba( self::sanitize_hex( $value ) );
|
||||
}
|
||||
|
||||
// By now we know the string is formatted as an rgba color so we can just return it.
|
||||
$value = str_replace( array( ' ', 'rgba', '(', ')' ), '', $value );
|
||||
$value = explode( ',', $value );
|
||||
$red = ( isset( $value[0] ) ) ? intval( $value[0] ) : 255;
|
||||
$green = ( isset( $value[1] ) ) ? intval( $value[1] ) : 255;
|
||||
$blue = ( isset( $value[2] ) ) ? intval( $value[2] ) : 255;
|
||||
$alpha = ( isset( $value[3] ) ) ? filter_var( $value[3], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : 1;
|
||||
|
||||
return 'rgba(' . $red . ',' . $green . ',' . $blue . ',' . $alpha . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize colors.
|
||||
* Determine if the current value is a hex or an rgba color and call the appropriate method.
|
||||
*
|
||||
* @since 0.8.5
|
||||
*
|
||||
* @param string $value hex or rgba color.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_color( $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
if ( isset( $value['rgba'] ) ) {
|
||||
$value = $value['rgba'];
|
||||
} elseif ( isset( $value['color'] ) ) {
|
||||
$opacity = ( isset( $value['opacity'] ) ) ? $value['opacity'] : null;
|
||||
$opacity = ( ! is_null( $opacity ) && isset( $value['alpha'] ) ) ? $value['alpha'] : null;
|
||||
$opacity = ( is_null( $opacity ) ) ? 1 : floatval( $opacity );
|
||||
|
||||
$value = self::get_rgba( $value['color'], $opacity );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'transparent' === $value ) {
|
||||
return 'transparent';
|
||||
}
|
||||
|
||||
// Is this an rgba color or a hex?
|
||||
$mode = ( false === strpos( $value, 'rgba' ) ) ? 'rgba' : 'hex';
|
||||
|
||||
if ( 'rgba' === $mode ) {
|
||||
return self::sanitize_hex( $value );
|
||||
} else {
|
||||
return self::sanitize_rgba( $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rgb value of the $hex color.
|
||||
*
|
||||
* @param string $hex The hex value of a color.
|
||||
* @param boolean $implode Whether we want to implode the values or not.
|
||||
*
|
||||
* @return mixed array|string
|
||||
*/
|
||||
public static function get_rgb( $hex, $implode = false ) {
|
||||
// Remove any trailing '#' symbols from the color value.
|
||||
$hex = self::sanitize_hex( $hex, false );
|
||||
|
||||
// rgb is an array.
|
||||
$rgb = array(
|
||||
hexdec( substr( $hex, 0, 2 ) ),
|
||||
hexdec( substr( $hex, 2, 2 ) ),
|
||||
hexdec( substr( $hex, 4, 2 ) ),
|
||||
);
|
||||
|
||||
return ( $implode ) ? implode( ',', $rgb ) : $rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an rgba color to hex
|
||||
* This is an approximation and not completely accurate.
|
||||
*
|
||||
* @param string $color RGBA color.
|
||||
* @param bool $apply_opacity Opacity value.
|
||||
*
|
||||
* @return string The hex value of the color.
|
||||
*/
|
||||
public static function rgba2hex( $color, $apply_opacity = false ) {
|
||||
// Remove parts of the string.
|
||||
$color = str_replace( array( 'rgba', '(', ')', ' ' ), '', $color );
|
||||
|
||||
if ( is_array( $color ) ) {
|
||||
return ( isset( $color['color'] ) ) ? $color['color'] : '#ffffff';
|
||||
}
|
||||
|
||||
// if not rgba, sanitize as HEX.
|
||||
if ( false !== strpos( $color, '#' ) ) {
|
||||
return self::sanitize_hex( $color );
|
||||
}
|
||||
|
||||
// Convert to array.
|
||||
$color = explode( ',', $color );
|
||||
|
||||
// This is not a valid rgba definition, so return white.
|
||||
if ( 4 !== count( $color ) ) {
|
||||
return '#ffffff';
|
||||
}
|
||||
|
||||
// Convert dec. to hex.
|
||||
$red = dechex( (int) $color[0] );
|
||||
$green = dechex( (int) $color[1] );
|
||||
$blue = dechex( (int) $color[2] );
|
||||
$alpha = $color[3];
|
||||
|
||||
// Make sure all colors are 2 digits.
|
||||
$red = ( 1 === strlen( $red ) ) ? '0' . $red : $red;
|
||||
$green = ( 1 === strlen( $green ) ) ? '0' . $green : $green;
|
||||
$blue = ( 1 === strlen( $blue ) ) ? '0' . $blue : $blue;
|
||||
|
||||
// Combine hex parts.
|
||||
$hex = $red . $green . $blue;
|
||||
if ( $apply_opacity ) {
|
||||
// Get the opacity value on a 0-100 basis instead of 0-1.
|
||||
$mix_level = intval( $alpha * 100 );
|
||||
|
||||
// Apply opacity - mix with white.
|
||||
$hex = self::mix_colors( $hex, '#ffffff', $mix_level );
|
||||
}
|
||||
|
||||
return '#' . str_replace( '#', '', $hex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alpha channel from an rgba color
|
||||
*
|
||||
* @param string $color The rgba color formatted like rgba(r,g,b,a).
|
||||
*
|
||||
* @return string The alpha value of the color.
|
||||
*/
|
||||
public static function get_alpha_from_rgba( $color ) {
|
||||
if ( is_array( $color ) ) {
|
||||
if ( isset( $color['opacity'] ) ) {
|
||||
return $color['opacity'];
|
||||
} elseif ( isset( $color['alpha'] ) ) {
|
||||
return $color['alpha'];
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ( false === strpos( $color, 'rgba' ) ) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
// Remove parts of the string.
|
||||
$color = str_replace( array( 'rgba', '(', ')', ' ' ), '', $color );
|
||||
|
||||
// Convert to array.
|
||||
$color = explode( ',', $color );
|
||||
|
||||
if ( isset( $color[3] ) ) {
|
||||
return (string) $color[3];
|
||||
} else {
|
||||
return '1';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rgb value of the $hex color.
|
||||
*
|
||||
* @param string $hex The hex value of a color.
|
||||
* @param int $opacity Opacity level (1-100).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_rgba( $hex = '#fff', $opacity = 100 ) {
|
||||
$hex = self::sanitize_hex( $hex, false );
|
||||
|
||||
/**
|
||||
* Make sure that opacity is properly formatted :
|
||||
* Set the opacity to 100 if a larger value has been entered by mistake.
|
||||
* If a negative value is used, then set to 0.
|
||||
* If an opacity value is entered in a decimal form (for example 0.25), then multiply by 100.
|
||||
*/
|
||||
if ( $opacity >= 100 ) {
|
||||
$opacity = 100;
|
||||
} elseif ( $opacity < 0 ) {
|
||||
$opacity = 0;
|
||||
} elseif ( $opacity <= 1 && 0 !== $opacity ) {
|
||||
$opacity = ( $opacity * 100 );
|
||||
}
|
||||
|
||||
// Divide the opacity by 100 to end-up with a CSS value for the opacity.
|
||||
$opacity = ( $opacity / 100 );
|
||||
$color = 'rgba(' . self::get_rgb( $hex, true ) . ', ' . $opacity . ')';
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the alpha value from an RGBA color string.
|
||||
*
|
||||
* @param string $rgba The RGBA color string.
|
||||
*
|
||||
* @return string The corresponding RGB string.
|
||||
*/
|
||||
public static function rgba_to_rgb( $rgba ) {
|
||||
$rgba = str_replace( ' ', '', $rgba );
|
||||
$rgba_array = explode( ',', $rgba );
|
||||
$rgba_array[0] = str_replace( 'rgba(', '', $rgba_array[0] );
|
||||
|
||||
if ( isset( $rgba_array[3] ) ) {
|
||||
unset( $rgba_array[3] );
|
||||
}
|
||||
|
||||
$rgb = sprintf( 'rgb(%s)', implode( ',', $rgba_array ) );
|
||||
|
||||
return $rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the brightness of the $hex color.
|
||||
*
|
||||
* @param string $hex The hex value of a color.
|
||||
*
|
||||
* @return int value between 0 and 255.
|
||||
*/
|
||||
public static function get_brightness( $hex ) {
|
||||
$hex = self::sanitize_hex( $hex, false );
|
||||
|
||||
// returns brightness value from 0 to 255.
|
||||
return intval( ( ( hexdec( substr( $hex, 0, 2 ) ) * 299 ) + ( hexdec( substr( $hex, 2, 2 ) ) * 587 ) + ( hexdec( substr( $hex, 4, 2 ) ) * 114 ) ) / 1000 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts brightness of the $hex color.
|
||||
*
|
||||
* @param string $hex The hex value of a color.
|
||||
* @param int $steps A value between -255 (darken) and 255 (lighten).
|
||||
*
|
||||
* @return string returns hex color.
|
||||
*/
|
||||
public static function adjust_brightness( $hex, $steps ) {
|
||||
$hex = self::sanitize_hex( $hex, false );
|
||||
|
||||
// Steps should be between -255 and 255. Negative = darker, positive = lighter.
|
||||
$steps = max( - 255, min( 255, $steps ) );
|
||||
|
||||
// Adjust number of steps and keep it inside 0 to 255.
|
||||
$red = max( 0, min( 255, hexdec( substr( $hex, 0, 2 ) ) + $steps ) );
|
||||
$green = max( 0, min( 255, hexdec( substr( $hex, 2, 2 ) ) + $steps ) );
|
||||
$blue = max( 0, min( 255, hexdec( substr( $hex, 4, 2 ) ) + $steps ) );
|
||||
|
||||
$red_hex = str_pad( dechex( $red ), 2, '0', STR_PAD_LEFT );
|
||||
$green_hex = str_pad( dechex( $green ), 2, '0', STR_PAD_LEFT );
|
||||
$blue_hex = str_pad( dechex( $blue ), 2, '0', STR_PAD_LEFT );
|
||||
|
||||
return self::sanitize_hex( $red_hex . $green_hex . $blue_hex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixes 2 hex colors.
|
||||
* the "percentage" variable is the percent of the first color
|
||||
* to be used it the mix. default is 50 (equal mix).
|
||||
*
|
||||
* @param string $hex1 The hex value of color 1.
|
||||
* @param string $hex2 The hex value of color 2.
|
||||
* @param int $percentage A value between 0 and 100.
|
||||
*
|
||||
* @return string returns hex color.
|
||||
*/
|
||||
public static function mix_colors( $hex1, $hex2, $percentage ) {
|
||||
$hex1 = self::sanitize_hex( $hex1, false );
|
||||
$hex2 = self::sanitize_hex( $hex2, false );
|
||||
|
||||
$red = ( $percentage * hexdec( substr( $hex1, 0, 2 ) ) + ( 100 - $percentage ) * hexdec( substr( $hex2, 0, 2 ) ) ) / 100;
|
||||
$green = ( $percentage * hexdec( substr( $hex1, 2, 2 ) ) + ( 100 - $percentage ) * hexdec( substr( $hex2, 2, 2 ) ) ) / 100;
|
||||
$blue = ( $percentage * hexdec( substr( $hex1, 4, 2 ) ) + ( 100 - $percentage ) * hexdec( substr( $hex2, 4, 2 ) ) ) / 100;
|
||||
|
||||
$red_hex = str_pad( dechex( $red ), 2, '0', STR_PAD_LEFT );
|
||||
$green_hex = str_pad( dechex( $green ), 2, '0', STR_PAD_LEFT );
|
||||
$blue_hex = str_pad( dechex( $blue ), 2, '0', STR_PAD_LEFT );
|
||||
|
||||
return self::sanitize_hex( $red_hex . $green_hex . $blue_hex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hex color to hsv
|
||||
*
|
||||
* @param string $hex The hex value of color 1.
|
||||
*
|
||||
* @return array returns array( 'h', 's', 'v' ).
|
||||
*/
|
||||
public static function hex_to_hsv( $hex ) {
|
||||
$rgb = (array) (array) self::get_rgb( self::sanitize_hex( $hex, false ) );
|
||||
|
||||
return self::rgb_to_hsv( $rgb );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hex color to hsv
|
||||
*
|
||||
* @param array $color The rgb color to conver array( 'r', 'g', 'b' ).
|
||||
*
|
||||
* @return array returns array( 'h', 's', 'v' ).
|
||||
*/
|
||||
public static function rgb_to_hsv( $color = array() ) {
|
||||
$var_r = ( $color[0] / 255 );
|
||||
$var_g = ( $color[1] / 255 );
|
||||
$var_b = ( $color[2] / 255 );
|
||||
|
||||
$var_min = min( $var_r, $var_g, $var_b );
|
||||
$var_max = max( $var_r, $var_g, $var_b );
|
||||
$del_max = $var_max - $var_min;
|
||||
|
||||
$h = 0;
|
||||
$s = 0;
|
||||
$v = $var_max;
|
||||
|
||||
if ( 0 !== $del_max ) {
|
||||
$s = $del_max / $var_max;
|
||||
|
||||
$del_r = ( ( ( $var_max - $var_r ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
|
||||
$del_g = ( ( ( $var_max - $var_g ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
|
||||
$del_b = ( ( ( $var_max - $var_b ) / 6 ) + ( $del_max / 2 ) ) / $del_max;
|
||||
|
||||
if ( $var_r === $var_max ) {
|
||||
$h = $del_b - $del_g;
|
||||
} elseif ( $var_g === $var_max ) {
|
||||
$h = ( 1 / 3 ) + $del_r - $del_b;
|
||||
} elseif ( $var_b === $var_max ) {
|
||||
$h = ( 2 / 3 ) + $del_g - $del_r;
|
||||
}
|
||||
|
||||
if ( $h < 0 ) {
|
||||
$h ++;
|
||||
}
|
||||
|
||||
if ( $h > 1 ) {
|
||||
$h --;
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'h' => round( $h, 2 ),
|
||||
's' => round( $s, 2 ),
|
||||
'v' => round( $v, 2 ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a very simple algorithm that works by summing up the differences between the three color components red, green and blue.
|
||||
* A value higher than 500 is recommended for good readability.
|
||||
*
|
||||
* @param string $color_1 Base color.
|
||||
* @param string $color_2 Color to compare.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function color_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
|
||||
$color_1 = self::sanitize_hex( $color_1, false );
|
||||
$color_2 = self::sanitize_hex( $color_2, false );
|
||||
|
||||
$color_1_rgb = self::get_rgb( $color_1 );
|
||||
$color_2_rgb = self::get_rgb( $color_2 );
|
||||
|
||||
$r_diff = max( $color_1_rgb[0], $color_2_rgb[0] ) - min( $color_1_rgb[0], $color_2_rgb[0] );
|
||||
$g_diff = max( $color_1_rgb[1], $color_2_rgb[1] ) - min( $color_1_rgb[1], $color_2_rgb[1] );
|
||||
$b_diff = max( $color_1_rgb[2], $color_2_rgb[2] ) - min( $color_1_rgb[2], $color_2_rgb[2] );
|
||||
|
||||
$color_diff = $r_diff + $g_diff + $b_diff;
|
||||
|
||||
return $color_diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function tries to compare the brightness of the colors.
|
||||
* A return value of more than 125 is recommended.
|
||||
* Combining it with the color_difference function above might make sense.
|
||||
*
|
||||
* @param string $color_1 Base color.
|
||||
* @param string $color_2 Color to compare.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function brightness_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
|
||||
$color_1 = self::sanitize_hex( $color_1, false );
|
||||
$color_2 = self::sanitize_hex( $color_2, false );
|
||||
|
||||
$color_1_rgb = self::get_rgb( $color_1 );
|
||||
$color_2_rgb = self::get_rgb( $color_2 );
|
||||
|
||||
$br_1 = ( 299 * $color_1_rgb[0] + 587 * $color_1_rgb[1] + 114 * $color_1_rgb[2] ) / 1000;
|
||||
$br_2 = ( 299 * $color_2_rgb[0] + 587 * $color_2_rgb[1] + 114 * $color_2_rgb[2] ) / 1000;
|
||||
|
||||
return intval( abs( $br_1 - $br_2 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the luminosity to calculate the difference between the given colors.
|
||||
* The returned value should be bigger than 5 for best readability.
|
||||
*
|
||||
* @param string $color_1 Base color.
|
||||
* @param string $color_2 Color to compare.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function lumosity_difference( $color_1 = '#ffffff', $color_2 = '#000000' ) {
|
||||
$color_1 = self::sanitize_hex( $color_1, false );
|
||||
$color_2 = self::sanitize_hex( $color_2, false );
|
||||
|
||||
$color_1_rgb = self::get_rgb( $color_1 );
|
||||
$color_2_rgb = self::get_rgb( $color_2 );
|
||||
|
||||
$l1 = 0.2126 * pow( $color_1_rgb[0] / 255, 2.2 ) + 0.7152 * pow( $color_1_rgb[1] / 255, 2.2 ) + 0.0722 * pow( $color_1_rgb[2] / 255, 2.2 );
|
||||
$l2 = 0.2126 * pow( $color_2_rgb[0] / 255, 2.2 ) + 0.7152 * pow( $color_2_rgb[1] / 255, 2.2 ) + 0.0722 * pow( $color_2_rgb[2] / 255, 2.2 );
|
||||
|
||||
$lum_diff = ( $l1 > $l2 ) ? ( $l1 + 0.05 ) / ( $l2 + 0.05 ) : ( $l2 + 0.05 ) / ( $l1 + 0.05 );
|
||||
|
||||
return round( $lum_diff, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,561 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Connection Banner Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Connection_Banner', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Connection_Banner
|
||||
*/
|
||||
class Redux_Connection_Banner {
|
||||
/**
|
||||
* Plugin version, used for cache-busting of style and script file references.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @var string
|
||||
*/
|
||||
protected $version = '1.0.0';
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*
|
||||
* @var Redux_Connection_Banner
|
||||
**/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Register option.
|
||||
*
|
||||
* @var string $register_option
|
||||
*/
|
||||
private $register_option = 'redux-connection-register';
|
||||
/**
|
||||
* Dismiss option.
|
||||
*
|
||||
* @var string $dismiss_option
|
||||
*/
|
||||
private $dismiss_option = 'redux-connection-dismiss';
|
||||
|
||||
/**
|
||||
* Nonce slug.
|
||||
*
|
||||
* @var string $dismiss_options
|
||||
*/
|
||||
private $nonce = 'redux-connection-nonce';
|
||||
|
||||
/**
|
||||
* URLs.
|
||||
*
|
||||
* @var array $urls
|
||||
*/
|
||||
private $urls = array();
|
||||
|
||||
/**
|
||||
* Init function.
|
||||
*
|
||||
* @return Redux_Connection_Banner
|
||||
*/
|
||||
public static function init() {
|
||||
if ( is_null( self::$instance ) ) {
|
||||
self::$instance = new Redux_Connection_Banner();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redux_Connection_Banner constructor.
|
||||
*
|
||||
* Since we call the Redux_Connection_Banner:init() method from the `Redux` class, and after
|
||||
* the admin_init action fires, we know that the admin is initialized at this point.
|
||||
*/
|
||||
private function __construct() {
|
||||
$clean_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $clean_get['_wpnonce'] ) && wp_verify_nonce( $clean_get['_wpnonce'], $this->nonce ) ) {
|
||||
if ( isset( $clean_get[ $this->register_option ] ) ) {
|
||||
Redux_Functions_Ex::set_activated( $clean_get[ $this->register_option ] );
|
||||
return;
|
||||
}
|
||||
if ( isset( $clean_get[ $this->dismiss_option ] ) ) {
|
||||
Redux_Functions_Ex::set_deactivated();
|
||||
update_option( 'redux-framework_tracking_notice', 'hide' );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_redux_activation', array( $this, 'admin_ajax' ) ); // Executed when logged in.
|
||||
add_action( 'current_screen', array( $this, 'maybe_initialize_hooks' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL for the current page to fallback if JS is broken.
|
||||
*
|
||||
* @param bool|string $location Used to determine the location of the banner for account creation.
|
||||
* @since 4.1.21
|
||||
* @return array
|
||||
*/
|
||||
private function get_urls( $location = true ) {
|
||||
if ( ! empty( $this->urls ) ) {
|
||||
return $this->urls;
|
||||
}
|
||||
|
||||
global $pagenow;
|
||||
|
||||
$clean_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $clean_get[ $this->register_option ] ) ) {
|
||||
unset( $clean_get[ $this->register_option ] );
|
||||
}
|
||||
if ( isset( $clean_get[ $this->dismiss_option ] ) ) {
|
||||
unset( $clean_get[ $this->dismiss_option ] );
|
||||
}
|
||||
$base_url = admin_url( add_query_arg( $clean_get, $pagenow ) );
|
||||
|
||||
return array(
|
||||
'dismiss' => wp_nonce_url( add_query_arg( $this->dismiss_option, true, $base_url ), $this->nonce ),
|
||||
'register' => wp_nonce_url( add_query_arg( $this->register_option, $location, $base_url ), $this->nonce ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback for dismissing the notice.
|
||||
*/
|
||||
public function admin_ajax() {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : '';
|
||||
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, $this->nonce ) ) {
|
||||
die( __( 'Security check failed.', 'redux-framework' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
if ( 'true' === $_REQUEST['activate'] ) {
|
||||
Redux_Functions_Ex::set_activated( sanitize_text_field( wp_unslash( $_REQUEST['activate'] ) ) );
|
||||
} else {
|
||||
Redux_Functions_Ex::set_deactivated();
|
||||
update_option( 'redux-framework_tracking_notice', 'hide' );
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback for dismissing the notice.
|
||||
*
|
||||
* @param string $admin_body_class Class string.
|
||||
* @return string
|
||||
*/
|
||||
public function admin_body_class( $admin_body_class = '' ) {
|
||||
$classes = explode( ' ', trim( $admin_body_class ) );
|
||||
|
||||
$classes[] = false ? 'redux-connected' : 'redux-disconnected';
|
||||
|
||||
$admin_body_class = implode( ' ', array_unique( $classes ) );
|
||||
return " $admin_body_class ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Will initialize hooks to display the new (as of 4.4) connection banner if the current user can
|
||||
* connect Redux, if Redux has not been deactivated, and if the current page is the plugins page.
|
||||
*
|
||||
* This method should not be called if the site is connected to WordPress.com or if the site is in development mode.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @since 4.5.0 Made the new (as of 4.4) connection banner display to everyone by default.
|
||||
* @since 5.3.0 Running another split test between 4.4 banner and a new one in 5.3.
|
||||
* @since 7.2 B test was removed.
|
||||
*
|
||||
* @param $current_screen
|
||||
*/
|
||||
public function maybe_initialize_hooks( $current_screen ) {
|
||||
// Redux_Functions_Ex::set_deactivated(); // Test code.
|
||||
|
||||
if ( Redux_Functions_Ex::activated() || 'hide' === get_option( 'redux-framework_tracking_notice', null ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't show the connect notice anywhere but the plugins.php after activating
|
||||
if ( 'plugins' !== $current_screen->base && 'dashboard' !== $current_screen->base ) {
|
||||
add_action( 'redux_admin_notices_run', array( $this, 'panel_admin_notice' ), 100, 2 );
|
||||
add_action( 'admin_head', array( $this, 'admin_head' ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Only show this notice when the plugin is installed.
|
||||
if ( class_exists( 'Redux_Framework_Plugin' ) && false === Redux_Framework_Plugin::$crash ) {
|
||||
add_action( 'admin_notices', array( $this, 'render_banner' ) );
|
||||
add_action( 'network_admin_notices', array( $this, 'network_connect_notice' ) );
|
||||
add_action( 'admin_head', array( $this, 'admin_head' ) );
|
||||
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ), 20 );
|
||||
|
||||
// Only fires immediately after plugin activation
|
||||
if ( get_transient( 'activated_Redux' ) ) {
|
||||
add_action( 'admin_notices', array( $this, 'render_connect_prompt_full_screen' ) );
|
||||
delete_transient( 'activated_Redux' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues JavaScript and CSS for new connect-in-place flow.
|
||||
*
|
||||
* @since 7.7
|
||||
*/
|
||||
public static function enqueue_connect_button_scripts() {
|
||||
global $is_safari;
|
||||
|
||||
wp_enqueue_script(
|
||||
'Redux-connect-button',
|
||||
'_inc/connect-button.js',
|
||||
array( 'jquery' ),
|
||||
Redux_Core::$version,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'Redux-connect-button',
|
||||
'css/Redux-connect.css'
|
||||
);
|
||||
|
||||
$ReduxApiUrl = wp_parse_url( Redux::connection()->api_url( '' ) );
|
||||
|
||||
// Due to the limitation in how 3rd party cookies are handled in Safari,
|
||||
// we're falling back to the original flow on Safari desktop and mobile.
|
||||
if ( $is_safari ) {
|
||||
$force_variation = 'original';
|
||||
} elseif ( Constants::is_true( 'Redux_SHOULD_USE_CONNECTION_IFRAME' ) ) {
|
||||
$force_variation = 'in_place';
|
||||
} elseif ( Constants::is_defined( 'Redux_SHOULD_USE_CONNECTION_IFRAME' ) ) {
|
||||
$force_variation = 'original';
|
||||
} else {
|
||||
$force_variation = null;
|
||||
}
|
||||
|
||||
$tracking = new Automattic\Redux\Tracking();
|
||||
$identity = $tracking->tracks_get_identity( get_current_user_id() );
|
||||
|
||||
wp_localize_script(
|
||||
'Redux-connect-button',
|
||||
'reduxConnect',
|
||||
array(
|
||||
'apiBaseUrl' => esc_url_raw( rest_url( 'Redux/v4' ) ),
|
||||
'registrationNonce' => wp_create_nonce( 'Redux-registration-nonce' ),
|
||||
'apiNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
'apiSiteDataNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
'buttonTextRegistering' => __( 'Loading...', 'redux-framework' ),
|
||||
'ReduxApiDomain' => $ReduxApiUrl['scheme'] . '://' . $ReduxApiUrl['host'],
|
||||
'forceVariation' => $force_variation,
|
||||
'connectInPlaceUrl' => Redux::admin_url( 'page=Redux#/setup' ),
|
||||
'dashboardUrl' => Redux::admin_url( 'page=Redux#/dashboard' ),
|
||||
'plansPromptUrl' => Redux::admin_url( 'page=Redux#/plans-prompt' ),
|
||||
'identity' => $identity,
|
||||
'preFetchScript' => plugins_url( '_inc/build/admin.js', Redux__PLUGIN_FILE ) . '?ver=' . Redux__VERSION,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the admin notice to users that have not opted-in or out
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function panel_admin_notice( $args ) {
|
||||
|
||||
$urls = $this->get_urls( 'panel_banner' );
|
||||
|
||||
$this->client = Redux_Core::$appsero;
|
||||
// don't show tracking if a local server
|
||||
|
||||
if ( empty( $this->notice ) ) {
|
||||
$name = 'Redux';
|
||||
// if ( isset( $args['display_name'] ) && !empty( $args['display_name'] )) {
|
||||
// $name = $name . ' & '.$args['display_name'];
|
||||
// }
|
||||
$notice = sprintf( __( 'Register <strong>%1$s</strong> to enable automatic Google Font updates service. Plus unlock all free block templates in the Redux template library.', 'redux-framework' ), $name );
|
||||
} else {
|
||||
$notice = $this->notice;
|
||||
}
|
||||
|
||||
$notice .= ' (<a class="redux-insights-data-we-collect" href="#" style="white-space: nowrap;">' . __( 'learn more', 'redux-framework' ) . '</a>)';
|
||||
|
||||
$notice .= '<p class="description" style="display:none;">' . self::tos_blurb( 'option_panel' ) . ' </p>';
|
||||
|
||||
echo '<div class="updated" id="redux-connect-message" data-nonce="' . wp_create_nonce( $this->nonce ) . '" style="border-left-color: #24b0a6;"><p>';
|
||||
echo $notice;
|
||||
echo '</p><p class="submit">';
|
||||
echo ' <a href="' . esc_url( $urls['register'] ) . '" class="button-primary button-large redux-activate-connection redux-connection-banner-action" data-url="' . admin_url( 'admin-ajax.php' ) . '" data-activate="panel_banner">' . __( 'Register Now', 'redux-framework' ) . '</a>';
|
||||
echo ' <a href="' . esc_url( $urls['dismiss'] ) . '" style="color: #aaa;" class="redux-connection-banner-action" data-activate="false" data-url="' . admin_url( 'admin-ajax.php' ) . '">' . __( 'No thanks', 'redux-framework' ) . '</a>';
|
||||
echo '</p></div>';
|
||||
echo '<style type="text/css">.wp-core-ui .button-primary.redux-activate-connection{background: #24b0a6;}.wp-core-ui .button-primary.redux-activate-connection:hover{background: #19837c;}</style>';
|
||||
|
||||
echo "<noscript><style type='text/css'>#redux-connect-message{display:none;}</style></noscript>";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide Individual Dashboard Pages
|
||||
*
|
||||
* @access public
|
||||
* @since 4.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function admin_head() {
|
||||
?>
|
||||
|
||||
<link
|
||||
rel='stylesheet' id='redux-banner-css' <?php // phpcs:ignore WordPress.WP.EnqueuedResources ?>
|
||||
href='<?php echo esc_url( Redux_Core::$url ); ?>inc/welcome/css/redux-banner.css'
|
||||
type='text/css' media='all'/>
|
||||
<script
|
||||
id="redux-banner-admin-js"
|
||||
src='<?php echo esc_url( Redux_Core::$url ); ?>inc/welcome/js/redux-banner-admin.js'>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the new connection banner as of 4.4.0.
|
||||
*
|
||||
* @since 7.2 Copy and visual elements reduced to show the new focus of Redux on Security and Performance.
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function render_banner() {
|
||||
|
||||
$urls = $this->get_urls( 'main_banner' );
|
||||
|
||||
?>
|
||||
<div id="redux-connect-message" class="updated redux-banner-container" data-nonce="<?php echo wp_create_nonce( $this->nonce ); ?>">
|
||||
<div class="redux-banner-container-top-text">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm1 15h-2v-2h2v2zm0-4h-2l-.5-6h3l-.5 6z"/></g></svg>
|
||||
<span>
|
||||
<?php esc_html_e( 'You’re almost done. Register for our service to unlock even more tools to help you build better sites faster in WordPress.', 'redux-framework' ); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="redux-banner-inner-container">
|
||||
<a href="<?php echo esc_url( $urls['dismiss'] ); ?>" data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>"
|
||||
class="notice-dismiss redux-banner-svg-dismiss redux-connection-banner-action"
|
||||
title="<?php esc_attr_e( 'Dismiss this notice', 'redux-framework' ); ?>" data-activate="false">
|
||||
</a>
|
||||
|
||||
<div class="redux-banner-content-container">
|
||||
|
||||
<!-- slide 1: intro -->
|
||||
<div class="redux-banner-slide redux-banner-slide-one redux-slide-is-active">
|
||||
|
||||
<div class="redux-banner-content-icon redux-illo">
|
||||
<a href="<?php echo esc_url( 'https://redux.io/?utm_source=plugin&utm_medium=appsero&utm_campaign=redux_banner_logo' ); ?>" target="_blank"><img
|
||||
src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/logo--color.svg"
|
||||
class="redux-banner-content-logo"
|
||||
alt="
|
||||
<?php
|
||||
esc_attr_e(
|
||||
'Visit our website to learn more!',
|
||||
'redux-framework'
|
||||
);
|
||||
?>
|
||||
"
|
||||
/></a>
|
||||
<img
|
||||
src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/redux-powering-up.svg"
|
||||
class="redux-banner-hide-phone-and-smaller"
|
||||
alt="
|
||||
<?php
|
||||
esc_attr_e(
|
||||
'Redux helps you to take your site to the next level with tools that greatly enhance your WordPress experience.',
|
||||
'redux-framework'
|
||||
);
|
||||
?>
|
||||
"
|
||||
height="auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="redux-banner-slide-text">
|
||||
<h2><?php esc_html_e( 'Build better sites faster with Redux', 'redux-framework' ); ?></h2>
|
||||
<p>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The Redux block library service allows you to build any site you want in minutes with a click of a button. With over 1,000+ templates, Redux helps you build sites fast!',
|
||||
'redux_framework'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
|
||||
<p><em>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'No registration is required to use Redux as you always have. By registering for our service you gain access to Google Font updates as well as access to all free templates in our block template library.',
|
||||
'redux-framework'
|
||||
);
|
||||
?>
|
||||
</em>
|
||||
</p>
|
||||
|
||||
<div class="redux-banner-button-container">
|
||||
<span class="redux-banner-tos-blurb"><?php echo self::tos_blurb( 'plugin_dashboard' ); ?></span>
|
||||
|
||||
<a href="<?php echo esc_url( $urls['dismiss'] ); ?>" data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>"
|
||||
class="button button-tiny button-link redux-connection-banner-action"
|
||||
title="<?php esc_attr_e( 'No thanks', 'redux-framework' ); ?>" data-activate="false"><?php esc_html_e( 'No Thanks', 'redux-framework' ); ?></a>
|
||||
|
||||
<a href="<?php echo esc_url( $urls['register'] ); ?>" data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>" data-activate="main_banner"
|
||||
class="button button-primary button-large redux-alt-connect-button redux-connection-banner-action">
|
||||
<?php esc_html_e( 'Register', 'redux-framework' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div> <!-- end slide 1 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<noscript><style type='text/css'>#redux-connect-message{display:none;}</style></noscript>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the full-screen connection prompt. Only shown once and on plugin activation.
|
||||
*/
|
||||
public static function render_connect_prompt_full_screen() {
|
||||
$current_screen = get_current_screen();
|
||||
if ( 'plugins' === $current_screen->base ) {
|
||||
$bottom_connect_url_from = 'full-screen-prompt';
|
||||
} else {
|
||||
$bottom_connect_url_from = 'landing-page-bottom';
|
||||
}
|
||||
if ( 'plugins' === $current_screen->base ) :
|
||||
?>
|
||||
?>
|
||||
<div class="redux-banner-full-container">
|
||||
<div class="redux-banner-full-container-card">
|
||||
<div class="redux-banner-full-dismiss">
|
||||
<svg class="redux-banner-svg-dismiss" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>Dismiss Redux Connection Window</title><rect x="0" fill="none" /><g><path d="M17.705 7.705l-1.41-1.41L12 10.59 7.705 6.295l-1.41 1.41L10.59 12l-4.295 4.295 1.41 1.41L12 13.41l4.295 4.295 1.41-1.41L13.41 12l4.295-4.295z"/></g></svg>
|
||||
</div>
|
||||
|
||||
<img
|
||||
src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/logo.svg"
|
||||
alt="<?php esc_attr_e( 'Redux Logo', 'redux-template' ); ?>"
|
||||
class="redux-banner-logo"
|
||||
/>
|
||||
|
||||
<div class="redux-banner-full-step-header">
|
||||
<h2 class="redux-banner-full-step-header-title"><?php esc_html_e( 'Activate essential WordPress security and performance tools by setting up Redux', 'redux-framework' ); ?></h2>
|
||||
</div>
|
||||
<p class="redux-banner-full-tos-blurb">
|
||||
<?php self::tos_blurb( 'fullscreen' ); ?>
|
||||
</p>
|
||||
<p class="redux-banner-button-container">
|
||||
<a href=""
|
||||
class="dops-button is-primary redux-button">
|
||||
<?php esc_html_e( 'Register', 'redux-framework' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="redux-banner-full-row" id="Redux-connection-cards">
|
||||
<div class="redux-banner-full-slide">
|
||||
<div class="redux-banner-full-slide-card illustration">
|
||||
<img
|
||||
src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/security.svg"
|
||||
alt="<?php esc_attr_e( 'Security & Backups', 'redux-framework' ); ?>"
|
||||
/>
|
||||
</div>
|
||||
<div class="redux-banner-full-slide-card">
|
||||
<p>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'Redux protects you against brute force attacks and unauthorized logins. ' .
|
||||
'Basic protection is always free, while premium plans add unlimited backups of your whole site, ' .
|
||||
'spam protection, malware scanning, and automated fixes.',
|
||||
'redux-framework'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="redux-banner-full-slide">
|
||||
<div class="redux-banner-full-slide-card illustration">
|
||||
<img
|
||||
src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/redux-speed.svg"
|
||||
alt="<?php esc_attr_e( 'Built-in Performance', 'redux-framework' ); ?>"
|
||||
/>
|
||||
</div>
|
||||
<div class="redux-banner-full-slide-card">
|
||||
<p>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'Activate site accelerator tools and watch your page load times decrease—' .
|
||||
"we'll optimize your images and serve them from our own powerful global network of servers, " .
|
||||
'and speed up your mobile site to reduce bandwidth usage.',
|
||||
'redux-framework'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( 'plugins' === $current_screen->base ) : ?>
|
||||
<p class="redux-banner-full-dismiss-paragraph">
|
||||
<a>
|
||||
<?php
|
||||
echo esc_html_x(
|
||||
'Not now, thank you.',
|
||||
'a link that closes the modal window that offers to connect Redux',
|
||||
'redux-framework'
|
||||
);
|
||||
?>
|
||||
</a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the legacy network connection banner.
|
||||
*/
|
||||
public function network_connect_notice() {
|
||||
?>
|
||||
<div id="message" class="updated Redux-message">
|
||||
<div class="squeezer">
|
||||
<h2>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__(
|
||||
'<strong>Redux is activated!</strong> Each site on your network must be connected individually by an admin on that site.',
|
||||
'Redux'
|
||||
),
|
||||
array( 'strong' => array() )
|
||||
);
|
||||
?>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<noscript><style type='text/css'>#message{display:none;}</style></noscript>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a TOS blurb used throughout the connection prompts.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @echo string
|
||||
*/
|
||||
public static function tos_blurb( $campaign = 'options_panel' ) {
|
||||
return sprintf(
|
||||
__( 'By clicking the <strong>Register</strong> button, you agree to our <a href="%1$s" target="_blank">terms of service</a>, to create an account, and to share details of your usage metrics with Redux.io.', 'redux-framework' ),
|
||||
Redux_Functions_Ex::get_site_utm_url( 'terms', 'appsero', 'activate', $campaign )
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// @codingStandardsIgnoreEnd
|
||||
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Descriptor Fields Class
|
||||
*
|
||||
* @class Redux_Descriptor_Fields
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
* @author Tofandel
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Redux_Descriptor
|
||||
*/
|
||||
class Redux_Descriptor_Fields implements ArrayAccess {
|
||||
|
||||
/**
|
||||
* Options had for this field.
|
||||
*
|
||||
* @var array $options Options.
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Order number for this field.
|
||||
*
|
||||
* @var int $order Order number.
|
||||
*/
|
||||
public static $order = 0;
|
||||
|
||||
/**
|
||||
* Redux_Descriptor_Fields constructor.
|
||||
*
|
||||
* @param string $name Name of field.
|
||||
* @param string $title Field title.
|
||||
* @param string $type Field Type.
|
||||
* @param string $description Field Description.
|
||||
* @param mixed $default Default vlaue.
|
||||
*
|
||||
* @throws Exception Throwable.
|
||||
*/
|
||||
public function __construct( $name, $title, $type, $description = '', $default = null ) {
|
||||
if ( ! Redux_Descriptor_Types::is_valid_type( $type ) ) {
|
||||
throw new Exception( 'Unknown type ' . $type . ' for option ' . $name );
|
||||
}
|
||||
if ( ! is_string( $title ) ) {
|
||||
$title = ucfirst( $name );
|
||||
}
|
||||
$this->options = array(
|
||||
'name' => $name,
|
||||
'title' => $title,
|
||||
'type' => $type,
|
||||
'description' => $description,
|
||||
'default' => $default,
|
||||
'order' => static::$order ++,
|
||||
'required' => (bool) $this->required,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Varible to set required for this field descriptor.
|
||||
*
|
||||
* @var bool $required Required.
|
||||
*/
|
||||
|
||||
protected $required = false;
|
||||
|
||||
/**
|
||||
* Set required.
|
||||
*
|
||||
* @param bool $required Set required for this field.
|
||||
*
|
||||
* @return Redux_Descriptor_Fields
|
||||
*/
|
||||
public function set_required( $required = true ) {
|
||||
$this->required = $required;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order.
|
||||
*
|
||||
* @param int $order Descriptor order for this field.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_order( $order ) {
|
||||
static::$order = $order;
|
||||
$this->options['order'] = (float) $order;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set group.
|
||||
*
|
||||
* @param string $group Set the group.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_group( $group ) {
|
||||
$this->options['group'] = $group;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option.
|
||||
*
|
||||
* @param string $option_key Option key.
|
||||
* @param mixed $option_value Value to set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_option( $option_key, $option_value ) {
|
||||
$this->options[ $option_key ] = $option_value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an option.
|
||||
*
|
||||
* @param string $option_key Named key of the option.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_option( $option_key ) {
|
||||
return $this->options[ $option_key ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an option.
|
||||
*
|
||||
* @param string $option_key Named key of the option.
|
||||
*/
|
||||
public function remove_option( $option_key ) {
|
||||
unset( $this->options[ $option_key ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* To documentation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function to_doc() {
|
||||
$doc = $this['name'] . '(' . $this['type'] . ')\n' . $this['description'] . "\n";
|
||||
|
||||
return $doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* To array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array() {
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a offset exists
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return boolean true on success or false on failure.
|
||||
*
|
||||
* The return value will be casted to boolean if non-boolean was returned.
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetExists( $offset ) {
|
||||
return array_key_exists( $offset, $this->options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to retrieve
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetGet( $offset ) {
|
||||
return $this->options[ $offset ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetSet( $offset, $value ) {
|
||||
$this->options[ $offset ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to unset
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
* @param mixed $offset The offset to unset.
|
||||
* @return void
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetUnset( $offset ) {
|
||||
unset( $this->options[ $offset ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Descriptor Types Class
|
||||
*
|
||||
* @class Redux_Descriptor_Types
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
* @author Tofandel
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Redux_Descriptor_Types
|
||||
*/
|
||||
abstract class Redux_Descriptor_Types {
|
||||
const TEXT = 'text';
|
||||
const TEXTAREA = 'textarea';
|
||||
const BOOL = 'bool';
|
||||
const SLIDER = 'slider';
|
||||
const NUMBER = 'number';
|
||||
const RANGE = 'range';
|
||||
const OPTIONS = 'array';
|
||||
const WP_DATA = 'wp_data';
|
||||
const RADIO = 'radio';
|
||||
// Todo add more field types for the builder!
|
||||
|
||||
/**
|
||||
* Get the available types of field.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_types() {
|
||||
static $const_cache;
|
||||
|
||||
if ( ! isset( $const_cache ) ) {
|
||||
$reflect = new ReflectionClass( __CLASS__ );
|
||||
$const_cache = $reflect->getConstants();
|
||||
}
|
||||
|
||||
return $const_cache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a type is in the list of available types.
|
||||
*
|
||||
* @param string $value Check if it's a valid type.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_valid_type( $value ) {
|
||||
return in_array( $value, self::get_types(), true );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Descriptor Class
|
||||
*
|
||||
* @class Redux_Descriptor
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
* @author Tofandel
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Redux_Descriptor
|
||||
*/
|
||||
class Redux_Descriptor {
|
||||
/**
|
||||
* Stores the Reflection class object.
|
||||
*
|
||||
* @var object ReflectionClass object.
|
||||
*/
|
||||
protected $reflection_class;
|
||||
/**
|
||||
* Field type.
|
||||
*
|
||||
* @var string $field_type Type of field.
|
||||
*/
|
||||
protected $field_type;
|
||||
/**
|
||||
* Name of the field.
|
||||
*
|
||||
* @var string $name Name of field.
|
||||
*/
|
||||
protected $name;
|
||||
/**
|
||||
* Description of the field.
|
||||
*
|
||||
* @var string $description Description of field.
|
||||
*/
|
||||
protected $description;
|
||||
/**
|
||||
* Icon of the field.
|
||||
*
|
||||
* @var string $icon Icon of field.
|
||||
*/
|
||||
protected $icon;
|
||||
/**
|
||||
* Icon of the field.
|
||||
*
|
||||
* @var bool $required Is field required?
|
||||
*/
|
||||
protected $required;
|
||||
|
||||
/**
|
||||
* Array of Redux_Descriptor_Fields.
|
||||
*
|
||||
* @var array Redux_Descriptor_Fields[] Array of descriptor_fields.
|
||||
*/
|
||||
protected $fields = array();
|
||||
|
||||
/**
|
||||
* Current field
|
||||
*
|
||||
* @var array Redux_Descriptor_Fields[] Array of descriptor_fields.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Redux_Descriptor constructor.
|
||||
*
|
||||
* @param string $field Field name.
|
||||
*/
|
||||
public function __construct( $field ) {
|
||||
Redux_Descriptor_Fields::$order = 0;
|
||||
try {
|
||||
$this->reflection_class = new ReflectionClass( $field );
|
||||
} catch ( ReflectionException $e ) {
|
||||
die ( $e->getMessage() ); // phpcs:ignore
|
||||
}
|
||||
$this->field_type = Redux_Core::strtolower( Redux_Helpers::remove_prefix( $this->reflection_class->getShortName(), 'Redux_' ) );
|
||||
$this->name = ucfirst( $this->field_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_type() {
|
||||
return $this->field_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the basic required information.
|
||||
*
|
||||
* @param string $name Set name for the descriptor.
|
||||
* @param string $description Set description for the descriptor.
|
||||
* @param string $icon Set icon for the descriptor.
|
||||
*/
|
||||
public function set_info( $name, $description = '', $icon = '' ) {
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->icon = $icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add field to the descriptor.
|
||||
*
|
||||
* @param string $name Name of field.
|
||||
* @param string $title Title of field.
|
||||
* @param string $type Type of field.
|
||||
* @param string $description Field Description.
|
||||
* @param mixed $default Field default value.
|
||||
*
|
||||
* @return Redux_Descriptor_Fields
|
||||
*/
|
||||
public function add_field( $name, $title, $type, $description = '', $default = null ) {
|
||||
try {
|
||||
$this->fields[ $name ] = new Redux_Descriptor_Fields( $name, $title, $type, $description, $default );
|
||||
} catch ( Exception $e ) {
|
||||
return null;
|
||||
}
|
||||
$this->current_field = $name;
|
||||
|
||||
return $this->fields[ $name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given request.
|
||||
*
|
||||
* @param array $req Request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parse_request( $req ) {
|
||||
$parsed_req = array();
|
||||
foreach ( $req as $k => $v ) {
|
||||
if ( isset( $this->fields[ $k ] ) ) {
|
||||
$parsed_req[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed_req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects and returns a field or the current field
|
||||
*
|
||||
* @param string $field_name Field name.
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function field( $field_name = '' ) {
|
||||
if ( ! empty( $field_name ) ) {
|
||||
$this->current_field = $field_name;
|
||||
}
|
||||
|
||||
if ( isset( $this->fields[ $this->current_field ] ) ) {
|
||||
return $this->fields[ $this->current_field ];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a field.
|
||||
*
|
||||
* @param string $name Remove a field from the keys.
|
||||
*/
|
||||
public function remove_field( $name ) {
|
||||
unset( $this->fields[ $name ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* To documentation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function to_doc() {
|
||||
$doc = $this->name . "\n" . $this->description . "\n";
|
||||
$doc .= 'Fields:';
|
||||
$this->sort_fields();
|
||||
foreach ( $this->fields as $option ) {
|
||||
$doc .= $option->to_doc();
|
||||
}
|
||||
|
||||
return $doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the fields by their order field.
|
||||
*/
|
||||
protected function sort_fields() {
|
||||
uksort(
|
||||
$this->fields,
|
||||
function ( $item1, $item2 ) {
|
||||
if ( isset( $item1['order'] ) && $item1['order'] === $item2['order'] ) {
|
||||
return 0;
|
||||
}
|
||||
return isset( $item1['order'] ) && $item1['order'] < $item2['order'] ? - 1 : 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* To array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array() {
|
||||
$fields = array();
|
||||
|
||||
$this->sort_fields();
|
||||
foreach ( $this->fields as $option ) {
|
||||
$fields[ $option['name'] ] = $option->to_array();
|
||||
}
|
||||
|
||||
return array(
|
||||
'type' => $this->field_type,
|
||||
'name' => $this->name,
|
||||
'description' => $this->description,
|
||||
'icon' => $this->icon,
|
||||
'fields' => $fields,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,514 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Enable Gutenberg Class
|
||||
*
|
||||
* @class Redux_Enable_Gutenberg
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
* @author Dovy Pauksts of Redux.io
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
|
||||
if ( ! class_exists( 'Redux_Enable_Gutenberg', false ) ) {
|
||||
|
||||
/**
|
||||
* Main Feedback Notice Class
|
||||
*/
|
||||
class Redux_Enable_Gutenberg {
|
||||
|
||||
/**
|
||||
* Slug.
|
||||
*
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*
|
||||
* @var string $name
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* No Bug Option.
|
||||
*
|
||||
* @var string $nobug_option
|
||||
*/
|
||||
public $nobug_option;
|
||||
|
||||
/**
|
||||
* Auto Enable Option.
|
||||
*
|
||||
* @var string $autoenable_option
|
||||
*/
|
||||
public $autoenable_option;
|
||||
|
||||
/**
|
||||
* Auto deactivate Option.
|
||||
*
|
||||
* @var string $decativate_option
|
||||
*/
|
||||
public $decativate_option;
|
||||
|
||||
/**
|
||||
* Nonce string.
|
||||
*
|
||||
* @var string $nonce
|
||||
*/
|
||||
public $nonce;
|
||||
|
||||
/**
|
||||
* Disabled by the theme.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $theme_disabled = false;
|
||||
|
||||
/**
|
||||
* Disabled at all.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $is_disabled = false;
|
||||
|
||||
/**
|
||||
* Quick fix known plugins that disable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $known_plugins = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $args Arguments.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
global $pagenow;
|
||||
|
||||
$defaults = array(
|
||||
'slug' => '',
|
||||
'name' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
if ( empty( $args['slug'] ) ) {
|
||||
echo 'You must pass a slug to the Redux_Enable_Gutenberg() constructor.';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( strpos( $args['slug'], 'gutenberg' ) === false ) {
|
||||
$args['slug'] .= '-gutenberg';
|
||||
}
|
||||
$this->slug = $args['slug'];
|
||||
$this->name = $args['name'];
|
||||
$this->nobug_option = $this->slug . '-no-bug';
|
||||
$this->nonce = $this->slug . '-nonce';
|
||||
$this->autoenable_option = $this->slug . '-force-enable';
|
||||
$this->decativate_option = $this->slug . '-deactivate-plugins';
|
||||
|
||||
if ( is_admin() && ! self::$is_disabled && ( 'post-new.php' === $pagenow || 'post.php' === $pagenow ) && ! get_site_option( $this->nobug_option, false ) ) {
|
||||
// We only want to do this for posts or pages.
|
||||
if ( ! isset( $_GET['post_type'] ) || ( isset( $_GET['post_type'] ) && 'page' === $_GET['post_type'] ) ) { // phpcs:ignore
|
||||
add_action( 'init', array( $this, 'check_init' ), 998 );
|
||||
add_action( 'init', array( $this, 'run_user_actions' ), 999 );
|
||||
if ( ! get_site_option( $this->nobug_option, false ) ) {
|
||||
add_action( 'plugins_loaded', array( $this, 'check_plugin' ), 999 );
|
||||
add_action( 'after_setup_theme', array( $this, 'check_theme' ), 999 );
|
||||
add_action( 'admin_notices', array( $this, 'display_admin_notice' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup for plugin deactivation.
|
||||
*
|
||||
* @param string $slug Slug for instance.
|
||||
*/
|
||||
public static function cleanup_options( $slug = '' ) {
|
||||
if ( ! empty( $slug ) ) {
|
||||
$obj = new Redux_Enable_Gutenberg(
|
||||
array(
|
||||
'slug' => $slug,
|
||||
'name' => '',
|
||||
)
|
||||
);
|
||||
delete_site_option( $obj->autoenable_option );
|
||||
delete_site_option( $obj->nobug_option );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the admin notice.
|
||||
*/
|
||||
public function display_admin_notice() {
|
||||
if ( ! self::$is_disabled ) {
|
||||
return;
|
||||
}
|
||||
global $pagenow;
|
||||
|
||||
$clean_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $clean_get[ $this->nobug_option ] ) ) {
|
||||
unset( $clean_get[ $this->nobug_option ] );
|
||||
}
|
||||
if ( isset( $clean_get[ $this->autoenable_option ] ) ) {
|
||||
unset( $clean_get[ $this->autoenable_option ] );
|
||||
}
|
||||
if ( isset( $clean_get[ $this->decativate_option ] ) ) {
|
||||
unset( $clean_get[ $this->decativate_option ] );
|
||||
}
|
||||
$base_url = admin_url( add_query_arg( $clean_get, $pagenow ) );
|
||||
|
||||
$no_bug_url = wp_nonce_url( add_query_arg( $this->nobug_option, true, $base_url ), $this->nonce );
|
||||
$auto_enable_url = wp_nonce_url( add_query_arg( $this->autoenable_option, true, $base_url ), $this->nonce );
|
||||
$deativate_url = wp_nonce_url( add_query_arg( $this->decativate_option, true, $base_url ), $this->nonce );
|
||||
|
||||
$data = array(
|
||||
'url' => '',
|
||||
'content' => '',
|
||||
'header' => __( 'Gutenberg is currently disabled!', 'redux-framework' ),
|
||||
'button' => '',
|
||||
);
|
||||
|
||||
if ( isset( $_GET[ $this->decativate_option ] ) || empty( self::$known_plugins ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
if ( isset( $_GET[ $this->decativate_option ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
// That didn't work.
|
||||
$data['header'] = __( 'Hmm, it seems something else is disabling Gutenberg...', 'redux-framework' );
|
||||
$data['content'] = sprintf( '<p>Well seems like we have more to do. Don\'t worry, we can still fix this! Click the <strong>Enable Gutenberg</strong> button and Redux will enable Gutenberg for you.</p>' );
|
||||
} elseif ( self::$theme_disabled ) {
|
||||
$data['header'] = __( 'Your theme author has disabled Gutenberg!', 'redux-framework' );
|
||||
$data['content'] .= sprintf( '<p>It looks like your theme has disabled Gutenberg. Don\'t panic though! Click the <strong>Enable Gutenberg</strong> button to the right and Redux will enable Gutenberg for you.</p>' );
|
||||
} else {
|
||||
$data['header'] = __( 'Looks like something has disabled Gutenberg?', 'redux-framework' );
|
||||
$data['content'] .= sprintf( '<p>Did you know that Gutenberg is disabled? If that\'s intended you can dismiss this notice, not what you intended? Click <strong>Enable Gutenberg</strong> and Redux will automatically fix this for you.</p>' );
|
||||
}
|
||||
|
||||
$data['url'] = $auto_enable_url;
|
||||
$data['button'] = __( 'Enable Gutenberg', 'redux-framework' );
|
||||
|
||||
} elseif ( empty( self::$known_plugins ) ) {
|
||||
// Disabled by the theme or other.
|
||||
$data['header'] = __( 'Your theme', 'redux-framework' );
|
||||
$data['url'] = $auto_enable_url;
|
||||
$data['button'] = __( 'Enable Gutenberg', 'redux-framework' );
|
||||
} else {
|
||||
// Disable Plugins!
|
||||
$all_plugins = get_plugins();
|
||||
|
||||
$plugins = '';
|
||||
|
||||
foreach ( self::$known_plugins as $slug ) {
|
||||
if ( isset( $all_plugins[ $slug ] ) ) {
|
||||
if ( ! empty( $plugins ) ) {
|
||||
$plugins .= ', ';
|
||||
}
|
||||
$plugins .= '<code>' . esc_html( $all_plugins[ $slug ]['Name'] ) . '</code>';
|
||||
}
|
||||
}
|
||||
|
||||
$data['url'] = $deativate_url;
|
||||
if ( 1 === count( self::$known_plugins ) ) {
|
||||
$data['button'] = __( 'Disable Plugin', 'redux-framework' );
|
||||
$data['content'] = sprintf( '<p>The following plugin is preventing Gutenberg from working: %s. To automatically fix the issue click the <strong>Disable Plugin</strong> button on the right and Redux will enable it for you.</p>', $plugins, esc_url( 'https://kinsta.com/blog/gutenberg-wordpress-editor/' ) );
|
||||
} else {
|
||||
$data['button'] = __( 'Disable Plugins', 'redux-framework' );
|
||||
$data['content'] = sprintf( '<p>The following plugin is preventing Gutenberg from working: %s. To automatically fix the issue click the <strong>Disable Plugins</strong> button on the right and Redux will enable it for you.</p>', $plugins, esc_url( 'https://kinsta.com/blog/gutenberg-wordpress-editor/' ) );
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<style>
|
||||
.notice.redux-notice {
|
||||
border-left-color: #24b0a6 !important;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.rtl .notice.redux-notice {
|
||||
border-right-color: #19837c !important;
|
||||
}
|
||||
|
||||
.notice.notice.redux-notice .redux-notice-inner {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-icon,
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-content,
|
||||
.notice.redux-notice .redux-notice-inner .redux-install-now {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-icon {
|
||||
color: #509ed2;
|
||||
font-size: 13px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-icon img {
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-content {
|
||||
padding: 0 40px 0 20px;
|
||||
}
|
||||
|
||||
.notice.redux-notice p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.notice.redux-notice h3 {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-install-now {
|
||||
text-align: center;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-install-now .redux-install-button {
|
||||
padding: 6px 50px;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
background: #24b0a6;
|
||||
border-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-install-now .redux-install-button:hover {
|
||||
background: #19837c;
|
||||
}
|
||||
|
||||
.notice.redux-notice a.no-thanks {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: #72777c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.notice.redux-notice a.no-thanks:hover {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
.notice.notice.redux-notice .redux-notice-inner {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.notice.redux-notice {
|
||||
padding: 20px !important;
|
||||
}
|
||||
|
||||
.notice.redux-noticee .redux-notice-inner {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-content {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .redux-install-now {
|
||||
margin-top: 20px;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .no-thanks {
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="notice updated redux-notice">
|
||||
<div class="redux-notice-inner">
|
||||
<div class="redux-notice-icon">
|
||||
<?php /* translators: 1. Name */ ?>
|
||||
<img src="<?php echo esc_url( Redux_Core::$url . '/assets/img/icon--color.svg' ); ?>" alt="<?php echo esc_attr__( 'Redux WordPress Plugin', 'redux-framework' ); ?>"/>
|
||||
</div>
|
||||
<div class="redux-notice-content">
|
||||
<?php /* translators: 1. Name */ ?>
|
||||
<h3><?php printf( esc_html( $data['header'] ) ); ?></h3>
|
||||
<?php printf( $data['content'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</div>
|
||||
<div class="redux-install-now">
|
||||
<?php printf( '<a href="%1$s" class="button button-primary redux-install-button">%2$s</a>', esc_url( $data['url'] ), esc_html( $data['button'] ) ); ?>
|
||||
<a href="<?php echo esc_url( $no_bug_url ); ?>" class="no-thanks"><?php echo esc_html__( 'No Thanks', 'redux-framework' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plugin to no longer bug users if user asks not to be.
|
||||
*/
|
||||
public function run_user_actions() {
|
||||
// Bail out if not on correct page.
|
||||
// phpcs:ignore
|
||||
if ( ! isset( $_GET['_wpnonce'] ) || ( ! wp_verify_nonce( $_GET['_wpnonce'], $this->nonce ) || ! is_admin() || ! current_user_can( 'manage_options' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $_GET[ $this->nobug_option ] ) ) { // User doesn't want to see this anymore.
|
||||
add_site_option( $this->nobug_option, true );
|
||||
} elseif ( isset( $_GET[ $this->autoenable_option ] ) ) { // User has opted to just auto-enable Gutenberg.
|
||||
unset( $_GET[ $this->autoenable_option ] );
|
||||
add_site_option( $this->autoenable_option, true );
|
||||
} elseif ( isset( $_GET[ $this->decativate_option ] ) && ! empty( self::$known_plugins ) ) { // User has opted to disable known gutenberg plugins.
|
||||
deactivate_plugins( self::$known_plugins );
|
||||
}
|
||||
global $pagenow;
|
||||
unset( $_GET['_wpnonce'] );
|
||||
$url = admin_url( add_query_arg( $_GET, $pagenow ) );
|
||||
wp_safe_redirect( $url );
|
||||
|
||||
exit();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plugin to no longer bug users if user asks not to be.
|
||||
*/
|
||||
public function set_auto_disable() {
|
||||
|
||||
// Bail out if not on correct page.
|
||||
// phpcs:ignore
|
||||
if ( ! isset( $_GET['_wpnonce'] ) || ( ! wp_verify_nonce( $_GET['_wpnonce'], $this->nonce ) || ! is_admin() || ! isset( $_GET[ $this->autoenable_option ] ) || ! current_user_can( 'manage_options' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_site_option( $this->autoenable_option, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for filter method.
|
||||
*/
|
||||
private function check_for_filter() {
|
||||
if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
|
||||
if ( has_filter( 'use_block_editor_for_post_type', '__return_false' ) ) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ( has_filter( 'gutenberg_can_edit_post_type', '__return_false' ) ) {
|
||||
return true; // WP < 5 beta.
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the Gutenberg disable filter for posts and pages only.
|
||||
*/
|
||||
private function remove_filter() {
|
||||
global $pagenow;
|
||||
|
||||
if ( is_admin() && ( 'post-new.php' === $pagenow || 'post.php' === $pagenow ) ) {
|
||||
// We only want to do this for posts or pages.
|
||||
if ( ! isset( $_GET['post_type'] ) || ( isset( $_GET['post_type'] ) && 'page' === $_GET['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
|
||||
// WP > 5 beta.
|
||||
remove_filter( 'use_block_editor_for_post_type', '__return_false' );
|
||||
} else {
|
||||
// WP < 5 beta.
|
||||
remove_filter( 'gutenberg_can_edit_post_type', '__return_false' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick checks against known plugins for disabling.
|
||||
*/
|
||||
public function quick_checks() {
|
||||
// Testing for known plugins if they're loaded, save on filters and performance.
|
||||
if ( class_exists( 'Classic_Editor' ) ) {
|
||||
$a = new \ReflectionClass( 'Classic_Editor' );
|
||||
self::$known_plugins[] = plugin_basename( $a->getFileName() );
|
||||
}
|
||||
|
||||
if ( defined( 'DISABLE_GUTENBERG_FILE' ) ) {
|
||||
self::$known_plugins[] = plugin_basename( DISABLE_GUTENBERG_FILE );
|
||||
}
|
||||
|
||||
if ( defined( 'ADE_PLUGIN_DIR_PATH' ) ) {
|
||||
if ( class_exists( 'CodePopular_disable_gutenburg' ) ) {
|
||||
$a = new \ReflectionClass( 'CodePopular_disable_gutenburg' );
|
||||
self::$known_plugins[] = plugin_basename( $a->getFileName() );
|
||||
} else {
|
||||
self::$known_plugins[] = plugin_basename( ADE_PLUGIN_DIR_PATH ) . '/auto-disable-gutenberg.php';
|
||||
}
|
||||
}
|
||||
self::$known_plugins[] = 'no-gutenberg/no-gutenberg.php';
|
||||
self::$known_plugins[] = 'enable-classic-editor/enable-classic-editor.php';
|
||||
|
||||
$plugins = get_option( 'active_plugins' );
|
||||
$results = array_intersect( $plugins, self::$known_plugins );
|
||||
self::$known_plugins = $results;
|
||||
if ( ! empty( self::$known_plugins ) ) {
|
||||
self::$is_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if plugins have the disable filter.
|
||||
*/
|
||||
public function check_plugin() {
|
||||
$this->quick_checks();
|
||||
if ( ! self::$is_disabled && $this->check_for_filter() ) {
|
||||
self::$is_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the theme have the disable filter.
|
||||
*/
|
||||
public function check_theme() {
|
||||
if ( ! self::$is_disabled && $this->check_for_filter() ) {
|
||||
self::$theme_disabled = true;
|
||||
self::$is_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if init hook still has the disable filter.
|
||||
*/
|
||||
public function check_init() {
|
||||
if ( ! self::$is_disabled ) {
|
||||
if ( $this->check_for_filter() ) {
|
||||
self::$is_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( self::$is_disabled && get_site_option( $this->autoenable_option, false ) ) {
|
||||
$this->remove_filter();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Instantiate the Redux_Enable_Gutenberg class.
|
||||
*/
|
||||
new Redux_Enable_Gutenberg(
|
||||
array(
|
||||
'slug' => 'redux-framework',
|
||||
'name' => __( 'Redux', 'redux-framework' ),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,768 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Primary Enqueue Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Enqueue', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Enqueue
|
||||
*/
|
||||
class Redux_Enqueue extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Data to localize.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $localize_data = array();
|
||||
|
||||
/**
|
||||
* Min string for .min files.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $min = '';
|
||||
|
||||
/**
|
||||
* Timestamp for file versions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $timestamp = '';
|
||||
|
||||
/**
|
||||
* Localize data required for the repeater extension.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $repeater_data = array();
|
||||
|
||||
/**
|
||||
* Redux_Enqueue constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
// Enqueue the admin page CSS and JS.
|
||||
if ( isset( $_GET['page'] ) && $_GET['page'] === $parent->args['page_slug'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'init' ), 1 );
|
||||
}
|
||||
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_init' ), 10 );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/{$parent->args['opt_name']}/enqueue/construct", $this );
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/enqueue/construct', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Scripts to enqueue on the frontend
|
||||
*/
|
||||
public function frontend_init() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( $core->args['elusive_frontend'] ) {
|
||||
wp_enqueue_style(
|
||||
'redux-elusive-icon',
|
||||
Redux_Core::$url . 'assets/css/vendor/elusive-icons.min.css',
|
||||
array(),
|
||||
Redux_Core::$version,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class init functions.
|
||||
*/
|
||||
public function init() {
|
||||
$core = $this->core();
|
||||
|
||||
Redux_Functions::$parent = $core;
|
||||
Redux_CDN::$parent = $core;
|
||||
|
||||
$this->min = Redux_Functions::is_min();
|
||||
|
||||
$this->timestamp = Redux_Core::$version;
|
||||
if ( $core->args['dev_mode'] ) {
|
||||
$this->timestamp .= '.' . time();
|
||||
}
|
||||
|
||||
$this->register_styles( $core );
|
||||
$this->register_scripts( $core );
|
||||
|
||||
add_thickbox();
|
||||
|
||||
$this->enqueue_fields( $core );
|
||||
|
||||
add_filter( "redux/{$core->args['opt_name']}/localize", array( 'Redux_Helpers', 'localize' ) );
|
||||
|
||||
$this->set_localized_data( $core );
|
||||
|
||||
/**
|
||||
* Action 'redux/page/{opt_name}/enqueue'
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/page/{$core->args['opt_name']}/enqueue" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all core framework styles.
|
||||
*
|
||||
* @param object $core ReduxFramework object.
|
||||
*/
|
||||
private function register_styles( $core ) {
|
||||
|
||||
// *****************************************************************
|
||||
// Redux Admin CSS
|
||||
// *****************************************************************
|
||||
if ( 'wordpress' === $core->args['admin_theme'] || 'wp' === $core->args['admin_theme'] ) { // phpcs:ignore WordPress.WP.CapitalPDangit
|
||||
$color_scheme = get_user_option( 'admin_color' );
|
||||
} elseif ( 'classic' === $core->args['admin_theme'] || '' === $core->args['admin_theme'] ) {
|
||||
$color_scheme = 'classic';
|
||||
} else {
|
||||
$color_scheme = $core->args['admin_theme'];
|
||||
}
|
||||
|
||||
if ( ! file_exists( Redux_Core::$dir . "assets/css/colors/$color_scheme/colors{$this->min}.css" ) ) {
|
||||
$color_scheme = 'fresh';
|
||||
}
|
||||
|
||||
$css = Redux_Core::$url . "assets/css/colors/$color_scheme/colors{$this->min}.css";
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$css = apply_filters( 'redux/enqueue/' . $core->args['opt_name'] . '/args/admin_theme/css_url', $css );
|
||||
|
||||
wp_register_style(
|
||||
'redux-admin-theme-css',
|
||||
$css,
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'redux-admin-css',
|
||||
Redux_Core::$url . "assets/css/redux-admin{$this->min}.css",
|
||||
array( 'redux-admin-theme-css' ),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Redux Fields CSS
|
||||
// *****************************************************************
|
||||
if ( ! $core->args['dev_mode'] ) {
|
||||
wp_enqueue_style(
|
||||
'redux-fields-css',
|
||||
Redux_Core::$url . 'assets/css/redux-fields.min.css',
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// Select2 CSS
|
||||
// *****************************************************************
|
||||
wp_enqueue_style(
|
||||
'select2-css',
|
||||
Redux_Core::$url . 'assets/css/vendor/select2.min.css',
|
||||
array(),
|
||||
'4.0.5',
|
||||
'all'
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Spectrum CSS
|
||||
// *****************************************************************
|
||||
$css_file = 'redux-spectrum.css';
|
||||
|
||||
wp_register_style(
|
||||
'redux-spectrum-css',
|
||||
Redux_Core::$url . "assets/css/vendor/spectrum{$this->min}.css",
|
||||
array(),
|
||||
'1.3.3',
|
||||
'all'
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Elusive Icon CSS
|
||||
// *****************************************************************
|
||||
wp_enqueue_style(
|
||||
'redux-elusive-icon',
|
||||
Redux_Core::$url . "assets/css/vendor/elusive-icons{$this->min}.css",
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// QTip CSS
|
||||
// *****************************************************************
|
||||
wp_enqueue_style(
|
||||
'qtip-css',
|
||||
Redux_Core::$url . "assets/css/vendor/qtip{$this->min}.css",
|
||||
array(),
|
||||
'2.2.0',
|
||||
'all'
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// JQuery UI CSS
|
||||
// *****************************************************************
|
||||
|
||||
wp_enqueue_style(
|
||||
'jquery-ui-css',
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/page/{$core->args['opt_name']}/enqueue/jquery-ui-css",
|
||||
Redux_Core::$url . 'assets/css/vendor/jquery-ui-1.10.0.custom.css'
|
||||
),
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Iris CSS
|
||||
// *****************************************************************
|
||||
wp_enqueue_style( 'wp-color-picker' );
|
||||
|
||||
if ( $core->args['dev_mode'] ) {
|
||||
// *****************************************************************
|
||||
// Media CSS
|
||||
// *****************************************************************
|
||||
wp_enqueue_style(
|
||||
'redux-field-media-css',
|
||||
Redux_Core::$url . 'assets/css/media.css',
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
|
||||
// *****************************************************************
|
||||
// RTL CSS
|
||||
// *****************************************************************
|
||||
if ( is_rtl() ) {
|
||||
wp_enqueue_style(
|
||||
'redux-rtl-css',
|
||||
Redux_Core::$url . 'assets/css/rtl.css',
|
||||
array( 'redux-admin-css' ),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all core framework scripts.
|
||||
*
|
||||
* @param object $core ReduxFramework object.
|
||||
*/
|
||||
private function register_scripts( $core ) {
|
||||
// *****************************************************************
|
||||
// JQuery / JQuery UI JS
|
||||
// *****************************************************************
|
||||
wp_enqueue_script( 'jquery' );
|
||||
wp_enqueue_script( 'jquery-ui-core' );
|
||||
wp_enqueue_script( 'jquery-ui-dialog' );
|
||||
|
||||
// *****************************************************************
|
||||
// Select2 Sortable JS
|
||||
// *****************************************************************
|
||||
wp_register_script(
|
||||
'redux-select2-sortable-js',
|
||||
Redux_Core::$url . 'assets/js/vendor/select2-sortable/redux.select2.sortable' . $this->min . '.js',
|
||||
array( 'jquery', 'jquery-ui-sortable' ),
|
||||
$this->timestamp,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'select2-js',
|
||||
Redux_Core::$url . 'assets/js/vendor/select2/select2' . $this->min . '.js`',
|
||||
array( 'jquery', 'redux-select2-sortable-js' ),
|
||||
'4.0.5',
|
||||
true
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// QTip JS
|
||||
// *****************************************************************
|
||||
wp_enqueue_script(
|
||||
'qtip-js',
|
||||
Redux_Core::$url . 'assets/js/vendor/qtip/qtip' . $this->min . '.js',
|
||||
array( 'jquery' ),
|
||||
'2.2.0',
|
||||
true
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Spectrum JS
|
||||
// *****************************************************************
|
||||
wp_register_script(
|
||||
'redux-spectrum-js',
|
||||
Redux_Core::$url . 'assets/js/vendor/spectrum/redux-spectrum' . $this->min . '.js',
|
||||
array( 'jquery' ),
|
||||
'1.3.3',
|
||||
true
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Vendor JS
|
||||
// *****************************************************************
|
||||
wp_register_script(
|
||||
'redux-vendor',
|
||||
Redux_Core::$url . 'assets/js/redux-vendors' . $this->min . '.js',
|
||||
array( 'jquery' ),
|
||||
$this->timestamp,
|
||||
true
|
||||
);
|
||||
|
||||
// *****************************************************************
|
||||
// Redux JS
|
||||
// *****************************************************************
|
||||
wp_register_script(
|
||||
'redux-js',
|
||||
Redux_Core::$url . 'assets/js/redux' . $this->min . '.js',
|
||||
array( 'jquery', 'redux-vendor' ),
|
||||
$this->timestamp,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $core->args['async_typography'] ) {
|
||||
wp_enqueue_script(
|
||||
'webfontloader',
|
||||
// phpcs:ignore Generic.Strings.UnnecessaryStringConcat
|
||||
'//' . 'ajax' . '.googleapis' . '.com/ajax/libs/webfont/1.6.26/webfont.js',
|
||||
array( 'jquery', 'redux-vendor' ),
|
||||
'1.6.26',
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue fields that are in use.
|
||||
*
|
||||
* @param object $core ReduxFramework object.
|
||||
* @param array $field Field array.
|
||||
*/
|
||||
public function enqueue_field( $core, $field ) {
|
||||
if ( isset( $field['type'] ) && 'callback' !== $field['type'] ) {
|
||||
|
||||
/**
|
||||
* Field class file
|
||||
* filter 'redux/{opt_name}/field/class/{field.type}
|
||||
*
|
||||
* @param string field class file path
|
||||
* @param array $field field config data
|
||||
*/
|
||||
$field_type = str_replace( '_', '-', $field['type'] );
|
||||
$core_path = Redux_Core::$dir . "inc/fields/{$field['type']}/class-redux-{$field_type}.php";
|
||||
|
||||
// Shim for v3 extension class names.
|
||||
if ( ! file_exists( $core_path ) ) {
|
||||
$core_path = Redux_Core::$dir . "inc/fields/{$field['type']}/field_{$field['type']}.php";
|
||||
}
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$pro_path = Redux_Pro::$dir . "core/inc/fields/{$field['type']}/class-redux-{$field_type}.php";
|
||||
|
||||
if ( file_exists( $pro_path ) ) {
|
||||
$filter_path = $pro_path;
|
||||
} else {
|
||||
$filter_path = $core_path;
|
||||
}
|
||||
} else {
|
||||
$filter_path = $core_path;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$class_file = apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/{$core->args['opt_name']}/field/class/{$field['type']}",
|
||||
$filter_path,
|
||||
$field
|
||||
);
|
||||
|
||||
$field_classes = array( 'Redux_' . $field['type'], 'ReduxFramework_' . $field['type'] );
|
||||
|
||||
if ( $class_file ) {
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
if ( false === $field_class ) {
|
||||
if ( file_exists( $class_file ) ) {
|
||||
require_once $class_file;
|
||||
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( method_exists( $field_class, 'enqueue' ) ) || method_exists( $field_class, 'localize' ) ) {
|
||||
if ( ! isset( $core->options[ $field['id'] ] ) ) {
|
||||
$core->options[ $field['id'] ] = '';
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'field' => $field,
|
||||
'value' => $core->options[ $field['id'] ],
|
||||
'core' => $core,
|
||||
'mode' => 'enqueue',
|
||||
);
|
||||
|
||||
Redux_Functions::load_pro_field( $data );
|
||||
|
||||
$the_field = new $field_class( $field, $core->options[ $field['id'] ], $core );
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$field_filter = Redux_Pro::$dir . 'core/inc/fields/' . $field['type'] . '/class-redux-pro-' . $field_type . '.php';
|
||||
|
||||
if ( file_exists( $field_filter ) ) {
|
||||
require_once $field_filter;
|
||||
|
||||
$filter_class_name = 'Redux_Pro_' . $field['type'];
|
||||
|
||||
if ( class_exists( $filter_class_name ) ) {
|
||||
$extend = new $filter_class_name( $field, $core->options[ $field['id'] ], $core );
|
||||
$extend->init( 'enqueue' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move dev_mode check to a new if/then block.
|
||||
if ( ( ! wp_script_is( 'redux-field-' . $field_type . '-js', 'enqueued' ) || ! wp_script_is(
|
||||
'redux-extension-' . $field_type . '-js',
|
||||
'enqueued'
|
||||
) || ! wp_script_is(
|
||||
'redux-pro-field-' . $field_type . '-js',
|
||||
'enqueued'
|
||||
) ) && class_exists( $field_class ) && method_exists( $field_class, 'enqueue' ) ) {
|
||||
$the_field->enqueue();
|
||||
}
|
||||
|
||||
if ( method_exists( $field_class, 'localize' ) ) {
|
||||
$params = $the_field->localize( $field );
|
||||
if ( ! isset( $this->localize_data[ $field['type'] ] ) ) {
|
||||
$this->localize_data[ $field['type'] ] = array();
|
||||
}
|
||||
|
||||
$localize_data = $the_field->localize( $field );
|
||||
|
||||
$shims = array( 'repeater' );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$shims = apply_filters( 'redux/' . $core->args['opt_name'] . '/localize/shims', $shims );
|
||||
|
||||
if ( is_array( $shims ) && in_array( $field['type'], $shims, true ) ) {
|
||||
$this->repeater_data[ $field['type'] ][ $field['id'] ] = $localize_data;
|
||||
}
|
||||
|
||||
$this->localize_data[ $field['type'] ][ $field['id'] ] = $localize_data;
|
||||
}
|
||||
|
||||
unset( $the_field );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue field files.
|
||||
*
|
||||
* @param object $core ReduxFramework object.
|
||||
*/
|
||||
private function enqueue_fields( $core ) {
|
||||
$data = array();
|
||||
|
||||
foreach ( $core->sections as $section ) {
|
||||
if ( isset( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $field ) {
|
||||
$this->enqueue_field( $core, $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build localize array from field functions, if any.
|
||||
*
|
||||
* @param object $core ReduxFramework object.
|
||||
* @param string $type Field type.
|
||||
*/
|
||||
private function build_local_array( $core, $type ) {
|
||||
if ( isset( $core->transients['last_save_mode'] ) && ! empty( $core->transients['notices'][ $type ] ) ) {
|
||||
$the_total = 0;
|
||||
$messages = array();
|
||||
|
||||
foreach ( $core->transients['notices'][ $type ] as $msg ) {
|
||||
$messages[ $msg['section_id'] ][ $type ][] = $msg;
|
||||
|
||||
if ( ! isset( $messages[ $msg['section_id'] ]['total'] ) ) {
|
||||
$messages[ $msg['section_id'] ]['total'] = 0;
|
||||
}
|
||||
|
||||
$messages[ $msg['section_id'] ]['total'] ++;
|
||||
$the_total ++;
|
||||
}
|
||||
|
||||
$this->localize_data[ $type ] = array(
|
||||
'total' => $the_total,
|
||||
"{$type}" => $messages,
|
||||
);
|
||||
|
||||
unset( $core->transients['notices'][ $type ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile panel errors and warings for locaize array.
|
||||
*/
|
||||
public function get_warnings_and_errors_array() {
|
||||
$core = $this->core();
|
||||
|
||||
$this->build_local_array( $core, 'errors' );
|
||||
$this->build_local_array( $core, 'warnings' );
|
||||
$this->build_local_array( $core, 'sanitize' );
|
||||
|
||||
if ( empty( $core->transients['notices'] ) ) {
|
||||
unset( $core->transients['notices'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit localized data to global array.
|
||||
*
|
||||
* @param object $core ReduxFramework object.
|
||||
*/
|
||||
private function set_localized_data( $core ) {
|
||||
if ( ! empty( $core->args['last_tab'] ) ) {
|
||||
$this->localize_data['last_tab'] = $core->args['last_tab'];
|
||||
}
|
||||
|
||||
$this->localize_data['core_instance'] = $core->core_instance;
|
||||
$this->localize_data['core_thread'] = $core->core_thread;
|
||||
|
||||
$this->localize_data['font_weights'] = $this->args['font_weights'];
|
||||
|
||||
$this->localize_data['required'] = $core->required;
|
||||
$this->repeater_data['fonts'] = $core->fonts;
|
||||
if ( ! isset( $this->repeater_data['opt_names'] ) ) {
|
||||
$this->repeater_data['opt_names'] = array();
|
||||
}
|
||||
$this->repeater_data['opt_names'][] = $core->args['opt_name'];
|
||||
$this->repeater_data['folds'] = array();
|
||||
$this->localize_data['required_child'] = $core->required_child;
|
||||
$this->localize_data['fields'] = $core->fields;
|
||||
|
||||
if ( isset( $core->font_groups['google'] ) ) {
|
||||
$this->repeater_data['googlefonts'] = $core->font_groups['google'];
|
||||
}
|
||||
|
||||
if ( isset( $core->font_groups['std'] ) ) {
|
||||
$this->repeater_data['stdfonts'] = $core->font_groups['std'];
|
||||
}
|
||||
|
||||
if ( isset( $core->font_groups['customfonts'] ) ) {
|
||||
$this->repeater_data['customfonts'] = $core->font_groups['customfonts'];
|
||||
}
|
||||
|
||||
if ( isset( $core->font_groups['typekitfonts'] ) ) {
|
||||
$this->repeater_data['typekitfonts'] = $core->font_groups['typekitfonts'];
|
||||
}
|
||||
|
||||
$this->localize_data['folds'] = $core->folds;
|
||||
|
||||
// Make sure the children are all hidden properly.
|
||||
foreach ( $core->fields as $key => $value ) {
|
||||
if ( in_array( $key, $core->fields_hidden, true ) ) {
|
||||
foreach ( $value as $k => $v ) {
|
||||
if ( ! in_array( $k, $core->fields_hidden, true ) ) {
|
||||
$core->fields_hidden[] = $k;
|
||||
$core->folds[ $k ] = 'hide';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->localize_data['fields_hidden'] = $core->fields_hidden;
|
||||
$this->localize_data['options'] = $core->options;
|
||||
$this->localize_data['defaults'] = $core->options_defaults;
|
||||
|
||||
/**
|
||||
* Save pending string
|
||||
* filter 'redux/{opt_name}/localize/save_pending
|
||||
*
|
||||
* @param string save_pending string
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$save_pending = apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/{$core->args['opt_name']}/localize/save_pending",
|
||||
esc_html__(
|
||||
'You have changes that are not saved. Would you like to save them now?',
|
||||
'redux-framework'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Reset all string
|
||||
* filter 'redux/{opt_name}/localize/reset
|
||||
*
|
||||
* @param string reset all string
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$reset_all = apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/{$core->args['opt_name']}/localize/reset",
|
||||
esc_html__(
|
||||
'Are you sure? Resetting will lose all custom values.',
|
||||
'redux-framework'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Reset section string
|
||||
* filter 'redux/{opt_name}/localize/reset_section
|
||||
*
|
||||
* @param string reset section string
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$reset_section = apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/{$core->args['opt_name']}/localize/reset_section",
|
||||
esc_html__(
|
||||
'Are you sure? Resetting will lose all custom values in this section.',
|
||||
'redux-framework'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Preset confirm string
|
||||
* filter 'redux/{opt_name}/localize/preset
|
||||
*
|
||||
* @param string preset confirm string
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$preset_confirm = apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/{$core->args['opt_name']}/localize/preset",
|
||||
esc_html__(
|
||||
'Your current options will be replaced with the values of this preset. Would you like to proceed?',
|
||||
'redux-framework'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Import confirm string
|
||||
* filter 'redux/{opt_name}/localize/import
|
||||
*
|
||||
* @param string import confirm string
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$import_confirm = apply_filters(
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
"redux/{$core->args['opt_name']}/localize/import",
|
||||
esc_html__(
|
||||
'Your current options will be replaced with the values of this import. Would you like to proceed?',
|
||||
'redux-framework'
|
||||
)
|
||||
);
|
||||
|
||||
global $pagenow;
|
||||
|
||||
$this->localize_data['args'] = array(
|
||||
'dev_mode' => $core->args['dev_mode'],
|
||||
'save_pending' => $save_pending,
|
||||
'reset_confirm' => $reset_all,
|
||||
'reset_section_confirm' => $reset_section,
|
||||
'preset_confirm' => $preset_confirm,
|
||||
'import_section_confirm' => $import_confirm,
|
||||
'please_wait' => esc_html__( 'Please Wait', 'redux-framework' ),
|
||||
'opt_name' => $core->args['opt_name'],
|
||||
'flyout_submenus' => isset( $core->args['pro']['flyout_submenus'] ) ? $core->args['pro']['flyout_submenus'] : false,
|
||||
'slug' => $core->args['page_slug'],
|
||||
'hints' => $core->args['hints'],
|
||||
'disable_save_warn' => $core->args['disable_save_warn'],
|
||||
'class' => $core->args['class'],
|
||||
'ajax_save' => $core->args['ajax_save'],
|
||||
'menu_search' => $pagenow . '?page=' . $core->args['page_slug'] . '&tab=',
|
||||
);
|
||||
|
||||
$this->localize_data['ajax'] = array(
|
||||
'console' => esc_html__(
|
||||
'There was an error saving. Here is the result of your action:',
|
||||
'redux-framework'
|
||||
),
|
||||
'alert' => esc_html__(
|
||||
'There was a problem with your action. Please try again or reload the page.',
|
||||
'redux-framework'
|
||||
),
|
||||
);
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$this->localize_data = apply_filters( "redux/{$core->args['opt_name']}/localize", $this->localize_data );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$this->repeater_data = apply_filters( "redux/{$core->args['opt_name']}/repeater", $this->repeater_data );
|
||||
|
||||
$this->get_warnings_and_errors_array();
|
||||
|
||||
if ( ! isset( $core->repeater_data ) ) {
|
||||
$core->repeater_data = array();
|
||||
}
|
||||
$core->repeater_data = Redux_Functions_Ex::nested_wp_parse_args(
|
||||
$this->repeater_data,
|
||||
$core->repeater_data
|
||||
);
|
||||
|
||||
if ( ! isset( $core->localize_data ) ) {
|
||||
$core->localize_data = array();
|
||||
}
|
||||
$core->localize_data = Redux_Functions_Ex::nested_wp_parse_args(
|
||||
$this->localize_data,
|
||||
$core->localize_data
|
||||
);
|
||||
|
||||
// Shim for extension compatibility.
|
||||
if ( Redux::$extension_compatibility ) {
|
||||
$this->repeater_data = Redux_Functions_Ex::nested_wp_parse_args(
|
||||
$this->repeater_data,
|
||||
$core->localize_data
|
||||
);
|
||||
}
|
||||
|
||||
wp_localize_script(
|
||||
'redux-js',
|
||||
'redux',
|
||||
$this->repeater_data
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'redux-js',
|
||||
'redux_' . str_replace( '-', '_', $core->args['opt_name'] ),
|
||||
$this->localize_data
|
||||
);
|
||||
|
||||
wp_enqueue_script( 'redux-js' ); // Enqueue the JS now.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'reduxCoreEnqueue' ) ) {
|
||||
class_alias( 'Redux_Enqueue', 'reduxCoreEnqueue' );
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Extension Abstract
|
||||
*
|
||||
* @class Redux_Extension_Abstract
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Redux_Extension_Abstract
|
||||
* An abstract class to make the writing of redux extensions easier by allowing users to extend this class
|
||||
*
|
||||
* @see the samples directory to find an usage example
|
||||
*/
|
||||
abstract class Redux_Extension_Abstract {
|
||||
/**
|
||||
* The version of the extension (This is a default value you may want to override it)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $version = '1.0.0';
|
||||
|
||||
/**
|
||||
* The extension URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extension_url;
|
||||
|
||||
/**
|
||||
* The extension dir.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extension_dir;
|
||||
|
||||
/**
|
||||
* The instance of the extension
|
||||
*
|
||||
* @var static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* The extension's file
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* The redux framework instance that spawned the extension.
|
||||
*
|
||||
* @var ReduxFramework
|
||||
*/
|
||||
public $parent;
|
||||
|
||||
/**
|
||||
* The ReflectionClass of the extension
|
||||
*
|
||||
* @var ReflectionClass
|
||||
*/
|
||||
protected $reflection_class;
|
||||
|
||||
/**
|
||||
* Redux_Extension_Abstract constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
* @param string $file Extension file.
|
||||
*/
|
||||
public function __construct( $parent, $file = '' ) {
|
||||
$this->parent = $parent;
|
||||
|
||||
// If the file is not given make sure we have one.
|
||||
if ( empty( $file ) ) {
|
||||
$file = $this->get_reflection()->getFileName();
|
||||
}
|
||||
|
||||
$this->file = $file;
|
||||
|
||||
$this->extension_dir = trailingslashit( str_replace( '\\', '/', dirname( $file ) ) );
|
||||
|
||||
$plugin_info = Redux_Functions_Ex::is_inside_plugin( $this->file );
|
||||
|
||||
if ( false !== $plugin_info ) {
|
||||
$this->extension_url = trailingslashit( dirname( $plugin_info['url'] ) );
|
||||
} else {
|
||||
$theme_info = Redux_Functions_Ex::is_inside_theme( $this->file );
|
||||
if ( false !== $theme_info ) {
|
||||
$this->extension_url = trailingslashit( dirname( $theme_info['url'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
static::$instance = $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reflection class of the extension.
|
||||
*
|
||||
* @return ReflectionClass
|
||||
*/
|
||||
protected function get_reflection() {
|
||||
if ( ! isset( $this->reflection_class ) ) {
|
||||
try {
|
||||
$this->reflection_class = new ReflectionClass( $this );
|
||||
} catch ( ReflectionException $e ) { // phpcs:ignore
|
||||
error_log( $e->getMessage() ); // phpcs:ignore
|
||||
}
|
||||
}
|
||||
|
||||
return $this->reflection_class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return extension version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_version() {
|
||||
return static::$version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extension instance.
|
||||
*
|
||||
* @return Redux_Extension_Abstract
|
||||
*/
|
||||
public static function get_instance() {
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return extension dir.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_dir() {
|
||||
return $this->extension_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extension URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_url() {
|
||||
return $this->extension_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the local field. (The use of add_field is recommended).
|
||||
*
|
||||
* @param string $field_name Name of field.
|
||||
*/
|
||||
protected function add_overload_field_filter( $field_name ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
add_filter(
|
||||
'redux/' . $this->parent->args['opt_name'] . '/field/class/' . $field_name,
|
||||
array(
|
||||
&$this,
|
||||
'overload_field_path',
|
||||
),
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the local field to the extension and register it in the builder.
|
||||
*
|
||||
* @param string $field_name Name of field.
|
||||
*/
|
||||
protected function add_field( $field_name ) {
|
||||
$class = $this->get_reflection()->getName();
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
add_filter(
|
||||
'redux/fields',
|
||||
function ( $classes ) use ( $field_name, $class ) {
|
||||
$classes[ $field_name ] = $class;
|
||||
return $classes;
|
||||
}
|
||||
);
|
||||
|
||||
$this->add_overload_field_filter( $field_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload field path.
|
||||
*
|
||||
* @param string $file Extension file.
|
||||
* @param array $field Field array.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function overload_field_path( $file, $field ) {
|
||||
$filename_fix = str_replace( '_', '-', $field['type'] );
|
||||
|
||||
$files = array(
|
||||
trailingslashit( dirname( $this->file ) ) . $field['type'] . DIRECTORY_SEPARATOR . 'field_' . $field['type'] . '.php',
|
||||
trailingslashit( dirname( $this->file ) ) . $field['type'] . DIRECTORY_SEPARATOR . 'class-redux-' . $filename_fix . '.php',
|
||||
);
|
||||
|
||||
$filename = Redux_Functions::file_exists_ex( $files );
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum version of Redux to use. Displays a notice if requirments not met.
|
||||
*
|
||||
* @param string $min_version Minimum version to evaluate.
|
||||
* @param string $extension_version Extension version number.
|
||||
* @param string $friendly_name Friend extension name for notice display.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_minimum_version( $min_version = '', $extension_version = '', $friendly_name = '' ) {
|
||||
$redux_ver = Redux_Core::$version;
|
||||
|
||||
if ( '' !== $min_version ) {
|
||||
if ( version_compare( $redux_ver, $min_version ) < 0 ) {
|
||||
// translators: %1$s Extension friendly name. %2$s: minimum Redux version.
|
||||
$msg = '<strong>' . sprintf( esc_html__( 'The %1$s extension requires Redux Framework version %2$s or higher.', 'redux-framework' ), $friendly_name, $min_version ) . '</strong> ' . esc_html__( 'You are currently running Redux Framework version ', 'redux-framework' ) . ' ' . $redux_ver . '.<br/><br/>' . esc_html__( 'This field will not render in your option panel, and featuress of this extension will not be available until the latest version of Redux Framework has been installed.', 'redux-framework' );
|
||||
|
||||
$data = array(
|
||||
'parent' => $this->parent,
|
||||
'type' => 'error',
|
||||
'msg' => $msg,
|
||||
'id' => $this->ext_name . '_notice_' . $extension_version,
|
||||
'dismiss' => false,
|
||||
);
|
||||
|
||||
if ( method_exists( 'Redux_Admin_Notices', 'set_notice' ) ) {
|
||||
Redux_Admin_Notices::set_notice( $data );
|
||||
} else {
|
||||
echo '<div class="error">';
|
||||
echo '<p>';
|
||||
echo $msg; // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Abstract_Extension' ) ) {
|
||||
class_alias( 'Redux_Extension_Abstract', 'Redux_Abstract_Extension' );
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Register Extensions for use
|
||||
*
|
||||
* @package Redux Framework/Classes
|
||||
* @since 3.0.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Extensions', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Extensions
|
||||
*/
|
||||
class Redux_Extensions extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_Extensions constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework object pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class load functions.
|
||||
*
|
||||
* @throws ReflectionException For fallback.
|
||||
*/
|
||||
private function load() {
|
||||
$core = $this->core();
|
||||
|
||||
$max = 1;
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$max = 2;
|
||||
}
|
||||
|
||||
for ( $i = 1; $i <= $max; $i ++ ) {
|
||||
$path = Redux_Core::$dir . 'inc/extensions/';
|
||||
|
||||
if ( 2 === $i ) {
|
||||
$path = Redux_Pro::$dir . 'core/inc/extensions/';
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$path = apply_filters( 'redux/' . $core->args['opt_name'] . '/extensions/dir', $path );
|
||||
|
||||
/**
|
||||
* Action 'redux/extensions/before'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/extensions/before', $core );
|
||||
|
||||
/**
|
||||
* Action 'redux/extensions/{opt_name}/before'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/extensions/{$core->args['opt_name']}/before", $core );
|
||||
|
||||
if ( isset( $core->old_opt_name ) && null !== $core->old_opt_name ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/extensions/' . $core->old_opt_name . '/before', $core );
|
||||
}
|
||||
|
||||
require_once Redux_Core::$dir . 'inc/classes/class-redux-extension-abstract.php';
|
||||
|
||||
$path = untrailingslashit( $path );
|
||||
|
||||
// Backwards compatibility for extensions.
|
||||
$instance_extensions = Redux::get_extensions( $core->args['opt_name'], '' );
|
||||
if ( ! empty( $instance_extensions ) ) {
|
||||
foreach ( $instance_extensions as $name => $extension ) {
|
||||
if ( ! isset( $core->extensions[ $name ] ) ) {
|
||||
if ( class_exists( 'ReduxFramework_Extension_' . $name ) ) {
|
||||
$a = new ReflectionClass( 'ReduxFramework_Extension_' . $name );
|
||||
Redux::set_extensions( $core->args['opt_name'], dirname( $a->getFileName() ), true );
|
||||
}
|
||||
}
|
||||
if ( ! isset( $core->extensions[ $name ] ) ) {
|
||||
/* translators: %s is the name of an extension */
|
||||
$msg = '<strong>' . sprintf( esc_html__( 'The `%s` extension was not located properly', 'redux-framework' ), $name ) . '</strong>';
|
||||
$data = array(
|
||||
'parent' => $this->parent,
|
||||
'type' => 'error',
|
||||
'msg' => $msg,
|
||||
'id' => $name . '_notice_',
|
||||
'dismiss' => false,
|
||||
);
|
||||
if ( method_exists( 'Redux_Admin_Notices', 'set_notice' ) ) {
|
||||
Redux_Admin_Notices::set_notice( $data );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( ! is_subclass_of( $core->extensions[ $name ], 'Redux_Extension_Abstract' ) ) {
|
||||
$ext_class = get_class( $core->extensions[ $name ] );
|
||||
$new_class_name = $ext_class . '_extended';
|
||||
Redux::$extension_compatibility = true;
|
||||
$core->extensions[ $name ] = Redux_Functions_Ex::extension_compatibility( $core, $extension['path'], $ext_class, $new_class_name, $name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Redux::set_extensions( $core->args['opt_name'], $path, true );
|
||||
|
||||
/**
|
||||
* Action 'redux/extensions/{opt_name}'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/extensions/{$core->args['opt_name']}", $core );
|
||||
|
||||
if ( isset( $core->old_opt_name ) && null !== $core->old_opt_name ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/extensions/' . $core->old_opt_name, $core );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Field Class
|
||||
*
|
||||
* @class Redux_Field
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Redux_Descriptor_Types as RDT; // TODO Require instead!
|
||||
|
||||
if ( ! class_exists( 'Redux_Field', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Field
|
||||
*/
|
||||
abstract class Redux_Field {
|
||||
|
||||
/**
|
||||
* Array of descriptors.
|
||||
*
|
||||
* @var Redux_Descriptor[]
|
||||
*/
|
||||
public static $descriptors = array();
|
||||
|
||||
/**
|
||||
* Make base descriptor.
|
||||
*
|
||||
* @return Redux_Descriptor
|
||||
*/
|
||||
public static function make_base_descriptor() {
|
||||
$d = new Redux_Descriptor( get_called_class() );
|
||||
self::$descriptors[ get_called_class() ] = $d;
|
||||
|
||||
$d->add_field( 'id', __( 'Field ID', 'redux-framework' ), RDT::TEXT )->set_order( 0 )->set_required();
|
||||
$d->add_field( 'title', __( 'Title', 'redux-framework' ), RDT::TEXT, '' )->set_order( 1 );
|
||||
$d->add_field( 'subtitle', __( 'Subtitle', 'redux-framework' ), RDT::TEXT, '' )->set_order( 2 );
|
||||
$d->add_field( 'desc', __( 'Description', 'redux-framework' ), RDT::TEXT, '' )->set_order( 3 );
|
||||
$d->add_field( 'class', __( 'Class', 'redux-framework' ), RDT::TEXT, '' )->set_order( 3 );
|
||||
$d->add_field( 'compiler', __( 'Compiler', 'redux-framework' ), RDT::BOOL, '', false )->set_order( 60 );
|
||||
$d->add_field( 'default', __( 'Default', 'redux-framework' ), RDT::OPTIONS, '', false )->set_order( 60 );
|
||||
$d->add_field( 'disabled', __( 'Disabled', 'redux-framework' ), RDT::BOOL, '', false )->set_order( 60 );
|
||||
$d->add_field( 'hint', __( 'Hint', 'redux-framework' ), RDT::OPTIONS, '', false )->set_order( 60 );
|
||||
$d->add_field( 'hint', __( 'Permissions', 'redux-framework' ), RDT::OPTIONS, '', false )->set_order( 60 );
|
||||
$d->add_field( 'required', __( 'Required', 'redux-framework' ), RDT::BOOL, '', false )->set_order( 60 );
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an attribute array into an html attributes string.
|
||||
*
|
||||
* @param array $attributes HTML attributes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function render_attributes( $attributes = array() ) {
|
||||
$output = '';
|
||||
|
||||
if ( empty( $attributes ) ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
foreach ( $attributes as $key => $value ) {
|
||||
if ( false === $value || '' === $value ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$value = wp_json_encode( $value );
|
||||
}
|
||||
|
||||
$output .= sprintf( true === $value ? ' %s' : ' %s="%s"', $key, esc_attr( $value ) );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get descriptor.
|
||||
*
|
||||
* @return Redux_Descriptor
|
||||
*/
|
||||
public static function get_descriptor() {
|
||||
if ( ! isset( static::$descriptors[ get_called_class() ] ) ) {
|
||||
static::make_descriptor();
|
||||
}
|
||||
|
||||
$d = self::$descriptors[ get_called_class() ];
|
||||
|
||||
static::make_descriptor();
|
||||
|
||||
// This part is out of opt name because it's non vendor dependant!
|
||||
return apply_filters( 'redux/field/' . $d->get_field_type() . '/get_descriptor', $d ); // phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the field descriptor in this function.
|
||||
*/
|
||||
public static function make_descriptor() {
|
||||
static::make_base_descriptor();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CSS styling per field output/compiler.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $style = null;
|
||||
|
||||
/**
|
||||
* Class dir.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $dir = null;
|
||||
|
||||
/**
|
||||
* Class URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $url = null;
|
||||
|
||||
/**
|
||||
* Timestamp for ver append in dev_mode
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $timestamp = null;
|
||||
|
||||
/**
|
||||
* ReduxFramework object pointer.
|
||||
*
|
||||
* @var ReduxFramework
|
||||
*/
|
||||
public $parent;
|
||||
|
||||
/**
|
||||
* Field values.
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Redux_Field constructor.
|
||||
*
|
||||
* @param array $field Field array.
|
||||
* @param string $value Field values.
|
||||
* @param null $parent ReduxFramework object pointer.
|
||||
*
|
||||
* @throws ReflectionException Comment.
|
||||
*/
|
||||
public function __construct( $field = array(), $value = null, $parent = null ) {
|
||||
$this->parent = $parent;
|
||||
$this->field = $field;
|
||||
$this->value = $value;
|
||||
|
||||
$this->select2_config = array(
|
||||
'width' => 'resolve',
|
||||
'allowClear' => false,
|
||||
'theme' => 'default',
|
||||
);
|
||||
|
||||
$this->set_defaults();
|
||||
|
||||
$class_name = get_class( $this );
|
||||
$reflector = new ReflectionClass( $class_name );
|
||||
$path = $reflector->getFilename();
|
||||
$path_info = Redux_Helpers::path_info( $path );
|
||||
$this->dir = trailingslashit( dirname( $path_info['real_path'] ) );
|
||||
$this->url = trailingslashit( dirname( $path_info['url'] ) );
|
||||
|
||||
$this->timestamp = Redux_Core::$version;
|
||||
if ( $parent->args['dev_mode'] ) {
|
||||
$this->timestamp .= '.' . time();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive dirname.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_dir() {
|
||||
return $this->dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Media query compiler for Redux Pro,
|
||||
*
|
||||
* @param string $style_data CSS string.
|
||||
*/
|
||||
public function media_query( $style_data = '' ) {
|
||||
$query_arr = $this->field['media_query'];
|
||||
$css = '';
|
||||
|
||||
if ( isset( $query_arr['queries'] ) ) {
|
||||
foreach ( $query_arr['queries'] as $idx => $query ) {
|
||||
$rule = isset( $query['rule'] ) ? $query['rule'] : '';
|
||||
$selectors = isset( $query['selectors'] ) ? $query['selectors'] : array();
|
||||
|
||||
if ( ! is_array( $selectors ) && '' !== $selectors ) {
|
||||
$selectors = array( $selectors );
|
||||
}
|
||||
|
||||
if ( '' !== $rule && ! empty( $selectors ) ) {
|
||||
$selectors = implode( ',', $selectors );
|
||||
|
||||
$css .= '@media ' . $rule . '{';
|
||||
$css .= $selectors . '{' . $style_data . '}';
|
||||
$css .= '}';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $query_arr['output'] ) && $query_arr['output'] ) {
|
||||
$this->parent->outputCSS .= $css;
|
||||
}
|
||||
|
||||
if ( isset( $query_arr['compiler'] ) && $query_arr['compiler'] ) {
|
||||
$this->parent->compilerCSS .= $css;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS for field output, if set.
|
||||
*
|
||||
* @param string $style CSS string.
|
||||
*/
|
||||
public function output( $style = '' ) {
|
||||
if ( '' !== $style ) {
|
||||
|
||||
// Force output value into an array.
|
||||
if ( isset( $this->field['output'] ) && ! is_array( $this->field['output'] ) ) {
|
||||
$this->field['output'] = array( $this->field['output'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->field['output'] ) && is_array( $this->field['output'] ) ) {
|
||||
$keys = implode( ',', $this->field['output'] );
|
||||
$this->parent->outputCSS .= $keys . '{' . $style . '}';
|
||||
}
|
||||
|
||||
// Force compiler value into an array.
|
||||
if ( isset( $this->field['compiler'] ) && ! is_array( $this->field['compiler'] ) ) {
|
||||
$this->field['compiler'] = array( $this->field['compiler'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->field['compiler'] ) && is_array( $this->field['compiler'] ) ) {
|
||||
$keys = implode( ',', $this->field['compiler'] );
|
||||
$this->parent->compilerCSS .= $keys . '{' . $style . '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unused for now.
|
||||
*
|
||||
* @param string $data CSS data.
|
||||
*/
|
||||
public function css_style( $data ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unused for now.
|
||||
*/
|
||||
public function set_defaults() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unused for now.
|
||||
*/
|
||||
public function render() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unused for now.
|
||||
*/
|
||||
public function enqueue() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unused for now.
|
||||
*
|
||||
* @param array $field Field array.
|
||||
* @param string $value Value array.
|
||||
*/
|
||||
public function localize( $field, $value = '' ) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,547 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Framework Private Extended Functions Container Class
|
||||
*
|
||||
* @class Redux_Functions_Ex
|
||||
* @since 3.0.0
|
||||
* @package Redux_Framework/Classes
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Functions_Ex', false ) ) {
|
||||
|
||||
/**
|
||||
* Redux Functions Class
|
||||
* Class of useful functions that can/should be shared among all Redux files.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class Redux_Functions_Ex {
|
||||
|
||||
/**
|
||||
* What is this for?
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $args;
|
||||
|
||||
/**
|
||||
* Parses the string into variables without the max_input_vars limitation.
|
||||
*
|
||||
* @since 3.5.7.11
|
||||
*
|
||||
* @param string $string String of data.
|
||||
*
|
||||
* @return array|false $result
|
||||
* @author harunbasic
|
||||
* @access private
|
||||
*/
|
||||
public static function parse_str( $string ) {
|
||||
if ( '' === $string ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
$pairs = explode( '&', $string );
|
||||
|
||||
foreach ( $pairs as $key => $pair ) {
|
||||
// use the original parse_str() on each element.
|
||||
parse_str( $pair, $params );
|
||||
|
||||
$k = key( $params );
|
||||
|
||||
if ( ! isset( $result[ $k ] ) ) {
|
||||
$result += $params;
|
||||
} elseif ( is_array( $result[ $k ] ) && is_array( $params[ $k ] ) ) {
|
||||
$result[ $k ] = self::array_merge_recursive_distinct( $result[ $k ], $params[ $k ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge arrays without converting values with duplicate keys to arrays as array_merge_recursive does.
|
||||
* As seen here http://php.net/manual/en/function.array-merge-recursive.php#92195
|
||||
*
|
||||
* @since 3.5.7.11
|
||||
*
|
||||
* @param array $array1 array one.
|
||||
* @param array $array2 array two.
|
||||
*
|
||||
* @return array $merged
|
||||
* @author harunbasic
|
||||
* @access private
|
||||
*/
|
||||
public static function array_merge_recursive_distinct( array $array1, array $array2 ) {
|
||||
$merged = $array1;
|
||||
|
||||
foreach ( $array2 as $key => $value ) {
|
||||
|
||||
if ( is_array( $value ) && isset( $merged[ $key ] ) && is_array( $merged[ $key ] ) ) {
|
||||
$merged[ $key ] = self::array_merge_recursive_distinct( $merged[ $key ], $value );
|
||||
} elseif ( is_numeric( $key ) && isset( $merged[ $key ] ) ) {
|
||||
$merged[] = $value;
|
||||
} else {
|
||||
$merged[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records calling function.
|
||||
*
|
||||
* @param string $opt_name Panel opt_name.
|
||||
*/
|
||||
public static function record_caller( $opt_name = '' ) {
|
||||
global $pagenow;
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification
|
||||
if ( ! ( 'tools.php' === $pagenow && isset( $_GET['page'] ) && ( 'redux-framework' === $_GET['page'] || 'health-check' === $_GET['page'] ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
||||
$caller = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 )[1]['file'];
|
||||
|
||||
if ( ! empty( $caller ) && ! empty( $opt_name ) && class_exists( 'Redux_Core' ) ) {
|
||||
if ( ! isset( Redux_Core::$callers[ $opt_name ] ) ) {
|
||||
Redux_Core::$callers[ $opt_name ] = array();
|
||||
}
|
||||
|
||||
if ( strpos( $caller, 'class-redux-' ) !== false || strpos( $caller, 'redux-core/framework.php' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! in_array( $caller, Redux_Core::$callers[ $opt_name ], true ) ) {
|
||||
Redux_Core::$callers[ $opt_name ][] = $caller;
|
||||
}
|
||||
|
||||
if ( ! empty( self::$args[ $opt_name ]['callers'] ) && ! in_array( $caller, self::$args[ $opt_name ]['callers'], true ) ) {
|
||||
self::$args[ $opt_name ]['callers'][] = $caller;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize path.
|
||||
*
|
||||
* @param string $path Path to normalize.
|
||||
*
|
||||
* @return mixed|null|string|string[]
|
||||
*/
|
||||
public static function wp_normalize_path( $path = '' ) {
|
||||
if ( function_exists( 'wp_normalize_path' ) ) {
|
||||
$path = wp_normalize_path( $path );
|
||||
} else {
|
||||
// Shim for pre WP 3.9.
|
||||
$path = str_replace( '\\', '/', $path );
|
||||
$path = preg_replace( '|(?<=.)/+|', '/', $path );
|
||||
|
||||
if ( ':' === substr( $path, 1, 1 ) ) {
|
||||
$path = ucfirst( $path );
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to add generator tag to page HEAD.
|
||||
*/
|
||||
public static function generator() {
|
||||
add_action( 'wp_head', array( 'Redux_Functions_Ex', 'meta_tag' ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for wp_head hook to add meta tag.
|
||||
*/
|
||||
public static function meta_tag() {
|
||||
echo '<meta name="framework" content="Redux ' . esc_html( Redux_Core::$version ) . '" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run URL through a ssl check.
|
||||
*
|
||||
* @param string $url URL to check.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function verify_url_protocol( $url ) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
||||
$protocol = ! empty( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'] || ( ! empty( $_SERVER['SERVER_PORT'] ) && 443 === $_SERVER['SERVER_PORT'] ) ? 'https://' : 'http://';
|
||||
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
||||
$new_protocol = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) . '://'; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
||||
if ( 'http://' === $protocol && $new_protocol !== $protocol && false === strpos( $url, $new_protocol ) ) {
|
||||
$url = str_replace( $protocol, $new_protocol, $url );
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check s.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.0.0
|
||||
* @return bool
|
||||
*/
|
||||
public static function s() {
|
||||
if ( ! empty( get_option( 'redux_p' . 'ro_lic' . 'ense_key', false ) ) ) { // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found
|
||||
$s = get_option( 'redux_p' . 'ro_l' . 'icense_status', false ); // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found
|
||||
if ( ! empty( $s ) && in_array( $s, array( 'valid', 'site_inactive' ), true ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is file in theme.
|
||||
*
|
||||
* @param string $file File to check.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function file_in_theme( $file ) {
|
||||
if ( strpos( dirname( $file ), get_template_directory() ) !== false ) {
|
||||
return true;
|
||||
} elseif ( strpos( dirname( $file ), get_stylesheet_directory() ) !== false ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Redux embedded inside a plugin.
|
||||
*
|
||||
* @param string $file File to check.
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function is_inside_plugin( $file ) {
|
||||
$file = self::wp_normalize_path( $file );
|
||||
$plugin_basename = self::wp_normalize_path( plugin_basename( $file ) );
|
||||
|
||||
if ( self::file_in_theme( $file ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $plugin_basename !== $file ) {
|
||||
$slug = explode( '/', $plugin_basename );
|
||||
$slug = $slug[0];
|
||||
|
||||
$data = array(
|
||||
'slug' => $slug,
|
||||
'basename' => $plugin_basename,
|
||||
'path' => $file,
|
||||
'url' => self::verify_url_protocol( plugins_url( $plugin_basename ) ),
|
||||
'real_path' => self::wp_normalize_path( dirname( realpath( $file ) ) ),
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Redux embedded in a theme.
|
||||
*
|
||||
* @param string $file File to check.
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function is_inside_theme( $file = '' ) {
|
||||
|
||||
if ( ! self::file_in_theme( $file ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$theme_paths = array(
|
||||
self::wp_normalize_path( get_template_directory() ) => get_template_directory_uri(),
|
||||
// parent.
|
||||
self::wp_normalize_path( get_stylesheet_directory() ) => get_stylesheet_directory_uri(),
|
||||
// child.
|
||||
);
|
||||
|
||||
$theme_paths = array_unique( $theme_paths );
|
||||
$file_path = self::wp_normalize_path( $file );
|
||||
|
||||
$filename = explode( '\\', $file );
|
||||
|
||||
end( $filename );
|
||||
|
||||
$filename = prev( $filename );
|
||||
|
||||
foreach ( $theme_paths as $theme_path => $url ) {
|
||||
$real_path = self::wp_normalize_path( realpath( $theme_path ) );
|
||||
|
||||
if ( empty( $real_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! empty( $real_path ) && strpos( $file_path, $real_path ) !== false ) {
|
||||
$slug = explode( '/', $theme_path );
|
||||
$slug = end( $slug );
|
||||
$relative_path = explode( $slug . '/', dirname( $file_path ) );
|
||||
$relative_path = $relative_path[1];
|
||||
$data = array(
|
||||
'slug' => $slug,
|
||||
'path' => trailingslashit( trailingslashit( $theme_path ) . $relative_path ) . $filename,
|
||||
'real_path' => trailingslashit( trailingslashit( $real_path ) . $relative_path ) . $filename,
|
||||
'url' => self::verify_url_protocol( trailingslashit( trailingslashit( $url ) . $relative_path ) . $filename ),
|
||||
'basename' => trailingslashit( $slug ) . trailingslashit( $relative_path ) . $filename,
|
||||
);
|
||||
$data['realpath'] = $data['real_path']; // Shim for old extensions.
|
||||
|
||||
if ( count( $theme_paths ) > 1 ) {
|
||||
$key = array_search( $theme_path, $theme_paths, true );
|
||||
|
||||
if ( false !== $key ) {
|
||||
unset( $theme_paths[ $key ] );
|
||||
}
|
||||
|
||||
$data['parent_slug'] = end( explode( '/', end( $theme_paths ) ) );
|
||||
$data['parent_slug'] = end( explode( '/', end( $theme_paths ) ) );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to fix 3.x and 4 compatibility for extensions
|
||||
*
|
||||
* @param object $parent The extension parent object.
|
||||
* @param string $path - Path of the file.
|
||||
* @param string $ext_class - Extension class name.
|
||||
* @param string $new_class_name - New dynamic class name.
|
||||
* @param string $name extension name.
|
||||
*
|
||||
* @return object - Extended field class.
|
||||
*/
|
||||
public static function extension_compatibility( $parent, $path, $ext_class, $new_class_name, $name ) {
|
||||
if ( empty( $new_class_name ) ) {
|
||||
return;
|
||||
}
|
||||
$upload_dir = ReduxFramework::$_upload_dir . '/extension_compatibility/';
|
||||
if ( ! file_exists( $upload_dir . $ext_class . '.php' ) ) {
|
||||
if ( ! is_dir( $upload_dir ) ) {
|
||||
$parent->filesystem->mkdir( $upload_dir );
|
||||
$parent->filesystem->put_contents( $upload_dir . 'index.php', '<?php // Silence is golden.' );
|
||||
}
|
||||
if ( ! class_exists( $ext_class ) ) {
|
||||
require_once $path;
|
||||
}
|
||||
if ( ! file_exists( $upload_dir . $new_class_name . '.php' ) ) {
|
||||
$class_file = '<?php' . PHP_EOL . PHP_EOL .
|
||||
'class {{ext_class}} extends Redux_Extension_Abstract {' . PHP_EOL .
|
||||
' private $c;' . PHP_EOL .
|
||||
' public function __construct( $parent, $path, $ext_class ) {' . PHP_EOL .
|
||||
' $this->c = $parent->extensions[\'' . $name . '\'];' . PHP_EOL .
|
||||
' // Add all the params of the Abstract to this instance.' . PHP_EOL .
|
||||
' foreach( get_object_vars( $this->c ) as $key => $value ) {' . PHP_EOL .
|
||||
' $this->$key = $value;' . PHP_EOL .
|
||||
' }' . PHP_EOL .
|
||||
' parent::__construct( $parent, $path );' . PHP_EOL .
|
||||
' }' . PHP_EOL .
|
||||
' // fake "extends Redux_Extension_Abstract\" using magic function' . PHP_EOL .
|
||||
' public function __call( $method, $args ) {' . PHP_EOL .
|
||||
' return call_user_func_array( array( $this->c, $method ), $args );' . PHP_EOL .
|
||||
' }' . PHP_EOL .
|
||||
'}' . PHP_EOL;
|
||||
$template = str_replace( '{{ext_class}}', $new_class_name, $class_file );
|
||||
$parent->filesystem->put_contents( $upload_dir . $new_class_name . '.php', $template );
|
||||
}
|
||||
if ( file_exists( $upload_dir . $new_class_name . '.php' ) ) {
|
||||
if ( ! class_exists( $new_class_name ) ) {
|
||||
require_once $upload_dir . $new_class_name . '.php';
|
||||
}
|
||||
if ( class_exists( $new_class_name ) ) {
|
||||
return new $new_class_name( $parent, $path, $ext_class );
|
||||
}
|
||||
} else {
|
||||
// Why doesn't the file exist? Gah permissions.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to deep merge two arrays.
|
||||
*
|
||||
* @param array $a First array to deep merge.
|
||||
* @param array $b Second array to deep merge.
|
||||
*
|
||||
* @return array - Deep merge of the two arrays.
|
||||
*/
|
||||
public static function nested_wp_parse_args( &$a, $b ) {
|
||||
$a = (array) $a;
|
||||
$b = (array) $b;
|
||||
$result = $b;
|
||||
foreach ( $a as $k => &$v ) {
|
||||
if ( is_array( $v ) && isset( $result[ $k ] ) ) {
|
||||
$result[ $k ] = self::nested_wp_parse_args( $v, $result[ $k ] );
|
||||
} else {
|
||||
$result[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback key
|
||||
*/
|
||||
public static function hash_key() {
|
||||
$key = '';
|
||||
$key .= defined( 'AUTH_KEY' ) ? AUTH_KEY : get_site_url();
|
||||
$key .= defined( 'SECURE_AUTH_KEY' ) ? SECURE_AUTH_KEY : '';
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Redux is activated.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function activated() {
|
||||
if ( Redux_Core::$insights->tracking_allowed() ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Redux to activated.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function set_activated() {
|
||||
Redux_Core::$insights->optin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Redux to deactivated.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function set_deactivated() {
|
||||
Redux_Core::$insights->optout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a class path to be autoloaded.
|
||||
*
|
||||
* Registers a namespace to be autoloaded from a given path, using the
|
||||
* WordPress/HM-style filenames (`class-{name}.php`).
|
||||
*
|
||||
* @link https://engineering.hmn.md/standards/style/php/#file-naming
|
||||
*
|
||||
* @param string $prefix Prefix to autoload from.
|
||||
* @param string $path Path to validate.
|
||||
*/
|
||||
public static function register_class_path( $prefix = '', $path = '' ) {
|
||||
if ( ! class_exists( 'Redux_Autoloader' ) ) {
|
||||
require_once Redux_Path::get_path( '/inc/classes/class-redux-autoloader.php' );
|
||||
}
|
||||
$loader = new Redux_Autoloader( $prefix, $path );
|
||||
spl_autoload_register( array( $loader, 'load' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string starts with a string.
|
||||
*
|
||||
* @param string $haystack Full string.
|
||||
* @param string $needle String to check if it starts with.
|
||||
* @return string
|
||||
*/
|
||||
public static function string_starts_with( $haystack, $needle ) {
|
||||
$length = strlen( $needle );
|
||||
return substr( $haystack, 0, $length ) === $needle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string ends with a string.
|
||||
*
|
||||
* @param string $haystack Full string.
|
||||
* @param string $needle String to check if it starts with.
|
||||
* @return string
|
||||
*/
|
||||
public static function string_ends_with( $haystack, $needle ) {
|
||||
$length = strlen( $needle );
|
||||
if ( ! $length ) {
|
||||
return true;
|
||||
}
|
||||
return substr( $haystack, -$length ) === $needle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url where the Admin Columns website is hosted
|
||||
*
|
||||
* @param string $path Path to add to url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function get_site_url( $path = '' ) {
|
||||
$url = 'https://redux.io';
|
||||
|
||||
if ( ! empty( $path ) ) {
|
||||
$url .= '/' . trim( $path, '/' ) . '/';
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Url with utm tags
|
||||
*
|
||||
* @param string $path Path on site.
|
||||
* @param string $utm_medium Medium var.
|
||||
* @param string $utm_content Content var.
|
||||
* @param bool $utm_campaign Campaign var.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_utm_url( $path, $utm_medium, $utm_content = null, $utm_campaign = false ) {
|
||||
$url = self::get_site_url( $path );
|
||||
|
||||
if ( ! $utm_campaign ) {
|
||||
$utm_campaign = 'plugin-installation';
|
||||
}
|
||||
|
||||
$args = array(
|
||||
// Referrer: plugin.
|
||||
'utm_source' => 'plugin-installation',
|
||||
|
||||
// Specific promotions or sales.
|
||||
'utm_campaign' => $utm_campaign,
|
||||
|
||||
// Marketing medium: banner, documentation or email.
|
||||
'utm_medium' => $utm_medium,
|
||||
|
||||
// Used for differentiation of medium.
|
||||
'utm_content' => $utm_content,
|
||||
);
|
||||
|
||||
$args = array_map( 'sanitize_key', array_filter( $args ) );
|
||||
|
||||
return add_query_arg( $args, $url );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Framework Private Functions Container Class
|
||||
*
|
||||
* @class Redux_Functions
|
||||
* @package Redux_Framework/Classes
|
||||
* @since 3.0.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Functions', false ) ) {
|
||||
|
||||
/**
|
||||
* Redux Functions Class
|
||||
* Class of useful functions that can/should be shared among all Redux files.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class Redux_Functions {
|
||||
|
||||
/**
|
||||
* ReduxFramework object pointer.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static $parent;
|
||||
|
||||
/**
|
||||
* ReduxFramework shim object pointer.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static $_parent; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
|
||||
|
||||
/**
|
||||
* Check for existence of class name via array of class names.
|
||||
*
|
||||
* @param array $class_names Array of class names.
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function class_exists_ex( $class_names = array() ) {
|
||||
foreach ( $class_names as $class_name ) {
|
||||
if ( class_exists( $class_name ) ) {
|
||||
return $class_name;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for existence of file name via array of file names.
|
||||
*
|
||||
* @param array $file_names Array of file names.
|
||||
* @return string|bool
|
||||
*/
|
||||
public static function file_exists_ex( $file_names = array() ) {
|
||||
foreach ( $file_names as $file_name ) {
|
||||
if ( file_exists( $file_name ) ) {
|
||||
return $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Extract data:
|
||||
* $field = field_array
|
||||
* $value = field values
|
||||
* $core = Redux instance
|
||||
* $mode = pro field init mode */
|
||||
|
||||
/**
|
||||
* Load fields from Redux Pro.
|
||||
*
|
||||
* @param array $data Pro field data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function load_pro_field( $data ) {
|
||||
// phpcs:ignore WordPress.PHP.DontExtract
|
||||
extract( $data );
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$field_type = str_replace( '_', '-', $field['type'] );
|
||||
|
||||
$field_filter = Redux_Pro::$dir . 'core/inc/fields/' . $field['type'] . '/class-redux-pro-' . $field_type . '.php';
|
||||
|
||||
if ( file_exists( $field_filter ) ) {
|
||||
require_once $field_filter;
|
||||
|
||||
$filter_class_name = 'Redux_Pro_' . $field['type'];
|
||||
|
||||
if ( class_exists( $filter_class_name ) ) {
|
||||
$extend = new $filter_class_name( $field, $value, $core );
|
||||
$extend->init( $mode );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse args to handle deep arrays. The WP one does not.
|
||||
*
|
||||
* @param array $args Array of args.
|
||||
* @param string $defaults Defaults array.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public static function parse_args( $args, $defaults = '' ) {
|
||||
$args = (array) $args;
|
||||
$defaults = (array) $defaults;
|
||||
|
||||
$result = $defaults;
|
||||
|
||||
foreach ( $args as $k => &$v ) {
|
||||
if ( is_array( $v ) && isset( $result[ $k ] ) ) {
|
||||
$result[ $k ] = self::parse_args( $v, $result[ $k ] );
|
||||
} else {
|
||||
$result[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: Return min tag for JS and CSS files in dev_mode.
|
||||
*
|
||||
* @deprecated No longer using camelCase naming conventions.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function isMin() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
|
||||
return self::is_min();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return min tag for JS and CSS files in dev_mode.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function is_min() {
|
||||
$min = '.min';
|
||||
$dev_mode = false;
|
||||
|
||||
$instances = Redux::all_instances();
|
||||
|
||||
if ( ! empty( $instances ) ) {
|
||||
foreach ( $instances as $opt_name => $instance ) {
|
||||
|
||||
if ( empty( self::$parent ) ) {
|
||||
self::$parent = $instance;
|
||||
self::$_parent = self::$parent;
|
||||
}
|
||||
if ( ! empty( $instance->args['dev_mode'] ) ) {
|
||||
$dev_mode = true;
|
||||
self::$parent = $instance;
|
||||
self::$_parent = self::$parent;
|
||||
}
|
||||
}
|
||||
if ( $dev_mode ) {
|
||||
$min = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a cookie.
|
||||
* Do nothing if unit testing.
|
||||
*
|
||||
* @since 3.5.4
|
||||
* @access public
|
||||
* @return void
|
||||
*
|
||||
* @param string $name The cookie name.
|
||||
* @param string $value The cookie value.
|
||||
* @param integer $expire Expiry time.
|
||||
* @param string $path The cookie path.
|
||||
* @param string $domain The cookie domain.
|
||||
* @param boolean $secure HTTPS only.
|
||||
* @param boolean $httponly Only set cookie on HTTP calls.
|
||||
*/
|
||||
public static function set_cookie( $name, $value, $expire, $path, $domain = null, $secure = false, $httponly = false ) {
|
||||
if ( ! defined( 'WP_TESTS_DOMAIN' ) ) {
|
||||
setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSS from output/compiler array
|
||||
*
|
||||
* @since 3.2.8
|
||||
* @access private
|
||||
*
|
||||
* @param array $css_array CSS data.
|
||||
* @param string $style CSS style.
|
||||
* @param string $value CSS values.
|
||||
*
|
||||
* @return string CSS string
|
||||
*/
|
||||
public static function parse_css( $css_array = array(), $style = '', $value = '' ) {
|
||||
|
||||
// Something wrong happened.
|
||||
if ( 0 === count( $css_array ) ) {
|
||||
return '';
|
||||
} else {
|
||||
$css = '';
|
||||
|
||||
foreach ( $css_array as $element => $selector ) {
|
||||
|
||||
// The old way.
|
||||
if ( 0 === $element ) {
|
||||
$css = self::the_old_way( $css_array, $style );
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
// New way continued.
|
||||
$css_style = $element . ':' . $value . ';';
|
||||
|
||||
$css .= $selector . '{' . $css_style . '}';
|
||||
}
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSS shim.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $css_array CSS data.
|
||||
* @param string $style CSS style.
|
||||
* @param string $value CSS values.
|
||||
*
|
||||
* @return string CSS string
|
||||
*/
|
||||
public static function parseCSS( $css_array = array(), $style = '', $value = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
|
||||
return self::parse_css( $css_array, $style, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSS the old way, without mode options.
|
||||
*
|
||||
* @param array $css_array CSS data.
|
||||
* @param string $style CSS style.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function the_old_way( $css_array, $style ) {
|
||||
$keys = implode( ',', $css_array );
|
||||
$css = $keys . '{' . $style . '}';
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return s.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.0.0
|
||||
* @return string
|
||||
*/
|
||||
public static function gs() {
|
||||
return get_option( 're' . 'dux_p' . 'ro_lic' . 'ense_key', '' ); // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated Initialized the WordPress filesystem, if it already isn't.
|
||||
*
|
||||
* @since 3.2.3
|
||||
* @access public
|
||||
* @deprecated NO longer using camelCase naming conventions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function initWpFilesystem() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
|
||||
self::init_wp_filesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialized the WordPress filesystem, if it already isn't.
|
||||
*
|
||||
* @since 3.2.3
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init_wp_filesystem() {
|
||||
global $wp_filesystem;
|
||||
|
||||
// Initialize the WordPress filesystem, no more using file_put_contents function.
|
||||
if ( empty( $wp_filesystem ) ) {
|
||||
require_once ABSPATH . '/wp-includes/pluggable.php';
|
||||
require_once ABSPATH . '/wp-admin/includes/file.php';
|
||||
|
||||
WP_Filesystem();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TRU.
|
||||
*
|
||||
* @param string $string .
|
||||
* @param string $opt_name .
|
||||
*
|
||||
* @return mixed|string|void
|
||||
*/
|
||||
public static function tru( $string, $opt_name ) {
|
||||
$redux = Redux::instance( $opt_name );
|
||||
|
||||
$check = get_user_option( 'r_tru_u_x', array() );
|
||||
|
||||
if ( ! empty( $check ) && ( isset( $check['expires'] ) < time() ) ) {
|
||||
$check = array();
|
||||
}
|
||||
|
||||
if ( empty( $check ) ) {
|
||||
$url = 'https://api.redux.io/status';
|
||||
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||
$check = @wp_remote_get(
|
||||
$url,
|
||||
array(
|
||||
'headers' => Redux_Helpers::get_request_headers(),
|
||||
)
|
||||
);
|
||||
|
||||
$check = json_decode( wp_remote_retrieve_body( $check ), true );
|
||||
|
||||
if ( ! empty( $check ) && isset( $check['id'] ) ) {
|
||||
if ( isset( $redux->args['dev_mode'] ) && true === $redux->args['dev_mode'] ) {
|
||||
$check['id'] = '';
|
||||
$check['expires'] = 60 * 60 * 24;
|
||||
}
|
||||
|
||||
update_user_option( get_current_user_id(), 'r_tru_u_x', $check );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $redux->args['dev_mode'] ) && true === $redux->args['dev_mode'] ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
return apply_filters( 'redux/' . $opt_name . '/aURL_filter', '<span data-id="1" class="' . $redux->core_thread . '"><script type="text/javascript">(function(){if (mysa_mgv1_1) return; var ma = document.createElement("script"); ma.type = "text/javascript"; ma.async = true; ma.src = "' . $string . '"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ma, s) })();var mysa_mgv1_1=true;</script></span>' );
|
||||
} else {
|
||||
|
||||
$check = isset( $check['id'] ) ? $check['id'] : $check;
|
||||
|
||||
if ( ! empty( $check ) ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
return apply_filters( 'redux/' . $opt_name . '/aURL_filter', '<span data-id="' . $check . '" class="' . $redux->core_thread . '"><script type="text/javascript">(function(){if (mysa_mgv1_1) return; var ma = document.createElement("script"); ma.type = "text/javascript"; ma.async = true; ma.src = "' . $string . '"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ma, s) })();var mysa_mgv1_1=true;</script></span>' );
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DAT.
|
||||
*
|
||||
* @param string $fname .
|
||||
* @param string $opt_name .
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public static function dat( $fname, $opt_name ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$name = apply_filters( 'redux/' . $opt_name . '/aDBW_filter', $fname );
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* BUB.
|
||||
*
|
||||
* @param string $fname .
|
||||
* @param string $opt_name .
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public static function bub( $fname, $opt_name ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$name = apply_filters( 'redux/' . $opt_name . '/aNF_filter', $fname );
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* YO.
|
||||
*
|
||||
* @param string $fname .
|
||||
* @param strong $opt_name .
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public static function yo( $fname, $opt_name ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$name = apply_filters( 'redux/' . $opt_name . '/aNFM_filter', $fname );
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Hash.
|
||||
*/
|
||||
public static function support_hash() {
|
||||
if ( isset( $_POST['nonce'] ) ) {
|
||||
if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux-support-hash' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
$data = get_option( 'redux_support_hash' );
|
||||
$data = wp_parse_args(
|
||||
$data,
|
||||
array(
|
||||
'check' => '',
|
||||
'identifier' => '',
|
||||
)
|
||||
);
|
||||
$generate_hash = true;
|
||||
$system_info = Redux_Helpers::compile_system_status();
|
||||
$new_hash = md5( wp_json_encode( $system_info ) );
|
||||
$return = array();
|
||||
|
||||
if ( $data['check'] === $new_hash ) {
|
||||
unset( $generate_hash );
|
||||
}
|
||||
|
||||
$post_data = array(
|
||||
'hash' => md5( network_site_url() . '-' . Redux_Core::$server['REMOTE_ADDR'] ),
|
||||
'site' => esc_url( home_url( '/' ) ),
|
||||
'tracking' => Redux_Helpers::get_statistics_object(),
|
||||
'system_status' => $system_info,
|
||||
);
|
||||
|
||||
$post_data = maybe_serialize( $post_data );
|
||||
|
||||
if ( isset( $generate_hash ) && $generate_hash ) {
|
||||
$data['check'] = $new_hash;
|
||||
$data['identifier'] = '';
|
||||
$response = wp_remote_post(
|
||||
'https://api.redux.io/support',
|
||||
array(
|
||||
'method' => 'POST',
|
||||
'timeout' => 65,
|
||||
'redirection' => 5,
|
||||
'httpversion' => '1.0',
|
||||
'blocking' => true,
|
||||
'compress' => true,
|
||||
'headers' => Redux_Helpers::get_request_headers(),
|
||||
'body' => array(
|
||||
'data' => $post_data,
|
||||
'serialize' => 1,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
echo wp_json_encode(
|
||||
array(
|
||||
'status' => 'error',
|
||||
'message' => $response->get_error_message(),
|
||||
)
|
||||
);
|
||||
|
||||
die( 1 );
|
||||
} else {
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
if ( 200 === $response_code ) {
|
||||
$response = wp_remote_retrieve_body( $response );
|
||||
$return = json_decode( $response, true );
|
||||
|
||||
if ( isset( $return['identifier'] ) ) {
|
||||
$data['identifier'] = $return['identifier'];
|
||||
update_option( 'redux_support_hash', $data );
|
||||
}
|
||||
} else {
|
||||
$response = wp_remote_retrieve_body( $response );
|
||||
|
||||
echo wp_json_encode(
|
||||
array(
|
||||
'status' => 'error',
|
||||
'message' => $response,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $data['identifier'] ) ) {
|
||||
$return['status'] = 'success';
|
||||
$return['identifier'] = $data['identifier'];
|
||||
} else {
|
||||
$return['status'] = 'error';
|
||||
$return['message'] = esc_html__( 'Support hash could not be generated. Please try again later.', 'redux-framework' );
|
||||
}
|
||||
|
||||
echo wp_json_encode( $return );
|
||||
|
||||
die( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanatize camcelCase keys in array, makes then snake_case.
|
||||
*
|
||||
* @param array $arr Array of keys.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function sanitize_camel_case_array_keys( $arr ) {
|
||||
$keys = array_keys( $arr );
|
||||
$values = array_values( $arr );
|
||||
|
||||
$result = preg_replace_callback(
|
||||
'/[A-Z]/',
|
||||
function ( $matches ) {
|
||||
return '-' . Redux_Core::strtolower( $matches[0] );
|
||||
},
|
||||
$keys
|
||||
);
|
||||
|
||||
$output = array_combine( $result, $values );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array into a html data string.
|
||||
*
|
||||
* @param array $data example input: array('id'=>'true').
|
||||
*
|
||||
* @return string $data_string example output: data-id='true'
|
||||
*/
|
||||
public static function create_data_string( $data = array() ) {
|
||||
$data_string = '';
|
||||
|
||||
foreach ( $data as $key => $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
$value = implode( '|', $value );
|
||||
}
|
||||
|
||||
$data_string .= ' data-' . $key . '=' . Redux_Helpers::make_bool_str( $value ) . '';
|
||||
}
|
||||
|
||||
return $data_string;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Load the plugin text domain for translation.
|
||||
*
|
||||
* @package Redux Framework/Classes
|
||||
* @since 3.0.5
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_I18n', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_I18n
|
||||
*/
|
||||
class Redux_I18n extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_I18n constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
* @param string $file Translation file.
|
||||
*/
|
||||
public function __construct( $parent, $file ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
$this->load( $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load translations.
|
||||
*
|
||||
* @param string $file Path to translation files.
|
||||
*/
|
||||
private function load( $file ) {
|
||||
$domain = 'redux-framework';
|
||||
|
||||
$core = $this->core();
|
||||
|
||||
/**
|
||||
* Locale for text domain
|
||||
* filter 'redux/textdomain/basepath/{opt_name}'
|
||||
*
|
||||
* @param string The locale of the blog or from the 'locale' hook
|
||||
* @param string 'redux-framework' text domain
|
||||
*/
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$locale = apply_filters( 'redux/locale', get_locale(), 'redux-framework' );
|
||||
$mofile = $domain . '-' . $locale . '.mo';
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$basepath = apply_filters( "redux/textdomain/basepath/{$core->args['opt_name']}", Redux_Core::$dir );
|
||||
|
||||
$loaded = load_textdomain( $domain, Redux_Core::$dir . 'languages/' . $mofile );
|
||||
|
||||
if ( ! $loaded ) {
|
||||
$mofile = WP_LANG_DIR . '/plugins/' . $mofile;
|
||||
|
||||
$loaded = load_textdomain( $domain, $mofile );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Framework Instance Container Class
|
||||
* Automatically captures and stores all instances
|
||||
* of ReduxFramework at instantiation.
|
||||
*
|
||||
* @package Redux_Framework/Classes
|
||||
* @subpackage Core
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Instances', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Instances
|
||||
*/
|
||||
class Redux_Instances {
|
||||
|
||||
/**
|
||||
* ReduxFramework instances
|
||||
*
|
||||
* @var ReduxFramework[]
|
||||
*/
|
||||
private static $instances;
|
||||
|
||||
/**
|
||||
* Get Instance
|
||||
* Get Redux_Instances instance
|
||||
* OR an instance of ReduxFramework by [opt_name]
|
||||
*
|
||||
* @param string|false $opt_name the defined opt_name.
|
||||
*
|
||||
* @return ReduxFramework class instance
|
||||
*/
|
||||
public static function get_instance( $opt_name = false ) {
|
||||
|
||||
if ( $opt_name && ! empty( self::$instances[ $opt_name ] ) ) {
|
||||
return self::$instances[ $opt_name ];
|
||||
}
|
||||
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shim for old get_redux_instance method.
|
||||
*
|
||||
* @param string|false $opt_name the defined opt_name.
|
||||
*
|
||||
* @return ReduxFramework class instance
|
||||
*/
|
||||
public static function get_redux_instance( $opt_name = '' ) {
|
||||
return self::get_instance( $opt_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all instantiated ReduxFramework instances (so far)
|
||||
*
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public static function get_all_instances() {
|
||||
return self::$instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redux_Instances constructor.
|
||||
*
|
||||
* @param mixed $redux_framework Is object.
|
||||
*/
|
||||
public function __construct( $redux_framework = false ) {
|
||||
if ( false !== $redux_framework ) {
|
||||
$this->store( $redux_framework );
|
||||
} else {
|
||||
add_action( 'redux/construct', array( $this, 'store' ), 5, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action hook callback.
|
||||
*
|
||||
* @param object $redux_framework Pointer.
|
||||
*/
|
||||
public function store( $redux_framework ) {
|
||||
if ( $redux_framework instanceof ReduxFramework ) {
|
||||
$key = $redux_framework->args['opt_name'];
|
||||
self::$instances[ $key ] = $redux_framework;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'ReduxFrameworkInstances' ) ) {
|
||||
class_alias( 'Redux_Instances', 'ReduxFrameworkInstances' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'get_redux_instance' ) ) {
|
||||
/**
|
||||
* Shim function that some theme oddly used.
|
||||
*
|
||||
* @param string|false $opt_name the defined opt_name.
|
||||
*
|
||||
* @return ReduxFramework class instance
|
||||
*/
|
||||
function get_redux_instance( $opt_name ) {
|
||||
return Redux_Instances::get_instance( $opt_name );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'get_all_redux_instances' ) ) {
|
||||
/**
|
||||
* Fetch all instances of ReduxFramework
|
||||
* as an associative array.
|
||||
*
|
||||
* @return array format ['opt_name' => $ReduxFramework]
|
||||
*/
|
||||
function get_all_redux_instances() {
|
||||
return Redux_Instances::get_all_instances();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Network Class
|
||||
*
|
||||
* @class Redux_Network
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Network', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Network
|
||||
*/
|
||||
class Redux_Network extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_Network constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
if ( 'network' === $parent->args['database'] && $parent->args['network_admin'] ) {
|
||||
add_action(
|
||||
'network_admin_edit_redux_' . $parent->args['opt_name'],
|
||||
array(
|
||||
$this,
|
||||
'save_network_page',
|
||||
),
|
||||
10,
|
||||
0
|
||||
);
|
||||
|
||||
// phpcs:ignore Generic.Strings.UnnecessaryStringConcat
|
||||
add_action( 'admin' . '_bar' . '_menu', array( $this, 'network_admin_bar' ), 999 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add node to network admin bar.
|
||||
*
|
||||
* @param object $wp_admin_bar Admin bar.
|
||||
*/
|
||||
public function network_admin_bar( $wp_admin_bar ) {
|
||||
$core = $this->core();
|
||||
|
||||
$args = array(
|
||||
'id' => $core->args['opt_name'] . '_network_admin',
|
||||
'title' => $core->args['menu_title'],
|
||||
'parent' => 'network-admin',
|
||||
'href' => network_admin_url( 'settings.php' ) . '?page=' . $core->args['page_slug'],
|
||||
'meta' => array( 'class' => 'redux-network-admin' ),
|
||||
);
|
||||
|
||||
$wp_admin_bar->add_node( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves network options.
|
||||
*/
|
||||
public function save_network_page() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( isset( $_POST[ $core->args['opt_name'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$opt_name = sanitize_text_field( wp_unslash( $_POST[ $core->args['opt_name'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
$data = $core->options_class->validate_options( $opt_name );
|
||||
|
||||
if ( ! empty( $data ) ) {
|
||||
$core->options_class->set( $data );
|
||||
}
|
||||
|
||||
wp_safe_redirect(
|
||||
add_query_arg(
|
||||
array(
|
||||
'page' => $core->args['page_slug'],
|
||||
'updated' => 'true',
|
||||
),
|
||||
network_admin_url( 'settings.php' )
|
||||
)
|
||||
);
|
||||
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Option Defaults Class
|
||||
*
|
||||
* @class Redux_Options_Defaults
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Options_Defaults', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Options_Defaults
|
||||
*/
|
||||
class Redux_Options_Defaults {
|
||||
|
||||
/**
|
||||
* Default options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options_defaults = array();
|
||||
|
||||
/**
|
||||
* Field array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fields = array();
|
||||
|
||||
/**
|
||||
* Creates default options array.
|
||||
*
|
||||
* @param string $opt_name Panel opt_name.
|
||||
* @param array $sections Panel sections array.
|
||||
* @param null $wp_data_class WordPress data class.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function default_values( $opt_name, $sections = array(), $wp_data_class = null ) {
|
||||
// We want it to be clean each time this is run.
|
||||
$this->options_defaults = array();
|
||||
|
||||
// Check to make sure we're not in the select2 action, we don't want to fetch any there.
|
||||
if ( isset( $_REQUEST['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( Redux_Functions_Ex::string_ends_with( $action, '_select2' ) && Redux_Functions_Ex::string_starts_with( $action, 'redux_' ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! is_null( $sections ) && ! empty( $sections ) ) {
|
||||
|
||||
// Fill the cache.
|
||||
foreach ( $sections as $sk => $section ) {
|
||||
if ( ! isset( $section['id'] ) ) {
|
||||
if ( ! is_numeric( $sk ) || ! isset( $section['title'] ) ) {
|
||||
$section['id'] = $sk;
|
||||
} else {
|
||||
$section['id'] = sanitize_title( $section['title'], $sk );
|
||||
}
|
||||
|
||||
$sections[ $sk ] = $section;
|
||||
}
|
||||
if ( isset( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $k => $field ) {
|
||||
if ( empty( $field['id'] ) && empty( $field['type'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->field_default_values( $opt_name, $field, $wp_data_class );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->options_defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Field default values.
|
||||
*
|
||||
* @param string $opt_name Panel opt_name.
|
||||
* @param array $field Fiel array.
|
||||
* @param object $wp_data_class WordPress data class.
|
||||
*/
|
||||
public function field_default_values( $opt_name = '', $field, $wp_data_class = null ) {
|
||||
if ( null === $wp_data_class && class_exists( 'Redux_WordPress_Data' ) && ! ( 'select' === $field['type'] && isset( $field['ajax'] ) && $field['ajax'] ) ) {
|
||||
$wp_data_class = new Redux_WordPress_Data( $opt_name );
|
||||
}
|
||||
|
||||
// Detect what field types are being used.
|
||||
if ( ! isset( $this->fields[ $field['type'] ][ $field['id'] ] ) ) {
|
||||
$this->fields[ $field['type'] ][ $field['id'] ] = 1;
|
||||
} else {
|
||||
$this->fields[ $field['type'] ] = array( $field['id'] => 1 );
|
||||
}
|
||||
|
||||
if ( isset( $field['default'] ) ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$this->options_defaults[ $field['id'] ] = apply_filters( "redux/{$opt_name}/field/{$field['type']}/defaults", $field['default'], $field );
|
||||
} elseif ( ( 'ace_editor' !== $field['type'] ) && ! ( 'select' === $field['type'] && ! empty( $field['ajax'] ) ) ) {
|
||||
if ( isset( $field['data'] ) && empty( $field['data'] ) ) {
|
||||
if ( ! isset( $field['args'] ) ) {
|
||||
$field['args'] = array();
|
||||
}
|
||||
if ( is_array( $field['data'] ) && ! empty( $field['data'] ) ) {
|
||||
foreach ( $field['data'] as $key => $data ) {
|
||||
if ( ! empty( $data ) ) {
|
||||
if ( ! isset( $field['args'][ $key ] ) ) {
|
||||
$field['args'][ $key ] = array();
|
||||
}
|
||||
if ( null !== $wp_data_class ) {
|
||||
$field['options'][ $key ] = $wp_data_class->get( $data, $field['args'][ $key ], $opt_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ( null !== $wp_data_class ) {
|
||||
$field['options'] = $wp_data_class->get( $field['data'], $field['args'], $opt_name );
|
||||
}
|
||||
|
||||
if ( 'sorter' === $field['type'] && isset( $field['data'] ) && ! empty( $field['data'] ) && is_array( $field['data'] ) ) {
|
||||
if ( ! isset( $field['args'] ) ) {
|
||||
$field['args'] = array();
|
||||
}
|
||||
foreach ( $field['data'] as $key => $data ) {
|
||||
if ( ! isset( $field['args'][ $key ] ) ) {
|
||||
$field['args'][ $key ] = array();
|
||||
}
|
||||
if ( null !== $wp_data_class ) {
|
||||
$field['options'][ $key ] = $wp_data_class->get( $data, $field['args'][ $key ], $opt_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $field['options'] ) ) {
|
||||
if ( 'sortable' === $field['type'] ) {
|
||||
$this->options_defaults[ $field['id'] ] = array();
|
||||
} elseif ( 'image_select' === $field['type'] ) {
|
||||
$this->options_defaults[ $field['id'] ] = '';
|
||||
} elseif ( 'select' === $field['type'] ) {
|
||||
$this->options_defaults[ $field['id'] ] = '';
|
||||
} else {
|
||||
$this->options_defaults[ $field['id'] ] = $field['options'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Output Class
|
||||
*
|
||||
* @class Redux_Output
|
||||
* @version 3.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Output', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Output
|
||||
*/
|
||||
class Redux_Output extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_Output constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
// Output dynamic CSS.
|
||||
// Frontend: Maybe enqueue dynamic CSS and Google fonts.
|
||||
if ( empty( $this->args['output_location'] ) || in_array( 'frontend', $this->args['output_location'], true ) ) {
|
||||
add_action( 'wp_head', array( $this, 'output_css' ), 150 );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ), 150 );
|
||||
}
|
||||
|
||||
// Login page: Maybe enqueue dynamic CSS and Google fonts.
|
||||
if ( in_array( 'login', $this->args['output_location'], true ) ) {
|
||||
add_action( 'login_head', array( $this, 'output_css' ), 150 );
|
||||
add_action( 'login_enqueue_scripts', array( $this, 'enqueue' ), 150 );
|
||||
}
|
||||
|
||||
// Admin area: Maybe enqueue dynamic CSS and Google fonts.
|
||||
if ( in_array( 'admin', $this->args['output_location'], true ) ) {
|
||||
add_action( 'admin_head', array( $this, 'output_css' ), 150 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 150 );
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/output/{$this->parent->args['opt_name']}/construct", $this );
|
||||
// Useful for adding different locations for CSS output.
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue CSS and Google fonts for front end
|
||||
*
|
||||
* @return void
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( false === $core->args['output'] && false === $core->args['compiler'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $core->sections as $k => $section ) {
|
||||
if ( isset( $section['type'] ) && ( 'divide' === $section['type'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $fieldk => $field ) {
|
||||
if ( isset( $field['type'] ) && 'callback' !== $field['type'] ) {
|
||||
$field_classes = array( 'Redux_' . $field['type'], 'ReduxFramework_' . $field['type'] );
|
||||
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
|
||||
if ( false === $field_class ) {
|
||||
if ( ! isset( $field['compiler'] ) ) {
|
||||
$field['compiler'] = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Field class file
|
||||
* filter 'redux/{opt_name}/field/class/{field.type}
|
||||
*
|
||||
* @param string field class file
|
||||
* @param array $field field config data
|
||||
*/
|
||||
$field_type = str_replace( '_', '-', $field['type'] );
|
||||
$core_path = Redux_Core::$dir . "inc/fields/{$field['type']}/class-redux-{$field_type}.php";
|
||||
|
||||
if ( ! file_exists( $core_path ) ) {
|
||||
$core_path = Redux_Core::$dir . "inc/fields/{$field['type']}/field_{$field['type']}.php";
|
||||
}
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$pro_path = Redux_Pro::$dir . "core/inc/fields/{$field['type']}/class-redux-{$field_type}.php";
|
||||
|
||||
if ( file_exists( $pro_path ) ) {
|
||||
$filter_path = $pro_path;
|
||||
} else {
|
||||
$filter_path = $core_path;
|
||||
}
|
||||
} else {
|
||||
$filter_path = $core_path;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$class_file = apply_filters( "redux/{$core->args['opt_name']}/field/class/{$field['type']}", $filter_path, $field );
|
||||
|
||||
if ( $class_file && file_exists( $class_file ) && ( ! class_exists( $field_class ) ) ) {
|
||||
require_once $class_file;
|
||||
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
}
|
||||
}
|
||||
|
||||
$field['default'] = isset( $field['default'] ) ? $field['default'] : '';
|
||||
$value = isset( $core->options[ $field['id'] ] ) ? $core->options[ $field['id'] ] : $field['default'];
|
||||
$style_data = '';
|
||||
$data = array(
|
||||
'field' => $field,
|
||||
'value' => $value,
|
||||
'core' => $core,
|
||||
'mode' => 'output',
|
||||
);
|
||||
|
||||
Redux_Functions::load_pro_field( $data );
|
||||
|
||||
if ( empty( $field_class ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field_object = new $field_class( $field, $value, $core );
|
||||
|
||||
if ( ! empty( $core->options[ $field['id'] ] ) && class_exists( $field_class ) && method_exists( $field_class, 'output' ) && $this->can_output_css( $core, $field ) ) {
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$field = apply_filters( "redux/field/{$core->args['opt_name']}/output_css", $field );
|
||||
|
||||
if ( ! empty( $field['output'] ) && ! is_array( $field['output'] ) ) {
|
||||
$field['output'] = array( $field['output'] );
|
||||
}
|
||||
|
||||
if ( ( ( isset( $field['output'] ) && ! empty( $field['output'] ) ) || ( isset( $field['compiler'] ) && ! empty( $field['compiler'] ) ) || isset( $field['media_query'] ) && ! empty( $field['media_query'] ) || 'typography' === $field['type'] || 'icon_select' === $field['type'] ) ) {
|
||||
if ( method_exists( $field_class, 'css_style' ) ) {
|
||||
$style_data = $field_object->css_style( $field_object->value );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( ( isset( $field['output'] ) && ! empty( $field['output'] ) ) || ( isset( $field['compiler'] ) && ! empty( $field['compiler'] ) ) || 'typography' === $field['type'] || 'icon_select' === $field['type'] ) ) {
|
||||
$field_object->output( $style_data );
|
||||
}
|
||||
if ( isset( $field['media_query'] ) && ! empty( $field['media_query'] ) ) {
|
||||
$field_object->media_query( $style_data );
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/field/{$core->args['opt_name']}/output_loop", $core, $field, $value, $style_data );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/field/{$core->args['opt_name']}/output_loop/{$field['type']}", $core, $field, $value, $style_data );
|
||||
|
||||
if ( method_exists( $field_class, 'output_variables' ) && $this->can_output_css( $core, $field ) ) {
|
||||
$passed_style_data = $field_object->output_variables( $style_data );
|
||||
$this->output_variables( $core, $section, $field, $value, $passed_style_data );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! empty( $core->outputCSS ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
$core->outputCSS = html_entity_decode( $core->outputCSS, ENT_QUOTES, 'UTF-8' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For use like in the customizer. Stops the output, but passes the CSS in the variable for the compiler.
|
||||
if ( isset( $core->no_output ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $core->typography ) && ! empty( $core->typography ) && filter_var( $core->args['output'], FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
$version = ! empty( $core->transients['last_save'] ) ? $core->transients['last_save'] : '';
|
||||
if ( ! class_exists( 'Redux_Typography' ) ) {
|
||||
require_once Redux_Core::$dir . '/inc/fields/typography/class-redux-typography.php';
|
||||
}
|
||||
$typography = new Redux_Typography( null, null, $core );
|
||||
|
||||
if ( $core->args['async_typography'] && ! empty( $core->typography ) ) {
|
||||
$families = array();
|
||||
|
||||
foreach ( $core->typography as $key => $value ) {
|
||||
$families[] = $key;
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
if ( typeof WebFontConfig === "undefined" ) {
|
||||
WebFontConfig = {};
|
||||
}
|
||||
|
||||
WebFontConfig['google'] = {
|
||||
families: [<?php echo $typography->make_google_web_font_string( $core->typography ); // phpcs:ignore WordPress.Security.EscapeOutput ?>]
|
||||
};
|
||||
|
||||
(function( d ) {
|
||||
var wf = d.createElement( 'script' );
|
||||
var s = d.scripts[0];
|
||||
wf.src = '//' + 'ajax' + '.googleapis' + '.com/ajax/libs/webfont/1.6.26/webfont.js';
|
||||
wf.async = true;
|
||||
s.parentNode.insertBefore( wf, s );
|
||||
})( document );
|
||||
</script>
|
||||
<?php
|
||||
} elseif ( ! $core->args['disable_google_fonts_link'] ) {
|
||||
$url = $typography->make_google_web_font_link( $core->typography );
|
||||
wp_enqueue_style( 'redux-google-fonts-' . $core->args['opt_name'], $url, array(), $version, 'all' );
|
||||
add_filter( 'style_loader_tag', array( $this, 'add_style_attributes' ), 10, 4 );
|
||||
add_filter( 'wp_resource_hints', array( $this, 'google_fonts_preconnect' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Google Fonts preconnect link.
|
||||
*
|
||||
* @param array $urls HTML to be added.
|
||||
* @param string $relationship_type Handle name.
|
||||
*
|
||||
* @return array
|
||||
* @since 4.1.15
|
||||
* @access public
|
||||
*/
|
||||
public function google_fonts_preconnect( $urls, $relationship_type ) {
|
||||
if ( 'preconnect' !== $relationship_type ) {
|
||||
return $urls;
|
||||
}
|
||||
$urls[] = array(
|
||||
'rel' => 'preconnect',
|
||||
'href' => 'https://fonts.gstatic.com',
|
||||
'crossorigin',
|
||||
);
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to enhance the google fonts enqueue.
|
||||
*
|
||||
* @param string $html HTML to be added.
|
||||
* @param string $handle Handle name.
|
||||
* @param string $href HREF URL of script.
|
||||
* @param string $media Media type.
|
||||
*
|
||||
* @return string
|
||||
* @since 4.1.15
|
||||
* @access public
|
||||
*/
|
||||
public function add_style_attributes( $html = '', $handle = '', $href = '', $media = '' ) {
|
||||
if ( Redux_Functions_Ex::string_starts_with( $handle, 'redux-google-fonts-' ) ) {
|
||||
// Revamp thanks to Harry: https://csswizardry.com/2020/05/the-fastest-google-fonts/.
|
||||
$href = str_replace( array( '|', ' ' ), array( '%7C', '%20' ), urldecode( $href ) );
|
||||
$new_html = '';
|
||||
$new_html .= '<link rel="preload" as="style" href="' . esc_attr( $href ) . '" />';
|
||||
$new_html .= '<link rel="stylesheet" href="' . esc_attr( $href ) . '" media="print" onload="this.media=\'all\'">'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
|
||||
$new_html .= '<noscript><link rel="stylesheet" href="' . esc_attr( $href ) . '" /></noscript>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
|
||||
$html = $new_html;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to output output_variables to the dynamic output.
|
||||
*
|
||||
* @param array $core ReduxFramework core pointer.
|
||||
* @param array $section Section containing this field.
|
||||
* @param array $field Field object.
|
||||
* @param array $value Current value of field.
|
||||
* @param string $style_data CSS output string to append to the root output variable.
|
||||
*
|
||||
* @return void
|
||||
* @since 4.0.3
|
||||
* @access public
|
||||
*/
|
||||
private function output_variables( $core = array(), $section = array(), $field = array(), $value = array(), $style_data = '' ) {
|
||||
// Let's allow section overrides please.
|
||||
if ( isset( $section['output_variables'] ) && ! isset( $field['output_variables'] ) ) {
|
||||
$field['output_variables'] = $section['output_variables'];
|
||||
}
|
||||
if ( isset( $section['output_variables_prefix'] ) && ! isset( $field['output_variables_prefix'] ) ) {
|
||||
$field['output_variables_prefix'] = $section['output_variables_prefix'];
|
||||
}
|
||||
if ( isset( $field['output_variables'] ) && $field['output_variables'] ) {
|
||||
$output_variables_prefix = $core->args['output_variables_prefix'];
|
||||
if ( isset( $field['output_variables_prefix'] ) && ! empty( $field['output_variables_prefix'] ) ) {
|
||||
$output_variables_prefix = $field['output_variables_prefix'];
|
||||
} elseif ( isset( $section['output_variables_prefix'] ) && ! empty( $section['output_variables_prefix'] ) ) {
|
||||
$output_variables_prefix = $section['output_variables_prefix'];
|
||||
}
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$val_pieces = array_filter( $value, 'strlen' );
|
||||
// We don't need to show the Google boolean.
|
||||
if ( 'typography' === $field['type'] && isset( $val_pieces['google'] ) ) {
|
||||
unset( $val_pieces['google'] );
|
||||
}
|
||||
|
||||
foreach ( $val_pieces as $val_key => $val_val ) {
|
||||
$val_key = $output_variables_prefix . sanitize_title_with_dashes( $field['id'] ) . '-' . $val_key;
|
||||
$core->output_variables[ $val_key ] = $val_val;
|
||||
if ( ! empty( $style_data ) ) {
|
||||
$val_key = $output_variables_prefix . sanitize_title_with_dashes( $field['id'] );
|
||||
$core->output_variables[ $val_key ] = $style_data;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( $style_data ) ) {
|
||||
$val_key = $output_variables_prefix . sanitize_title_with_dashes( $field['id'] );
|
||||
$core->output_variables[ $val_key ] = $style_data;
|
||||
} else {
|
||||
$val_key = $output_variables_prefix . sanitize_title_with_dashes( $field['id'] );
|
||||
$core->output_variables[ $val_key ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output dynamic CSS at bottom of HEAD
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.8
|
||||
* @access public
|
||||
*/
|
||||
public function output_css() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( false === $core->args['output'] && false === $core->args['compiler'] && empty( $core->output_variables ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $core->no_output ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $core->output_variables ) ) {
|
||||
$root_css = ':root{';
|
||||
foreach ( $core->output_variables as $key => $value ) {
|
||||
$root_css .= "{$key}:{$value};";
|
||||
}
|
||||
$root_css .= '}';
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName, WordPress.Security.EscapeOutput
|
||||
$core->outputCSS = $root_css . $core->outputCSS;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
if ( ! empty( $core->outputCSS ) && ( true === $core->args['output_tag'] || ( isset( $_POST['customized'] ) && isset( $_POST['nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'preview-customize_' . wp_get_theme()->get_stylesheet() ) ) ) ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName, WordPress.Security.EscapeOutput
|
||||
echo '<style id="' . esc_attr( $core->args['opt_name'] ) . '-dynamic-css" title="dynamic-css" class="redux-options-output">' . $core->outputCSS . '</style>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can Output CSS
|
||||
* Check if a field meets its requirements before outputting to CSS
|
||||
*
|
||||
* @param object $core ReduxFramework core pointer.
|
||||
* @param array $field Field array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function can_output_css( $core, $field ) {
|
||||
$return = true;
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$field = apply_filters( "redux/field/{$core->args['opt_name']}/_can_output_css", $field );
|
||||
if ( isset( $field['force_output'] ) && true === $field['force_output'] ) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
if ( ! empty( $field['required'] ) ) {
|
||||
if ( isset( $field['required'][0] ) ) {
|
||||
if ( ! is_array( $field['required'][0] ) && 3 === count( $field['required'] ) ) {
|
||||
$parent_value = isset( $GLOBALS[ $core->args['global_variable'] ][ $field['required'][0] ] ) ? $GLOBALS[ $core->args['global_variable'] ][ $field['required'][0] ] : '';
|
||||
$check_value = $field['required'][2];
|
||||
$operation = $field['required'][1];
|
||||
$return = $core->required_class->compare_value_dependencies( $parent_value, $check_value, $operation );
|
||||
} elseif ( is_array( $field['required'][0] ) ) {
|
||||
foreach ( $field['required'] as $required ) {
|
||||
if ( ! is_array( $required[0] ) && 3 === count( $required ) ) {
|
||||
$parent_value = isset( $GLOBALS[ $core->args['global_variable'] ][ $required[0] ] ) ? $GLOBALS[ $core->args['global_variable'] ][ $required[0] ] : '';
|
||||
$check_value = $required[2];
|
||||
$operation = $required[1];
|
||||
$return = $core->required_class->compare_value_dependencies( $parent_value, $check_value, $operation );
|
||||
}
|
||||
if ( ! $return ) {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,420 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Panel Class
|
||||
*
|
||||
* @class Redux_Panel
|
||||
* @version 3.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Panel', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Panel
|
||||
*/
|
||||
class Redux_Panel {
|
||||
|
||||
/**
|
||||
* ReduxFramwrok object pointer.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $parent = null;
|
||||
|
||||
/**
|
||||
* Path to templates dir.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
public $template_path = null;
|
||||
|
||||
/**
|
||||
* Original template path.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
public $original_path = null;
|
||||
|
||||
/**
|
||||
* Sets the path from the arg or via filter. Also calls the panel template function.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
$this->parent = $parent;
|
||||
$this->template_path = Redux_Core::$dir . 'templates/panel/';
|
||||
$this->original_path = Redux_Core::$dir . 'templates/panel/';
|
||||
|
||||
if ( ! empty( $this->parent->args['templates_path'] ) ) {
|
||||
$this->template_path = trailingslashit( $this->parent->args['templates_path'] );
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$this->template_path = trailingslashit( apply_filters( "redux/{$this->parent->args['opt_name']}/panel/templates_path", $this->template_path ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class init.
|
||||
*/
|
||||
public function init() {
|
||||
$this->panel_template();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the panel templates where needed and provides the container for Redux
|
||||
*/
|
||||
private function panel_template() {
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
$this->template_file_check_notice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Action 'redux/{opt_name}/panel/before'
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/{$this->parent->args['opt_name']}/panel/before" );
|
||||
|
||||
echo '<div class="wrap"><h2></h2></div>'; // Stupid hack for WordPress alerts and warnings.
|
||||
|
||||
echo '<div class="clear"></div>';
|
||||
echo '<div class="wrap redux-wrap-div" data-opt-name="' . esc_attr( $this->parent->args['opt_name'] ) . '">';
|
||||
|
||||
// Do we support JS?
|
||||
echo '<noscript><div class="no-js">' . esc_html__( 'Warning- This options panel will not work properly without javascript!', 'redux-framework' ) . '</div></noscript>';
|
||||
|
||||
// Security is vital!
|
||||
echo '<input type="hidden" class="redux-ajax-security" data-opt-name="' . esc_attr( $this->parent->args['opt_name'] ) . '" id="ajaxsecurity" name="security" value="' . esc_attr( wp_create_nonce( 'redux_ajax_nonce' . $this->parent->args['opt_name'] ) ) . '" />';
|
||||
|
||||
/**
|
||||
* Action 'redux/page/{opt_name}/form/before'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/page/{$this->parent->args['opt_name']}/form/before", $this );
|
||||
|
||||
if ( is_rtl() ) {
|
||||
$this->parent->args['class'] = ' redux-rtl';
|
||||
}
|
||||
|
||||
$this->get_template( 'container.tpl.php' );
|
||||
|
||||
/**
|
||||
* Action 'redux/page/{opt_name}/form/after'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/page/{$this->parent->args['opt_name']}/form/after", $this );
|
||||
|
||||
echo '<div class="clear"></div>';
|
||||
echo '</div>';
|
||||
|
||||
if ( true === $this->parent->args['dev_mode'] ) {
|
||||
echo '<br /><div class="redux-timer">' . esc_html( get_num_queries() ) . ' queries in ' . esc_html( timer_stop( 0 ) ) . ' seconds<br/>Redux is currently set to developer mode.</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Action 'redux/{opt_name}/panel/after'
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/{$this->parent->args['opt_name']}/panel/after" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the various notification bars and sets the appropriate templates.
|
||||
*/
|
||||
public function notification_bar() {
|
||||
if ( isset( $this->parent->transients['last_save_mode'] ) ) {
|
||||
|
||||
if ( 'import' === $this->parent->transients['last_save_mode'] ) {
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/import'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/import", $this, $this->parent->transients['changed_values'] );
|
||||
|
||||
echo '<div class="admin-notice notice-blue saved_notice">';
|
||||
|
||||
/**
|
||||
* Filter 'redux-imported-text-{opt_name}'
|
||||
*
|
||||
* @param string translated "settings imported" text
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo '<strong>' . esc_html( apply_filters( "redux-imported-text-{$this->parent->args['opt_name']}", esc_html__( 'Settings Imported!', 'redux-framework' ) ) ) . '</strong>';
|
||||
echo '</div>';
|
||||
} elseif ( 'defaults' === $this->parent->transients['last_save_mode'] ) {
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/reset'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/reset", $this );
|
||||
|
||||
echo '<div class="saved_notice admin-notice notice-yellow">';
|
||||
|
||||
/**
|
||||
* Filter 'redux-defaults-text-{opt_name}'
|
||||
*
|
||||
* @param string translated "settings imported" text
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo '<strong>' . esc_html( apply_filters( "redux-defaults-text-{$this->parent->args['opt_name']}", esc_html__( 'All Defaults Restored!', 'redux-framework' ) ) ) . '</strong>';
|
||||
echo '</div>';
|
||||
} elseif ( 'defaults_section' === $this->parent->transients['last_save_mode'] ) {
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/section/reset'
|
||||
*
|
||||
* @param object $this ReduxFramework
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/section/reset", $this );
|
||||
|
||||
echo '<div class="saved_notice admin-notice notice-yellow">';
|
||||
|
||||
/**
|
||||
* Filter 'redux-defaults-section-text-{opt_name}'
|
||||
*
|
||||
* @param string translated "settings imported" text
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo '<strong>' . esc_html( apply_filters( "redux-defaults-section-text-{$this->parent->args['opt_name']}", esc_html__( 'Section Defaults Restored!', 'redux-framework' ) ) ) . '</strong>';
|
||||
echo '</div>';
|
||||
} elseif ( 'normal' === $this->parent->transients['last_save_mode'] ) {
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/saved'
|
||||
*
|
||||
* @param mixed $value set/saved option value
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/saved", $this->parent->options, $this->parent->transients['changed_values'] );
|
||||
|
||||
echo '<div class="saved_notice admin-notice notice-green">';
|
||||
|
||||
/**
|
||||
* Filter 'redux-saved-text-{opt_name}'
|
||||
*
|
||||
* @param string translated "settings saved" text
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo '<strong>' . esc_html( apply_filters( "redux-saved-text-{$this->parent->args['opt_name']}", esc_html__( 'Settings Saved!', 'redux-framework' ) ) ) . '</strong>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
unset( $this->parent->transients['last_save_mode'] );
|
||||
|
||||
$this->parent->transient_class->set();
|
||||
}
|
||||
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/settings/changes'
|
||||
*
|
||||
* @param mixed $value set/saved option value
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/settings/change", $this->parent->options, $this->parent->transients['changed_values'] );
|
||||
|
||||
echo '<div class="redux-save-warn notice-yellow">';
|
||||
|
||||
/**
|
||||
* Filter 'redux-changed-text-{opt_name}'
|
||||
*
|
||||
* @param string translated "settings have changed" text
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo '<strong>' . esc_html( apply_filters( "redux-changed-text-{$this->parent->args['opt_name']}", esc_html__( 'Settings have changed, you should save them!', 'redux-framework' ) ) ) . '</strong>';
|
||||
echo '</div>';
|
||||
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/errors'
|
||||
*
|
||||
* @param array $this ->errors error information
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/errors", $this->parent->errors );
|
||||
|
||||
echo '<div class="redux-field-errors notice-red">';
|
||||
echo '<strong>';
|
||||
echo '<span></span> ' . esc_html__( 'error(s) were found!', 'redux-framework' );
|
||||
echo '</strong>';
|
||||
echo '</div>';
|
||||
|
||||
/**
|
||||
* Action 'redux/options/{opt_name}/warnings'
|
||||
*
|
||||
* @param array $this ->warnings warning information
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/warnings", $this->parent->warnings );
|
||||
|
||||
echo '<div class="redux-field-warnings notice-yellow">';
|
||||
echo '<strong>';
|
||||
echo '<span></span> ' . esc_html__( 'warning(s) were found!', 'redux-framework' );
|
||||
echo '</strong>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to intitialize the settings fields for this panel. Required for saving and redirect.
|
||||
*/
|
||||
private function init_settings_fields() {
|
||||
// Must run or the page won't redirect properly.
|
||||
settings_fields( "{$this->parent->args['opt_name']}_group" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable file deprecate warning from core. This is necessary because the function is considered private.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function tick_file_deprecate_warning() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to select the proper template. If it doesn't exist in the path, then the original template file is used.
|
||||
*
|
||||
* @param string $file Path to template file.
|
||||
*/
|
||||
public function get_template( $file ) {
|
||||
if ( empty( $file ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( file_exists( $this->template_path . $file ) ) {
|
||||
$path = $this->template_path . $file;
|
||||
} else {
|
||||
$path = $this->original_path . $file;
|
||||
}
|
||||
|
||||
// Shim for v3 templates.
|
||||
if ( ! file_exists( $path ) ) {
|
||||
$old_file = $file;
|
||||
|
||||
add_filter( 'deprecated_file_trigger_error', array( $this, 'tick_file_deprecate_warning' ) );
|
||||
|
||||
$file = str_replace( '-', '_', $file );
|
||||
|
||||
_deprecated_file( esc_html( $file ), '4.0', esc_html( $old_file ), 'Please replace this outdated template with the current one from the Redux core.' );
|
||||
|
||||
if ( file_exists( $this->template_path . $file ) ) {
|
||||
$path = $this->template_path . $file;
|
||||
} else {
|
||||
$path = $this->original_path . $file;
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/{$this->parent->args['opt_name']}/panel/template/" . $file . '/before' );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$path = apply_filters( "redux/{$this->parent->args['opt_name']}/panel/template/" . $file, $path );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/{$this->parent->args['opt_name']}/panel/template/" . $file . '/after' );
|
||||
|
||||
require $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the template files.
|
||||
*
|
||||
* @param string $template_path Path to template file.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function scan_template_files( $template_path ) {
|
||||
$files = scandir( $template_path );
|
||||
$result = array();
|
||||
if ( $files ) {
|
||||
foreach ( $files as $key => $value ) {
|
||||
if ( ! in_array( $value, array( '.', '..' ), true ) ) {
|
||||
if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
|
||||
$sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
|
||||
foreach ( $sub_files as $sub_file ) {
|
||||
$result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
|
||||
}
|
||||
} else {
|
||||
$result[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a notice highlighting bad template files
|
||||
*/
|
||||
public function template_file_check_notice() {
|
||||
if ( $this->original_path === $this->template_path ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$core_templates = $this->scan_template_files( $this->original_path );
|
||||
|
||||
foreach ( $core_templates as $file ) {
|
||||
$developer_theme_file = false;
|
||||
|
||||
if ( file_exists( $this->template_path . $file ) ) {
|
||||
$developer_theme_file = $this->template_path . $file;
|
||||
}
|
||||
|
||||
if ( $developer_theme_file ) {
|
||||
$core_version = Redux_Helpers::get_template_version( $this->original_path . $file );
|
||||
$developer_version = Redux_Helpers::get_template_version( $developer_theme_file );
|
||||
|
||||
if ( $core_version && $developer_version && version_compare( $developer_version, $core_version, '<' ) && isset( $this->parent->args['dev_mode'] ) && ! empty( $this->parent->args['dev_mode'] ) ) {
|
||||
?>
|
||||
<div id="message" class="error redux-message">
|
||||
<p>
|
||||
<strong><?php esc_html_e( 'Your panel has bundled copies of Redux Framework template files that are outdated!', 'redux-framework' ); ?></strong> <?php esc_html_e( 'Please update them now as functionality issues could arise.', 'redux-framework' ); ?></a></strong>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the HTML for a given section using the WordPress settings API.
|
||||
*
|
||||
* @param mixed $k Section number of settings panel to display.
|
||||
*/
|
||||
private function output_section( $k ) {
|
||||
do_settings_sections( $this->parent->args['opt_name'] . $k . '_section_group' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'reduxCorePanel' ) ) {
|
||||
class_alias( 'Redux_Panel', 'reduxCorePanel' );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Path Class
|
||||
*
|
||||
* @class Redux_Path
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Path', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Path
|
||||
*/
|
||||
class Redux_Path {
|
||||
|
||||
/**
|
||||
* Class init
|
||||
*/
|
||||
public static function init() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Redux path.
|
||||
*
|
||||
* @param string $relative_path Self explanitory.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_path( $relative_path ) {
|
||||
$path = Redux_Core::$redux_path . $relative_path;
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
|
||||
$pro_path = Redux_Pro::$dir . '/core' . $relative_path;
|
||||
|
||||
if ( file_exists( $pro_path ) ) {
|
||||
$path = $pro_path;
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require class.
|
||||
*
|
||||
* @param string $relative_path Path.
|
||||
*/
|
||||
public static function require_class( $relative_path ) {
|
||||
$path = self::get_path( $relative_path );
|
||||
|
||||
if ( file_exists( $path ) ) {
|
||||
require_once $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Redux_Path::init();
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Required Class
|
||||
*
|
||||
* @class Redux_Required
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Required', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Required
|
||||
*/
|
||||
class Redux_Required extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Array of fields to reload.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $reload_fields = array();
|
||||
|
||||
/**
|
||||
* Checks dependencies between objects based on the $field['required'] array
|
||||
* If the array is set it needs to have exactly 3 entries.
|
||||
* The first entry describes which field should be monitored by the current field. eg: "content"
|
||||
* The second entry describes the comparison parameter. eg: "equals, not, is_larger, is_smaller ,contains"
|
||||
* The third entry describes the value that we are comparing against.
|
||||
* Example: if the required array is set to array('content','equals','Hello World'); then the current
|
||||
* field will only be displayed if the field with id "content" has exactly the value "Hello World"
|
||||
*
|
||||
* @param array $field Field array.
|
||||
*/
|
||||
public function check_dependencies( $field ) {
|
||||
$core = $this->core();
|
||||
|
||||
if ( isset( $field['ajax_save'] ) && false === $field['ajax_save'] ) {
|
||||
$core->required_class->reload_fields[] = $field['id'];
|
||||
}
|
||||
|
||||
if ( ! empty( $field['required'] ) ) {
|
||||
if ( ! isset( $core->required_child[ $field['id'] ] ) ) {
|
||||
$core->required_child[ $field['id'] ] = array();
|
||||
}
|
||||
|
||||
if ( ! isset( $core->required[ $field['id'] ] ) ) {
|
||||
$core->required[ $field['id'] ] = array();
|
||||
}
|
||||
|
||||
if ( is_array( $field['required'][0] ) ) {
|
||||
|
||||
foreach ( $field['required'] as $value ) {
|
||||
if ( is_array( $value ) && 3 === count( $value ) ) {
|
||||
$data = array();
|
||||
$data['parent'] = $value[0];
|
||||
$data['operation'] = $value[1];
|
||||
$data['checkValue'] = $value[2];
|
||||
|
||||
$core->required[ $data['parent'] ][ $field['id'] ][] = $data;
|
||||
|
||||
if ( ! in_array( $data['parent'], $core->required_child[ $field['id'] ], true ) ) {
|
||||
$core->required_child[ $field['id'] ][] = $data;
|
||||
}
|
||||
|
||||
$this->check_required_dependencies( $core, $field, $data );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data = array();
|
||||
$data['parent'] = $field['required'][0];
|
||||
$data['operation'] = $field['required'][1];
|
||||
$data['checkValue'] = $field['required'][2];
|
||||
|
||||
$core->required[ $data['parent'] ][ $field['id'] ][] = $data;
|
||||
|
||||
if ( ! in_array( $data['parent'], $core->required_child[ $field['id'] ], true ) ) {
|
||||
$core->required_child[ $field['id'] ][] = $data;
|
||||
}
|
||||
|
||||
$this->check_required_dependencies( $core, $field, $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check field for require deps.
|
||||
*
|
||||
* @param object $core ReduxFramework core pointer.
|
||||
* @param array $field Field array.
|
||||
* @param array $data Required data.
|
||||
*/
|
||||
private function check_required_dependencies( $core, $field, $data ) {
|
||||
// required field must not be hidden. otherwise hide this one by default.
|
||||
if ( ! in_array( $data['parent'], $core->fields_hidden, true ) && ( ! isset( $core->folds[ $field['id'] ] ) || 'hide' !== $core->folds[ $field['id'] ] ) ) {
|
||||
if ( isset( $core->options[ $data['parent'] ] ) ) {
|
||||
$return = $this->compare_value_dependencies( $core->options[ $data['parent'] ], $data['checkValue'], $data['operation'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( isset( $return ) && $return ) && ( ! isset( $core->folds[ $field['id'] ] ) || 'hide' !== $core->folds[ $field['id'] ] ) ) {
|
||||
$core->folds[ $field['id'] ] = 'show';
|
||||
} else {
|
||||
$core->folds[ $field['id'] ] = 'hide';
|
||||
|
||||
if ( ! in_array( $field['id'], $core->fields_hidden, true ) ) {
|
||||
$core->fields_hidden[] = $field['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare data for required field.
|
||||
*
|
||||
* @param mixed $parent_value Parent value.
|
||||
* @param mixed $check_value Check value.
|
||||
* @param string $operation Operation.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function compare_value_dependencies( $parent_value, $check_value, $operation ) {
|
||||
$return = false;
|
||||
|
||||
switch ( $operation ) {
|
||||
case '=':
|
||||
case 'equals':
|
||||
$data['operation'] = '=';
|
||||
|
||||
if ( is_array( $parent_value ) ) {
|
||||
foreach ( $parent_value as $idx => $val ) {
|
||||
if ( is_array( $check_value ) ) {
|
||||
foreach ( $check_value as $i => $v ) {
|
||||
if ( Redux_Helpers::make_bool_str( $val ) === Redux_Helpers::make_bool_str( $v ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( Redux_Helpers::make_bool_str( $val ) === Redux_Helpers::make_bool_str( $check_value ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( is_array( $check_value ) ) {
|
||||
foreach ( $check_value as $i => $v ) {
|
||||
if ( Redux_Helpers::make_bool_str( $parent_value ) === Redux_Helpers::make_bool_str( $v ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( Redux_Helpers::make_bool_str( $parent_value ) === Redux_Helpers::make_bool_str( $check_value ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '!=':
|
||||
case 'not':
|
||||
$data['operation'] = '!==';
|
||||
if ( is_array( $parent_value ) ) {
|
||||
foreach ( $parent_value as $idx => $val ) {
|
||||
if ( is_array( $check_value ) ) {
|
||||
foreach ( $check_value as $i => $v ) {
|
||||
if ( Redux_Helpers::make_bool_str( $val ) !== Redux_Helpers::make_bool_str( $v ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( Redux_Helpers::make_bool_str( $val ) !== Redux_Helpers::make_bool_str( $check_value ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( is_array( $check_value ) ) {
|
||||
foreach ( $check_value as $i => $v ) {
|
||||
if ( Redux_Helpers::make_bool_str( $parent_value ) !== Redux_Helpers::make_bool_str( $v ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( Redux_Helpers::make_bool_str( $parent_value ) !== Redux_Helpers::make_bool_str( $check_value ) ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case '>':
|
||||
case 'greater':
|
||||
case 'is_larger':
|
||||
$data['operation'] = '>';
|
||||
if ( $parent_value > $check_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case '>=':
|
||||
case 'greater_equal':
|
||||
case 'is_larger_equal':
|
||||
$data['operation'] = '>=';
|
||||
if ( $parent_value >= $check_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
case 'less':
|
||||
case 'is_smaller':
|
||||
$data['operation'] = '<';
|
||||
if ( $parent_value < $check_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case '<=':
|
||||
case 'less_equal':
|
||||
case 'is_smaller_equal':
|
||||
$data['operation'] = '<=';
|
||||
if ( $parent_value <= $check_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case 'contains':
|
||||
if ( is_array( $parent_value ) ) {
|
||||
$parent_value = implode( ',', $parent_value );
|
||||
}
|
||||
|
||||
if ( is_array( $check_value ) ) {
|
||||
foreach ( $check_value as $idx => $opt ) {
|
||||
if ( strpos( $parent_value, (string) $opt ) !== false ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( strpos( $parent_value, (string) $check_value ) !== false ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'doesnt_contain':
|
||||
case 'not_contain':
|
||||
if ( is_array( $parent_value ) ) {
|
||||
$parent_value = implode( ',', $parent_value );
|
||||
}
|
||||
|
||||
if ( is_array( $check_value ) ) {
|
||||
foreach ( $check_value as $idx => $opt ) {
|
||||
if ( strpos( $parent_value, (string) $opt ) === false ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( strpos( $parent_value, (string) $check_value ) === false ) {
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'is_empty_or':
|
||||
if ( empty( $parent_value ) || $check_value === $parent_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case 'not_empty_and':
|
||||
if ( ! empty( $parent_value ) && $check_value !== $parent_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case 'is_empty':
|
||||
case 'empty':
|
||||
case '!isset':
|
||||
if ( empty( $parent_value ) || '' === $parent_value || null === $parent_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
case 'not_empty':
|
||||
case '!empty':
|
||||
case 'isset':
|
||||
if ( ! empty( $parent_value ) && '' !== $parent_value && null !== $parent_value ) {
|
||||
$return = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Build API Class
|
||||
*
|
||||
* @class Redux_Rest_Api_Builder
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
* @author Tofandel & Dovy
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Redux_Rest_Api_Builder
|
||||
*/
|
||||
class Redux_Rest_Api_Builder {
|
||||
|
||||
const ENDPOINT = 'redux/descriptors';
|
||||
const VER = 'v1';
|
||||
|
||||
/**
|
||||
* Get the namespace of the api.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_namespace() {
|
||||
return self::ENDPOINT . '/' . self::VER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rest url for an api call.
|
||||
*
|
||||
* @param string $route Route router.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_url( $route ) {
|
||||
return rest_url( trailingslashit( $this->get_namespace() ) . ltrim( '/', $route ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redux_Rest_Api_Builder constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the rest api.
|
||||
*/
|
||||
public function rest_api_init() {
|
||||
register_rest_route(
|
||||
$this->get_namespace(),
|
||||
'/fields',
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'list_fields' ),
|
||||
'permission_callback' => '__return_true',
|
||||
)
|
||||
);
|
||||
register_rest_route(
|
||||
$this->get_namespace(),
|
||||
'/field/(?P<type>[a-z0-9-_]+)',
|
||||
array(
|
||||
'args' => array(
|
||||
'type' => array(
|
||||
'description' => __( 'The field type', 'redux-framework' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_field' ),
|
||||
'permission_callback' => '__return_true',
|
||||
)
|
||||
);
|
||||
register_rest_route(
|
||||
$this->get_namespace(),
|
||||
'/field/(?P<type>[a-z0-9-_]+)/render',
|
||||
array(
|
||||
'args' => array(
|
||||
'name' => array(
|
||||
'description' => __( 'The field type', 'redux-framework' ),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
'methods' => WP_REST_Server::ALLMETHODS,
|
||||
'callback' => array( $this, 'render_field' ),
|
||||
'permission_callback' => '__return_true',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the folders in the field directory
|
||||
*
|
||||
* @return RecursiveDirectoryIterator
|
||||
*/
|
||||
public function field_directories() {
|
||||
|
||||
return $dirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the Redux fields paths.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_field_paths() {
|
||||
$fields = array();
|
||||
$fields_dir = trailingslashit( Redux_Core::$dir ) . 'inc' . DIRECTORY_SEPARATOR . 'fields' . DIRECTORY_SEPARATOR;
|
||||
$dirs = new RecursiveDirectoryIterator( $fields_dir );
|
||||
|
||||
$data = array();
|
||||
foreach ( $dirs as $path ) {
|
||||
$folder = explode( '/', $path );
|
||||
$folder = end( $folder );
|
||||
if ( in_array( $folder, array( '.', '..' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
$files = array(
|
||||
trailingslashit( $path ) . 'field_' . $folder . '.php',
|
||||
trailingslashit( $path ) . 'class-redux-' . $folder . '.php',
|
||||
);
|
||||
$filename = Redux_Functions::file_exists_ex( $files );
|
||||
|
||||
if ( $filename ) {
|
||||
$data[ $folder ] = $filename;
|
||||
}
|
||||
}
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$data = apply_filters( 'redux/fields', $data );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function list_fields() {
|
||||
$field_classes = $this->get_field_paths();
|
||||
$fields = array();
|
||||
|
||||
foreach ( $field_classes as $folder => $filename ) {
|
||||
$class = 'Redux_' . ucwords( str_replace( '-', '_', $folder ) );
|
||||
if ( ! class_exists( $class ) && file_exists( $filename ) ) {
|
||||
require_once $filename;
|
||||
}
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
// Load it here to save some resources in autoloading!
|
||||
if ( $field_class && is_subclass_of( $class, 'Redux_Field' ) ) {
|
||||
$descriptor = call_user_func( array( $class, 'get_descriptor' ) );
|
||||
$descriptor_type = $descriptor->get_field_type();
|
||||
if ( ! empty( $descriptor_type ) ) {
|
||||
$field_data = $descriptor->to_array();
|
||||
if ( isset( $field_data['fields'] ) && ! empty( $field_data['fields'] ) ) {
|
||||
$field_data['fields'] = $this->prepare_fields_output( $field_data['fields'] );
|
||||
}
|
||||
$fields[ $descriptor_type ] = $field_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information of a field.
|
||||
*
|
||||
* @param array $request Pointer to ReduxFramework object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_field( $request = array() ) {
|
||||
$type = $request['type'];
|
||||
|
||||
$field_classes = $this->get_field_paths();
|
||||
if ( isset( $field_classes[ mb_strtolower( $type ) ] ) ) {
|
||||
$class = 'Redux_' . ucwords( str_replace( '-', '_', $type ) );
|
||||
if ( ! class_exists( $class ) ) {
|
||||
require_once $field_classes[ mb_strtolower( $type ) ];
|
||||
}
|
||||
$field_class = array( 'Redux_' . ucwords( $type ), 'ReduxFramework_' . ucwords( $type ) );
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_class );
|
||||
|
||||
if ( $field_class && is_subclass_of( $field_class, 'Redux_Field' ) ) {
|
||||
/**
|
||||
* Test if the field exists
|
||||
*
|
||||
* @var Redux_Descriptor $descriptor
|
||||
*/
|
||||
$descriptor = call_user_func( array( $field_class, 'get_descriptor' ) );
|
||||
|
||||
$data = $descriptor->to_array();
|
||||
if ( isset( $data['fields'] ) ) {
|
||||
$data['fields'] = $this->prepare_fields_output( $data['fields'] );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
return array( 'success' => false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to order the fields based on the order key.
|
||||
*
|
||||
* @param array $a First value.
|
||||
* @param array $b Second value.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sort_by_order( $a, $b ) {
|
||||
return $a['order'] - $b['order'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the fields value to have the proper order.
|
||||
*
|
||||
* @param array $fields Array of fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function prepare_fields_output( $fields = array() ) {
|
||||
if ( empty( $fields ) ) {
|
||||
return $fields;
|
||||
}
|
||||
$new_output = array_values( $fields );
|
||||
usort( $new_output, array( $this, 'sort_by_order' ) );
|
||||
foreach ( $new_output as $key => $item ) {
|
||||
if ( isset( $item['order'] ) ) {
|
||||
unset( $new_output[ $key ]['order'] );
|
||||
}
|
||||
}
|
||||
return $new_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the html of a field and return it to the api.
|
||||
*
|
||||
* @param array $request Name of field.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function render_field( $request = array() ) {
|
||||
$type = $request['type'];
|
||||
$field_classes = $this->get_field_paths();
|
||||
if ( isset( $field_classes[ mb_strtolower( $type ) ] ) ) {
|
||||
$class = 'Redux_' . ucwords( str_replace( '-', '_', $type ) );
|
||||
if ( ! class_exists( $class ) ) {
|
||||
require_once $field_classes[ mb_strtolower( $type ) ];
|
||||
}
|
||||
$field_class = array( 'Redux_' . ucwords( $type ), 'ReduxFramework_' . ucwords( $type ) );
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_class );
|
||||
|
||||
if ( $field_class && is_subclass_of( $field_class, 'Redux_Field' ) ) {
|
||||
// TODO MODIFY the function to get the post data from the data object with a post method in the register route!
|
||||
try {
|
||||
$class = new ReflectionClass( 'ReduxFramework_' . $type );
|
||||
} catch ( ReflectionException $e ) {
|
||||
return array( 'success' => false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the field descriptor
|
||||
*
|
||||
* @var Redux_Descriptor $descriptor
|
||||
*/
|
||||
$descriptor = call_user_func( array( 'ReduxFramework_' . $type, 'get_descriptor' ) );
|
||||
$opt_name = 'redux_builder_api';
|
||||
|
||||
$redux_instance = new ReduxFramework( array(), array( 'opt_name' => $opt_name ) );
|
||||
$req = $descriptor->parse_request( $request );
|
||||
|
||||
$req = wp_parse_args(
|
||||
$req,
|
||||
array(
|
||||
'class' => '',
|
||||
'example_values' => '',
|
||||
'name_suffix' => '',
|
||||
)
|
||||
);
|
||||
|
||||
$req['id'] = isset( $request['id'] ) ? $request['id'] : 'redux_field';
|
||||
$req['name'] = isset( $request['name'] ) ? $request['name'] : $req['id'];
|
||||
|
||||
$field = $class->newInstance( $req, $request['example_values'], $redux_instance );
|
||||
ob_start();
|
||||
$field->render();
|
||||
|
||||
return array(
|
||||
'success' => true,
|
||||
'render' => ob_get_clean(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array( 'success' => false );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Sanitize Class
|
||||
*
|
||||
* @class Redux_Sanitize
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Sanitize', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Sanitize
|
||||
*/
|
||||
class Redux_Sanitize extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Sanitize values from options form (used in settings api validate function)
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $plugin_options PLugin Options.
|
||||
* @param array $options Options.
|
||||
* @param array $sections Sections array.
|
||||
*
|
||||
* @return array $plugin_options
|
||||
*/
|
||||
public function sanitize( $plugin_options, $options, $sections ) {
|
||||
$core = $this->core();
|
||||
|
||||
foreach ( $sections as $k => $section ) {
|
||||
if ( isset( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $fkey => $field ) {
|
||||
|
||||
if ( is_array( $field ) ) {
|
||||
$field['section_id'] = $k;
|
||||
}
|
||||
|
||||
if ( isset( $field['type'] ) && ( 'text' === $field['type'] || 'textarea' === $field['type'] || 'multi_text' === $field['type'] ) ) {
|
||||
|
||||
// Make sure 'sanitize' field is set.
|
||||
if ( isset( $field['sanitize'] ) ) {
|
||||
|
||||
// Can we make this an array of validations?
|
||||
$val_arr = array();
|
||||
|
||||
if ( is_array( $field['sanitize'] ) ) {
|
||||
$val_arr = $field['sanitize'];
|
||||
} else {
|
||||
$val_arr[] = $field['sanitize'];
|
||||
}
|
||||
|
||||
foreach ( $val_arr as $idx => $function ) {
|
||||
|
||||
// Check for empty id value.
|
||||
if ( ! isset( $field['id'] ) || ! isset( $plugin_options[ $field['id'] ] ) || ( isset( $plugin_options[ $field['id'] ] ) && '' === $plugin_options[ $field['id'] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( function_exists( $function ) ) {
|
||||
if ( empty( $options[ $field['id'] ] ) ) {
|
||||
$options[ $field['id'] ] = '';
|
||||
}
|
||||
|
||||
if ( isset( $plugin_options[ $field['id'] ] ) && is_array( $plugin_options[ $field['id'] ] ) && ! empty( $plugin_options[ $field['id'] ] ) ) {
|
||||
foreach ( $plugin_options[ $field['id'] ] as $key => $value ) {
|
||||
$before = null;
|
||||
$after = null;
|
||||
|
||||
if ( isset( $plugin_options[ $field['id'] ][ $key ] ) && ( ! empty( $plugin_options[ $field['id'] ][ $key ] ) || '0' === $plugin_options[ $field['id'] ][ $key ] ) ) {
|
||||
if ( is_array( $plugin_options[ $field['id'] ][ $key ] ) ) {
|
||||
$before = $plugin_options[ $field['id'] ][ $key ];
|
||||
} else {
|
||||
$before = trim( $plugin_options[ $field['id'] ][ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $options[ $field['id'] ][ $key ] ) && ( ! empty( $plugin_options[ $field['id'] ][ $key ] ) || '0' === $plugin_options[ $field['id'] ][ $key ] ) ) {
|
||||
$after = $options[ $field['id'] ][ $key ];
|
||||
}
|
||||
|
||||
$value = call_user_func( $function, $before );
|
||||
|
||||
if ( ! empty( $value ) || false !== $value ) {
|
||||
$plugin_options[ $field['id'] ][ $key ] = $value;
|
||||
} else {
|
||||
unset( $plugin_options[ $field['id'] ][ $key ] );
|
||||
}
|
||||
|
||||
$field['current'] = $value;
|
||||
|
||||
$core->sanitize[] = $field;
|
||||
}
|
||||
} else {
|
||||
if ( isset( $plugin_options[ $field['id'] ] ) ) {
|
||||
if ( is_array( $plugin_options[ $field['id'] ] ) ) {
|
||||
$pofi = $plugin_options[ $field['id'] ];
|
||||
} else {
|
||||
$pofi = trim( $plugin_options[ $field['id'] ] );
|
||||
}
|
||||
} else {
|
||||
$pofi = null;
|
||||
}
|
||||
|
||||
$value = call_user_func( $function, $pofi );
|
||||
|
||||
$plugin_options[ $field['id'] ] = $value;
|
||||
|
||||
$field['current'] = $value;
|
||||
|
||||
$core->sanitize[] = $field;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $plugin_options;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux ThirdParty Fixes Class
|
||||
*
|
||||
* @class Redux_ThirdParty_Fixes
|
||||
* @version 3.0.0
|
||||
* @package Redux Framework/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_ThirdParty_Fixes', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_ThirdParty_Fixes
|
||||
*/
|
||||
class Redux_ThirdParty_Fixes extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Redux_ThirdParty_Fixes constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
$this->gt3_page_builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* GT3 Page Buiolder fix.
|
||||
*/
|
||||
private function gt3_page_builder() {
|
||||
// Fix for the GT3 page builder: http://www.gt3themes.com/wordpress-gt3-page-builder-plugin/.
|
||||
if ( has_action( 'ecpt_field_options_' ) ) {
|
||||
global $pagenow;
|
||||
|
||||
if ( 'admin.php' === $pagenow ) {
|
||||
remove_action( 'admin_init', 'pb_admin_init' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Transients Class
|
||||
*
|
||||
* @class Redux_Transients
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Transients', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Transients
|
||||
*/
|
||||
class Redux_Transients extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Get transients from database.
|
||||
*/
|
||||
public function get() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( empty( $core->transients ) ) {
|
||||
$core->transients = get_option( $core->args['opt_name'] . '-transients', array() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set transients in database.
|
||||
*/
|
||||
public function set() {
|
||||
$core = $this->core();
|
||||
|
||||
if ( ! isset( $core->transients ) || ! isset( $core->transients_check ) || $core->transients_check !== $core->transients ) {
|
||||
update_option( $core->args['opt_name'] . '-transients', $core->transients );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin review class.
|
||||
* Prompts users to give a review of the plugin on WordPress.org after a period of usage.
|
||||
*
|
||||
* Heavily based on code by CoBlocks
|
||||
* https://github.com/coblocks/coblocks/blob/master/includes/admin/class-coblocks-feedback.php
|
||||
*
|
||||
* @package Redux
|
||||
* @author Jeffrey Carandang
|
||||
* @link https://redux.io
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Feedback Notice Class
|
||||
*/
|
||||
class Redux_User_Feedback {
|
||||
|
||||
/**
|
||||
* Slug.
|
||||
*
|
||||
* @var string $slug
|
||||
*/
|
||||
private $slug;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*
|
||||
* @var string $name
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Time limit.
|
||||
*
|
||||
* @var string $time_limit
|
||||
*/
|
||||
private $time_limit;
|
||||
|
||||
/**
|
||||
* No Bug Option.
|
||||
*
|
||||
* @var string $nobug_option
|
||||
*/
|
||||
public $nobug_option;
|
||||
|
||||
/**
|
||||
* Activation Date Option.
|
||||
*
|
||||
* @var string $date_option
|
||||
*/
|
||||
public $date_option;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param string $args Arguments.
|
||||
*/
|
||||
public function __construct( $args ) {
|
||||
|
||||
$this->slug = $args['slug'];
|
||||
$this->name = $args['name'];
|
||||
|
||||
$this->date_option = $this->slug . '_activation_date';
|
||||
$this->nobug_option = $this->slug . '_no_bug';
|
||||
|
||||
if ( isset( $args['time_limit'] ) ) {
|
||||
$this->time_limit = $args['time_limit'];
|
||||
} else {
|
||||
$this->time_limit = WEEK_IN_SECONDS;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Framework_Plugin' ) || ( class_exists( 'Redux_Framework_Plugin' ) && false === Redux_Framework_Plugin::$crash ) ) {
|
||||
// Add actions.
|
||||
add_action( 'admin_init', array( $this, 'check_installation_date' ) );
|
||||
add_action( 'admin_init', array( $this, 'set_no_bug' ), 5 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Seconds to words.
|
||||
*
|
||||
* @param string $seconds Seconds in time.
|
||||
* @return string
|
||||
*/
|
||||
public function seconds_to_words( $seconds ) {
|
||||
|
||||
// Get the years.
|
||||
$years = ( intval( $seconds ) / YEAR_IN_SECONDS ) % 100;
|
||||
if ( $years > 1 ) {
|
||||
/* translators: Number of years */
|
||||
return sprintf( __( '%s years', 'redux-framework' ), $years );
|
||||
} elseif ( $years > 0 ) {
|
||||
return __( 'a year', 'redux-framework' );
|
||||
}
|
||||
|
||||
// Get the weeks.
|
||||
$weeks = ( intval( $seconds ) / WEEK_IN_SECONDS ) % 52;
|
||||
if ( $weeks > 1 ) {
|
||||
/* translators: Number of weeks */
|
||||
return sprintf( __( '%s weeks', 'redux-framework' ), $weeks );
|
||||
} elseif ( $weeks > 0 ) {
|
||||
return __( 'a week', 'redux-framework' );
|
||||
}
|
||||
|
||||
// Get the days.
|
||||
$days = ( intval( $seconds ) / DAY_IN_SECONDS ) % 7;
|
||||
if ( $days > 1 ) {
|
||||
/* translators: Number of days */
|
||||
return sprintf( __( '%s days', 'redux-framework' ), $days );
|
||||
} elseif ( $days > 0 ) {
|
||||
return __( 'a day', 'redux-framework' );
|
||||
}
|
||||
|
||||
// Get the hours.
|
||||
$hours = ( intval( $seconds ) / HOUR_IN_SECONDS ) % 24;
|
||||
if ( $hours > 1 ) {
|
||||
/* translators: Number of hours */
|
||||
return sprintf( __( '%s hours', 'redux-framework' ), $hours );
|
||||
} elseif ( $hours > 0 ) {
|
||||
return __( 'an hour', 'redux-framework' );
|
||||
}
|
||||
|
||||
// Get the minutes.
|
||||
$minutes = ( intval( $seconds ) / MINUTE_IN_SECONDS ) % 60;
|
||||
if ( $minutes > 1 ) {
|
||||
/* translators: Number of minutes */
|
||||
return sprintf( __( '%s minutes', 'redux-framework' ), $minutes );
|
||||
} elseif ( $minutes > 0 ) {
|
||||
return __( 'a minute', 'redux-framework' );
|
||||
}
|
||||
|
||||
// Get the seconds.
|
||||
$seconds = intval( $seconds ) % 60;
|
||||
if ( $seconds > 1 ) {
|
||||
/* translators: Number of seconds */
|
||||
return sprintf( __( '%s seconds', 'redux-framework' ), $seconds );
|
||||
} elseif ( $seconds > 0 ) {
|
||||
return __( 'a second', 'redux-framework' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check date on admin initiation and add to admin notice if it was more than the time limit.
|
||||
*/
|
||||
public function check_installation_date() {
|
||||
|
||||
if ( ! get_site_option( $this->nobug_option ) || false === get_site_option( $this->nobug_option ) ) {
|
||||
|
||||
add_site_option( $this->date_option, time() );
|
||||
|
||||
// Retrieve the activation date.
|
||||
$install_date = get_site_option( $this->date_option );
|
||||
|
||||
// If difference between install date and now is greater than time limit, then display notice.
|
||||
if ( ( time() - $install_date ) > $this->time_limit ) {
|
||||
add_action( 'admin_notices', array( $this, 'display_admin_notice' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the admin notice.
|
||||
*/
|
||||
public function display_admin_notice() {
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( isset( $screen->base ) && 'plugins' === $screen->base ) {
|
||||
$no_bug_url = wp_nonce_url( admin_url( 'plugins.php?' . $this->nobug_option . '=true' ), 'redux-feedback-nounce' );
|
||||
$time = $this->seconds_to_words( time() - get_site_option( $this->date_option ) );
|
||||
?>
|
||||
<style>
|
||||
.notice.redux-notice {
|
||||
border-left-color: #24b0a6 !important;
|
||||
padding: 20px;
|
||||
}
|
||||
.rtl .notice.redux-notice {
|
||||
border-right-color: #19837c !important;
|
||||
}
|
||||
.notice.notice.redux-notice .redux-notice-inner {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-icon,
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-content,
|
||||
.notice.redux-notice .redux-notice-inner .redux-install-now {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.notice.redux-notice .redux-notice-icon {
|
||||
color: #509ed2;
|
||||
font-size: 13px;
|
||||
width: 60px;
|
||||
}
|
||||
.notice.redux-notice .redux-notice-icon img {
|
||||
width: 64px;
|
||||
}
|
||||
.notice.redux-notice .redux-notice-content {
|
||||
padding: 0 40px 0 20px;
|
||||
}
|
||||
.notice.redux-notice p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.notice.redux-notice h3 {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
.notice.redux-notice .redux-install-now {
|
||||
text-align: center;
|
||||
}
|
||||
.notice.redux-notice .redux-install-now .redux-install-button {
|
||||
padding: 6px 50px;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
background: #24b0a6;
|
||||
border-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
.notice.redux-notice .redux-install-now .redux-install-button:hover {
|
||||
background: #19837c;
|
||||
}
|
||||
.notice.redux-notice a.no-thanks {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: #72777c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.notice.redux-notice a.no-thanks:hover {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
.notice.notice.redux-notice .redux-notice-inner {
|
||||
display: block;
|
||||
}
|
||||
.notice.redux-notice {
|
||||
padding: 20px !important;
|
||||
}
|
||||
.notice.redux-noticee .redux-notice-inner {
|
||||
display: block;
|
||||
}
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-content {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
.notice.redux-notice .redux-notice-inner .redux-notice-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .redux-install-now {
|
||||
margin-top: 20px;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.notice.redux-notice .redux-notice-inner .no-thanks {
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="notice updated redux-notice">
|
||||
<div class="redux-notice-inner">
|
||||
<div class="redux-notice-icon">
|
||||
<?php /* translators: 1. Name */ ?>
|
||||
<img src="<?php echo esc_url( Redux_Core::$url . '/assets/img/icon--color.svg' ); ?>" alt="<?php printf( esc_attr__( '%s WordPress Plugin', 'redux-framework' ), esc_attr( $this->name ) ); ?>" />
|
||||
</div>
|
||||
<div class="redux-notice-content">
|
||||
<?php /* translators: 1. Name */ ?>
|
||||
<h3><?php printf( esc_html__( 'Are you enjoying %s?', 'redux-framework' ), esc_html( $this->name ) ); ?></h3>
|
||||
<p>
|
||||
<?php /* translators: 1. Name, 2. Time */ ?>
|
||||
<?php printf( esc_html__( 'You have been using %1$s for %2$s now. Would you mind leaving a review to let us know know what you think? We\'d really appreciate it!', 'redux-framework' ), esc_html( $this->name ), esc_html( $time ) ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="redux-install-now">
|
||||
<?php printf( '<a href="%1$s" class="button button-primary redux-install-button" target="_blank">%2$s</a>', esc_url( 'https://wordpress.org/support/plugin/redux-framework/reviews/?filter=5#new-post' ), esc_html__( 'Leave a Review', 'redux-framework' ) ); ?>
|
||||
<a href="<?php echo esc_url( $no_bug_url ); ?>" class="no-thanks"><?php echo esc_html__( 'No thanks / I already have', 'redux-framework' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plugin to no longer bug users if user asks not to be.
|
||||
*/
|
||||
public function set_no_bug() {
|
||||
|
||||
// Bail out if not on correct page.
|
||||
// phpcs:ignore
|
||||
if ( ! isset( $_GET['_wpnonce'] ) || ( ! wp_verify_nonce( $_GET['_wpnonce'], 'redux-feedback-nounce' ) || ! is_admin() || ! isset( $_GET[ $this->nobug_option ] ) || ! current_user_can( 'manage_options' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_site_option( $this->nobug_option, true );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Instantiate the Redux_User_Feedback class.
|
||||
*/
|
||||
new Redux_User_Feedback(
|
||||
array(
|
||||
'slug' => 'Redux_plugin_feedback',
|
||||
'name' => __( 'Redux', 'redux-framework' ),
|
||||
'time_limit' => WEEK_IN_SECONDS,
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Validate Class
|
||||
*
|
||||
* @class Redux_Validate
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Validate', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Validate
|
||||
*/
|
||||
abstract class Redux_Validate {
|
||||
|
||||
/**
|
||||
* Redux_Validate constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
* @param array $field Fields array.
|
||||
* @param array $value Values array.
|
||||
* @param mixed $current Current.
|
||||
*/
|
||||
public function __construct( $parent, $field, $value, $current ) {
|
||||
$this->parent = $parent;
|
||||
$this->field = $field;
|
||||
$this->value = $value;
|
||||
$this->current = $current;
|
||||
|
||||
if ( isset( $this->field['validate_msg'] ) ) {
|
||||
$this->field['msg'] = $this->field['validate_msg'];
|
||||
|
||||
unset( $this->field['validate_msg'] );
|
||||
}
|
||||
|
||||
$this->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function validate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Validation Class
|
||||
*
|
||||
* @class Redux_Validation
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Validation', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Validation
|
||||
*/
|
||||
class Redux_Validation extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Validate values from options form (used in settings api validate function)
|
||||
* calls the custom validation class for the field so authors can override with custom classes
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $plugin_options Plugin Options.
|
||||
* @param array $options Options.
|
||||
* @param array $sections Sections array.
|
||||
*
|
||||
* @return array $plugin_options
|
||||
*/
|
||||
public function validate( $plugin_options, $options, $sections ) {
|
||||
$core = $this->core();
|
||||
|
||||
foreach ( $sections as $k => $section ) {
|
||||
if ( isset( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $fkey => $field ) {
|
||||
|
||||
if ( is_array( $field ) ) {
|
||||
$field['section_id'] = $k;
|
||||
}
|
||||
|
||||
if ( isset( $field['type'] ) && ( 'checkbox' === $field['type'] || 'checkbox_hide_below' === $field['type'] || 'checkbox_hide_all' === $field['type'] ) ) {
|
||||
if ( ! isset( $plugin_options[ $field['id'] ] ) ) {
|
||||
$plugin_options[ $field['id'] ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Part of Dovy's serialize typography effort. Preserved here in case it becomes a thing. - kp.
|
||||
/**
|
||||
* If ( isset ( $field['type'] ) && $field['type'] == 'typography' ) {
|
||||
* if ( ! is_array( $plugin_options[ $field['id'] ] ) && ! empty( $plugin_options[ $field['id'] ] ) ) {
|
||||
* $plugin_options[ $field['id'] ] = json_decode( $plugin_options[ $field['id'] ], true );
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
if ( isset( $core->extensions[ $field['type'] ] ) && method_exists( $core->extensions[ $field['type'] ], '_validate_values' ) ) {
|
||||
$plugin_options = $core->extensions[ $field['type'] ]->_validate_values( $plugin_options, $field, $sections );
|
||||
}
|
||||
|
||||
// Make sure 'validate' field is set.
|
||||
if ( isset( $field['validate'] ) ) {
|
||||
|
||||
// Can we make this an array of validations?
|
||||
$val_arr = array();
|
||||
|
||||
if ( is_array( $field['validate'] ) ) {
|
||||
$val_arr = $field['validate'];
|
||||
} else {
|
||||
$val_arr[] = $field['validate'];
|
||||
}
|
||||
|
||||
foreach ( $val_arr as $idx => $val ) {
|
||||
// shim for old *_not_empty validations.
|
||||
if ( 'email_not_empty' === $val || 'numeric_not_empty' === $val ) {
|
||||
$val = 'not_empty';
|
||||
}
|
||||
|
||||
// Make sure 'validate field' is set to 'not_empty'.
|
||||
$is_not_empty = false;
|
||||
|
||||
if ( 'not_empty' === $val ) {
|
||||
// Set the flag.
|
||||
$is_not_empty = true;
|
||||
}
|
||||
|
||||
// Check for empty id value.
|
||||
if ( ! isset( $field['id'] ) || ! isset( $plugin_options[ $field['id'] ] ) || ( isset( $plugin_options[ $field['id'] ] ) && '' === $plugin_options[ $field['id'] ] ) ) {
|
||||
|
||||
// If we are looking for an empty value, in the case of 'not_empty'
|
||||
// then we need to keep processing.
|
||||
if ( ! $is_not_empty ) {
|
||||
|
||||
// Empty id and not checking for 'not_empty. Bail out...
|
||||
if ( ! isset( $field['validate_callback'] ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Force validate of custom field types.
|
||||
if ( isset( $field['type'] ) && ! isset( $val ) && ! isset( $field['validate_callback'] ) ) {
|
||||
if ( 'color' === $field['type'] || 'color_gradient' === $field['type'] ) {
|
||||
$val = 'color';
|
||||
} elseif ( 'date' === $field['type'] ) {
|
||||
$val = 'date';
|
||||
}
|
||||
}
|
||||
|
||||
// No need. Spectrum self validates.
|
||||
if ( 'color_rgba' === $field['type'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Shim out old colorgrba validators.
|
||||
if ( 'color_rgba' === $val || 'colorrgba' === $val ) {
|
||||
$val = 'color';
|
||||
}
|
||||
|
||||
$validate = 'Redux_Validation_' . $val;
|
||||
|
||||
if ( ! class_exists( $validate ) ) {
|
||||
|
||||
/**
|
||||
* Filter 'redux/validate/{opt_name}/class/{field.validate}'
|
||||
*
|
||||
* @param string validation class file path
|
||||
* @param string $class_file validation class file path
|
||||
*/
|
||||
|
||||
$file = str_replace( '_', '-', $val );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$class_file = apply_filters( "redux/validate/{$core->args['opt_name']}/class/{$val}", Redux_Core::$dir . "inc/validation/{$val}/class-redux-validation-{$file}.php", $validate );
|
||||
|
||||
if ( $class_file ) {
|
||||
if ( file_exists( $class_file ) ) {
|
||||
require_once $class_file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $validate ) ) {
|
||||
if ( empty( $options[ $field['id'] ] ) ) {
|
||||
$options[ $field['id'] ] = '';
|
||||
}
|
||||
|
||||
if ( isset( $plugin_options[ $field['id'] ] ) && is_array( $plugin_options[ $field['id'] ] ) && ! empty( $plugin_options[ $field['id'] ] ) ) {
|
||||
foreach ( $plugin_options[ $field['id'] ] as $key => $value ) {
|
||||
$before = null;
|
||||
$after = null;
|
||||
|
||||
if ( isset( $plugin_options[ $field['id'] ][ $key ] ) && ( ! empty( $plugin_options[ $field['id'] ][ $key ] ) || '0' === $plugin_options[ $field['id'] ][ $key ] ) ) {
|
||||
if ( is_array( $plugin_options[ $field['id'] ][ $key ] ) ) {
|
||||
$before = $plugin_options[ $field['id'] ][ $key ];
|
||||
} else {
|
||||
$before = trim( $plugin_options[ $field['id'] ][ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $options[ $field['id'] ][ $key ] ) && ( ! empty( $plugin_options[ $field['id'] ][ $key ] ) || '0' === $plugin_options[ $field['id'] ][ $key ] ) ) {
|
||||
$after = $options[ $field['id'] ][ $key ];
|
||||
}
|
||||
|
||||
$validation = new $validate( $core, $field, $before, $after );
|
||||
|
||||
if ( ! empty( $validation->value ) || '0' === $validation->value ) {
|
||||
$plugin_options[ $field['id'] ][ $key ] = $validation->value;
|
||||
} else {
|
||||
unset( $plugin_options[ $field['id'] ][ $key ] );
|
||||
}
|
||||
|
||||
if ( isset( $validation->error ) ) {
|
||||
$core->errors[] = $validation->error;
|
||||
}
|
||||
|
||||
if ( isset( $validation->warning ) ) {
|
||||
$core->warnings[] = $validation->warning;
|
||||
}
|
||||
|
||||
if ( isset( $validation->sanitize ) ) {
|
||||
$core->sanitize[] = $validation->sanitize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( isset( $plugin_options[ $field['id'] ] ) ) {
|
||||
if ( is_array( $plugin_options[ $field['id'] ] ) ) {
|
||||
$pofi = $plugin_options[ $field['id'] ];
|
||||
} else {
|
||||
$pofi = trim( $plugin_options[ $field['id'] ] );
|
||||
}
|
||||
} else {
|
||||
$pofi = null;
|
||||
}
|
||||
|
||||
$validation = new $validate( $core, $field, $pofi, $options[ $field['id'] ] );
|
||||
$plugin_options[ $field['id'] ] = $validation->value;
|
||||
|
||||
if ( isset( $validation->error ) ) {
|
||||
$core->errors[] = $validation->error;
|
||||
}
|
||||
|
||||
if ( isset( $validation->warning ) ) {
|
||||
$core->warnings[] = $validation->warning;
|
||||
}
|
||||
|
||||
if ( isset( $validation->sanitize ) ) {
|
||||
$core->sanitize[] = $validation->sanitize;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $field['validate_callback'] ) && ( is_callable( $field['validate_callback'] ) || ( is_string( $field['validate_callback'] ) && function_exists( $field['validate_callback'] ) ) ) ) {
|
||||
$callback = $field['validate_callback'];
|
||||
unset( $field['validate_callback'] );
|
||||
|
||||
$plugin_option = isset( $plugin_options[ $field['id'] ] ) ? $plugin_options[ $field['id'] ] : null;
|
||||
$option = isset( $options[ $field['id'] ] ) ? $options[ $field['id'] ] : null;
|
||||
|
||||
$callbackvalues = call_user_func( $callback, $field, $plugin_option, $option );
|
||||
|
||||
$plugin_options[ $field['id'] ] = $callbackvalues['value'];
|
||||
|
||||
if ( isset( $callbackvalues['error'] ) ) {
|
||||
$core->errors[] = $callbackvalues['error'];
|
||||
}
|
||||
|
||||
if ( isset( $callbackvalues['warning'] ) ) {
|
||||
$core->warnings[] = $callbackvalues['warning'];
|
||||
}
|
||||
|
||||
if ( isset( $callbackvalues['sanitize'] ) ) {
|
||||
$core->sanitize[] = $callbackvalues['sanitize'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $plugin_options;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,695 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux WordPress Data Class
|
||||
*
|
||||
* @class Redux_WordPress_Data
|
||||
* @version 3.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_WordPress_Data', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_WordPress_Data
|
||||
*/
|
||||
class Redux_WordPress_Data extends Redux_Class {
|
||||
|
||||
/**
|
||||
* Holds WordPress data.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $wp_data = null;
|
||||
|
||||
/**
|
||||
* Redux_WordPress_Data constructor.
|
||||
*
|
||||
* @param mixed $parent ReduxFramework pointer or opt_name.
|
||||
*/
|
||||
public function __construct( $parent = null ) {
|
||||
if ( is_string( $parent ) ) {
|
||||
$this->opt_name = $parent;
|
||||
} else {
|
||||
parent::__construct( $parent );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data.
|
||||
*
|
||||
* @param bool $type Type.
|
||||
* @param array $args Args.
|
||||
* @param string|int $current_value Current value.
|
||||
* @param bool $ajax Tells if this is a AJAX call.
|
||||
*
|
||||
* @return array|mixed|string
|
||||
*/
|
||||
public function get( $type = false, $args = array(), $current_value = '', $ajax = false ) {
|
||||
$opt_name = $this->opt_name;
|
||||
|
||||
// We don't want to run this, it's not a string value. Send it back!
|
||||
if ( is_array( $type ) ) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter 'redux/options/{opt_name}/pre_data/{type}'
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
$pre_data = apply_filters( "redux/options/{$opt_name}/pre_data/$type", null ); // phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
if ( null !== $pre_data || empty( $type ) ) {
|
||||
return $pre_data;
|
||||
}
|
||||
|
||||
if ( isset( $args['data_sortby'] ) && in_array( $args['data_sortby'], array( 'value', 'key' ), true ) ) {
|
||||
$data_sort = $args['data_sortby'];
|
||||
unset( $args['data_sortby'] );
|
||||
} else {
|
||||
$data_sort = 'value';
|
||||
}
|
||||
if ( isset( $args['data_order'] ) && in_array( $args['data_order'], array( 'asc', 'desc' ), true ) ) {
|
||||
$data_order = $args['data_order'];
|
||||
unset( $args['data_order'] );
|
||||
} else {
|
||||
$data_order = 'asc';
|
||||
}
|
||||
|
||||
$this->maybe_get_translation( $type, $current_value, $args );
|
||||
|
||||
$current_data = array();
|
||||
if ( empty( $current_value ) && ! Redux_Helpers::is_integer( $current_value ) ) {
|
||||
$current_value = null;
|
||||
} else {
|
||||
// Get the args to grab the current data.
|
||||
$current_data_args = $this->get_current_data_args( $type, $args, $current_value );
|
||||
|
||||
// Let's make a unique key for this arg array.
|
||||
$current_data_args_key = md5( maybe_serialize( $current_data_args ) );
|
||||
|
||||
// Check to make sure we haven't already run this call before.
|
||||
if ( isset( $this->wp_data[ $type . $current_data_args_key ] ) ) {
|
||||
$current_data = $this->wp_data[ $type . $current_data_args_key ];
|
||||
} else {
|
||||
$current_data = $this->get_data( $type, $current_data_args, $current_value );
|
||||
}
|
||||
}
|
||||
|
||||
// If ajax is enabled AND $current_data is empty, set a dummy value for the init.
|
||||
if ( $ajax && ! wp_doing_ajax() ) {
|
||||
// Dummy is needed otherwise empty.
|
||||
if ( empty( $current_data ) ) {
|
||||
$current_data = array(
|
||||
'dummy' => '',
|
||||
);
|
||||
}
|
||||
|
||||
return $current_data;
|
||||
}
|
||||
|
||||
// phpcs:ignore Squiz.PHP.CommentedOutCode
|
||||
$args_key = md5( maybe_serialize( $args ) );
|
||||
|
||||
// Data caching.
|
||||
if ( isset( $this->wp_data[ $type . $args_key ] ) ) {
|
||||
$data = $this->wp_data[ $type . $args_key ];
|
||||
} else {
|
||||
/**
|
||||
* Use data from WordPress to populate options array.
|
||||
* */
|
||||
$data = $this->get_data( $type, $args, $current_value );
|
||||
}
|
||||
|
||||
if ( ! empty( $current_data ) ) {
|
||||
$data += $current_data;
|
||||
}
|
||||
|
||||
if ( ! empty( $data ) ) {
|
||||
$data = $this->order_data( $data, $data_sort, $data_order );
|
||||
$this->wp_data[ $type . $args_key ] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter 'redux/options/{opt_name}/data/{type}'
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$data = apply_filters( "redux/options/{$opt_name}/data/$type", $data );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the results into a proper array, fetching the data elements needed for each data type.
|
||||
*
|
||||
* @param array $results Results to process in the data array.
|
||||
* @param string|bool $id_key Key on object/array that represents the ID.
|
||||
* @param string|bool $name_key Key on object/array that represents the name/text.
|
||||
* @param bool $add_key If true, the display key will appear in the text..
|
||||
* @param string|bool $secondary_key If a data type you'd rather display a different ID as the display key.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function process_results( $results = array(), $id_key = '', $name_key = '', $add_key = true, $secondary_key = 'slug' ) {
|
||||
$data = array();
|
||||
if ( ! empty( $results ) && ! is_a( $results, 'WP_Error' ) ) {
|
||||
foreach ( $results as $k => $v ) {
|
||||
if ( empty( $id_key ) ) {
|
||||
$key = $k;
|
||||
} else {
|
||||
if ( is_object( $v ) ) {
|
||||
$key = $v->$id_key;
|
||||
} elseif ( is_array( $v ) ) {
|
||||
$key = $v[ $id_key ];
|
||||
} else {
|
||||
$key = $k;
|
||||
}
|
||||
}
|
||||
if ( empty( $name_key ) ) {
|
||||
$value = $v;
|
||||
} else {
|
||||
if ( is_object( $v ) ) {
|
||||
$value = $v->$name_key;
|
||||
} elseif ( is_array( $v ) ) {
|
||||
$value = $v[ $name_key ];
|
||||
} else {
|
||||
$value = $v;
|
||||
}
|
||||
}
|
||||
$display_key = $key;
|
||||
if ( is_object( $v ) && isset( $v->$secondary_key ) ) {
|
||||
$display_key = $v->$secondary_key;
|
||||
} elseif ( ! is_object( $v ) && isset( $v[ $secondary_key ] ) ) {
|
||||
$display_key = $v[ $secondary_key ];
|
||||
}
|
||||
$data[ $key ] = $value;
|
||||
if ( $display_key !== $value && $add_key ) {
|
||||
$data[ $key ] = $data[ $key ] . ' [' . $display_key . ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order / Sort the data.
|
||||
*
|
||||
* @param array $data Data to sort.
|
||||
* @param string $sort Way to sort. Accepts: key|value.
|
||||
* @param string $order Order of the sort. Accepts: asc|desc.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function order_data( $data = array(), $sort = 'value', $order = 'asc' ) {
|
||||
if ( 'key' === $sort ) {
|
||||
if ( 'asc' === $order ) {
|
||||
ksort( $data );
|
||||
} else {
|
||||
krsort( $data );
|
||||
}
|
||||
} elseif ( 'value' === $sort ) {
|
||||
if ( 'asc' === $order ) {
|
||||
asort( $data );
|
||||
} else {
|
||||
arsort( $data );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the data for a given type.
|
||||
*
|
||||
* @param string $type The data type we're fetching..
|
||||
* @param array $args Arguments to pass.
|
||||
* @param mixed $current_value If a current value already set in the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_data( $type, $args, $current_value ) {
|
||||
$args = $this->get_arg_defaults( $type, $args );
|
||||
|
||||
$opt_name = $this->opt_name;
|
||||
if ( empty( $args ) ) {
|
||||
$args = array();
|
||||
}
|
||||
|
||||
$data = array();
|
||||
if ( isset( $args['args'] ) && empty( $args['args'] ) ) {
|
||||
unset( $args['args'] );
|
||||
}
|
||||
|
||||
$display_keys = false;
|
||||
if ( isset( $args['display_keys'] ) ) {
|
||||
$display_keys = true;
|
||||
unset( $args['display_keys'] );
|
||||
}
|
||||
|
||||
$secondary_key = 'slug';
|
||||
if ( isset( $args['secondary_key'] ) ) {
|
||||
$display_key = $args['secondary_key'];
|
||||
unset( $args['secondary_key'] );
|
||||
}
|
||||
|
||||
switch ( $type ) {
|
||||
case 'categories':
|
||||
case 'category':
|
||||
case 'terms':
|
||||
case 'term':
|
||||
if ( isset( $args['taxonomies'] ) ) {
|
||||
$args['taxonomy'] = $args['taxonomies'];
|
||||
unset( $args['taxonomies'] );
|
||||
}
|
||||
$results = get_terms( $args );
|
||||
$data = $this->process_results( $results, 'term_id', 'name', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'pages':
|
||||
case 'page':
|
||||
$results = get_pages( $args );
|
||||
$data = $this->process_results( $results, 'ID', 'post_title', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'tags':
|
||||
case 'tag':
|
||||
$results = get_tags( $args );
|
||||
$data = $this->process_results( $results, 'term_id', 'name', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'menus':
|
||||
case 'menu':
|
||||
$results = wp_get_nav_menus( $args );
|
||||
$data = $this->process_results( $results, 'term_id', 'name', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'posts':
|
||||
case 'post':
|
||||
$results = get_posts( $args );
|
||||
$data = $this->process_results( $results, 'ID', 'post_title', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
case 'user':
|
||||
$results = get_users( $args );
|
||||
$data = $this->process_results( $results, 'ID', 'display_name', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'sites':
|
||||
case 'site':
|
||||
// WP > 4.6.
|
||||
if ( function_exists( 'get_sites' ) && class_exists( 'WP_Site_Query' ) ) {
|
||||
$sites = get_sites();
|
||||
// WP < 4.6.
|
||||
} elseif ( function_exists( 'wp_get_sites' ) ) {
|
||||
$sites = wp_get_sites(); // phpcs:ignore WordPress.WP.DeprecatedFunctions
|
||||
}
|
||||
if ( isset( $sites ) ) {
|
||||
$results = array();
|
||||
foreach ( $sites as $site ) {
|
||||
$site = (array) $site;
|
||||
$k = $site['blog_id'];
|
||||
$v = $site['domain'] . $site['path'];
|
||||
$name = get_blog_option( $k, 'blogname' );
|
||||
if ( ! empty( $name ) ) {
|
||||
$v .= ' - [' . $name . ']';
|
||||
}
|
||||
$results[ $k ] = $v;
|
||||
}
|
||||
$data = $this->process_results( $results, '', '', $display_keys, $secondary_key );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'taxonomies':
|
||||
case 'taxonomy':
|
||||
case 'tax':
|
||||
$results = get_taxonomies( $args );
|
||||
$data = $this->process_results( $results, '', '', $display_keys, $secondary_key );
|
||||
break;
|
||||
|
||||
case 'post_types':
|
||||
case 'post_type':
|
||||
global $wp_post_types;
|
||||
|
||||
$output = $args['output'];
|
||||
unset( $args['output'] );
|
||||
$operator = $args['operator'];
|
||||
unset( $args['operator'] );
|
||||
|
||||
$post_types = get_post_types( $args, $output, $operator );
|
||||
|
||||
foreach ( $post_types as $name => $title ) {
|
||||
if ( isset( $wp_post_types[ $name ]->labels->menu_name ) ) {
|
||||
$data[ $name ] = $wp_post_types[ $name ]->labels->menu_name;
|
||||
} else {
|
||||
$data[ $name ] = ucfirst( $name );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'menu_locations':
|
||||
case 'menu_location':
|
||||
global $_wp_registered_nav_menus;
|
||||
foreach ( $_wp_registered_nav_menus as $k => $v ) {
|
||||
$data[ $k ] = $v;
|
||||
if ( ! has_nav_menu( $k ) ) {
|
||||
$data[ $k ] .= ' ' . __( '[unassigned]', 'redux-framework' );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'image_sizes':
|
||||
case 'image_size':
|
||||
global $_wp_additional_image_sizes;
|
||||
$results = array();
|
||||
foreach ( $_wp_additional_image_sizes as $size_name => $size_attrs ) {
|
||||
$results[ $size_name ] = $size_name . ' - ' . $size_attrs['width'] . ' x ' . $size_attrs['height'];
|
||||
}
|
||||
$data = $this->process_results( $results, '', '', $display_keys, $secondary_key );
|
||||
|
||||
break;
|
||||
|
||||
case 'elusive-icons':
|
||||
case 'elusive-icon':
|
||||
case 'elusive':
|
||||
case 'icons':
|
||||
case 'font-icon':
|
||||
case 'font-icons':
|
||||
$fs = Redux_Filesystem::get_instance();
|
||||
$fonts = $fs->get_contents( Redux_Core::$dir . 'assets/css/vendor/elusive-icons.css' );
|
||||
if ( ! empty( $fonts ) ) {
|
||||
preg_match_all( '@\.el-(\w+)::before@', $fonts, $matches );
|
||||
foreach ( $matches[1] as $item ) {
|
||||
if ( 'before' === $item ) {
|
||||
continue;
|
||||
}
|
||||
$data[ 'el el-' . $item ] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter 'redux/font-icons'
|
||||
*
|
||||
* @param array $font_icons array of elusive icon classes
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$font_icons = apply_filters( 'redux/font-icons', $data );
|
||||
|
||||
/**
|
||||
* Filter 'redux/{opt_name}/field/font/icons'
|
||||
*
|
||||
* @param array $font_icons array of elusive icon classes
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$font_icons = apply_filters( "redux/{$opt_name}/field/font/icons", $font_icons );
|
||||
|
||||
break;
|
||||
|
||||
case 'dashicons':
|
||||
case 'dashicon':
|
||||
case 'dash':
|
||||
$fs = Redux_Filesystem::get_instance();
|
||||
$fonts = $fs->get_contents( ABSPATH . WPINC . '/css/dashicons.css' );
|
||||
if ( ! empty( $fonts ) ) {
|
||||
preg_match_all( '@\.dashicons-(\w+):before@', $fonts, $matches );
|
||||
foreach ( $matches[1] as $item ) {
|
||||
if ( 'before' === $item ) {
|
||||
continue;
|
||||
}
|
||||
$data[ 'dashicons dashicons-' . $item ] = $item;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'roles':
|
||||
case 'role':
|
||||
global $wp_roles;
|
||||
$results = $wp_roles->get_names();
|
||||
$data = $this->process_results( $results, '', '', $display_keys, $secondary_key );
|
||||
|
||||
break;
|
||||
|
||||
case 'sidebars':
|
||||
case 'sidebar':
|
||||
global $wp_registered_sidebars;
|
||||
$data = $this->process_results( $wp_registered_sidebars, '', 'name', $display_keys, $secondary_key );
|
||||
break;
|
||||
case 'capabilities':
|
||||
case 'capability':
|
||||
global $wp_roles;
|
||||
$results = array();
|
||||
foreach ( $wp_roles->roles as $role ) {
|
||||
foreach ( $role['capabilities'] as $key => $cap ) {
|
||||
$results[ $key ] = ucwords( str_replace( '_', ' ', $key ) );
|
||||
}
|
||||
}
|
||||
$data = $this->process_results( $results, '', '', $display_keys, $secondary_key );
|
||||
|
||||
break;
|
||||
|
||||
case 'capabilities_grouped':
|
||||
case 'capability_grouped':
|
||||
case 'capabilities_group':
|
||||
case 'capability_group':
|
||||
global $wp_roles;
|
||||
|
||||
foreach ( $wp_roles->roles as $k => $role ) {
|
||||
$caps = array();
|
||||
foreach ( $role['capabilities'] as $key => $cap ) {
|
||||
$caps[ $key ] = ucwords( str_replace( '_', ' ', $key ) );
|
||||
}
|
||||
asort( $caps );
|
||||
$data[ $role['name'] ] = $caps;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'callback':
|
||||
if ( ! empty( $args ) ) {
|
||||
$data = call_user_func( $args, $current_value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Router for translation based on the given post type.
|
||||
*
|
||||
* @param string $type Type of data request..
|
||||
* @param mixed $current_value Current value stored in DB.
|
||||
* @param array $args Arguments for the call.
|
||||
*/
|
||||
private function maybe_get_translation( $type, &$current_value = '', $args = array() ) {
|
||||
switch ( $type ) {
|
||||
case 'categories':
|
||||
case 'category':
|
||||
$this->maybe_translate( $current_value, 'category' );
|
||||
break;
|
||||
|
||||
case 'pages':
|
||||
case 'page':
|
||||
$this->maybe_translate( $current_value, 'page' );
|
||||
break;
|
||||
|
||||
case 'terms':
|
||||
case 'term':
|
||||
$this->maybe_translate( $current_value, isset( $args['taxonomy'] ) ? $args['taxonomy'] : '' );
|
||||
break;
|
||||
|
||||
case 'tags':
|
||||
case 'tag':
|
||||
$this->maybe_translate( $current_value, 'post_tag' );
|
||||
break;
|
||||
|
||||
case 'menus':
|
||||
case 'menu':
|
||||
$this->maybe_translate( $current_value, 'nav_menu' );
|
||||
break;
|
||||
|
||||
case 'post':
|
||||
case 'posts':
|
||||
$this->maybe_translate( $current_value, 'post' );
|
||||
break;
|
||||
default:
|
||||
$this->maybe_translate( $current_value, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe translate the values.
|
||||
*
|
||||
* @param string $value Value.
|
||||
* @param string $post_type Post type.
|
||||
*/
|
||||
private function maybe_translate( &$value, $post_type ) {
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$value = apply_filters( "redux/options/{$this->opt_name}/wordpress_data/translate/post_type_value", $value, $post_type );
|
||||
|
||||
// WPML Integration, see https://wpml.org/documentation/support/creating-multilingual-wordpress-themes/language-dependent-ids/.
|
||||
if ( function_exists( 'icl_object_id' ) ) {
|
||||
if ( has_filter( 'wpml_object_id' ) ) {
|
||||
if ( Redux_Helpers::is_integer( $value ) ) {
|
||||
$value = apply_filters( 'wpml_object_id', $value, $post_type, true );
|
||||
} elseif ( is_array( $value ) ) {
|
||||
$value = array_map(
|
||||
function ( $val ) use ( $post_type ) {
|
||||
return apply_filters( 'wpml_object_id', $val, $post_type, true );
|
||||
},
|
||||
$value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default arguments for a current query (existing data).
|
||||
*
|
||||
* @param string $type Type of data request.
|
||||
* @param array $args Arguments for the call.
|
||||
* @param mixed $current_value Current value stored in DB.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_current_data_args( $type, $args, &$current_value ) {
|
||||
// In this section we set the default arguments for each data type.
|
||||
switch ( $type ) {
|
||||
case 'categories':
|
||||
case 'category':
|
||||
case 'pages':
|
||||
case 'page':
|
||||
case 'terms':
|
||||
case 'term':
|
||||
case 'users':
|
||||
case 'user':
|
||||
$args['include'] = $current_value;
|
||||
break;
|
||||
case 'tags':
|
||||
case 'tag':
|
||||
$args['get'] = 'all';
|
||||
break;
|
||||
case 'menus':
|
||||
case 'menu':
|
||||
$args['object_ids'] = $current_value;
|
||||
break;
|
||||
case 'post':
|
||||
case 'posts':
|
||||
if ( ! empty( $current_value ) ) {
|
||||
$args['post__in'] = is_array( $current_value ) ? $current_value : array( $current_value );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$args = array();
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get default arguments for a given data type.
|
||||
*
|
||||
* @param string $type Type of data request.
|
||||
* @param array $args Arguments for the call.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_arg_defaults( $type, $args = array() ) {
|
||||
// In this section we set the default arguments for each data type.
|
||||
switch ( $type ) {
|
||||
case 'categories':
|
||||
case 'category':
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
'taxonomy' => 'category',
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'pages':
|
||||
case 'page':
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
'display_keys' => true,
|
||||
'posts_per_page' => 20,
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'post_type':
|
||||
case 'post_types':
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
'public' => true,
|
||||
'exclude_from_search' => false,
|
||||
'output' => 'names',
|
||||
'operator' => 'and',
|
||||
)
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
case 'tags':
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
'get' => 'all',
|
||||
'display_keys' => true,
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'sidebars':
|
||||
case 'sidebar':
|
||||
case 'capabilities':
|
||||
case 'capability':
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
'display_keys' => true,
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'capabilities_grouped':
|
||||
case 'capability_grouped':
|
||||
case 'capabilities_group':
|
||||
case 'capability_group':
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array(
|
||||
'data_sortby' => '',
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,823 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Customizer Extension Class
|
||||
* Short description.
|
||||
*
|
||||
* @package ReduxFramework/Extentions
|
||||
* @class Redux_Extension_Customizer
|
||||
* @version 4.0.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Extension_Customizer', false ) ) {
|
||||
|
||||
/**
|
||||
* Main ReduxFramework customizer extension class
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Redux_Extension_Customizer extends Redux_Extension_Abstract {
|
||||
|
||||
/**
|
||||
* Set extension version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $version = '4.0.0';
|
||||
|
||||
/**
|
||||
* Set the name of the field. Ideally, this will also be your extension's name.
|
||||
* Please use underscores and NOT dashes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $field_name = 'customizer';
|
||||
|
||||
/**
|
||||
* Set the friendly name of the extension. This is for display purposes. No underscores or dashes are required.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $extension_name = 'Customizer';
|
||||
|
||||
/**
|
||||
* Set the minumum required version of Redux here (optional).
|
||||
*
|
||||
* Leave blank to require no minimum version. This allows you to specify a minimum required version of
|
||||
* Redux in the event you do not want to support older versions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $minimum_redux_version = '4.0.0';
|
||||
|
||||
/**
|
||||
* Original options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $orig_options = array();
|
||||
|
||||
/**
|
||||
* Post values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $post_values = array();
|
||||
|
||||
/**
|
||||
* Options array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* Redux_Extension_my_extension constructor.
|
||||
*
|
||||
* @param object $parent ReduxFramework pointer.
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent, __FILE__ );
|
||||
|
||||
if ( is_admin() && ! $this->is_minimum_version( $this->minimum_redux_version, self::$version, $this->extension_name ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->add_field( 'customizer' );
|
||||
|
||||
$this->load();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The customizer load code
|
||||
*/
|
||||
private function load() {
|
||||
if ( false === $this->parent->args['customizer'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Override the Redux_Core class.
|
||||
add_filter(
|
||||
"redux/extension/{$this->parent->args['opt_name']}/customizer",
|
||||
array(
|
||||
$this,
|
||||
'remove_core_customizer_class',
|
||||
)
|
||||
);
|
||||
|
||||
global $pagenow, $wp_customize;
|
||||
|
||||
if ( ! isset( $wp_customize ) && 'customize.php' !== $pagenow && 'admin-ajax.php' !== $pagenow ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::get_post_values();
|
||||
|
||||
// Create defaults array.
|
||||
$defaults = array();
|
||||
|
||||
if ( isset( $_POST['wp_customize'] ) && 'on' === $_POST['wp_customize'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->parent->args['customizer_only'] = true;
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wp_customize'] ) && 'on' === $_POST['wp_customize'] && isset( $_POST['customized'] ) && ! empty( $_POST['customized'] ) && ! isset( $_POST['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
add_action(
|
||||
"redux/options/{$this->parent->args['opt_name']}/options",
|
||||
array(
|
||||
$this,
|
||||
'override_values',
|
||||
),
|
||||
100
|
||||
);
|
||||
}
|
||||
|
||||
add_action( 'customize_register', array( $this, 'register_customizer_controls' ) ); // Create controls.
|
||||
add_action( 'wp_head', array( $this, 'customize_preview_init' ) );
|
||||
|
||||
// phpcs:ignore Squiz.PHP.CommentedOutCode
|
||||
// add_action( 'customize_save', array( $this, 'customizer_save_before' ) ); // Before save.
|
||||
add_action( 'customize_save_after', array( &$this, 'customizer_save_after' ) ); // After save.
|
||||
|
||||
// Add global controls CSS file.
|
||||
add_action( 'customize_controls_print_scripts', array( $this, 'enqueue_controls_css' ) );
|
||||
add_action( 'customize_controls_init', array( $this, 'enqueue_panel_css' ) );
|
||||
add_action( 'wp_enqueue_styles', array( $this, 'custom_css' ), 11 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue extension scripts/styles.
|
||||
*/
|
||||
public function enqueue_controls_css() {
|
||||
$this->parent->enqueue_class->get_warnings_and_errors_array();
|
||||
$this->parent->enqueue_class->init();
|
||||
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
wp_enqueue_style(
|
||||
'redux-extension-customizer',
|
||||
$this->extension_url . 'redux-extension-customizer.css',
|
||||
array(),
|
||||
self::$version,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'redux-extension-customizer-js',
|
||||
$this->extension_url . 'redux-extension-customizer' . Redux_Functions::is_min() . '.js',
|
||||
array( 'jquery', 'redux-js' ),
|
||||
self::$version,
|
||||
true
|
||||
);
|
||||
|
||||
$custom_css = '#' . $this->parent->core_thread . '{line-height:0;border:0;}';
|
||||
$custom_css .= '#' . $this->parent->core_instance . '{position:inherit!important;right:0!important;top:0!important;bottom:0!important;';
|
||||
$custom_css .= 'left:0!important;text-align:center;margin-bottom:0;line-height:0;-webkit-transition:left ease-in-out .18s;transition:left ease-in-out .18s;}';
|
||||
$custom_css .= '#' . $this->parent->core_instance . ' img{-webkit-transition:left ease-in-out .18s;transition:left ease-in-out .18s;}';
|
||||
|
||||
wp_add_inline_style( 'redux-extension-customizer-css', $custom_css );
|
||||
|
||||
wp_localize_script(
|
||||
'redux-extension-customizer',
|
||||
'redux_customizer',
|
||||
array(
|
||||
'body_class' => sanitize_html_class( 'admin-color-' . get_user_option( 'admin_color' ), 'fresh' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue panel CSS>
|
||||
*/
|
||||
public function enqueue_panel_css() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove core customizer class.
|
||||
*
|
||||
* @param string $path Path to class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function remove_core_customizer_class( $path ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize preview init.
|
||||
*/
|
||||
public function customize_preview_init() {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/customizer/live_preview' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post values.
|
||||
*/
|
||||
protected static function get_post_values() {
|
||||
if ( empty( self::$post_values ) && isset( $_POST['customized'] ) && ! empty( $_POST['customized'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
self::$post_values = json_decode( stripslashes_deep( sanitize_text_field( wp_unslash( $_POST['customized'] ) ) ), true ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override customizer values.
|
||||
*
|
||||
* @param array $data Values.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function override_values( $data ) {
|
||||
self::get_post_values();
|
||||
|
||||
if ( isset( $_POST['customized'] ) && ! empty( self::$post_values ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
if ( is_array( self::$post_values ) ) {
|
||||
foreach ( self::$post_values as $key => $value ) {
|
||||
if ( strpos( $key, $this->parent->args['opt_name'] ) !== false ) {
|
||||
|
||||
$key = str_replace( $this->parent->args['opt_name'] . '[', '', rtrim( $key, ']' ) );
|
||||
$data[ $key ] = $value;
|
||||
|
||||
$GLOBALS[ $this->parent->args['global_variable'] ][ $key ] = $value;
|
||||
$this->parent->options[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Redux fields.
|
||||
*
|
||||
* @param array $control .
|
||||
*/
|
||||
public function render( $control ) {
|
||||
$field_id = str_replace( $this->parent->args['opt_name'] . '-', '', $control->redux_id );
|
||||
$field = $this->options[ $field_id ];
|
||||
|
||||
if ( isset( $field['compiler'] ) && ! empty( $field['compiler'] ) ) {
|
||||
echo '<tr class="compiler">';
|
||||
} else {
|
||||
echo '<tr>';
|
||||
}
|
||||
echo '<th scope="row">' . wp_kses_post( $this->parent->field_head[ $field['id'] ] ) . '</th>';
|
||||
echo '<td>';
|
||||
|
||||
$field['name'] = $field['id'];
|
||||
$this->parent->render_class->field_input( $field );
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
// All sections, settings, and controls will be added here.
|
||||
|
||||
/**
|
||||
* Register customizer controls.
|
||||
*
|
||||
* @param object $wp_customize .
|
||||
*/
|
||||
public function register_customizer_controls( $wp_customize ) {
|
||||
if ( ! class_exists( 'Redux_Customizer_Section' ) ) {
|
||||
require_once dirname( __FILE__ ) . '/inc/class-redux-customizer-section.php';
|
||||
if ( method_exists( $wp_customize, 'register_section_type' ) ) {
|
||||
$wp_customize->register_section_type( 'Redux_Customizer_Section' );
|
||||
}
|
||||
}
|
||||
if ( ! class_exists( 'Redux_Customizer_Panel' ) ) {
|
||||
require_once dirname( __FILE__ ) . '/inc/class-redux-customizer-panel.php';
|
||||
if ( method_exists( $wp_customize, 'register_panel_type' ) ) {
|
||||
$wp_customize->register_panel_type( 'Redux_Customizer_Panel' );
|
||||
}
|
||||
}
|
||||
if ( ! class_exists( 'Redux_Customizer_Control' ) ) {
|
||||
require_once dirname( __FILE__ ) . '/inc/class-redux-customizer-control.php';
|
||||
}
|
||||
|
||||
require_once dirname( __FILE__ ) . '/inc/class-redux-customizer-fields.php';
|
||||
require_once dirname( __FILE__ ) . '/inc/class-redux-customizer-section-dev.php';
|
||||
require_once dirname( __FILE__ ) . '/inc/class-redux-customizer-control-dev.php';
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/extension/customizer/control/includes' );
|
||||
|
||||
$order = array(
|
||||
'heading' => - 500,
|
||||
'option' => - 500,
|
||||
);
|
||||
|
||||
$defaults = array(
|
||||
'default-color' => '',
|
||||
'default-image' => '',
|
||||
'wp-head-callback' => '',
|
||||
'admin-head-callback' => '',
|
||||
'admin-preview-callback' => '',
|
||||
);
|
||||
|
||||
$panel = '';
|
||||
|
||||
$this->parent->args['options_api'] = false;
|
||||
$this->parent->_register_settings();
|
||||
|
||||
$parent_section_id = null;
|
||||
$new_parent = true;
|
||||
|
||||
foreach ( $this->parent->sections as $key => $section ) {
|
||||
// Not a type that should go on the customizer.
|
||||
if ( isset( $section['type'] ) && ( 'divide' === $section['type'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $section['id'] ) && 'import/export' === $section['id'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If section customizer is set to false.
|
||||
if ( isset( $section['customizer'] ) && false === $section['customizer'] ) {
|
||||
continue;
|
||||
}
|
||||
// if we are in a subsection and parent is set to customizer false !!!
|
||||
if ( ( isset( $section['subsection'] ) && $section['subsection'] ) ) {
|
||||
if ( $new_parent ) {
|
||||
$new_parent = false;
|
||||
$parent_section_id = ( $key - 1 );
|
||||
}
|
||||
} else { // not a subsection reset.
|
||||
$parent_section_id = null;
|
||||
$new_parent = true;
|
||||
}
|
||||
if ( isset( $parent_section_id ) && ( isset( $this->parent->sections[ $parent_section_id ]['customizer'] ) && false === $this->parent->sections[ $parent_section_id ]['customizer'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$section['permissions'] = isset( $section['permissions'] ) ? $section['permissions'] : 'edit_theme_options';
|
||||
|
||||
// No errors please.
|
||||
if ( ! isset( $section['desc'] ) ) {
|
||||
$section['desc'] = '';
|
||||
}
|
||||
|
||||
// Fill the description if there is a subtitle.
|
||||
if ( empty( $section['desc'] ) && ! empty( $section['subtitle'] ) ) {
|
||||
$section['desc'] = $section['subtitle'];
|
||||
}
|
||||
|
||||
// Let's make a section ID from the title.
|
||||
if ( empty( $section['id'] ) ) {
|
||||
$section['id'] = Redux_Core::strtolower( str_replace( ' ', '', $section['title'] ) );
|
||||
}
|
||||
|
||||
// No title is present, let's show what section is missing a title.
|
||||
if ( ! isset( $section['title'] ) ) {
|
||||
$section['title'] = '';
|
||||
}
|
||||
|
||||
// Let's set a default priority.
|
||||
if ( empty( $section['priority'] ) ) {
|
||||
$section['priority'] = $order['heading'];
|
||||
$order['heading'] ++;
|
||||
}
|
||||
$section['id'] = $this->parent->args['opt_name'] . '-' . $section['id'];
|
||||
|
||||
if ( method_exists( $wp_customize, 'add_panel' ) && ( ! isset( $section['subsection'] ) || ( isset( $section['subsection'] ) && true !== $section['subsection'] ) ) && isset( $this->parent->sections[ ( $key + 1 ) ]['subsection'] ) && $this->parent->sections[ ( $key + 1 ) ]['subsection'] ) {
|
||||
$this->add_panel(
|
||||
$this->parent->args['opt_name'] . '-' . $section['id'],
|
||||
array(
|
||||
'priority' => $section['priority'],
|
||||
'capability' => $section['permissions'],
|
||||
'title' => $section['title'],
|
||||
'section' => $section,
|
||||
'opt_name' => $this->parent->args['opt_name'],
|
||||
'description' => '',
|
||||
),
|
||||
$wp_customize
|
||||
);
|
||||
|
||||
$panel = $this->parent->args['opt_name'] . '-' . $section['id'];
|
||||
|
||||
$this->add_section(
|
||||
$section['id'],
|
||||
array(
|
||||
'title' => $section['title'],
|
||||
'priority' => $section['priority'],
|
||||
'description' => $section['desc'],
|
||||
'section' => $section,
|
||||
'opt_name' => $this->parent->args['opt_name'],
|
||||
'capability' => $section['permissions'],
|
||||
'panel' => $panel,
|
||||
),
|
||||
$wp_customize
|
||||
);
|
||||
} else {
|
||||
if ( ! isset( $section['subsection'] ) || ( isset( $section['subsection'] ) && true !== $section['subsection'] ) ) {
|
||||
$panel = '';
|
||||
}
|
||||
|
||||
$this->add_section(
|
||||
$section['id'],
|
||||
array(
|
||||
'title' => $section['title'],
|
||||
'priority' => $section['priority'],
|
||||
'description' => $section['desc'],
|
||||
'opt_name' => $this->parent->args['opt_name'],
|
||||
'section' => $section,
|
||||
'capability' => $section['permissions'],
|
||||
'panel' => $panel,
|
||||
),
|
||||
$wp_customize
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! isset( $section['fields'] ) || ( isset( $section['fields'] ) && empty( $section['fields'] ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $section['fields'] as $skey => $option ) {
|
||||
|
||||
if ( isset( $option['customizer'] ) && false === $option['customizer'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( false === $this->parent->args['customizer'] && ( ! isset( $option['customizer'] ) || true !== $option['customizer'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->options[ $option['id'] ] = $option;
|
||||
add_action(
|
||||
'redux/advanced_customizer/control/render/' . $this->parent->args['opt_name'] . '-' . $option['id'],
|
||||
array(
|
||||
$this,
|
||||
'render',
|
||||
)
|
||||
);
|
||||
|
||||
$option['permissions'] = isset( $option['permissions'] ) ? $option['permissions'] : 'edit_theme_options';
|
||||
|
||||
// Change the item priority if not set.
|
||||
if ( 'heading' !== $option['type'] && ! isset( $option['priority'] ) ) {
|
||||
$option['priority'] = $order['option'];
|
||||
$order['option'] ++;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->options_defaults[ $option['id'] ] ) ) {
|
||||
$option['default'] = $this->options_defaults['option']['id'];
|
||||
}
|
||||
|
||||
if ( ! isset( $option['default'] ) ) {
|
||||
$option['default'] = '';
|
||||
}
|
||||
if ( ! isset( $option['title'] ) ) {
|
||||
$option['title'] = '';
|
||||
}
|
||||
|
||||
$option['id'] = $this->parent->args['opt_name'] . '[' . $option['id'] . ']';
|
||||
|
||||
if ( 'heading' !== $option['type'] && 'import_export' !== $option['type'] && ! empty( $option['type'] ) ) {
|
||||
|
||||
$wp_customize->add_setting(
|
||||
$option['id'],
|
||||
array(
|
||||
'default' => $option['default'],
|
||||
'transport' => 'refresh',
|
||||
'opt_name' => $this->parent->args['opt_name'],
|
||||
'sanitize_callback' => array( $this, 'field_validation' ),
|
||||
|
||||
// phpcs:ignore Squiz.PHP.CommentedOutCode
|
||||
// 'type' => 'option',
|
||||
// 'capabilities' => $option['permissions'],
|
||||
// 'capabilities' => 'edit_theme_options',
|
||||
// 'capabilities' => $this->parent->args['page_permissions'],
|
||||
// 'theme_supports' => '',
|
||||
// 'sanitize_callback' => '__return_false',
|
||||
// 'sanitize_js_callback' =>array( &$parent, '_field_input' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $option['data'] ) && empty( $option['options'] ) ) {
|
||||
if ( empty( $option['args'] ) ) {
|
||||
$option['args'] = array();
|
||||
}
|
||||
|
||||
if ( 'elusive-icons' === $option['data'] || 'elusive-icon' === $option['data'] || 'elusive' === $option['data'] ) {
|
||||
$icons_file = Redux_Core::$dir . 'inc/fields/select/elusive-icons.php';
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$icons_file = apply_filters( 'redux-font-icons-file', $icons_file );
|
||||
|
||||
if ( file_exists( $icons_file ) ) {
|
||||
require_once $icons_file;
|
||||
}
|
||||
}
|
||||
$option['options'] = $this->parent->wordpress_data->get( $option['data'], $option['args'] );
|
||||
}
|
||||
|
||||
$class_name = 'Redux_Customizer_Control_' . $option['type'];
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/extension/customizer/control_init', $option );
|
||||
|
||||
if ( ! class_exists( $class_name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$wp_customize->add_control(
|
||||
new $class_name(
|
||||
$wp_customize,
|
||||
$option['id'],
|
||||
array(
|
||||
'label' => $option['title'],
|
||||
'section' => $section['id'],
|
||||
'settings' => $option['id'],
|
||||
'type' => 'redux-' . $option['type'],
|
||||
'field' => $option,
|
||||
'ReduxFramework' => $this->parent,
|
||||
'active_callback' => ( isset( $option['required'] ) && class_exists( 'Redux_Customizer_Active_Callback' ) ) ? array(
|
||||
'Redux_Customizer_Active_Callback',
|
||||
'evaluate',
|
||||
) : '__return_true',
|
||||
'priority' => $option['priority'],
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$section['fields'][ $skey ]['name'] = $option['id'];
|
||||
if ( ! isset( $section['fields'][ $skey ]['class'] ) ) { // No errors please.
|
||||
$section['fields'][ $skey ]['class'] = '';
|
||||
}
|
||||
|
||||
$this->controls[ $section['fields'][ $skey ]['id'] ] = $section['fields'][ $skey ];
|
||||
|
||||
add_action(
|
||||
'redux/advanced_customizer/render/' . $option['id'],
|
||||
array(
|
||||
$this,
|
||||
'field_render',
|
||||
),
|
||||
$option['priority']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add customizer section.
|
||||
*
|
||||
* @param string $id ID.
|
||||
* @param array $args Args.
|
||||
* @param object $wp_customize .
|
||||
*/
|
||||
public function add_section( $id, $args = array(), $wp_customize ) {
|
||||
|
||||
if ( is_a( $id, 'WP_Customize_Section' ) ) {
|
||||
$section = $id;
|
||||
} else {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$section_class = apply_filters( 'redux/customizer/section/class_name', 'Redux_Customizer_Section' );
|
||||
$section = new $section_class( $wp_customize, $id, $args );
|
||||
}
|
||||
|
||||
$wp_customize->add_section( $section, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a customize panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param WP_Customize_Panel|string $id Customize Panel object, or Panel ID.
|
||||
* @param array $args Optional. Panel arguments. Default empty array.
|
||||
* @param object $wp_customize .
|
||||
*/
|
||||
public function add_panel( $id, $args = array(), $wp_customize ) {
|
||||
if ( is_a( $id, 'WP_Customize_Panel' ) ) {
|
||||
$panel = $id;
|
||||
} else {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$panel_class = apply_filters( 'redux/customizer/panel/class_name', 'Redux_Customizer_Panel' );
|
||||
$panel = new $panel_class( $wp_customize, $id, $args );
|
||||
}
|
||||
|
||||
$wp_customize->add_panel( $panel, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Redux fields.
|
||||
*
|
||||
* @param array $option Option.
|
||||
*/
|
||||
public function field_render( $option ) {
|
||||
echo '1';
|
||||
preg_match_all( '/\[([^\]]*)\]/', $option->id, $matches );
|
||||
$id = $matches[1][0];
|
||||
echo esc_url( $option->link() );
|
||||
|
||||
$this->parent->render_class->field_input( $this->controls[ $id ] );
|
||||
echo '2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to take before customizer save.
|
||||
*
|
||||
* @param array $plugin_options .
|
||||
*/
|
||||
public function customizer_save_before( $plugin_options ) {
|
||||
$this->before_save = $this->parent->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions to take after customizer save.
|
||||
*
|
||||
* @param Object $wp_customize .
|
||||
*/
|
||||
public function customizer_save_after( $wp_customize ) {
|
||||
if ( empty( $this->parent->options ) ) {
|
||||
$this->parent->get_options();
|
||||
}
|
||||
if ( empty( $this->orig_options ) && ! empty( $this->parent->options ) ) {
|
||||
$this->orig_options = $this->parent->options;
|
||||
}
|
||||
|
||||
if ( isset( $_POST['customized'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$options = json_decode( sanitize_text_field( wp_unslash( $_POST['customized'] ) ), true ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
$compiler = false;
|
||||
$changed = false;
|
||||
|
||||
foreach ( $options as $key => $value ) {
|
||||
if ( strpos( $key, $this->parent->args['opt_name'] ) !== false ) {
|
||||
$key = str_replace( $this->parent->args['opt_name'] . '[', '', rtrim( $key, ']' ) );
|
||||
|
||||
if ( ! isset( $this->orig_options[ $key ] ) || $value !== $this->orig_options[ $key ] || ( isset( $this->orig_options[ $key ] ) && ! empty( $this->orig_options[ $key ] ) && empty( $value ) ) ) {
|
||||
$this->parent->options[ $key ] = $value;
|
||||
$changed = true;
|
||||
if ( isset( $this->parent->compiler_fields[ $key ] ) ) {
|
||||
$compiler = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $changed ) {
|
||||
$this->parent->set_options( $this->parent->options );
|
||||
if ( $compiler ) {
|
||||
// Have to set this to stop the output of the CSS and typography stuff.
|
||||
$this->parent->no_output = true;
|
||||
$this->parent->output_class->enqueue();
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->parent->args['opt_name']}/compiler", $this->parent->options, $this->parent->compilerCSS );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/options/{$this->args['opt_name']}/compiler/advanced", $this->parent );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue CSS/JS for preview pane
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @global $wp_styles
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_previewer() {
|
||||
wp_enqueue_script( 'redux-extension-previewer-js', $this->extension_url . 'assets/js/preview.js', array(), self::$version, true );
|
||||
|
||||
$localize = array(
|
||||
'save_pending' => esc_html__( 'You have changes that are not saved. Would you like to save them now?', 'redux-framework' ),
|
||||
'reset_confirm' => esc_html__( 'Are you sure? Resetting will lose all custom values.', 'redux-framework' ),
|
||||
'preset_confirm' => esc_html__( 'Your current options will be replaced with the values of this preset. Would you like to proceed?', 'redux-framework' ),
|
||||
'opt_name' => $this->args['opt_name'],
|
||||
'options' => $this->parent->options,
|
||||
'defaults' => $this->parent->options_defaults,
|
||||
|
||||
// phpcs:ignore Squiz.PHP.CommentedOutCode
|
||||
// 'folds' => $this->folds,
|
||||
);
|
||||
|
||||
wp_localize_script( 'redux-extension-previewer-js', 'reduxPost', $localize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue CSS/JS for the customizer controls
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @global $wp_styles
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue() {
|
||||
global $wp_styles;
|
||||
|
||||
$localize = array(
|
||||
'save_pending' => esc_html__( 'You have changes that are not saved. Would you like to save them now?', 'redux-framework' ),
|
||||
'reset_confirm' => esc_html__( 'Are you sure? Resetting will lose all custom values.', 'redux-framework' ),
|
||||
'preset_confirm' => esc_html__( 'Your current options will be replaced with the values of this preset. Would you like to proceed?', 'redux-framework' ),
|
||||
'opt_name' => $this->args['opt_name'],
|
||||
'field' => $this->parent->options,
|
||||
'defaults' => $this->parent->options_defaults,
|
||||
|
||||
// phpcs:ignore Squiz.PHP.CommentedOutCode
|
||||
// 'folds' => $this->folds,
|
||||
);
|
||||
|
||||
// Values used by the javascript.
|
||||
wp_localize_script( 'redux-js', 'redux_opts', $localize );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux-enqueue-' . $this->args['opt_name'] );
|
||||
|
||||
foreach ( $this->sections as $section ) {
|
||||
if ( isset( $section['fields'] ) ) {
|
||||
foreach ( $section['fields'] as $field ) {
|
||||
if ( isset( $field['type'] ) ) {
|
||||
$field_classes = array( 'Redux_' . $field['type'], 'ReduxFramework_' . $field['type'] );
|
||||
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
|
||||
if ( false === $field_class ) {
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$class_file = apply_filters( 'redux-typeclass-load', $this->path . 'inc/fields/' . $field['type'] . '/field_' . $field['type'] . '.php', $field_class );
|
||||
|
||||
if ( $class_file ) {
|
||||
require_once $class_file;
|
||||
|
||||
$field_class = Redux_Functions::class_exists_ex( $field_classes );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $field_class ) && method_exists( $field_class, 'enqueue' ) ) {
|
||||
$enqueue = new $field_class( '', '', $this );
|
||||
$enqueue->enqueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Option for use
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function register_setting() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the options before insertion
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $value The options array.
|
||||
*
|
||||
* @return $value
|
||||
*/
|
||||
public function field_validation( $value ) {
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML OUTPUT.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function customizer_html_output() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'redux_customizer_custom_validation' ) ) {
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @param mixed $field Field.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function redux_customizer_custom_validation( $field ) {
|
||||
return $field;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'ReduxFramework_extension_customizer' ) ) {
|
||||
class_alias( 'Redux_Extension_Customizer', 'ReduxFramework_extension_customizer' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Customizer Control Dev Class
|
||||
*
|
||||
* @class Redux_Customizer_Control_Dev
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Dev', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Customizer_Control_Dev
|
||||
*/
|
||||
class Redux_Customizer_Control_Dev extends WP_Customize_Control {
|
||||
|
||||
/**
|
||||
* Field render.
|
||||
*/
|
||||
public function render() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Label render.
|
||||
*/
|
||||
public function label() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Description render.
|
||||
*/
|
||||
public function description() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Title render.
|
||||
*/
|
||||
public function title() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer Control.
|
||||
*
|
||||
* @package Redux Framework/Extensions
|
||||
* @version 3.5
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Customizer_Control
|
||||
*/
|
||||
class Redux_Customizer_Control extends WP_Customize_Control {
|
||||
|
||||
/**
|
||||
* Field render.
|
||||
*/
|
||||
public function render() {
|
||||
|
||||
$this->redux_id = str_replace( 'customize-control-', '', 'customize-control-' . str_replace( '[', '-', str_replace( ']', '', $this->id ) ) );
|
||||
$class = 'customize-control redux-group-tab redux-field customize-control-' . $this->type;
|
||||
$opt_name_arr = explode( '[', $this->id );
|
||||
$opt_name = $opt_name_arr[0];
|
||||
$field_id = str_replace( ']', '', $opt_name_arr[1] );
|
||||
|
||||
$section = Redux_Helpers::section_from_field_id( $opt_name, $field_id );
|
||||
|
||||
if ( isset( $section['disabled'] ) && true === $section['disabled'] ) {
|
||||
$class .= ' disabled';
|
||||
}
|
||||
|
||||
if ( isset( $section['hidden'] ) && true === $section['hidden'] ) {
|
||||
$class .= ' hidden';
|
||||
}
|
||||
|
||||
?>
|
||||
<li id="<?php echo esc_attr( $this->redux_id ); ?>-li" class="<?php echo esc_attr( $class ); ?>">
|
||||
<?php if ( 'repeater' !== $this->type ) { ?>
|
||||
<input
|
||||
type="hidden"
|
||||
data-id="<?php echo esc_attr( $this->id ); ?>"
|
||||
data-key="<?php echo esc_attr( str_replace( $opt_name . '-', '', $this->redux_id ) ); ?>"
|
||||
class="redux-customizer-input"
|
||||
id="customizer_control_id_<?php echo esc_attr( $this->redux_id ); ?>" <?php echo esc_url( $this->link() ); ?>
|
||||
value=""/>
|
||||
<?php } ?>
|
||||
<?php $this->render_content(); ?>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Redner content hook.
|
||||
*/
|
||||
public function render_content() {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/advanced_customizer/control/render/' . $this->redux_id, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Label output.
|
||||
*/
|
||||
public function label() {
|
||||
// The label has already been sanitized in the Fields class, no need to re-sanitize it.
|
||||
echo( $this->label ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
|
||||
/**
|
||||
* Description output.
|
||||
*/
|
||||
public function description() {
|
||||
if ( ! empty( $this->description ) ) {
|
||||
// The description has already been sanitized in the Fields class, no need to re-sanitize it.
|
||||
echo '<span class="description customize-control-description">' . esc_html( $this->description ) . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Title output.
|
||||
*/
|
||||
public function title() {
|
||||
echo '<span class="customize-control-title">';
|
||||
$this->label();
|
||||
$this->description();
|
||||
echo '</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
|
||||
/**
|
||||
* Redux Customizer Fields Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
|
||||
// phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound
|
||||
// phpcs:disable Generic.Files.OneClassPerFile
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Checkbox', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_checkbox
|
||||
*/
|
||||
class Redux_Customizer_Control_Checkbox extends Redux_Customizer_Control {
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-checkbox';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Color_Rgba', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_color_rgba
|
||||
*/
|
||||
class Redux_Customizer_Control_Color_Rgba extends Redux_Customizer_Control {
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-color_rgba';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Color', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_color
|
||||
*/
|
||||
class Redux_Customizer_Control_Color extends Redux_Customizer_Control {
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-color';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Media', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_media
|
||||
*/
|
||||
class Redux_Customizer_Control_Media extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-media';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Spinner', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_spinner
|
||||
*/
|
||||
class Redux_Customizer_Control_Spinner extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-spinner';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Palette', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_palette
|
||||
*/
|
||||
class Redux_Customizer_Control_Palette extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-palette';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Button_Set', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_button_set
|
||||
*/
|
||||
class Redux_Customizer_Control_Button_Set extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-button_set';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Image_Select', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_image_select
|
||||
*/
|
||||
class Redux_Customizer_Control_Image_Select extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-image_select';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Radio', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_radio
|
||||
*/
|
||||
class Redux_Customizer_Control_Radio extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-radio';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Select', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_select
|
||||
*/
|
||||
class Redux_Customizer_Control_Select extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-select';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Gallery', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_gallery
|
||||
*/
|
||||
class Redux_Customizer_Control_Gallery extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-gallery';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Slider', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_slider
|
||||
*/
|
||||
class Redux_Customizer_Control_Slider extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-slider';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Sortable', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_sortable
|
||||
*/
|
||||
class Redux_Customizer_Control_Sortable extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-sortable';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Switch', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_switch
|
||||
*/
|
||||
class Redux_Customizer_Control_Switch extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-switch';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Text', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_text
|
||||
*/
|
||||
class Redux_Customizer_Control_Text extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-text';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Control_Textarea', false ) ) {
|
||||
/**
|
||||
* Class Redux_Customizer_Control_textarea
|
||||
*/
|
||||
class Redux_Customizer_Control_Textarea extends Redux_Customizer_Control {
|
||||
// phpcs:ignore Generic.Files.OneClassPerFile
|
||||
|
||||
/**
|
||||
* Set control type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux-textarea';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Customizer Panel Class
|
||||
*
|
||||
* @class Redux_Customizer_Panel
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework/Extentions
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Customizer section representing widget area (sidebar).
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 4.1.0
|
||||
* @see WP_Customize_Section
|
||||
*/
|
||||
class Redux_Customizer_Panel extends WP_Customize_Panel {
|
||||
|
||||
/**
|
||||
* Type of this panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux';
|
||||
|
||||
/**
|
||||
* Panel opt_name.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $opt_name = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Any supplied $args override class property defaults.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
|
||||
* @param string $id An specific ID for the panel.
|
||||
* @param array $args Panel arguments.
|
||||
*/
|
||||
public function __construct( $manager, $id, $args = array() ) {
|
||||
parent::__construct( $manager, $id, $args );
|
||||
|
||||
// Redux addition.
|
||||
if ( isset( $args['section'] ) ) {
|
||||
$this->section = $args['section'];
|
||||
$this->description = isset( $this->section['desc'] ) ? $this->section['desc'] : '';
|
||||
$this->opt_name = isset( $args['opt_name'] ) ? $args['opt_name'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WP < 4.3 Render
|
||||
*
|
||||
* @since
|
||||
* @access protected
|
||||
*/
|
||||
protected function render() {
|
||||
global $wp_version;
|
||||
$version = explode( '-', $wp_version );
|
||||
if ( version_compare( $version[0], '4.3', '<' ) ) {
|
||||
$this->render_fallback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*/
|
||||
protected function render_fallback() {
|
||||
$classes = 'accordion-section redux-main redux-panel control-section control-panel control-panel-' . esc_attr( $this->type );
|
||||
?>
|
||||
<li id="accordion-panel-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
|
||||
<h3 class="accordion-section-title" tabindex="0">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$this->title,
|
||||
array(
|
||||
'em' => array(),
|
||||
'i' => array(),
|
||||
'strong' => array(),
|
||||
'span' => array(
|
||||
'class' => array(),
|
||||
'style' => array(),
|
||||
),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Press return or enter to open this panel', 'redux-framework' ); ?></span>
|
||||
</h3>
|
||||
<ul class="accordion-sub-container control-panel-content">
|
||||
<table class="form-table">
|
||||
<tbody><?php $this->render_content(); ?></tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the sections that have been added to the panel.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function render_content() {
|
||||
?>
|
||||
<li class="panel-meta accordion-section redux-panel redux-panel-meta control-section
|
||||
<?php
|
||||
if ( empty( $this->description ) ) {
|
||||
echo ' cannot-expand';
|
||||
}
|
||||
?>
|
||||
">
|
||||
<div class="accordion-section-title" tabindex="0">
|
||||
<span class="preview-notice">
|
||||
<?php /* translators: %s is the site/panel title in the Customizer */ ?>
|
||||
<?php echo sprintf( esc_html__( 'You are customizing', 'redux-framework' ) . ' %s', '<strong class="panel-title">' . esc_html( $this->title ) . '</strong>' ); ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php if ( ! empty( $this->description ) ) { ?>
|
||||
<div class="accordion-section-content description legacy">
|
||||
<?php echo wp_kses_post( $this->description ); ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function json() {
|
||||
$array = parent::json();
|
||||
$array['opt_name'] = $this->opt_name;
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* An Underscore (JS) template for this panel's content (but not its container).
|
||||
* Class variables for this panel class are available in the `data` JS object;
|
||||
* export custom variables by overriding {@see WP_Customize_Panel::json()}.
|
||||
*
|
||||
* @see WP_Customize_Panel::print_template()
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function content_template() {
|
||||
?>
|
||||
<li
|
||||
class="panel-meta customize-info redux-customizer-opt-name redux-panel accordion-section <# if ( ! data.description ) { #> cannot-expand<# } #>"
|
||||
data-opt-name="{{{ data.opt_name }}}">
|
||||
<button class="customize-panel-back" tabindex="-1">
|
||||
<span class="screen-reader-text"><?php esc_attr_e( 'Back', 'redux-framework' ); ?></span></button>
|
||||
<div class="accordion-section-title">
|
||||
<span class="preview-notice">
|
||||
<?php /* translators: %s is the site/panel title in the Customizer */ ?>
|
||||
<?php echo sprintf( esc_html__( 'You are customizing', 'redux-framework' ) . ' %s', '<strong class="panel-title">{{ data.title }}</strong>' ); ?>
|
||||
</span>
|
||||
<# if ( data.description ) { #>
|
||||
<button
|
||||
class="customize-help-toggle dashicons dashicons-editor-help"
|
||||
tabindex="0"
|
||||
aria-expanded="false">
|
||||
<span class="screen-reader-text"><?php esc_attr_e( 'Help', 'redux-framework' ); ?></span></button>
|
||||
<# } #>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="description customize-panel-description">
|
||||
{{{ data.description }}}
|
||||
</div>
|
||||
<# } #>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Customizer Section Dev Class
|
||||
*
|
||||
* @class Redux_Customizer_Section_Dev
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'Redux_Customizer_Section_Dev', false ) ) {
|
||||
|
||||
/**
|
||||
* Customizer section representing widget area (sidebar).
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 4.1.0
|
||||
* @see WP_Customize_Section
|
||||
*/
|
||||
class Redux_Customizer_Section_Dev extends WP_Customize_Section {
|
||||
|
||||
/**
|
||||
* Field render.
|
||||
*/
|
||||
protected function render() {}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* Customizer section representing widget area (sidebar).
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 4.0.0
|
||||
* @see WP_Customize_Section
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class Redux_Customizer_Section
|
||||
*/
|
||||
class Redux_Customizer_Section extends WP_Customize_Section {
|
||||
|
||||
/**
|
||||
* Type of this section.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'redux';
|
||||
|
||||
/**
|
||||
* Panel opt_name.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $opt_name = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Any supplied $args override class property defaults.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
|
||||
* @param string $id An specific ID of the section.
|
||||
* @param array $args Section arguments.
|
||||
*/
|
||||
public function __construct( $manager, $id, $args = array() ) {
|
||||
parent::__construct( $manager, $id, $args );
|
||||
// Redux addition.
|
||||
if ( isset( $args['section'] ) ) {
|
||||
$this->section = $args['section'];
|
||||
$this->description = isset( $this->section['desc'] ) ? $this->section['desc'] : '';
|
||||
$this->opt_name = isset( $args['opt_name'] ) ? $args['opt_name'] : '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WP < 4.3 Render
|
||||
*/
|
||||
protected function render() {
|
||||
global $wp_version;
|
||||
$version = explode( '-', $wp_version );
|
||||
if ( version_compare( $version[0], '4.3', '<' ) ) {
|
||||
$this->render_fallback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the section, and the controls that have been added to it.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected function render_fallback() {
|
||||
$classes = 'accordion-section redux-section control-section control-section-' . $this->type;
|
||||
?>
|
||||
<li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
|
||||
<h3 class="accordion-section-title" tabindex="0">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$this->title,
|
||||
array(
|
||||
'em' => array(),
|
||||
'i' => array(),
|
||||
'strong' => array(),
|
||||
'span' => array(
|
||||
'class' => array(),
|
||||
'style' => array(),
|
||||
),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<span class="screen-reader-text"><?php esc_attr_e( 'Press return or enter to expand', 'redux-framework' ); ?></span>
|
||||
</h3>
|
||||
<ul class="accordion-section-content redux-main">
|
||||
<?php
|
||||
if ( isset( $this->opt_name ) && isset( $this->section ) ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/page/{$this->opt_name}/section/before", $this->section );
|
||||
}
|
||||
?>
|
||||
<?php if ( ! empty( $this->description ) ) { ?>
|
||||
<li class="customize-section-description-container">
|
||||
<p class="description customize-section-description legacy"><?php echo wp_kses_post( $this->description ); ?></p>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gather the parameters passed to client JavaScript via JSON.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return array The array to be exported to the client as JSON.
|
||||
*/
|
||||
public function json() {
|
||||
$array = parent::json();
|
||||
$array['opt_name'] = $this->opt_name;
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* An Underscore (JS) template for rendering this section.
|
||||
* Class variables for this section class are available in the `data` JS object;
|
||||
* export custom variables by overriding {@see WP_Customize_Section::json()}.
|
||||
*
|
||||
* @see WP_Customize_Section::print_template()
|
||||
* @since 4.3.0
|
||||
*/
|
||||
protected function render_template() {
|
||||
|
||||
?>
|
||||
<li id="accordion-section-{{ data.id }}"
|
||||
class="redux-standalone-section redux-customizer-opt-name redux-section accordion-section control-section control-section-{{ data.type }}"
|
||||
data-opt-name="{{ data.opt_name }}">
|
||||
<h3 class="accordion-section-title" tabindex="0">
|
||||
{{ data.title }}
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Press return or enter to open', 'redux-framework' ); ?></span>
|
||||
</h3>
|
||||
<ul class="accordion-section-content redux-main">
|
||||
|
||||
<li class="customize-section-description-container">
|
||||
<div class="customize-section-title">
|
||||
<button class="customize-section-back" tabindex="-1">
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Back', 'redux-framework' ); ?></span>
|
||||
</button>
|
||||
<h3>
|
||||
<span class="customize-action">
|
||||
{{{ data.customizeAction }}}
|
||||
</span> {{ data.title }}
|
||||
</h3>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<p class="description customize-section-description">{{{ data.description }}}</p>
|
||||
<# } #>
|
||||
<?php
|
||||
if ( isset( $this->opt_name ) && isset( $this->section ) ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( "redux/page/{$this->opt_name}/section/before", $this->section );
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
// Shim for the old way of calling the customizer.
|
||||
require_once dirname( __FILE__ ) . '/class-redux-customizer-panel.php';
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
// Shim for the old way of calling the customizer.
|
||||
require_once dirname( __FILE__ ) . '/class-redux-customizer-section.php';
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,55 @@
|
||||
.wp-customizer .redux-container { overflow: visible; }
|
||||
|
||||
.wp-customizer .redux-container .redux-main input { margin: 0 !important; }
|
||||
|
||||
.wp-customizer .redux-container .redux-main input.spinner-input { margin-right: 30px !important; margin-left: 30px !important; margin-top: 0px !important; }
|
||||
|
||||
.wp-customizer .redux-section.open .redux-group-tab { display: block !important; }
|
||||
|
||||
.wp-customizer .redux-section p.customize-section-description { margin-top: 22px; word-break: break-word; }
|
||||
|
||||
.wp-customizer .redux-section p.customize-section-description.legacy { margin-top: 7px; }
|
||||
|
||||
.wp-customizer .control-section-themes .accordion-section-title { margin: 0; }
|
||||
|
||||
.wp-customizer #customize-controls .description { display: block; }
|
||||
|
||||
.wp-customizer #customize-controls .customize-info { margin-bottom: 0; }
|
||||
|
||||
.wp-customizer #customize-controls .redux-section .accordion-section-content { background: #fcfcfc; }
|
||||
|
||||
.wp-customizer .redux-section .accordion-section-title i, .wp-customizer .redux-field .accordion-field-title i, .wp-customizer .redux-panel .accordion-section-title i { margin-right: 5px; }
|
||||
|
||||
.wp-customizer .accordion-section.redux-main { background: inherit; margin-left: inherit; border-left: inherit; -moz-box-shadow: inherit; -webkit-box-shadow: inherit; padding: inherit; box-shadow: inherit; }
|
||||
|
||||
.wp-customizer .redux_field_th { padding: 13px 0px 0px 0px; }
|
||||
|
||||
.wp-customizer .redux-main .redux-field-container { padding: 10px 0; }
|
||||
|
||||
.wp-customizer .redux-main .select_wrapper { float: none; width: 100%; display: inline-block; }
|
||||
|
||||
.wp-customizer .redux-main .select2-container { margin-right: 0 !important; margin-bottom: 5px !important; width: 100% !important; }
|
||||
|
||||
.wp-customizer .redux-main .select_wrapper:nth-child(odd) { margin-right: 0; }
|
||||
|
||||
.wp-customizer .redux-main .redux-option-image { max-width: 42% !important; margin-right: 3%; }
|
||||
|
||||
.wp-customizer .redux-main .customize-control { border-bottom: 1px solid #ddd; padding-bottom: 4px; }
|
||||
|
||||
.wp-customizer .redux-main .customize-control:last-child { border-bottom: 0; padding-bottom: 0; }
|
||||
|
||||
.wp-customizer .redux-main .upload { width: 100% !important; }
|
||||
|
||||
.wp-customizer .redux-main h3 { margin-top: inherit; }
|
||||
|
||||
.wp-customizer .redux-main .redux-container-raw { margin-top: 22px; word-break: break-word; padding: 0 !important; }
|
||||
|
||||
.wp-customizer .redux-main .redux-container-password input { width: 100%; }
|
||||
|
||||
.wp-customizer .select2-drop, .wp-customizer .select2-container { z-index: 999999; }
|
||||
|
||||
.wp-customizer .customize-control-redux-raw { list-style: none; }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtZXh0ZW5zaW9uLWN1c3RvbWl6ZXIuY3NzIiwic291cmNlcyI6WyJyZWR1eC1leHRlbnNpb24tY3VzdG9taXplci5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLEFBQ0ksY0FEVSxDQUNWLGdCQUFnQixDQUFDLEVBQ2IsUUFBUSxFQUFFLE9BQU8sR0FZcEI7O0FBZEwsQUFJWSxjQUpFLENBQ1YsZ0JBQWdCLENBRVosV0FBVyxDQUNQLEtBQUssQ0FBQyxFQUNGLE1BQU0sRUFBRSxZQUFZLEdBQ3ZCOztBQU5iLEFBUVksY0FSRSxDQUNWLGdCQUFnQixDQUVaLFdBQVcsQ0FLUCxLQUFLLEFBQUEsY0FBYyxDQUFDLEVBQ2hCLFlBQVksRUFBRSxlQUFlLEVBQzdCLFdBQVcsRUFBRSxlQUFlLEVBQzVCLFVBQVUsRUFBRSxjQUFjLEdBQzdCOztBQVpiLEFBZUksY0FmVSxDQWVWLGNBQWMsQUFBQSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsRUFDakMsT0FBTyxFQUFFLGdCQUFnQixHQUM1Qjs7QUFqQkwsQUFvQlEsY0FwQk0sQ0FtQlYsY0FBYyxDQUNWLENBQUMsQUFBQSw4QkFBOEIsQ0FBQyxFQUM1QixVQUFVLEVBQUUsSUFBSSxFQUNoQixVQUFVLEVBQUUsVUFBVSxHQUl6Qjs7QUExQlQsQUF1QlksY0F2QkUsQ0FtQlYsY0FBYyxDQUNWLENBQUMsQUFBQSw4QkFBOEIsQUFHMUIsT0FBTyxDQUFDLEVBQ0wsVUFBVSxFQUFFLEdBQUcsR0FDbEI7O0FBekJiLEFBNkJJLGNBN0JVLENBNkJWLHVCQUF1QixDQUFDLHdCQUF3QixDQUFDLEVBQzdDLE1BQU0sRUFBRSxDQUFDLEdBQ1o7O0FBL0JMLEFBa0NRLGNBbENNLENBaUNWLG1CQUFtQixDQUNmLFlBQVksQ0FBQyxFQUNULE9BQU8sRUFBRSxLQUFLLEdBQ2pCOztBQXBDVCxBQXFDUSxjQXJDTSxDQWlDVixtQkFBbUIsQ0FJZixlQUFlLENBQUMsRUFDWixhQUFhLEVBQUUsQ0FBQyxHQUNuQjs7QUF2Q1QsQUF3Q1EsY0F4Q00sQ0FpQ1YsbUJBQW1CLENBT2YsY0FBYyxDQUFDLDBCQUEwQixDQUFDLEVBQ3RDLFVBQVUsRUFBRSxPQUFPLEdBQ3RCOztBQTFDVCxBQTZDSSxjQTdDVSxDQTZDVixjQUFjLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxFQTdDN0MsY0FBYyxDQThDVixZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxFQTlDekMsY0FBYyxDQStDVixZQUFZLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLEVBQ3BDLFlBQVksRUFBRSxHQUFHLEdBQ3BCOztBQWpETCxBQW1ESSxjQW5EVSxDQW1EVixrQkFBa0IsQUFBQSxXQUFXLENBQUMsRUFDMUIsVUFBVSxFQUFFLE9BQU8sRUFDbkIsV0FBVyxFQUFFLE9BQU8sRUFDcEIsV0FBVyxFQUFFLE9BQU8sRUFDcEIsZUFBZSxFQUFFLE9BQU8sRUFDeEIsa0JBQWtCLEVBQUUsT0FBTyxFQUMzQixPQUFPLEVBQUUsT0FBTyxFQUNoQixVQUFVLEVBQUUsT0FBTyxHQUN0Qjs7QUEzREwsQUE2REksY0E3RFUsQ0E2RFYsZUFBZSxDQUFDLEVBQ1osT0FBTyxFQUFFLGdCQUFnQixHQUM1Qjs7QUEvREwsQUFrRVEsY0FsRU0sQ0FpRVYsV0FBVyxDQUNQLHNCQUFzQixDQUFDLEVBQ25CLE9BQU8sRUFBRSxNQUFNLEdBQ2xCOztBQXBFVCxBQXFFUSxjQXJFTSxDQWlFVixXQUFXLENBSVAsZUFBZSxDQUFDLEVBQ1osS0FBSyxFQUFFLElBQUksRUFDWCxLQUFLLEVBQUUsSUFBSSxFQUNYLE9BQU8sRUFBRSxZQUFZLEdBQ3hCOztBQXpFVCxBQTBFUSxjQTFFTSxDQWlFVixXQUFXLENBU1Asa0JBQWtCLENBQUMsRUFDZixZQUFZLEVBQUUsWUFBWSxFQUMxQixhQUFhLEVBQUUsY0FBYyxFQUM3QixLQUFLLEVBQUUsZUFBZSxHQUN6Qjs7QUE5RVQsQUErRVEsY0EvRU0sQ0FpRVYsV0FBVyxDQWNQLGVBQWUsQUFBQSxVQUFXLENBQUEsR0FBRyxFQUFFLEVBQzNCLFlBQVksRUFBRSxDQUFDLEdBQ2xCOztBQWpGVCxBQWtGUSxjQWxGTSxDQWlFVixXQUFXLENBaUJQLG1CQUFtQixDQUFDLEVBQ2hCLFNBQVMsRUFBRSxjQUFjLEVBQ3pCLFlBQVksRUFBRSxFQUFFLEdBQ25COztBQXJGVCxBQXNGUSxjQXRGTSxDQWlFVixXQUFXLENBcUJQLGtCQUFrQixDQUFDLEVBQ2YsYUFBYSxFQUFFLGNBQWMsRUFDN0IsY0FBYyxFQUFFLEdBQUcsR0FDdEI7O0FBekZULEFBMEZRLGNBMUZNLENBaUVWLFdBQVcsQ0F5QlAsa0JBQWtCLEFBQUEsV0FBVyxDQUFDLEVBQzFCLGFBQWEsRUFBRSxDQUFDLEVBQ2hCLGNBQWMsRUFBRSxDQUFDLEdBQ3BCOztBQTdGVCxBQThGUSxjQTlGTSxDQWlFVixXQUFXLENBNkJQLE9BQU8sQ0FBQyxFQUNKLEtBQUssRUFBRSxlQUFlLEdBQ3pCOztBQWhHVCxBQWlHUSxjQWpHTSxDQWlFVixXQUFXLENBZ0NQLEVBQUUsQ0FBQyxFQUNDLFVBQVUsRUFBRSxPQUFPLEdBQ3RCOztBQW5HVCxBQW9HUSxjQXBHTSxDQWlFVixXQUFXLENBbUNQLG9CQUFvQixDQUFDLEVBQ2pCLFVBQVUsRUFBRSxJQUFJLEVBQ2hCLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLE9BQU8sRUFBRSxZQUFZLEdBQ3hCOztBQXhHVCxBQXlHUSxjQXpHTSxDQWlFVixXQUFXLENBd0NQLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxFQUM1QixLQUFLLEVBQUUsSUFBSSxHQUNkOztBQTNHVCxBQThHSSxjQTlHVSxDQThHVixhQUFhLEVBOUdqQixjQUFjLENBK0dWLGtCQUFrQixDQUFDLEVBQ2YsT0FBTyxFQUFFLE1BQU0sR0FDbEI7O0FBakhMLEFBbUhJLGNBbkhVLENBbUhWLDRCQUE0QixDQUFDLEVBQ3pCLFVBQVUsRUFBRSxJQUFJLEdBQ25CIn0= */
|
||||
|
||||
/*# sourceMappingURL=redux-extension-customizer.css.map */
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,461 @@
|
||||
/* global jQuery, document, redux, redux_change:true, wp */
|
||||
|
||||
/**
|
||||
* SerializeJSON jQuery plugin.
|
||||
* https://github.com/marioizquierdo/jquery.serializeJSON
|
||||
* version 2.6.0 (Apr, 2015)
|
||||
|
||||
* Copyright (c) 2012, 2015 Mario Izquierdo
|
||||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
||||
*/
|
||||
(function( $ ) {
|
||||
'use strict';
|
||||
|
||||
// Usage: jQuery('form').serializeJSON() .
|
||||
$.fn.serializeJSON = function( options ) {
|
||||
var serializedObject, formAsArray, keys, type, value, f, opts;
|
||||
f = $.serializeJSON;
|
||||
opts = f.setupOpts( options ); // Calculate values for options {parseNumbers, parseBoolens, parseNulls}.
|
||||
formAsArray = this.serializeArray(); // Array of objects {name, value}.
|
||||
f.readCheckboxUncheckedValues( formAsArray, this, opts ); // Add {name, value} of unchecked checkboxes if needed.
|
||||
|
||||
serializedObject = {};
|
||||
|
||||
$.each(
|
||||
formAsArray,
|
||||
function( i, input ) {
|
||||
i = null;
|
||||
|
||||
keys = f.splitInputNameIntoKeysArray( input.name, opts );
|
||||
type = keys.pop(); // The last element is always the type ('string' by default).
|
||||
if ( 'skip' !== type ) { // Aasy way to skip a value.
|
||||
value = f.parseValue( input.value, type, opts ); // String, number, boolean or null.
|
||||
if ( opts.parseWithFunction && '_' === type ) {
|
||||
value = opts.parseWithFunction( value, input.name );
|
||||
} // Allow for custom parsing.
|
||||
|
||||
f.deepSet( serializedObject, keys, value, opts );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return serializedObject;
|
||||
};
|
||||
|
||||
// Use $.serializeJSON as namespace for the auxiliar functions
|
||||
// and to define defaults.
|
||||
$.serializeJSON = {
|
||||
|
||||
defaultOptions: {
|
||||
checkboxUncheckedValue: undefined, // To include that value for unchecked checkboxes (instead of ignoring them).
|
||||
|
||||
parseNumbers: false, // Convert values like '1', '-2.33' to 1, -2.33.
|
||||
parseBooleans: false, // Convert 'true', 'false' to true, false.
|
||||
parseNulls: false, // Convert 'null' to null.
|
||||
parseAll: false, // All of the above.
|
||||
parseWithFunction: null, // To use custom parser, a function like: function(val){ return parsed_val; }.
|
||||
|
||||
customTypes: {}, // Override defaultTypes.
|
||||
defaultTypes: {
|
||||
string: function( str ) {
|
||||
return String( str );
|
||||
}, number: function( str ) {
|
||||
return Number( str );
|
||||
}, boolean: function( str ) {
|
||||
return (['false', 'null', 'undefined', '', '0'].indexOf( str ) === - 1 );
|
||||
}, null: function( str ) {
|
||||
return (['false', 'null', 'undefined', '', '0'].indexOf( str ) !== - 1 ) ? null : str;
|
||||
}, array: function( str ) {
|
||||
return JSON.parse( str );
|
||||
}, object: function( str ) {
|
||||
return JSON.parse( str );
|
||||
}, auto: function( str ) {
|
||||
return $.serializeJSON.parseValue(
|
||||
str,
|
||||
null,
|
||||
{
|
||||
parseNumbers: true,
|
||||
parseBooleans: true,
|
||||
parseNulls: true
|
||||
}
|
||||
);
|
||||
} // Try again with something like "parseAll".
|
||||
},
|
||||
|
||||
useIntKeysAsArrayIndex: false // Name="foo[2]" value="v" => {foo: [null, null, "v"]}, instead of {foo: ["2": "v"]}.
|
||||
},
|
||||
|
||||
// Merge option defaults into the options.
|
||||
setupOpts: function( options ) {
|
||||
var opt, validOpts, defaultOptions, optWithDefault, parseAll, f;
|
||||
f = $.serializeJSON;
|
||||
|
||||
if ( null === options || undefined === options ) {
|
||||
options = {}; // Options ||= {}.
|
||||
}
|
||||
|
||||
defaultOptions = f.defaultOptions || {}; // Default Options.
|
||||
|
||||
// Make sure that the user didn't misspell an option.
|
||||
validOpts = [
|
||||
'checkboxUncheckedValue',
|
||||
'parseNumbers',
|
||||
'parseBooleans',
|
||||
'parseNulls',
|
||||
'parseAll',
|
||||
'parseWithFunction',
|
||||
'customTypes',
|
||||
'defaultTypes',
|
||||
'useIntKeysAsArrayIndex'
|
||||
]; // Re-define because the user may override the defaultOptions.
|
||||
|
||||
for ( opt in options ) {
|
||||
if ( validOpts.indexOf( opt ) === - 1 ) {
|
||||
throw new Error( 'serializeJSON ERROR: invalid option ' + opt + '. Please use one of ' + validOpts.join( ', ' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to get the default value for this option if none is specified by the user.
|
||||
optWithDefault = function( key ) {
|
||||
return ( false !== options[key] ) && ( '' !== options[key] ) && ( options[key] || defaultOptions[key] );
|
||||
};
|
||||
|
||||
// Return computed options (opts to be used in the rest of the script).
|
||||
parseAll = optWithDefault( 'parseAll' );
|
||||
return {
|
||||
checkboxUncheckedValue: optWithDefault( 'checkboxUncheckedValue' ),
|
||||
parseNumbers: parseAll || optWithDefault( 'parseNumbers' ),
|
||||
parseBooleans: parseAll || optWithDefault( 'parseBooleans' ),
|
||||
parseNulls: parseAll || optWithDefault( 'parseNulls' ),
|
||||
parseWithFunction: optWithDefault( 'parseWithFunction' ),
|
||||
typeFunctions: $.extend( {}, optWithDefault( 'defaultTypes' ), optWithDefault( 'customTypes' ) ),
|
||||
useIntKeysAsArrayIndex: optWithDefault( 'useIntKeysAsArrayIndex' )
|
||||
};
|
||||
},
|
||||
|
||||
// Given a string, apply the type or the relevant "parse" options, to return the parsed value.
|
||||
parseValue: function( str, type, opts ) {
|
||||
var typeFunction, f;
|
||||
f = $.serializeJSON;
|
||||
|
||||
// Parse with a type if available.
|
||||
typeFunction = opts.typeFunctions && opts.typeFunctions[type];
|
||||
if ( typeFunction ) {
|
||||
return typeFunction( str ); // Use specific type.
|
||||
}
|
||||
|
||||
// Otherwise, check if there is any auto-parse option enabled and use it.
|
||||
if ( opts.parseNumbers && f.isNumeric( str ) ) {
|
||||
return Number( str );
|
||||
} // Auto: number.
|
||||
|
||||
if ( opts.parseBooleans && ( 'true' === str || 'false' === str ) ) {
|
||||
return 'true' === str;
|
||||
} // Auto: boolean.
|
||||
|
||||
if ( opts.parseNulls && 'null' === str ) {
|
||||
return null;
|
||||
} // Auto: null.
|
||||
|
||||
// If none applies, just return the str.
|
||||
return str;
|
||||
},
|
||||
|
||||
isObject: function( obj ) {
|
||||
return obj === Object( obj );
|
||||
}, // Is this variable an object?
|
||||
isUndefined: function( obj ) {
|
||||
return obj === void 0;
|
||||
}, // Safe check for undefined values.
|
||||
isValidArrayIndex: function( val ) {
|
||||
return /^[0-9]+$/.test( String( val ) );
|
||||
}, // 1,2,3,4 ... are valid array indexes
|
||||
isNumeric: function( obj ) {
|
||||
return obj - parseFloat( obj ) >= 0;
|
||||
}, // Taken from jQuery.isNumeric implementation. Not using jQuery.isNumeric to support old jQuery and Zepto versions.
|
||||
|
||||
optionKeys: function( obj ) {
|
||||
var keys;
|
||||
var key;
|
||||
|
||||
if ( Object.keys ) {
|
||||
return Object.keys( obj );
|
||||
} else {
|
||||
keys = [];
|
||||
for ( key in obj ) {
|
||||
if ( obj.hasOwnProperty( key ) ) {
|
||||
keys.push( key );
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
}, // Polyfill Object.keys to get option keys in IE<9.
|
||||
|
||||
// Split the input name in programatically readable keys.
|
||||
// The last element is always the type (default "_").
|
||||
// Examples:
|
||||
// "foo" => ['foo', '_']
|
||||
// "foo:string" => ['foo', 'string']
|
||||
// "foo:boolean" => ['foo', 'boolean']
|
||||
// "[foo]" => ['foo', '_']
|
||||
// "foo[inn][bar]" => ['foo', 'inn', 'bar', '_']
|
||||
// "foo[inn[bar]]" => ['foo', 'inn', 'bar', '_']
|
||||
// "foo[inn][arr][0]" => ['foo', 'inn', 'arr', '0', '_']
|
||||
// "arr[][val]" => ['arr', '', 'val', '_']
|
||||
// "arr[][val]:null" => ['arr', '', 'val', 'null'] .
|
||||
splitInputNameIntoKeysArray: function( name, opts ) {
|
||||
var keys, nameWithoutType, type, _ref, f;
|
||||
|
||||
f = $.serializeJSON;
|
||||
_ref = f.extractTypeFromInputName( name, opts );
|
||||
nameWithoutType = _ref[0];
|
||||
type = _ref[1];
|
||||
|
||||
keys = nameWithoutType.split( '[' ); // Split string into array.
|
||||
keys = $.map(
|
||||
keys,
|
||||
function( key ) {
|
||||
return key.replace( /]/g, '' );
|
||||
}
|
||||
); // Remove closing brackets.
|
||||
|
||||
if ( '' === keys[0] ) {
|
||||
keys.shift();
|
||||
} // Ensure no opening bracket ("[foo][inn]" should be same as "foo[inn]").
|
||||
|
||||
keys.push( type ); // Add type at the end.
|
||||
return keys;
|
||||
},
|
||||
|
||||
// Returns [name-without-type, type] from name.
|
||||
// "foo" => ["foo", '_']
|
||||
// "foo:boolean" => ["foo", 'boolean']
|
||||
// "foo[bar]:null" => ["foo[bar]", 'null'].
|
||||
extractTypeFromInputName: function( name, opts ) {
|
||||
var match, validTypes, f;
|
||||
|
||||
match = name.match( /(.*):([^:]+)$/ );
|
||||
|
||||
if ( match ) {
|
||||
f = $.serializeJSON;
|
||||
|
||||
validTypes = f.optionKeys( opts ? opts.typeFunctions : f.defaultOptions.defaultTypes );
|
||||
validTypes.push( 'skip' ); // Skip is a special type that makes it easy to remove.
|
||||
if ( validTypes.indexOf( match[2] ) !== - 1 ) {
|
||||
return [match[1], match[2]];
|
||||
} else {
|
||||
throw new Error( 'serializeJSON ERROR: Invalid type ' + match[2] + ' found in input name "' + name + '", please use one of ' + validTypes.join( ', ' ) );
|
||||
}
|
||||
} else {
|
||||
return [name, '_']; // No defined type, then use parse options.
|
||||
}
|
||||
},
|
||||
|
||||
// Set a value in an object or array, using multiple keys to set in a nested object or array:
|
||||
// jscs:disable requireCapitalizedComments
|
||||
//
|
||||
// deepSet(obj, ['foo'], v) // obj['foo'] = v
|
||||
// deepSet(obj, ['foo', 'inn'], v) // obj['foo']['inn'] = v // Create the inner obj['foo'] object, if needed
|
||||
// deepSet(obj, ['foo', 'inn', '123'], v) // obj['foo']['arr']['123'] = v //
|
||||
//
|
||||
// deepSet(obj, ['0'], v) // obj['0'] = v
|
||||
// deepSet(arr, ['0'], v, {useIntKeysAsArrayIndex: true}) // arr[0] = v
|
||||
// deepSet(arr, [''], v) // arr.push(v)
|
||||
// deepSet(obj, ['arr', ''], v) // obj['arr'].push(v)
|
||||
//
|
||||
// arr = [];
|
||||
// deepSet(arr, ['', v] // arr => [v]
|
||||
// deepSet(arr, ['', 'foo'], v) // arr => [v, {foo: v}]
|
||||
// deepSet(arr, ['', 'bar'], v) // arr => [v, {foo: v, bar: v}]
|
||||
// deepSet(arr, ['', 'bar'], v) // arr => [v, {foo: v, bar: v}, {bar: v}].
|
||||
deepSet: function( o, keys, value, opts ) {
|
||||
var key, nextKey, tail, lastIdx, lastVal, f;
|
||||
if ( null === opts ) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
f = $.serializeJSON;
|
||||
|
||||
if ( f.isUndefined( o ) ) {
|
||||
throw new Error( 'ArgumentError: param \'o\' expected to be an object or array, found undefined' );
|
||||
}
|
||||
if ( ! keys || 0 === keys.length ) {
|
||||
throw new Error( 'ArgumentError: param \'keys\' expected to be an array with least one element' );
|
||||
}
|
||||
|
||||
key = keys[0];
|
||||
|
||||
// Only one key, then it's not a deepSet, just assign the value.
|
||||
if ( 1 === keys.length ) {
|
||||
if ( '' === key ) {
|
||||
o.push( value ); // '' is used to push values into the array (assume o is an array)
|
||||
} else {
|
||||
o[key] = value; // Other keys can be used as object keys or array indexes.
|
||||
}
|
||||
|
||||
// With more keys is a deepSet. Apply recursively.
|
||||
} else {
|
||||
nextKey = keys[1];
|
||||
|
||||
// '' is used to push values into the array,
|
||||
// with nextKey, set the value into the same object, in object[nextKey].
|
||||
// Covers the case of ['', 'foo'] and ['', 'var'] to push the object {foo, var}, and the case of nested arrays.
|
||||
if ( '' === key ) {
|
||||
lastIdx = o.length - 1; // asume o is array.
|
||||
lastVal = o[lastIdx];
|
||||
if ( f.isObject( lastVal ) && ( f.isUndefined( lastVal[nextKey] ) || keys.length > 2 ) ) { // If nextKey is not present in the last object element, or there are more keys to deep set.
|
||||
key = lastIdx; // then set the new value in the same object element.
|
||||
} else {
|
||||
key = lastIdx + 1; // otherwise, point to set the next index in the array.
|
||||
}
|
||||
}
|
||||
|
||||
// '' is used to push values into the array "array[]"
|
||||
if ( '' === nextKey ) {
|
||||
if ( f.isUndefined( o[key] ) || ! $.isArray( o[key] ) ) {
|
||||
o[key] = []; // define (or override) as array to push values.
|
||||
}
|
||||
} else {
|
||||
if ( opts.useIntKeysAsArrayIndex && f.isValidArrayIndex( nextKey ) ) { // if 1, 2, 3 ... then use an array, where nextKey is the index.
|
||||
if ( f.isUndefined( o[key] ) || ! $.isArray( o[key] ) ) {
|
||||
o[key] = []; // define (or override) as array, to insert values using int keys as array indexes.
|
||||
}
|
||||
} else { // for anything else, use an object, where nextKey is going to be the attribute name.
|
||||
if ( f.isUndefined( o[key] ) || ! f.isObject( o[key] ) ) {
|
||||
o[key] = {}; // define (or override) as object, to set nested properties.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively set the inner object.
|
||||
tail = keys.slice( 1 );
|
||||
f.deepSet( o[key], tail, value, opts );
|
||||
}
|
||||
},
|
||||
|
||||
// Fill the formAsArray object with values for the unchecked checkbox inputs,
|
||||
// using the same format as the jquery.serializeArray function.
|
||||
// The value of the unchecked values is determined from the opts.checkboxUncheckedValue
|
||||
// and/or the data-unchecked-value attribute of the inputs.
|
||||
readCheckboxUncheckedValues: function( formAsArray, $form, opts ) {
|
||||
var selector, $uncheckedCheckboxes, $el, dataUncheckedValue, f;
|
||||
if ( null === opts ) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
f = $.serializeJSON;
|
||||
|
||||
selector = 'input[type=checkbox][name]:not(:checked):not([disabled])';
|
||||
$uncheckedCheckboxes = $form.find( selector ).add( $form.filter( selector ) );
|
||||
$uncheckedCheckboxes.each(
|
||||
function( i, el ) {
|
||||
i = null;
|
||||
$el = $( el );
|
||||
dataUncheckedValue = $el.attr( 'data-unchecked-value' );
|
||||
if ( dataUncheckedValue ) { // data-unchecked-value has precedence over option opts.checkboxUncheckedValue.
|
||||
formAsArray.push( { name: el.name, value: dataUncheckedValue } );
|
||||
} else {
|
||||
if ( ! f.isUndefined( opts.checkboxUncheckedValue ) ) {
|
||||
formAsArray.push( { name: el.name, value: opts.checkboxUncheckedValue } );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}( window.jQuery || window.$ ) );
|
||||
|
||||
(function( $ ) {
|
||||
'use strict';
|
||||
|
||||
redux.customizer = redux.customizer || {};
|
||||
|
||||
$( document ).ready(
|
||||
function() {
|
||||
redux.customizer.init();
|
||||
}
|
||||
);
|
||||
|
||||
redux.customizer.init = function() {
|
||||
var reduxChange;
|
||||
var redux_initFields;
|
||||
|
||||
$( 'body' ).addClass( redux.customizer.body_class );
|
||||
$( '.accordion-section.redux-section, .accordion-section.redux-panel, .accordion-section-title' ).click(
|
||||
function() {
|
||||
$.redux.initFields();
|
||||
}
|
||||
);
|
||||
|
||||
if ( undefined === redux.optName ) {
|
||||
console.log( 'Redux customizer extension failure' );
|
||||
return;
|
||||
}
|
||||
|
||||
redux.optName.args.disable_save_warn = true;
|
||||
reduxChange = redux_change;
|
||||
redux_change = function( variable ) {
|
||||
variable = $( variable );
|
||||
reduxChange.apply( this, arguments );
|
||||
redux.customizer.save( variable );
|
||||
};
|
||||
|
||||
redux_initFields = $.redux.initFields;
|
||||
|
||||
$.redux.initFiles = function() {
|
||||
redux_initFields();
|
||||
};
|
||||
};
|
||||
|
||||
redux.customizer.save = function( $obj ) {
|
||||
var $parent = $obj.hasClass( 'redux-field' ) ? $obj : $obj.parents( '.redux-field-container:first' );
|
||||
redux.customizer.inputSave( $parent );
|
||||
};
|
||||
|
||||
redux.customizer.inputSave = function( $parent ) {
|
||||
var $id;
|
||||
var $nData;
|
||||
var $key;
|
||||
var $control;
|
||||
|
||||
if ( ! $parent.hasClass( 'redux-field-container' ) ) {
|
||||
$parent = $parent.parents( '[class^="redux-field-container"]' );
|
||||
}
|
||||
|
||||
$id = $parent.parent().find( '.redux-customizer-input' ).data( 'id' );
|
||||
|
||||
if ( ! $id ) {
|
||||
$parent = $parent.parents( '.redux-container-repeater:first' );
|
||||
$id = $parent.parent().find( '.redux-customizer-input' ).data( 'id' );
|
||||
}
|
||||
|
||||
// var $nData = $parent.serializeJSON(); .
|
||||
$nData = $parent.find( ':input' ).serializeJSON();
|
||||
|
||||
$.each(
|
||||
$nData,
|
||||
function( $k, $v ) {
|
||||
$k = null;
|
||||
$nData = $v;
|
||||
}
|
||||
);
|
||||
|
||||
$key = $parent.parent().find( '.redux-customizer-input' ).data( 'key' );
|
||||
if ( $nData[$key] ) {
|
||||
$nData = $nData[$key];
|
||||
}
|
||||
|
||||
$control = wp.customize.control( $id );
|
||||
|
||||
// Customizer hack since they didn't code it to save order...
|
||||
if ( JSON.stringify( $control.setting._value ) !== JSON.stringify( $nData ) ) {
|
||||
$control.setting._value = null;
|
||||
}
|
||||
|
||||
$control.setting.set( $nData );
|
||||
};
|
||||
})( jQuery );
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,119 @@
|
||||
.wp-customizer {
|
||||
.redux-container {
|
||||
overflow: visible;
|
||||
.redux-main {
|
||||
input {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
input.spinner-input {
|
||||
margin-right: 30px !important;
|
||||
margin-left: 30px !important;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.redux-section.open .redux-group-tab {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.redux-section {
|
||||
p.customize-section-description {
|
||||
margin-top: 22px;
|
||||
word-break: break-word;
|
||||
&.legacy {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.control-section-themes .accordion-section-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#customize-controls {
|
||||
.description {
|
||||
display: block;
|
||||
}
|
||||
.customize-info {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.redux-section .accordion-section-content {
|
||||
background: #fcfcfc;
|
||||
}
|
||||
}
|
||||
|
||||
.redux-section .accordion-section-title i,
|
||||
.redux-field .accordion-field-title i,
|
||||
.redux-panel .accordion-section-title i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.accordion-section.redux-main {
|
||||
background: inherit;
|
||||
margin-left: inherit;
|
||||
border-left: inherit;
|
||||
-moz-box-shadow: inherit;
|
||||
-webkit-box-shadow: inherit;
|
||||
padding: inherit;
|
||||
box-shadow: inherit;
|
||||
}
|
||||
|
||||
.redux_field_th {
|
||||
padding: 13px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.redux-main {
|
||||
.redux-field-container {
|
||||
padding: 10px 0;
|
||||
}
|
||||
.select_wrapper {
|
||||
float: none;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.select2-container {
|
||||
margin-right: 0 !important;
|
||||
margin-bottom: 5px !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.select_wrapper:nth-child(odd) {
|
||||
margin-right: 0;
|
||||
}
|
||||
.redux-option-image {
|
||||
max-width: 42% !important;
|
||||
margin-right: 3%;
|
||||
}
|
||||
.customize-control {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
.customize-control:last-child {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.upload {
|
||||
width: 100% !important;
|
||||
}
|
||||
h3 {
|
||||
margin-top: inherit;
|
||||
}
|
||||
.redux-container-raw {
|
||||
margin-top: 22px;
|
||||
word-break: break-word;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.redux-container-password input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-drop,
|
||||
.select2-container {
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.customize-control-redux-raw {
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Import/Export Extention Class
|
||||
*
|
||||
* @class Redux_Extension_Import_Export
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Extension_Import_Export', false ) ) {
|
||||
|
||||
/**
|
||||
* Main ReduxFramework import_export extension class
|
||||
*
|
||||
* @since 3.1.6
|
||||
*/
|
||||
class Redux_Extension_Import_Export extends Redux_Extension_Abstract {
|
||||
|
||||
/**
|
||||
* Ext version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $version = '4.0';
|
||||
|
||||
/**
|
||||
* Is field bit.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is_field = false;
|
||||
|
||||
/**
|
||||
* Class Constructor. Defines the args for the extions class
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param object $parent ReduxFramework object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent, __FILE__ );
|
||||
|
||||
$this->add_field( 'import_export' );
|
||||
|
||||
add_action(
|
||||
'wp_ajax_redux_link_options-' . $this->parent->args['opt_name'],
|
||||
array(
|
||||
$this,
|
||||
'link_options',
|
||||
)
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wp_ajax_nopriv_redux_link_options-' . $this->parent->args['opt_name'],
|
||||
array(
|
||||
$this,
|
||||
'link_options',
|
||||
)
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wp_ajax_redux_download_options-' . $this->parent->args['opt_name'],
|
||||
array(
|
||||
$this,
|
||||
'download_options',
|
||||
)
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wp_ajax_nopriv_redux_download_options-' . $this->parent->args['opt_name'],
|
||||
array(
|
||||
$this,
|
||||
'download_options',
|
||||
)
|
||||
);
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/options/' . $this->parent->args['opt_name'] . '/import', array( $this, 'remove_cookie' ) );
|
||||
|
||||
$this->is_field = Redux_Helpers::is_field_in_use( $parent, 'import_export' );
|
||||
|
||||
if ( ! $this->is_field && $this->parent->args['show_import_export'] ) {
|
||||
$this->add_section();
|
||||
}
|
||||
|
||||
add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the appropriate mime types to WordPress
|
||||
*
|
||||
* @param array $existing_mimes .
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function custom_upload_mimes( $existing_mimes = array() ) {
|
||||
$existing_mimes['redux'] = 'application/redux';
|
||||
|
||||
return $existing_mimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add section to panel.
|
||||
*/
|
||||
public function add_section() {
|
||||
$this->parent->sections[] = array(
|
||||
'id' => 'import/export',
|
||||
'title' => esc_html__( 'Import / Export', 'redux-framework' ),
|
||||
'heading' => '',
|
||||
'icon' => 'el el-refresh',
|
||||
'customizer' => false,
|
||||
'fields' => array(
|
||||
array(
|
||||
'id' => 'redux_import_export',
|
||||
'type' => 'import_export',
|
||||
'full_width' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import link options.
|
||||
*/
|
||||
public function link_options() {
|
||||
if ( ! isset( $_GET['secret'] ) || md5( md5( Redux_Functions_Ex::hash_key() ) . '-' . $this->parent->args['opt_name'] ) !== $_GET['secret'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
wp_die( 'Invalid Secret for options use' );
|
||||
exit;
|
||||
}
|
||||
|
||||
$var = $this->parent->options;
|
||||
$var['redux-backup'] = 1;
|
||||
|
||||
if ( isset( $var['REDUX_imported'] ) ) {
|
||||
unset( $var['REDUX_imported'] );
|
||||
}
|
||||
|
||||
echo wp_json_encode( $var );
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import download options.
|
||||
*/
|
||||
public function download_options() {
|
||||
if ( ! isset( $_GET['secret'] ) || md5( md5( Redux_Functions_Ex::hash_key() ) . '-' . $this->parent->args['opt_name'] ) !== $_GET['secret'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
wp_die( 'Invalid Secret for options use' );
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->parent->get_options();
|
||||
$backup_options = $this->parent->options;
|
||||
$backup_options['redux-backup'] = 1;
|
||||
|
||||
if ( isset( $backup_options['REDUX_imported'] ) ) {
|
||||
unset( $backup_options['REDUX_imported'] );
|
||||
}
|
||||
|
||||
// No need to escape this, as it's been properly escaped previously and through json_encode.
|
||||
$content = wp_json_encode( $backup_options );
|
||||
|
||||
if ( isset( $_GET['action'] ) && 'redux_download_options-' . $this->parent->args['opt_name'] === $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
header( 'Content-Description: File Transfer' );
|
||||
header( 'Content-type: application/txt' );
|
||||
header( 'Content-Disposition: attachment; filename="redux_options_"' . $this->parent->args['opt_name'] . '_backup_' . gmdate( 'd-m-Y' ) . '.json' );
|
||||
header( 'Content-Transfer-Encoding: binary' );
|
||||
header( 'Expires: 0' );
|
||||
header( 'Cache-Control: must-revalidate' );
|
||||
header( 'Pragma: public' );
|
||||
|
||||
echo( $content ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
|
||||
exit;
|
||||
} else {
|
||||
header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
|
||||
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . 'GMT' );
|
||||
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
|
||||
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
|
||||
header( 'Cache-Control: post-check=0, pre-check=0', false );
|
||||
header( 'Pragma: no-cache' );
|
||||
|
||||
// Can't include the type. Thanks old Firefox and IE. BAH.
|
||||
// header('Content-type: application/json');.
|
||||
echo( $content ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove current tab cookie.
|
||||
*/
|
||||
public function remove_cookie() {
|
||||
// Remove the import/export tab cookie.
|
||||
if ( isset( $_COOKIE ) && isset( $_COOKIE[ 'redux_current_tab_' . $this->parent->args['opt_name'] ] ) && 'import_export_default' === $_COOKIE[ 'redux_current_tab_' . $this->parent->args['opt_name'] ] ) {
|
||||
setcookie( 'redux_current_tab_' . $this->parent->args['opt_name'], '', 1, '/' );
|
||||
$_COOKIE[ 'redux_current_tab_' . $this->parent->args['opt_name'] ] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'ReduxFramework_extension_import_export' ) ) {
|
||||
class_alias( 'Redux_Extension_Import_Export', 'ReduxFramework_extension_import_export' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php // phpcs:disable WordPress.WhiteSpace.PrecisionAlignment.Found
|
||||
/**
|
||||
* Import & Export for Option Panel
|
||||
*
|
||||
* @package ReduxFramework
|
||||
* @author Dovy Paukstys
|
||||
* @version 4.0.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Import_Export', false ) ) {
|
||||
|
||||
/**
|
||||
* Main Redux_import_export class
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Redux_Import_Export extends Redux_Field {
|
||||
|
||||
|
||||
/**
|
||||
* Redux_Import_Export constructor.
|
||||
*
|
||||
* @param array $field Field array.
|
||||
* @param string $value Value array.
|
||||
* @param object $parent ReduxFramework object.
|
||||
*
|
||||
* @throws ReflectionException .
|
||||
*/
|
||||
public function __construct( $field = array(), $value = '', $parent ) {
|
||||
parent::__construct( $field, $value, $parent );
|
||||
|
||||
$this->is_field = $this->parent->extensions['import_export']->is_field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field defaults.
|
||||
*/
|
||||
public function set_defaults() {
|
||||
// Set default args for this field to avoid bad indexes. Change this to anything you use.
|
||||
$defaults = array(
|
||||
'options' => array(),
|
||||
'stylesheet' => '',
|
||||
'output' => true,
|
||||
'enqueue' => true,
|
||||
'enqueue_frontend' => true,
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Field Render Function.
|
||||
* Takes the vars and outputs the HTML for the field in the settings
|
||||
*
|
||||
* @return void
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function render() {
|
||||
$secret = md5( md5( Redux_Functions_Ex::hash_key() ) . '-' . $this->parent->args['opt_name'] );
|
||||
|
||||
// No errors please.
|
||||
$defaults = array(
|
||||
'full_width' => true,
|
||||
'overflow' => 'inherit',
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $defaults );
|
||||
|
||||
$do_close = false;
|
||||
|
||||
$id = $this->parent->args['opt_name'] . '-' . $this->field['id'];
|
||||
?>
|
||||
<h4><?php esc_html_e( 'Import Options', 'redux-framework' ); ?></h4>
|
||||
<p>
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
id="redux-import-code-button"
|
||||
class="button-secondary">
|
||||
<?php esc_html_e( 'Import from Clipboard', 'redux-framework' ); ?>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
id="redux-import-link-button"
|
||||
class="button-secondary">
|
||||
<?php esc_html_e( 'Import from URL', 'redux-framework' ); ?>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="#"
|
||||
id="redux-import-upload"
|
||||
class="button-secondary">
|
||||
<?php esc_html_e( 'Upload file', 'redux-framework' ); ?><span></span>
|
||||
</a>
|
||||
<input type="file" id="redux-import-upload-file" size="50">
|
||||
</p>
|
||||
<div id="redux-import-code-wrapper">
|
||||
<p class="description" id="import-code-description">
|
||||
<?php // phpcs:ignore WordPress.NamingConventions.ValidHookName ?>
|
||||
<?php echo esc_html( apply_filters( 'redux-import-file-description', esc_html__( 'Paste your clipboard data here.', 'redux-framework' ) ) ); ?>
|
||||
</p>
|
||||
<textarea
|
||||
id="import-code-value"
|
||||
name="<?php echo esc_attr( $this->parent->args['opt_name'] ); ?>[import_code]"
|
||||
class="large-text no-update" rows="3"></textarea>
|
||||
</div>
|
||||
<div id="redux-import-link-wrapper">
|
||||
<p class="description" id="import-link-description">
|
||||
<?php // phpcs:ignore WordPress.NamingConventions.ValidHookName ?>
|
||||
<?php echo esc_html( apply_filters( 'redux-import-link-description', esc_html__( 'Input the URL to another sites options set and hit Import to load the options from that site.', 'redux-framework' ) ) ); ?>
|
||||
</p>
|
||||
<input
|
||||
class="large-text no-update"
|
||||
id="import-link-value"
|
||||
name="<?php echo esc_attr( $this->parent->args['opt_name'] ); ?>[import_link]"
|
||||
rows="2"/>
|
||||
</div>
|
||||
<p id="redux-import-action">
|
||||
<input
|
||||
type="submit"
|
||||
id="redux-import"
|
||||
name="import"
|
||||
class="button-primary"
|
||||
value="<?php esc_html_e( 'Import', 'redux-framework' ); ?>">
|
||||
<span>
|
||||
<?php // phpcs:ignore WordPress.NamingConventions.ValidHookName ?>
|
||||
<?php echo esc_html( apply_filters( 'redux-import-warning', esc_html__( 'WARNING! This will overwrite all existing option values, please proceed with caution!', 'redux-framework' ) ) ); ?>
|
||||
</span>
|
||||
</p>
|
||||
<div class="hr">
|
||||
<div class="inner">
|
||||
<span> </span>
|
||||
</div>
|
||||
</div>
|
||||
<h4><?php esc_html_e( 'Export Options', 'redux-framework' ); ?></h4>
|
||||
<div class="redux-section-desc">
|
||||
<p class="description">
|
||||
<?php // phpcs:ignore WordPress.NamingConventions.ValidHookName ?>
|
||||
<?php echo esc_html( apply_filters( 'redux-backup-description', esc_html__( 'Here you can copy/download your current option settings. Keep this safe as you can use it as a backup should anything go wrong, or you can use it to restore your settings on this site (or any other site).', 'redux-framework' ) ) ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php $link = admin_url( 'admin-ajax.php?action=redux_download_options-' . $this->parent->args['opt_name'] . '&secret=' . $secret ); ?>
|
||||
<p>
|
||||
<button id="redux-export-code-copy" class="button-secondary"
|
||||
data-secret="<?php echo esc_attr( $secret ); ?>"
|
||||
data-copy="<?php esc_attr_e( 'Copy to Clipboard', 'redux-framework' ); ?>"
|
||||
data-copied="<?php esc_attr_e( 'Copied!', 'redux-framework' ); ?>">
|
||||
<?php esc_html_e( 'Copy to Clipboard', 'redux-framework' ); ?>
|
||||
</button>
|
||||
<a href="<?php echo esc_url( $link ); ?>" id="redux-export-code-dl" class="button-primary">
|
||||
<?php esc_html_e( 'Export File', 'redux-framework' ); ?>
|
||||
</a>
|
||||
<a href="javascript:void(0);" id="redux-export-link" class="button-secondary"
|
||||
data-copy="<?php esc_attr_e( 'Copy Export URL', 'redux-framework' ); ?>"
|
||||
data-copied="<?php esc_attr_e( 'Copied!', 'redux-framework' ); ?>"
|
||||
data-url="<?php echo esc_url( $link ); ?>">
|
||||
<?php esc_html_e( 'Copy Export URL', 'redux-framework' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
<p></p>
|
||||
<textarea class="large-text no-update" id="redux-export-code" rows="1"></textarea>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Function.
|
||||
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
|
||||
*
|
||||
* @return void
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue() {
|
||||
wp_enqueue_script(
|
||||
'redux-extension-import-export-js',
|
||||
$this->url . 'redux-import-export' . Redux_Functions::is_min() . '.js',
|
||||
array(
|
||||
'jquery',
|
||||
'redux-js',
|
||||
),
|
||||
Redux_Extension_Import_Export::$version,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_style( 'redux-import-export', $this->url . 'redux-import-export.css', array(), Redux_Extension_Import_Export::$version, 'all' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,11 @@
|
||||
.redux-container-import_export #redux-import-link-wrapper, .redux-container-import_export #redux-import-code-wrapper { display: none; }
|
||||
|
||||
.redux-container-import_export #redux-export-code, .redux-container-import_export #redux-export-link-value, .redux-container-import_export #redux-import-upload-file { display: none; }
|
||||
|
||||
.redux-container-import_export #redux-import-action span { color: #b94a48; }
|
||||
|
||||
.redux-container-import_export #redux-import-upload span { font-weight: bold; }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtaW1wb3J0LWV4cG9ydC5jc3MiLCJzb3VyY2VzIjpbInJlZHV4LWltcG9ydC1leHBvcnQuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUNJLDhCQUQwQixDQUMxQiwwQkFBMEIsRUFEOUIsOEJBQThCLENBRTFCLDBCQUEwQixDQUFDLEVBQ3ZCLE9BQU8sRUFBRSxJQUFJLEdBQ2hCOztBQUpMLEFBTUksOEJBTjBCLENBTTFCLGtCQUFrQixFQU50Qiw4QkFBOEIsQ0FPMUIsd0JBQXdCLEVBUDVCLDhCQUE4QixDQVExQix5QkFBeUIsQ0FBQyxFQUN0QixPQUFPLEVBQUUsSUFBSSxHQUNoQjs7QUFWTCxBQVlJLDhCQVowQixDQVkxQixvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFDdEIsS0FBSyxFQUFFLE9BQU8sR0FDakI7O0FBZEwsQUFlSSw4QkFmMEIsQ0FlMUIsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQ3RCLFdBQVcsRUFBRSxJQUFJLEdBQ3BCIn0= */
|
||||
|
||||
/*# sourceMappingURL=redux-import-export.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["redux-import-export.scss","redux-import-export.css"],"names":[],"mappings":"AAAA,uHCGQ,aAAa,EAAA;;ADHrB,uKCSQ,aAAa,EAAA;;ADTrB,2DCaQ,cAAc,EAAA;;ADbtB,2DCgBQ,iBAAiB,EAAA;;AARzB,qqBAAqqB","file":"redux-import-export.css","sourcesContent":[".redux-container-import_export {\n #redux-import-link-wrapper,\n #redux-import-code-wrapper {\n display: none;\n }\n\n #redux-export-code,\n #redux-export-link-value,\n #redux-import-upload-file {\n display: none;\n }\n\n #redux-import-action span {\n color: #b94a48;\n }\n #redux-import-upload span {\n font-weight: bold;\n }\n}\n\n",".redux-container-import_export #redux-import-link-wrapper, .redux-container-import_export #redux-import-code-wrapper { display: none; }\n\n.redux-container-import_export #redux-export-code, .redux-container-import_export #redux-export-link-value, .redux-container-import_export #redux-import-upload-file { display: none; }\n\n.redux-container-import_export #redux-import-action span { color: #b94a48; }\n\n.redux-container-import_export #redux-import-upload span { font-weight: bold; }\n\n/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtaW1wb3J0LWV4cG9ydC5jc3MiLCJzb3VyY2VzIjpbInJlZHV4LWltcG9ydC1leHBvcnQuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUNJLDhCQUQwQixDQUMxQiwwQkFBMEIsRUFEOUIsOEJBQThCLENBRTFCLDBCQUEwQixDQUFDLEVBQ3ZCLE9BQU8sRUFBRSxJQUFJLEdBQ2hCOztBQUpMLEFBTUksOEJBTjBCLENBTTFCLGtCQUFrQixFQU50Qiw4QkFBOEIsQ0FPMUIsd0JBQXdCLEVBUDVCLDhCQUE4QixDQVExQix5QkFBeUIsQ0FBQyxFQUN0QixPQUFPLEVBQUUsSUFBSSxHQUNoQjs7QUFWTCxBQVlJLDhCQVowQixDQVkxQixvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFDdEIsS0FBSyxFQUFFLE9BQU8sR0FDakI7O0FBZEwsQUFlSSw4QkFmMEIsQ0FlMUIsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQ3RCLFdBQVcsRUFBRSxJQUFJLEdBQ3BCIn0= */\n\n/*# sourceMappingURL=redux-import-export.css.map */\n"]}
|
||||
@@ -0,0 +1,246 @@
|
||||
/* global jQuery, document, redux, ajaxurl */
|
||||
|
||||
(function( $ ) {
|
||||
'use strict';
|
||||
|
||||
redux.field_objects = redux.field_objects || {};
|
||||
redux.field_objects.import_export = redux.field_objects.import_export || {};
|
||||
|
||||
redux.field_objects.import_export.copy_text = function( $text ) {
|
||||
var copyFrom = document.createElement( 'textarea' );
|
||||
document.body.appendChild( copyFrom );
|
||||
copyFrom.textContent = $text;
|
||||
copyFrom.select();
|
||||
document.execCommand( 'copy' );
|
||||
copyFrom.remove();
|
||||
};
|
||||
|
||||
redux.field_objects.import_export.get_options = function( $secret ) {
|
||||
var $el = $( '#redux-export-code-copy' );
|
||||
var url = ajaxurl + '?download=0&action=redux_download_options-' + redux.optName.args.opt_name + '&secret=' + $secret;
|
||||
$el.addClass( 'disabled' ).attr( 'disabled', 'disabled' );
|
||||
$el.text( $el.data( 'copy' ) );
|
||||
$.get( url, function( data ) {
|
||||
redux.field_objects.import_export.copy_text( data );
|
||||
$el.removeClass( 'disabled' );
|
||||
$el.text( $el.data( 'copied' ) );
|
||||
setTimeout( function() {
|
||||
$el.text( $el.data( 'copy' ) ).removeClass( 'disabled' ).removeAttr( 'disabled' );
|
||||
}, 2000 );
|
||||
} );
|
||||
};
|
||||
|
||||
redux.field_objects.import_export.init = function( selector ) {
|
||||
selector = $.redux.getSelector( selector, 'import_export' );
|
||||
|
||||
$( selector ).each(
|
||||
function() {
|
||||
var textBox1;
|
||||
var textBox2;
|
||||
|
||||
var el = $( this );
|
||||
var parent = el;
|
||||
|
||||
if ( ! el.hasClass( 'redux-field-container' ) ) {
|
||||
parent = el.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
if ( parent.is( ':hidden' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
el.each(
|
||||
function() {
|
||||
$( '#redux-import' ).click(
|
||||
function( e ) {
|
||||
if ( '' === $( '#import-code-value' ).val() && '' === $(
|
||||
'#import-link-value' ).val() ) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$( this ).find( '#redux-import-code-button' ).click(
|
||||
function() {
|
||||
var $el = $( '#redux-import-code-wrapper' );
|
||||
if ( $( '#redux-import-link-wrapper' ).is( ':visible' ) ) {
|
||||
$( '#import-link-value' ).val( '' );
|
||||
$( '#redux-import-link-wrapper' ).fadeOut(
|
||||
'fast',
|
||||
function() {
|
||||
$el.fadeIn(
|
||||
'fast',
|
||||
function() {
|
||||
$( '#import-code-value' ).focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
if ( $el.is( ':visible' ) ) {
|
||||
$el.fadeOut();
|
||||
} else {
|
||||
$el.fadeIn(
|
||||
'medium',
|
||||
function() {
|
||||
$( '#import-code-value' ).focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$( this ).find( '#redux-import-link-button' ).click(
|
||||
function() {
|
||||
var $el = $( '#redux-import-link-wrapper' );
|
||||
if ( $( '#redux-import-code-wrapper' ).is( ':visible' ) ) {
|
||||
$( '#import-code-value' ).text( '' );
|
||||
$( '#redux-import-code-wrapper' ).fadeOut(
|
||||
'fast',
|
||||
function() {
|
||||
$el.fadeIn(
|
||||
'fast',
|
||||
function() {
|
||||
$( '#import-link-value' ).focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
if ( $el.is( ':visible' ) ) {
|
||||
$el.fadeOut();
|
||||
} else {
|
||||
$el.fadeIn(
|
||||
'medium',
|
||||
function() {
|
||||
$( '#import-link-value' ).focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
$( this ).find( '#redux-export-code-dl' ).click( function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
if ( !! window.onbeforeunload ) {
|
||||
if ( confirm( 'Your panel has unchanged values, would you like to save them now?' ) ) {
|
||||
$( '#redux_top_save' ).click();
|
||||
setTimeout( function() {
|
||||
window.open( $( this ).attr( 'href' ) );
|
||||
}, 2000 );
|
||||
}
|
||||
} else {
|
||||
window.open( $( this ).attr( 'href' ) );
|
||||
}
|
||||
} );
|
||||
$( this ).find( '#redux-import-upload' ).click( function() {
|
||||
$( '#redux-import-upload-file' ).click();
|
||||
} );
|
||||
|
||||
document.getElementById( 'redux-import-upload-file' ).addEventListener( 'change', function() {
|
||||
var file_to_read = document.getElementById( 'redux-import-upload-file' ).files[0];
|
||||
var fileread = new FileReader();
|
||||
$( '#redux-import-upload span' ).text( ': ' + file_to_read.name );
|
||||
fileread.onload = function() {
|
||||
var content = fileread.result;
|
||||
$( '#import-code-value' ).val( content );
|
||||
};
|
||||
fileread.readAsText( file_to_read );
|
||||
} );
|
||||
$( this ).find( '#redux-export-code-copy' ).click(
|
||||
function( e ) {
|
||||
var $el = $( '#redux-export-code' );
|
||||
var $secret = $( this ).data( 'secret' );
|
||||
e.preventDefault();
|
||||
if ( !! window.onbeforeunload ) {
|
||||
if ( confirm(
|
||||
'Your panel has unchanged values, would you like to save them now?' ) ) {
|
||||
$( '#redux_top_save' ).click();
|
||||
setTimeout( function() {
|
||||
redux.field_objects.import_export.get_options( $secret, $el );
|
||||
}, 2000 );
|
||||
}
|
||||
} else {
|
||||
redux.field_objects.import_export.get_options( $secret, $el );
|
||||
}
|
||||
}
|
||||
);
|
||||
$( this ).find( 'textarea' ).focusout(
|
||||
function() {
|
||||
var $id = $( this ).attr( 'id' );
|
||||
var $el = $( this );
|
||||
var $container = $el;
|
||||
|
||||
if ( 'import-link-value' === $id || 'import-code-value' === $id ) {
|
||||
$container = $( this ).parent();
|
||||
}
|
||||
|
||||
$container.fadeOut(
|
||||
'medium',
|
||||
function() {
|
||||
if ( 'redux-export-link-value' !== $id ) {
|
||||
$el.text( '' );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$( this ).find( '#redux-export-link' ).click(
|
||||
function() {
|
||||
var $el = $( this );
|
||||
$el.addClass( 'disabled' ).attr( 'disabled', 'disabled' );
|
||||
$el.text( $el.data( 'copy' ) );
|
||||
redux.field_objects.import_export.copy_text( $el.data( 'url' ) );
|
||||
$el.removeClass( 'disabled' );
|
||||
$el.text( $el.data( 'copied' ) );
|
||||
setTimeout( function() {
|
||||
$el.text( $el.data( 'copy' ) ).removeClass( 'disabled' ).removeAttr( 'disabled' );
|
||||
}, 2000 );
|
||||
}
|
||||
);
|
||||
|
||||
textBox1 = document.getElementById( 'redux-export-code' );
|
||||
|
||||
textBox1.onfocus = function() {
|
||||
textBox1.select();
|
||||
|
||||
// Work around Chrome's little problem.
|
||||
textBox1.onmouseup = function() {
|
||||
|
||||
// Prevent further mouseup intervention.
|
||||
textBox1.onmouseup = null;
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
textBox2 = document.getElementById( 'import-code-value' );
|
||||
|
||||
textBox2.onfocus = function() {
|
||||
textBox2.select();
|
||||
|
||||
// Work around Chrome's little problem.
|
||||
textBox2.onmouseup = function() {
|
||||
|
||||
// Prevent further mouseup intervention.
|
||||
textBox2.onmouseup = null;
|
||||
return false;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
})( jQuery );
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
!function(d){"use strict";redux.field_objects=redux.field_objects||{},redux.field_objects.import_export=redux.field_objects.import_export||{},redux.field_objects.import_export.copy_text=function(e){var t=document.createElement("textarea");document.body.appendChild(t),t.textContent=e,t.select(),document.execCommand("copy"),t.remove()},redux.field_objects.import_export.get_options=function(e){var t=d("#redux-export-code-copy"),o=ajaxurl+"?download=0&action=redux_download_options-"+redux.optName.args.opt_name+"&secret="+e;t.addClass("disabled").attr("disabled","disabled"),t.text(t.data("copy")),d.get(o,function(e){redux.field_objects.import_export.copy_text(e),t.removeClass("disabled"),t.text(t.data("copied")),setTimeout(function(){t.text(t.data("copy")).removeClass("disabled").removeAttr("disabled")},2e3)})},redux.field_objects.import_export.init=function(e){e=d.redux.getSelector(e,"import_export"),d(e).each(function(){var e,t,o=d(this),i=o;o.hasClass("redux-field-container")||(i=o.parents(".redux-field-container:first")),i.is(":hidden")||i.hasClass("redux-field-init")&&(i.removeClass("redux-field-init"),o.each(function(){d("#redux-import").click(function(e){if(""===d("#import-code-value").val()&&""===d("#import-link-value").val())return e.preventDefault(),!1}),d(this).find("#redux-import-code-button").click(function(){var e=d("#redux-import-code-wrapper");d("#redux-import-link-wrapper").is(":visible")?(d("#import-link-value").val(""),d("#redux-import-link-wrapper").fadeOut("fast",function(){e.fadeIn("fast",function(){d("#import-code-value").focus()})})):e.is(":visible")?e.fadeOut():e.fadeIn("medium",function(){d("#import-code-value").focus()})}),d(this).find("#redux-import-link-button").click(function(){var e=d("#redux-import-link-wrapper");d("#redux-import-code-wrapper").is(":visible")?(d("#import-code-value").text(""),d("#redux-import-code-wrapper").fadeOut("fast",function(){e.fadeIn("fast",function(){d("#import-link-value").focus()})})):e.is(":visible")?e.fadeOut():e.fadeIn("medium",function(){d("#import-link-value").focus()})}),d(this).find("#redux-export-code-dl").click(function(e){e.preventDefault(),window.onbeforeunload?confirm("Your panel has unchanged values, would you like to save them now?")&&(d("#redux_top_save").click(),setTimeout(function(){window.open(d(this).attr("href"))},2e3)):window.open(d(this).attr("href"))}),d(this).find("#redux-import-upload").click(function(){d("#redux-import-upload-file").click()}),document.getElementById("redux-import-upload-file").addEventListener("change",function(){var e=document.getElementById("redux-import-upload-file").files[0],t=new FileReader;d("#redux-import-upload span").text(": "+e.name),t.onload=function(){var e=t.result;d("#import-code-value").val(e)},t.readAsText(e)}),d(this).find("#redux-export-code-copy").click(function(e){var t=d("#redux-export-code"),o=d(this).data("secret");e.preventDefault(),window.onbeforeunload?confirm("Your panel has unchanged values, would you like to save them now?")&&(d("#redux_top_save").click(),setTimeout(function(){redux.field_objects.import_export.get_options(o,t)},2e3)):redux.field_objects.import_export.get_options(o,t)}),d(this).find("textarea").focusout(function(){var e=d(this).attr("id"),t=d(this),o=t;"import-link-value"!==e&&"import-code-value"!==e||(o=d(this).parent()),o.fadeOut("medium",function(){"redux-export-link-value"!==e&&t.text("")})}),d(this).find("#redux-export-link").click(function(){var e=d(this);e.addClass("disabled").attr("disabled","disabled"),e.text(e.data("copy")),redux.field_objects.import_export.copy_text(e.data("url")),e.removeClass("disabled"),e.text(e.data("copied")),setTimeout(function(){e.text(e.data("copy")).removeClass("disabled").removeAttr("disabled")},2e3)}),(e=document.getElementById("redux-export-code")).onfocus=function(){e.select(),e.onmouseup=function(){return e.onmouseup=null,!1}},(t=document.getElementById("import-code-value")).onfocus=function(){t.select(),t.onmouseup=function(){return t.onmouseup=null,!1}}}))})}}(jQuery);
|
||||
@@ -0,0 +1,20 @@
|
||||
.redux-container-import_export {
|
||||
#redux-import-link-wrapper,
|
||||
#redux-import-code-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#redux-export-code,
|
||||
#redux-export-link-value,
|
||||
#redux-import-upload-file {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#redux-import-action span {
|
||||
color: #b94a48;
|
||||
}
|
||||
#redux-import-upload span {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Options Object Extension Class
|
||||
*
|
||||
* @class Redux_Core
|
||||
* @version 4.0.0
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Extension_Options_Object', false ) ) {
|
||||
|
||||
|
||||
/**
|
||||
* Main ReduxFramework options_object extension class
|
||||
*
|
||||
* @since 3.1.6
|
||||
*/
|
||||
class Redux_Extension_Options_Object extends Redux_Extension_Abstract {
|
||||
|
||||
/**
|
||||
* Ext version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $version = '4.0';
|
||||
|
||||
/**
|
||||
* Set the name of the field. Ideally, this will also be your extension's name.
|
||||
* Please use underscores and NOT dashes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $field_name = 'my_extension';
|
||||
|
||||
/**
|
||||
* Is field bit.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is_field = false;
|
||||
|
||||
/**
|
||||
* Class Constructor. Defines the args for the extions class
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $parent Redux object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
parent::__construct( $parent, __FILE__ );
|
||||
|
||||
$this->add_field( $this->field_name );
|
||||
$this->is_field = Redux_Helpers::is_field_in_use( $parent, $this->field_name );
|
||||
|
||||
if ( ! $this->is_field && $this->parent->args['dev_mode'] && $this->parent->args['show_options_object'] ) {
|
||||
$this->add_section();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sectio to panel.
|
||||
*/
|
||||
public function add_section() {
|
||||
$this->parent->sections[] = array(
|
||||
'id' => 'options-object',
|
||||
'title' => esc_html__( 'Options Object', 'redux-framework' ),
|
||||
'heading' => '',
|
||||
'icon' => 'el el-info-circle',
|
||||
'customizer' => false,
|
||||
'fields' => array(
|
||||
array(
|
||||
'id' => 'redux_options_object',
|
||||
'type' => 'options_object',
|
||||
'title' => '',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'ReduxFramework_Extension_options_object' ) ) {
|
||||
class_alias( 'Redux_Extension_Options_Object', 'ReduxFramework_Extension_options_object' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Debug Options Object
|
||||
*
|
||||
* @package ReduxFramework
|
||||
* @author Kevin Provance (kprovance)
|
||||
* @version 3.5.4
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Options_Object', false ) ) {
|
||||
|
||||
/**
|
||||
* Main Redux_options_object class
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Redux_Options_Object extends Redux_Field {
|
||||
|
||||
/**
|
||||
* Redux_Options_Object constructor.
|
||||
*
|
||||
* @param array $field Field array.
|
||||
* @param string $value Value array.
|
||||
* @param object $parent ReduxFramework object.
|
||||
*
|
||||
* @throws ReflectionException .
|
||||
*/
|
||||
public function __construct( $field = array(), $value = '', $parent ) {
|
||||
parent::__construct( $field, $value, $parent );
|
||||
|
||||
$this->is_field = $this->parent->extensions['options_object']->is_field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field defaults.
|
||||
*/
|
||||
public function set_defaults() {
|
||||
$defaults = array(
|
||||
'options' => array(),
|
||||
'stylesheet' => '',
|
||||
'output' => true,
|
||||
'enqueue' => true,
|
||||
'enqueue_frontend' => true,
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Field Render Function.
|
||||
* Takes the vars and outputs the HTML for the field in the settings
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function render() {
|
||||
if ( version_compare( phpversion(), '5.3.0', '>=' ) ) {
|
||||
$json = wp_json_encode( $this->parent->options, true );
|
||||
} else {
|
||||
$json = wp_json_encode( $this->parent->options );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'full_width' => true,
|
||||
'overflow' => 'inherit',
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $defaults );
|
||||
|
||||
if ( $this->is_field ) {
|
||||
$full_width = $this->field['full_width'];
|
||||
}
|
||||
|
||||
$do_close = false;
|
||||
|
||||
$id = $this->parent->args['opt_name'] . '-' . $this->field['id'];
|
||||
|
||||
if ( ! $this->is_field || ( $this->is_field && false === $full_width ) ) {
|
||||
?>
|
||||
<style>#<?php echo esc_html( $id ); ?>{padding: 0;}</style>
|
||||
<?php // phpcs:ignore WordPress.CodeAnalysis.EmptyStatement ?>
|
||||
<?php echo '</td></tr></table>'; ?>
|
||||
<table id="<?php echo esc_attr( $id ); ?>" class="form-table no-border redux-group-table redux-raw-table" style=" overflow: <?php esc_attr( $this->field['overflow'] ); ?>;">
|
||||
<tbody><tr><td>
|
||||
<?php
|
||||
$do_close = true;
|
||||
}
|
||||
?>
|
||||
<fieldset
|
||||
id="<?php echo esc_attr( $id ); ?>-fieldset"
|
||||
class="redux-field redux-container-<?php echo esc_attr( $this->field['type'] ) . ' ' . esc_attr( $this->field['class'] ); ?>"
|
||||
data-id="<?php echo esc_attr( $this->field['id'] ); ?>">
|
||||
|
||||
<h3><?php esc_html_e( 'Options Object', 'redux-framework' ); ?></h3>
|
||||
<div id="redux-object-browser"></div>
|
||||
<div id="redux-object-json" class="hide"><?php echo( $json ); // phpcs:ignore WordPress.Security.EscapeOutput ?></div>
|
||||
<a
|
||||
href="#" id="consolePrintObject"
|
||||
class="button">
|
||||
<?php esc_html_e( 'Show Object in Javascript Console Object', 'redux-framework' ); ?></a>
|
||||
|
||||
</fieldset>
|
||||
<?php if ( true === $do_close ) { ?>
|
||||
</td></tr></table>
|
||||
<table class="form-table no-border" style="margin-top: 0;">
|
||||
<tbody>
|
||||
<tr style="border-bottom: 0;">
|
||||
<th></th>
|
||||
<td>
|
||||
<?php } ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Function.
|
||||
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue() {
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
wp_enqueue_script(
|
||||
'redux-extension-options-object-js',
|
||||
$this->url . 'redux-options-object' . Redux_Functions::is_min() . '.js',
|
||||
array( 'jquery', 'redux-js' ),
|
||||
Redux_Extension_Options_Object::$version,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
wp_enqueue_style(
|
||||
'redux-options-object',
|
||||
$this->url . 'redux-options-object.css',
|
||||
array(),
|
||||
Redux_Extension_Options_Object::$version,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,5 @@
|
||||
#redux-object-browser { overflow: auto; word-wrap: break-word; max-height: 600px; max-width: 100%; }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtb3B0aW9ucy1vYmplY3QuY3NzIiwic291cmNlcyI6WyJyZWR1eC1vcHRpb25zLW9iamVjdC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLEFBQUEscUJBQXFCLENBQUMsRUFDbEIsUUFBUSxFQUFFLElBQUksRUFDZCxTQUFTLEVBQUUsVUFBVSxFQUNyQixVQUFVLEVBQUUsS0FBSyxFQUNqQixTQUFTLEVBQUUsSUFBSSxHQUNsQiJ9 */
|
||||
|
||||
/*# sourceMappingURL=redux-options-object.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["redux-options-object.scss","redux-options-object.css"],"names":[],"mappings":"AAAA,wBCCI,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EAAA;;AAFnB,yWAAyW","file":"redux-options-object.css","sourcesContent":["#redux-object-browser {\n overflow: auto;\n word-wrap: break-word;\n max-height: 600px;\n max-width: 100%;\n}\n\n","#redux-object-browser { overflow: auto; word-wrap: break-word; max-height: 600px; max-width: 100%; }\n\n/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtb3B0aW9ucy1vYmplY3QuY3NzIiwic291cmNlcyI6WyJyZWR1eC1vcHRpb25zLW9iamVjdC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLEFBQUEscUJBQXFCLENBQUMsRUFDbEIsUUFBUSxFQUFFLElBQUksRUFDZCxTQUFTLEVBQUUsVUFBVSxFQUNyQixVQUFVLEVBQUUsS0FBSyxFQUNqQixTQUFTLEVBQUUsSUFBSSxHQUNsQiJ9 */\n\n/*# sourceMappingURL=redux-options-object.css.map */\n"]}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*global redux, jsonView */
|
||||
|
||||
(function( $ ) {
|
||||
redux.field_objects = redux.field_objects || {};
|
||||
redux.field_objects.options_object = redux.field_objects.options_object || {};
|
||||
|
||||
redux.field_objects.options_object.init = function( selector ) {
|
||||
var parent;
|
||||
|
||||
selector = $.redux.getSelector( selector, 'options_object' );
|
||||
|
||||
parent = selector;
|
||||
|
||||
if ( ! selector.hasClass( 'redux-field-container' ) ) {
|
||||
parent = selector.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$( '#consolePrintObject' ).on(
|
||||
'click',
|
||||
function( e ) {
|
||||
e.preventDefault();
|
||||
console.log( $.parseJSON( $( '#redux-object-json' ).html() ) );
|
||||
}
|
||||
);
|
||||
|
||||
if ( 'function' === typeof jsonView ) {
|
||||
jsonView( '#redux-object-json', '#redux-object-browser' );
|
||||
}
|
||||
};
|
||||
})( jQuery );
|
||||
@@ -0,0 +1 @@
|
||||
!function(t){redux.field_objects=redux.field_objects||{},redux.field_objects.options_object=redux.field_objects.options_object||{},redux.field_objects.options_object.init=function(e){var o;(o=e=t.redux.getSelector(e,"options_object")).hasClass("redux-field-container")||(o=e.parents(".redux-field-container:first")),o.hasClass("redux-field-init")&&(o.removeClass("redux-field-init"),t("#consolePrintObject").on("click",function(e){e.preventDefault(),console.log(t.parseJSON(t("#redux-object-json").html()))}),"function"==typeof jsonView&&jsonView("#redux-object-json","#redux-object-browser"))}}(jQuery);
|
||||
@@ -0,0 +1,7 @@
|
||||
#redux-object-browser {
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
max-height: 600px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* ACE Editor Field.
|
||||
*
|
||||
* @package Redux Framework/Fields
|
||||
* @subpackage ACE_Editor
|
||||
* @version 3.0.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Ace_Editor', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Ace_Editor
|
||||
*/
|
||||
class Redux_Ace_Editor extends Redux_Field {
|
||||
|
||||
/**
|
||||
* Field Render Function.
|
||||
* Takes the vars and outputs the HTML for the field in the settings
|
||||
*
|
||||
* @since ReduxFramework 1.0.0
|
||||
*/
|
||||
public function render() {
|
||||
if ( is_array( $this->value ) ) {
|
||||
$this->value = '';
|
||||
} else {
|
||||
$this->value = trim( $this->value );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->field['options'] ) ) {
|
||||
$this->field['args'] = $this->field['options'];
|
||||
unset( $this->field['options'] );
|
||||
}
|
||||
|
||||
if ( ! isset( $this->field['mode'] ) ) {
|
||||
$this->field['mode'] = 'javascript';
|
||||
}
|
||||
if ( ! isset( $this->field['theme'] ) ) {
|
||||
$this->field['theme'] = 'monokai';
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'minLines' => 10,
|
||||
'maxLines' => 30,
|
||||
);
|
||||
|
||||
if ( isset( $this->field['args'] ) && ! empty( $this->field['args'] ) && is_array( $this->field['args'] ) ) {
|
||||
$params = wp_parse_args( $this->field['args'], $params );
|
||||
}
|
||||
?>
|
||||
<div class="ace-wrapper">
|
||||
<input
|
||||
type="hidden"
|
||||
class="localize_data"
|
||||
value="<?php echo esc_html( wp_json_encode( $params ) ); ?>"/>
|
||||
<textarea
|
||||
name="<?php echo esc_attr( $this->field['name'] . $this->field['name_suffix'] ); ?>"
|
||||
id="<?php echo esc_attr( $this->field['id'] ); ?>-textarea"
|
||||
class="ace-editor hide <?php echo esc_attr( $this->field['class'] ); ?>"
|
||||
data-editor="<?php echo esc_attr( $this->field['id'] ); ?>-editor"
|
||||
data-mode="<?php echo esc_attr( $this->field['mode'] ); ?>"
|
||||
data-theme="<?php echo esc_attr( $this->field['theme'] ); ?>"><?php echo esc_textarea( $this->value ); ?></textarea>
|
||||
<pre
|
||||
id="<?php echo esc_attr( $this->field['id'] ); ?>-editor"
|
||||
class="ace-editor-area"><?php echo esc_html( $this->value ); ?>
|
||||
</pre>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Function.
|
||||
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue() {
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
wp_enqueue_style(
|
||||
'redux-field-ace-editor-css',
|
||||
Redux_Core::$url . 'inc/fields/ace_editor/redux-ace-editor.css',
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! wp_script_is( 'ace-editor-js' ) ) {
|
||||
Redux_CDN::enqueue_script(
|
||||
'ace-editor-js',
|
||||
// phpcs:ignore Generic.Strings.UnnecessaryStringConcat
|
||||
'//' . 'cdnjs' . '.cloudflare' . '.com/ajax/libs/ace/1.4.2/ace.js',
|
||||
array( 'jquery' ),
|
||||
'1.4.2',
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'redux-field-ace-editor-js',
|
||||
Redux_Core::$url . 'inc/fields/ace_editor/redux-ace-editor' . Redux_Functions::is_min() . '.js',
|
||||
array( 'jquery', 'ace-editor-js', 'redux-js' ),
|
||||
$this->timestamp,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias( 'Redux_Ace_Editor', 'ReduxFramework_Ace_Editor' );
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Shim file for bad theme developers.
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,9 @@
|
||||
.redux-container-ace_editor .ace-wrapper { position: static; }
|
||||
|
||||
.redux-container-ace_editor .ace_editor { height: 200px; border-radius: 3px; }
|
||||
|
||||
.redux-container-ace_editor .ace_gutter { z-index: 1 !important; }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtYWNlLWVkaXRvci5jc3MiLCJzb3VyY2VzIjpbInJlZHV4LWFjZS1lZGl0b3Iuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUNJLDJCQUR1QixDQUN2QixZQUFZLENBQUMsRUFDVCxRQUFRLEVBQUUsTUFBTSxHQUNuQjs7QUFITCxBQUtJLDJCQUx1QixDQUt2QixXQUFXLENBQUMsRUFDUixNQUFNLEVBQUUsS0FBSyxFQUNiLHFCQUFxQixFQUFFLEdBQUcsRUFDMUIsa0JBQWtCLEVBQUUsR0FBRyxFQUN2QixhQUFhLEVBQUUsR0FBRyxHQUNyQjs7QUFWTCxBQVlJLDJCQVp1QixDQVl2QixXQUFXLENBQUMsRUFDUixPQUFPLEVBQUUsWUFBWSxHQUN4QiJ9 */
|
||||
|
||||
/*# sourceMappingURL=redux-ace-editor.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["redux-ace-editor.scss","redux-ace-editor.css"],"names":[],"mappings":"AAAA,2CAAA,gBAAA,EAAA;;AAAA,0CCMQ,aAAa,EAGb,kBAAkB,EAAA;;ADT1B,0CCaQ,qBAAqB,EAAA;;AAP7B,ihBAAihB","file":"redux-ace-editor.css","sourcesContent":[".redux-container-ace_editor {\n .ace-wrapper {\n position: static;\n }\n\n .ace_editor {\n height: 200px;\n -webkit-border-radius: 3px;\n -moz-border-radius: 3px;\n border-radius: 3px;\n }\n\n .ace_gutter {\n z-index: 1 !important;\n }\n}\n\n",".redux-container-ace_editor .ace-wrapper { position: static; }\n\n.redux-container-ace_editor .ace_editor { height: 200px; border-radius: 3px; }\n\n.redux-container-ace_editor .ace_gutter { z-index: 1 !important; }\n\n/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtYWNlLWVkaXRvci5jc3MiLCJzb3VyY2VzIjpbInJlZHV4LWFjZS1lZGl0b3Iuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUNJLDJCQUR1QixDQUN2QixZQUFZLENBQUMsRUFDVCxRQUFRLEVBQUUsTUFBTSxHQUNuQjs7QUFITCxBQUtJLDJCQUx1QixDQUt2QixXQUFXLENBQUMsRUFDUixNQUFNLEVBQUUsS0FBSyxFQUNiLHFCQUFxQixFQUFFLEdBQUcsRUFDMUIsa0JBQWtCLEVBQUUsR0FBRyxFQUN2QixhQUFhLEVBQUUsR0FBRyxHQUNyQjs7QUFWTCxBQVlJLDJCQVp1QixDQVl2QixXQUFXLENBQUMsRUFDUixPQUFPLEVBQUUsWUFBWSxHQUN4QiJ9 */\n\n/*# sourceMappingURL=redux-ace-editor.css.map */\n"]}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*global jQuery, redux, redux_change, ace */
|
||||
|
||||
( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
redux.field_objects = redux.field_objects || {};
|
||||
redux.field_objects.ace_editor = redux.field_objects.ace_editor || {};
|
||||
|
||||
redux.field_objects.ace_editor.init = function( selector ) {
|
||||
selector = $.redux.getSelector( selector, 'ace_editor' );
|
||||
|
||||
$( selector ).each(
|
||||
function() {
|
||||
var el = $( this );
|
||||
var parent = el;
|
||||
|
||||
if ( ! el.hasClass( 'redux-field-container' ) ) {
|
||||
parent = el.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
if ( parent.is( ':hidden' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
el.find( '.ace-editor' ).each(
|
||||
function( index, element ) {
|
||||
var area = element;
|
||||
var params = JSON.parse( $( this ).parent().find( '.localize_data' ).val() );
|
||||
var editor = $( element ).attr( 'data-editor' );
|
||||
var aceeditor = ace.edit( editor );
|
||||
var id = '';
|
||||
|
||||
index = null;
|
||||
|
||||
aceeditor.setTheme( 'ace/theme/' + jQuery( element ).attr( 'data-theme' ) );
|
||||
aceeditor.getSession().setMode( 'ace/mode/' + $( element ).attr( 'data-mode' ) );
|
||||
|
||||
if ( el.hasClass( 'redux-field-container' ) ) {
|
||||
id = el.attr( 'data-id' );
|
||||
} else {
|
||||
id = el.parents( '.redux-field-container:first' ).attr( 'data-id' );
|
||||
}
|
||||
|
||||
aceeditor.setOptions( params );
|
||||
aceeditor.on(
|
||||
'change',
|
||||
function() {
|
||||
$( '#' + area.id ).val( aceeditor.getSession().getValue() );
|
||||
redux_change( $( element ) );
|
||||
aceeditor.resize();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
})( jQuery );
|
||||
1
wp-content/plugins/redux-framework/redux-core/inc/fields/ace_editor/redux-ace-editor.min.js
vendored
Normal file
1
wp-content/plugins/redux-framework/redux-core/inc/fields/ace_editor/redux-ace-editor.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(n){"use strict";redux.field_objects=redux.field_objects||{},redux.field_objects.ace_editor=redux.field_objects.ace_editor||{},redux.field_objects.ace_editor.init=function(e){e=n.redux.getSelector(e,"ace_editor"),n(e).each(function(){var s=n(this),e=s;s.hasClass("redux-field-container")||(e=s.parents(".redux-field-container:first")),e.is(":hidden")||e.hasClass("redux-field-init")&&(e.removeClass("redux-field-init"),s.find(".ace-editor").each(function(e,t){var a=t,i=JSON.parse(n(this).parent().find(".localize_data").val()),d=n(t).attr("data-editor"),r=ace.edit(d);r.setTheme("ace/theme/"+jQuery(t).attr("data-theme")),r.getSession().setMode("ace/mode/"+n(t).attr("data-mode")),s.hasClass("redux-field-container")?s.attr("data-id"):s.parents(".redux-field-container:first").attr("data-id"),r.setOptions(i),r.on("change",function(){n("#"+a.id).val(r.getSession().getValue()),redux_change(n(t)),r.resize()})}))})}}(jQuery);
|
||||
@@ -0,0 +1,17 @@
|
||||
.redux-container-ace_editor {
|
||||
.ace-wrapper {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.ace_editor {
|
||||
height: 200px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.ace_gutter {
|
||||
z-index: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,449 @@
|
||||
<?php
|
||||
/**
|
||||
* Background Field.
|
||||
*
|
||||
* @package ReduxFramework/Fields
|
||||
* @author Dovy Paukstys & Kevin Provance (kprovance)
|
||||
* @version 4.0.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Background', false ) ) {
|
||||
|
||||
/**
|
||||
* Main Redux_background class
|
||||
*
|
||||
* @since 3.1.5
|
||||
*/
|
||||
class Redux_Background extends Redux_Field {
|
||||
|
||||
/**
|
||||
* Set field and value defaults.
|
||||
*/
|
||||
public function set_defaults() {
|
||||
$defaults = array(
|
||||
'background-color' => true,
|
||||
'background-repeat' => true,
|
||||
'background-attachment' => true,
|
||||
'background-position' => true,
|
||||
'background-image' => true,
|
||||
'background-gradient' => false,
|
||||
'background-clip' => false,
|
||||
'background-origin' => false,
|
||||
'background-size' => true,
|
||||
'preview_media' => false,
|
||||
'preview' => true,
|
||||
'preview_height' => '200px',
|
||||
'transparent' => true,
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $defaults );
|
||||
|
||||
// No errors please.
|
||||
$defaults = array(
|
||||
'background-color' => '',
|
||||
'background-repeat' => '',
|
||||
'background-attachment' => '',
|
||||
'background-position' => '',
|
||||
'background-image' => '',
|
||||
'background-clip' => '',
|
||||
'background-origin' => '',
|
||||
'background-size' => '',
|
||||
'media' => array(),
|
||||
);
|
||||
|
||||
$this->value = wp_parse_args( $this->value, $defaults );
|
||||
|
||||
$defaults = array(
|
||||
'id' => '',
|
||||
'width' => '',
|
||||
'height' => '',
|
||||
'thumbnail' => '',
|
||||
);
|
||||
|
||||
$this->value['media'] = wp_parse_args( $this->value['media'], $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Field Render Function.
|
||||
* Takes the vars and outputs the HTML for the field in the settings
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function render() {
|
||||
$this->select2_config['allowClear'] = true;
|
||||
|
||||
if ( isset( $this->field['select2'] ) ) {
|
||||
$this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config );
|
||||
} else {
|
||||
$this->field['select2'] = $this->select2_config;
|
||||
}
|
||||
|
||||
$this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] );
|
||||
|
||||
$select2_data = Redux_Functions::create_data_string( $this->field['select2'] );
|
||||
|
||||
if ( true === $this->field['background-color'] ) {
|
||||
if ( isset( $this->value['color'] ) && empty( $this->value['background-color'] ) ) {
|
||||
$this->value['background-color'] = $this->value['color'];
|
||||
}
|
||||
|
||||
$def_bg_color = isset( $this->field['default']['background-color'] ) ? $this->field['default']['background-color'] : '';
|
||||
|
||||
echo '<input ';
|
||||
echo 'data-id="' . esc_attr( $this->field['id'] ) . '"';
|
||||
echo 'name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-color]"';
|
||||
echo 'id="' . esc_attr( $this->field['id'] ) . '-color"';
|
||||
echo 'class="color-picker redux-color redux-background-input redux-color-init ' . esc_attr( $this->field['class'] ) . '"';
|
||||
echo 'type="text" value="' . esc_attr( $this->value['background-color'] ) . '"';
|
||||
echo 'data-default-color="' . esc_attr( $def_bg_color ) . '"';
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$data = array(
|
||||
'field' => $this->field,
|
||||
'index' => 'color',
|
||||
);
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo esc_html( apply_filters( 'redux/pro/render/color_alpha', $data ) );
|
||||
}
|
||||
|
||||
echo '/>';
|
||||
|
||||
echo '<input type="hidden" class="redux-saved-color" id="' . esc_attr( $this->field['id'] ) . '-saved-color" value="">';
|
||||
|
||||
if ( ! isset( $this->field['transparent'] ) || false !== $this->field['transparent'] ) {
|
||||
$is_checked = '';
|
||||
if ( 'transparent' === $this->value['background-color'] ) {
|
||||
$is_checked = ' checked="checked"';
|
||||
}
|
||||
echo '<label for="' . esc_attr( $this->field['id'] ) . '-transparency" class="color-transparency-check"><input type="checkbox" class="checkbox color-transparency redux-background-input ' . esc_attr( $this->field['class'] ) . '" id="' . esc_attr( $this->field['id'] ) . '-transparency" data-id="' . esc_attr( $this->field['id'] ) . '-color" value="1" ' . esc_html( $is_checked ) . '> ' . esc_html__( 'Transparent', 'redux-framework' ) . '</label>';
|
||||
}
|
||||
|
||||
if ( true === $this->field['background-repeat'] || true === $this->field['background-position'] || true === $this->field['background-attachment'] ) {
|
||||
echo '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->field['background-image'] ) {
|
||||
if ( true === $this->field['background-repeat'] ) {
|
||||
$array = array(
|
||||
'no-repeat' => esc_html__( 'No Repeat', 'redux-framework' ),
|
||||
'repeat' => esc_html__( 'Repeat All', 'redux-framework' ),
|
||||
'repeat-x' => esc_html__( 'Repeat Horizontally', 'redux-framework' ),
|
||||
'repeat-y' => esc_html__( 'Repeat Vertically', 'redux-framework' ),
|
||||
'inherit' => esc_html__( 'Inherit', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select id="' . esc_attr( $this->field['id'] ) . '-repeat-select" data-placeholder="' . esc_html__( 'Background Repeat', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-repeat]" class="redux-select-item redux-background-input redux-background-repeat ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
echo '<option></option>';
|
||||
|
||||
foreach ( $array as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-repeat'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
if ( true === $this->field['background-clip'] ) {
|
||||
$array = array(
|
||||
'inherit' => esc_html__( 'Inherit', 'redux-framework' ),
|
||||
'border-box' => esc_html__( 'Border Box', 'redux-framework' ),
|
||||
'content-box' => esc_html__( 'Content Box', 'redux-framework' ),
|
||||
'padding-box' => esc_html__( 'Padding Box', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select id="' . esc_attr( $this->field['id'] ) . '-clip-select" data-placeholder="' . esc_html__( 'Background Clip', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-clip]" class="redux-select-item redux-background-input redux-background-clip ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
echo '<option></option>';
|
||||
|
||||
foreach ( $array as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-clip'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
if ( true === $this->field['background-origin'] ) {
|
||||
$array = array(
|
||||
'inherit' => esc_html__( 'Inherit', 'redux-framework' ),
|
||||
'border-box' => esc_html__( 'Border Box', 'redux-framework' ),
|
||||
'content-box' => esc_html__( 'Content Box', 'redux-framework' ),
|
||||
'padding-box' => esc_html__( 'Padding Box', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select id="' . esc_attr( $this->field['id'] ) . '-origin-select" data-placeholder="' . esc_html__( 'Background Origin', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-origin]" class="redux-select-item redux-background-input redux-background-origin ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
echo '<option></option>';
|
||||
|
||||
foreach ( $array as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-origin'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
if ( true === $this->field['background-size'] ) {
|
||||
$array = array(
|
||||
'inherit' => esc_html__( 'Inherit', 'redux-framework' ),
|
||||
'cover' => esc_html__( 'Cover', 'redux-framework' ),
|
||||
'contain' => esc_html__( 'Contain', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select id="' . esc_attr( $this->field['id'] ) . '-size-select" data-placeholder="' . esc_html__( 'Background Size', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-size]" class="redux-select-item redux-background-input redux-background-size ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
echo '<option></option>';
|
||||
|
||||
foreach ( $array as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-size'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
if ( true === $this->field['background-attachment'] ) {
|
||||
$array = array(
|
||||
'fixed' => esc_html__( 'Fixed', 'redux-framework' ),
|
||||
'scroll' => esc_html__( 'Scroll', 'redux-framework' ),
|
||||
'inherit' => esc_html__( 'Inherit', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select id="' . esc_attr( $this->field['id'] ) . '-attachment-select" data-placeholder="' . esc_html__( 'Background Attachment', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-attachment]" class="redux-select-item redux-background-input redux-background-attachment ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
echo '<option></option>';
|
||||
|
||||
foreach ( $array as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-attachment'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
if ( true === $this->field['background-position'] ) {
|
||||
$array = array(
|
||||
'left top' => esc_html__( 'Left Top', 'redux-framework' ),
|
||||
'left center' => esc_html__( 'Left center', 'redux-framework' ),
|
||||
'left bottom' => esc_html__( 'Left Bottom', 'redux-framework' ),
|
||||
'center top' => esc_html__( 'Center Top', 'redux-framework' ),
|
||||
'center center' => esc_html__( 'Center Center', 'redux-framework' ),
|
||||
'center bottom' => esc_html__( 'Center Bottom', 'redux-framework' ),
|
||||
'right top' => esc_html__( 'Right Top', 'redux-framework' ),
|
||||
'right center' => esc_html__( 'Right center', 'redux-framework' ),
|
||||
'right bottom' => esc_html__( 'Right Bottom', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select id="' . esc_attr( $this->field['id'] ) . '-position-select" data-placeholder="' . esc_html__( 'Background Position', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-position]" class="redux-select-item redux-background-input redux-background-position ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
echo '<option></option>';
|
||||
|
||||
foreach ( $array as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-position'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->field['background-image'] ) {
|
||||
echo '<br />';
|
||||
|
||||
if ( empty( $this->value ) && ! empty( $this->field['default'] ) ) {
|
||||
if ( is_array( $this->field['default'] ) ) {
|
||||
if ( ! empty( $this->field['default']['media']['id'] ) ) {
|
||||
$this->value['media']['id'] = $this->field['default']['media']['id'];
|
||||
} elseif ( ! empty( $this->field['default']['id'] ) ) {
|
||||
$this->value['media']['id'] = $this->field['default']['id'];
|
||||
}
|
||||
|
||||
if ( ! empty( $this->field['default']['url'] ) ) {
|
||||
$this->value['background-image'] = $this->field['default']['url'];
|
||||
} elseif ( ! empty( $this->field['default']['media']['url'] ) ) {
|
||||
$this->value['background-image'] = $this->field['default']['media']['url'];
|
||||
} elseif ( ! empty( $this->field['default']['background-image'] ) ) {
|
||||
$this->value['background-image'] = $this->field['default']['background-image'];
|
||||
}
|
||||
} else {
|
||||
if ( is_numeric( $this->field['default'] ) ) { // Check if it's an attachment ID.
|
||||
$this->value['media']['id'] = $this->field['default'];
|
||||
} else { // Must be a URL.
|
||||
$this->value['background-image'] = $this->field['default'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $this->value['background-image'] ) && ! empty( $this->value['media']['id'] ) ) {
|
||||
$img = wp_get_attachment_image_src( $this->value['media']['id'], 'full' );
|
||||
$this->value['background-image'] = $img[0];
|
||||
$this->value['media']['width'] = $img[1];
|
||||
$this->value['media']['height'] = $img[2];
|
||||
}
|
||||
|
||||
$hide = 'hide ';
|
||||
|
||||
if ( ( isset( $this->field['preview_media'] ) && false === $this->field['preview_media'] ) ) {
|
||||
$this->field['class'] .= ' noPreview';
|
||||
}
|
||||
|
||||
if ( ( ! empty( $this->field['background-image'] ) && true === $this->field['background-image'] ) || isset( $this->field['preview'] ) && false === $this->field['preview'] ) {
|
||||
$hide = '';
|
||||
}
|
||||
|
||||
$placeholder = isset( $this->field['placeholder'] ) ? $this->field['placeholder'] : esc_html__( 'No media selected', 'redux-framework' );
|
||||
|
||||
echo '<input placeholder="' . esc_html( $placeholder ) . '" type="text" class="redux-background-input ' . esc_attr( $hide ) . 'upload ' . esc_attr( $this->field['class'] ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-image]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][background-image]" value="' . esc_url( $this->value['background-image'] ) . '" />';
|
||||
echo '<input type="hidden" class="upload-id ' . esc_attr( $this->field['class'] ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][id]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][id]" value="' . esc_attr( $this->value['media']['id'] ) . '" />';
|
||||
echo '<input type="hidden" class="upload-height" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][height]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][height]" value="' . esc_attr( $this->value['media']['height'] ) . '" />';
|
||||
echo '<input type="hidden" class="upload-width" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][width]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][width]" value="' . esc_attr( $this->value['media']['width'] ) . '" />';
|
||||
echo '<input type="hidden" class="upload-thumbnail" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][thumbnail]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][thumbnail]" value="' . esc_url( $this->value['media']['thumbnail'] ) . '" />';
|
||||
|
||||
// Preview.
|
||||
$hide = '';
|
||||
|
||||
if ( ( isset( $this->field['preview_media'] ) && false === $this->field['preview_media'] ) || empty( $this->value['background-image'] ) ) {
|
||||
$hide = 'hide ';
|
||||
}
|
||||
|
||||
if ( empty( $this->value['media']['thumbnail'] ) && ! empty( $this->value['background-image'] ) ) { // Just in case.
|
||||
if ( ! empty( $this->value['media']['id'] ) ) {
|
||||
$image = wp_get_attachment_image_src(
|
||||
$this->value['media']['id'],
|
||||
array(
|
||||
150,
|
||||
150,
|
||||
)
|
||||
);
|
||||
|
||||
$this->value['media']['thumbnail'] = $image[0];
|
||||
} else {
|
||||
$this->value['media']['thumbnail'] = $this->value['background-image'];
|
||||
}
|
||||
}
|
||||
|
||||
echo '<div class="' . esc_attr( $hide ) . 'screenshot">';
|
||||
echo '<a class="of-uploaded-image" href="' . esc_url( $this->value['background-image'] ) . '" target="_blank">';
|
||||
|
||||
$alt = wp_prepare_attachment_for_js( $this->value['media']['id'] );
|
||||
$alt = isset( $alt['alt'] ) ? $alt['alt'] : '';
|
||||
|
||||
echo '<img class="redux-option-image" id="image_' . esc_attr( $this->value['media']['id'] ) . '" src="' . esc_url( $this->value['media']['thumbnail'] ) . '" alt="' . esc_attr( $alt ) . '" target="_blank" rel="external" />';
|
||||
echo '</a>';
|
||||
echo '</div>';
|
||||
|
||||
// Upload controls DIV.
|
||||
echo '<div class="upload_button_div">';
|
||||
|
||||
// If the user has WP3.5+ show upload/remove button.
|
||||
echo '<span class="button redux-background-upload" id="' . esc_attr( $this->field['id'] ) . '-media">' . esc_html__( 'Upload', 'redux-framework' ) . '</span>';
|
||||
|
||||
$hide = '';
|
||||
if ( empty( $this->value['background-image'] ) || '' === $this->value['background-image'] ) {
|
||||
$hide = ' hide';
|
||||
}
|
||||
|
||||
echo '<span class="button removeCSS redux-remove-background' . esc_attr( $hide ) . '" id="reset_' . esc_attr( $this->field['id'] ) . '" rel="' . esc_attr( $this->field['id'] ) . '">' . esc_html__( 'Remove', 'redux-framework' ) . '</span>';
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview
|
||||
* */
|
||||
if ( ! isset( $this->field['preview'] ) || false !== $this->field['preview'] ) {
|
||||
$css = $this->css_style( $this->value );
|
||||
|
||||
$is_bg = strpos( $css, 'background-image' );
|
||||
|
||||
if ( empty( $css ) || ! $is_bg ) {
|
||||
$css = 'display:none;';
|
||||
}
|
||||
|
||||
$css .= 'height: ' . esc_attr( $this->field['preview_height'] ) . ';';
|
||||
echo '<p class="clear ' . esc_attr( $this->field['id'] ) . '_previewer background-preview" style="' . esc_attr( $css ) . '"> </p>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Function.
|
||||
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue() {
|
||||
if ( function_exists( 'wp_enqueue_media' ) ) {
|
||||
wp_enqueue_media();
|
||||
} else {
|
||||
if ( ! wp_script_is( 'media-upload' ) ) {
|
||||
wp_enqueue_script( 'media-upload' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! wp_style_is( 'select2-css' ) ) {
|
||||
wp_enqueue_style( 'select2-css' );
|
||||
}
|
||||
|
||||
if ( ! wp_style_is( 'wp-color-picker' ) ) {
|
||||
wp_enqueue_style( 'wp-color-picker' );
|
||||
}
|
||||
|
||||
$dep_array = array( 'jquery', 'wp-color-picker', 'select2-js', 'redux-js' );
|
||||
|
||||
wp_enqueue_script(
|
||||
'redux-field-background-js',
|
||||
Redux_Core::$url . 'inc/fields/background/redux-background' . Redux_Functions::is_min() . '.js',
|
||||
$dep_array,
|
||||
$this->timestamp,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
wp_enqueue_style(
|
||||
'redux-field-background-css',
|
||||
Redux_Core::$url . 'inc/fields/background/redux-background.css',
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
|
||||
wp_enqueue_style( 'redux-color-picker-css' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output CSS styling.
|
||||
*
|
||||
* @param array $value Value array.
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function css_style( $value = array() ) {
|
||||
$css = '';
|
||||
|
||||
if ( ! empty( $value ) && is_array( $value ) ) {
|
||||
foreach ( $value as $key => $val ) {
|
||||
if ( ! empty( $val ) && 'media' !== $key ) {
|
||||
if ( 'background-image' === $key ) {
|
||||
$css .= $key . ":url('" . esc_url( $val ) . "');";
|
||||
} else {
|
||||
$css .= $key . ':' . esc_attr( $val ) . ';';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable output_variables to be generated.
|
||||
*
|
||||
* @since 4.0.3
|
||||
* @return void
|
||||
*/
|
||||
public function output_variables() {
|
||||
// No code needed, just defining the method is enough.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias( 'Redux_Background', 'ReduxFramework_Background' );
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Shim file for bad theme developers.
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,17 @@
|
||||
.redux-main .redux-container-background .redux-background-position, .redux-main .redux-container-background .redux-background-position select, .redux-main .redux-container-background .redux-background-attachment, .redux-main .redux-container-background .redux-background-attachment select, .redux-main .redux-container-background .redux-background-clip, .redux-main .redux-container-background .redux-background-clip select, .redux-main .redux-container-background .redux-background-origin, .redux-main .redux-container-background .redux-background-origin select, .redux-main .redux-container-background .redux-background-size, .redux-main .redux-container-background .redux-background-size select, .redux-main .redux-container-background .redux-background-repeat, .redux-main .redux-container-background .redux-background-repeat select { width: 200px !important; margin-right: 10px; margin-bottom: 7px; }
|
||||
|
||||
.redux-main .redux-container-background .background-preview { display: block; width: 100%; margin: 5px 0 10px; border: 1px dotted #d3d3d3; }
|
||||
|
||||
.redux-main .redux-container-background .select2-container { margin-right: 10px; margin-bottom: 10px; }
|
||||
|
||||
.redux-main .redux-container-background .wp-picker-container { margin-bottom: 10px; }
|
||||
|
||||
.redux-main .redux-container-background .upload { width: 100%; margin-bottom: 8px; }
|
||||
|
||||
.redux-main .redux-container-select li.ui-state-highlight { height: 20px; margin-top: 2px; margin-left: 5px; width: 64px; margin-bottom: 0; }
|
||||
|
||||
.wp-customizer .redux-container-background .redux-background-position, .wp-customizer .redux-container-background .redux-background-position select, .wp-customizer .redux-container-background .redux-background-attachment, .wp-customizer .redux-container-background .redux-background-attachment select, .wp-customizer .redux-container-background .redux-background-clip, .wp-customizer .redux-container-background .redux-background-clip select, .wp-customizer .redux-container-background .redux-background-origin, .wp-customizer .redux-container-background .redux-background-origin select, .wp-customizer .redux-container-background .redux-background-size, .wp-customizer .redux-container-background .redux-background-size select, .wp-customizer .redux-container-background .redux-background-repeat, .wp-customizer .redux-container-background .redux-background-repeat select { width: 100% !important; }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtYmFja2dyb3VuZC5jc3MiLCJzb3VyY2VzIjpbInJlZHV4LWJhY2tncm91bmQuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUVRLFdBRkcsQ0FDUCwyQkFBMkIsQ0FDdkIsMEJBQTBCLEVBRmxDLFdBQVcsQ0FDUCwyQkFBMkIsQ0FFdkIsMEJBQTBCLENBQUMsTUFBTSxFQUh6QyxXQUFXLENBQ1AsMkJBQTJCLENBR3ZCLDRCQUE0QixFQUpwQyxXQUFXLENBQ1AsMkJBQTJCLENBSXZCLDRCQUE0QixDQUFDLE1BQU0sRUFMM0MsV0FBVyxDQUNQLDJCQUEyQixDQUt2QixzQkFBc0IsRUFOOUIsV0FBVyxDQUNQLDJCQUEyQixDQU12QixzQkFBc0IsQ0FBQyxNQUFNLEVBUHJDLFdBQVcsQ0FDUCwyQkFBMkIsQ0FPdkIsd0JBQXdCLEVBUmhDLFdBQVcsQ0FDUCwyQkFBMkIsQ0FRdkIsd0JBQXdCLENBQUMsTUFBTSxFQVR2QyxXQUFXLENBQ1AsMkJBQTJCLENBU3ZCLHNCQUFzQixFQVY5QixXQUFXLENBQ1AsMkJBQTJCLENBVXZCLHNCQUFzQixDQUFDLE1BQU0sRUFYckMsV0FBVyxDQUNQLDJCQUEyQixDQVd2Qix3QkFBd0IsRUFaaEMsV0FBVyxDQUNQLDJCQUEyQixDQVl2Qix3QkFBd0IsQ0FBQyxNQUFNLENBQUMsRUFDNUIsS0FBSyxFQUFFLGdCQUFnQixFQUN2QixZQUFZLEVBQUUsSUFBSSxFQUNsQixhQUFhLEVBQUUsR0FBRyxHQUNyQjs7QUFqQlQsQUFtQlEsV0FuQkcsQ0FDUCwyQkFBMkIsQ0FrQnZCLG1CQUFtQixDQUFDLEVBQ2hCLE9BQU8sRUFBRSxLQUFLLEVBQ2QsS0FBSyxFQUFFLElBQUksRUFDWCxNQUFNLEVBQUUsVUFBVSxFQUNsQixNQUFNLEVBQUUsa0JBQWtCLEdBQzdCOztBQXhCVCxBQTBCUSxXQTFCRyxDQUNQLDJCQUEyQixDQXlCdkIsa0JBQWtCLENBQUMsRUFDZixZQUFZLEVBQUUsSUFBSSxFQUNsQixhQUFhLEVBQUUsSUFBSSxHQUN0Qjs7QUE3QlQsQUErQlEsV0EvQkcsQ0FDUCwyQkFBMkIsQ0E4QnZCLG9CQUFvQixDQUFDLEVBQ2pCLGFBQWEsRUFBRSxJQUFJLEdBQ3RCOztBQWpDVCxBQW1DUSxXQW5DRyxDQUNQLDJCQUEyQixDQWtDdkIsT0FBTyxDQUFDLEVBQ0osS0FBSyxFQUFFLElBQUksRUFDWCxhQUFhLEVBQUUsR0FBRyxHQUNyQjs7QUF0Q1QsQUEwQ1EsV0ExQ0csQ0F5Q1AsdUJBQXVCLENBQ25CLEVBQUUsQUFBQSxtQkFBbUIsQ0FBQyxFQUNsQixNQUFNLEVBQUUsSUFBSSxFQUNaLFVBQVUsRUFBRSxHQUFHLEVBQ2YsV0FBVyxFQUFFLEdBQUcsRUFDaEIsS0FBSyxFQUFFLElBQUksRUFDWCxhQUFhLEVBQUUsQ0FBQyxHQUNuQjs7QUFJVCxBQUVRLGNBRk0sQ0FDViwyQkFBMkIsQ0FDdkIsMEJBQTBCLEVBRmxDLGNBQWMsQ0FDViwyQkFBMkIsQ0FFdkIsMEJBQTBCLENBQUMsTUFBTSxFQUh6QyxjQUFjLENBQ1YsMkJBQTJCLENBR3ZCLDRCQUE0QixFQUpwQyxjQUFjLENBQ1YsMkJBQTJCLENBSXZCLDRCQUE0QixDQUFDLE1BQU0sRUFMM0MsY0FBYyxDQUNWLDJCQUEyQixDQUt2QixzQkFBc0IsRUFOOUIsY0FBYyxDQUNWLDJCQUEyQixDQU12QixzQkFBc0IsQ0FBQyxNQUFNLEVBUHJDLGNBQWMsQ0FDViwyQkFBMkIsQ0FPdkIsd0JBQXdCLEVBUmhDLGNBQWMsQ0FDViwyQkFBMkIsQ0FRdkIsd0JBQXdCLENBQUMsTUFBTSxFQVR2QyxjQUFjLENBQ1YsMkJBQTJCLENBU3ZCLHNCQUFzQixFQVY5QixjQUFjLENBQ1YsMkJBQTJCLENBVXZCLHNCQUFzQixDQUFDLE1BQU0sRUFYckMsY0FBYyxDQUNWLDJCQUEyQixDQVd2Qix3QkFBd0IsRUFaaEMsY0FBYyxDQUNWLDJCQUEyQixDQVl2Qix3QkFBd0IsQ0FBQyxNQUFNLENBQUMsRUFDNUIsS0FBSyxFQUFFLGVBQWUsR0FDekIifQ== */
|
||||
|
||||
/*# sourceMappingURL=redux-background.css.map */
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* Redux Background
|
||||
* Dependencies : jquery, wp media uploader
|
||||
* Feature added by : Dovy Paukstys
|
||||
* Date : 07 Jan 2014
|
||||
*/
|
||||
|
||||
/*global redux_change, wp, redux, colorValidate */
|
||||
|
||||
(function( $ ) {
|
||||
'use strict';
|
||||
|
||||
redux.field_objects = redux.field_objects || {};
|
||||
redux.field_objects.background = redux.field_objects.background || {};
|
||||
|
||||
redux.field_objects.background.init = function( selector ) {
|
||||
selector = $.redux.getSelector( selector, 'background' );
|
||||
|
||||
$( selector ).each(
|
||||
function() {
|
||||
var el = $( this );
|
||||
var parent = el;
|
||||
|
||||
if ( ! el.hasClass( 'redux-field-container' ) ) {
|
||||
parent = el.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
if ( parent.is( ':hidden' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the image button.
|
||||
el.find( '.redux-remove-background' ).unbind( 'click' ).on(
|
||||
'click',
|
||||
function( e ) {
|
||||
e.preventDefault();
|
||||
redux.field_objects.background.removeImage( $( this ).parents( '.redux-container-background:first' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
// Upload media button.
|
||||
el.find( '.redux-background-upload' ).unbind().on(
|
||||
'click',
|
||||
function( event ) {
|
||||
redux.field_objects.background.addImage( event, $( this ).parents( '.redux-container-background:first' ) );
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-background-input' ).on(
|
||||
'change',
|
||||
function() {
|
||||
redux.field_objects.background.preview( $( this ) );
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-color' ).wpColorPicker(
|
||||
{
|
||||
change: function( e, ui ) {
|
||||
$( this ).val( ui.color.toString() );
|
||||
redux_change( $( this ) );
|
||||
$( '#' + e.target.id + '-transparency' ).removeAttr( 'checked' );
|
||||
redux.field_objects.background.preview( $( this ) );
|
||||
},
|
||||
|
||||
clear: function( e ) {
|
||||
e = null;
|
||||
redux_change( $( this ).parent().find( '.redux-color-init' ) );
|
||||
redux.field_objects.background.preview( $( this ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Replace and validate field on blur.
|
||||
el.find( '.redux-color' ).on(
|
||||
'blur',
|
||||
function() {
|
||||
var value = $( this ).val();
|
||||
var id = '#' + $( this ).attr( 'id' );
|
||||
|
||||
if ( 'transparent' === value ) {
|
||||
$( this ).parent().parent().find( '.wp-color-result' ).css( 'background-color', 'transparent' );
|
||||
|
||||
el.find( id + '-transparency' ).attr( 'checked', 'checked' );
|
||||
} else {
|
||||
if ( colorValidate( this ) === value ) {
|
||||
if ( 0 !== value.indexOf( '#' ) ) {
|
||||
$( this ).val( $( this ).data( 'oldcolor' ) );
|
||||
}
|
||||
}
|
||||
|
||||
el.find( id + '-transparency' ).removeAttr( 'checked' );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-color' ).on(
|
||||
'focus',
|
||||
function() {
|
||||
$( this ).data( 'oldcolor', $( this ).val() );
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-color' ).on(
|
||||
'keyup',
|
||||
function() {
|
||||
var value = $( this ).val();
|
||||
var color = colorValidate( this );
|
||||
var id = '#' + $( this ).attr( 'id' );
|
||||
|
||||
if ( 'transparent' === value ) {
|
||||
$( this ).parent().parent().find( '.wp-color-result' ).css( 'background-color', 'transparent' );
|
||||
el.find( id + '-transparency' ).attr( 'checked', 'checked' );
|
||||
} else {
|
||||
el.find( id + '-transparency' ).removeAttr( 'checked' );
|
||||
|
||||
if ( color && color !== $( this ).val() ) {
|
||||
$( this ).val( color );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// When transparency checkbox is clicked.
|
||||
el.find( '.color-transparency' ).on(
|
||||
'click',
|
||||
function() {
|
||||
var prevColor;
|
||||
|
||||
if ( $( this ).is( ':checked' ) ) {
|
||||
el.find( '.redux-saved-color' ).val( $( '#' + $( this ).data( 'id' ) ).val() );
|
||||
el.find( '#' + $( this ).data( 'id' ) ).val( 'transparent' );
|
||||
el.find( '#' + $( this ).data( 'id' ) ).parents( '.redux-field-container' ).find( '.wp-color-result' ).css( 'background-color', 'transparent' );
|
||||
} else {
|
||||
prevColor = $( this ).parents( '.redux-field-container' ).find( '.redux-saved-color' ).val();
|
||||
if ( '' === prevColor ) {
|
||||
prevColor = $( '#' + $( this ).data( 'id' ) ).data( 'default-color' );
|
||||
}
|
||||
el.find( '#' + $( this ).data( 'id' ) ).parents( '.redux-field-container' ).find( '.wp-color-result' ).css( 'background-color', prevColor );
|
||||
el.find( '#' + $( this ).data( 'id' ) ).val( prevColor );
|
||||
}
|
||||
|
||||
redux_change( $( this ) );
|
||||
}
|
||||
);
|
||||
|
||||
el.find( ' .redux-background-repeat, .redux-background-clip, .redux-background-origin, .redux-background-size, .redux-background-attachment, .redux-background-position' ).select2();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Update the background preview.
|
||||
redux.field_objects.background.preview = function( selector ) {
|
||||
var css;
|
||||
|
||||
var hide = true;
|
||||
var parent = $( selector ).parents( '.redux-container-background:first' );
|
||||
var preview = $( parent ).find( '.background-preview' );
|
||||
|
||||
if ( ! preview ) { // No preview present.
|
||||
return;
|
||||
}
|
||||
|
||||
css = 'height:' + preview.height() + 'px;';
|
||||
|
||||
$( parent ).find( '.redux-background-input' ).each(
|
||||
function() {
|
||||
var data = $( this ).serializeArray();
|
||||
|
||||
data = data[0];
|
||||
if ( data && data.name.indexOf( '[background-' ) !== - 1 ) {
|
||||
if ( '' !== data.value ) {
|
||||
hide = false;
|
||||
|
||||
data.name = data.name.split( '[background-' );
|
||||
data.name = 'background-' + data.name[1].replace( ']', '' );
|
||||
|
||||
if ( 'background-image' === data.name ) {
|
||||
css += data.name + ':url("' + data.value + '");';
|
||||
} else {
|
||||
css += data.name + ':' + data.value + ';';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if ( ! hide ) {
|
||||
preview.attr( 'style', css ).fadeIn();
|
||||
} else {
|
||||
preview.slideUp();
|
||||
}
|
||||
};
|
||||
|
||||
// Add a file via the wp.media function.
|
||||
redux.field_objects.background.addImage = function( event, selector ) {
|
||||
var frame;
|
||||
var jQueryel = $( this );
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
frame = wp.media(
|
||||
{
|
||||
multiple: false,
|
||||
library: {
|
||||
|
||||
},
|
||||
title: jQueryel.data( 'choose' ),
|
||||
button: {
|
||||
text: jQueryel.data( 'update' )
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// When an image is selected, run a callback.
|
||||
frame.on(
|
||||
'select',
|
||||
function() {
|
||||
var thumbSrc;
|
||||
var height;
|
||||
var key;
|
||||
var object;
|
||||
|
||||
// Grab the selected attachment.
|
||||
var attachment = frame.state().get( 'selection' ).first();
|
||||
frame.close();
|
||||
|
||||
if ( 'image' !== attachment.attributes.type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
selector.find( '.upload' ).val( attachment.attributes.url );
|
||||
selector.find( '.upload-id' ).val( attachment.attributes.id );
|
||||
selector.find( '.upload-height' ).val( attachment.attributes.height );
|
||||
selector.find( '.upload-width' ).val( attachment.attributes.width );
|
||||
|
||||
redux_change( $( selector ).find( '.upload-id' ) );
|
||||
|
||||
thumbSrc = attachment.attributes.url;
|
||||
|
||||
if ( 'undefined' !== typeof attachment.attributes.sizes && 'undefined' !== typeof attachment.attributes.sizes.thumbnail ) {
|
||||
thumbSrc = attachment.attributes.sizes.thumbnail.url;
|
||||
} else if ( 'undefined' !== typeof attachment.attributes.sizes ) {
|
||||
height = attachment.attributes.height;
|
||||
|
||||
for ( key in attachment.attributes.sizes ) {
|
||||
if ( attachment.attributes.sizes.hasOwnProperty( key ) ) {
|
||||
object = attachment.attributes.sizes[key];
|
||||
if ( object.height < height ) {
|
||||
height = object.height;
|
||||
thumbSrc = object.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
thumbSrc = attachment.attributes.icon;
|
||||
}
|
||||
|
||||
selector.find( '.upload-thumbnail' ).val( thumbSrc );
|
||||
|
||||
if ( ! selector.find( '.upload' ).hasClass( 'noPreview' ) ) {
|
||||
selector.find( '.screenshot' ).empty().hide().append( '<img class="redux-option-image" src="' + thumbSrc + '">' ).slideDown( 'fast' );
|
||||
}
|
||||
|
||||
selector.find( '.redux-remove-background' ).removeClass( 'hide' );
|
||||
selector.find( '.redux-background-input-properties' ).slideDown();
|
||||
|
||||
redux.field_objects.background.preview( selector.find( '.upload' ) );
|
||||
}
|
||||
);
|
||||
|
||||
// Finally, open the modal.
|
||||
frame.open();
|
||||
};
|
||||
|
||||
// Update the background preview.
|
||||
redux.field_objects.background.removeImage = function( selector ) {
|
||||
var screenshot;
|
||||
|
||||
// This shouldn't have been run...
|
||||
if ( ! selector.find( '.redux-remove-background' ).addClass( 'hide' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
selector.find( '.redux-remove-background' ).addClass( 'hide' ); // Hide "Remove" button.
|
||||
selector.find( '.upload' ).val( '' );
|
||||
selector.find( '.upload-id' ).val( '' );
|
||||
selector.find( '.upload-height' ).val( '' );
|
||||
selector.find( '.upload-width' ).val( '' );
|
||||
|
||||
redux_change( $( selector ).find( '.upload-id' ) );
|
||||
|
||||
selector.find( '.redux-background-input-properties' ).hide();
|
||||
|
||||
screenshot = selector.find( '.screenshot' );
|
||||
|
||||
// Hide the screenshot.
|
||||
screenshot.slideUp();
|
||||
|
||||
selector.find( '.remove-file' ).unbind();
|
||||
|
||||
// We don't display the upload button if .upload-notice is present
|
||||
// This means the user doesn't have the WordPress 3.5 Media Library Support.
|
||||
if ( $( '.section-upload .upload-notice' ).length > 0 ) {
|
||||
$( '.redux-background-upload' ).remove();
|
||||
}
|
||||
};
|
||||
})( jQuery );
|
||||
1
wp-content/plugins/redux-framework/redux-core/inc/fields/background/redux-background.min.js
vendored
Normal file
1
wp-content/plugins/redux-framework/redux-core/inc/fields/background/redux-background.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,70 @@
|
||||
.redux-main {
|
||||
.redux-container-background {
|
||||
.redux-background-position,
|
||||
.redux-background-position select,
|
||||
.redux-background-attachment,
|
||||
.redux-background-attachment select,
|
||||
.redux-background-clip,
|
||||
.redux-background-clip select,
|
||||
.redux-background-origin,
|
||||
.redux-background-origin select,
|
||||
.redux-background-size,
|
||||
.redux-background-size select,
|
||||
.redux-background-repeat,
|
||||
.redux-background-repeat select {
|
||||
width: 200px !important;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.background-preview {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 5px 0 10px;
|
||||
border: 1px dotted #d3d3d3;
|
||||
}
|
||||
|
||||
.select2-container {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.wp-picker-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.upload {
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.redux-container-select {
|
||||
li.ui-state-highlight {
|
||||
height: 20px;
|
||||
margin-top: 2px;
|
||||
margin-left: 5px;
|
||||
width: 64px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wp-customizer {
|
||||
.redux-container-background {
|
||||
.redux-background-position,
|
||||
.redux-background-position select,
|
||||
.redux-background-attachment,
|
||||
.redux-background-attachment select,
|
||||
.redux-background-clip,
|
||||
.redux-background-clip select,
|
||||
.redux-background-origin,
|
||||
.redux-background-origin select,
|
||||
.redux-background-size,
|
||||
.redux-background-size select,
|
||||
.redux-background-repeat,
|
||||
.redux-background-repeat select {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
<?php
|
||||
/**
|
||||
* Border Field.
|
||||
*
|
||||
* @package ReduxFramework/Fields
|
||||
* @author Dovy Paukstys & Kevin Provance (kprovance)
|
||||
* @version 4.0.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Border', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Border
|
||||
*/
|
||||
class Redux_Border extends Redux_Field {
|
||||
|
||||
/**
|
||||
* Set field and value defaults.
|
||||
*/
|
||||
public function set_defaults() {
|
||||
// No errors please.
|
||||
$defaults = array(
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
'all' => true,
|
||||
'style' => true,
|
||||
'color' => true,
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $defaults );
|
||||
|
||||
$defaults = array(
|
||||
'top' => '',
|
||||
'right' => '',
|
||||
'bottom' => '',
|
||||
'left' => '',
|
||||
'color' => '',
|
||||
'style' => '',
|
||||
);
|
||||
|
||||
$this->value = wp_parse_args( $this->value, $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Field Render Function.
|
||||
* Takes the vars and outputs the HTML for the field in the settings
|
||||
*
|
||||
* @since ReduxFramework 1.0.0
|
||||
*/
|
||||
public function render() {
|
||||
$value = array(
|
||||
'top' => isset( $this->value['border-top'] ) ? filter_var( $this->value['border-top'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : filter_var( $this->value['top'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ),
|
||||
'right' => isset( $this->value['border-right'] ) ? filter_var( $this->value['border-right'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : filter_var( $this->value['right'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ),
|
||||
'bottom' => isset( $this->value['border-bottom'] ) ? filter_var( $this->value['border-bottom'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : filter_var( $this->value['bottom'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ),
|
||||
'left' => isset( $this->value['border-left'] ) ? filter_var( $this->value['border-left'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : filter_var( $this->value['left'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ),
|
||||
'color' => isset( $this->value['border-color'] ) ? $this->value['border-color'] : $this->value['color'],
|
||||
'style' => isset( $this->value['border-style'] ) ? $this->value['border-style'] : $this->value['style'],
|
||||
);
|
||||
|
||||
if ( ( isset( $this->value['width'] ) || isset( $this->value['border-width'] ) ) ) {
|
||||
if ( isset( $this->value['border-width'] ) && ! empty( $this->value['border-width'] ) ) {
|
||||
$this->value['width'] = $this->value['border-width'];
|
||||
}
|
||||
|
||||
$this->value['width'] = $this->strip_alphas( $this->value['width'] );
|
||||
|
||||
$value['top'] = $this->value['width'];
|
||||
$value['right'] = $this->value['width'];
|
||||
$value['bottom'] = $this->value['width'];
|
||||
$value['left'] = $this->value['width'];
|
||||
}
|
||||
|
||||
$this->value = $value;
|
||||
|
||||
$defaults = array(
|
||||
'top' => '',
|
||||
'right' => '',
|
||||
'bottom' => '',
|
||||
'left' => '',
|
||||
);
|
||||
|
||||
$this->check_for_all();
|
||||
|
||||
$this->value = wp_parse_args( $this->value, $defaults );
|
||||
|
||||
$this->select2_config['allowClear'] = false;
|
||||
|
||||
if ( isset( $this->field['select2'] ) ) {
|
||||
$this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config );
|
||||
} else {
|
||||
$this->field['select2'] = $this->select2_config;
|
||||
}
|
||||
|
||||
$this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] );
|
||||
|
||||
$select2_data = Redux_Functions::create_data_string( $this->field['select2'] );
|
||||
|
||||
echo '<input type="hidden" class="field-units" value="px">';
|
||||
|
||||
if ( isset( $this->field['all'] ) && true === $this->field['all'] ) {
|
||||
echo '<div class="field-border-input input-prepend"><span class="add-on"><i class="el el-fullscreen icon-large"></i></span><input type="text" class="redux-border-all redux-border-input mini ' . esc_attr( $this->field['class'] ) . '" placeholder="' . esc_html__( 'All', 'redux-framework' ) . '" rel="' . esc_attr( $this->field['id'] ) . '-all" value="' . esc_attr( $this->value['top'] ) . '"></div>';
|
||||
}
|
||||
|
||||
echo '<input type="hidden" class="redux-border-value" id="' . esc_attr( $this->field['id'] ) . '-top" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-top]" value="' . ( isset( $this->value['top'] ) && '' !== $this->value['top'] ? esc_attr( $this->value['top'] ) . 'px' : '' ) . '">';
|
||||
echo '<input type="hidden" class="redux-border-value" id="' . esc_attr( $this->field['id'] ) . '-right" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-right]" value="' . ( isset( $this->value['right'] ) && '' !== $this->value['right'] ? esc_attr( $this->value['right'] ) . 'px' : '' ) . '">';
|
||||
echo '<input type="hidden" class="redux-border-value" id="' . esc_attr( $this->field['id'] ) . '-bottom" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-bottom]" value="' . ( isset( $this->value['bottom'] ) && '' !== $this->value['bottom'] ? esc_attr( $this->value['bottom'] ) . 'px' : '' ) . '">';
|
||||
echo '<input type="hidden" class="redux-border-value" id="' . esc_attr( $this->field['id'] ) . '-left" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-left]" value="' . ( isset( $this->value['left'] ) && '' !== $this->value['left'] ? esc_attr( $this->value['left'] ) . 'px' : '' ) . '">';
|
||||
|
||||
if ( ! isset( $this->field['all'] ) || true !== $this->field['all'] ) {
|
||||
/**
|
||||
* Top
|
||||
* */
|
||||
if ( true === $this->field['top'] ) {
|
||||
echo '<div class="field-border-input input-prepend">
|
||||
<span class="add-on">
|
||||
<i class="el el-arrow-up icon-large"></i>
|
||||
</span>
|
||||
<input type="text" class="redux-border-top redux-border-input mini ' . esc_attr( $this->field['class'] ) . '" placeholder="' . esc_html__( 'Top', 'redux-framework' ) . '" rel="' . esc_attr( $this->field['id'] ) . '-top" value="' . esc_attr( $this->value['top'] ) . '">
|
||||
</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Right
|
||||
* */
|
||||
if ( true === $this->field['right'] ) {
|
||||
echo '<div class="field-border-input input-prepend">
|
||||
<span class="add-on">
|
||||
<i class="el el-arrow-right icon-large"></i>
|
||||
</span>
|
||||
<input type="text" class="redux-border-right redux-border-input mini ' . esc_attr( $this->field['class'] ) . '" placeholder="' . esc_html__( 'Right', 'redux-framework' ) . '" rel="' . esc_attr( $this->field['id'] ) . '-right" value="' . esc_attr( $this->value['right'] ) . '">
|
||||
</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Bottom
|
||||
* */
|
||||
if ( true === $this->field['bottom'] ) {
|
||||
echo '<div class="field-border-input input-prepend">
|
||||
<span class="add-on">
|
||||
<i class="el el-arrow-down icon-large"></i>
|
||||
</span>
|
||||
<input type="text" class="redux-border-bottom redux-border-input mini ' . esc_attr( $this->field['class'] ) . '" placeholder="' . esc_html__( 'Bottom', 'redux-framework' ) . '" rel="' . esc_attr( $this->field['id'] ) . '-bottom" value="' . esc_attr( $this->value['bottom'] ) . '">
|
||||
</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Left
|
||||
* */
|
||||
if ( true === $this->field['left'] ) {
|
||||
echo '<div class="field-border-input input-prepend">
|
||||
<span class="add-on">
|
||||
<i class="el el-arrow-left icon-large"></i>
|
||||
</span>
|
||||
<input type="text" class="redux-border-left redux-border-input mini ' . esc_attr( $this->field['class'] ) . '" placeholder="' . esc_html__( 'Left', 'redux-framework' ) . '" rel="' . esc_attr( $this->field['id'] ) . '-left" value="' . esc_attr( $this->value['left'] ) . '">
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Border-style
|
||||
* */
|
||||
if ( false !== $this->field['style'] ) {
|
||||
$options = array(
|
||||
'solid' => esc_html__( 'Solid', 'redux-framework' ),
|
||||
'dashed' => esc_html__( 'Dashed', 'redux-framework' ),
|
||||
'dotted' => esc_html__( 'Dotted', 'redux-framework' ),
|
||||
'double' => esc_html__( 'Double', 'redux-framework' ),
|
||||
'none' => esc_html__( 'None', 'redux-framework' ),
|
||||
);
|
||||
|
||||
echo '<select data-placeholder="' . esc_html__( 'Border style', 'redux-framework' ) . '" id="' . esc_attr( $this->field['id'] ) . '[border-style]" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-style]" class="tips redux-border-style ' . esc_attr( $this->field['class'] ) . '" rows="6" data-id="' . esc_attr( $this->field['id'] ) . '"' . esc_attr( $select2_data ) . '>';
|
||||
|
||||
foreach ( $options as $k => $v ) {
|
||||
echo '<option value="' . esc_attr( $k ) . '" ' . selected( $value['style'], $k, false ) . '>' . esc_html( $v ) . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
} else {
|
||||
echo '<input type="hidden" id="' . esc_attr( $this->field['id'] ) . '[border-style]" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-style]" value="' . esc_attr( $this->value['style'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Color
|
||||
* */
|
||||
if ( false !== $this->field['color'] ) {
|
||||
$default = isset( $this->field['default']['border-color'] ) ? $this->field['default']['border-color'] : '';
|
||||
|
||||
if ( empty( $default ) ) {
|
||||
$default = ( isset( $this->field['default']['color'] ) ) ? $this->field['default']['color'] : '#ffffff';
|
||||
}
|
||||
|
||||
echo '<input ';
|
||||
echo 'name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-color]"';
|
||||
echo 'id="' . esc_attr( $this->field['id'] ) . '-border"';
|
||||
echo 'class="color-picker redux-border-color redux-color redux-color-init ' . esc_attr( $this->field['class'] ) . '"';
|
||||
echo 'type="text"';
|
||||
echo 'value="' . esc_attr( $this->value['color'] ) . '"';
|
||||
echo 'data-default-color="' . esc_attr( $default ) . '"';
|
||||
echo 'data-id="' . esc_attr( $this->field['id'] ) . '"';
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
$data = array(
|
||||
'field' => $this->field,
|
||||
'index' => '',
|
||||
);
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
echo esc_html( apply_filters( 'redux/pro/render/color_alpha', $data ) );
|
||||
}
|
||||
|
||||
echo '/>';
|
||||
} else {
|
||||
echo '<input type="hidden" id="' . esc_attr( $this->field['id'] ) . '[border-color]" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[border-color]" value="' . esc_attr( $this->value['color'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '">';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Function.
|
||||
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
|
||||
*
|
||||
* @since ReduxFramework 1.0.0
|
||||
*/
|
||||
public function enqueue() {
|
||||
$min = Redux_Functions::is_min();
|
||||
|
||||
if ( ! wp_style_is( 'select2-css' ) ) {
|
||||
wp_enqueue_style( 'select2-css' );
|
||||
}
|
||||
|
||||
if ( ! wp_style_is( 'wp-color-picker' ) ) {
|
||||
wp_enqueue_style( 'wp-color-picker' );
|
||||
}
|
||||
|
||||
$dep_array = array( 'jquery', 'select2-js', 'wp-color-picker', 'redux-js' );
|
||||
|
||||
wp_enqueue_script(
|
||||
'redux-field-border-js',
|
||||
Redux_Core::$url . 'inc/fields/border/redux-border' . $min . '.js',
|
||||
$dep_array,
|
||||
$this->timestamp,
|
||||
true
|
||||
);
|
||||
|
||||
if ( Redux_Core::$pro_loaded ) {
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
do_action( 'redux/pro/enqueue/color_alpha', $this->field );
|
||||
}
|
||||
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
if ( ! wp_style_is( 'redux-color-picker-css' ) ) {
|
||||
wp_enqueue_style( 'redux-color-picker-css' );
|
||||
}
|
||||
|
||||
wp_enqueue_style(
|
||||
'redux-field-border-css',
|
||||
Redux_Core::$url . 'inc/fields/border/redux-border.css',
|
||||
array(),
|
||||
$this->timestamp,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to make sure all is properly set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function check_for_all() {
|
||||
if ( true === $this->field['all'] ) {
|
||||
if ( 1 !== $this->field['top'] || 1 !== $this->field['bottom'] || 1 !== $this->field['left'] || 1 !== $this->field['right'] ) {
|
||||
$this->field['all'] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output CSS styling.
|
||||
*
|
||||
* @param string $data Value array.
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function css_style( $data ) {
|
||||
$style = '';
|
||||
|
||||
$this->check_for_all();
|
||||
|
||||
if ( isset( $this->field['all'] ) && true === $this->field['all'] ) {
|
||||
$border_width = isset( $data['border-width'] ) ? $data['border-width'] : '0px';
|
||||
$val = isset( $data['border-top'] ) ? $data['border-top'] : $border_width;
|
||||
|
||||
$data['border-top'] = $val;
|
||||
$data['border-bottom'] = $val;
|
||||
$data['border-left'] = $val;
|
||||
$data['border-right'] = $val;
|
||||
}
|
||||
|
||||
$clean_value = array(
|
||||
'color' => ! empty( $data['border-color'] ) ? $data['border-color'] : '',
|
||||
'style' => ! empty( $data['border-style'] ) ? $data['border-style'] : '',
|
||||
);
|
||||
|
||||
$border_width = '';
|
||||
if ( isset( $data['border-width'] ) ) {
|
||||
$border_width = $data['border-width'];
|
||||
}
|
||||
|
||||
$this->field['top'] = isset( $this->field['top'] ) ? $this->field['top'] : true;
|
||||
$this->field['bottom'] = isset( $this->field['bottom'] ) ? $this->field['bottom'] : true;
|
||||
$this->field['left'] = isset( $this->field['left'] ) ? $this->field['left'] : true;
|
||||
$this->field['right'] = isset( $this->field['right'] ) ? $this->field['right'] : true;
|
||||
|
||||
if ( true === $this->field['top'] ) {
|
||||
$clean_value['top'] = ! empty( $data['border-top'] ) ? $data['border-top'] : $border_width;
|
||||
}
|
||||
|
||||
if ( true === $this->field['bottom'] ) {
|
||||
$clean_value['bottom'] = ! empty( $data['border-bottom'] ) ? $data['border-bottom'] : $border_width;
|
||||
}
|
||||
|
||||
if ( true === $this->field['left'] ) {
|
||||
$clean_value['left'] = ! empty( $data['border-left'] ) ? $data['border-left'] : $border_width;
|
||||
}
|
||||
|
||||
if ( true === $this->field['right'] ) {
|
||||
$clean_value['right'] = ! empty( $data['border-right'] ) ? $data['border-right'] : $border_width;
|
||||
}
|
||||
|
||||
// absolute, padding, margin.
|
||||
if ( ! isset( $this->field['all'] ) || true !== $this->field['all'] ) {
|
||||
foreach ( $clean_value as $key => $value ) {
|
||||
if ( 'color' === $key || 'style' === $key ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! empty( $value ) ) {
|
||||
$style .= 'border-' . $key . ':' . $value . ' ' . $clean_value['style'] . ' ' . $clean_value['color'] . ';';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( $clean_value['top'] ) ) {
|
||||
$style .= 'border:' . $clean_value['top'] . ' ' . $clean_value['style'] . ' ' . $clean_value['color'] . ';';
|
||||
}
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip alpha chars.
|
||||
*
|
||||
* @param string $s Criteria.
|
||||
*
|
||||
* @return null|string|string[]
|
||||
*/
|
||||
private function strip_alphas( $s ) {
|
||||
// Regex is our friend. THERE ARE FOUR LIGHTS!!
|
||||
return preg_replace( '/[^\d.-]/', '', $s );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable output_variables to be generated.
|
||||
*
|
||||
* @since 4.0.3
|
||||
* @return void
|
||||
*/
|
||||
public function output_variables() {
|
||||
// No code needed, just defining the method is enough.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias( 'Redux_Border', 'ReduxFramework_Border' );
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Shim file for bad theme developers.
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,15 @@
|
||||
.redux-container-border .select2-container { float: left; display: block; margin-right: 10px; }
|
||||
|
||||
.redux-container-border .select_wrapper { float: left; width: inherit; }
|
||||
|
||||
.redux-container-border .select_wrapper select { width: 80px; float: left; }
|
||||
|
||||
.redux-container-border .field-border-input { margin-right: 10px; margin-bottom: 7px; }
|
||||
|
||||
@media screen and (max-width: 782px) { .redux-container-border .field-border-input input { display: inline-block !important; width: 100px !important; }
|
||||
.redux-container-border .field-border-input .add-on { padding: 7px 4px; font-size: 16px; line-height: 1.5; }
|
||||
.redux-container-border .select_wrapper { margin-top: 6px; } }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtYm9yZGVyLmNzcyIsInNvdXJjZXMiOlsicmVkdXgtYm9yZGVyLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsQUFDSSx1QkFEbUIsQ0FDbkIsa0JBQWtCLENBQUMsRUFDZixLQUFLLEVBQUUsSUFBSSxFQUNYLE9BQU8sRUFBRSxLQUFLLEVBQ2QsWUFBWSxFQUFFLElBQUksR0FDckI7O0FBTEwsQUFPSSx1QkFQbUIsQ0FPbkIsZUFBZSxDQUFDLEVBQ1osS0FBSyxFQUFFLElBQUksRUFNWCxLQUFLLEVBQUUsT0FBTyxHQUNqQjs7QUFmTCxBQVNRLHVCQVRlLENBT25CLGVBQWUsQ0FFWCxNQUFNLENBQUMsRUFDSCxLQUFLLEVBQUUsSUFBSSxFQUNYLEtBQUssRUFBRSxJQUFJLEdBRWQ7O0FBYlQsQUFpQkksdUJBakJtQixDQWlCbkIsbUJBQW1CLENBQUMsRUFDaEIsWUFBWSxFQUFFLElBQUksRUFDbEIsYUFBYSxFQUFFLEdBQUcsR0FDckI7O0FBR0wsTUFBTSxDQUFDLE1BQU0sTUFBTSxTQUFTLEVBQUUsS0FBSyxJQUMvQixBQUVRLHVCQUZlLENBQ25CLG1CQUFtQixDQUNmLEtBQUssQ0FBQyxFQUNGLE9BQU8sRUFBRSx1QkFBdUIsRUFDaEMsS0FBSyxFQUFFLGdCQUFnQixHQUMxQjtDQUxULEFBT1EsdUJBUGUsQ0FDbkIsbUJBQW1CLENBTWYsT0FBTyxDQUFDLEVBQ0osT0FBTyxFQUFFLE9BQU8sRUFDaEIsU0FBUyxFQUFFLElBQUksRUFDZixXQUFXLEVBQUUsR0FBRyxHQUNuQjtDQVhULEFBY0ksdUJBZG1CLENBY25CLGVBQWUsQ0FBQyxFQUNaLFVBQVUsRUFBRSxHQUFHLEdBQ2xCIn0= */
|
||||
|
||||
/*# sourceMappingURL=redux-border.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["redux-border.scss","redux-border.css"],"names":[],"mappings":"AAAA,6CAAA,WAAA,ECGQ,cAAc,EDHtB,kBAOI,EAAA;;AAPJ,0CAuBO,WAAY,ECTX,cAAc,EAAA;;ADdtB,iDAwBI,WAAA,ECbQ,WAAW,EAAA;;ADXvB,8CCkBQ,kBAAkB,EAClB,kBAAkB,EAAA;;AAI1B,uCACI,oDAGY,gCAAgC,EAChC,uBAAuB,EAAA;CAJnC,sDAQY,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAAA;CAV5B,0CAeQ,eAAe,EAAA,EAClB;;AA5BT,qjCAAqjC","file":"redux-border.css","sourcesContent":[".redux-container-border {\n .select2-container {\n float: left;\n display: block;\n margin-right: 10px;\n }\n\n .select_wrapper {\n float: left;\n select {\n width: 80px;\n float: left;\n\n }\n width: inherit;\n }\n\n .field-border-input {\n margin-right: 10px;\n margin-bottom: 7px;\n }\n}\n\n@media screen and (max-width: 782px) {\n .redux-container-border {\n .field-border-input {\n input {\n display: inline-block !important;\n width: 100px !important;\n }\n\n .add-on {\n padding: 7px 4px;\n font-size: 16px;\n line-height: 1.5;\n }\n }\n\n .select_wrapper {\n margin-top: 6px;\n }\n }\n}\n",".redux-container-border .select2-container { float: left; display: block; margin-right: 10px; }\n\n.redux-container-border .select_wrapper { float: left; width: inherit; }\n\n.redux-container-border .select_wrapper select { width: 80px; float: left; }\n\n.redux-container-border .field-border-input { margin-right: 10px; margin-bottom: 7px; }\n\n@media screen and (max-width: 782px) { .redux-container-border .field-border-input input { display: inline-block !important; width: 100px !important; }\n\t.redux-container-border .field-border-input .add-on { padding: 7px 4px; font-size: 16px; line-height: 1.5; }\n\t.redux-container-border .select_wrapper { margin-top: 6px; } }\n\n/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtYm9yZGVyLmNzcyIsInNvdXJjZXMiOlsicmVkdXgtYm9yZGVyLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsQUFDSSx1QkFEbUIsQ0FDbkIsa0JBQWtCLENBQUMsRUFDZixLQUFLLEVBQUUsSUFBSSxFQUNYLE9BQU8sRUFBRSxLQUFLLEVBQ2QsWUFBWSxFQUFFLElBQUksR0FDckI7O0FBTEwsQUFPSSx1QkFQbUIsQ0FPbkIsZUFBZSxDQUFDLEVBQ1osS0FBSyxFQUFFLElBQUksRUFNWCxLQUFLLEVBQUUsT0FBTyxHQUNqQjs7QUFmTCxBQVNRLHVCQVRlLENBT25CLGVBQWUsQ0FFWCxNQUFNLENBQUMsRUFDSCxLQUFLLEVBQUUsSUFBSSxFQUNYLEtBQUssRUFBRSxJQUFJLEdBRWQ7O0FBYlQsQUFpQkksdUJBakJtQixDQWlCbkIsbUJBQW1CLENBQUMsRUFDaEIsWUFBWSxFQUFFLElBQUksRUFDbEIsYUFBYSxFQUFFLEdBQUcsR0FDckI7O0FBR0wsTUFBTSxDQUFDLE1BQU0sTUFBTSxTQUFTLEVBQUUsS0FBSyxJQUMvQixBQUVRLHVCQUZlLENBQ25CLG1CQUFtQixDQUNmLEtBQUssQ0FBQyxFQUNGLE9BQU8sRUFBRSx1QkFBdUIsRUFDaEMsS0FBSyxFQUFFLGdCQUFnQixHQUMxQjtDQUxULEFBT1EsdUJBUGUsQ0FDbkIsbUJBQW1CLENBTWYsT0FBTyxDQUFDLEVBQ0osT0FBTyxFQUFFLE9BQU8sRUFDaEIsU0FBUyxFQUFFLElBQUksRUFDZixXQUFXLEVBQUUsR0FBRyxHQUNuQjtDQVhULEFBY0ksdUJBZG1CLENBY25CLGVBQWUsQ0FBQyxFQUNaLFVBQVUsRUFBRSxHQUFHLEdBQ2xCIn0= */\n\n/*# sourceMappingURL=redux-border.css.map */\n"]}
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Field Border (border)
|
||||
*/
|
||||
|
||||
/*global redux_change, redux, colorValidate */
|
||||
|
||||
(function( $ ) {
|
||||
'use strict';
|
||||
|
||||
redux.field_objects = redux.field_objects || {};
|
||||
redux.field_objects.border = redux.field_objects.border || {};
|
||||
|
||||
redux.field_objects.border.init = function( selector ) {
|
||||
selector = $.redux.getSelector( selector, 'border' );
|
||||
|
||||
$( selector ).each(
|
||||
function() {
|
||||
var el = $( this );
|
||||
var parent = el;
|
||||
|
||||
if ( ! el.hasClass( 'redux-field-container' ) ) {
|
||||
parent = el.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
if ( parent.is( ':hidden' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
el.find( '.redux-border-top, .redux-border-right, .redux-border-bottom, .redux-border-left, .redux-border-all' ).numeric( { allowMinus: false } );
|
||||
el.find( '.redux-border-style' ).select2();
|
||||
|
||||
el.find( '.redux-border-input' ).on(
|
||||
'change',
|
||||
function() {
|
||||
var value;
|
||||
|
||||
var units = $( this ).parents( '.redux-field:first' ).find( '.field-units' ).val();
|
||||
|
||||
if ( 0 !== $( this ).parents( '.redux-field:first' ).find( '.redux-border-units' ).length ) {
|
||||
units = $( this ).parents( '.redux-field:first' ).find( '.redux-border-units option:selected' ).val();
|
||||
}
|
||||
|
||||
value = $( this ).val();
|
||||
|
||||
if ( 'undefined' !== typeof units && value ) {
|
||||
value += units;
|
||||
}
|
||||
|
||||
if ( $( this ).hasClass( 'redux-border-all' ) ) {
|
||||
$( this ).parents( '.redux-field:first' ).find( '.redux-border-value' ).each(
|
||||
function() {
|
||||
$( this ).val( value );
|
||||
}
|
||||
);
|
||||
} else {
|
||||
$( '#' + $( this ).attr( 'rel' ) ).val( value );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-border-units' ).on(
|
||||
'change',
|
||||
function() {
|
||||
$( this ).parents( '.redux-field:first' ).find( '.redux-border-input' ).change();
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-color-init' ).wpColorPicker(
|
||||
{
|
||||
change: function( e, ui ) {
|
||||
$( this ).val( ui.color.toString() );
|
||||
redux_change( $( this ) );
|
||||
el.find( '#' + e.target.getAttribute( 'data-id' ) + '-transparency' ).removeAttr( 'checked' );
|
||||
},
|
||||
clear: function( e, ui ) {
|
||||
e = null;
|
||||
$( this ).val( ui.color.toString() );
|
||||
redux_change( $( this ).parent().find( '.redux-color-init' ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
el.find( '.redux-color' ).on(
|
||||
'keyup',
|
||||
function() {
|
||||
var color = colorValidate( this );
|
||||
|
||||
if ( color && color !== $( this ).val() ) {
|
||||
$( this ).val( color );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Replace and validate field on blur.
|
||||
el.find( '.redux-color' ).on(
|
||||
'blur',
|
||||
function() {
|
||||
var value = $( this ).val();
|
||||
|
||||
if ( colorValidate( this ) === value ) {
|
||||
if ( 0 !== value.indexOf( '#' ) ) {
|
||||
$( this ).val( $( this ).data( 'oldcolor' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Store the old valid color on keydown.
|
||||
el.find( '.redux-color' ).on(
|
||||
'keydown',
|
||||
function() {
|
||||
$( this ).data( 'oldkeypress', $( this ).val() );
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
})( jQuery );
|
||||
1
wp-content/plugins/redux-framework/redux-core/inc/fields/border/redux-border.min.js
vendored
Normal file
1
wp-content/plugins/redux-framework/redux-core/inc/fields/border/redux-border.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(t){"use strict";redux.field_objects=redux.field_objects||{},redux.field_objects.border=redux.field_objects.border||{},redux.field_objects.border.init=function(e){e=t.redux.getSelector(e,"border"),t(e).each(function(){var i=t(this),e=i;i.hasClass("redux-field-container")||(e=i.parents(".redux-field-container:first")),e.is(":hidden")||e.hasClass("redux-field-init")&&(e.removeClass("redux-field-init"),i.find(".redux-border-top, .redux-border-right, .redux-border-bottom, .redux-border-left, .redux-border-all").numeric({allowMinus:!1}),i.find(".redux-border-style").select2(),i.find(".redux-border-input").on("change",function(){var e,r=t(this).parents(".redux-field:first").find(".field-units").val();0!==t(this).parents(".redux-field:first").find(".redux-border-units").length&&(r=t(this).parents(".redux-field:first").find(".redux-border-units option:selected").val()),e=t(this).val(),void 0!==r&&e&&(e+=r),t(this).hasClass("redux-border-all")?t(this).parents(".redux-field:first").find(".redux-border-value").each(function(){t(this).val(e)}):t("#"+t(this).attr("rel")).val(e)}),i.find(".redux-border-units").on("change",function(){t(this).parents(".redux-field:first").find(".redux-border-input").change()}),i.find(".redux-color-init").wpColorPicker({change:function(e,r){t(this).val(r.color.toString()),redux_change(t(this)),i.find("#"+e.target.getAttribute("data-id")+"-transparency").removeAttr("checked")},clear:function(e,r){t(this).val(r.color.toString()),redux_change(t(this).parent().find(".redux-color-init"))}}),i.find(".redux-color").on("keyup",function(){var e=colorValidate(this);e&&e!==t(this).val()&&t(this).val(e)}),i.find(".redux-color").on("blur",function(){var e=t(this).val();colorValidate(this)===e&&0!==e.indexOf("#")&&t(this).val(t(this).data("oldcolor"))}),i.find(".redux-color").on("keydown",function(){t(this).data("oldkeypress",t(this).val())}))})}}(jQuery);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user