관리-도구
편집 파일: helpers.php
<?php /** * Generic helpers used in the plugin. * * @package WPCode */ /** * Get a URL with UTM parameters. * * @param string $url The URL to add the params to. * @param string $medium The marketing medium. * @param string $campaign The campaign. * @param string $ad_content The utm_content param. * * @return string */ function wpcode_utm_url( $url, $medium = '', $campaign = '', $ad_content = '' ) { $args = array( 'utm_source' => class_exists( 'WPCode_License' ) ? 'proplugin' : 'liteplugin', 'utm_medium' => sanitize_key( $medium ), 'utm_campaign' => sanitize_key( $campaign ) ); if ( ! empty( $ad_content ) ) { $args['utm_content'] = sanitize_key( $ad_content ); } return add_query_arg( $args, $url ); } /** * Get a standard auto-insert location select menu. * * @param string $selected_location The location currently selected. * @param string $code_type The code type for the current snippet (disables some locations). * @param string $name The name for the select (used in the form). * * @return string */ function wpcode_get_auto_insert_location_picker( $selected_location, $code_type = 'html', $name = 'wpcode_auto_insert_location' ) { $available_types = wpcode()->auto_insert->get_types(); ob_start(); ?> <select name="<?php echo esc_attr( $name ); ?>" id="<?php echo esc_attr( $name ); ?>" class="wpcode-select2 wpcode-auto-insert-location-picker"> <?php foreach ( $available_types as $type ) { $options = $type->get_locations(); if ( empty( $options ) ) { continue; } $extra_data = ''; if ( ! empty( $type->upgrade_title ) ) { $extra_data = ' data-upgrade-title="' . esc_attr( $type->upgrade_title ) . '"'; } if ( ! empty( $type->upgrade_text ) ) { $extra_data .= ' data-upgrade-text="' . esc_attr( $type->upgrade_text ) . '"'; } if ( ! empty( $type->upgrade_link ) ) { $extra_data .= ' data-upgrade-link="' . esc_attr( $type->upgrade_link ) . '"'; } if ( ! empty( $type->upgrade_button ) ) { $extra_data .= ' data-upgrade-button="' . esc_attr( $type->upgrade_button ) . '"'; } ?> <optgroup label="<?php echo esc_attr( $type->get_label() ); ?>" data-code-type="<?php echo esc_attr( $type->code_type ); ?>" data-label-pill="<?php echo esc_attr( $type->label_pill ); ?>" <?php echo $extra_data; ?> > <?php foreach ( $options as $key => $location ) { $disabled = false; if ( 'all' !== $type->code_type && $type->code_type !== $code_type ) { $disabled = true; } $label = wpcode_find_location_label( $key ); ?> <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $selected_location, $key ); ?> <?php disabled( $disabled ); ?>> <?php echo esc_html( $label ); ?> </option> <?php } ?> </optgroup> <?php } ?> </select> <?php return ob_get_clean(); } /** * Get the label for an auto-insert location. * * @param $location_slug * * @return string */ function wpcode_find_location_label( $location_slug ) { $available_types = wpcode()->auto_insert->get_types(); $location_label = ''; foreach ( $available_types as $type ) { $options = $type->get_locations(); foreach ( $options as $key => $location ) { if ( $key === $location_slug ) { if ( isset( $location['label'] ) ) { $label = $location['label']; } else { $label = $location; } $location_label = $label; break 2; } } } return $location_label; } /** * Get a checkbox wrapped with markup to be displayed as a toggle. * * @param bool $checked Is it checked or not. * @param string $name The name for the input. * @param string $description Field description (optional). * @param string|int $value Field value (optional). * @param string $label Field label (optional). * * @return string */ function wpcode_get_checkbox_toggle( $checked, $name, $description = '', $value = '', $label = '' ) { $markup = '<label class="wpcode-checkbox-toggle">'; $markup .= '<input type="checkbox" ' . checked( $checked, true, false ) . ' name="' . esc_attr( $name ) . '" id="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '" />'; $markup .= '<span class="wpcode-checkbox-toggle-slider"></span>'; $markup .= '</label>'; if ( ! empty( $label ) ) { $markup .= '<label class="wpcode-checkbox-toggle-label" for="' . esc_attr( $name ) . '">' . esc_html( $label ) . '</label>'; } if ( ! empty( $description ) ) { $markup .= '<p class="description">' . wp_kses_post( $description ) . '</p>'; } return $markup; } /** * Button that copies target input value to the clipboard. * * @param string $target The id of the input to copy from. * @param string $prefix If you want something prepended to the copied value. * @param string $suffix If you want something appended to the copied value. * * @return string */ function wpcode_get_copy_target_button( $target, $prefix = '', $suffix = '' ) { return sprintf( '<button class="wpcode-button wpcode-button-icon wpcode-button-secondary wpcode-copy-target" data-target="#%4$s" type="button" data-prefix="%5$s" data-suffix="%6$s"><span class="wpcode-default-icon">%1$s</span><span class="wpcode-success-icon">%2$s</span> %3$s</button>', get_wpcode_icon( 'copy', 16, 16 ), get_wpcode_icon( 'check', 16, 13 ), _x( 'Copy', 'Copy to clipboard', 'insert-headers-and-footers' ), esc_attr( $target ), esc_attr( $prefix ), esc_attr( $suffix ) ); } /** * Get a list of labels for the conditions used in conditional logic. * * @return array */ function wpcode_get_conditions_relation_labels() { return array( 'contains' => __( 'Contains', 'insert-headers-and-footers' ), 'notcontains' => __( 'Doesn\'t Contain', 'insert-headers-and-footers' ), '=' => __( 'Is', 'insert-headers-and-footers' ), '!=' => __( 'Is not', 'insert-headers-and-footers' ), 'before' => __( 'Is Before', 'insert-headers-and-footers' ), 'after' => __( 'Is After', 'insert-headers-and-footers' ), 'before-or' => __( 'Is on or Before', 'insert-headers-and-footers' ), 'after-or' => __( 'Is on or After', 'insert-headers-and-footers' ), ); } /** * Get an array of locations that support an insert number. * * @return string[] */ function wpcode_get_auto_insert_locations_with_number() { return array( 'before_paragraph', 'after_paragraph', 'archive_before_post', 'archive_after_post', 'after_words', 'every_words', ); } /** * Returns the site domain. * * @return string */ function wpcode_get_site_domain() { return wp_parse_url( home_url(), PHP_URL_HOST ); } /** * Check WP version and include the compatible upgrader skin. */ function wpcode_require_upgrader() { global $wp_version; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // WP 5.3 changes the upgrader skin. if ( version_compare( $wp_version, '5.3', '<' ) ) { require_once WPCODE_PLUGIN_PATH . 'includes/admin/class-wpcode-skin-legacy.php'; } else { require_once WPCODE_PLUGIN_PATH . 'includes/admin/class-wpcode-skin.php'; } } /** * Get timezone string if the function doesn't exist. (WP < 5.3). * * @return string * @since 2.0.10 */ function wpcode_wp_timezone_string() { if ( function_exists( 'wp_timezone_string' ) ) { return wp_timezone_string(); } $timezone_string = get_option( 'timezone_string' ); if ( $timezone_string ) { return $timezone_string; } $offset = (float) get_option( 'gmt_offset' ); $hours = (int) $offset; $minutes = ( $offset - $hours ); $sign = ( $offset < 0 ) ? '-' : '+'; $abs_hour = abs( $hours ); $abs_mins = abs( $minutes * 60 ); $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins ); return $tz_offset; } /** * Add a new library username to be loaded in the WPCode Library. * * @param string $slug The username to load snippets for from the WPCode Library. * @param string $label The label to display for the username in the library. * @param string $version The version of the plugin/theme. Used to filter snippets that should not be loaded for newer versions. * * @return void */ function wpcode_register_library_username( $slug, $label = '', $version = '' ) { if ( ! is_admin() || ! isset( wpcode()->library ) ) { return; } wpcode()->library->register_library_username( $slug, $label, $version ); } /** * Load snippets from the library by a specific username. * This function also loads the library if it hasn't been loaded yet so that it can be used in API endpoints. * It also adds links to install snippets and checks for permissions. * * @param string $username The username to load snippets for from the WPCode Library. * * @return array */ function wpcode_get_library_snippets_by_username( $username ) { wpcode_maybe_load_library(); $snippets = wpcode()->library->get_snippets_by_username( $username ); // Let's prepare this a bit for easier output. // If there are no snippets just return an empty array. if ( empty( $snippets['snippets'] ) ) { return array(); } $can_install = current_user_can( 'wpcode_edit_snippets' ); $prepared = array(); $used_library_snippets = wpcode()->library->get_used_library_snippets(); foreach ( $snippets['snippets'] as $snippet ) { $snippet['installed'] = false; // If the user can't install snippets, don't provide an install link. if ( ! $can_install ) { $url = ''; } elseif ( ! empty( $used_library_snippets[ $snippet['library_id'] ] ) ) { // If the snippet is already installed link to the snippet so they can edit it. $snippet['installed'] = true; $url = wpcode()->library->get_edit_snippet_url( $used_library_snippets[ $snippet['library_id'] ] ); } else { // If the snippet is not yet installed, add a link to install it. $url = wpcode()->library->get_install_snippet_url( $snippet['library_id'] ); } $snippet['install'] = $url; $prepared[] = $snippet; } return $prepared; } /** * Make sure the WPCode library is loaded, along with the components it needs to run. * * @return void */ function wpcode_maybe_load_library() { if ( ! isset( wpcode()->library ) ) { // Snippet Library. require_once WPCODE_PLUGIN_PATH . 'includes/class-wpcode-library.php'; // Load components needed for the library, if not loaded. if ( ! isset( wpcode()->file_cache ) ) { // File cache. require_once WPCODE_PLUGIN_PATH . 'includes/class-wpcode-file-cache.php'; wpcode()->file_cache = new WPCode_File_Cache(); } if ( ! isset( wpcode()->library_auth ) ) { // Authentication for the library site. require_once WPCODE_PLUGIN_PATH . 'includes/class-wpcode-library-auth.php'; wpcode()->library_auth = new WPCode_Library_Auth(); } wpcode()->library = new WPCode_Library(); } } /** * Helper function for testing mode. * * @return bool */ function wpcode_testing_mode_enabled() { if ( ! class_exists( 'WPCode_Testing_Mode' ) ) { return false; } return WPCode_Testing_Mode::get_instance()->testing_mode_enabled(); } /** * Get the user's IP address. * * @return string */ function wpcode_get_user_ip() { $ip = '127.0.0.1'; $address_headers = array( 'HTTP_TRUE_CLIENT_IP', 'HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR', ); foreach ( $address_headers as $header ) { if ( empty( $_SERVER[ $header ] ) ) { continue; } /* * HTTP_X_FORWARDED_FOR can contain a chain of comma-separated addresses, with or without spaces. * The first address is the original client. It can't be trusted for authenticity, * but we don't need to for this purpose. */ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $address_chain = explode( ',', wp_unslash( $_SERVER[ $header ] ) ); $ip = filter_var( trim( $address_chain[0] ), FILTER_VALIDATE_IP ); break; } /** * Filter detected IP address. * * @param string $ip IP address. */ return filter_var( apply_filters( 'wpcode_get_user_ip', $ip ), FILTER_VALIDATE_IP ); } /** * Is the ip for a localhost. Defaults to the current user ip. * * @param string $ip The IP to check. * * @return string */ function wpcode_is_local( $ip = null ) { if ( ! $ip ) { $ip = wpcode_get_user_ip(); } return empty( $ip ) || in_array( $ip, array( '127.0.0.1', '::1' ), true ); } /** * Attempts to detect popular caching plugins and clear their cache. * * @param string $context The context in which the cache is being cleared. * * @return void */ function wpcode_clear_all_plugins_page_cache( $context = '' ) { if ( apply_filters( 'wpcode_skip_clear_all_plugins_cache', false, $context ) ) { return; } // LiteSpeed Cache. if ( function_exists( 'run_litespeed_cache' ) && class_exists( 'LiteSpeed\Purge' ) && method_exists( 'LiteSpeed\Purge', 'purge_all' ) ) { LiteSpeed\Purge::purge_all(); } // WP Super Cache. if ( function_exists( 'wp_cache_clear_cache' ) ) { wp_cache_clear_cache(); } // W3 Total Cache. if ( function_exists( 'w3tc_flush_all' ) ) { w3tc_flush_all(); } // WP-Optimize. if ( function_exists( 'WP_Optimize' ) ) { WP_Optimize()->get_page_cache()->purge(); } // WP Rocket. if ( function_exists( 'rocket_clean_domain' ) ) { rocket_clean_domain(); } // WP Fastest Cache. if ( function_exists( 'wpfc_clear_all_cache' ) ) { wpfc_clear_all_cache(); } // SiteGround Optimizer. if ( function_exists( 'sg_cachepress_purge_cache' ) ) { sg_cachepress_purge_cache(); } if ( class_exists( 'Swift_Performance_Cache' ) ) { if ( method_exists( 'Swift_Performance_Cache', 'clear_all_cache' ) ) { Swift_Performance_Cache::clear_all_cache(); } } // WP Engine. if ( class_exists( 'WpeCommon' ) ) { if ( method_exists( 'WpeCommon', 'purge_varnish_cache' ) ) { WpeCommon::purge_varnish_cache(); } } }