'header', 'linking' => 'internal', 'side' => 'frontend', 'priority' => 5, 'language' => 'css', ); /** * Array with the options for a specific custom-css-js post */ private $options = array(); /** * Constructor */ public function __construct() { $this->add_functions(); } /** * Add actions and filters */ function add_functions() { // Add filters $filters = array( 'manage_custom-css-js_posts_columns' => 'manage_custom_posts_columns', ); foreach( $filters as $_key => $_value ) { add_filter( $_key, array( $this, $_value ) ); } // Add actions $actions = array( 'admin_menu' => 'admin_menu', 'admin_enqueue_scripts' => 'admin_enqueue_scripts', 'current_screen' => 'current_screen', 'admin_notices' => 'create_uploads_directory', 'edit_form_after_title' => 'codemirror_editor', 'add_meta_boxes' => 'add_meta_boxes', 'save_post' => 'options_save_meta_box_data', 'trashed_post' => 'trash_post', 'untrashed_post' => 'trash_post', 'wp_ajax_ccj_active_code' => 'wp_ajax_ccj_active_code', 'wp_ajax_ccj_permalink' => 'wp_ajax_ccj_permalink', 'post_submitbox_start' => 'post_submitbox_start', 'restrict_manage_posts' => 'restrict_manage_posts', 'edit_form_before_permalink' => 'edit_form_before_permalink', 'before_delete_post' => 'before_delete_post', ); foreach( $actions as $_key => $_value ) { add_action( $_key, array( $this, $_value ) ); } // Add some custom actions/filters add_action( 'manage_custom-css-js_posts_custom_column', array( $this, 'manage_posts_columns' ), 10, 2 ); add_filter( 'manage_edit-custom-css-js_sortable_columns', array( $this, 'manage_edit_posts_sortable_columns' ) ); add_filter( 'post_row_actions', array( $this, 'post_row_actions' ), 10, 2 ); add_filter( 'parse_query', array($this, 'parse_query') , 10); add_action('current_screen', array($this, 'current_screen_2'), 100); } /** * Add submenu pages */ function admin_menu() { $menu_slug = 'edit.php?post_type=custom-css-js'; $submenu_slug = 'post-new.php?post_type=custom-css-js'; remove_submenu_page( $menu_slug, $submenu_slug); $title = __('Add Custom CSS', 'custom-css-js'); add_submenu_page( $menu_slug, $title, $title, 'publish_custom_csss', $submenu_slug .'&language=css'); $title = __('Add Custom JS', 'custom-css-js'); add_submenu_page( $menu_slug, $title, $title, 'publish_custom_csss', $submenu_slug . '&language=js'); $title = __('Add Custom HTML', 'custom-css-js'); add_submenu_page( $menu_slug, $title, $title, 'publish_custom_csss', $submenu_slug . '&language=html'); } /** * Enqueue the scripts and styles */ public function admin_enqueue_scripts( $hook ) { $screen = get_current_screen(); // Only for custom-css-js post type if ( $screen->post_type != 'custom-css-js' ) return false; // Some handy variables $a = plugins_url( '/', CCJ_PLUGIN_FILE). 'assets'; $cm = $a . '/codemirror'; $v = CCJ_VERSION; wp_register_script( 'ccj-admin', $a . '/ccj_admin.js', array('jquery', 'jquery-ui-resizable'), $v, false ); wp_localize_script( 'ccj-admin', 'CCJ', $this->cm_localize() ); wp_enqueue_script( 'ccj-admin' ); wp_enqueue_style( 'ccj-admin', $a . '/ccj_admin.css', array(), $v ); // Only for the new/edit Code's page if ( $hook == 'post-new.php' || $hook == 'post.php' ) { wp_deregister_script('wp-codemirror'); wp_enqueue_style( 'jquery-ui', 'https://code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css', array(), $v ); wp_enqueue_script( 'ccj-codemirror', $cm . '/lib/codemirror.js', array( 'jquery' ), $v, false); wp_enqueue_style( 'ccj-codemirror', $cm . '/lib/codemirror.css', array(), $v ); wp_enqueue_script( 'ccj-admin_url_rules', $a . '/ccj_admin-url_rules.js', array('jquery'), $v, false ); // Add the language modes $cmm = $cm . '/mode/'; wp_enqueue_script('cm-xml', $cmm . 'xml/xml.js', array('ccj-codemirror'), $v, false); wp_enqueue_script('cm-js', $cmm . 'javascript/javascript.js', array('ccj-codemirror'), $v, false); wp_enqueue_script('cm-css', $cmm . 'css/css.js', array('ccj-codemirror'), $v, false); wp_enqueue_script('cm-htmlmixed', $cmm . 'htmlmixed/htmlmixed.js', array('ccj-codemirror'), $v, false); $cma = $cm . '/addon/'; wp_enqueue_script('cm-dialog', $cma . 'dialog/dialog.js', array('ccj-codemirror'), $v, false); wp_enqueue_script('cm-search', $cma . 'search/search.js', array('ccj-codemirror'), $v, false); wp_enqueue_script('cm-searchcursor', $cma . 'search/searchcursor.js',array('ccj-codemirror'), $v, false); wp_enqueue_script('cm-jump-to-line', $cma . 'search/jump-to-line.js', array('ccj-codemirror'), $v, false); wp_enqueue_style('cm-dialog', $cma . 'dialog/dialog.css', array(), $v ); // remove the assets from other plugins so it doesn't interfere with CodeMirror global $wp_scripts; if (is_array($wp_scripts->registered) && count($wp_scripts->registered) != 0) { foreach($wp_scripts->registered as $_key => $_value) { if (!isset($_value->src)) continue; if (strstr($_value->src, 'wp-content/plugins') !== false && strstr($_value->src, 'plugins/custom-css-js/assets') === false && strstr($_value->src, 'plugins/advanced-custom-fields/') === false && strstr($_value->src, 'plugins/advanced-custom-fields-pro/') === false) { unset($wp_scripts->registered[$_key]); } } } } } /** * Send variables to the ccj_admin.js script */ public function cm_localize() { $vars = array( 'active' => __('Active', 'custom-css-js'), 'inactive' => __('Inactive', 'custom-css-js'), 'activate' => __('Activate', 'custom-css-js'), 'deactivate' => __('Deactivate', 'custom-css-js'), 'active_title' => __('The code is active. Click to deactivate it', 'custom-css-js'), 'deactive_title' => __('The code is inactive. Click to activate it', 'custom-css-js'), ); return $vars; } public function add_meta_boxes() { add_meta_box('custom-code-options', __('Options', 'custom-css-js'), array( $this, 'custom_code_options_meta_box_callback'), 'custom-css-js', 'side', 'low'); remove_meta_box( 'slugdiv', 'custom-css-js', 'normal' ); } /** * Get options for a specific custom-css-js post */ private function get_options( $post_id ) { if ( isset( $this->options[ $post_id ] ) ) { return $this->options[ $post_id ]; } $options = get_post_meta( $post_id ); if ( empty( $options ) || ! isset ( $options['options'][0] ) ) { $this->options[ $post_id ] = $this->default_options; return $this->default_options; } $options = unserialize( $options['options'][0] ); $this->options[ $post_id ] = $options; return $options; } /** * Reformat the `edit` or the `post` screens */ function current_screen( $current_screen ) { if ( $current_screen->post_type != 'custom-css-js' ) { return false; } if ( $current_screen->base == 'post' ) { add_action( 'admin_head', array( $this, 'current_screen_post' ) ); } if ( $current_screen->base == 'edit' ) { add_action( 'admin_head', array( $this, 'current_screen_edit' ) ); } wp_deregister_script( 'autosave' ); } /** * Add the buttons in the `edit` screen */ function add_new_buttons() { $current_screen = get_current_screen(); if ( (isset($current_screen->action ) && $current_screen->action == 'add') || $current_screen->post_type != 'custom-css-js' ) { return false; } ?>
'', 'active' => '', 'type' => __('Type', 'custom-css-js'), 'title' => __('Title', 'custom-css-js'), 'author' => __('Author', 'custom-css-js'), 'published' => __('Published', 'custom-css-js'), 'modified' => __('Modified', 'custom-css-js'), ); } /** * Fill the data for the new added columns in the `edit` screen */ function manage_posts_columns( $column, $post_id ) { if ( $column == 'type' ) { $options = $this->get_options( $post_id ); echo ''; } if ( $column == 'modified' || $column == 'published' ) { if ( $column == 'modified' ) { $f_time = get_post_modified_time( __('Y/m/d g:i:s a'), true, $post_id ); $g_time = get_post_modified_time( 'G', true, $post_id ); } else { $f_time = get_post_time( __('Y/m/d g:i:s a' ), true ); $g_time = get_post_time( 'G', true ); } $time_diff = time() - $g_time; if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) { $h_time = sprintf( __( '%s ago', 'custom-css-js' ), human_time_diff( $g_time) ); } else { $h_time = mysql2date( get_option('date_format'), $f_time ); } echo $h_time; } if ( $column == 'active' ) { $url = wp_nonce_url( admin_url( 'admin-ajax.php?action=ccj_active_code&code_id=' . $post_id ), 'ccj-active-code-' .$post_id ); if ( $this->is_active( $post_id ) ) { $active_title = __('The code is active. Click to deactivate it', 'custom-css-js'); $active_icon = 'dashicons-star-filled'; } else { $active_title = __('The code is inactive. Click to activate it', 'custom-css-js'); $active_icon = 'dashicons-star-empty ccj_row'; } echo '' . ''. ''; } } /** * Make the 'Modified' column sortable */ function manage_edit_posts_sortable_columns( $columns ) { $columns['modified'] = 'modified'; $columns['published'] = 'published'; return $columns; } /** * List table: Change the query in order to filter by code type */ function parse_query( $query ){ if ( !is_admin() || !$query->is_main_query() ){ return $query; } if ( !isset($query->query['post_type'])) { return $query; } if ( 'custom-css-js' !== $query->query['post_type'] ) { return $query; } $filter = filter_input( INPUT_GET, 'language_filter' ); if ( !is_string($filter) || strlen($filter) == 0 ) { return $query; } global $wpdb; $post_id_query = "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value LIKE %s"; $post_ids = $wpdb->get_col( $wpdb->prepare($post_id_query, 'options', '%'.$filter.'%') ); if ( !is_array($post_ids) || count($post_ids) == 0 ) { $post_ids = array(-1); } $query->query_vars['post__in'] = $post_ids; return $query; } /** * List table: add a filter by code type */ function restrict_manage_posts( $post_type ) { if('custom-css-js' !== $post_type){ return; } $languages = array( 'css' => __('CSS Codes', 'custom-cs-js'), 'js' => __('JS Codes', 'custom-css-js'), 'html' => __('HTML Codes', 'custom-css-js'), ); echo ''; echo ''; } /** * Activate/deactivate a code * * @return void */ function wp_ajax_ccj_active_code() { if ( ! isset( $_GET['code_id'] ) ) die(); $code_id = absint( $_GET['code_id'] ); $response = 'error'; if ( check_admin_referer( 'ccj-active-code-' . $code_id) ) { if ( 'custom-css-js' === get_post_type( $code_id ) ) { $active = get_post_meta($code_id, '_active', true ); if ( $active === false || $active === '' ) { $active = 'yes'; } $response = $active; update_post_meta( $code_id, '_active', $active === 'yes' ? 'no' : 'yes' ); $this->build_search_tree(); } } echo $response; die(); } /** * Check if a code is active * * @return bool */ function is_active( $post_id ) { return get_post_meta( $post_id, '_active', true ) !== 'no'; } /** * Reformat the `edit` screen */ function current_screen_edit() { ?> remove_unallowed_metaboxes(); $strings = array( 'Add CSS Code' => __('Add CSS Code', 'custom-css-js'), 'Add JS Code' => __('Add JS Code', 'custom-css-js'), 'Add HTML Code' => __('Add HTML Code', 'custom-css-js'), 'Edit CSS Code' => __('Edit CSS Code', 'custom-css-js'), 'Edit JS Code' => __('Edit JS Code', 'custom-css-js'), 'Edit HTML Code' => __('Edit HTML Code', 'custom-css-js'), ); if ( isset( $_GET['post'] ) ) { $action = 'Edit'; $post_id = esc_attr($_GET['post']); } else { $action = 'Add'; $post_id = false; } $language = $this->get_language($post_id); $title = $action . ' ' . strtoupper( $language ) . ' Code'; $title = (isset($strings[$title])) ? $strings[$title] : $strings['Add CSS Code']; if ( $action == 'Edit' ) { $title .= ' '.__('Add CSS Code', 'custom-css-js') .' '; $title .= ''.__('Add JS Code', 'custom-css-js') .''; $title .= ''.__('Add HTML Code', 'custom-css-js') .''; } ?> $_boxes ) { foreach( $_boxes as $_key => $_value ) { if ( ! in_array( $_key, $allowed ) ) { unset( $wp_meta_boxes['custom-css-js']['side'][$_priority][$_key] ); } } } // Normal boxes $allowed = array( 'slugdiv', 'previewdiv', 'url-rules', 'revisionsdiv' ); $allowed = apply_filters( 'custom-css-js-meta-boxes-normal', $allowed ); foreach( $wp_meta_boxes['custom-css-js']['normal'] as $_priority => $_boxes ) { foreach( $_boxes as $_key => $_value ) { if ( ! in_array( $_key, $allowed ) ) { unset( $wp_meta_boxes['custom-css-js']['normal'][$_priority][$_key] ); } } } unset($wp_meta_boxes['custom-css-js']['advanced']); } /** * Add the codemirror editor in the `post` screen */ public function codemirror_editor( $post ) { $current_screen = get_current_screen(); if ( $current_screen->post_type != 'custom-css-js' ) { return false; } if ( empty( $post->title ) && empty( $post->post_content ) ) { $new_post = true; $post_id = false; } else { $new_post = false; if ( ! isset( $_GET['post'] ) ) $_GET['post'] = $post->id; $post_id = esc_attr($_GET['post']); } $language = $this->get_language($post_id); $settings = get_option( 'ccj_settings' ); // Replace the htmlentities (https://wordpress.org/support/topic/annoying-bug-in-text-editor/), but only selectively if ( isset($settings['ccj_htmlentities']) && $settings['ccj_htmlentities'] == 1 && strstr($post->post_content, '&') ) { // First the ampresands $post->post_content = str_replace('&', htmlentities('&'), $post->post_content ); // Then the rest of the entities $html_flags = defined('ENT_HTML5') ? ENT_QUOTES | ENT_HTML5 : ENT_QUOTES; $entities = get_html_translation_table(HTML_ENTITIES, $html_flags); unset( $entities[ array_search('&', $entities) ]); $regular_expression = str_replace(';', '', '/('.implode('|', $entities).')/i'); preg_match_all($regular_expression, $post->post_content, $matches); if ( isset($matches[0]) && count($matches[0]) > 0 ) { foreach($matches[0] as $_entity) { $post->post_content = str_replace($_entity, htmlentities($_entity), $post->post_content); } } } if ( isset($settings['ccj_htmlentities2']) && $settings['ccj_htmlentities2'] == 1 ) { $post->post_content = htmlentities( $post->post_content ); } switch ( $language ) { case 'js' : if ( $new_post ) { $post->post_content = __('/* Add your JavaScript code here. If you are using the jQuery library, then don\'t forget to wrap your code inside jQuery.ready() as follows: jQuery(document).ready(function( $ ){ // Your code in here }); -- If you want to link a JavaScript file that resides on another server (similar to ), then please use the "Add HTML Code" page, as this is a HTML code that links a JavaScript file. End of comment */ ', 'custom-css-js') . PHP_EOL . PHP_EOL; } $code_mirror_mode = 'text/javascript'; $code_mirror_before = ''; break; case 'html' : if ( $new_post ) { $post->post_content = __(' ', 'custom-css-js') . PHP_EOL . PHP_EOL; } $code_mirror_mode = 'html'; $code_mirror_before = ''; $code_mirror_after = ''; break; case 'php' : if ( $new_post ) { $post->post_content = '/* The following will be executed as if it were written in functions.php. */' . PHP_EOL . PHP_EOL; } $code_mirror_mode = 'php'; $code_mirror_before = ''; break; default : if ( $new_post ) { $post->post_content = __('/* Add your CSS code here. For example: .example { color: red; } For brushing up on your CSS knowledge, check out http://www.w3schools.com/css/css_syntax.asp End of comment */ ', 'custom-css-js') . PHP_EOL . PHP_EOL; } $code_mirror_mode = 'text/css'; $code_mirror_before = ''; } ?> get_options( $post->ID ); if ( ! isset($options['preprocessor'] ) ) $options['preprocessor'] = 'none'; if ( isset( $_GET['language'] ) ) { $options['language'] = $this->get_language(); } $meta = $this->get_options_meta(); if ( $options['language'] == 'html' ) { $meta = $this->get_options_meta_html(); } wp_nonce_field( 'options_save_meta_box_data', 'custom-css-js_meta_box_nonce' ); ?> array( 'title' => __('Linking type', 'custom-css-js'), 'type' => 'radio', 'default' => 'internal', 'values' => array( 'external' => array( 'title' => __('External File', 'custom-css-js'), 'dashicon' => 'media-code', ), 'internal' => array( 'title' => __('Internal', 'custom-css-js'), 'dashicon' => 'editor-alignleft', ), ), ), 'type' => array( 'title' => __('Where on page', 'custom-css-js'), 'type' => 'radio', 'default' => 'header', 'values' => array( 'header' => array( 'title' => __('Header', 'custom-css-js'), 'dashicon' => 'arrow-up-alt2', ), 'footer' => array( 'title' => __('Footer', 'custom-css-js'), 'dashicon' => 'arrow-down-alt2', ), ), ), 'side' => array( 'title' => __('Where in site', 'custom-css-js'), 'type' => 'radio', 'default' => 'frontend', 'values' => array( 'frontend' => array( 'title' => __('In Frontend', 'custom-css-js'), 'dashicon' => 'tagcloud', ), 'admin' => array( 'title' => __('In Admin', 'custom-css-js'), 'dashicon' => 'id', ), 'login' => array( 'title' => __('On Login Page', 'custom-css-js'), 'dashicon' => 'admin-network', ), ), ), 'preprocessor' => array( 'title' => __('CSS Preprocessor', 'custom-css-js'), 'type' => 'radio', 'default' => 'none', 'values' => array( 'none' => array( 'title' => __('None', 'custom-css-js'), ), 'less' => array( 'title' => __('Less', 'custom-css-js'), ), 'sass' => array( 'title' => __('SASS (only SCSS syntax)', 'custom-css-js'), ), ), 'disabled' => true, ), 'minify' => array( 'title' => __('Minify the code', 'custom-css-js'), 'type' => 'checkbox', 'default' => false, 'dashicon' => 'editor-contract', 'disabled' => true, ), 'priority' => array( 'title' => __('Priority', 'custom-css-js'), 'type' => 'select', 'default' => 5, 'dashicon' => 'sort', 'values' => array( 1 => _x('1 (highest)', '1 is the highest priority', 'custom-css-js'), 2 => '2', 3 => '3', 4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => _x('10 (lowest)', '10 is the lowest priority', 'custom-css-js'), ), 'disabled' => true, ), ); return $options; } /** * Get an array with all the information for building the code's options */ function get_options_meta_html() { $options = array( 'type' => array( 'title' => __('Where on page', 'custom-css-js'), 'type' => 'radio', 'default' => 'header', 'values' => array( 'header' => array( 'title' => __('Header', 'custom-css-js'), 'dashicon' => 'arrow-up-alt2', ), 'footer' => array( 'title' => __('Footer', 'custom-css-js'), 'dashicon' => 'arrow-down-alt2', ), ), ), 'side' => array( 'title' => __('Where in site', 'custom-css-js'), 'type' => 'radio', 'default' => 'frontend', 'values' => array( 'frontend' => array( 'title' => __('In Frontend', 'custom-css-js'), 'dashicon' => 'tagcloud', ), 'admin' => array( 'title' => __('In Admin', 'custom-css-js'), 'dashicon' => 'id', ), ), ), 'linking' => array( 'title' => __('On which device', 'custom-css-js'), 'type' => 'radio', 'default' => 'both', 'dashicon' => '', 'values' => array( 'desktop' => array( 'title' => __('Desktop', 'custom-css-js'), 'dashicon' => 'desktop', ), 'mobile' => array( 'title' => __('Mobile', 'custom-css-js'), 'dashicon' => 'smartphone', ), 'both' => array( 'title' => __('Both', 'custom-css-js'), 'dashicon' => 'tablet', ), ), 'disabled' => true, ), 'priority' => array( 'title' => __('Priority', 'custom-css-js'), 'type' => 'select', 'default' => 5, 'dashicon' => 'sort', 'values' => array( 1 => _x('1 (highest)', '1 is the highest priority', 'custom-css-js'), 2 => '2', 3 => '3', 4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => _x('10 (lowest)', '10 is the lowest priority', 'custom-css-js'), ), 'disabled' => true, ), ); return $options; } /** * Save the post and the metadata */ function options_save_meta_box_data( $post_id ) { // The usual checks if ( ! isset( $_POST['custom-css-js_meta_box_nonce'] ) ) { return; } if ( ! wp_verify_nonce( $_POST['custom-css-js_meta_box_nonce'], 'options_save_meta_box_data' ) ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( isset( $_POST['post_type'] ) && 'custom-css-js' != $_POST['post_type'] ) { return; } // Update the post's meta $defaults = array( 'type' => 'header', 'linking' => 'internal', 'priority' => 5, 'side' => 'frontend', 'language' => 'css', ); if ( $_POST['custom_code_language'] == 'html' ) { $defaults = array( 'type' => 'header', 'linking' => 'both', 'side' => 'frontend', 'language' => 'html', 'priority' => 5, ); } foreach( $defaults as $_field => $_default ) { $options[ $_field ] = isset( $_POST['custom_code_'.$_field] ) ? esc_attr($_POST['custom_code_'.$_field]) : $_default; } update_post_meta( $post_id, 'options', $options ); if ( $options['language'] == 'html' ) { $this->build_search_tree(); return; } if ( $options['language'] == 'js' ) { // Replace the default comment if ( preg_match('@/\* Add your JavaScript code here[\s\S]*?End of comment \*/@im', $_POST['content'] ) ) { $_POST['content'] = preg_replace('@/\* Add your JavaScript code here[\s\S]*?End of comment \*/@im', '/* Default comment here */', $_POST['content']); } // For other locales remove all the comments if ( substr( get_locale(), 0, 3) !== 'en_' ) { $_POST['content'] = preg_replace('@/\*[\s\S]*?\*/@', '', $_POST['content']); } } // Save the Custom Code in a file in `wp-content/uploads/custom-css-js` if ( $options['linking'] == 'internal' ) { $before = '' . PHP_EOL; $after = '' . PHP_EOL; if ( $options['language'] == 'css' ) { $before .= '' . PHP_EOL . $after; } if ( $options['language'] == 'js' ) { if ( ! preg_match( '/' . PHP_EOL . $after; } else { // the content has a