WINP_SNIPPETS_POST_TYPE, 'meta_query' => [ 'relation' => 'AND', [ 'key' => 'wbcr_inp_snippet_scope', 'value' => 'shortcode', ], [ 'key' => 'wbcr_inp_snippet_activate', 'value' => 1, ], ], 'post_status' => 'publish', 'numberposts' => - 1, ] ); $result = []; if ( ! empty( $snippets ) ) { foreach ( (array) $snippets as $snippet ) { $tag_names = [ 'id' ]; $snippet_type = self::get_snippet_type( $snippet->ID ); $available_tags = self::getMetaOption( $snippet->ID, 'snippet_tags' ); $available_tags = ! empty( $available_tags ) ? trim( rtrim( $available_tags ) ) : ''; if ( ! empty( $available_tags ) ) { $available_tags = array_map( 'trim', explode( ',', $available_tags ) ); $available_tags = array_unique( $available_tags ); } elseif ( $snippet_type !== 'text' && $snippet_type !== 'advert' ) { $available_tags = [ 'id', 'title' ]; } else { $available_tags = [ 'id' ]; } $tags = [ 'id' => $snippet->ID, 'type' => $snippet_type, 'name' => $snippet_type == WINP_SNIPPET_TYPE_UNIVERSAL ? 'wbcr_snippet' : 'wbcr_' . $snippet_type . '_snippet', 'title' => empty( $snippet->post_title ) ? '(no titled, ID=' . $snippet->ID . ')' : $snippet->post_title, ]; if ( ! empty( $available_tags ) ) { foreach ( (array) $available_tags as $tag ) { if ( '' != $tag ) { if ( 'title' == $tag ) { $tags['title'] = empty( $snippet->post_title ) ? '(no titled, ID=' . $snippet->ID . ')' : $snippet->post_title; $tag_names[] = 'title'; } elseif ( 'id' != $tag ) { $tag = preg_replace( '/[^a-zA-Z0-9_\x7f-\xff]/', '', $tag ); $tags[ $tag ] = ''; $tag_names[] = $tag; } } } } $tags['snippet_tags'] = $tag_names; $result[] = $tags; } } return apply_filters( 'wbcr/inp/helper/get_shortcode_data', $result, $tinymce ); } /** * Get snippet type * * @param mixed $post_id Post ID. * * @return string|false Snippet type string, or false if post is not a valid snippet post type or not found. */ public static function get_snippet_type( $post_id = null ) { global $post; $_post = $post; $snippet_type = WINP_HTTP::get( 'winp_item', WINP_SNIPPET_TYPE_PHP, 'sanitize_key' ); $get_post = WINP_HTTP::get( 'post', '' ); if ( empty( $post_id ) && ! empty( $get_post ) && ! is_array( $get_post ) ) { $post_id = esc_attr( $get_post ); } if ( ! empty( $post_id ) ) { $_post = get_post( $post_id ); // Security: Validate that the post belongs to the snippet post type // to prevent arbitrary post content execution via shortcodes. if ( empty( $_post ) || WINP_SNIPPETS_POST_TYPE !== $_post->post_type ) { return false; } } if ( ! empty( $_post ) && WINP_SNIPPETS_POST_TYPE === $_post->post_type ) { $_snippet_type = get_post_meta( $_post->ID, 'wbcr_inp_snippet_type', true ); $snippet_type = $_snippet_type ? $_snippet_type : $snippet_type; } return $snippet_type; } /** * Checks if the current request is a WP REST API request. * * Case #1: After WP_REST_Request initialisation * Case #2: Support "plain" permalink settings * Case #3: URL Path begins with wp-json/ (your REST prefix) * Also supports WP installations in subfolders * * @author matzeeable https://wordpress.stackexchange.com/questions/221202/does-something-like-is-rest-exist * @since 2.1.0 * @return boolean */ public static function doing_rest_api() { $prefix = rest_get_url_prefix(); $rest_route = WINP_HTTP::get( 'rest_route', null ); if ( defined( 'REST_REQUEST' ) && REST_REQUEST // (#1) || ! is_null( $rest_route ) // (#2) && strpos( trim( $rest_route, '\\/' ), $prefix, 0 ) === 0 ) { return true; } // (#3) $rest_url = wp_parse_url( site_url( $prefix ) ); $current_url = wp_parse_url( esc_url( add_query_arg( [] ) ) ); if ( empty( $rest_url['path'] ) || empty( $current_url['path'] ) ) { return false; } return strpos( $current_url['path'], $rest_url['path'], 0 ) === 0; } /** * @return bool * @since 2.1.0 */ public static function doing_ajax() { if ( function_exists( 'wp_doing_ajax' ) ) { return wp_doing_ajax(); } return defined( 'DOING_AJAX' ) && DOING_AJAX; } /** * @return bool * @since 2.1.0 */ public static function doing_cron() { if ( function_exists( 'wp_doing_cron' ) ) { return wp_doing_cron(); } return defined( 'DOING_CRON' ) && DOING_CRON; } /** * In the new version of the plugin, we moved the code of the snippets * from the meta data to the post table, to the post_content cell. * * If the migration was an error, we need to reliably get the * snippet code if the post_content cell is empty. * * @param WP_Post $post * * @return string snippet code * @since 2.2.1 */ public static function get_snippet_code( $post ) { if ( empty( $post->post_content ) ) { return self::getMetaOption( $post->ID, 'snippet_code' ); } return $post->post_content; } /** * Get meta option * * @param int $post_id * @param string $option_name * @param mixed $default * * @return mixed|array */ public static function getMetaOption( $post_id, $option_name, $default = null ) { $post_id = (int) $post_id; if ( ! isset( self::$meta_options[ $post_id ] ) || empty( self::$meta_options[ $post_id ] ) ) { $meta_vals = get_post_meta( $post_id, '', true ); if ( ! empty( $meta_vals ) && is_array( $meta_vals ) ) { foreach ( $meta_vals as $name => $val ) { self::$meta_options[ $post_id ][ $name ] = $val[0]; } } } return isset( self::$meta_options[ $post_id ][ 'wbcr_inp_' . $option_name ] ) ? self::$meta_options[ $post_id ][ 'wbcr_inp_' . $option_name ] : $default; } /** * Udpdate meta option * * @param int $post_id * @param string $option_name * @param mixed $option_value * * @return bool|int */ public static function updateMetaOption( $post_id, $option_name, $option_value ) { $post_id = (int) $post_id; return update_post_meta( $post_id, 'wbcr_inp_' . $option_name, $option_value ); } /** * Check capabilities for snippets post type. * * @since 2.2.0 */ public static function has_post_capabilities() { $role = get_role( 'administrator' ); if ( ! $role ) { return false; } return $role->has_cap( 'edit_' . WINP_SNIPPETS_POST_TYPE ); } /** * Set capabilities for snippets post type. * * @since 2.2.0 */ public static function set_post_capabilities() { $role = get_role( 'administrator' ); if ( ! $role ) { return false; } $role->add_cap( 'edit_' . WINP_SNIPPETS_POST_TYPE ); $role->add_cap( 'read_' . WINP_SNIPPETS_POST_TYPE ); $role->add_cap( 'delete_' . WINP_SNIPPETS_POST_TYPE ); $role->add_cap( 'edit_' . WINP_SNIPPETS_POST_TYPE . 's' ); $role->add_cap( 'edit_others_' . WINP_SNIPPETS_POST_TYPE . 's' ); $role->add_cap( 'publish_' . WINP_SNIPPETS_POST_TYPE . 's' ); $role->add_cap( 'read_private_' . WINP_SNIPPETS_POST_TYPE . 's' ); return true; } /** * Create a demo snippets with examples of use */ public static function create_demo_snippets() { update_option( 'wbcr_inp_activate_by_default', 1 ); update_option( 'wbcr_inp_complete_uninstall', 0 ); update_option( 'wbcr_inp_code_editor_theme', 'default' ); update_option( 'wbcr_inp_code_editor_indent_with_tabs', 1 ); update_option( 'wbcr_inp_code_editor_tab_size', 4 ); update_option( 'wbcr_inp_code_editor_indent_unit', 4 ); update_option( 'wbcr_inp_code_editor_wrap_lines', 1 ); update_option( 'wbcr_inp_code_editor_line_numbers', 1 ); update_option( 'wbcr_inp_code_editor_auto_close_brackets', 1 ); update_option( 'wbcr_inp_code_editor_highlight_selection_matches', 0 ); $posts = [ [ 'post_title' => __( 'Simple universal snippet: Google analytics tracking', 'insert-php' ), 'post_name' => 'simple-universal-snippet', 'post_content' => self::get_simple_universal_snippet(), 'meta' => [ 'type' => WINP_SNIPPET_TYPE_UNIVERSAL, 'description' => __( 'Google analytics tracking code will be added to all pages before the </head> tag. Please remember to set the Tracking ID before activating the snippet.', 'insert-php' ), 'filters' => 'a:1:{i:0;O:8:"stdClass":2:{s:10:"conditions";a:1:{i:0;O:8:"stdClass":2:{s:4:"type";s:5:"scope";s:10:"conditions";a:1:{i:0;O:8:"stdClass":4:{s:5:"param";s:18:"location-some-page";s:8:"operator";s:6:"equals";s:4:"type";s:6:"select";s:5:"value";s:8:"base_web";}}}}s:4:"type";s:6:"showif";}}', 'tags' => [ 'universal', 'tracking' ], 'priority' => 10, ], ], [ 'post_title' => __( 'Simple text snippet: What is Lorem Ipsum?', 'insert-php' ), 'post_name' => 'simple-text-snippet', 'post_content' => self::get_simple_text_snippet(), 'meta' => [ 'type' => WINP_SNIPPET_TYPE_TEXT, 'description' => __( 'This is ordinary maintenance text. With this snippet, you can fill your pages with meaningless English text.', 'insert-php' ), 'filters' => 'a:1:{i:0;O:8:"stdClass":2:{s:10:"conditions";a:2:{i:0;O:8:"stdClass":2:{s:4:"type";s:5:"scope";s:10:"conditions";a:1:{i:0;O:8:"stdClass":4:{s:5:"param";s:18:"location-some-page";s:8:"operator";s:6:"equals";s:4:"type";s:6:"select";s:5:"value";s:9:"base_sing";}}}i:1;O:8:"stdClass":2:{s:4:"type";s:5:"scope";s:10:"conditions";a:2:{i:0;O:8:"stdClass":4:{s:5:"param";s:18:"location-post-type";s:8:"operator";s:6:"equals";s:4:"type";s:6:"select";s:5:"value";s:4:"post";}i:1;O:8:"stdClass":4:{s:5:"param";s:18:"location-post-type";s:8:"operator";s:6:"equals";s:4:"type";s:6:"select";s:5:"value";s:4:"page";}}}}s:4:"type";s:6:"showif";}}', 'tags' => [ 'text', 'lorem ipsum' ], 'priority' => 20, ], ], [ 'post_title' => __( 'Simple php snippet: Disable emojis', 'insert-php' ), 'post_name' => 'simple-php-snippet', 'post_content' => self::get_simple_php_snippet(), 'meta' => [ 'type' => WINP_SNIPPET_TYPE_PHP, 'description' => __( 'Emojis are little icons used to express ideas or emotions. While these icons are useful, they may not be necessary for your WordPress site. Use this snippet to disable emojis on your site and make it faster.', 'insert-php' ), 'tags' => [ 'php', 'disable features' ], 'priority' => 30, ], ], [ 'post_title' => __( 'Add Facebook Pixel to the Order success page', 'insert-php' ), 'post_name' => 'simple-uni-snippet-for-woocommerce', 'post_content' => self::get_woo_snippet(), 'meta' => [ 'type' => WINP_SNIPPET_TYPE_UNIVERSAL, 'description' => __( 'Add Facebook Pixel to the Order success page.', 'insert-php' ), 'filters' => 'a:1:{i:0;O:8:"stdClass":2:{s:10:"conditions";a:1:{i:0;O:8:"stdClass":2:{s:4:"type";s:5:"scope";s:10:"conditions";a:1:{i:0;O:8:"stdClass":4:{s:5:"param";s:18:"location-some-page";s:8:"operator";s:6:"equals";s:4:"type";s:6:"select";s:5:"value";s:16:"woo_checkout_pay";}}}}s:4:"type";s:6:"showif";}}', 'tags' => [ 'woocommerce' ], 'priority' => 40, ], ], ]; foreach ( $posts as $post ) { // '@' here is to hide unexpected output while plugin activation $post_id = @wp_insert_post( [ 'post_content' => $post['post_content'], 'post_title' => $post['post_title'], 'post_status' => 'publish', 'post_type' => WINP_SNIPPETS_POST_TYPE, ] ); if ( ! is_wp_error( $post_id ) ) { if ( isset( $post['meta']['type'] ) ) { self::updateMetaOption( $post_id, 'snippet_type', $post['meta']['type'] ); if ( $post['meta']['type'] == WINP_SNIPPET_TYPE_PHP ) { self::updateMetaOption( $post_id, 'snippet_scope', 'evrywhere' ); } if ( $post['meta']['type'] == WINP_SNIPPET_TYPE_TEXT ) { self::updateMetaOption( $post_id, 'snippet_scope', 'shortcode' ); } if ( $post['meta']['type'] == WINP_SNIPPET_TYPE_UNIVERSAL ) { self::updateMetaOption( $post_id, 'snippet_scope', 'auto' ); self::updateMetaOption( $post_id, 'snippet_location', 'header' ); } } if ( isset( $post['meta']['description'] ) ) { self::updateMetaOption( $post_id, 'snippet_description', $post['meta']['description'] ); } if ( isset( $post['meta']['filters'] ) && is_serialized( $post['meta']['filters'] ) ) { $unserialized_filters = unserialize( $post['meta']['filters'] ); self::updateMetaOption( $post_id, 'snippet_filters', $unserialized_filters ); self::updateMetaOption( $post_id, 'changed_filters', 1 ); } if ( isset( $post['meta']['tags'] ) && ! empty( $post['meta']['tags'] ) ) { if ( ! taxonomy_exists( WINP_SNIPPETS_TAXONOMY ) ) { register_taxonomy( WINP_SNIPPETS_TAXONOMY, WINP_SNIPPETS_POST_TYPE, [] ); } wp_set_post_terms( $post_id, $post['meta']['tags'], WINP_SNIPPETS_TAXONOMY, true ); } if ( isset( $post['meta']['priority'] ) ) { self::updateMetaOption( $post_id, 'snippet_priority', $post['meta']['priority'] ); } } } update_option( 'wbcr_inp_demo_snippets_created', 1 ); } /** * Returns an example php snippet content * * @return string */ protected static function get_simple_php_snippet() { $output = '/**' . PHP_EOL; $output .= '* Disable WP 4.2 emoji' . PHP_EOL; $output .= '*/' . PHP_EOL; $output .= 'function ace_remove_emoji() {' . PHP_EOL; $output .= "\tadd_filter( 'emoji_svg_url', '__return_false' );" . PHP_EOL; $output .= "\tremove_action( 'admin_print_styles', 'print_emoji_styles' );" . PHP_EOL; $output .= "\tremove_action( 'wp_head', 'print_emoji_detection_script', 7 );" . PHP_EOL; $output .= "\tremove_action( 'admin_print_scripts', 'print_emoji_detection_script' );" . PHP_EOL; $output .= "\tremove_action( 'wp_print_styles', 'print_emoji_styles' );" . PHP_EOL; $output .= "\tremove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );" . PHP_EOL; $output .= "\tremove_filter( 'the_content_feed', 'wp_staticize_emoji' );" . PHP_EOL; $output .= "\tremove_filter( 'comment_text_rss', 'wp_staticize_emoji' );" . PHP_EOL; $output .= "\t// filter to remove TinyMCE emojis" . PHP_EOL; $output .= "\tadd_filter( 'tiny_mce_plugins', 'ace_disable_emoji_tinymce' );" . PHP_EOL; $output .= '}' . PHP_EOL; $output .= "add_action( 'init', 'ace_remove_emoji' );" . PHP_EOL; $output .= '/**' . PHP_EOL; $output .= '* Remove tinyMCE emoji' . PHP_EOL; $output .= '*/' . PHP_EOL; $output .= 'function ace_disable_emoji_tinymce( $plugins ) {' . PHP_EOL; $output .= "\tunset( \$plugins['wpemoji'] );" . PHP_EOL; $output .= "\treturn \$plugins;" . PHP_EOL; $output .= '}' . PHP_EOL; return $output; } /** * Returns an example of the content of a text snippet. * * @return string */ protected static function get_simple_text_snippet() { $output = '