/** * This function sets up properties on this class and allows other plugins and themes * to adjust those properties by filtering. */ public function init() { global $wp_version, $wp_customize, $wp_registered_widgets, $wp_registered_sidebars; // Load required assets $this->includes(); // Grab the Note Widget instance if (function_exists('Note_Widget')) { $note_widget = Note_Widget(); } // Determine HTML5 support $caption_html5_support = current_theme_supports('html5', 'caption'); // Captions $gallery_html5_support = current_theme_supports('html5', 'gallery'); // Galleries // Grab Note options $note_options = Note_Options::get_options(); // Setup of Note Sidebar data if we're in the Customizer if (is_customize_preview()) { // Grab the Note Sidebars instance $note_sidebars = Note_Sidebars(); // Grab Note Sidebar Customizer arguments $this->note_sidebar_args = Note_Sidebars::get_customizer_sidebar_args(); // Loop through Note sidebars foreach ($note_sidebars->sidebars as $post_id => $note_sidebar_ids) { // Loop through Note sidebar locations foreach ($note_sidebars->sidebar_locations as $sidebar_location) { // Loop through each sidebar within this location foreach ($sidebar_location as $sidebar_id) { // Add the sidebar ID to the list of registered sidebars $this->note_sidebar_locations[] = Note_Sidebars::get_sidebar_id($sidebar_id, $post_id); } } // Loop through registered Note Sidebar IDs foreach ($note_sidebar_ids as $sidebar_id) { // Add the sidebar ID to the list of registered sidebars $this->note_registered_sidebars[] = Note_Sidebars::get_sidebar_id($sidebar_id, $post_id); } } $this->note_unregistered_sidebars = array_values(array_diff($this->note_sidebar_locations, $this->note_registered_sidebars)); $sidebars_widgets = array_merge(array('wp_inactive_widgets' => array()), array_fill_keys(array_keys($wp_registered_sidebars), array()), wp_get_sidebars_widgets()); // Loop through sidebar widgets foreach ($sidebars_widgets as $sidebar_id => $sidebar_widget_ids) { if (empty($sidebar_widget_ids)) { $sidebar_widget_ids = array(); } // Unregistered Note Sidebars only if (in_array($sidebar_id, $this->note_unregistered_sidebars)) { // Store a reference to sidebars that were previously active but are now inactive $this->note_inactive_sidebars[] = $sidebar_id; // Add a control for each inactive widget foreach ($sidebar_widget_ids as $i => $widget_id) { // Only widgets that are still registered if (isset($wp_registered_widgets[$widget_id])) { // Customizer is ready if (is_a($wp_customize, 'WP_Customize_Manager')) { $setting_id = $wp_customize->widgets->get_setting_id($widget_id); // Store a reference to the Customizer setting ID for this inactive widget $this->note_inactive_widgets[] = array('widget_id' => $widget_id, 'setting_id' => $setting_id); if (!isset($this->note_inactive_sidebars_widgets[$sidebar_id])) { $this->note_inactive_sidebars_widgets[$sidebar_id] = array(); } // Store a reference to the inactive widget attached to the sidebar ID $this->note_inactive_sidebars_widgets[$sidebar_id][$i] = array('widget_id' => $widget_id, 'setting_id' => $setting_id); } } } } } } // Note Widget Editor Types $this->note_editor_types = apply_filters('note_tinymce_editor_types', $this->note_editor_types, $this); // Setup Customizer localization $this->note_customizer_localize = apply_filters('note_customizer_localize', array('wp_version' => $wp_version, 'wp_major_version' => (int) substr($wp_version, 0, 1), 'sidebars' => array('registered' => $note_options['sidebars'], 'customizer' => array('setting' => 'note[sidebars]', 'section' => 'note_sidebars', 'control' => 'note_sidebars', 'section_prefix' => 'sidebar-widgets-', 'inactive_sidebars' => $this->note_inactive_sidebars, 'inactive_widgets' => $this->note_inactive_widgets, 'inactive_sidebars_widgets' => $this->note_inactive_sidebars_widgets), 'args' => $this->note_sidebar_args)), $this); // Setup Previewer localization $this->note_localize = apply_filters('note_localize', array('tinymce' => array('selector' => '.note-widget .widget-content', 'plugins' => implode(' ', array_unique(apply_filters('note_tinymce_plugins', array('paste', 'lists', 'hr', 'textcolor', 'colorpicker', 'wordpress', 'wplink', 'wpview', 'note_insert', 'note_image', 'note_placeholder'), $this))), 'blocks' => apply_filters('note_tinymce_blocks', array('wp_image', 'note_edit'), $this), 'toolbar' => apply_filters('note_tinymce_toolbar', array('formatselect', 'styleselect', 'forecolor', 'backcolor', 'bold', 'italic', 'link', 'unlink', 'bullist', 'numlist', 'outdent', 'indent', 'alignleft', 'aligncenter', 'alignright', 'alignjustify'), $this), 'formats' => array('alignleft' => array(array('selector' => 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,address', 'styles' => array('textAlign' => 'left')), array('selector' => 'img,table,dl.wp-caption', 'classes' => array('alignleft'))), 'aligncenter' => array(array('selector' => 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,address', 'styles' => array('textAlign' => 'center')), array('selector' => 'img,table,dl.wp-caption', 'classes' => array('aligncenter'))), 'alignright' => array(array('selector' => 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,address', 'styles' => array('textAlign' => 'right')), array('selector' => 'img,table,dl.wp-caption', 'classes' => array('alignright')))), 'preview_styles' => implode(' ', array_unique(apply_filters('note_tinymce_preview_styles', array('font-family', 'font-size', 'font-weight', 'font-style', 'text-decoration', 'text-transform', 'color', 'background-color', 'border', 'border-radius', 'outline', 'text-shadow'), $this))), 'style_formats' => apply_filters('note_tinymce_style_formats', array(array('title' => __('12px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '12px')), array('title' => __('14px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '14px')), array('title' => __('16px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '16px')), array('title' => __('18px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '18px')), array('title' => __('20px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '20px')), array('title' => __('22px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '22px')), array('title' => __('24px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '24px')), array('title' => __('28px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '28px')), array('title' => __('32px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '32px')), array('title' => __('36px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '36px')), array('title' => __('42px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '42px')), array('title' => __('48px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '48px')), array('title' => __('56px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '56px')), array('title' => __('64px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '64px')), array('title' => __('72px', 'note'), 'inline' => 'span', 'styles' => array('fontSize' => '72px'))), $this), 'theme' => 'note', 'inline' => true, 'relative_urls' => false, 'convert_urls' => false, 'browser_spellcheck' => true, 'entity_encoding' => 'named', 'placeholder' => apply_filters('note_tinymce_placeholder', __('Start typing here…', 'note'), $this), 'html5_support' => array('caption' => $caption_html5_support, 'gallery' => $gallery_html5_support), 'caption_html' => $caption_html5_support ? array('itemtag' => 'figure', 'icontag' => 'div', 'captiontag' => 'figcaption') : array('itemtag' => 'dl', 'icontag' => 'dt', 'captiontag' => 'dd'), 'gallery_html5_support' => array()), 'modal_commands' => array('activate' => array('tinymce' => array('BeforeExecCommand' => 'WP_Link', 'wpLoadImageForm'), 'document' => array('note-modal-open'), 'wp.media.events' => array('editor:image-edit')), 'deactivate' => array('tinymce' => array('wpLoadImageData', 'wpLoadImageForm' => array('wp.media.frame' => 'close')), 'document' => array('wplink-close', 'note-modal-close'), 'wp.media.events' => array('editor:frame-create' => array('event.frame' => 'close')))), 'widget' => array('id' => isset($note_widget) ? $note_widget->id_base : 'note-widget'), 'widgets' => array('defaults' => array(), 'settings' => array(), 'templates' => array()), 'modals' => array('register_sidebar' => array('title' => __('Add Note Sidebar', 'note'), 'content' => sprintf('%1$s <div class="inputs"><input type="checkbox" name="ignore-register-sidebar" id="note-ignore-register-sidebar" class="ignore-register-sidebar ignore-register-sidebar-modal" value="true" /> <label for="note-ignore-register-sidebar">%2$s</label></div>', __('Are you sure you want to add a sidebar to this location?', 'note'), __('Don\'t display this confirmation in the future', 'note')), 'submit_label' => __('Add Note Sidebar', 'note')), 'unregister_sidebar' => array('title' => __('Remove Note Sidebar', 'note'), 'content' => sprintf('%1$s', __('Are you sure you want to remove this sidebar?', 'note')), 'submit_label' => __('Remove Note Sidebar', 'note'))))); // If we have editor types if (is_array($this->note_editor_types) && !empty($this->note_editor_types)) { // Adjust Note localization data (store TinyMCE data in an array under the 'default' key) $this->note_localize['tinymce'] = array('default' => $this->note_localize['tinymce']); // Shim for Conductor 1.2.* TODO: Remove in a future version if (!Note::conductor_has_flexbox_display()) { $this->note_localize['tinymce'] = array_merge($this->note_localize['tinymce'], $this->note_localize['tinymce']['default']); } // Loop through editor types for configuration foreach ($this->note_editor_types as $editor_type) { // Copy Note localization data $settings = $this->note_localize['tinymce']['default']; // Switch based on editor type switch ($editor_type) { // Rich Text Only case 'rich_text_only': // Make plugins an array $settings['plugins'] = explode(' ', $settings['plugins']); // Search for the 'note_image' TinyMCE plugin in existing settings $note_image = array_search('note_image', $settings['plugins']); // If we have an index for the the 'note_image' TinyMCE plugin if ($note_image !== false) { // Remove the 'note_image' TinyMCE plugin unset($settings['plugins'][$note_image]); // Reset array keys to ensure JavaScript logic receives an array $settings['plugins'] = array_values($settings['plugins']); } // Make plugins a string again $settings['plugins'] = implode(' ', $settings['plugins']); // Search for the 'wp_image' TinyMCE block in existing settings $wp_image = array_search('wp_image', $settings['blocks']); // If we have an index for the the 'wp_image' TinyMCE block if ($wp_image !== false) { // Remove the 'wp_image' TinyMCE block unset($settings['blocks'][$wp_image]); // Reset array keys to ensure JavaScript logic receives an array $settings['blocks'] = array_values($settings['blocks']); } break; // Media // Media case 'media': // Add media blocks $settings['media_blocks'] = array('wp_image'); // Reset the placeholder $settings['placeholder'] = ''; break; // Rich Text (Also default; just inherit from Note) // Rich Text (Also default; just inherit from Note) default: // Do nothing (for now) break; } // Allow filtering of plugins, toolbar items, and placeholder $settings['plugins'] = explode(' ', $settings['plugins']); $settings['plugins'] = implode(' ', array_unique(apply_filters('note_tinymce_editor_plugins', $settings['plugins'], $editor_type, $this))); $settings['blocks'] = apply_filters('note_tinymce_editor_blocks', $settings['blocks'], $editor_type, $this); $settings['toolbar'] = apply_filters('note_tinymce_editor_toolbar', $settings['toolbar'], $editor_type, $this); //$settings['block_formats'] = apply_filters( 'note_tinymce_editor_block_formats', $settings['block_formats'], $editor_type, $this ); $settings['preview_styles'] = explode(' ', $settings['preview_styles']); $settings['preview_styles'] = implode(' ', array_unique(apply_filters('note_tinymce_editor_preview_styles', $settings['preview_styles'], $editor_type, $this))); $settings['style_formats'] = apply_filters('note_tinymce_editor_style_formats', $settings['style_formats'], $editor_type, $this); $settings['placeholder'] = apply_filters('note_tinymce_editor_placeholder', $settings['placeholder'], $editor_type, $this); // Add the Note editor type $settings['note_type'] = $editor_type; // Assign the configuration to the localization data $settings = apply_filters('note_tinymce_editor_settings', $settings, $editor_type, $this); $this->note_localize['tinymce'][$editor_type] = $settings; } } // Setup Previewer TinyMCE localization $this->note_tinymce_localize = apply_filters('note_tinymce_localize', array('wp_version' => $wp_version, 'wp_major_version' => (int) substr($wp_version, 0, 1)), $this); }
/** * This function sets up all of the actions and filters on instance. It also initializes widget options * including class name, description, width/height, and creates an instance of the widget */ function __construct() { // Load required assets $this->includes(); $id_base = 'note-widget'; // Widget/Control options $this->widget_options = array('classname' => $id_base, 'description' => __('A simple and easy to use widget for editing bits of text.', 'note')); $this->widget_options = apply_filters('note_widget_widget_options', $this->widget_options, $this); $this->control_options = apply_filters('note_widget_control_options', array('id_base' => $id_base), $this); // Defaults $this->defaults = apply_filters('note_widget_defaults', array('title' => false, 'hide_title' => true, 'content' => false, 'content_areas' => array(), 'css_class' => false, 'template' => 'default', 'columns' => 1, 'rows' => 1, 'extras' => array('background_image_attachment_id' => false)), $this); // Set up the default widget settings // Maximum number of rows $this->max_rows = (int) apply_filters('note_widget_max_rows', $this->max_rows, $this); // Maximum number of columns $this->max_columns = (int) apply_filters('note_widget_max_columns', $this->max_columns, $this); // Background image CSS properties $this->background_image_css = apply_filters('note_widget_background_image_css', $this->background_image_css, $this); /* * Set up the default widget templates * * Valid content area types: * - rich_text - Default type (if not specified) * - rich_text_only - Rich text only (no media) * * Format: * 'template-id' => array( // ID for the template (unique) * 'label' => __( 'Template Label', 'note' ), // Label for the template * // Please Note: TinyMCE does not like white space with nested elements inside of placeholder configuration data and extra white space could lead to placeholder display issues/undesired results in the Previewer * 'placeholder' => '<p>Placeholder</p>', // Global placeholder text/html for this template (this placeholder will be used if an individual config does not specify a placeholder property); data-note-placeholder="false" may be used to specify an element that should not inherit Note placeholder styles * 'template' => 'template', // Template name for this template (optional; without .php suffix; the widget will search through $this->base_template_dir and theme assets first, then load the fallback) * 'type' => 'simple', // Type of display layout (used for grouping in Note Widget settings; should match a "template types" value) * 'config' => array( // Customizer Previewer Configuration (array key to start at 1, not 0, and is a string) * 'type' => 'rich_text_only', // Type for this content area (optional) * // Placeholder Content (optional) * 'placeholder' => '<p>Placeholder</p>', // Content area placeholder text/html for this template (optional); data-note-placeholder="false" may be used to specify an element that should not inherit Note placeholder styles * // Plugins, Additional elements and features that this editor supports (optional) * 'plugins' => array( * 'note_background' // Allow for addition of a background image * ), * // Blocks, Additional blocks to be added to the "insert" toolbar * 'blocks' => array( * 'note_background' // Matches plugin name above * ), * // Allow for the customization of columns and rows by the end user through widget settings (optional) * 'customize' => array( * 'columns' => true, // Columns * 'rows' => true, // Rows * 'note_background' => true // Note Background * ), * // Column Support, Integer (will inherit default Note TinyMCE editor config) or an array of individual column configurations * 'columns' => 6 // (1-6) 6 columns is the default maximum number of columns that Note Widgets support * || * array( * // Column 1 * 1 => array( // First content area * 'type' => 'rich_text_only', // Type for this content area (optional) * // Placeholder Content (optional) * 'placeholder' => '<p>Placeholder</p>', // Content area placeholder text/html for this template (optional); data-note-placeholder="false" may be used to specify an element that should not inherit Note placeholder styles * // Plugins, Additional elements and features that this editor supports (optional) * 'plugins' => array( * 'note_background' // Allow for addition of a background image * ), * // Blocks, Additional blocks to be added to the "insert" toolbar * 'blocks' => array( * 'note_background' // Matches plugin name above * ) * ... * ) * ) * ) * * TODO: Placeholder/default content could be set in the template possibly * TODO: Allow for different columns to specify a template? */ $this->templates = apply_filters('note_widget_templates', array('2-col' => array('label' => __('2 Columns', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array(), '2' => array()))), '2-col-media-content' => array('label' => __('2 Columns - Media Left/Content Right', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'template' => '2-col', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array('type' => 'media', 'placeholder' => ''), '2' => array()))), '2-col-content-media' => array('label' => __('2 Columns - Content Left/Media Right', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'template' => '2-col', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array(), '2' => array('type' => 'media', 'placeholder' => '')))), '3-col' => array('label' => __('3 Columns', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array(), '2' => array(), '3' => array()))), '4-col' => array('label' => __('4 Columns', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array(), '2' => array(), '3' => array(), '4' => array()))), '5-col' => array('label' => __('5 Columns', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array(), '2' => array(), '3' => array(), '4' => array(), '5' => array()))), '6-col' => array('label' => __('6 Columns', 'note'), 'placeholder' => '<h2>Heading 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eros tortor, molestie eget tortor sit amet, feugiat semper ante. Aliquam a pellentesque purus, quis vulputate lacus.</p>', 'type' => 'simple', 'config' => array('customize' => array('rows' => true), 'columns' => array('1' => array(), '2' => array(), '3' => array(), '4' => array(), '5' => array(), '6' => array())))), $this); // Set up the default widget template types $this->template_types = apply_filters('note_widget_template_types', array('simple' => __('Simple', 'note')), $this); // Organize templates by type and determine the maximum number of content areas if (!empty($this->templates)) { foreach ($this->templates as $template_id => $template) { /* * Templates by Type */ // TODO: Ensure the simple templates are at the "top" of the list using array_splice? Use order of $this->template_types array keys for order of $this->templates_by_type if possible // If this template has a type if (isset($template['type'])) { // Create the template type array if it doesn't exist if (!isset($this->templates_by_type[$template['type']])) { $this->templates_by_type[$template['type']] = array(); } // Store a reference to the template ID in it's type $this->templates_by_type[$template['type']][] = $template_id; } else { // Create the template type array if it doesn't exist if (!isset($this->templates_by_type['simple'])) { $this->templates_by_type['simple'] = array(); } // Store a reference to the template ID in the default simple type $this->templates_by_type['simple'][] = $template_id; } /* * Maximum Content Areas */ $template_content_areas = 1; // Count the number of content areas for this template if (isset($template['config']['columns'])) { $template_columns = is_array($template['config']['columns']) ? count($template['config']['columns']) : (int) $template['config']['columns']; $template_content_areas = $this->max_rows * $template_columns; if ($template_columns < $this->max_columns) { $template_content_areas = $this->max_rows * $this->max_columns; } } // If this template has more content areas than the current maximum number, adjust the value if ($template_content_areas > $this->max_content_areas) { $this->max_content_areas = $template_content_areas; } } } // Allow for filtering of the base template directory $this->base_template_dir = apply_filters('note_widget_base_template_dir', $this->base_template_dir, $this); // Call the parent constructor element parent::__construct($id_base, sprintf(__('%1$s', 'note'), $this->name), $this->widget_options, $this->control_options); // Hooks if (!has_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'))) { add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); } // Enqueue admin scripts if (!has_action('note_widget', array(get_class(), 'note_widget'))) { add_action('note_widget', array(get_class(), 'note_widget'), 10, 3); } // Output standard Note Widget content if (!has_action('note_widget_after', array(get_class(), 'note_widget_after'))) { add_action('note_widget_after', array(get_class(), 'note_widget_after'), 10, 3); } // Output standard Note Widget content // Shim for Conductor 1.2.* TODO: Remove in a future version if (!Note::conductor_has_flexbox_display() && function_exists('Conduct_Note_Widget')) { // Grab the Conductor Note Widget instance $conductor_note_widget = Conduct_Note_Widget(); // Remove all hooks associated with Conductor Note Widget remove_filter('note_tinymce_plugins', array($conductor_note_widget, 'note_tinymce_plugins')); // Note TinyMCE Plugins remove_filter('note_tinymce_toolbar', array($conductor_note_widget, 'note_tinymce_toolbar')); // Note TinyMCE Toolbar remove_filter('note_widget_widget_options', array($conductor_note_widget, 'note_widget_widget_options')); // Note Widget Options remove_action('note_widget_defaults', array($conductor_note_widget, 'note_widget_defaults')); // Note Widget Defaults remove_action('note_widget_settings_content_before', array($conductor_note_widget, 'note_widget_settings_content_before'), 10, 2); // Note Widget Settings before content remove_filter('note_widget_update', array($conductor_note_widget, 'note_widget_update')); // Note Widget Update remove_filter('note_widget_instance', array($conductor_note_widget, 'note_widget_instance')); // Note Widget Instance remove_action('note_widget_before', array($conductor_note_widget, 'note_widget_before'), 1); // Note Widget Output (early) remove_action('note_widget_after', array($conductor_note_widget, 'note_widget_after'), 9999); // Note Widget Output After (late) } }