| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- <?php
- class Vamtam_Customizer {
- private static $instance;
- private $sections;
- private $args;
- protected $class_from_type_cache = array();
- private $controls;
- public static $version = '1.0.0';
- public static function get_instance() {
- if ( ! isset( self::$instance ) ) {
- self::$instance = new self();
- }
- return self::$instance;
- }
- public function __construct( $args = array() ) {
- // Autoload classes on demand
- if ( function_exists( '__autoload' ) )
- spl_autoload_register( '__autoload' );
- spl_autoload_register( array( $this, 'autoload' ) );
- $this->args = $args;
- $this->sections = array();
- $this->dir = plugin_dir_path( __FILE__ );
- $this->class_from_type_cache = array();
- add_action( 'customize_register', array( $this, 'customize_register' ), 5 );
- add_action( 'customize_save_after', array( $this, 'customize_save_after' ) );
- add_action( 'after_setup_theme', array( $this, 'setup_options' ), 5 );
- add_action( 'wp_ajax_vamtam-customizer-control', array( $this, 'control_ajax' ) );
- add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ), 7 );
- }
- public function customize_controls_enqueue_scripts() {
- }
- public function customize_save_after( $wp_customize ) {
- global $vamtam_fonts;
- $fonts_by_family = vamtam_get_fonts_by_family();
- $google_fonts = array();
- $customized = json_decode( stripslashes_deep( $_POST['customized'] ), true );
- $fields = $this->get_fields_by_id();
- $options = $this->get_options();
- $compiler = false;
- foreach ( $fields as $id => $field ) {
- $full_id = $this->args['opt_name'] . '[' . $id . ']';
- // cache google fonts, so we can just load them later
- if ( 'typography' === $field['type'] ) {
- $font_id = $fonts_by_family[ $options[ $id ]['font-family'] ];
- $font = $vamtam_fonts[ $font_id ];
- if ( isset( $font['gf'] ) && $font['gf'] ) {
- $google_fonts[ $font_id ][] = isset( $options[ $id ]['variant'] ) ? $options[ $id ]['variant'] : 'normal';
- }
- }
- // if a compiler option was changed
- if ( isset( $customized[ $full_id ] ) && ( isset( $field['compiler'] ) && $field['compiler'] ) ) {
- $compiler = true;
- }
- }
- $options['google_fonts'] = self::build_google_fonts_url( $google_fonts, $options['gfont-subsets'] );
- $this->set_options( $options );
- if ( $compiler ) {
- do_action( "vamtam_customizer/{$this->args['opt_name']}/compiler", $options );
- }
- do_action( 'vamtam_saved_options' );
- }
- public static function build_google_fonts_url( $google_fonts, $subsets ) {
- $font_imports_url = '';
- if ( is_array( $google_fonts ) && count( $google_fonts ) ) {
- $param = array();
- foreach ( $google_fonts as $font => $weights ) {
- $weights[] = 'bold'; // always include a bold version, if available
- $weights = str_replace( ' ', '', implode( ',', array_unique( $weights ) ) );
- $param[] = urlencode( $font ) . ':' . $weights;
- }
- $param = implode( '|', $param );
- $subsets_filtered = array();
- foreach ( $subsets as $subset => $set ) {
- if ( $set === '1' ) {
- $subsets_filtered[] = $subset;
- }
- }
- $subsets = implode( ',', $subsets_filtered );
- $font_imports_url = 'https://fonts.googleapis.com/css?family=' . $param . '&subset=' . $subsets;
- }
- return $font_imports_url;
- }
- public function autoload( $class ) {
- $file = 'class-' . str_replace( '_', '-', strtolower( $class ) ) . '.php';
- if ( is_readable( $this->dir . $file ) ) {
- include_once $this->dir . $file;
- return;
- }
- if ( is_readable( $this->dir . 'controls/' . $file ) ) {
- include_once $this->dir . 'controls/' . $file;
- return;
- }
- if ( is_readable( $this->dir . 'ajax/' . $file ) ) {
- include_once $this->dir . 'ajax/' . $file;
- return;
- }
- }
- public function control_ajax() {
- // ucwords $delimiter param was added in 5.4.32, 5.5.16
- $type = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $_POST['control'] ) ) );
- $class = 'Vamtam_Customize_' . $type . '_Ajax';
- if ( class_exists( $class ) ) {
- $ajax_obj = new $class( $this->get_options() );
- $method = array( $ajax_obj, 'ajax_' . $_POST['method'] );
- if ( is_callable( $method ) ) {
- call_user_func( $method );
- exit;
- }
- }
- header( 'Content-type: application/json' );
- echo json_encode( array(
- 'error' => 'cannot call ' . $class . '::ajax_' . $_POST['method'],
- ) );
- exit;
- }
- public function get_arg( $key ) {
- return $this->args[ $key ];
- }
- public function setup_options() {
- if ( ! isset( $GLOBALS[ $this->args['opt_name'] ] ) ) {
- $GLOBALS[ $this->args['opt_name'] ] = $this->get_options();
- if ( is_customize_preview() && isset( $_POST['customized'] ) ) {
- $raw_options = json_decode( stripslashes_deep( $_POST['customized'] ), true );
- if ( ! empty( $raw_options ) ) {
- if ( is_array( $raw_options ) ) {
- foreach ( $raw_options as $key => $value ) {
- if ( strpos( $key, $this->args['opt_name'] ) !== false ) {
- $key = str_replace( $this->args['opt_name'] . '[', '', rtrim( $key, ']' ) );
- $GLOBALS[ $this->args['opt_name'] ][ $key ] = $value;
- }
- }
- }
- }
- }
- }
- }
- public function get_options() {
- $options = get_option( $this->args['opt_name'] );
- if ( false === $options ) {
- $options = array();
- }
- return wp_parse_args( $options, $this->get_defaults() );
- }
- public function get_defaults() {
- $options = array();
- $fields = $this->get_fields_by_id();
- foreach ( $fields as $id => $field ) {
- if ( isset( $field['default'] ) ) {
- $options[ $id ] = $field['default'];
- }
- }
- return $options;
- }
- public function set_options( $options ) {
- return update_option( $this->args['opt_name'], $options );
- }
- public function add_section( array $args ) {
- $top_level_sections = count( $this->sections );
- if ( isset( $args['fields'] ) ) {
- $args['fields'] = apply_filters( 'vamtam_customizer_fields_options', $args['fields'] );
- }
- $args['permissions'] = isset( $args['permissions'] ) ? $args['permissions'] : 'edit_theme_options';
- if ( isset( $args['subsection'] ) && $args['subsection'] && $top_level_sections > 0 ) {
- $this->sections[ $top_level_sections - 1 ]['children'][] = $args;
- } else {
- $args['children'] = array();
- $this->sections[] = $args;
- }
- }
- public function get_sections() {
- return $this->sections;
- }
- public function get_fields_by_id() {
- if ( ! isset( $this->fields_by_id ) ) {
- $this->fields_by_id = array();
- foreach ( $this->sections as $section ) {
- if ( count( $section['children'] ) > 0 ) {
- foreach ( $section['children'] as $child ) {
- foreach ( $child['fields'] as $field ) {
- $this->fields_by_id[ $field['id'] ] = $field;
- }
- }
- } else {
- if ( isset( $section['fields'] ) ) {
- foreach ( $section['fields'] as $field ) {
- $this->fields_by_id[ $field['id'] ] = $field;
- }
- }
- }
- }
- }
- return $this->fields_by_id;
- }
- public function get_fields_by_type( $type ) {
- $fields = array();
- $options = $this->get_fields_by_id();
- foreach ( $options as $id => $opt ) {
- if ( isset( $opt['type'] ) && $opt['type'] === $type ) {
- $fields[ $id ] = $opt;
- }
- }
- return $fields;
- }
- public function customize_register( WP_Customize_Manager $wp_customize ) {
- if ( method_exists( $wp_customize, 'register_section_type' ) ) {
- $wp_customize->register_section_type( 'Vamtam_Customizer_Section' );
- }
- if ( method_exists( $wp_customize, 'register_panel_type' ) ) {
- $wp_customize->register_panel_type( 'Vamtam_Customizer_Panel' );
- }
- $priority = 1;
- foreach ( $this->sections as $section ) {
- if ( empty( $section['priority'] ) ) {
- $section['priority'] = $priority++;
- }
- $parent_id = $this->args['opt_name'] . '-' . $section['id'];
- if ( count( $section['children'] ) > 0 ) {
- $wp_customize->add_panel( $parent_id, array(
- 'priority' => $section['priority'],
- 'capability' => $section['permissions'],
- 'title' => $section['title'],
- 'section' => $section,
- 'description' => '',
- ) );
- foreach ( $section['children'] as $child ) {
- if ( empty( $child['priority'] ) ) {
- $child['priority'] = $priority++;
- }
- $wp_customize->add_section( $this->args['opt_name'] . '-' . $child['id'], array(
- 'title' => $child['title'],
- 'priority' => $child['priority'],
- 'description' => $child['description'],
- 'section' => $child,
- 'capability' => $child['permissions'],
- 'panel' => $parent_id,
- ) );
- $this->setup_fields( $child, $wp_customize );
- }
- } else {
- if ( ! isset( $section['preexisting'] ) || ! $section['preexisting'] ) {
- $wp_customize->add_section( $parent_id, array(
- 'priority' => $section['priority'],
- 'capability' => $section['permissions'],
- 'title' => $section['title'],
- 'section' => $section,
- 'description' => '',
- ) );
- }
- $this->setup_fields( $section, $wp_customize );
- }
- }
- }
- private function setup_fields( $section, WP_Customize_Manager $wp_customize ) {
- $priority = 1;
- foreach ( $section['fields'] as $field ) {
- $field['id'] = $this->args['opt_name'] . '[' . $field['id'] . ']';
- if ( ! isset( $field['priority'] ) ) {
- $field['priority'] = $priority++;
- }
- $class = $this->class_from_type( $field['type'], $wp_customize );
- if ( $class ) {
- $type = $field['type'];
- if ( $class !== 'Vamtam_Customize_Control' && strpos( $class, 'Vamtam' ) !== false ) {
- $type = 'vamtam-' . $type;
- }
- $wp_customize->add_setting( $field['id'], array(
- 'default' => isset( $field['default'] ) ? $field['default'] : '',
- 'type' => 'option',
- 'transport' => isset( $field['transport'] ) ? $field['transport'] : 'refresh',
- 'sanitize_callback' => $this->get_sanitize_callback( $field, $wp_customize ),
- ) );
- $control_attrs = array_merge( $field, array(
- 'section' => isset( $field['section'] ) ? $field['section'] : $this->args['opt_name'] . '-' . $section['id'],
- 'settings' => $field['id'],
- 'type' => $type,
- 'field' => $field,
- ) );
- $wp_customize->add_control( new $class( $wp_customize, $field['id'], $control_attrs ) );
- }
- }
- }
- private function get_sanitize_callback( $field, $wp_customize ) {
- $callback = '';
- if ( isset( $field['sanitize_callback'] ) ) {
- $callback = $field['sanitize_callback'];
- } else {
- $class = $this->class_from_type( $field['type'], $wp_customize );
- $common_callbacks = array(
- 'color' => 'sanitize_hex_color',
- 'number' => array( __CLASS__, 'sanitize_number' ),
- 'image' => 'esc_url_raw',
- );
- if ( isset( $common_callbacks[ $field['type'] ] ) ) {
- $callback = $common_callbacks[ $field['type'] ];
- } elseif ( is_callable( array( $class, 'sanitize_callback' ) ) ) {
- $callback = array( $class, 'sanitize_callback' );
- }
- }
- return apply_filters( 'vamtam_customize_setting_sanitize_callback', $callback );
- }
- public static function sanitize_number( $value ) {
- $can_validate = method_exists( 'WP_Customize_Setting', 'validate' );
- if ( ! is_numeric( $value ) ) {
- return $can_validate ? new WP_Error( 'nan', __( 'Not a number', 'vamtam-consulting' ) ) : null;
- }
- return intval( $value );
- }
- protected function class_from_type( $type, WP_Customize_Manager $wp_customize ) {
- if ( isset( $this->class_from_type_cache[ $type ] ) ) {
- return $this->class_from_type_cache[ $type ];
- }
- $orig_type = $type;
- // ucwords $delimiter param was added in 5.4.32, 5.5.16
- $type = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $type ) ) );
- $class = '';
- $test_core = 'WP_Customize_' . $type . '_Control';
- $test_vamtam = 'Vamtam_Customize_' . $type . '_Control';
- if ( class_exists( $test_vamtam ) ) {
- $class = $test_vamtam;
- try {
- $reflection = new \ReflectionMethod( $test_vamtam, 'content_template' );
- $declaringClass = $reflection->getDeclaringClass()->getName();
- $proto = $reflection->getPrototype();
- if ( $proto && $proto->getDeclaringClass()->getName() !== $declaringClass ) {
- $wp_customize->register_control_type( $class );
- }
- } catch ( Exception $e ) {
- // getPrototype will throw if content_template() is not overriden
- }
- } elseif ( class_exists( $test_core ) ) {
- $class = $test_core;
- } else {
- $class = 'Vamtam_Customize_Control'; // default WP Core control - implements text, radio, select, etc.
- }
- $this->class_from_type_cache[ $orig_type ] = $class;
- return $class;
- }
- }
|