File manager - Edit - /home/theblueo/tv/fb4e3b/frontend.tar
Back
frontend-filters.php 0000666 00000032601 15213274706 0010557 0 ustar 00 <?php /** * Filters content by language on frontend * * @since 1.2 */ class PLL_Frontend_Filters extends PLL_Filters { /** * Constructor: setups filters and actions * * @since 1.2 * * @param object $polylang */ public function __construct( &$polylang ) { parent::__construct( $polylang ); // Filters the WordPress locale add_filter( 'locale', array( $this, 'get_locale' ) ); // Filter sticky posts by current language add_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) ); // Adds cache domain when querying terms add_filter( 'get_terms_args', array( $this, 'get_terms_args' ) ); // Filters categories and post tags by language add_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10, 3 ); // Rewrites archives, next and previous post links to filter them by language add_filter( 'getarchives_join', array( $this, 'getarchives_join' ), 10, 2 ); add_filter( 'getarchives_where', array( $this, 'getarchives_where' ), 10, 2 ); add_filter( 'get_previous_post_join', array( $this, 'posts_join' ), 10, 5 ); add_filter( 'get_next_post_join', array( $this, 'posts_join' ), 10, 5 ); add_filter( 'get_previous_post_where', array( $this, 'posts_where' ), 10, 5 ); add_filter( 'get_next_post_where', array( $this, 'posts_where' ), 10, 5 ); // Filters the widgets according to the current language add_filter( 'widget_display_callback', array( $this, 'widget_display_callback' ), 10, 2 ); add_filter( 'sidebars_widgets', array( $this, 'sidebars_widgets' ) ); if ( $this->options['media_support'] ) { foreach ( array( 'audio', 'image', 'video' ) as $media ) { add_filter( "widget_media_{$media}_instance", array( $this, 'widget_media_instance' ), 1 ); // Since WP 4.8 } } // Strings translation ( must be applied before WordPress applies its default formatting filters ) foreach ( array( 'widget_text', 'widget_title', 'option_blogname', 'option_blogdescription', 'option_date_format', 'option_time_format' ) as $filter ) { add_filter( $filter, 'pll__', 1 ); } // Translates biography add_filter( 'get_user_metadata', array( $this, 'get_user_metadata' ), 10, 4 ); // Set posts and terms language when created from frontend ( ex with P2 theme ) add_action( 'save_post', array( $this, 'save_post' ), 200, 2 ); add_action( 'create_term', array( $this, 'save_term' ), 10, 3 ); add_action( 'edit_term', array( $this, 'save_term' ), 10, 3 ); if ( $this->options['media_support'] ) { add_action( 'add_attachment', array( $this, 'set_default_language' ) ); } // Support theme customizer // FIXME of course does not work if 'transport' is set to 'postMessage' if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { add_filter( 'pre_option_blogname', 'pll__', 20 ); add_filter( 'pre_option_blogdescription', 'pll__', 20 ); } } /** * Returns the locale based on current language * * @since 0.1 * * @param string $locale * @return string */ public function get_locale( $locale ) { return $this->curlang->locale; } /** * Filters sticky posts by current language * * @since 0.8 * * @param array $posts list of sticky posts ids * @return array modified list of sticky posts ids */ public function option_sticky_posts( $posts ) { global $wpdb; if ( $this->curlang && ! empty( $posts ) ) { $_posts = wp_cache_get( 'sticky_posts', 'options' ); // This option is usually cached in 'all_options' by WP if ( empty( $_posts ) || ! is_array( $_posts[ $this->curlang->term_taxonomy_id ] ) ) { $posts = array_map( 'intval', $posts ); $posts = implode( ',', $posts ); $languages = $this->model->get_languages_list( array( 'fields' => 'term_taxonomy_id' ) ); $_posts = array_fill_keys( $languages, array() ); // Init with empty arrays $languages = implode( ',', $languages ); $relations = $wpdb->get_results( "SELECT object_id, term_taxonomy_id FROM {$wpdb->term_relationships} WHERE object_id IN ({$posts}) AND term_taxonomy_id IN ({$languages})" ); foreach ( $relations as $relation ) { $_posts[ $relation->term_taxonomy_id ][] = $relation->object_id; } wp_cache_add( 'sticky_posts', $_posts, 'options' ); } $posts = $_posts[ $this->curlang->term_taxonomy_id ]; } return $posts; } /** * Adds language dependent cache domain when querying terms * useful as the 'lang' parameter is not included in cache key by WordPress * * @since 1.3 * * @param array $args * @return array */ public function get_terms_args( $args ) { $lang = isset( $args['lang'] ) ? $args['lang'] : $this->curlang->slug; $key = '_' . ( is_array( $lang ) ? implode( ',', $lang ) : $lang ); $args['cache_domain'] = empty( $args['cache_domain'] ) ? 'pll' . $key : $args['cache_domain'] . $key; return $args; } /** * Filters categories and post tags by language when needed * * @since 0.2 * * @param array $clauses sql clauses * @param array $taxonomies * @param array $args get_terms arguments * @return array modified sql clauses */ public function terms_clauses( $clauses, $taxonomies, $args ) { // Does nothing except on taxonomies which are filterable // Since WP 4.7, make sure not to filter wp_get_object_terms() if ( ! $this->model->is_translated_taxonomy( $taxonomies ) || ! empty( $args['object_ids'] ) ) { return $clauses; } // Adds our clauses to filter by language return $this->model->terms_clauses( $clauses, isset( $args['lang'] ) ? $args['lang'] : $this->curlang ); } /** * Modifies the sql request for wp_get_archives to filter by the current language * * @since 1.9 * * @param string $sql JOIN clause * @param array $r wp_get_archives arguments * @return string modified JOIN clause */ public function getarchives_join( $sql, $r ) { return ! empty( $r['post_type'] ) && $this->model->is_translated_post_type( $r['post_type'] ) ? $sql . $this->model->post->join_clause() : $sql; } /** * Modifies the sql request for wp_get_archives to filter by the current language * * @since 1.9 * * @param string $sql WHERE clause * @param array $r wp_get_archives arguments * @return string modified WHERE clause */ public function getarchives_where( $sql, $r ) { return ! empty( $r['post_type'] ) && $this->model->is_translated_post_type( $r['post_type'] ) ? $sql . $this->model->post->where_clause( $this->curlang ) : $sql; } /** * Modifies the sql request for get_adjacent_post to filter by the current language * * @since 0.1 * * @param string $sql The JOIN clause in the SQL. * @param bool $in_same_term Whether post should be in a same taxonomy term. * @param array $excluded_terms Array of excluded term IDs. * @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true. * @param WP_Post $post WP_Post object. * @return string modified JOIN clause */ public function posts_join( $sql, $in_same_term, $excluded_terms, $taxonomy = '', $post = null ) { return $this->model->is_translated_post_type( $post->post_type ) ? $sql . $this->model->post->join_clause( 'p' ) : $sql; } /** * Modifies the sql request for wp_get_archives and get_adjacent_post to filter by the current language * * @since 0.1 * * @param string $sql The WHERE clause in the SQL. * @param bool $in_same_term Whether post should be in a same taxonomy term. * @param array $excluded_terms Array of excluded term IDs. * @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true. * @param WP_Post $post WP_Post object. * @return string modified WHERE clause */ public function posts_where( $sql, $in_same_term, $excluded_terms, $taxonomy = '', $post = null ) { return $this->model->is_translated_post_type( $post->post_type ) ? $sql . $this->model->post->where_clause( $this->curlang ) : $sql; } /** * Filters the widgets according to the current language * Don't display if a language filter is set and this is not the current one * * @since 0.3 * * @param array $instance widget settings * @param object $widget WP_Widget object * @return bool|array false if we hide the widget, unmodified $instance otherwise */ public function widget_display_callback( $instance, $widget ) { return ! empty( $instance['pll_lang'] ) && $instance['pll_lang'] != $this->curlang->slug ? false : $instance; } /** * Remove widgets from sidebars if they are not visible in the current language * Needed to allow is_active_sidebar() to return false if all widgets are not for the current language. See #54 * * @since 2.1 * * @param array $sidebars_widgets An associative array of sidebars and their widgets * @return array */ public function sidebars_widgets( $sidebars_widgets ) { global $wp_registered_widgets; foreach ( $sidebars_widgets as $sidebar => $widgets ) { if ( 'wp_inactive_widgets' == $sidebar || empty( $widgets ) ) { continue; } foreach ( $widgets as $key => $widget ) { // Nothing can be done if the widget is created using pre WP2.8 API :( // There is no object, so we can't access it to get the widget options if ( ! isset( $wp_registered_widgets[ $widget ]['callback'] ) || ! is_array( $wp_registered_widgets[ $widget ]['callback'] ) || ! isset( $wp_registered_widgets[ $widget ]['callback'][0] ) || ! is_object( $wp_registered_widgets[ $widget ]['callback'][0] ) || ! method_exists( $wp_registered_widgets[ $widget ]['callback'][0], 'get_settings' ) ) { continue; } $widget_settings = $wp_registered_widgets[ $widget ]['callback'][0]->get_settings(); $number = $wp_registered_widgets[ $widget ]['params'][0]['number']; // Remove the widget if not visible in the current language if ( ! empty( $widget_settings[ $number ]['pll_lang'] ) && $widget_settings[ $number ]['pll_lang'] !== $this->curlang->slug ) { unset( $sidebars_widgets[ $sidebar ][ $key ] ); } } } return $sidebars_widgets; } /** * Translates media in media widgets * * @since 2.1.5 * * @param array $instance Widget instance data * @return array */ public function widget_media_instance( $instance ) { if ( empty( $instance['pll_lang'] ) && $instance['attachment_id'] && $tr_id = pll_get_post( $instance['attachment_id'] ) ) { $instance['attachment_id'] = $tr_id; $attachment = get_post( $tr_id ); if ( $instance['caption'] && ! empty( $attachment->post_excerpt ) ) { $instance['caption'] = $attachment->post_excerpt; } if ( $instance['alt'] && $alt_text = get_post_meta( $tr_id, '_wp_attachment_image_alt', true ) ) { $instance['alt'] = $alt_text; } if ( $instance['image_title'] && ! empty( $attachment->post_title ) ) { $instance['image_title'] = $attachment->post_title; } } return $instance; } /** * Translates biography * Makes sure that the correct locale is used for ajax calls when the user is logged in * * @since 0.9 * * @param null $return * @param int $id User id * @param string $meta_key * @param bool $single Whether to return only the first value of the specified $meta_key * @return null|string */ public function get_user_metadata( $return, $id, $meta_key, $single ) { switch ( $meta_key ) { case 'description': if ( $this->curlang->slug !== $this->options['default_lang'] ) { $return = get_user_meta( $id, 'description_' . $this->curlang->slug, $single ); } break; case 'locale': if ( Polylang::is_ajax_on_front() ) { $return = get_locale(); } break; } return $return; } /** * Allows to set a language by default for posts if it has no language yet * * @since 1.5.4 * * @param int $post_id */ public function set_default_language( $post_id ) { if ( ! $this->model->post->get_language( $post_id ) ) { if ( isset( $_REQUEST['lang'] ) ) { $this->model->post->set_language( $post_id, $_REQUEST['lang'] ); } elseif ( ( $parent_id = wp_get_post_parent_id( $post_id ) ) && $parent_lang = $this->model->post->get_language( $parent_id ) ) { $this->model->post->set_language( $post_id, $parent_lang ); } else { $this->model->post->set_language( $post_id, $this->curlang ); } } } /** * Called when a post ( or page ) is saved, published or updated * Does nothing except on post types which are filterable * Sets the language but does not allow to modify it * * @since 1.1 * * @param int $post_id * @param object $post */ public function save_post( $post_id, $post ) { if ( $this->model->is_translated_post_type( $post->post_type ) ) { $this->set_default_language( $post_id ); } } /** * Called when a category or post tag is created or edited * Does nothing except on taxonomies which are filterable * Sets the language but does not allow to modify it * * @since 1.1 * * @param int $term_id * @param int $tt_id Term taxonomy id * @param string $taxonomy */ public function save_term( $term_id, $tt_id, $taxonomy ) { if ( $this->model->is_translated_taxonomy( $taxonomy ) && ! $this->model->term->get_language( $term_id ) ) { if ( isset( $_REQUEST['lang'] ) ) { $this->model->term->set_language( $term_id, $_REQUEST['lang'] ); } elseif ( ( $term = get_term( $term_id, $taxonomy ) ) && ! empty( $term->parent ) && $parent_lang = $this->model->term->get_language( $term->parent ) ) { $this->model->term->set_language( $term_id, $parent_lang ); } else { $this->model->term->set_language( $term_id, $this->curlang ); } } } } choose-lang-domain.php 0000666 00000001375 15213274706 0010742 0 ustar 00 <?php /** * Choose the language when the language is managed by different domains * * @since 1.5 */ class PLL_Choose_Lang_Domain extends PLL_Choose_Lang_Url { /** * don't set any language cookie * * @since 1.5 */ public function maybe_setcookie() {} /** * don't redirect according to browser preferences * * @since 1.5 */ public function get_preferred_language() { return $this->model->get_language( $this->links_model->get_language_from_url() ); } /** * Adds query vars to query for home pages in all languages * * @since 1.5 */ public function home_requested() { $this->set_curlang_in_query( $GLOBALS['wp_query'] ); /** This action is documented in include/choose-lang.php */ do_action( 'pll_home_requested' ); } } choose-lang-content.php 0000666 00000010616 15213274706 0011143 0 ustar 00 <?php /** * Choose the language when it is set from content * The language is set either in parse_query with priority 2 or in wp with priority 5 * * @since 1.2 */ class PLL_Choose_Lang_Content extends PLL_Choose_lang { /** * defers the language choice to the 'wp' action (when the content is known) * * @since 1.8 */ public function init() { parent::init(); if ( ! did_action( 'pll_language_defined' ) ) { // set the languages from content add_action( 'wp', array( $this, 'wp' ), 5 ); // priority 5 for post types and taxonomies registered in wp hook with default priority // if no language found, choose the preferred one add_filter( 'pll_get_current_language', array( $this, 'pll_get_current_language' ) ); } } /** * overwrites parent::set_language to remove the 'wp' action if the language is set before * * @since 1.2 * * @param object $curlang current language */ protected function set_language( $curlang ) { parent::set_language( $curlang ); remove_action( 'wp', array( $this, 'wp' ), 5 ); // won't attempt to set the language a 2nd time } /** * returns the language based on the queried content * * @since 1.2 * * @return object|bool detected language, false if none was found */ protected function get_language_from_content() { // no language set for 404 if ( is_404() || ( is_attachment() && ! $this->options['media_support'] ) ) { return $this->get_preferred_language(); } if ( $var = get_query_var( 'lang' ) ) { $lang = explode( ',',$var ); $lang = $this->model->get_language( reset( $lang ) ); // choose the first queried language } elseif ( ( is_single() || is_page() || ( is_attachment() && $this->options['media_support'] ) ) && ( ( $var = get_queried_object_id() ) || ( $var = get_query_var( 'p' ) ) || ( $var = get_query_var( 'page_id' ) ) || ( $var = get_query_var( 'attachment_id' ) ) ) ) { $lang = $this->model->post->get_language( $var ); } else { foreach ( $this->model->get_translated_taxonomies() as $taxonomy ) { if ( $var = get_query_var( get_taxonomy( $taxonomy )->query_var ) ) { $lang = $this->model->term->get_language( $var, $taxonomy ); } } } /** * Filter the language before it is set from the content * * @since 0.9 * * @param bool|object $lang language object or false if none was found */ return apply_filters( 'pll_get_current_language', isset( $lang ) ? $lang : false ); } /** * sets the language for home page * add the lang query var when querying archives with no language code * * @since 1.2 * * @param object $query instance of WP_Query */ public function parse_main_query( $query ) { if ( $query !== $GLOBALS['wp_the_query'] ) { return; } $qv = $query->query_vars; // homepage is requested, let's set the language // take care to avoid posts page for which is_home = 1 if ( empty( $query->query ) && ( is_home() || is_page() ) ) { $this->home_language(); $this->home_requested(); } parent::parse_main_query( $query ); $is_archive = ( count( $query->query ) == 1 && ! empty( $qv['paged'] ) ) || $query->is_date || $query->is_author || ( ! empty( $qv['post_type'] ) && $query->is_post_type_archive && $this->model->is_translated_post_type( $qv['post_type'] ) ); // sets the language in case we hide the default language // use $query->query['s'] as is_search is not set when search is empty // http://wordpress.org/support/topic/search-for-empty-string-in-default-language if ( $this->options['hide_default'] && ! isset( $qv['lang'] ) && ( $is_archive || isset( $query->query['s'] ) || ( count( $query->query ) == 1 && ! empty( $qv['feed'] ) ) ) ) { $this->set_language( $this->model->get_language( $this->options['default_lang'] ) ); $this->set_curlang_in_query( $query ); } } /** * sets the language from content * * @since 1.2 */ public function wp() { // nothing to do if the language has already been set ( although normally the filter has been removed ) if ( ! $this->curlang && $curlang = $this->get_language_from_content() ) { parent::set_language( $curlang ); } } /** * if no language found by get_language_from_content, return the preferred one * * @since 0.9 * * @param object|bool $lang Language found in get_language_from_content * @return object Language */ public function pll_get_current_language( $lang ) { return ! $lang ? $this->get_preferred_language() : $lang; } } frontend-filters-links.php 0000666 00000032255 15213274706 0011702 0 ustar 00 <?php /** * Manages links filters on frontend * * @since 1.8 */ class PLL_Frontend_Filters_Links extends PLL_Filters_Links { public $cache; // Our internal non persistent cache object /** * Constructor * Adds filters once the language is defined * Low priority on links filters to come after any other modification * * @since 1.8 * * @param object $polylang */ public function __construct( &$polylang ) { parent::__construct( $polylang ); $this->curlang = &$polylang->curlang; $this->cache = new PLL_Cache(); // Rewrites author and date links to filter them by language foreach ( array( 'feed_link', 'author_link', 'search_link', 'year_link', 'month_link', 'day_link' ) as $filter ) { add_filter( $filter, array( $this, 'archive_link' ), 20 ); } // Meta in the html head section add_action( 'wp_head', array( $this, 'wp_head' ) ); // Modifies the home url if ( ! defined( 'PLL_FILTER_HOME_URL' ) || PLL_FILTER_HOME_URL ) { add_filter( 'home_url', array( $this, 'home_url' ), 10, 2 ); } if ( $this->options['force_lang'] > 1 ) { // Rewrites next and previous post links when not automatically done by WordPress add_filter( 'get_pagenum_link', array( $this, 'archive_link' ), 20 ); // Rewrites ajax url add_filter( 'admin_url', array( $this, 'admin_url' ), 10, 2 ); } // Redirects to canonical url before WordPress redirect_canonical // but after Nextgen Gallery which hacks $_SERVER['REQUEST_URI'] !!! and restores it in 'template_redirect' with priority 1 add_action( 'template_redirect', array( $this, 'check_canonical_url' ), 4 ); } /** * Modifies the author and date links to add the language parameter ( as well as feed link ) * * @since 0.4 * * @param string $link * @return string modified link */ public function archive_link( $link ) { return $this->links_model->switch_language_in_link( $link, $this->curlang ); } /** * Modifies page links * and caches the result * * @since 1.7 * * @param string $link post link * @param int $post_id post ID * @return string modified post link */ public function _get_page_link( $link, $post_id ) { $sample = false !== strpos( $link, '%pagename%' ); // To avoid a conflict with plugin Custom Permalinks $cache_key = "post:{$post_id}:{$sample}"; if ( false === $_link = $this->cache->get( $cache_key ) ) { $_link = parent::_get_page_link( $link, $post_id ); $this->cache->set( $cache_key, $_link ); } return $_link; } /** * Modifies attachment links * and caches the result * * @since 1.6.2 * * @param string $link attachment link * @param int $post_id attachment link * @return string modified attachment link */ public function attachment_link( $link, $post_id ) { $cache_key = 'post:' . $post_id; if ( false === $_link = $this->cache->get( $cache_key ) ) { $_link = parent::attachment_link( $link, $post_id ); $this->cache->set( $cache_key, $_link ); } return $_link; } /** * Modifies custom posts links * and caches the result * * @since 1.6 * * @param string $link post link * @param object $post post object * @return string modified post link */ public function post_type_link( $link, $post ) { $sample = false !== strpos( $link, '%postname%' ); // To avoid a conflict with plugin Custom Permalinks $cache_key = "post:{$post->ID}:{$sample}"; if ( false === $_link = $this->cache->get( $cache_key ) ) { $_link = parent::post_type_link( $link, $post ); $this->cache->set( $cache_key, $_link ); } return $_link; } /** * Modifies filtered taxonomies ( post format like ) and translated taxonomies links * and caches the result * * @since 0.7 * * @param string $link * @param object $term term object * @param string $tax taxonomy name * @return string modified link */ public function term_link( $link, $term, $tax ) { $cache_key = 'term:' . $term->term_id; if ( false === $_link = $this->cache->get( $cache_key ) ) { if ( in_array( $tax, $this->model->get_filtered_taxonomies() ) ) { $_link = $this->links_model->switch_language_in_link( $link, $this->curlang ); /** This filter is documented in include/filters-links.php */ $_link = apply_filters( 'pll_term_link', $_link, $this->curlang, $term ); } else { $_link = parent::term_link( $link, $term, $tax ); } $this->cache->set( $cache_key, $_link ); } return $_link; } /** * Outputs references to translated pages ( if exists ) in the html head section * * @since 0.1 */ public function wp_head() { // Don't output anything on paged archives: see https://wordpress.org/support/topic/hreflang-on-page2 // Don't output anything on paged pages and paged posts if ( is_paged() || ( is_singular() && ( $page = get_query_var( 'page' ) ) && $page > 1 ) ) { return; } // Google recommends to include self link https://support.google.com/webmasters/answer/189077?hl=en foreach ( $this->model->get_languages_list() as $language ) { if ( $url = $this->links->get_translation_url( $language ) ) { $urls[ $language->get_locale( 'display' ) ] = $url; } } // Ouptputs the section only if there are translations ( $urls always contains self link ) if ( ! empty( $urls ) && count( $urls ) > 1 ) { // Prepare the list of languages to remove the country code foreach ( array_keys( $urls ) as $locale ) { $split = explode( '-', $locale ); $languages[ $locale ] = reset( $split ); } $count = array_count_values( $languages ); foreach ( $urls as $locale => $url ) { $lang = $count[ $languages[ $locale ] ] > 1 ? $locale : $languages[ $locale ]; // Output the country code only when necessary $hreflangs[ $lang ] = $url; } // Adds the site root url when the default language code is not hidden // See https://wordpress.org/support/topic/implementation-of-hreflangx-default if ( is_front_page() && ! $this->options['hide_default'] && $this->options['force_lang'] < 3 ) { $hreflangs['x-default'] = home_url( '/' ); } /** * Filters the list of rel hreflang attributes * * @since 2.1 * * @param array $hreflangs Array of urls with language codes as keys */ $hreflangs = apply_filters( 'pll_rel_hreflang_attributes', $hreflangs ); foreach ( $hreflangs as $lang => $url ) { printf( '<link rel="alternate" href="%s" hreflang="%s" />' . "\n", esc_url( $url ), esc_attr( $lang ) ); } } } /** * Filters the home url to get the right language * * @since 0.4 * * @param string $url * @param string $path * @return string */ public function home_url( $url, $path ) { if ( ! ( did_action( 'template_redirect' ) || did_action( 'login_init' ) ) || rtrim( $url,'/' ) != $this->links_model->home ) { return $url; } static $white_list, $black_list; // Avoid evaluating this at each function call // We *want* to filter the home url in these cases if ( empty( $white_list ) ) { // On Windows get_theme_root() mixes / and \ // We want only \ for the comparison with debug_backtrace $theme_root = get_theme_root(); $theme_root = ( false === strpos( $theme_root, '\\' ) ) ? $theme_root : str_replace( '/', '\\', $theme_root ); /** * Filter the white list of the Polylang 'home_url' filter * The $args contains an array of arrays each of them having * a 'file' key and/or a 'function' key to decide which functions in * which files using home_url() calls must be filtered * * @since 1.1.2 * * @param array $args */ $white_list = apply_filters( 'pll_home_url_white_list', array( array( 'file' => $theme_root ), array( 'function' => 'wp_nav_menu' ), array( 'function' => 'login_footer' ), array( 'function' => 'get_custom_logo' ), ) ); } // We don't want to filter the home url in these cases if ( empty( $black_list ) ) { /** * Filter the black list of the Polylang 'home_url' filter * The $args contains an array of arrays each of them having * a 'file' key and/or a 'function' key to decide which functions in * which files using home_url() calls must be filtered * * @since 1.1.2 * * @param array $args */ $black_list = apply_filters( 'pll_home_url_black_list', array( array( 'file' => 'searchform.php' ), // Since WP 3.6 searchform.php is passed through get_search_form array( 'function' => 'get_search_form' ), ) ); } $traces = version_compare( PHP_VERSION, '5.2.5', '>=' ) ? debug_backtrace( false ) : debug_backtrace(); unset( $traces[0], $traces[1] ); // We don't need the last 2 calls: this function + call_user_func_array (or apply_filters on PHP7+) foreach ( $traces as $trace ) { // Black list first foreach ( $black_list as $v ) { if ( ( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) ) || ( isset( $trace['function'], $v['function'] ) && $trace['function'] == $v['function'] ) ) { return $url; } } foreach ( $white_list as $v ) { if ( ( isset( $trace['function'], $v['function'] ) && $trace['function'] == $v['function'] ) || ( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) && in_array( $trace['function'], array( 'home_url', 'get_home_url', 'bloginfo', 'get_bloginfo' ) ) ) ) { $ok = true; } } } return empty( $ok ) ? $url : ( empty( $path ) ? rtrim( $this->links->get_home_url( $this->curlang ), '/' ) : $this->links->get_home_url( $this->curlang ) ); } /** * Rewrites ajax url when using domains or subdomains * * @since 1.5 * * @param string $url admin url with path evaluated by WordPress * @param string $path admin path * @return string */ public function admin_url( $url, $path ) { return 'admin-ajax.php' === $path ? $this->links_model->switch_language_in_link( $url, $this->curlang ) : $url; } /** * If the language code is not in agreement with the language of the content * redirects incoming links to the proper URL to avoid duplicate content * * @since 0.9.6 * * @param string $requested_url optional * @param bool $do_redirect optional, whether to perform the redirection or not * @return string if redirect is not performed */ public function check_canonical_url( $requested_url = '', $do_redirect = true ) { global $wp_query, $post, $is_IIS; // Don't redirect in same cases as WP if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $is_IIS && ! iis7_supports_permalinks() ) ) { return; } // Don't redirect mysite.com/?attachment_id= to mysite.com/en/?attachment_id= if ( 1 == $this->options['force_lang'] && is_attachment() && isset( $_GET['attachment_id'] ) ) { return; } // If the default language code is not hidden and the static front page url contains the page name // the customizer lands here and the code below would redirect to the list of posts if ( is_customize_preview() ) { return; } if ( empty( $requested_url ) ) { $requested_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } if ( is_single() || is_page() ) { if ( isset( $post->ID ) && $this->model->is_translated_post_type( $post->post_type ) ) { $language = $this->model->post->get_language( (int) $post->ID ); } } elseif ( is_category() || is_tag() || is_tax() ) { $obj = $wp_query->get_queried_object(); if ( $this->model->is_translated_taxonomy( $obj->taxonomy ) ) { $language = $this->model->term->get_language( (int) $obj->term_id ); } } elseif ( $wp_query->is_posts_page ) { $obj = $wp_query->get_queried_object(); $language = $this->model->post->get_language( (int) $obj->ID ); } elseif ( is_404() && ! empty( $wp_query->query['page_id'] ) && $id = get_query_var( 'page_id' ) ) { // Special case for page shortlinks when using subdomains or multiple domains // Needed because redirect_canonical doesn't accept to change the domain name $language = $this->model->post->get_language( (int) $id ); } if ( empty( $language ) ) { $language = $this->curlang; $redirect_url = $requested_url; } else { // First get the canonical url evaluated by WP // Workaround a WP bug wich removes the port for some urls and get it back at second call to redirect_canonical $_redirect_url = ( ! $_redirect_url = redirect_canonical( $requested_url, false ) ) ? $requested_url : $_redirect_url; $redirect_url = ( ! $redirect_url = redirect_canonical( $_redirect_url, false ) ) ? $_redirect_url : $redirect_url; // Then get the right language code in url $redirect_url = $this->options['force_lang'] ? $this->links_model->switch_language_in_link( $redirect_url, $language ) : $this->links_model->remove_language_from_link( $redirect_url ); // Works only for default permalinks } /** * Filters the canonical url detected by Polylang * * @since 1.6 * * @param bool|string $redirect_url false or the url to redirect to * @param object $language the language detected */ $redirect_url = apply_filters( 'pll_check_canonical_url', $redirect_url, $language ); // The language is not correctly set so let's redirect to the correct url for this object if ( $do_redirect && $redirect_url && $requested_url != $redirect_url ) { wp_redirect( $redirect_url, 301 ); exit; } return $redirect_url; } } frontend-static-pages.php 0000666 00000021576 15213274706 0011504 0 ustar 00 <?php /** * Manages the static front page and the page for posts on frontend * * @since 1.8 */ class PLL_Frontend_Static_Pages extends PLL_Static_Pages { /** * Constructor: setups filters and actions * * @since 1.8 * * @param object $polylang */ public function __construct( &$polylang ) { parent::__construct( $polylang ); $this->links_model = &$polylang->links_model; $this->links = &$polylang->links; add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ) ); add_action( 'pll_home_requested', array( $this, 'pll_home_requested' ) ); // Manages the redirection of the homepage add_filter( 'redirect_canonical', array( $this, 'redirect_canonical' ), 10, 2 ); add_filter( 'pll_pre_translation_url', array( $this, 'pll_pre_translation_url' ), 10, 3 ); add_filter( 'pll_check_canonical_url', array( $this, 'pll_check_canonical_url' ) ); add_filter( 'pll_set_language_from_query', array( $this, 'page_on_front_query' ), 10, 2 ); add_filter( 'pll_set_language_from_query', array( $this, 'page_for_posts_query' ), 10, 2 ); } /** * Init the filters * * @since 1.8 */ public function pll_language_defined() { // Translates our page on front and page for posts properties $this->init(); // Translates page for posts and page on front add_filter( 'option_page_on_front', array( $this, 'translate_page_on_front' ) ); add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) ); // Support theme customizer if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { add_filter( 'pre_option_page_on_front', 'pll_get_post', 20 ); add_filter( 'pre_option_page_for_post', 'pll_get_post', 20 ); } } /** * Translates the page_id query var when the site root page is requested * * @since 1.8 */ public function pll_home_requested() { set_query_var( 'page_id', $this->curlang->page_on_front ); } /** * Translates page on front * * @since 1.8 * * @param int $v page on front page id * @return int */ public function translate_page_on_front( $v ) { // returns the current page if there is no translation to avoid ugly notices return isset( $this->curlang->page_on_front ) ? $this->curlang->page_on_front : $v; } /** * Manages canonical redirection of the homepage when using page on front * * @since 0.1 * * @param string $redirect_url * @param string $requested_url * @return bool|string modified url, false if redirection is canceled */ public function redirect_canonical( $redirect_url, $requested_url ) { global $wp_query; if ( is_page() && ! is_feed() && isset( $wp_query->queried_object ) && $wp_query->queried_object->ID == $this->curlang->page_on_front ) { $url = is_paged() ? $this->links_model->add_paged_to_link( $this->links->get_home_url(), $wp_query->query_vars['page'] ) : $this->links->get_home_url(); // Don't forget additional query vars $query = parse_url( $redirect_url, PHP_URL_QUERY ); if ( ! empty( $query ) ) { parse_str( $query, $query_vars ); $query_vars = rawurlencode_deep( $query_vars ); // WP encodes query vars values $url = add_query_arg( $query_vars, $url ); } return $url; } return $redirect_url; } /** * Translates the url of the page on front and page for posts * * @since 1.8 * * @param string $url not used * @param object $language language in which we want the translation * @param int $queried_object_id id of the queried object * @return string */ public function pll_pre_translation_url( $url, $language, $queried_object_id ) { if ( ! empty( $queried_object_id ) ) { // Page for posts if ( $GLOBALS['wp_query']->is_posts_page && ( $id = $this->model->post->get( $queried_object_id, $language ) ) ) { $url = get_permalink( $id ); } // Page on front elseif ( is_front_page() && $language->page_on_front && ( $language->page_on_front == $this->model->post->get( $queried_object_id, $language ) ) ) { $url = $language->home_url; } } return $url; } /** * Handles canonical redirection if we are on a static front page * * @since 1.8 * * @param string $redirect_url * @return bool|string */ public function pll_check_canonical_url( $redirect_url ) { if ( ! empty( $this->curlang->page_on_front ) && is_page( $this->curlang->page_on_front ) ) { // Redirect www.mysite.fr to mysite.fr if ( 3 === $this->options['force_lang'] ) { foreach ( $this->options['domains'] as $lang => $domain ) { $host = parse_url( $domain, PHP_URL_HOST ); if ( 'www.' . $_SERVER['HTTP_HOST'] === $host || 'www.' . $host === $_SERVER['HTTP_HOST'] ) { $language = $this->model->get_language( $lang ); return $language->home_url; } } } // Prevents canonical redirection made by WP from secondary language to main language if ( $this->options['redirect_lang'] ) { return false; } } return $redirect_url; } /** * Setups query vars when requesting a static front page * * @since 1.8 * * @param bool|object $lang * @param object $query * @return bool|object */ public function page_on_front_query( $lang, $query ) { if ( ! empty( $lang ) || ! $this->page_on_front ) { return $lang; } // The home page is requested if ( did_action( 'home_requested' ) ) { $query->set( 'page_id', $lang->page_on_front ); } // Redirect the language page to the homepage when using a static front page elseif ( ( $this->options['redirect_lang'] || $this->options['hide_default'] ) && ( count( $query->query ) == 1 || ( ( is_preview() || is_paged() || ! empty( $query->query['page'] ) ) && count( $query->query ) == 2 ) || ( ( is_preview() && ( is_paged() || ! empty( $query->query['page'] ) ) ) && count( $query->query ) == 3 ) ) && is_tax( 'language' ) ) { $lang = $this->model->get_language( get_query_var( 'lang' ) ); $query->set( 'page_id', $lang->page_on_front ); $query->is_singular = $query->is_page = true; $query->is_archive = $query->is_tax = false; unset( $query->query_vars['lang'], $query->queried_object ); // Reset queried object } // Fix paged static front page in plain permalinks when Settings > Reading doesn't match the default language elseif ( ! $this->links_model->using_permalinks && count( $query->query ) === 1 && ! empty( $query->query['page'] ) ) { $lang = $this->model->get_language( $this->options['default_lang'] ); $query->set( 'page_id', $lang->page_on_front ); $query->is_singular = $query->is_page = true; $query->is_archive = $query->is_tax = false; unset( $query->query_vars['lang'], $query->queried_object ); // Reset queried object } // Set the language when requesting a static front page else { $page_id = $this->get_page_id( $query ); $languages = $this->model->get_languages_list(); $pages = wp_list_pluck( $languages, 'page_on_front' ); if ( ! empty( $page_id ) && false !== $n = array_search( $page_id, $pages ) ) { $lang = $languages[ $n ]; } } // Fix <!--nextpage--> for page_on_front if ( ( $this->options['force_lang'] < 2 || ! $this->options['redirect_lang'] ) && $this->links_model->using_permalinks && ! empty( $lang ) && isset( $query->query['paged'] ) ) { $query->set( 'page', $query->query['paged'] ); unset( $query->query['paged'] ); } elseif ( ! $this->links_model->using_permalinks && ! empty( $query->query['page'] ) ) { $query->is_paged = true; } return $lang; } /** * Setups query vars when requesting a posts page * * @since 1.8 * * @param bool|object $lang * @param object $query * @return bool|object */ public function page_for_posts_query( $lang, $query ) { if ( empty( $lang ) && $this->page_for_posts ) { $page_id = $this->get_page_id( $query ); if ( ! empty( $page_id ) && in_array( $page_id, $pages = $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) ) ) ) { // Fill the cache with all pages for posts to avoid one query per page later // The posts_per_page limit is a trick to avoid splitting the query get_posts( array( 'posts_per_page' => 999, 'post_type' => 'page', 'post__in' => $pages, 'lang' => '' ) ); $lang = $this->model->post->get_language( $page_id ); $query->is_singular = $query->is_page = false; $query->is_home = $query->is_posts_page = true; } } return $lang; } /** * Get queried page_id ( if exists ) * If permalinks are used, WordPress does set and use $query->queried_object_id and sets $query->query_vars['page_id'] to 0 * and does set and use $query->query_vars['page_id'] if permalinks are not used :( * * @since 1.5 * * @param object $query instance of WP_Query * @return int page_id */ protected function get_page_id( $query ) { if ( ! empty( $query->query_vars['pagename'] ) && isset( $query->queried_object_id ) ) { return $query->queried_object_id; } if ( isset( $query->query_vars['page_id'] ) ) { return $query->query_vars['page_id']; } return 0; // No page queried } } frontend.php 0000666 00000014267 15213274706 0007121 0 ustar 00 <?php /** * frontend controller * accessible as $polylang global object * * properties: * options => inherited, reference to Polylang options array * model => inherited, reference to PLL_Model object * links_model => inherited, reference to PLL_Links_Model object * links => reference to PLL_Links object * static_pages => reference to PLL_Frontend_Static_Pages object * filters_links => inherited, reference to PLL_Frontend_Filters_Links object * choose_lang => reference to PLL_Choose_lang object * curlang => current language * filters => reference to PLL_Filters object * filters_search => reference to PLL_Frontend_Filters_Search object * nav_menu => reference to PLL_Frontend_Nav_Menu object * auto_translate => optional, reference to PLL_Auto_Translate object * * @since 1.2 */ class PLL_Frontend extends PLL_Base { public $curlang; public $links, $choose_lang, $filters, $filters_search, $nav_menu, $auto_translate; /** * constructor * * @since 1.2 * * @param object $links_model */ public function __construct( &$links_model ) { parent::__construct( $links_model ); add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ), 1 ); // avoids the language being the queried object when querying multiple taxonomies add_action( 'parse_tax_query', array( $this, 'parse_tax_query' ), 1 ); // filters posts by language add_action( 'parse_query', array( $this, 'parse_query' ), 6 ); // not before 'check_canonical_url' if ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) { add_action( 'template_redirect', array( $this, 'auto_translate' ), 7 ); } } /** * setups the language chooser based on options * * @since 1.2 */ public function init() { $this->links = new PLL_Frontend_Links( $this ); // Static front page and page for posts if ( 'page' === get_option( 'show_on_front' ) ) { $this->static_pages = new PLL_Frontend_Static_Pages( $this ); } // setup the language chooser $c = array( 'Content', 'Url', 'Url', 'Domain' ); $class = 'PLL_Choose_Lang_' . $c[ $this->options['force_lang'] ]; $this->choose_lang = new $class( $this ); $this->choose_lang->init(); // need to load nav menu class early to correctly define the locations in the customizer when the language is set from the content $this->nav_menu = new PLL_Frontend_Nav_Menu( $this ); } /** * setups filters and nav menus once the language has been defined * * @since 1.2 */ public function pll_language_defined() { // filters $this->filters_links = new PLL_Frontend_Filters_Links( $this ); $this->filters = new PLL_Frontend_Filters( $this ); $this->filters_search = new PLL_Frontend_Filters_Search( $this ); } /** * when querying multiple taxonomies, makes sure that the language is not the queried object * * @since 1.8 * * @param object $query WP_Query object */ public function parse_tax_query( $query ) { $pll_query = new PLL_Query( $query, $this->model ); $queried_taxonomies = $pll_query->get_queried_taxonomies(); if ( ! empty( $queried_taxonomies ) && 'language' == reset( $queried_taxonomies ) ) { $query->tax_query->queried_terms['language'] = array_shift( $query->tax_query->queried_terms ); } } /** * modifies some query vars to "hide" that the language is a taxonomy and avoid conflicts * * @since 1.2 * * @param object $query WP_Query object */ public function parse_query( $query ) { $qv = $query->query_vars; $pll_query = new PLL_Query( $query, $this->model ); $taxonomies = $pll_query->get_queried_taxonomies(); // Allow filtering recent posts and secondary queries by the current language if ( ! empty( $this->curlang ) ) { $pll_query->filter_query( $this->curlang ); } // modifies query vars when the language is queried if ( ! empty( $qv['lang'] ) || ( ! empty( $taxonomies ) && array( 'language' ) == array_values( $taxonomies ) ) ) { // do we query a custom taxonomy? $taxonomies = array_diff( $taxonomies , array( 'language', 'category', 'post_tag' ) ); // remove pages query when the language is set unless we do a search // take care not to break the single page, attachment and taxonomies queries! if ( empty( $qv['post_type'] ) && ! $query->is_search && ! $query->is_page && ! $query->is_attachment && empty( $taxonomies ) ) { $query->set( 'post_type', 'post' ); } // unset the is_archive flag for language pages to prevent loading the archive template // keep archive flag for comment feed otherwise the language filter does not work if ( empty( $taxonomies ) && ! $query->is_comment_feed && ! $query->is_post_type_archive && ! $query->is_date && ! $query->is_author && ! $query->is_category && ! $query->is_tag ) { $query->is_archive = false; } // unset the is_tax flag except if another custom tax is queried if ( empty( $taxonomies ) && ($query->is_category || $query->is_tag || $query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search || $query->is_feed ) ) { $query->is_tax = false; unset( $query->queried_object ); // FIXME useless? } } } /** * auto translate posts and terms ids * * @since 1.2 */ public function auto_translate() { $this->auto_translate = new PLL_Frontend_Auto_Translate( $this ); } /** * resets some variables when switching blog * overrides parent method * * @since 1.5.1 * * @param int $new_blog * @param int $old_blog */ public function switch_blog( $new_blog, $old_blog ) { // need to check that some languages are defined when user is logged in, has several blogs, some without any languages if ( parent::switch_blog( $new_blog, $old_blog ) && did_action( 'pll_language_defined' ) && $this->model->get_languages_list() ) { static $restore_curlang; if ( empty( $restore_curlang ) ) { $restore_curlang = $this->curlang->slug; // to always remember the current language through blogs } $lang = $this->model->get_language( $restore_curlang ); $this->curlang = $lang ? $lang : $this->model->get_language( $this->options['default_lang'] ); if ( isset( $this->static_pages ) ) { $this->static_pages->init(); } $this->load_strings_translations(); } } } frontend-auto-translate.php 0000666 00000016532 15213274706 0012057 0 ustar 00 <?php /** * auto translates the posts and terms ids * useful for example for themes querying a specific cat * * @since 1.1 */ class PLL_Frontend_Auto_Translate { public $model, $curlang; /** * constructor * * @since 1.1 * * @param object $polylang */ public function __construct( &$polylang ) { $this->model = &$polylang->model; $this->curlang = &$polylang->curlang; add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); // after main Polylang filter add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 ); } /** * helper function to get the translated post in the current language * * since 1.8 * * @param int $post_id * @return int */ protected function get_post( $post_id ) { return $this->model->post->get( $post_id, $this->curlang ); } /** * helper function to get the translated term in the current language * * since 1.8 * * @param int $term_id * @return int */ protected function get_term( $term_id ) { return $this->model->term->get( $term_id, $this->curlang ); } /** * filters posts query to automatically translate included ids * * @since 1.1 * * @param object $query WP_Query object */ public function pre_get_posts( $query ) { global $wpdb; $qv = &$query->query_vars; if ( $query->is_main_query() || isset( $qv['lang'] ) || ( ! empty( $qv['post_type'] ) && ! $this->model->is_translated_post_type( $qv['post_type'] ) ) ) { return; } // /!\ always keep untranslated as is // term ids separated by a comma $arr = array(); if ( ! empty( $qv['cat'] ) ) { foreach ( explode( ',', $qv['cat'] ) as $cat ) { $tr = $this->get_term( abs( $cat ) ); $arr[] = $cat < 0 ? -$tr : $tr; } $qv['cat'] = implode( ',', $arr ); } // category_name $arr = array(); if ( ! empty( $qv['category_name'] ) ) { foreach ( explode( ',', $qv['category_name'] ) as $slug ) { $arr[] = ( ( $cat = wpcom_vip_get_category_by_slug( $slug ) ) && ( $tr_id = $this->get_term( $cat->term_id ) ) && ! is_wp_error( $tr = get_category( $tr_id ) ) ) ? $tr->slug : $slug; } $qv['category_name'] = implode( ',', $arr ); } // array of term ids foreach ( array( 'category__and', 'category__in', 'category__not_in', 'tag__and', 'tag__in', 'tag__not_in' ) as $key ) { $arr = array(); if ( ! empty( $qv[ $key ] ) ) { foreach ( $qv[ $key ] as $cat ) { $arr[] = ( $tr = $this->get_term( $cat ) ) ? $tr : $cat; } $qv[ $key ] = $arr; } } // tag $arr = array(); if ( ! empty( $qv['tag'] ) ) { $sep = strpos( $qv['tag'], ',' ) !== false ? ',' : '+'; // two possible separators for tag slugs foreach ( explode( $sep, $qv['tag'] ) as $slug ) { $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, 'post_tag' ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_tag( $tr_id ) ) ) ? $tr->slug : $slug; } $qv['tag'] = implode( $sep, $arr ); } // tag_id can only take one id if ( ! empty( $qv['tag_id'] ) && $tr_id = $this->get_term( $qv['tag_id'] ) ) { $qv['tag_id'] = $tr_id; } // array of tag slugs foreach ( array( 'tag_slug__and', 'tag_slug__in' ) as $key ) { $arr = array(); if ( ! empty( $qv[ $key ] ) ) { foreach ( $qv[ $key ] as $slug ) { $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, 'post_tag' ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_tag( $tr_id ) ) ) ? $tr->slug : $slug; } $qv[ $key ] = $arr; } } // custom taxonomies // according to codex, this type of query is deprecated as of WP 3.1 but it does not appear in WP 3.5 source code foreach ( array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) ) as $taxonomy ) { $tax = get_taxonomy( $taxonomy ); $arr = array(); if ( ! empty( $qv[ $tax->query_var ] ) ) { $sep = strpos( $qv[ $tax->query_var ], ',' ) !== false ? ',' : '+'; // two possible separators foreach ( explode( $sep, $qv[ $tax->query_var ] ) as $slug ) { $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, $taxonomy ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) ? $tr->slug : $slug; } $qv[ $tax->query_var ] = implode( $sep, $arr ); } } // tax_query since WP 3.1 if ( ! empty( $qv['tax_query'] ) && is_array( $qv['tax_query'] ) ) { $qv['tax_query'] = $this->translate_tax_query_recursive( $qv['tax_query'] ); } // p, page_id, post_parent can only take one id foreach ( array( 'p', 'page_id', 'post_parent' ) as $key ) { if ( ! empty( $qv[ $key ] ) && $tr_id = $this->get_post( $qv[ $key ] ) ) { $qv[ $key ] = $tr_id; } } // name, pagename can only take one slug foreach ( array( 'name', 'pagename' ) as $key ) { if ( ! empty( $qv[ $key ] ) ) { // no function to get post by name except get_posts itself $post_type = empty( $qv['post_type'] ) ? 'post' : $qv['post_type']; $id = $wpdb->get_var( $wpdb->prepare( "SELECT ID from $wpdb->posts WHERE post_type=%s AND post_name=%s", $post_type, $qv[ $key ] ) ); $qv[ $key ] = ( $id && ( $tr_id = $this->get_post( $id ) ) && $tr = get_post( $tr_id ) ) ? $tr->post_name : $qv[ $key ]; } } // array of post ids // post_parent__in & post_parent__not_in since WP 3.6 foreach ( array( 'post__in', 'post__not_in', 'post_parent__in', 'post_parent__not_in' ) as $key ) { $arr = array(); if ( ! empty( $qv[ $key ] ) ) { // post__in used by the 2 functions below // useless to filter them as output is already in the right language and would result in performance loss foreach ( debug_backtrace() as $trace ) { if ( in_array( $trace['function'], array( 'wp_nav_menu', 'gallery_shortcode' ) ) ) { return; } } foreach ( $qv[ $key ] as $p ) { $arr[] = ( $tr = $this->get_post( $p ) ) ? $tr : $p; } $qv[ $key ] = $arr; } } } /** * filters terms query to automatically translate included ids * * @since 1.1.1 * * @param array $args * @param array $taxonomies * @return array modified $args */ public function get_terms_args( $args, $taxonomies ) { if ( ! empty( $args['include'] ) && $this->model->is_translated_taxonomy( $taxonomies ) ) { foreach ( wp_parse_id_list( $args['include'] ) as $id ) { $arr[] = ( $tr = $this->get_term( $id ) ) ? $tr : $id; } $args['include'] = $arr; } return $args; } /** * translates tax queries * compatible with nested tax queries introduced in WP 4.1 * * @since 1.7 * * @param array $tax_queries * @return array translated tax queries */ protected function translate_tax_query_recursive( $tax_queries ) { foreach ( $tax_queries as $key => $q ) { if ( isset( $q['taxonomy'], $q['terms'] ) && $this->model->is_translated_taxonomy( $q['taxonomy'] ) ) { $arr = array(); $field = isset( $q['field'] ) && in_array( $q['field'], array( 'slug', 'name' ) ) ? $q['field'] : 'term_id'; foreach ( (array) $q['terms'] as $t ) { $arr[] = ( ( $tag = wpcom_vip_get_term_by( $field, $t, $q['taxonomy'] ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_term( $tr_id, $q['taxonomy'] ) ) ) ? $tr->$field : $t; } $tax_queries[ $key ]['terms'] = $arr; } // nested queries elseif ( is_array( $q ) ) { $tax_queries[ $key ] = $this->translate_tax_query_recursive( $q ); } } return $tax_queries; } } frontend-filters-search.php 0000666 00000010274 15213274706 0012024 0 ustar 00 <?php /** * filters search forms when using permalinks * * @since 1.2 */ class PLL_Frontend_Filters_Search { public $links_model, $curlang; /** * constructor * * @since 1.2 * * @param object $polylang */ public function __construct( &$polylang ) { $this->links_model = &$polylang->links_model; $this->curlang = &$polylang->curlang; // adds the language information in the search form // low priority in case the search form is created using the same filter as described in http://codex.wordpress.org/Function_Reference/get_search_form add_filter( 'get_search_form', array( $this, 'get_search_form' ), 99 ); // adds the language information in admin bar search form add_action( 'add_admin_bar_menus', array( $this, 'add_admin_bar_menus' ) ); // adds javascript at the end of the document // was used for WP < 3.6. kept just in case if ( defined( 'PLL_SEARCH_FORM_JS' ) && PLL_SEARCH_FORM_JS ) { add_action( 'wp_footer', array( $this, 'wp_print_footer_scripts' ) ); } } /** * adds the language information in the search form * does not work if searchform.php ( prior to WP 3.6 ) is used or if the search form is hardcoded in another template file * * @since 0.1 * * @param string $form search form * @return string modified search form */ public function get_search_form( $form ) { if ( $form ) { if ( $this->links_model->using_permalinks ) { // take care to modify only the url in the <form> tag preg_match( '#<form.+>#', $form, $matches ); $old = reset( $matches ); $new = preg_replace( '#' . esc_url( $this->links_model->home ) . '\/?#', esc_url( $this->curlang->search_url ), $old ); $form = str_replace( $old, $new, $form ); } else { $form = str_replace( '</form>', '<input type="hidden" name="lang" value="' . esc_attr( $this->curlang->slug ) . '" /></form>', $form ); } } return $form; } /** * adds the language information in admin bar search form * * @since 1.2 */ function add_admin_bar_menus() { remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 ); add_action( 'admin_bar_menu', array( $this, 'admin_bar_search_menu' ), 4 ); } /** * rewrites the admin bar search form to pass our get_search form filter. See #21342 * code base is WP 4.3.1 * * @since 0.9 * * @param object $wp_admin_bar */ public function admin_bar_search_menu( $wp_admin_bar ) { $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">'; $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />'; $form .= '<label for="adminbar-search" class="screen-reader-text">' . esc_html__( 'Search' ) . '</label>'; $form .= '<input type="submit" class="adminbar-button" value="' . esc_attr__( 'Search' ) . '"/>'; $form .= '</form>'; $wp_admin_bar->add_menu( array( 'parent' => 'top-secondary', 'id' => 'search', 'title' => $this->get_search_form( $form ), // pass the get_search_form filter 'meta' => array( 'class' => 'admin-bar-search', 'tabindex' => -1 ), ) ); } /** * allows modifying the search form if it does not pass get_search_form * * @since 0.1 */ public function wp_print_footer_scripts() { // don't use directly e[0] just in case there is somewhere else an element named 's' // check before if the hidden input has not already been introduced by get_search_form ( FIXME: is there a way to improve this ) ? // thanks to AndyDeGroo for improving the code for compatility with old browsers // http://wordpress.org/support/topic/development-of-polylang-version-08?replies=6#post-2645559 $lang = esc_js( $this->curlang->slug ); $js = "//<![CDATA[ e = document.getElementsByName( 's' ); for ( i = 0; i < e.length; i++ ) { if ( e[i].tagName.toUpperCase() == 'INPUT' ) { s = e[i].parentNode.parentNode.children; l = 0; for ( j = 0; j < s.length; j++ ) { if ( s[j].name == 'lang' ) { l = 1; } } if ( l == 0 ) { var ih = document.createElement( 'input' ); ih.type = 'hidden'; ih.name = 'lang'; ih.value = '$lang'; e[i].parentNode.appendChild( ih ); } } } //]]>"; echo '<script type="text/javascript">' . $js . '</script>'; } } choose-lang.php 0000666 00000025306 15213274706 0007475 0 ustar 00 <?php /** * base class to choose the language * * @since 1.2 */ abstract class PLL_Choose_Lang { public $links_model, $model, $options; public $curlang; /** * constructor * * @since 1.2 * * @param object $polylang */ public function __construct( &$polylang ) { $this->links_model = &$polylang->links_model; $this->model = &$polylang->model; $this->options = &$polylang->options; $this->curlang = &$polylang->curlang; } /** * sets the language for ajax requests * and setup actions * any child class must call this method if it overrides it * * @since 1.8 */ public function init() { if ( PLL_AJAX_ON_FRONT || false === stripos( $_SERVER['SCRIPT_FILENAME'], 'index.php' ) ) { $this->set_language( empty( $_REQUEST['lang'] ) ? $this->get_preferred_language() : $this->model->get_language( $_REQUEST['lang'] ) ); } add_action( 'pre_comment_on_post', array( $this, 'pre_comment_on_post' ) ); // sets the language of comment add_action( 'parse_query', array( $this, 'parse_main_query' ), 2 ); // sets the language in special cases add_action( 'wp', array( $this, 'maybe_setcookie' ), 7 ); } /** * writes language cookie * loads user defined translations * fires the action 'pll_language_defined' * * @since 1.2 * * @param object $curlang current language */ protected function set_language( $curlang ) { // don't set the language a second time if ( isset( $this->curlang ) ) { return; } // final check in case $curlang has an unexpected value // see https://wordpress.org/support/topic/detect-browser-language-sometimes-setting-null-language $this->curlang = ( $curlang instanceof PLL_Language ) ? $curlang : $this->model->get_language( $this->options['default_lang'] ); $GLOBALS['text_direction'] = $this->curlang->is_rtl ? 'rtl' : 'ltr'; /** * Fires when the current language is defined * * @since 0.9.5 * * @param string $slug current language code * @param object $curlang current language object */ do_action( 'pll_language_defined', $this->curlang->slug, $this->curlang ); } /** * set a cookie to remember the language. * possibility to set PLL_COOKIE to false will disable cookie although it will break some functionalities * * @since 1.5 */ public function maybe_setcookie() { // check headers have not been sent to avoid ugly error // cookie domain must be set to false for localhost ( default value for COOKIE_DOMAIN ) thanks to Stephen Harris. if ( ! headers_sent() && PLL_COOKIE !== false && ! empty( $this->curlang ) && ( ! isset( $_COOKIE[ PLL_COOKIE ] ) || $_COOKIE[ PLL_COOKIE ] != $this->curlang->slug ) && ! is_404() ) { /** * Filter the Polylang cookie duration * * @since 1.8 * * @param int $duration cookie duration in seconds */ $expiration = apply_filters( 'pll_cookie_expiration', YEAR_IN_SECONDS ); setcookie( PLL_COOKIE, $this->curlang->slug, time() + $expiration, COOKIEPATH, 2 == $this->options['force_lang'] ? parse_url( $this->links_model->home, PHP_URL_HOST ) : COOKIE_DOMAIN, is_ssl() ); } } /** * get the preferred language according to the browser preferences * code adapted from http://www.thefutureoftheweb.com/blog/use-accept-language-header * * @since 1.8 * * @return string|bool the preferred language slug or false */ public function get_preferred_browser_language() { $accept_langs = array(); if ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) { // break up string into pieces ( languages and q factors ) preg_match_all( '/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*( 1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse ); $k = $lang_parse[1]; $v = $lang_parse[4]; if ( $n = count( $k ) ) { // set default to 1 for any without q factor foreach ( $v as $key => $val ) { if ( '' === $val ) { $v[ $key ] = 1; } } // bubble sort ( need a stable sort for Android, so can't use a PHP sort function ) if ( $n > 1 ) { for ( $i = 2; $i <= $n; $i++ ) { for ( $j = 0; $j <= $n - 2; $j++ ) { if ( $v[ $j ] < $v[ $j + 1 ] ) { // swap values $temp = $v[ $j ]; $v[ $j ] = $v[ $j + 1 ]; $v[ $j + 1 ] = $temp; // Swap keys $temp = $k[ $j ]; $k[ $j ] = $k[ $j + 1 ]; $k[ $j + 1 ] = $temp; } } } } $accept_langs = array_combine( $k,$v ); } } $languages = $this->model->get_languages_list( array( 'hide_empty' => true ) ); // hides languages with no post /** * Filter the list of languages to use to match the browser preferences * * @since 1.9.3 * * @param array $languages array of PLL_Language objects */ $languages = apply_filters( 'pll_languages_for_browser_preferences', $languages ); // looks through sorted list and use first one that matches our language list foreach ( array_keys( $accept_langs ) as $accept_lang ) { // first loop to match the exact locale foreach ( $languages as $language ) { if ( 0 === strcasecmp( $accept_lang, $language->get_locale( 'display' ) ) ) { return $language->slug; } } // second loop to match the language set foreach ( $languages as $language ) { if ( 0 === stripos( $accept_lang, $language->slug ) || 0 === stripos( $language->get_locale( 'display' ), $accept_lang ) ) { return $language->slug; } } } return false; } /** * returns the language according to browser preference or the default language * * @since 0.1 * * @return object browser preferred language or default language */ public function get_preferred_language() { // check first if the user was already browsing this site if ( isset( $_COOKIE[ PLL_COOKIE ] ) ) { return $this->model->get_language( $_COOKIE[ PLL_COOKIE ] ); } /** * Filter the visitor's preferred language (normally set first by cookie * if this is not the first visit, then by the browser preferences). * If no preferred language has been found or set by this filter, * Polylang fallbacks to the default language * * @since 1.0 * * @param string $language preferred language code */ $slug = apply_filters( 'pll_preferred_language', $this->options['browser'] ? $this->get_preferred_browser_language() : false ); // return default if there is no preferences in the browser or preferences does not match our languages or it is requested not to use the browser preference return ( $lang = $this->model->get_language( $slug ) ) ? $lang : $this->model->get_language( $this->options['default_lang'] ); } /** * sets the language when home page is resquested * * @since 1.2 */ protected function home_language() { // test referer in case PLL_COOKIE is set to false // thanks to Ov3rfly http://wordpress.org/support/topic/enhance-feature-when-front-page-is-visited-set-language-according-to-browser $language = $this->options['hide_default'] && ( ( isset( $_SERVER['HTTP_REFERER'] ) && in_array( parse_url( $_SERVER['HTTP_REFERER'], PHP_URL_HOST ), $this->links_model->get_hosts() ) ) || ! $this->options['browser'] ) ? $this->model->get_language( $this->options['default_lang'] ) : $this->get_preferred_language(); // sets the language according to browser preference or default language $this->set_language( $language ); } /** * to call when the home page has been requested * make sure to call this after 'setup_theme' has been fired as we need $wp_query * performs a redirection to the home page in the current language if needed * * @since 0.9 */ public function home_requested() { // we are already on the right page if ( $this->options['default_lang'] == $this->curlang->slug && $this->options['hide_default'] ) { $this->set_curlang_in_query( $GLOBALS['wp_query'] ); /** * Fires when the site root page is requested * * @since 1.8 */ do_action( 'pll_home_requested' ); } // redirect to the home page in the right language // test to avoid crash if get_home_url returns something wrong // FIXME why this happens? http://wordpress.org/support/topic/polylang-crashes-1 // don't redirect if $_POST is not empty as it could break other plugins // don't forget the query string which may be added by plugins elseif ( is_string( $redirect = $this->curlang->home_url ) && empty( $_POST ) ) { $redirect = empty( $_SERVER['QUERY_STRING'] ) ? $redirect : $redirect . ( $this->links_model->using_permalinks ? '?' : '&' ) . $_SERVER['QUERY_STRING']; /** * When a visitor reaches the site home, Polylang redirects to the home page in the correct language. * This filter allows plugins to modify the redirected url or prevent this redirection * * @since 1.1.1 * * @param string $redirect the url the visitor will be redirected to */ if ( $redirect = apply_filters( 'pll_redirect_home', $redirect ) ) { wp_redirect( $redirect ); exit; } } } /** * set the language when posting a comment * * @since 0.8.4 * * @param int $post_id the post beeing commented */ public function pre_comment_on_post( $post_id ) { $this->set_language( $this->model->post->get_language( $post_id ) ); } /** * modifies some main query vars for home page and page for posts * to enable one home page ( and one page for posts ) per language * * @since 1.2 * * @param object $query instance of WP_Query */ public function parse_main_query( $query ) { if ( ! $query->is_main_query() ) { return; } /** * This filter allows to set the language based on information contained in the main query * * @since 1.8 * * @param bool|object $lang false or language object * @param object $query WP_Query object */ if ( $lang = apply_filters( 'pll_set_language_from_query', false, $query ) ) { $this->set_language( $lang ); $this->set_curlang_in_query( $query ); } // sets is_home on translated home page when it displays posts // is_home must be true on page 2, 3... too // as well as when searching an empty string: http://wordpress.org/support/topic/plugin-polylang-polylang-breaks-search-in-spun-theme if ( 'posts' == get_option( 'show_on_front' ) && ( count( $query->query ) == 1 || ( is_paged() && count( $query->query ) == 2 ) || ( isset( $query->query['s'] ) && ! $query->query['s'] ) ) && $lang = get_query_var( 'lang' ) ) { $lang = $this->model->get_language( $lang ); $this->set_language( $lang ); // sets the language now otherwise it will be too late to filter sticky posts ! $query->is_home = true; $query->is_archive = $query->is_tax = false; } } /** * Sets the current language in the query * * @since 2.2 * * @param object $query */ protected function set_curlang_in_query( &$query ) { $pll_query = new PLL_Query( $query, $this->model ); $pll_query->set_language( $this->curlang ); } } frontend-nav-menu.php 0000666 00000023052 15213274706 0010635 0 ustar 00 <?php /** * Manages custom menus translations as well as the language switcher menu item on frontend * * @since 1.2 */ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu { public $curlang; /** * Constructor * * @since 1.2 * * @param object $polylang */ public function __construct( &$polylang ) { parent::__construct( $polylang ); $this->curlang = &$polylang->curlang; // Split the language switcher menu item in several language menu items add_filter( 'wp_get_nav_menu_items', array( $this, 'wp_get_nav_menu_items' ), 20 ); // after the customizer menus add_filter( 'wp_nav_menu_objects', array( $this, 'wp_nav_menu_objects' ) ); add_filter( 'nav_menu_link_attributes', array( $this, 'nav_menu_link_attributes' ), 10, 2 ); // Filters menus by language add_filter( 'theme_mod_nav_menu_locations', array( $this, 'nav_menu_locations' ), 20 ); add_filter( 'wp_nav_menu_args', array( $this, 'wp_nav_menu_args' ) ); // The customizer if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { add_filter( 'wp_nav_menu_args', array( $this, 'filter_args_before_customizer' ) ); add_filter( 'wp_nav_menu_args', array( $this, 'filter_args_after_customizer' ), 2000 ); } } /** * Sort menu items by menu order * * @since 1.7.9 * * @param object $a The first object to compare * @param object $b The second object to compare * @return int -1 or 1 if $a is considered to be respectively less than or greater than $b. */ protected function usort_menu_items( $a, $b ) { return ( $a->menu_order < $b->menu_order ) ? -1 : 1; } /** * Splits the one item of backend in several items on frontend * take care to menu_order as it is used later in wp_nav_menu * * @since 1.1.1 * * @param array $items menu items * @return array modified items */ public function wp_get_nav_menu_items( $items ) { if ( doing_action( 'customize_register' ) ) { // needed since WP 4.3, doing_action available since WP 3.9 return $items; } // The customizer menus does not sort the items and we need them to be sorted before splitting the language switcher usort( $items, array( $this, 'usort_menu_items' ) ); $new_items = array(); $offset = 0; foreach ( $items as $key => $item ) { if ( $options = get_post_meta( $item->ID, '_pll_menu_item', true ) ) { $i = 0; $switcher = new PLL_Switcher; $args = array_merge( array( 'raw' => 1 ), $options ); $the_languages = $switcher->the_languages( PLL()->links, $args ); // parent item for dropdown if ( ! empty( $options['dropdown'] ) ) { $item->title = $options['show_flags'] && $options['show_names'] ? $this->curlang->flag . ' ' . esc_html( $this->curlang->name ) : ( $options['show_flags'] ? $this->curlang->flag : esc_html( $this->curlang->name ) ); $item->attr_title = ''; $item->classes = array( 'pll-parent-menu-item' ); $new_items[] = $item; $offset++; } foreach ( $the_languages as $lang ) { $lang_item = clone $item; $lang_item->ID = $lang_item->ID . '-' . $lang['slug']; // A unique ID $lang_item->title = $options['show_flags'] && $options['show_names'] ? $lang['flag'] . '<span style="margin-left:0.3em;">' . esc_html( $lang['name'] ) . '</span>' : ( $options['show_flags'] ? $lang['flag'] : esc_html( $lang['name'] ) ); $lang_item->attr_title = ''; $lang_item->url = $lang['url']; $lang_item->lang = $lang['locale']; // Save this for use in nav_menu_link_attributes $lang_item->classes = $lang['classes']; $lang_item->menu_order += $offset + $i++; if ( ! empty( $options['dropdown'] ) ) { $lang_item->menu_item_parent = $item->db_id; $lang_item->db_id = 0; // to avoid recursion } $new_items[] = $lang_item; } $offset += $i - 1; } else { $item->menu_order += $offset; $new_items[] = $item; } } return $new_items; } /** * Returns the ancestors of a menu item * * @since 1.1.1 * * @param object $item * @return array ancestors ids */ public function get_ancestors( $item ) { $ids = array(); $_anc_id = (int) $item->db_id; while ( ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) && ! in_array( $_anc_id, $ids ) ) { $ids[] = $_anc_id; } return $ids; } /** * Removes current-menu and current-menu-ancestor classes to lang switcher when not on the home page * * @since 1.1.1 * * @param array $items * @return array modified menu items */ public function wp_nav_menu_objects( $items ) { $r_ids = $k_ids = array(); foreach ( $items as $item ) { if ( ! empty( $item->classes ) && is_array( $item->classes ) ) { if ( in_array( 'current-lang', $item->classes ) ) { $item->current = false; $item->classes = array_diff( $item->classes, array( 'current-menu-item' ) ); $r_ids = array_merge( $r_ids, $this->get_ancestors( $item ) ); // Remove the classes for these ancestors } elseif ( in_array( 'current-menu-item', $item->classes ) ) { $k_ids = array_merge( $k_ids, $this->get_ancestors( $item ) ); // Keep the classes for these ancestors } } } $r_ids = array_diff( $r_ids, $k_ids ); foreach ( $items as $item ) { if ( ! empty( $item->db_id ) && in_array( $item->db_id, $r_ids ) ) { $item->classes = array_diff( $item->classes, array( 'current-menu-ancestor', 'current-menu-parent', 'current_page_parent', 'current_page_ancestor' ) ); } } return $items; } /** * Adds hreflang attribute for the language switcher menu items * available since WP 3.6 * * @since 1.1 * * @param array $atts * @param object $item * @return array modified $atts */ public function nav_menu_link_attributes( $atts, $item ) { if ( isset( $item->lang ) ) { $atts['lang'] = $atts['hreflang'] = esc_attr( $item->lang ); } return $atts; } /** * Fills the theme nav menus locations with the right menu in the right language * Needs to wait for the language to be defined * * @since 1.2 * * @param array|bool $menus list of nav menus locations, false if menu locations have not been filled yet * @return array|bool modified list of nav menus locations */ public function nav_menu_locations( $menus ) { if ( is_array( $menus ) && ! empty( $this->curlang ) ) { // First get multilingual menu locations from DB $theme = get_option( 'stylesheet' ); foreach ( $menus as $loc => $menu ) { $menus[ $loc ] = empty( $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ] ) ? 0 : $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ]; } // Support for theme customizer // Let's look for multilingual menu locations directly in $_POST as there are not in customizer object if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { $customized = json_decode( wp_unslash( $_POST['customized'] ) ); if ( is_object( $customized ) ) { foreach ( $customized as $key => $c ) { if ( false !== strpos( $key, 'nav_menu_locations[' ) ) { $loc = substr( trim( $key, ']' ), 19 ); $infos = $this->explode_location( $loc ); if ( $infos['lang'] == $this->curlang->slug ) { $menus[ $infos['location'] ] = $c; } elseif ( $this->curlang->slug == $this->options['default_lang'] ) { $menus[ $loc ] = $c; } } } } } } return $menus; } /** * Attempt to translate the nav menu when it is hardcoded or when no location is defined in wp_nav_menu * * @since 1.7.10 * * @param array $args * @return array modified $args */ public function wp_nav_menu_args( $args ) { $theme = get_option( 'stylesheet' ); if ( empty( $this->curlang ) || empty( $this->options['nav_menus'][ $theme ] ) ) { return $args; } // Get the nav menu based on the requested menu $menu = wp_get_nav_menu_object( $args['menu'] ); // Attempt to find a translation of this menu // This obviously does not work if the nav menu has no associated theme location if ( $menu ) { foreach ( $this->options['nav_menus'][ $theme ] as $menus ) { if ( in_array( $menu->term_id, $menus ) && ! empty( $menus[ $this->curlang->slug ] ) ) { $args['menu'] = $menus[ $this->curlang->slug ]; return $args; } } } // Get the first menu that has items and and is in the current language if we still can't find a menu if ( ! $menu && ! $args['theme_location'] ) { $menus = wp_get_nav_menus(); foreach ( $menus as $menu_maybe ) { if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) { foreach ( $this->options['nav_menus'][ $theme ] as $menus ) { if ( in_array( $menu_maybe->term_id, $menus ) && ! empty( $menus[ $this->curlang->slug ] ) ) { $args['menu'] = $menus[ $this->curlang->slug ]; return $args; } } } } } return $args; } /** * Filters the nav menu location before the customizer so that it matches the temporary location in the customizer * * @since 1.8 * * @param array $args wp_nav_menu $args * @return array modified $args */ public function filter_args_before_customizer( $args ) { if ( ! empty( $this->curlang ) ) { $args['theme_location'] = $this->combine_location( $args['theme_location'], $this->curlang ); } return $args; } /** * Filters the nav menu location after the customizer to get back the true nav menu location for the theme * * @since 1.8 * * @param array $args wp_nav_menu $args * @return array modified $args */ public function filter_args_after_customizer( $args ) { $infos = $this->explode_location( $args['theme_location'] ); $args['theme_location'] = $infos['location']; return $args; } } choose-lang-url.php 0000666 00000006724 15213274706 0010300 0 ustar 00 <?php /** * Choose the language when the language code is added to all urls * The language is set in plugins_loaded with priority 1 as done by WPML * Some actions have to be delayed to wait for $wp_rewrite availibility * * @since 1.2 */ class PLL_Choose_Lang_Url extends PLL_Choose_lang { protected $index = 'index.php'; // need this before $wp_rewrite is created, also harcoded in wp-includes/rewrite.php /** * sets the language * * @since 1.8 */ public function init() { parent::init(); if ( ! did_action( 'pll_language_defined' ) ) { $this->set_language_from_url(); } add_action( 'request', array( $this, 'request' ) ); } /** * finds the language according to information found in the url * * @since 1.2 */ public function set_language_from_url() { $host = str_replace( 'www.', '', parse_url( $this->links_model->home, PHP_URL_HOST ) ); $home_path = parse_url( $this->links_model->home, PHP_URL_PATH ); $requested_host = str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ); $requested_uri = rtrim( str_replace( $this->index, '', $_SERVER['REQUEST_URI'] ), '/' ); // some PHP setups turn requests for / into /index.php in REQUEST_URI // home is resquested if ( $requested_host == $host && $requested_uri == $home_path && empty( $_SERVER['QUERY_STRING'] ) ) { $this->home_language(); add_action( 'setup_theme', array( $this, 'home_requested' ) ); } // take care to post & page preview http://wordpress.org/support/topic/static-frontpage-url-parameter-url-language-information elseif ( isset( $_GET['preview'] ) && ( ( isset( $_GET['p'] ) && $id = (int) $_GET['p'] ) || ( isset( $_GET['page_id'] ) && $id = (int) $_GET['page_id'] ) ) ) { $curlang = ( $lg = $this->model->post->get_language( $id ) ) ? $lg : $this->model->get_language( $this->options['default_lang'] ); } // take care to ( unattached ) attachments elseif ( isset( $_GET['attachment_id'] ) && $id = (int) $_GET['attachment_id'] ) { $curlang = ( $lg = $this->model->post->get_language( $id ) ) ? $lg : $this->get_preferred_language(); } elseif ( $slug = $this->links_model->get_language_from_url() ) { $curlang = $this->model->get_language( $slug ); } elseif ( $this->options['hide_default'] ) { $curlang = $this->model->get_language( $this->options['default_lang'] ); } // if no language found, check_language_code_in_url will attempt to find one and redirect to the correct url // otherwise 404 will be fired in the preferred language $this->set_language( empty( $curlang ) ? $this->get_preferred_language() : $curlang ); } /** * adds the current language in query vars * useful for subdomains and multiple domains * * @since 1.8 * * @param array $qv main request query vars * @return array modified query vars */ public function request( $qv ) { // FIXME take care not to break untranslated content // FIXME media ? // untranslated post types if ( isset( $qv['post_type'] ) && ! $this->model->is_translated_post_type( $qv['post_type'] ) ) { return $qv; } // untranslated taxonomies $tax_qv = array_filter( wp_list_pluck( get_taxonomies( array(), 'objects' ), 'query_var' ) ); // get all taxonomies query vars $tax_qv = array_intersect( $tax_qv, array_keys( $qv ) ); // get all queried taxonomies query vars if ( ! $this->model->is_translated_taxonomy( array_keys( $tax_qv ) ) ) { return $qv; } if ( isset( $this->curlang ) && empty( $qv['lang'] ) ) { $qv['lang'] = $this->curlang->slug; } return $qv; } } frontend-links.php 0000666 00000014623 15213274706 0010233 0 ustar 00 <?php /** * manages links filters and url of translations on frontend * * @since 1.2 */ class PLL_Frontend_Links extends PLL_Links { public $curlang; public $cache; // our internal non persistent cache object /** * constructor * * @since 1.2 * * @param object $polylang */ public function __construct( &$polylang ) { parent::__construct( $polylang ); $this->curlang = &$polylang->curlang; $this->cache = new PLL_Cache(); } /** * returns the url of the translation ( if exists ) of the current page * * @since 0.1 * * @param object $language * @return string */ public function get_translation_url( $language ) { global $wp_query; if ( false !== $translation_url = $this->cache->get( 'translation_url:' . $language->slug ) ) { return $translation_url; } // make sure that we have the queried object // see https://wordpress.org/support/topic/patch-for-fixing-a-notice $queried_object_id = $wp_query->get_queried_object_id(); /** * Filter the translation url before Polylang attempts to find one * Internally used by Polylang for the static front page and posts page * * @since 1.8 * * @param string $url empty or the url of the translation of teh current page * @param object $language language of the translation * @param int $queried_object_id queried object id */ if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) { $qv = $wp_query->query_vars; $hide = $this->options['default_lang'] == $language->slug && $this->options['hide_default']; // post and attachment if ( is_single() && ( $this->options['media_support'] || ! is_attachment() ) && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->current_user_can_read( $id ) ) { $url = get_permalink( $id ); } // page elseif ( is_page() && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->current_user_can_read( $id ) ) { $url = get_page_link( $id ); } elseif ( is_search() ) { $url = $this->get_archive_url( $language ); // special case for search filtered by translated taxonomies: taxonomy terms are translated in the translation url if ( ! empty( $wp_query->tax_query->queries ) ) { foreach ( $wp_query->tax_query->queries as $tax_query ) { if ( ! empty( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) ) { $tax = get_taxonomy( $tax_query['taxonomy'] ); $terms = get_terms( $tax->name, array( 'fields' => 'id=>slug' ) ); // filtered by current language foreach ( $tax_query['terms'] as $slug ) { $term_id = array_search( $slug, $terms ); // what is the term_id corresponding to taxonomy term? if ( $term_id && $term_id = $this->model->term->get_translation( $term_id, $language ) ) { // get the translated term_id $term = get_term( $term_id, $tax->name ); $url = str_replace( $slug, $term->slug, $url ); } } } } } } // translated taxonomy // take care that is_tax() is false for categories and tags elseif ( ( is_category() || is_tag() || is_tax() ) && ( $term = get_queried_object() ) && $this->model->is_translated_taxonomy( $term->taxonomy ) ) { $lang = $this->model->term->get_language( $term->term_id ); if ( ! $lang || $language->slug == $lang->slug ) { $url = wpcom_vip_get_term_link( $term, $term->taxonomy ); // self link } elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) { $tr_term = get_term( $tr_id, $term->taxonomy ); // check if translated term ( or children ) have posts if ( $tr_term && ( $tr_term->count || ( is_taxonomy_hierarchical( $term->taxonomy ) && array_sum( wp_list_pluck( get_terms( $term->taxonomy, array( 'child_of' => $tr_term->term_id, 'lang' => $language->slug ) ), 'count' ) ) ) ) ) { $url = wpcom_vip_get_term_link( $tr_term, $term->taxonomy ); } } } // post type archive elseif ( is_post_type_archive() ) { if ( $this->model->is_translated_post_type( $qv['post_type'] ) && $this->model->count_posts( $language, array( 'post_type' => $qv['post_type'] ) ) ) { $url = $this->get_archive_url( $language ); } } elseif ( is_archive() ) { $keys = array( 'post_type', 'm', 'year', 'monthnum', 'day', 'author', 'author_name' ); $keys = array_merge( $keys, $this->model->get_filtered_taxonomies_query_vars() ); // check if there are existing translations before creating the url if ( $this->model->count_posts( $language, array_intersect_key( $qv, array_flip( $keys ) ) ) ) { $url = $this->get_archive_url( $language ); } } // front page when it is the list of posts elseif ( is_front_page() ) { $url = $this->get_home_url( $language ); } } /** * Filter the translation url of the current page before Polylang caches it * * @since 1.1.2 * * @param null|string $url the translation url, null if none was found * @param string $language the language code of the translation */ $translation_url = apply_filters( 'pll_translation_url', ( isset( $url ) && ! is_wp_error( $url ) ? $url : null ), $language->slug ); $this->cache->set( 'translation_url:' . $language->slug, $translation_url ); return $translation_url; } /** * get the translation of the current archive url * used also for search * * @since 1.2 * * @param object $language * @return string */ public function get_archive_url( $language ) { $url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; $url = $this->links_model->switch_language_in_link( $url, $language ); $url = $this->links_model->remove_paged_from_link( $url ); /** * Filter the archive url * * @since 1.6 * * @param string $url url of the archive * @param object $language language of the archive */ return apply_filters( 'pll_get_archive_url', $url, $language ); } /** * returns the home url in the right language * * @since 0.1 * * @param object $language Optional, defaults to current language * @param bool $is_search Optional, whether we need the home url for a search form, defaults to false */ public function get_home_url( $language = '', $is_search = false ) { if ( empty( $language ) ) { $language = $this->curlang; } return parent::get_home_url( $language, $is_search ); } } geolocation.js 0000666 00000004057 15214157447 0007431 0 ustar 00 /*global wc_geolocation_params */ jQuery( function( $ ) { var this_page = window.location.toString(); var $append_hashes = function() { if ( wc_geolocation_params.hash ) { $( 'a[href^="' + wc_geolocation_params.home_url + '"]:not(a[href*="v="]), a[href^="/"]:not(a[href*="v="])' ).each( function() { var $this = $( this ); var href = $this.attr( 'href' ); if ( href.indexOf( '?' ) > 0 ) { $this.attr( 'href', href + '&v=' + wc_geolocation_params.hash ); } else { $this.attr( 'href', href + '?v=' + wc_geolocation_params.hash ); } }); } }; var $geolocation_redirect = function( hash ) { if ( this_page.indexOf( '?v=' ) > 0 || this_page.indexOf( '&v=' ) > 0 ) { this_page = this_page.replace( /v=[^&]+/, 'v=' + hash ); } else if ( this_page.indexOf( '?' ) > 0 ) { this_page = this_page + '&v=' + hash; } else { this_page = this_page + '?v=' + hash; } window.location = this_page; }; var $geolocate_customer = { url: wc_geolocation_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_customer_location' ), type: 'GET', success: function( response ) { if ( response.success && response.data.hash && response.data.hash !== wc_geolocation_params.hash ) { $geolocation_redirect( response.data.hash ); } } }; if ( '1' === wc_geolocation_params.is_available ) { $.ajax( $geolocate_customer ); // Support form elements $( 'form' ).each( function() { var $this = $( this ); var method = $this.attr( 'method' ); if ( method && 'get' === method.toLowerCase() ) { $this.append( '<input type="hidden" name="v" value="' + wc_geolocation_params.hash + '" />' ); } else { var href = $this.attr( 'action' ); if ( href ) { if ( href.indexOf( '?' ) > 0 ) { $this.attr( 'action', href + '&v=' + wc_geolocation_params.hash ); } else { $this.attr( 'action', href + '?v=' + wc_geolocation_params.hash ); } } } }); // Append hashes on load $append_hashes(); } $( document.body ).on( 'added_to_cart', function() { $append_hashes(); }); }); cart-fragments.js 0000666 00000011303 15214157447 0010033 0 ustar 00 /* global wc_cart_fragments_params */ jQuery( function( $ ) { // wc_cart_fragments_params is required to continue, ensure the object exists if ( typeof wc_cart_fragments_params === 'undefined' ) { return false; } /* Storage Handling */ var $supports_html5_storage; var cart_hash_key = wc_cart_fragments_params.ajax_url.toString() + '-wc_cart_hash'; try { $supports_html5_storage = ( 'sessionStorage' in window && window.sessionStorage !== null ); window.sessionStorage.setItem( 'wc', 'test' ); window.sessionStorage.removeItem( 'wc' ); window.localStorage.setItem( 'wc', 'test' ); window.localStorage.removeItem( 'wc' ); } catch( err ) { $supports_html5_storage = false; } /* Cart session creation time to base expiration on */ function set_cart_creation_timestamp() { if ( $supports_html5_storage ) { sessionStorage.setItem( 'wc_cart_created', ( new Date() ).getTime() ); } } /** Set the cart hash in both session and local storage */ function set_cart_hash( cart_hash ) { if ( $supports_html5_storage ) { localStorage.setItem( cart_hash_key, cart_hash ); sessionStorage.setItem( cart_hash_key, cart_hash ); } } var $fragment_refresh = { url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ), type: 'POST', success: function( data ) { if ( data && data.fragments ) { $.each( data.fragments, function( key, value ) { $( key ).replaceWith( value ); }); if ( $supports_html5_storage ) { sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( data.fragments ) ); set_cart_hash( data.cart_hash ); if ( data.cart_hash ) { set_cart_creation_timestamp(); } } $( document.body ).trigger( 'wc_fragments_refreshed' ); } } }; /* Named callback for refreshing cart fragment */ function refresh_cart_fragment() { $.ajax( $fragment_refresh ); } /* Cart Handling */ if ( $supports_html5_storage ) { var cart_timeout = null, day_in_ms = ( 24 * 60 * 60 * 1000 ); $( document.body ).bind( 'wc_fragment_refresh updated_wc_div', function() { refresh_cart_fragment(); }); $( document.body ).bind( 'added_to_cart', function( event, fragments, cart_hash ) { var prev_cart_hash = sessionStorage.getItem( cart_hash_key ); if ( prev_cart_hash === null || prev_cart_hash === undefined || prev_cart_hash === '' ) { set_cart_creation_timestamp(); } sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( fragments ) ); set_cart_hash( cart_hash ); }); $( document.body ).bind( 'wc_fragments_refreshed', function() { clearTimeout( cart_timeout ); cart_timeout = setTimeout( refresh_cart_fragment, day_in_ms ); } ); // Refresh when storage changes in another tab $( window ).on( 'storage onstorage', function ( e ) { if ( cart_hash_key === e.originalEvent.key && localStorage.getItem( cart_hash_key ) !== sessionStorage.getItem( cart_hash_key ) ) { refresh_cart_fragment(); } }); try { var wc_fragments = $.parseJSON( sessionStorage.getItem( wc_cart_fragments_params.fragment_name ) ), cart_hash = sessionStorage.getItem( cart_hash_key ), cookie_hash = $.cookie( 'woocommerce_cart_hash'), cart_created = sessionStorage.getItem( 'wc_cart_created' ); if ( cart_hash === null || cart_hash === undefined || cart_hash === '' ) { cart_hash = ''; } if ( cookie_hash === null || cookie_hash === undefined || cookie_hash === '' ) { cookie_hash = ''; } if ( cart_hash && ( cart_created === null || cart_created === undefined || cart_created === '' ) ) { throw 'No cart_created'; } if ( cart_created ) { var cart_expiration = ( ( 1 * cart_created ) + day_in_ms ), timestamp_now = ( new Date() ).getTime(); if ( cart_expiration < timestamp_now ) { throw 'Fragment expired'; } cart_timeout = setTimeout( refresh_cart_fragment, ( cart_expiration - timestamp_now ) ); } if ( wc_fragments && wc_fragments['div.widget_shopping_cart_content'] && cart_hash === cookie_hash ) { $.each( wc_fragments, function( key, value ) { $( key ).replaceWith(value); }); $( document.body ).trigger( 'wc_fragments_loaded' ); } else { throw 'No fragment'; } } catch( err ) { refresh_cart_fragment(); } } else { refresh_cart_fragment(); } /* Cart Hiding */ if ( $.cookie( 'woocommerce_items_in_cart' ) > 0 ) { $( '.hide_cart_widget_if_empty' ).closest( '.widget_shopping_cart' ).show(); } else { $( '.hide_cart_widget_if_empty' ).closest( '.widget_shopping_cart' ).hide(); } $( document.body ).bind( 'adding_to_cart', function() { $( '.hide_cart_widget_if_empty' ).closest( '.widget_shopping_cart' ).show(); }); }); single-product.min.js 0000666 00000003345 15214157447 0010646 0 ustar 00 jQuery(function(a){return"undefined"!=typeof wc_single_product_params&&(a("body").on("init",".wc-tabs-wrapper, .woocommerce-tabs",function(){a(".wc-tab, .woocommerce-tabs .panel:not(.panel .panel)").hide();var b=window.location.hash,c=window.location.href,d=a(this).find(".wc-tabs, ul.tabs").first();b.toLowerCase().indexOf("comment-")>=0||"#reviews"===b||"#tab-reviews"===b?d.find("li.reviews_tab a").click():c.indexOf("comment-page-")>0||c.indexOf("cpage=")>0?d.find("li.reviews_tab a").click():d.find("li:first a").click()}).on("click",".wc-tabs li a, ul.tabs li a",function(b){b.preventDefault();var c=a(this),d=c.closest(".wc-tabs-wrapper, .woocommerce-tabs"),e=d.find(".wc-tabs, ul.tabs");e.find("li").removeClass("active"),d.find(".wc-tab, .panel:not(.panel .panel)").hide(),c.closest("li").addClass("active"),d.find(c.attr("href")).show()}).on("click","a.woocommerce-review-link",function(){return a(".reviews_tab a").click(),!0}).on("init","#rating",function(){a("#rating").hide().before('<p class="stars"><span><a class="star-1" href="#">1</a><a class="star-2" href="#">2</a><a class="star-3" href="#">3</a><a class="star-4" href="#">4</a><a class="star-5" href="#">5</a></span></p>')}).on("click","#respond p.stars a",function(){var b=a(this),c=a(this).closest("#respond").find("#rating"),d=a(this).closest(".stars");return c.val(b.text()),b.siblings("a").removeClass("active"),b.addClass("active"),d.addClass("selected"),!1}).on("click","#respond #submit",function(){var b=a(this).closest("#respond").find("#rating"),c=b.val();if(b.length>0&&!c&&"yes"===wc_single_product_params.review_rating_required)return window.alert(wc_single_product_params.i18n_required_rating_text),!1}),void a(".wc-tabs-wrapper, .woocommerce-tabs, #rating").trigger("init"))}); password-strength-meter.min.js 0000666 00000003550 15214157447 0012515 0 ustar 00 jQuery(function(a){var b={init:function(){a(document.body).on("keyup change","form.register #reg_password, form.checkout #account_password, form.edit-account #password_1, form.lost_reset_password #password_1",this.strengthMeter),a("form.checkout #createaccount").change()},strengthMeter:function(){var c=a("form.register, form.checkout, form.edit-account, form.lost_reset_password"),d=a('input[type="submit"]',c),e=a("#reg_password, #account_password, #password_1",c),f=1;b.includeMeter(c,e),f=b.checkPasswordStrength(c,e),f<wc_password_strength_meter_params.min_password_strength&&!c.is("form.checkout")?d.attr("disabled","disabled").addClass("disabled"):d.removeAttr("disabled","disabled").removeClass("disabled")},includeMeter:function(b,c){var d=b.find(".woocommerce-password-strength");""===c.val()?(d.remove(),a(document.body).trigger("wc-password-strength-removed")):0===d.length&&(c.after('<div class="woocommerce-password-strength" aria-live="polite"></div>'),a(document.body).trigger("wc-password-strength-added"))},checkPasswordStrength:function(a,b){var c=a.find(".woocommerce-password-strength"),d=a.find(".woocommerce-password-hint"),e='<small class="woocommerce-password-hint">'+wc_password_strength_meter_params.i18n_password_hint+"</small>",f=wp.passwordStrength.meter(b.val(),wp.passwordStrength.userInputBlacklist()),g="";switch(c.removeClass("short bad good strong"),d.remove(),f<wc_password_strength_meter_params.min_password_strength&&(g=" - "+wc_password_strength_meter_params.i18n_password_error),f){case 0:c.addClass("short").html(pwsL10n.short+g),c.after(e);break;case 1:c.addClass("bad").html(pwsL10n.bad+g),c.after(e);break;case 2:c.addClass("bad").html(pwsL10n.bad+g),c.after(e);break;case 3:c.addClass("good").html(pwsL10n.good+g);break;case 4:c.addClass("strong").html(pwsL10n.strong+g);break;case 5:c.addClass("short").html(pwsL10n.mismatch)}return f}};b.init()}); add-to-cart-variation.js 0000666 00000050353 15214157447 0011217 0 ustar 00 /*global wc_add_to_cart_variation_params, wc_cart_fragments_params */ ;(function ( $, window, document, undefined ) { /** * VariationForm class which handles variation forms and attributes. */ var VariationForm = function( $form ) { this.$form = $form; this.$attributeFields = $form.find( '.variations select' ); this.$singleVariation = $form.find( '.single_variation' ), this.$singleVariationWrap = $form.find( '.single_variation_wrap' ); this.$resetVariations = $form.find( '.reset_variations' ); this.$product = $form.closest( '.product' ); this.variationData = $form.data( 'product_variations' ); this.useAjax = false === this.variationData; this.xhr = false; // Initial state. this.$singleVariationWrap.show(); this.$form.unbind( 'check_variations update_variation_values found_variation' ); this.$resetVariations.unbind( 'click' ); this.$attributeFields.unbind( 'change ' ); // Methods. this.getChosenAttributes = this.getChosenAttributes.bind( this ); this.findMatchingVariations = this.findMatchingVariations.bind( this ); this.isMatch = this.isMatch.bind( this ); this.toggleResetLink = this.toggleResetLink.bind( this ); // Events. $form.on( 'click', '.reset_variations', { variationForm: this }, this.onReset ); $form.on( 'reload_product_variations', { variationForm: this }, this.onReload ); $form.on( 'hide_variation', { variationForm: this }, this.onHide ); $form.on( 'show_variation', { variationForm: this }, this.onShow ); $form.on( 'click', '.single_add_to_cart_button', { variationForm: this }, this.onAddToCart ); $form.on( 'reset_data', { variationForm: this }, this.onResetDisplayedVariation ); $form.on( 'reset_image', { variationForm: this }, this.onResetImage ); $form.on( 'change', '.variations select', { variationForm: this }, this.onChange ); $form.on( 'found_variation', { variationForm: this }, this.onFoundVariation ); $form.on( 'check_variations', { variationForm: this }, this.onFindVariation ); $form.on( 'update_variation_values', { variationForm: this }, this.onUpdateAttributes ); // Check variations once init. $form.trigger( 'check_variations' ); $form.trigger( 'wc_variation_form' ); }; /** * Reset all fields. */ VariationForm.prototype.onReset = function( event ) { event.preventDefault(); event.data.variationForm.$attributeFields.val( '' ).change(); event.data.variationForm.$form.trigger( 'reset_data' ); }; /** * Reload variation data from the DOM. */ VariationForm.prototype.onReload = function( event ) { var form = event.data.variationForm; form.variationData = form.$form.data( 'product_variations' ); form.useAjax = false === form.variationData; form.$form.trigger( 'check_variations' ); }; /** * When a variation is hidden. */ VariationForm.prototype.onHide = function( event ) { event.preventDefault(); event.data.variationForm.$form.find( '.single_add_to_cart_button' ).removeClass( 'wc-variation-is-unavailable' ).addClass( 'disabled wc-variation-selection-needed' ); event.data.variationForm.$form.find( '.woocommerce-variation-add-to-cart' ).removeClass( 'woocommerce-variation-add-to-cart-enabled' ).addClass( 'woocommerce-variation-add-to-cart-disabled' ); }; /** * When a variation is shown. */ VariationForm.prototype.onShow = function( event, variation, purchasable ) { event.preventDefault(); if ( purchasable ) { event.data.variationForm.$form.find( '.single_add_to_cart_button' ).removeClass( 'disabled wc-variation-selection-needed wc-variation-is-unavailable' ); event.data.variationForm.$form.find( '.woocommerce-variation-add-to-cart' ).removeClass( 'woocommerce-variation-add-to-cart-disabled' ).addClass( 'woocommerce-variation-add-to-cart-enabled' ); } else { event.data.variationForm.$form.find( '.single_add_to_cart_button' ).removeClass( 'wc-variation-selection-needed' ).addClass( 'disabled wc-variation-is-unavailable' ); event.data.variationForm.$form.find( '.woocommerce-variation-add-to-cart' ).removeClass( 'woocommerce-variation-add-to-cart-enabled' ).addClass( 'woocommerce-variation-add-to-cart-disabled' ); } }; /** * When the cart button is pressed. */ VariationForm.prototype.onAddToCart = function( event ) { if ( $( this ).is('.disabled') ) { event.preventDefault(); if ( $( this ).is('.wc-variation-is-unavailable') ) { window.alert( wc_add_to_cart_variation_params.i18n_unavailable_text ); } else if ( $( this ).is('.wc-variation-selection-needed') ) { window.alert( wc_add_to_cart_variation_params.i18n_make_a_selection_text ); } } }; /** * When displayed variation data is reset. */ VariationForm.prototype.onResetDisplayedVariation = function( event ) { var form = event.data.variationForm; form.$product.find( '.product_meta' ).find( '.sku' ).wc_reset_content(); form.$product.find( '.product_weight' ).wc_reset_content(); form.$product.find( '.product_dimensions' ).wc_reset_content(); form.$form.trigger( 'reset_image' ); form.$singleVariation.slideUp( 200 ).trigger( 'hide_variation' ); }; /** * When the product image is reset. */ VariationForm.prototype.onResetImage = function( event ) { event.data.variationForm.$form.wc_variations_image_update( false ); }; /** * Looks for matching variations for current selected attributes. */ VariationForm.prototype.onFindVariation = function( event ) { var form = event.data.variationForm, attributes = form.getChosenAttributes(), currentAttributes = attributes.data; if ( attributes.count === attributes.chosenCount ) { if ( form.useAjax ) { if ( form.xhr ) { form.xhr.abort(); } form.$form.block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } ); currentAttributes.product_id = parseInt( form.$form.data( 'product_id' ), 10 ); currentAttributes.custom_data = form.$form.data( 'custom_data' ); form.xhr = $.ajax( { url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_variation' ), type: 'POST', data: currentAttributes, success: function( variation ) { if ( variation ) { form.$form.trigger( 'found_variation', [ variation ] ); } else { form.$form.trigger( 'reset_data' ); form.$form.find( '.single_variation' ).after( '<p class="wc-no-matching-variations woocommerce-info">' + wc_add_to_cart_variation_params.i18n_no_matching_variations_text + '</p>' ); form.$form.find( '.wc-no-matching-variations' ).slideDown( 200 ); } }, complete: function() { form.$form.unblock(); } } ); } else { form.$form.trigger( 'update_variation_values' ); var matching_variations = form.findMatchingVariations( form.variationData, currentAttributes ), variation = matching_variations.shift(); if ( variation ) { form.$form.trigger( 'found_variation', [ variation ] ); } else { window.alert( wc_add_to_cart_variation_params.i18n_no_matching_variations_text ); form.$form.trigger( 'reset_data' ); } } } else { form.$form.trigger( 'update_variation_values' ); form.$form.trigger( 'reset_data' ); } // Show reset link. form.toggleResetLink( attributes.chosenCount > 0 ); // added to get around variation image flicker issue $( '.product.has-default-attributes > .images' ).fadeTo( 200, 1 ); }; /** * Triggered when a variation has been found which matches all attributes. */ VariationForm.prototype.onFoundVariation = function( event, variation ) { var form = event.data.variationForm, $sku = form.$product.find( '.product_meta' ).find( '.sku' ), $weight = form.$product.find( '.product_weight' ), $dimensions = form.$product.find( '.product_dimensions' ), $qty = form.$singleVariationWrap.find( '.quantity' ), purchasable = true, variation_id = '', template = false, $template_html = ''; if ( variation.sku ) { $sku.wc_set_content( variation.sku ); } else { $sku.wc_reset_content(); } if ( variation.weight ) { $weight.wc_set_content( variation.weight ); } else { $weight.wc_reset_content(); } if ( variation.dimensions ) { $dimensions.wc_set_content( variation.dimensions ); } else { $dimensions.wc_reset_content(); } form.$form.wc_variations_image_update( variation ); if ( ! variation.variation_is_visible ) { template = wp.template( 'unavailable-variation-template' ); } else { template = wp.template( 'variation-template' ); variation_id = variation.variation_id; } $template_html = template( { variation: variation } ); $template_html = $template_html.replace( '/*<![CDATA[*/', '' ); $template_html = $template_html.replace( '/*]]>*/', '' ); form.$singleVariation.html( $template_html ); form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( variation.variation_id ).change(); // Hide or show qty input if ( variation.is_sold_individually === 'yes' ) { $qty.find( 'input.qty' ).val( '1' ).attr( 'min', '1' ).attr( 'max', '' ); $qty.hide(); } else { $qty.find( 'input.qty' ).attr( 'min', variation.min_qty ).attr( 'max', variation.max_qty ); $qty.show(); } // Enable or disable the add to cart button if ( ! variation.is_purchasable || ! variation.is_in_stock || ! variation.variation_is_visible ) { purchasable = false; } // Reveal if ( $.trim( form.$singleVariation.text() ) ) { form.$singleVariation.slideDown( 200 ).trigger( 'show_variation', [ variation, purchasable ] ); } else { form.$singleVariation.show().trigger( 'show_variation', [ variation, purchasable ] ); } }; /** * Triggered when an attribute field changes. */ VariationForm.prototype.onChange = function( event ) { var form = event.data.variationForm; form.$form.find( 'input[name="variation_id"], input.variation_id' ).val( '' ).change(); form.$form.find( '.wc-no-matching-variations' ).remove(); if ( form.useAjax ) { form.$form.trigger( 'check_variations' ); } else { form.$form.trigger( 'woocommerce_variation_select_change' ); form.$form.trigger( 'check_variations' ); $( this ).blur(); } // Custom event for when variation selection has been changed form.$form.trigger( 'woocommerce_variation_has_changed' ); }; /** * Escape quotes in a string. * @param {string} string * @return {string} */ VariationForm.prototype.addSlashes = function( string ) { string = string.replace( /'/g, '\\\'' ); string = string.replace( /"/g, '\\\"' ); return string; }; /** * Updates attributes in the DOM to show valid values. */ VariationForm.prototype.onUpdateAttributes = function( event ) { var form = event.data.variationForm, attributes = form.getChosenAttributes(), currentAttributes = attributes.data; if ( form.useAjax ) { return; } // Loop through selects and disable/enable options based on selections. form.$attributeFields.each( function( index, el ) { var current_attr_select = $( el ), current_attr_name = current_attr_select.data( 'attribute_name' ) || current_attr_select.attr( 'name' ), show_option_none = $( el ).data( 'show_option_none' ), option_gt_filter = ':gt(0)', attached_options_count = 0, new_attr_select = $( '<select/>' ), selected_attr_val = current_attr_select.val() || '', selected_attr_val_valid = true; // Reference options set at first. if ( ! current_attr_select.data( 'attribute_html' ) ) { var refSelect = current_attr_select.clone(); refSelect.find( 'option' ).removeAttr( 'disabled attached' ).removeAttr( 'selected' ); current_attr_select.data( 'attribute_options', refSelect.find( 'option' + option_gt_filter ).get() ); // Legacy data attribute. current_attr_select.data( 'attribute_html', refSelect.html() ); } new_attr_select.html( current_attr_select.data( 'attribute_html' ) ); // The attribute of this select field should not be taken into account when calculating its matching variations: // The constraints of this attribute are shaped by the values of the other attributes. var checkAttributes = $.extend( true, {}, currentAttributes ); checkAttributes[ current_attr_name ] = ''; var variations = form.findMatchingVariations( form.variationData, checkAttributes ); // Loop through variations. for ( var num in variations ) { if ( typeof( variations[ num ] ) !== 'undefined' ) { var variationAttributes = variations[ num ].attributes; for ( var attr_name in variationAttributes ) { if ( variationAttributes.hasOwnProperty( attr_name ) ) { var attr_val = variationAttributes[ attr_name ], variation_active = ''; if ( attr_name === current_attr_name ) { if ( variations[ num ].variation_is_active ) { variation_active = 'enabled'; } if ( attr_val ) { // Decode entities and add slashes. attr_val = $( '<div/>' ).html( attr_val ).text(); // Attach. new_attr_select.find( 'option[value="' + form.addSlashes( attr_val ) + '"]' ).addClass( 'attached ' + variation_active ); } else { // Attach all apart from placeholder. new_attr_select.find( 'option:gt(0)' ).addClass( 'attached ' + variation_active ); } } } } } } // Count available options. attached_options_count = new_attr_select.find( 'option.attached' ).length; // Check if current selection is in attached options. if ( selected_attr_val && ( attached_options_count === 0 || new_attr_select.find( 'option.attached.enabled[value="' + form.addSlashes( selected_attr_val ) + '"]' ).length === 0 ) ) { selected_attr_val_valid = false; } // Detach the placeholder if: // - Valid options exist. // - The current selection is non-empty. // - The current selection is valid. // - Placeholders are not set to be permanently visible. if ( attached_options_count > 0 && selected_attr_val && selected_attr_val_valid && ( 'no' === show_option_none ) ) { new_attr_select.find( 'option:first' ).remove(); option_gt_filter = ''; } // Detach unattached. new_attr_select.find( 'option' + option_gt_filter + ':not(.attached)' ).remove(); // Finally, copy to DOM and set value. current_attr_select.html( new_attr_select.html() ); current_attr_select.find( 'option' + option_gt_filter + ':not(.enabled)' ).prop( 'disabled', true ); // Choose selected value. if ( selected_attr_val ) { // If the previously selected value is no longer available, fall back to the placeholder (it's going to be there). if ( selected_attr_val_valid ) { current_attr_select.val( selected_attr_val ); } else { current_attr_select.val( '' ).change(); } } else { current_attr_select.val( '' ); // No change event to prevent infinite loop. } }); // Custom event for when variations have been updated. form.$form.trigger( 'woocommerce_update_variation_values' ); }; /** * Get chosen attributes from form. * @return array */ VariationForm.prototype.getChosenAttributes = function() { var data = {}; var count = 0; var chosen = 0; this.$attributeFields.each( function() { var attribute_name = $( this ).data( 'attribute_name' ) || $( this ).attr( 'name' ); var value = $( this ).val() || ''; if ( value.length > 0 ) { chosen ++; } count ++; data[ attribute_name ] = value; }); return { 'count' : count, 'chosenCount': chosen, 'data' : data }; }; /** * Find matching variations for attributes. */ VariationForm.prototype.findMatchingVariations = function( variations, attributes ) { var matching = []; for ( var i = 0; i < variations.length; i++ ) { var variation = variations[i]; if ( this.isMatch( variation.attributes, attributes ) ) { matching.push( variation ); } } return matching; }; /** * See if attributes match. * @return {Boolean} */ VariationForm.prototype.isMatch = function( variation_attributes, attributes ) { var match = true; for ( var attr_name in variation_attributes ) { if ( variation_attributes.hasOwnProperty( attr_name ) ) { var val1 = variation_attributes[ attr_name ]; var val2 = attributes[ attr_name ]; if ( val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2 ) { match = false; } } } return match; }; /** * Show or hide the reset link. */ VariationForm.prototype.toggleResetLink = function( on ) { if ( on ) { if ( this.$resetVariations.css( 'visibility' ) === 'hidden' ) { this.$resetVariations.css( 'visibility', 'visible' ).hide().fadeIn(); } } else { this.$resetVariations.css( 'visibility', 'hidden' ); } }; /** * Function to call wc_variation_form on jquery selector. */ $.fn.wc_variation_form = function() { new VariationForm( this ); return this; }; /** * Stores the default text for an element so it can be reset later */ $.fn.wc_set_content = function( content ) { if ( undefined === this.attr( 'data-o_content' ) ) { this.attr( 'data-o_content', this.text() ); } this.text( content ); }; /** * Stores the default text for an element so it can be reset later */ $.fn.wc_reset_content = function() { if ( undefined !== this.attr( 'data-o_content' ) ) { this.text( this.attr( 'data-o_content' ) ); } }; /** * Stores a default attribute for an element so it can be reset later */ $.fn.wc_set_variation_attr = function( attr, value ) { if ( undefined === this.attr( 'data-o_' + attr ) ) { this.attr( 'data-o_' + attr, ( ! this.attr( attr ) ) ? '' : this.attr( attr ) ); } this.attr( attr, value ); }; /** * Reset a default attribute for an element so it can be reset later */ $.fn.wc_reset_variation_attr = function( attr ) { if ( undefined !== this.attr( 'data-o_' + attr ) ) { this.attr( attr, this.attr( 'data-o_' + attr ) ); } }; /** * Sets product images for the chosen variation */ $.fn.wc_variations_image_update = function( variation ) { var $form = this, $product = $form.closest('.product'), $product_img = $product.find( 'div.images img:eq(0)' ), $product_link = $product.find( 'div.images a.zoom:eq(0)' ); if ( variation && variation.image_src && variation.image_src.length > 1 ) { $product_img.wc_set_variation_attr( 'src', variation.image_src ); $product_img.wc_set_variation_attr( 'title', variation.image_title ); $product_img.wc_set_variation_attr( 'alt', variation.image_alt ); $product_img.wc_set_variation_attr( 'srcset', variation.image_srcset ); $product_img.wc_set_variation_attr( 'sizes', variation.image_sizes ); $product_link.wc_set_variation_attr( 'href', variation.image_link ); $product_link.wc_set_variation_attr( 'title', variation.image_caption ); } else { $product_img.wc_reset_variation_attr( 'src' ); $product_img.wc_reset_variation_attr( 'title' ); $product_img.wc_reset_variation_attr( 'alt' ); $product_img.wc_reset_variation_attr( 'srcset' ); $product_img.wc_reset_variation_attr( 'sizes' ); $product_link.wc_reset_variation_attr( 'href' ); $product_link.wc_reset_variation_attr( 'title' ); } }; $(function() { if ( typeof wc_add_to_cart_variation_params !== 'undefined' ) { $( '.variations_form' ).each( function() { $( this ).wc_variation_form(); }); } }); /** * Matches inline variation objects to chosen attributes * @deprecated 2.6.9 * @type {Object} */ var wc_variation_form_matcher = { find_matching_variations: function( product_variations, settings ) { var matching = []; for ( var i = 0; i < product_variations.length; i++ ) { var variation = product_variations[i]; if ( wc_variation_form_matcher.variations_match( variation.attributes, settings ) ) { matching.push( variation ); } } return matching; }, variations_match: function( attrs1, attrs2 ) { var match = true; for ( var attr_name in attrs1 ) { if ( attrs1.hasOwnProperty( attr_name ) ) { var val1 = attrs1[ attr_name ]; var val2 = attrs2[ attr_name ]; if ( val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2 ) { match = false; } } } return match; } }; })( jQuery, window, document ); woocommerce.js 0000666 00000000644 15214157447 0007443 0 ustar 00 jQuery( function( $ ) { // Orderby $( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() { $( this ).closest( 'form' ).submit(); }); // Target quantity inputs on product pages $( 'input.qty:not(.product-quantity input.qty)' ).each( function() { var min = parseFloat( $( this ).attr( 'min' ) ); if ( min >= 0 && parseFloat( $( this ).val() ) < min ) { $( this ).val( min ); } }); }); cart.min.js 0000666 00000015330 15214157447 0006635 0 ustar 00 jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")||a.parents(".processing").length},d=function(a){c(a)||a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a(".shop_table.cart",c).closest("form"),e=a(".cart_totals",c),f=a(".woocommerce-error",c),i=a(".woocommerce-message",c),j=a(".woocommerce-info",c);if(a(".woocommerce-error, .woocommerce-message, .woocommerce-info").remove(),0===d.length){if(a(".woocommerce-checkout").length)return void window.location.reload();var k=a(".cart-empty",c).closest(".woocommerce");a(".shop_table.cart").closest(".woocommerce").replaceWith(k),f.length>0&&h(f,a(".cart-empty").closest(".woocommerce")),i.length>0&&h(i,a(".cart-empty").closest(".woocommerce")),j.length>0&&h(j,a(".cart-empty").closest(".woocommerce"))}else a(".woocommerce-checkout").length&&a(document.body).trigger("update_checkout"),a(".shop_table.cart").closest("form").replaceWith(d),a(".shop_table.cart").closest("form").find('input[name="update_cart"]').prop("disabled",!0),f.length>0&&h(f),i.length>0&&h(i),j.length>0&&h(j),g(e);a(document.body).trigger("updated_wc_div")},g=function(b){a(".cart_totals").replaceWith(b),a(document.body).trigger("updated_cart_totals")},h=function(b,c){c||(c=a(".shop_table.cart").closest("form")),c.before(b)},i={init:function(b){this.cart=b,this.toggle_shipping=this.toggle_shipping.bind(this),this.shipping_method_selected=this.shipping_method_selected.bind(this),this.shipping_calculator_submit=this.shipping_calculator_submit.bind(this),a(document).on("click",".shipping-calculator-button",this.toggle_shipping),a(document).on("change","select.shipping_method, input[name^=shipping_method]",this.shipping_method_selected),a(document).on("submit","form.woocommerce-shipping-calculator",this.shipping_calculator_submit),a(".shipping-calculator-form").hide()},toggle_shipping:function(){return a(".shipping-calculator-form").slideToggle("slow"),!1},shipping_method_selected:function(c){var f=c.currentTarget,h={};a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){h[a(f).data("index")]=a(f).val()}),d(a("div.cart_totals"));var i={security:wc_cart_params.update_shipping_method_nonce,shipping_method:h};a.ajax({type:"post",url:b("update_shipping_method"),data:i,dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals")),a(document.body).trigger("updated_shipping_method")}})},shipping_calculator_submit:function(b){b.preventDefault();var c=a(b.currentTarget);d(a("div.cart_totals")),d(c),a("<input />").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c),e(a("div.cart_totals"))}})}},j={init:function(){this.update_cart_totals=this.update_cart_totals.bind(this),this.input_keypress=this.input_keypress.bind(this),this.cart_submit=this.cart_submit.bind(this),this.submit_click=this.submit_click.bind(this),this.apply_coupon=this.apply_coupon.bind(this),this.remove_coupon_clicked=this.remove_coupon_clicked.bind(this),this.quantity_update=this.quantity_update.bind(this),this.item_remove_clicked=this.item_remove_clicked.bind(this),this.update_cart=this.update_cart.bind(this),a(document).on("wc_update_cart",this.update_cart),a(document).on("click","div.woocommerce > form input[type=submit]",this.submit_click),a(document).on("keypress","div.woocommerce > form input[type=number]",this.input_keypress),a(document).on("submit","div.woocommerce:not(.widget_product_search) > form",this.cart_submit),a(document).on("click","a.woocommerce-remove-coupon",this.remove_coupon_clicked),a(document).on("click","td.product-remove > a",this.item_remove_clicked),a(document).on("change input","div.woocommerce > form .cart_item :input",this.input_changed),a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!0)},input_changed:function(){a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!1)},update_cart:function(){var b=a(".shop_table.cart").closest("form");d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(b),e(a("div.cart_totals"))}})},update_cart_totals:function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals"))}})},input_keypress:function(a){13===a.keyCode&&(a.preventDefault(),this.cart_submit(a))},cart_submit:function(b){var d=a(document.activeElement),e=a("input[type=submit][clicked=true]"),f=a(b.currentTarget);if(f.is("form")||(f=a(b.currentTarget).parents("form")),0!==f.find(".shop_table.cart").length)return!c(f)&&void(e.is('[name="update_cart"]')||d.is("input.qty")?(b.preventDefault(),this.quantity_update(f)):(e.is('[name="apply_coupon"]')||d.is("#coupon_code"))&&(b.preventDefault(),this.apply_coupon(f)))},submit_click:function(b){a("input[type=submit]",a(b.target).parents("form")).removeAttr("clicked"),a(b.target).attr("clicked","true")},apply_coupon:function(c){d(c);var f=this,g=a("#coupon_code"),i=g.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(b){a(".woocommerce-error, .woocommerce-message, .woocommerce-info").remove(),h(b),a(document.body).trigger("applied_coupon")},complete:function(){e(c),g.val(""),f.update_cart_totals()}})},remove_coupon_clicked:function(c){c.preventDefault();var f=this,g=a(c.currentTarget).parents("tr"),i=a(c.currentTarget).attr("data-coupon");d(g.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(b){a(".woocommerce-error, .woocommerce-message, .woocommerce-info").remove(),h(b),a(document.body).trigger("removed_coupon"),e(g.parents("table"))},complete:function(){f.update_cart_totals()}})},quantity_update:function(b){a("<input />").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b),e(a("div.cart_totals"))}})},item_remove_clicked:function(b){b.preventDefault();var c=a(b.currentTarget),g=c.parents("form");d(g),d(a("div.cart_totals")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g),e(a("div.cart_totals"))}})}};i.init(j),j.init()}); geolocation.min.js 0000666 00000002207 15214157447 0010206 0 ustar 00 jQuery(function(a){var b=window.location.toString(),c=function(){wc_geolocation_params.hash&&a('a[href^="'+wc_geolocation_params.home_url+'"]:not(a[href*="v="]), a[href^="/"]:not(a[href*="v="])').each(function(){var b=a(this),c=b.attr("href");c.indexOf("?")>0?b.attr("href",c+"&v="+wc_geolocation_params.hash):b.attr("href",c+"?v="+wc_geolocation_params.hash)})},d=function(a){b=b.indexOf("?v=")>0||b.indexOf("&v=")>0?b.replace(/v=[^&]+/,"v="+a):b.indexOf("?")>0?b+"&v="+a:b+"?v="+a,window.location=b},e={url:wc_geolocation_params.wc_ajax_url.toString().replace("%%endpoint%%","get_customer_location"),type:"GET",success:function(a){a.success&&a.data.hash&&a.data.hash!==wc_geolocation_params.hash&&d(a.data.hash)}};"1"===wc_geolocation_params.is_available&&(a.ajax(e),a("form").each(function(){var b=a(this),c=b.attr("method");if(c&&"get"===c.toLowerCase())b.append('<input type="hidden" name="v" value="'+wc_geolocation_params.hash+'" />');else{var d=b.attr("action");d&&(d.indexOf("?")>0?b.attr("action",d+"&v="+wc_geolocation_params.hash):b.attr("action",d+"?v="+wc_geolocation_params.hash))}}),c()),a(document.body).on("added_to_cart",function(){c()})}); credit-card-form.min.js 0000666 00000001006 15214157447 0011021 0 ustar 00 jQuery(function(a){a(".wc-credit-card-form-card-number").payment("formatCardNumber"),a(".wc-credit-card-form-card-expiry").payment("formatCardExpiry"),a(".wc-credit-card-form-card-cvc").payment("formatCardCVC"),a(document.body).on("updated_checkout wc-credit-card-form-init",function(){a(".wc-credit-card-form-card-number").payment("formatCardNumber"),a(".wc-credit-card-form-card-expiry").payment("formatCardExpiry"),a(".wc-credit-card-form-card-cvc").payment("formatCardCVC")}).trigger("wc-credit-card-form-init")}); lost-password.min.js 0000666 00000000203 15214157447 0010516 0 ustar 00 jQuery(function(a){a(".lost_reset_password").on("submit",function(){a('input[type="submit"]',this).attr("disabled","disabled")})}); single-product.js 0000666 00000005075 15214157447 0010066 0 ustar 00 /*global wc_single_product_params */ jQuery( function( $ ) { // wc_single_product_params is required to continue, ensure the object exists if ( typeof wc_single_product_params === 'undefined' ) { return false; } // Tabs $( 'body' ) .on( 'init', '.wc-tabs-wrapper, .woocommerce-tabs', function() { $( '.wc-tab, .woocommerce-tabs .panel:not(.panel .panel)' ).hide(); var hash = window.location.hash; var url = window.location.href; var $tabs = $( this ).find( '.wc-tabs, ul.tabs' ).first(); if ( hash.toLowerCase().indexOf( 'comment-' ) >= 0 || hash === '#reviews' || hash === '#tab-reviews' ) { $tabs.find( 'li.reviews_tab a' ).click(); } else if ( url.indexOf( 'comment-page-' ) > 0 || url.indexOf( 'cpage=' ) > 0 ) { $tabs.find( 'li.reviews_tab a' ).click(); } else { $tabs.find( 'li:first a' ).click(); } }) .on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) { e.preventDefault(); var $tab = $( this ); var $tabs_wrapper = $tab.closest( '.wc-tabs-wrapper, .woocommerce-tabs' ); var $tabs = $tabs_wrapper.find( '.wc-tabs, ul.tabs' ); $tabs.find( 'li' ).removeClass( 'active' ); $tabs_wrapper.find( '.wc-tab, .panel:not(.panel .panel)' ).hide(); $tab.closest( 'li' ).addClass( 'active' ); $tabs_wrapper.find( $tab.attr( 'href' ) ).show(); }) // Review link .on( 'click', 'a.woocommerce-review-link', function() { $( '.reviews_tab a' ).click(); return true; }) // Star ratings for comments .on( 'init', '#rating', function() { $( '#rating' ).hide().before( '<p class="stars"><span><a class="star-1" href="#">1</a><a class="star-2" href="#">2</a><a class="star-3" href="#">3</a><a class="star-4" href="#">4</a><a class="star-5" href="#">5</a></span></p>' ); }) .on( 'click', '#respond p.stars a', function() { var $star = $( this ), $rating = $( this ).closest( '#respond' ).find( '#rating' ), $container = $( this ).closest( '.stars' ); $rating.val( $star.text() ); $star.siblings( 'a' ).removeClass( 'active' ); $star.addClass( 'active' ); $container.addClass( 'selected' ); return false; }) .on( 'click', '#respond #submit', function() { var $rating = $( this ).closest( '#respond' ).find( '#rating' ), rating = $rating.val(); if ( $rating.length > 0 && ! rating && wc_single_product_params.review_rating_required === 'yes' ) { window.alert( wc_single_product_params.i18n_required_rating_text ); return false; } }); //Init Tabs and Star Ratings $( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' ); }); price-slider.js 0000666 00000005715 15214157447 0007512 0 ustar 00 /* global woocommerce_price_slider_params */ jQuery( function( $ ) { // woocommerce_price_slider_params is required to continue, ensure the object exists if ( typeof woocommerce_price_slider_params === 'undefined' ) { return false; } // Get markup ready for slider $( 'input#min_price, input#max_price' ).hide(); $( '.price_slider, .price_label' ).show(); // Price slider uses jquery ui var min_price = $( '.price_slider_amount #min_price' ).data( 'min' ), max_price = $( '.price_slider_amount #max_price' ).data( 'max' ), current_min_price = parseInt( min_price, 10 ), current_max_price = parseInt( max_price, 10 ); if ( woocommerce_price_slider_params.min_price ) { current_min_price = parseInt( woocommerce_price_slider_params.min_price, 10 ); } if ( woocommerce_price_slider_params.max_price ) { current_max_price = parseInt( woocommerce_price_slider_params.max_price, 10 ); } $( document.body ).bind( 'price_slider_create price_slider_slide', function( event, min, max ) { if ( woocommerce_price_slider_params.currency_pos === 'left' ) { $( '.price_slider_amount span.from' ).html( woocommerce_price_slider_params.currency_symbol + min ); $( '.price_slider_amount span.to' ).html( woocommerce_price_slider_params.currency_symbol + max ); } else if ( woocommerce_price_slider_params.currency_pos === 'left_space' ) { $( '.price_slider_amount span.from' ).html( woocommerce_price_slider_params.currency_symbol + ' ' + min ); $( '.price_slider_amount span.to' ).html( woocommerce_price_slider_params.currency_symbol + ' ' + max ); } else if ( woocommerce_price_slider_params.currency_pos === 'right' ) { $( '.price_slider_amount span.from' ).html( min + woocommerce_price_slider_params.currency_symbol ); $( '.price_slider_amount span.to' ).html( max + woocommerce_price_slider_params.currency_symbol ); } else if ( woocommerce_price_slider_params.currency_pos === 'right_space' ) { $( '.price_slider_amount span.from' ).html( min + ' ' + woocommerce_price_slider_params.currency_symbol ); $( '.price_slider_amount span.to' ).html( max + ' ' + woocommerce_price_slider_params.currency_symbol ); } $( document.body ).trigger( 'price_slider_updated', [ min, max ] ); }); $( '.price_slider' ).slider({ range: true, animate: true, min: min_price, max: max_price, values: [ current_min_price, current_max_price ], create: function() { $( '.price_slider_amount #min_price' ).val( current_min_price ); $( '.price_slider_amount #max_price' ).val( current_max_price ); $( document.body ).trigger( 'price_slider_create', [ current_min_price, current_max_price ] ); }, slide: function( event, ui ) { $( 'input#min_price' ).val( ui.values[0] ); $( 'input#max_price' ).val( ui.values[1] ); $( document.body ).trigger( 'price_slider_slide', [ ui.values[0], ui.values[1] ] ); }, change: function( event, ui ) { $( document.body ).trigger( 'price_slider_change', [ ui.values[0], ui.values[1] ] ); } }); }); add-payment-method.js 0000666 00000002103 15214157447 0010575 0 ustar 00 jQuery( function( $ ) { // woocommerce_params is required to continue, ensure the object exists if ( typeof woocommerce_params === 'undefined' ) { return false; } $( '#add_payment_method' ) /* Payment option selection */ .on( 'click init_add_payment_method', '.payment_methods input.input-radio', function() { if ( $( '.payment_methods input.input-radio' ).length > 1 ) { var target_payment_box = $( 'div.payment_box.' + $( this ).attr( 'ID' ) ); if ( $( this ).is( ':checked' ) && ! target_payment_box.is( ':visible' ) ) { $( 'div.payment_box' ).filter( ':visible' ).slideUp( 250 ); if ( $( this ).is( ':checked' ) ) { $( 'div.payment_box.' + $( this ).attr( 'ID' ) ).slideDown( 250 ); } } } else { $( 'div.payment_box' ).show(); } }) // Trigger initial click .find( 'input[name=payment_method]:checked' ).click(); $( '#add_payment_method' ).submit( function() { $( '#add_payment_method' ).block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } }); }); $( document.body ).trigger( 'init_add_payment_method' ); }); country-select.js 0000666 00000012167 15214157447 0010107 0 ustar 00 /*global wc_country_select_params */ jQuery( function( $ ) { // wc_country_select_params is required to continue, ensure the object exists if ( typeof wc_country_select_params === 'undefined' ) { return false; } function getEnhancedSelectFormatString() { var formatString = { formatMatches: function( matches ) { if ( 1 === matches ) { return wc_country_select_params.i18n_matches_1; } return wc_country_select_params.i18n_matches_n.replace( '%qty%', matches ); }, formatNoMatches: function() { return wc_country_select_params.i18n_no_matches; }, formatAjaxError: function() { return wc_country_select_params.i18n_ajax_error; }, formatInputTooShort: function( input, min ) { var number = min - input.length; if ( 1 === number ) { return wc_country_select_params.i18n_input_too_short_1; } return wc_country_select_params.i18n_input_too_short_n.replace( '%qty%', number ); }, formatInputTooLong: function( input, max ) { var number = input.length - max; if ( 1 === number ) { return wc_country_select_params.i18n_input_too_long_1; } return wc_country_select_params.i18n_input_too_long_n.replace( '%qty%', number ); }, formatSelectionTooBig: function( limit ) { if ( 1 === limit ) { return wc_country_select_params.i18n_selection_too_long_1; } return wc_country_select_params.i18n_selection_too_long_n.replace( '%qty%', limit ); }, formatLoadMore: function() { return wc_country_select_params.i18n_load_more; }, formatSearching: function() { return wc_country_select_params.i18n_searching; } }; return formatString; } // Select2 Enhancement if it exists if ( $().select2 ) { var wc_country_select_select2 = function() { $( 'select.country_select:visible, select.state_select:visible' ).each( function() { var select2_args = $.extend({ placeholderOption: 'first', width: '100%' }, getEnhancedSelectFormatString() ); $( this ).select2( select2_args ); }); }; wc_country_select_select2(); $( document.body ).bind( 'country_to_state_changed', function() { wc_country_select_select2(); }); } /* State/Country select boxes */ var states_json = wc_country_select_params.countries.replace( /"/g, '"' ), states = $.parseJSON( states_json ); $( document.body ).on( 'change', 'select.country_to_state, input.country_to_state', function() { // Grab wrapping element to target only stateboxes in same 'group' var $wrapper = $( this ).closest('.woocommerce-billing-fields, .woocommerce-shipping-fields, .woocommerce-shipping-calculator'); if ( ! $wrapper.length ) { $wrapper = $( this ).closest('.form-row').parent(); } var country = $( this ).val(), $statebox = $wrapper.find( '#billing_state, #shipping_state, #calc_shipping_state' ), $parent = $statebox.parent(), input_name = $statebox.attr( 'name' ), input_id = $statebox.attr( 'id' ), value = $statebox.val(), placeholder = $statebox.attr( 'placeholder' ) || $statebox.attr( 'data-placeholder' ) || ''; if ( states[ country ] ) { if ( $.isEmptyObject( states[ country ] ) ) { $statebox.parent().hide().find( '.select2-container' ).remove(); $statebox.replaceWith( '<input type="hidden" class="hidden" name="' + input_name + '" id="' + input_id + '" value="" placeholder="' + placeholder + '" />' ); $( document.body ).trigger( 'country_to_state_changed', [ country, $wrapper ] ); } else { var options = '', state = states[ country ]; for( var index in state ) { if ( state.hasOwnProperty( index ) ) { options = options + '<option value="' + index + '">' + state[ index ] + '</option>'; } } $statebox.parent().show(); if ( $statebox.is( 'input' ) ) { // Change for select $statebox.replaceWith( '<select name="' + input_name + '" id="' + input_id + '" class="state_select" data-placeholder="' + placeholder + '"></select>' ); $statebox = $wrapper.find( '#billing_state, #shipping_state, #calc_shipping_state' ); } $statebox.html( '<option value="">' + wc_country_select_params.i18n_select_state_text + '</option>' + options ); $statebox.val( value ).change(); $( document.body ).trigger( 'country_to_state_changed', [country, $wrapper ] ); } } else { if ( $statebox.is( 'select' ) ) { $parent.show().find( '.select2-container' ).remove(); $statebox.replaceWith( '<input type="text" class="input-text" name="' + input_name + '" id="' + input_id + '" placeholder="' + placeholder + '" />' ); $( document.body ).trigger( 'country_to_state_changed', [country, $wrapper ] ); } else if ( $statebox.is( 'input[type="hidden"]' ) ) { $parent.show().find( '.select2-container' ).remove(); $statebox.replaceWith( '<input type="text" class="input-text" name="' + input_name + '" id="' + input_id + '" placeholder="' + placeholder + '" />' ); $( document.body ).trigger( 'country_to_state_changed', [country, $wrapper ] ); } } $( document.body ).trigger( 'country_to_state_changing', [country, $wrapper ] ); }); $(function() { $( ':input.country_to_state' ).change(); }); }); add-payment-method.min.js 0000666 00000001334 15214157447 0011364 0 ustar 00 jQuery(function(a){return"undefined"!=typeof woocommerce_params&&(a("#add_payment_method").on("click init_add_payment_method",".payment_methods input.input-radio",function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show()}).find("input[name=payment_method]:checked").click(),a("#add_payment_method").submit(function(){a("#add_payment_method").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}),void a(document.body).trigger("init_add_payment_method"))}); add-to-cart-variation.min.js 0000666 00000024044 15214157447 0011777 0 ustar 00 !function(a,b,c,d){var e=function(a){this.$form=a,this.$attributeFields=a.find(".variations select"),this.$singleVariation=a.find(".single_variation"),this.$singleVariationWrap=a.find(".single_variation_wrap"),this.$resetVariations=a.find(".reset_variations"),this.$product=a.closest(".product"),this.variationData=a.data("product_variations"),this.useAjax=!1===this.variationData,this.xhr=!1,this.$singleVariationWrap.show(),this.$form.unbind("check_variations update_variation_values found_variation"),this.$resetVariations.unbind("click"),this.$attributeFields.unbind("change "),this.getChosenAttributes=this.getChosenAttributes.bind(this),this.findMatchingVariations=this.findMatchingVariations.bind(this),this.isMatch=this.isMatch.bind(this),this.toggleResetLink=this.toggleResetLink.bind(this),a.on("click",".reset_variations",{variationForm:this},this.onReset),a.on("reload_product_variations",{variationForm:this},this.onReload),a.on("hide_variation",{variationForm:this},this.onHide),a.on("show_variation",{variationForm:this},this.onShow),a.on("click",".single_add_to_cart_button",{variationForm:this},this.onAddToCart),a.on("reset_data",{variationForm:this},this.onResetDisplayedVariation),a.on("reset_image",{variationForm:this},this.onResetImage),a.on("change",".variations select",{variationForm:this},this.onChange),a.on("found_variation",{variationForm:this},this.onFoundVariation),a.on("check_variations",{variationForm:this},this.onFindVariation),a.on("update_variation_values",{variationForm:this},this.onUpdateAttributes),a.trigger("check_variations"),a.trigger("wc_variation_form")};e.prototype.onReset=function(a){a.preventDefault(),a.data.variationForm.$attributeFields.val("").change(),a.data.variationForm.$form.trigger("reset_data")},e.prototype.onReload=function(a){var b=a.data.variationForm;b.variationData=b.$form.data("product_variations"),b.useAjax=!1===b.variationData,b.$form.trigger("check_variations")},e.prototype.onHide=function(a){a.preventDefault(),a.data.variationForm.$form.find(".single_add_to_cart_button").removeClass("wc-variation-is-unavailable").addClass("disabled wc-variation-selection-needed"),a.data.variationForm.$form.find(".woocommerce-variation-add-to-cart").removeClass("woocommerce-variation-add-to-cart-enabled").addClass("woocommerce-variation-add-to-cart-disabled")},e.prototype.onShow=function(a,b,c){a.preventDefault(),c?(a.data.variationForm.$form.find(".single_add_to_cart_button").removeClass("disabled wc-variation-selection-needed wc-variation-is-unavailable"),a.data.variationForm.$form.find(".woocommerce-variation-add-to-cart").removeClass("woocommerce-variation-add-to-cart-disabled").addClass("woocommerce-variation-add-to-cart-enabled")):(a.data.variationForm.$form.find(".single_add_to_cart_button").removeClass("wc-variation-selection-needed").addClass("disabled wc-variation-is-unavailable"),a.data.variationForm.$form.find(".woocommerce-variation-add-to-cart").removeClass("woocommerce-variation-add-to-cart-enabled").addClass("woocommerce-variation-add-to-cart-disabled"))},e.prototype.onAddToCart=function(c){a(this).is(".disabled")&&(c.preventDefault(),a(this).is(".wc-variation-is-unavailable")?b.alert(wc_add_to_cart_variation_params.i18n_unavailable_text):a(this).is(".wc-variation-selection-needed")&&b.alert(wc_add_to_cart_variation_params.i18n_make_a_selection_text))},e.prototype.onResetDisplayedVariation=function(a){var b=a.data.variationForm;b.$product.find(".product_meta").find(".sku").wc_reset_content(),b.$product.find(".product_weight").wc_reset_content(),b.$product.find(".product_dimensions").wc_reset_content(),b.$form.trigger("reset_image"),b.$singleVariation.slideUp(200).trigger("hide_variation")},e.prototype.onResetImage=function(a){a.data.variationForm.$form.wc_variations_image_update(!1)},e.prototype.onFindVariation=function(c){var d=c.data.variationForm,e=d.getChosenAttributes(),f=e.data;if(e.count===e.chosenCount)if(d.useAjax)d.xhr&&d.xhr.abort(),d.$form.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),f.product_id=parseInt(d.$form.data("product_id"),10),f.custom_data=d.$form.data("custom_data"),d.xhr=a.ajax({url:wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%","get_variation"),type:"POST",data:f,success:function(a){a?d.$form.trigger("found_variation",[a]):(d.$form.trigger("reset_data"),d.$form.find(".single_variation").after('<p class="wc-no-matching-variations woocommerce-info">'+wc_add_to_cart_variation_params.i18n_no_matching_variations_text+"</p>"),d.$form.find(".wc-no-matching-variations").slideDown(200))},complete:function(){d.$form.unblock()}});else{d.$form.trigger("update_variation_values");var g=d.findMatchingVariations(d.variationData,f),h=g.shift();h?d.$form.trigger("found_variation",[h]):(b.alert(wc_add_to_cart_variation_params.i18n_no_matching_variations_text),d.$form.trigger("reset_data"))}else d.$form.trigger("update_variation_values"),d.$form.trigger("reset_data");d.toggleResetLink(e.chosenCount>0),a(".product.has-default-attributes > .images").fadeTo(200,1)},e.prototype.onFoundVariation=function(b,c){var d=b.data.variationForm,e=d.$product.find(".product_meta").find(".sku"),f=d.$product.find(".product_weight"),g=d.$product.find(".product_dimensions"),h=d.$singleVariationWrap.find(".quantity"),i=!0,j="",k=!1,l="";c.sku?e.wc_set_content(c.sku):e.wc_reset_content(),c.weight?f.wc_set_content(c.weight):f.wc_reset_content(),c.dimensions?g.wc_set_content(c.dimensions):g.wc_reset_content(),d.$form.wc_variations_image_update(c),c.variation_is_visible?(k=wp.template("variation-template"),j=c.variation_id):k=wp.template("unavailable-variation-template"),l=k({variation:c}),l=l.replace("/*<![CDATA[*/",""),l=l.replace("/*]]>*/",""),d.$singleVariation.html(l),d.$form.find('input[name="variation_id"], input.variation_id').val(c.variation_id).change(),"yes"===c.is_sold_individually?(h.find("input.qty").val("1").attr("min","1").attr("max",""),h.hide()):(h.find("input.qty").attr("min",c.min_qty).attr("max",c.max_qty),h.show()),c.is_purchasable&&c.is_in_stock&&c.variation_is_visible||(i=!1),a.trim(d.$singleVariation.text())?d.$singleVariation.slideDown(200).trigger("show_variation",[c,i]):d.$singleVariation.show().trigger("show_variation",[c,i])},e.prototype.onChange=function(b){var c=b.data.variationForm;c.$form.find('input[name="variation_id"], input.variation_id').val("").change(),c.$form.find(".wc-no-matching-variations").remove(),c.useAjax?c.$form.trigger("check_variations"):(c.$form.trigger("woocommerce_variation_select_change"),c.$form.trigger("check_variations"),a(this).blur()),c.$form.trigger("woocommerce_variation_has_changed")},e.prototype.addSlashes=function(a){return a=a.replace(/'/g,"\\'"),a=a.replace(/"/g,'\\"')},e.prototype.onUpdateAttributes=function(b){var c=b.data.variationForm,d=c.getChosenAttributes(),e=d.data;c.useAjax||(c.$attributeFields.each(function(b,d){var f=a(d),g=f.data("attribute_name")||f.attr("name"),h=a(d).data("show_option_none"),i=":gt(0)",j=0,k=a("<select/>"),l=f.val()||"",m=!0;if(!f.data("attribute_html")){var n=f.clone();n.find("option").removeAttr("disabled attached").removeAttr("selected"),f.data("attribute_options",n.find("option"+i).get()),f.data("attribute_html",n.html())}k.html(f.data("attribute_html"));var o=a.extend(!0,{},e);o[g]="";var p=c.findMatchingVariations(c.variationData,o);for(var q in p)if("undefined"!=typeof p[q]){var r=p[q].attributes;for(var s in r)if(r.hasOwnProperty(s)){var t=r[s],u="";s===g&&(p[q].variation_is_active&&(u="enabled"),t?(t=a("<div/>").html(t).text(),k.find('option[value="'+c.addSlashes(t)+'"]').addClass("attached "+u)):k.find("option:gt(0)").addClass("attached "+u))}}j=k.find("option.attached").length,!l||0!==j&&0!==k.find('option.attached.enabled[value="'+c.addSlashes(l)+'"]').length||(m=!1),j>0&&l&&m&&"no"===h&&(k.find("option:first").remove(),i=""),k.find("option"+i+":not(.attached)").remove(),f.html(k.html()),f.find("option"+i+":not(.enabled)").prop("disabled",!0),l?m?f.val(l):f.val("").change():f.val("")}),c.$form.trigger("woocommerce_update_variation_values"))},e.prototype.getChosenAttributes=function(){var b={},c=0,d=0;return this.$attributeFields.each(function(){var e=a(this).data("attribute_name")||a(this).attr("name"),f=a(this).val()||"";f.length>0&&d++,c++,b[e]=f}),{count:c,chosenCount:d,data:b}},e.prototype.findMatchingVariations=function(a,b){for(var c=[],d=0;d<a.length;d++){var e=a[d];this.isMatch(e.attributes,b)&&c.push(e)}return c},e.prototype.isMatch=function(a,b){var c=!0;for(var e in a)if(a.hasOwnProperty(e)){var f=a[e],g=b[e];f!==d&&g!==d&&0!==f.length&&0!==g.length&&f!==g&&(c=!1)}return c},e.prototype.toggleResetLink=function(a){a?"hidden"===this.$resetVariations.css("visibility")&&this.$resetVariations.css("visibility","visible").hide().fadeIn():this.$resetVariations.css("visibility","hidden")},a.fn.wc_variation_form=function(){return new e(this),this},a.fn.wc_set_content=function(a){d===this.attr("data-o_content")&&this.attr("data-o_content",this.text()),this.text(a)},a.fn.wc_reset_content=function(){d!==this.attr("data-o_content")&&this.text(this.attr("data-o_content"))},a.fn.wc_set_variation_attr=function(a,b){d===this.attr("data-o_"+a)&&this.attr("data-o_"+a,this.attr(a)?this.attr(a):""),this.attr(a,b)},a.fn.wc_reset_variation_attr=function(a){d!==this.attr("data-o_"+a)&&this.attr(a,this.attr("data-o_"+a))},a.fn.wc_variations_image_update=function(a){var b=this,c=b.closest(".product"),d=c.find("div.images img:eq(0)"),e=c.find("div.images a.zoom:eq(0)");a&&a.image_src&&a.image_src.length>1?(d.wc_set_variation_attr("src",a.image_src),d.wc_set_variation_attr("title",a.image_title),d.wc_set_variation_attr("alt",a.image_alt),d.wc_set_variation_attr("srcset",a.image_srcset),d.wc_set_variation_attr("sizes",a.image_sizes),e.wc_set_variation_attr("href",a.image_link),e.wc_set_variation_attr("title",a.image_caption)):(d.wc_reset_variation_attr("src"),d.wc_reset_variation_attr("title"),d.wc_reset_variation_attr("alt"),d.wc_reset_variation_attr("srcset"),d.wc_reset_variation_attr("sizes"),e.wc_reset_variation_attr("href"),e.wc_reset_variation_attr("title"))},a(function(){"undefined"!=typeof wc_add_to_cart_variation_params&&a(".variations_form").each(function(){a(this).wc_variation_form()})})}(jQuery,window,document); credit-card-form.js 0000666 00000001114 15214157447 0010237 0 ustar 00 jQuery( function( $ ) { $( '.wc-credit-card-form-card-number' ).payment( 'formatCardNumber' ); $( '.wc-credit-card-form-card-expiry' ).payment( 'formatCardExpiry' ); $( '.wc-credit-card-form-card-cvc' ).payment( 'formatCardCVC' ); $( document.body ) .on( 'updated_checkout wc-credit-card-form-init', function() { $( '.wc-credit-card-form-card-number' ).payment( 'formatCardNumber' ); $( '.wc-credit-card-form-card-expiry' ).payment( 'formatCardExpiry' ); $( '.wc-credit-card-form-card-cvc' ).payment( 'formatCardCVC' ); }) .trigger( 'wc-credit-card-form-init' ); } ); tokenization-form.js 0000666 00000005453 15214157447 0010606 0 ustar 00 ( function( $ ) { $( function() { var wcTokenizationForm = (function() { function wcTokenizationForm( target ) { var $target = $( target ), $formWrap = $target.closest( '.payment_box' ), $wcTokenizationForm = this; this.onTokenChange = function() { if ( 'new' === $( this ).val() ) { $wcTokenizationForm.showForm(); $wcTokenizationForm.showSaveNewCheckbox(); } else { $wcTokenizationForm.hideForm(); $wcTokenizationForm.hideSaveNewCheckbox(); } }; this.onCreateAccountChange = function() { if ( $( this ).is( ':checked' ) ) { $wcTokenizationForm.showSaveNewCheckbox(); } else { $wcTokenizationForm.hideSaveNewCheckbox(); } }; this.onDisplay = function() { // Make sure a radio button is selected if there is no is_default for this payment method.. if ( 0 === $( ':input.woocommerce-SavedPaymentMethods-tokenInput:checked', $target ).length ) { $( ':input.woocommerce-SavedPaymentMethods-tokenInput:last', $target ).prop( 'checked', true ); } // Don't show the "use new" radio button if we only have one method.. if ( 0 === $target.data( 'count' ) ) { $( '.woocommerce-SavedPaymentMethods-new', $target ).hide(); } // Trigger change event $( ':input.woocommerce-SavedPaymentMethods-tokenInput:checked', $target ).trigger( 'change' ); // Hide "save card" if "Create Account" is not checked. // Check that the field is shown in the form - some plugins and force create account remove it if ( $( 'input#createaccount' ).length && ! $('input#createaccount').is( ':checked' ) ) { $wcTokenizationForm.hideSaveNewCheckbox(); } }; this.hideForm = function() { $( '.wc-payment-form', $formWrap ).hide(); }; this.showForm = function() { $( '.wc-payment-form', $formWrap ).show(); }; this.showSaveNewCheckbox = function() { $( '.woocommerce-SavedPaymentMethods-saveNew', $formWrap ).show(); }; this.hideSaveNewCheckbox = function() { $( '.woocommerce-SavedPaymentMethods-saveNew', $formWrap ).hide(); }; // When a radio button is changed, make sure to show/hide our new CC info area $( ':input.woocommerce-SavedPaymentMethods-tokenInput', $target ).change( this.onTokenChange ); // OR if create account is checked $ ( 'input#createaccount' ).change( this.onCreateAccountChange ); this.onDisplay(); } return wcTokenizationForm; })(); $( document.body ).on( 'updated_checkout wc-credit-card-form-init', function() { // Loop over gateways with saved payment methods var $saved_payment_methods = $( 'ul.woocommerce-SavedPaymentMethods' ); $saved_payment_methods.each( function() { new wcTokenizationForm( this ); } ); } ); }); })( jQuery ); price-slider.min.js 0000666 00000004126 15214157447 0010267 0 ustar 00 jQuery(function(a){if("undefined"==typeof woocommerce_price_slider_params)return!1;a("input#min_price, input#max_price").hide(),a(".price_slider, .price_label").show();var b=a(".price_slider_amount #min_price").data("min"),c=a(".price_slider_amount #max_price").data("max"),d=parseInt(b,10),e=parseInt(c,10);woocommerce_price_slider_params.min_price&&(d=parseInt(woocommerce_price_slider_params.min_price,10)),woocommerce_price_slider_params.max_price&&(e=parseInt(woocommerce_price_slider_params.max_price,10)),a(document.body).bind("price_slider_create price_slider_slide",function(b,c,d){"left"===woocommerce_price_slider_params.currency_pos?(a(".price_slider_amount span.from").html(woocommerce_price_slider_params.currency_symbol+c),a(".price_slider_amount span.to").html(woocommerce_price_slider_params.currency_symbol+d)):"left_space"===woocommerce_price_slider_params.currency_pos?(a(".price_slider_amount span.from").html(woocommerce_price_slider_params.currency_symbol+" "+c),a(".price_slider_amount span.to").html(woocommerce_price_slider_params.currency_symbol+" "+d)):"right"===woocommerce_price_slider_params.currency_pos?(a(".price_slider_amount span.from").html(c+woocommerce_price_slider_params.currency_symbol),a(".price_slider_amount span.to").html(d+woocommerce_price_slider_params.currency_symbol)):"right_space"===woocommerce_price_slider_params.currency_pos&&(a(".price_slider_amount span.from").html(c+" "+woocommerce_price_slider_params.currency_symbol),a(".price_slider_amount span.to").html(d+" "+woocommerce_price_slider_params.currency_symbol)),a(document.body).trigger("price_slider_updated",[c,d])}),a(".price_slider").slider({range:!0,animate:!0,min:b,max:c,values:[d,e],create:function(){a(".price_slider_amount #min_price").val(d),a(".price_slider_amount #max_price").val(e),a(document.body).trigger("price_slider_create",[d,e])},slide:function(b,c){a("input#min_price").val(c.values[0]),a("input#max_price").val(c.values[1]),a(document.body).trigger("price_slider_slide",[c.values[0],c.values[1]])},change:function(b,c){a(document.body).trigger("price_slider_change",[c.values[0],c.values[1]])}})}); address-i18n.min.js 0000666 00000003676 15214157447 0010120 0 ustar 00 jQuery(function(a){function b(a,b){b?(a.find("label").append(' <abbr class="required" title="'+wc_address_i18n_params.i18n_required_text+'">*</abbr>'),a.addClass("validate-required")):(a.find("label abbr").remove(),a.removeClass("validate-required"))}if("undefined"==typeof wc_address_i18n_params)return!1;var c=wc_address_i18n_params.locale.replace(/"/g,'"'),d=a.parseJSON(c);a(document.body).bind("country_to_state_changing",function(c,e,f){var g,h=f;g="undefined"!=typeof d[e]?d[e]:d.default;var i=h.find("#billing_postcode_field, #shipping_postcode_field"),j=h.find("#billing_city_field, #shipping_city_field"),k=h.find("#billing_state_field, #shipping_state_field");i.attr("data-o_class")||(i.attr("data-o_class",i.attr("class")),j.attr("data-o_class",j.attr("class")),k.attr("data-o_class",k.attr("class"))),g.postcode_before_city?(i.add(j).add(k).removeClass("form-row-first form-row-last").addClass("form-row-first"),j.removeClass("form-row-wide form-row-first").addClass("form-row-last"),i.insertBefore(j)):(i.attr("class",i.attr("data-o_class")),j.attr("class",j.attr("data-o_class")),k.attr("class",k.attr("data-o_class")),i.insertAfter(k));var l=a.parseJSON(wc_address_i18n_params.locale_fields);a.each(l,function(a,c){var e=h.find(c);g[a]?(g[a].label&&e.find("label").html(g[a].label),g[a].placeholder&&e.find("input").attr("placeholder",g[a].placeholder),b(e,!1),"undefined"==typeof g[a].required&&d.default[a].required===!0?b(e,!0):g[a].required===!0&&b(e,!0),"state"!==a&&(g[a].hidden===!0?e.hide().find("input").val(""):e.show())):d.default[a]&&("state"!==a&&("undefined"==typeof d.default[a].hidden||d.default[a].hidden===!1?e.show():d.default[a].hidden===!0&&e.hide().find("input").val("")),"postcode"!==a&&"city"!==a&&"state"!==a||(d.default[a].label&&e.find("label").html(d.default[a].label),d.default[a].placeholder&&e.find("input").attr("placeholder",d.default[a].placeholder)),d.default[a].required===!0&&0===e.find("label abbr").length&&b(e,!0))})})}); add-to-cart.min.js 0000666 00000003347 15214157447 0010010 0 ustar 00 /*! * WooCommerce Add to Cart JS */ jQuery(function(a){return"undefined"!=typeof wc_add_to_cart_params&&void a(document).on("click",".add_to_cart_button",function(){var b=a(this);if(b.is(".ajax_add_to_cart")){if(!b.attr("data-product_id"))return!0;b.removeClass("added"),b.addClass("loading");var c={};return a.each(b.data(),function(a,b){c[a]=b}),a(document.body).trigger("adding_to_cart",[b,c]),a.post(wc_add_to_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","add_to_cart"),c,function(c){if(c){var d=window.location.toString();if(d=d.replace("add-to-cart","added-to-cart"),c.error&&c.product_url)return void(window.location=c.product_url);if("yes"===wc_add_to_cart_params.cart_redirect_after_add)return void(window.location=wc_add_to_cart_params.cart_url);b.removeClass("loading");var e=c.fragments,f=c.cart_hash;e&&a.each(e,function(b){a(b).addClass("updating")}),a(".shop_table.cart, .updating, .cart_totals").fadeTo("400","0.6").block({message:null,overlayCSS:{opacity:.6}}),b.addClass("added"),wc_add_to_cart_params.is_cart||0!==b.parent().find(".added_to_cart").length||b.after(' <a href="'+wc_add_to_cart_params.cart_url+'" class="added_to_cart wc-forward" title="'+wc_add_to_cart_params.i18n_view_cart+'">'+wc_add_to_cart_params.i18n_view_cart+"</a>"),e&&a.each(e,function(b,c){a(b).replaceWith(c)}),a(".widget_shopping_cart, .updating").stop(!0).css("opacity","1").unblock(),a(".shop_table.cart").load(d+" .shop_table.cart:eq(0) > *",function(){a(".shop_table.cart").stop(!0).css("opacity","1").unblock(),a(document.body).trigger("cart_page_refreshed")}),a(".cart_totals").load(d+" .cart_totals:eq(0) > *",function(){a(".cart_totals").stop(!0).css("opacity","1").unblock()}),a(document.body).trigger("added_to_cart",[e,f,b])}}),!1}return!0})}); password-strength-meter.js 0000666 00000006314 15214157447 0011734 0 ustar 00 /* global wp, pwsL10n, wc_password_strength_meter_params */ jQuery( function( $ ) { /** * Password Strength Meter class. */ var wc_password_strength_meter = { /** * Initialize strength meter actions. */ init: function() { $( document.body ) .on( 'keyup change', 'form.register #reg_password, form.checkout #account_password, form.edit-account #password_1, form.lost_reset_password #password_1', this.strengthMeter ); $( 'form.checkout #createaccount' ).change(); }, /** * Strength Meter. */ strengthMeter: function() { var wrapper = $( 'form.register, form.checkout, form.edit-account, form.lost_reset_password' ), submit = $( 'input[type="submit"]', wrapper ), field = $( '#reg_password, #account_password, #password_1', wrapper ), strength = 1; wc_password_strength_meter.includeMeter( wrapper, field ); strength = wc_password_strength_meter.checkPasswordStrength( wrapper, field ); if ( strength < wc_password_strength_meter_params.min_password_strength && ! wrapper.is( 'form.checkout' ) ) { submit.attr( 'disabled', 'disabled' ).addClass( 'disabled' ); } else { submit.removeAttr( 'disabled', 'disabled' ).removeClass( 'disabled' ); } }, /** * Include meter HTML. * * @param {Object} wrapper * @param {Object} field */ includeMeter: function( wrapper, field ) { var meter = wrapper.find( '.woocommerce-password-strength' ); if ( '' === field.val() ) { meter.remove(); $( document.body ).trigger( 'wc-password-strength-removed' ); } else if ( 0 === meter.length ) { field.after( '<div class="woocommerce-password-strength" aria-live="polite"></div>' ); $( document.body ).trigger( 'wc-password-strength-added' ); } }, /** * Check password strength. * * @param {Object} field * * @return {Int} */ checkPasswordStrength: function( wrapper, field ) { var meter = wrapper.find( '.woocommerce-password-strength' ); var hint = wrapper.find( '.woocommerce-password-hint' ); var hint_html = '<small class="woocommerce-password-hint">' + wc_password_strength_meter_params.i18n_password_hint + '</small>'; var strength = wp.passwordStrength.meter( field.val(), wp.passwordStrength.userInputBlacklist() ); var error = ''; // Reset meter.removeClass( 'short bad good strong' ); hint.remove(); // Error to append if ( strength < wc_password_strength_meter_params.min_password_strength ) { error = ' - ' + wc_password_strength_meter_params.i18n_password_error; } switch ( strength ) { case 0 : meter.addClass( 'short' ).html( pwsL10n['short'] + error ); meter.after( hint_html ); break; case 1 : meter.addClass( 'bad' ).html( pwsL10n.bad + error ); meter.after( hint_html ); break; case 2 : meter.addClass( 'bad' ).html( pwsL10n.bad + error ); meter.after( hint_html ); break; case 3 : meter.addClass( 'good' ).html( pwsL10n.good + error ); break; case 4 : meter.addClass( 'strong' ).html( pwsL10n.strong + error ); break; case 5 : meter.addClass( 'short' ).html( pwsL10n.mismatch ); break; } return strength; } }; wc_password_strength_meter.init(); }); lost-password.js 0000666 00000000236 15214157447 0007742 0 ustar 00 jQuery( function( $ ) { $( '.lost_reset_password' ).on( 'submit', function () { $( 'input[type="submit"]', this ).attr( 'disabled', 'disabled' ); }); }); cart.js 0000666 00000033667 15214157447 0006070 0 ustar 00 /* global wc_cart_params */ jQuery( function( $ ) { // wc_cart_params is required to continue, ensure the object exists if ( typeof wc_cart_params === 'undefined' ) { return false; } // Utility functions for the file. /** * Gets a url for a given AJAX endpoint. * * @param {String} endpoint The AJAX Endpoint * @return {String} The URL to use for the request */ var get_url = function( endpoint ) { return wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', endpoint ); }; /** * Check if a node is blocked for processing. * * @param {JQuery Object} $node * @return {bool} True if the DOM Element is UI Blocked, false if not. */ var is_blocked = function( $node ) { return $node.is( '.processing' ) || $node.parents( '.processing' ).length; }; /** * Block a node visually for processing. * * @param {JQuery Object} $node */ var block = function( $node ) { if ( ! is_blocked( $node ) ) { $node.addClass( 'processing' ).block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } ); } }; /** * Unblock a node after processing is complete. * * @param {JQuery Object} $node */ var unblock = function( $node ) { $node.removeClass( 'processing' ).unblock(); }; /** * Update the .woocommerce div with a string of html. * * @param {String} html_str The HTML string with which to replace the div. */ var update_wc_div = function( html_str ) { var $html = $.parseHTML( html_str ); var $new_form = $( '.shop_table.cart', $html ).closest( 'form' ); var $new_totals = $( '.cart_totals', $html ); // Error message collection var $error = $( '.woocommerce-error', $html ); var $message = $( '.woocommerce-message', $html ); var $info = $( '.woocommerce-info', $html ); // Remove errors $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove(); if ( $new_form.length === 0 ) { // If the checkout is also displayed on this page, trigger reload instead. if ( $( '.woocommerce-checkout' ).length ) { window.location.reload(); return; } // No items to display now! Replace all cart content. var $cart_html = $( '.cart-empty', $html ).closest( '.woocommerce' ); $( '.shop_table.cart' ).closest( '.woocommerce' ).replaceWith( $cart_html ); // Display errors if ( $error.length > 0 ) { show_notice( $error, $( '.cart-empty' ).closest( '.woocommerce' ) ); } if ( $message.length > 0 ) { show_notice( $message, $( '.cart-empty' ).closest( '.woocommerce' ) ); } if ( $info.length > 0 ) { show_notice( $info, $( '.cart-empty' ).closest( '.woocommerce' ) ); } } else { // If the checkout is also displayed on this page, trigger update event. if ( $( '.woocommerce-checkout' ).length ) { $( document.body ).trigger( 'update_checkout' ); } $( '.shop_table.cart' ).closest( 'form' ).replaceWith( $new_form ); $( '.shop_table.cart' ).closest( 'form' ).find( 'input[name="update_cart"]' ).prop( 'disabled', true ); if ( $error.length > 0 ) { show_notice( $error ); } if ( $message.length > 0 ) { show_notice( $message ); } if ( $info.length > 0 ) { show_notice( $info ); } update_cart_totals_div( $new_totals ); } $( document.body ).trigger( 'updated_wc_div' ); }; /** * Update the .cart_totals div with a string of html. * * @param {String} html_str The HTML string with which to replace the div. */ var update_cart_totals_div = function( html_str ) { $( '.cart_totals' ).replaceWith( html_str ); $( document.body ).trigger( 'updated_cart_totals' ); }; /** * Clear previous notices and shows new one above form. * * @param {Object} The Notice HTML Element in string or object form. */ var show_notice = function( html_element, $target ) { if ( ! $target ) { $target = $( '.shop_table.cart' ).closest( 'form' ); } $target.before( html_element ); }; /** * Object to handle AJAX calls for cart shipping changes. */ var cart_shipping = { /** * Initialize event handlers and UI state. */ init: function( cart ) { this.cart = cart; this.toggle_shipping = this.toggle_shipping.bind( this ); this.shipping_method_selected = this.shipping_method_selected.bind( this ); this.shipping_calculator_submit = this.shipping_calculator_submit.bind( this ); $( document ).on( 'click', '.shipping-calculator-button', this.toggle_shipping ); $( document ).on( 'change', 'select.shipping_method, input[name^=shipping_method]', this.shipping_method_selected ); $( document ).on( 'submit', 'form.woocommerce-shipping-calculator', this.shipping_calculator_submit ); $( '.shipping-calculator-form' ).hide(); }, /** * Toggle Shipping Calculator panel */ toggle_shipping: function() { $( '.shipping-calculator-form' ).slideToggle( 'slow' ); return false; }, /** * Handles when a shipping method is selected. * * @param {Object} evt The JQuery event. */ shipping_method_selected: function( evt ) { var target = evt.currentTarget; var shipping_methods = {}; $( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() { shipping_methods[ $( target ).data( 'index' ) ] = $( target ).val(); } ); block( $( 'div.cart_totals' ) ); var data = { security: wc_cart_params.update_shipping_method_nonce, shipping_method: shipping_methods }; $.ajax( { type: 'post', url: get_url( 'update_shipping_method' ), data: data, dataType: 'html', success: function( response ) { update_cart_totals_div( response ); }, complete: function() { unblock( $( 'div.cart_totals' ) ); $( document.body ).trigger( 'updated_shipping_method' ); } } ); }, /** * Handles a shipping calculator form submit. * * @param {Object} evt The JQuery event. */ shipping_calculator_submit: function( evt ) { evt.preventDefault(); var $form = $( evt.currentTarget ); block( $( 'div.cart_totals' ) ); block( $form ); // Provide the submit button value because wc-form-handler expects it. $( '<input />' ).attr( 'type', 'hidden' ) .attr( 'name', 'calc_shipping' ) .attr( 'value', 'x' ) .appendTo( $form ); // Make call to actual form post URL. $.ajax( { type: $form.attr( 'method' ), url: $form.attr( 'action' ), data: $form.serialize(), dataType: 'html', success: function( response ) { update_wc_div( response ); }, complete: function() { unblock( $form ); unblock( $( 'div.cart_totals' ) ); } } ); } }; /** * Object to handle cart UI. */ var cart = { /** * Initialize cart UI events. */ init: function() { this.update_cart_totals = this.update_cart_totals.bind( this ); this.input_keypress = this.input_keypress.bind( this ); this.cart_submit = this.cart_submit.bind( this ); this.submit_click = this.submit_click.bind( this ); this.apply_coupon = this.apply_coupon.bind( this ); this.remove_coupon_clicked = this.remove_coupon_clicked.bind( this ); this.quantity_update = this.quantity_update.bind( this ); this.item_remove_clicked = this.item_remove_clicked.bind( this ); this.update_cart = this.update_cart.bind( this ); $( document ).on( 'wc_update_cart', this.update_cart ); $( document ).on( 'click', 'div.woocommerce > form input[type=submit]', this.submit_click ); $( document ).on( 'keypress', 'div.woocommerce > form input[type=number]', this.input_keypress ); $( document ).on( 'submit', 'div.woocommerce:not(.widget_product_search) > form', this.cart_submit ); $( document ).on( 'click', 'a.woocommerce-remove-coupon', this.remove_coupon_clicked ); $( document ).on( 'click', 'td.product-remove > a', this.item_remove_clicked ); $( document ).on( 'change input', 'div.woocommerce > form .cart_item :input', this.input_changed ); $( 'div.woocommerce > form input[name="update_cart"]' ).prop( 'disabled', true ); }, /** * After an input is changed, enable the update cart button. */ input_changed: function() { $( 'div.woocommerce > form input[name="update_cart"]' ).prop( 'disabled', false ); }, /** * Update entire cart via ajax. */ update_cart: function() { var $form = $( '.shop_table.cart' ).closest( 'form' ); block( $form ); block( $( 'div.cart_totals' ) ); // Make call to actual form post URL. $.ajax( { type: $form.attr( 'method' ), url: $form.attr( 'action' ), data: $form.serialize(), dataType: 'html', success: function( response ) { update_wc_div( response ); }, complete: function() { unblock( $form ); unblock( $( 'div.cart_totals' ) ); } } ); }, /** * Update the cart after something has changed. */ update_cart_totals: function() { block( $( 'div.cart_totals' ) ); $.ajax( { url: get_url( 'get_cart_totals' ), dataType: 'html', success: function( response ) { update_cart_totals_div( response ); }, complete: function() { unblock( $( 'div.cart_totals' ) ); } } ); }, /** * Handle the <ENTER> key for quantity fields. * * @param {Object} evt The JQuery event * * For IE, if you hit enter on a quantity field, it makes the * document.activeElement the first submit button it finds. * For us, that is the Apply Coupon button. This is required * to catch the event before that happens. */ input_keypress: function( evt ) { // Catch the enter key and don't let it submit the form. if ( 13 === evt.keyCode ) { evt.preventDefault(); this.cart_submit( evt ); } }, /** * Handle cart form submit and route to correct logic. * * @param {Object} evt The JQuery event */ cart_submit: function( evt ) { var $submit = $( document.activeElement ); var $clicked = $( 'input[type=submit][clicked=true]' ); var $form = $( evt.currentTarget ); // For submit events, currentTarget is form. // For keypress events, currentTarget is input. if ( ! $form.is( 'form' ) ) { $form = $( evt.currentTarget ).parents( 'form' ); } if ( 0 === $form.find( '.shop_table.cart' ).length ) { return; } if ( is_blocked( $form ) ) { return false; } if ( $clicked.is( '[name="update_cart"]' ) || $submit.is( 'input.qty' ) ) { evt.preventDefault(); this.quantity_update( $form ); } else if ( $clicked.is( '[name="apply_coupon"]' ) || $submit.is( '#coupon_code' ) ) { evt.preventDefault(); this.apply_coupon( $form ); } }, /** * Special handling to identify which submit button was clicked. * * @param {Object} evt The JQuery event */ submit_click: function( evt ) { $( 'input[type=submit]', $( evt.target ).parents( 'form' ) ).removeAttr( 'clicked' ); $( evt.target ).attr( 'clicked', 'true' ); }, /** * Apply Coupon code * * @param {JQuery Object} $form The cart form. */ apply_coupon: function( $form ) { block( $form ); var cart = this; var $text_field = $( '#coupon_code' ); var coupon_code = $text_field.val(); var data = { security: wc_cart_params.apply_coupon_nonce, coupon_code: coupon_code }; $.ajax( { type: 'POST', url: get_url( 'apply_coupon' ), data: data, dataType: 'html', success: function( response ) { $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove(); show_notice( response ); $( document.body ).trigger( 'applied_coupon' ); }, complete: function() { unblock( $form ); $text_field.val( '' ); cart.update_cart_totals(); } } ); }, /** * Handle when a remove coupon link is clicked. * * @param {Object} evt The JQuery event */ remove_coupon_clicked: function( evt ) { evt.preventDefault(); var cart = this; var $tr = $( evt.currentTarget ).parents( 'tr' ); var coupon = $( evt.currentTarget ).attr( 'data-coupon' ); block( $tr.parents( 'table' ) ); var data = { security: wc_cart_params.remove_coupon_nonce, coupon: coupon }; $.ajax( { type: 'POST', url: get_url( 'remove_coupon' ), data: data, dataType: 'html', success: function( response ) { $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove(); show_notice( response ); $( document.body ).trigger( 'removed_coupon' ); unblock( $tr.parents( 'table' ) ); }, complete: function() { cart.update_cart_totals(); } } ); }, /** * Handle a cart Quantity Update * * @param {JQuery Object} $form The cart form. */ quantity_update: function( $form ) { // Provide the submit button value because wc-form-handler expects it. $( '<input />' ).attr( 'type', 'hidden' ) .attr( 'name', 'update_cart' ) .attr( 'value', 'Update Cart' ) .appendTo( $form ); block( $form ); block( $( 'div.cart_totals' ) ); // Make call to actual form post URL. $.ajax( { type: $form.attr( 'method' ), url: $form.attr( 'action' ), data: $form.serialize(), dataType: 'html', success: update_wc_div, complete: function() { unblock( $form ); unblock( $( 'div.cart_totals' ) ); } } ); }, /** * Handle when a remove item link is clicked. * * @param {Object} evt The JQuery event */ item_remove_clicked: function( evt ) { evt.preventDefault(); var $a = $( evt.currentTarget ); var $form = $a.parents( 'form' ); block( $form ); block( $( 'div.cart_totals' ) ); $.ajax( { type: 'GET', url: $a.attr( 'href' ), dataType: 'html', success: update_wc_div, complete: function() { unblock( $form ); unblock( $( 'div.cart_totals' ) ); } } ); } }; cart_shipping.init( cart ); cart.init(); } ); address-i18n.js 0000666 00000007606 15214157447 0007333 0 ustar 00 /*global wc_address_i18n_params */ jQuery( function( $ ) { // wc_address_i18n_params is required to continue, ensure the object exists if ( typeof wc_address_i18n_params === 'undefined' ) { return false; } var locale_json = wc_address_i18n_params.locale.replace( /"/g, '"' ), locale = $.parseJSON( locale_json ); function field_is_required( field, is_required ) { if ( is_required ) { field.find( 'label' ).append( ' <abbr class="required" title="' + wc_address_i18n_params.i18n_required_text + '">*</abbr>' ); field.addClass( 'validate-required' ); } else { field.find( 'label abbr' ).remove(); field.removeClass( 'validate-required' ); } } $( document.body ) // Handle locale .bind( 'country_to_state_changing', function( event, country, wrapper ) { var thisform = wrapper, thislocale; if ( typeof locale[ country ] !== 'undefined' ) { thislocale = locale[ country ]; } else { thislocale = locale['default']; } var $postcodefield = thisform.find( '#billing_postcode_field, #shipping_postcode_field' ), $cityfield = thisform.find( '#billing_city_field, #shipping_city_field' ), $statefield = thisform.find( '#billing_state_field, #shipping_state_field' ); if ( ! $postcodefield.attr( 'data-o_class' ) ) { $postcodefield.attr( 'data-o_class', $postcodefield.attr( 'class' ) ); $cityfield.attr( 'data-o_class', $cityfield.attr( 'class' ) ); $statefield.attr( 'data-o_class', $statefield.attr( 'class' ) ); } // Re-order postcode/city if ( thislocale.postcode_before_city ) { $postcodefield.add( $cityfield ).add( $statefield ).removeClass( 'form-row-first form-row-last' ).addClass( 'form-row-first' ); $cityfield.removeClass( 'form-row-wide form-row-first' ).addClass( 'form-row-last' ); $postcodefield.insertBefore( $cityfield ); } else { // Default $postcodefield.attr( 'class', $postcodefield.attr( 'data-o_class' ) ); $cityfield.attr( 'class', $cityfield.attr( 'data-o_class' ) ); $statefield.attr( 'class', $statefield.attr( 'data-o_class' ) ); $postcodefield.insertAfter( $statefield ); } // Handle locale fields var locale_fields = $.parseJSON( wc_address_i18n_params.locale_fields ); $.each( locale_fields, function( key, value ) { var field = thisform.find( value ); if ( thislocale[ key ] ) { if ( thislocale[ key ].label ) { field.find( 'label' ).html( thislocale[ key ].label ); } if ( thislocale[ key ].placeholder ) { field.find( 'input' ).attr( 'placeholder', thislocale[ key ].placeholder ); } field_is_required( field, false ); if ( typeof thislocale[ key ].required === 'undefined' && locale['default'][ key ].required === true ) { field_is_required( field, true ); } else if ( thislocale[ key ].required === true ) { field_is_required( field, true ); } if ( key !== 'state' ) { if ( thislocale[ key ].hidden === true ) { field.hide().find( 'input' ).val( '' ); } else { field.show(); } } } else if ( locale['default'][ key ] ) { if ( 'state' !== key ) { if ( typeof locale['default'][ key ].hidden === 'undefined' || locale['default'][ key ].hidden === false ) { field.show(); } else if ( locale['default'][ key ].hidden === true ) { field.hide().find( 'input' ).val( '' ); } } if ( 'postcode' === key || 'city' === key || 'state' === key ) { if ( locale['default'][ key ].label ) { field.find( 'label' ).html( locale['default'][ key ].label ); } if ( locale['default'][ key ].placeholder ) { field.find( 'input' ).attr( 'placeholder', locale['default'][ key ].placeholder ); } } if ( locale['default'][ key ].required === true ) { if ( field.find( 'label abbr' ).length === 0 ) { field_is_required( field, true ); } } } }); }); }); checkout.min.js 0000666 00000026216 15214157447 0007516 0 ustar 00 jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select, input:checkbox",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(b){var c=a(".woocommerce-checkout").find('input[name="payment_method"]');1===c.length&&c.eq(0).hide(),b&&a("#"+b).prop("checked",!0),0===c.filter(":checked").length&&c.eq(0).prop("checked",!0),c.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c||(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){var d=a('.woocommerce-checkout input[name="payment_method"]:checked').attr("id");if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var e=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),e&&a("#terms").prop("checked",!0),"failure"===c.result){var f=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?f.prepend('<div class="woocommerce-NoticeGroup-updateOrderReview">'+c.messages+"</div>"):f.prepend(c),f.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(d),a(document.body).trigger("updated_checkout",[c])}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(a){var e=b.match(/{"result.*"}/);null===e?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=e[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('<div class="woocommerce-error">'+wc_checkout_params.i18n_checkout_error+"</div>")}},error:function(a,c,d){b.submit_error('<div class="woocommerce-error">'+d+"</div>")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); checkout.js 0000666 00000044457 15214157447 0006743 0 ustar 00 /* global wc_checkout_params */ jQuery( function( $ ) { // wc_checkout_params is required to continue, ensure the object exists if ( typeof wc_checkout_params === 'undefined' ) { return false; } $.blockUI.defaults.overlayCSS.cursor = 'default'; var wc_checkout_form = { updateTimer: false, dirtyInput: false, xhr: false, $order_review: $( '#order_review' ), $checkout_form: $( 'form.checkout' ), init: function() { $( document.body ).bind( 'update_checkout', this.update_checkout ); $( document.body ).bind( 'init_checkout', this.init_checkout ); // Payment methods this.$checkout_form.on( 'click', 'input[name="payment_method"]', this.payment_method_selected ); if ( $( document.body ).hasClass( 'woocommerce-order-pay' ) ) { this.$order_review.on( 'click', 'input[name="payment_method"]', this.payment_method_selected ); } // Form submission this.$checkout_form.on( 'submit', this.submit ); // Inline validation this.$checkout_form.on( 'blur change', '.input-text, select, input:checkbox', this.validate_field ); // Manual trigger this.$checkout_form.on( 'update', this.trigger_update_checkout ); // Inputs/selects which update totals this.$checkout_form.on( 'change', 'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]', this.trigger_update_checkout ); this.$checkout_form.on( 'change', '.address-field select', this.input_changed ); this.$checkout_form.on( 'change', '.address-field input.input-text, .update_totals_on_change input.input-text', this.maybe_input_changed ); this.$checkout_form.on( 'change keydown', '.address-field input.input-text, .update_totals_on_change input.input-text', this.queue_update_checkout ); // Address fields this.$checkout_form.on( 'change', '#ship-to-different-address input', this.ship_to_different_address ); // Trigger events this.$checkout_form.find( '#ship-to-different-address input' ).change(); this.init_payment_methods(); // Update on page load if ( wc_checkout_params.is_checkout === '1' ) { $( document.body ).trigger( 'init_checkout' ); } if ( wc_checkout_params.option_guest_checkout === 'yes' ) { $( 'input#createaccount' ).change( this.toggle_create_account ).change(); } }, init_payment_methods: function( selectedPaymentMethod ) { var $payment_methods = $( '.woocommerce-checkout' ).find( 'input[name="payment_method"]' ); // If there is one method, we can hide the radio input if ( 1 === $payment_methods.length ) { $payment_methods.eq(0).hide(); } // If there was a previously selected method, check that one. if ( selectedPaymentMethod ) { $( '#' + selectedPaymentMethod ).prop( 'checked', true ); } // If there are none selected, select the first. if ( 0 === $payment_methods.filter( ':checked' ).length ) { $payment_methods.eq(0).prop( 'checked', true ); } // Trigger click event for selected method $payment_methods.filter( ':checked' ).eq(0).trigger( 'click' ); }, get_payment_method: function() { return wc_checkout_form.$order_review.find( 'input[name="payment_method"]:checked' ).val(); }, payment_method_selected: function() { if ( $( '.payment_methods input.input-radio' ).length > 1 ) { var target_payment_box = $( 'div.payment_box.' + $( this ).attr( 'ID' ) ); if ( $( this ).is( ':checked' ) && ! target_payment_box.is( ':visible' ) ) { $( 'div.payment_box' ).filter( ':visible' ).slideUp( 250 ); if ( $( this ).is( ':checked' ) ) { $( 'div.payment_box.' + $( this ).attr( 'ID' ) ).slideDown( 250 ); } } } else { $( 'div.payment_box' ).show(); } if ( $( this ).data( 'order_button_text' ) ) { $( '#place_order' ).val( $( this ).data( 'order_button_text' ) ); } else { $( '#place_order' ).val( $( '#place_order' ).data( 'value' ) ); } }, toggle_create_account: function() { $( 'div.create-account' ).hide(); if ( $( this ).is( ':checked' ) ) { $( 'div.create-account' ).slideDown(); } }, init_checkout: function() { $( '#billing_country, #shipping_country, .country_to_state' ).change(); $( document.body ).trigger( 'update_checkout' ); }, maybe_input_changed: function( e ) { if ( wc_checkout_form.dirtyInput ) { wc_checkout_form.input_changed( e ); } }, input_changed: function( e ) { wc_checkout_form.dirtyInput = e.target; wc_checkout_form.maybe_update_checkout(); }, queue_update_checkout: function( e ) { var code = e.keyCode || e.which || 0; if ( code === 9 ) { return true; } wc_checkout_form.dirtyInput = this; wc_checkout_form.reset_update_checkout_timer(); wc_checkout_form.updateTimer = setTimeout( wc_checkout_form.maybe_update_checkout, '1000' ); }, trigger_update_checkout: function() { wc_checkout_form.reset_update_checkout_timer(); wc_checkout_form.dirtyInput = false; $( document.body ).trigger( 'update_checkout' ); }, maybe_update_checkout: function() { var update_totals = true; if ( $( wc_checkout_form.dirtyInput ).length ) { var $required_inputs = $( wc_checkout_form.dirtyInput ).closest( 'div' ).find( '.address-field.validate-required' ); if ( $required_inputs.length ) { $required_inputs.each( function() { if ( $( this ).find( 'input.input-text' ).val() === '' ) { update_totals = false; } }); } } if ( update_totals ) { wc_checkout_form.trigger_update_checkout(); } }, ship_to_different_address: function() { $( 'div.shipping_address' ).hide(); if ( $( this ).is( ':checked' ) ) { $( 'div.shipping_address' ).slideDown(); } }, reset_update_checkout_timer: function() { clearTimeout( wc_checkout_form.updateTimer ); }, validate_field: function() { var $this = $( this ), $parent = $this.closest( '.form-row' ), validated = true; if ( $parent.is( '.validate-required' ) ) { if ( 'checkbox' === $this.attr( 'type' ) && ! $this.is( ':checked' ) ) { $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' ); validated = false; } else if ( $this.val() === '' ) { $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' ); validated = false; } } if ( $parent.is( '.validate-email' ) ) { if ( $this.val() ) { /* https://stackoverflow.com/questions/2855865/jquery-validate-e-mail-address-regex */ var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i); if ( ! pattern.test( $this.val() ) ) { $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-email' ); validated = false; } } } if ( validated ) { $parent.removeClass( 'woocommerce-invalid woocommerce-invalid-required-field' ).addClass( 'woocommerce-validated' ); } }, update_checkout: function( event, args ) { // Small timeout to prevent multiple requests when several fields update at the same time wc_checkout_form.reset_update_checkout_timer(); wc_checkout_form.updateTimer = setTimeout( wc_checkout_form.update_checkout_action, '5', args ); }, update_checkout_action: function( args ) { if ( wc_checkout_form.xhr ) { wc_checkout_form.xhr.abort(); } if ( $( 'form.checkout' ).length === 0 ) { return; } args = typeof args !== 'undefined' ? args : { update_shipping_method: true }; var country = $( '#billing_country' ).val(), state = $( '#billing_state' ).val(), postcode = $( 'input#billing_postcode' ).val(), city = $( '#billing_city' ).val(), address = $( 'input#billing_address_1' ).val(), address_2 = $( 'input#billing_address_2' ).val(), s_country = country, s_state = state, s_postcode = postcode, s_city = city, s_address = address, s_address_2 = address_2; if ( $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' ) ) { s_country = $( '#shipping_country' ).val(); s_state = $( '#shipping_state' ).val(); s_postcode = $( 'input#shipping_postcode' ).val(); s_city = $( '#shipping_city' ).val(); s_address = $( 'input#shipping_address_1' ).val(); s_address_2 = $( 'input#shipping_address_2' ).val(); } var data = { security: wc_checkout_params.update_order_review_nonce, payment_method: wc_checkout_form.get_payment_method(), country: country, state: state, postcode: postcode, city: city, address: address, address_2: address_2, s_country: s_country, s_state: s_state, s_postcode: s_postcode, s_city: s_city, s_address: s_address, s_address_2: s_address_2, post_data: $( 'form.checkout' ).serialize() }; if ( false !== args.update_shipping_method ) { var shipping_methods = {}; $( 'select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]' ).each( function() { shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val(); } ); data.shipping_method = shipping_methods; } $( '.woocommerce-checkout-payment, .woocommerce-checkout-review-order-table' ).block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } }); wc_checkout_form.xhr = $.ajax({ type: 'POST', url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_order_review' ), data: data, success: function( data ) { var selectedPaymentMethod = $( '.woocommerce-checkout input[name="payment_method"]:checked' ).attr( 'id' ); // Reload the page if requested if ( 'true' === data.reload ) { window.location.reload(); return; } // Remove any notices added previously $( '.woocommerce-NoticeGroup-updateOrderReview' ).remove(); var termsCheckBoxChecked = $( '#terms' ).prop( 'checked' ); // Always update the fragments if ( data && data.fragments ) { $.each( data.fragments, function ( key, value ) { $( key ).replaceWith( value ); $( key ).unblock(); } ); } // Recheck the terms and conditions box, if needed if ( termsCheckBoxChecked ) { $( '#terms' ).prop( 'checked', true ); } // Check for error if ( 'failure' === data.result ) { var $form = $( 'form.checkout' ); // Remove notices from all sources $( '.woocommerce-error, .woocommerce-message' ).remove(); // Add new errors returned by this event if ( data.messages ) { $form.prepend( '<div class="woocommerce-NoticeGroup-updateOrderReview">' + data.messages + '</div>' ); } else { $form.prepend( data ); } // Lose focus for all fields $form.find( '.input-text, select, input:checkbox' ).blur(); // Scroll to top $( 'html, body' ).animate( { scrollTop: ( $( 'form.checkout' ).offset().top - 100 ) }, 1000 ); } // Re-init methods wc_checkout_form.init_payment_methods( selectedPaymentMethod ); // Fire updated_checkout e $( document.body ).trigger( 'updated_checkout', [ data ] ); } }); }, submit: function() { wc_checkout_form.reset_update_checkout_timer(); var $form = $( this ); if ( $form.is( '.processing' ) ) { return false; } // Trigger a handler to let gateways manipulate the checkout if needed if ( $form.triggerHandler( 'checkout_place_order' ) !== false && $form.triggerHandler( 'checkout_place_order_' + wc_checkout_form.get_payment_method() ) !== false ) { $form.addClass( 'processing' ); var form_data = $form.data(); if ( 1 !== form_data['blockUI.isBlocked'] ) { $form.block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } }); } // ajaxSetup is global, but we use it to ensure JSON is valid once returned. $.ajaxSetup( { dataFilter: function( raw_response, dataType ) { // We only want to work with JSON if ( 'json' !== dataType ) { return raw_response; } try { // Check for valid JSON var data = $.parseJSON( raw_response ); if ( data && 'object' === typeof data ) { // Valid - return it so it can be parsed by Ajax handler return raw_response; } } catch ( e ) { // Attempt to fix the malformed JSON var valid_json = raw_response.match( /{"result.*"}/ ); if ( null === valid_json ) { console.log( 'Unable to fix malformed JSON' ); } else { console.log( 'Fixed malformed JSON. Original:' ); console.log( raw_response ); raw_response = valid_json[0]; } } return raw_response; } } ); $.ajax({ type: 'POST', url: wc_checkout_params.checkout_url, data: $form.serialize(), dataType: 'json', success: function( result ) { try { if ( result.result === 'success' ) { if ( -1 === result.redirect.indexOf( 'https://' ) || -1 === result.redirect.indexOf( 'http://' ) ) { window.location = result.redirect; } else { window.location = decodeURI( result.redirect ); } } else if ( result.result === 'failure' ) { throw 'Result failure'; } else { throw 'Invalid response'; } } catch( err ) { // Reload page if ( result.reload === 'true' ) { window.location.reload(); return; } // Trigger update in case we need a fresh nonce if ( result.refresh === 'true' ) { $( document.body ).trigger( 'update_checkout' ); } // Add new errors if ( result.messages ) { wc_checkout_form.submit_error( result.messages ); } else { wc_checkout_form.submit_error( '<div class="woocommerce-error">' + wc_checkout_params.i18n_checkout_error + '</div>' ); } } }, error: function( jqXHR, textStatus, errorThrown ) { wc_checkout_form.submit_error( '<div class="woocommerce-error">' + errorThrown + '</div>' ); } }); } return false; }, submit_error: function( error_message ) { $( '.woocommerce-error, .woocommerce-message' ).remove(); wc_checkout_form.$checkout_form.prepend( error_message ); wc_checkout_form.$checkout_form.removeClass( 'processing' ).unblock(); wc_checkout_form.$checkout_form.find( '.input-text, select, input:checkbox' ).blur(); $( 'html, body' ).animate({ scrollTop: ( $( 'form.checkout' ).offset().top - 100 ) }, 1000 ); $( document.body ).trigger( 'checkout_error' ); } }; var wc_checkout_coupons = { init: function() { $( document.body ).on( 'click', 'a.showcoupon', this.show_coupon_form ); $( document.body ).on( 'click', '.woocommerce-remove-coupon', this.remove_coupon ); $( 'form.checkout_coupon' ).hide().submit( this.submit ); }, show_coupon_form: function() { $( '.checkout_coupon' ).slideToggle( 400, function() { $( '.checkout_coupon' ).find( ':input:eq(0)' ).focus(); }); return false; }, submit: function() { var $form = $( this ); if ( $form.is( '.processing' ) ) { return false; } $form.addClass( 'processing' ).block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } }); var data = { security: wc_checkout_params.apply_coupon_nonce, coupon_code: $form.find( 'input[name="coupon_code"]' ).val() }; $.ajax({ type: 'POST', url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ), data: data, success: function( code ) { $( '.woocommerce-error, .woocommerce-message' ).remove(); $form.removeClass( 'processing' ).unblock(); if ( code ) { $form.before( code ); $form.slideUp(); $( document.body ).trigger( 'update_checkout', { update_shipping_method: false } ); } }, dataType: 'html' }); return false; }, remove_coupon: function( e ) { e.preventDefault(); var container = $( this ).parents( '.woocommerce-checkout-review-order' ), coupon = $( this ).data( 'coupon' ); container.addClass( 'processing' ).block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } }); var data = { security: wc_checkout_params.remove_coupon_nonce, coupon: coupon }; $.ajax({ type: 'POST', url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'remove_coupon' ), data: data, success: function( code ) { $( '.woocommerce-error, .woocommerce-message' ).remove(); container.removeClass( 'processing' ).unblock(); if ( code ) { $( 'form.woocommerce-checkout' ).before( code ); $( document.body ).trigger( 'update_checkout', { update_shipping_method: false } ); // Remove coupon code from coupon field $( 'form.checkout_coupon' ).find( 'input[name="coupon_code"]' ).val( '' ); } }, error: function ( jqXHR ) { if ( wc_checkout_params.debug_mode ) { /* jshint devel: true */ console.log( jqXHR.responseText ); } }, dataType: 'html' }); } }; var wc_checkout_login_form = { init: function() { $( document.body ).on( 'click', 'a.showlogin', this.show_login_form ); }, show_login_form: function() { $( 'form.login' ).slideToggle(); return false; } }; wc_checkout_form.init(); wc_checkout_coupons.init(); wc_checkout_login_form.init(); }); cart-fragments.min.js 0000666 00000004541 15214157447 0010623 0 ustar 00 jQuery(function(a){function b(){e&&sessionStorage.setItem("wc_cart_created",(new Date).getTime())}function c(a){e&&(localStorage.setItem(f,a),sessionStorage.setItem(f,a))}function d(){a.ajax(g)}if("undefined"==typeof wc_cart_fragments_params)return!1;var e,f=wc_cart_fragments_params.ajax_url.toString()+"-wc_cart_hash";try{e="sessionStorage"in window&&null!==window.sessionStorage,window.sessionStorage.setItem("wc","test"),window.sessionStorage.removeItem("wc"),window.localStorage.setItem("wc","test"),window.localStorage.removeItem("wc")}catch(a){e=!1}var g={url:wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%","get_refreshed_fragments"),type:"POST",success:function(d){d&&d.fragments&&(a.each(d.fragments,function(b,c){a(b).replaceWith(c)}),e&&(sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(d.fragments)),c(d.cart_hash),d.cart_hash&&b()),a(document.body).trigger("wc_fragments_refreshed"))}};if(e){var h=null,i=864e5;a(document.body).bind("wc_fragment_refresh updated_wc_div",function(){d()}),a(document.body).bind("added_to_cart",function(a,d,e){var g=sessionStorage.getItem(f);null!==g&&void 0!==g&&""!==g||b(),sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(d)),c(e)}),a(document.body).bind("wc_fragments_refreshed",function(){clearTimeout(h),h=setTimeout(d,i)}),a(window).on("storage onstorage",function(a){f===a.originalEvent.key&&localStorage.getItem(f)!==sessionStorage.getItem(f)&&d()});try{var j=a.parseJSON(sessionStorage.getItem(wc_cart_fragments_params.fragment_name)),k=sessionStorage.getItem(f),l=a.cookie("woocommerce_cart_hash"),m=sessionStorage.getItem("wc_cart_created");if(null!==k&&void 0!==k&&""!==k||(k=""),null!==l&&void 0!==l&&""!==l||(l=""),k&&(null===m||void 0===m||""===m))throw"No cart_created";if(m){var n=1*m+i,o=(new Date).getTime();if(n<o)throw"Fragment expired";h=setTimeout(d,n-o)}if(!j||!j["div.widget_shopping_cart_content"]||k!==l)throw"No fragment";a.each(j,function(b,c){a(b).replaceWith(c)}),a(document.body).trigger("wc_fragments_loaded")}catch(a){d()}}else d();a.cookie("woocommerce_items_in_cart")>0?a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show():a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").hide(),a(document.body).bind("adding_to_cart",function(){a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show()})}); add-to-cart.js 0000666 00000006120 15214157447 0007216 0 ustar 00 /*! * WooCommerce Add to Cart JS */ jQuery( function( $ ) { /* global wc_add_to_cart_params */ if ( typeof wc_add_to_cart_params === 'undefined' ) { return false; } // Ajax add to cart $( document ).on( 'click', '.add_to_cart_button', function() { // AJAX add to cart request var $thisbutton = $( this ); if ( $thisbutton.is( '.ajax_add_to_cart' ) ) { if ( ! $thisbutton.attr( 'data-product_id' ) ) { return true; } $thisbutton.removeClass( 'added' ); $thisbutton.addClass( 'loading' ); var data = {}; $.each( $thisbutton.data(), function( key, value ) { data[key] = value; }); // Trigger event $( document.body ).trigger( 'adding_to_cart', [ $thisbutton, data ] ); // Ajax action $.post( wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ), data, function( response ) { if ( ! response ) { return; } var this_page = window.location.toString(); this_page = this_page.replace( 'add-to-cart', 'added-to-cart' ); if ( response.error && response.product_url ) { window.location = response.product_url; return; } // Redirect to cart option if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) { window.location = wc_add_to_cart_params.cart_url; return; } else { $thisbutton.removeClass( 'loading' ); var fragments = response.fragments; var cart_hash = response.cart_hash; // Block fragments class if ( fragments ) { $.each( fragments, function( key ) { $( key ).addClass( 'updating' ); }); } // Block widgets and fragments $( '.shop_table.cart, .updating, .cart_totals' ).fadeTo( '400', '0.6' ).block({ message: null, overlayCSS: { opacity: 0.6 } }); // Changes button classes $thisbutton.addClass( 'added' ); // View cart text if ( ! wc_add_to_cart_params.is_cart && $thisbutton.parent().find( '.added_to_cart' ).length === 0 ) { $thisbutton.after( ' <a href="' + wc_add_to_cart_params.cart_url + '" class="added_to_cart wc-forward" title="' + wc_add_to_cart_params.i18n_view_cart + '">' + wc_add_to_cart_params.i18n_view_cart + '</a>' ); } // Replace fragments if ( fragments ) { $.each( fragments, function( key, value ) { $( key ).replaceWith( value ); }); } // Unblock $( '.widget_shopping_cart, .updating' ).stop( true ).css( 'opacity', '1' ).unblock(); // Cart page elements $( '.shop_table.cart' ).load( this_page + ' .shop_table.cart:eq(0) > *', function() { $( '.shop_table.cart' ).stop( true ).css( 'opacity', '1' ).unblock(); $( document.body ).trigger( 'cart_page_refreshed' ); }); $( '.cart_totals' ).load( this_page + ' .cart_totals:eq(0) > *', function() { $( '.cart_totals' ).stop( true ).css( 'opacity', '1' ).unblock(); }); // Trigger event so themes can refresh other areas $( document.body ).trigger( 'added_to_cart', [ fragments, cart_hash, $thisbutton ] ); } }); return false; } return true; }); }); country-select.min.js 0000666 00000006167 15214157447 0010674 0 ustar 00 jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_country_select_params.i18n_matches_1:wc_country_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_country_select_params.i18n_no_matches},formatAjaxError:function(){return wc_country_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_country_select_params.i18n_input_too_short_1:wc_country_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_country_select_params.i18n_input_too_long_1:wc_country_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_country_select_params.i18n_selection_too_long_1:wc_country_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_country_select_params.i18n_load_more},formatSearching:function(){return wc_country_select_params.i18n_searching}};return a}if("undefined"==typeof wc_country_select_params)return!1;if(a().select2){var c=function(){a("select.country_select:visible, select.state_select:visible").each(function(){var c=a.extend({placeholderOption:"first",width:"100%"},b());a(this).select2(c)})};c(),a(document.body).bind("country_to_state_changed",function(){c()})}var d=wc_country_select_params.countries.replace(/"/g,'"'),e=a.parseJSON(d);a(document.body).on("change","select.country_to_state, input.country_to_state",function(){var b=a(this).closest(".woocommerce-billing-fields, .woocommerce-shipping-fields, .woocommerce-shipping-calculator");b.length||(b=a(this).closest(".form-row").parent());var c=a(this).val(),d=b.find("#billing_state, #shipping_state, #calc_shipping_state"),f=d.parent(),g=d.attr("name"),h=d.attr("id"),i=d.val(),j=d.attr("placeholder")||d.attr("data-placeholder")||"";if(e[c])if(a.isEmptyObject(e[c]))d.parent().hide().find(".select2-container").remove(),d.replaceWith('<input type="hidden" class="hidden" name="'+g+'" id="'+h+'" value="" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[c,b]);else{var k="",l=e[c];for(var m in l)l.hasOwnProperty(m)&&(k=k+'<option value="'+m+'">'+l[m]+"</option>");d.parent().show(),d.is("input")&&(d.replaceWith('<select name="'+g+'" id="'+h+'" class="state_select" data-placeholder="'+j+'"></select>'),d=b.find("#billing_state, #shipping_state, #calc_shipping_state")),d.html('<option value="">'+wc_country_select_params.i18n_select_state_text+"</option>"+k),d.val(i).change(),a(document.body).trigger("country_to_state_changed",[c,b])}else d.is("select")?(f.show().find(".select2-container").remove(),d.replaceWith('<input type="text" class="input-text" name="'+g+'" id="'+h+'" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[c,b])):d.is('input[type="hidden"]')&&(f.show().find(".select2-container").remove(),d.replaceWith('<input type="text" class="input-text" name="'+g+'" id="'+h+'" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[c,b]));a(document.body).trigger("country_to_state_changing",[c,b])}),a(function(){a(":input.country_to_state").change()})}); woocommerce.min.js 0000666 00000000425 15214157447 0010222 0 ustar 00 jQuery(function(a){a(".woocommerce-ordering").on("change","select.orderby",function(){a(this).closest("form").submit()}),a("input.qty:not(.product-quantity input.qty)").each(function(){var b=parseFloat(a(this).attr("min"));b>=0&&parseFloat(a(this).val())<b&&a(this).val(b)})}); tokenization-form.min.js 0000666 00000002614 15214157447 0011364 0 ustar 00 !function(a){a(function(){var b=function(){function b(b){var c=a(b),d=c.closest(".payment_box"),e=this;this.onTokenChange=function(){"new"===a(this).val()?(e.showForm(),e.showSaveNewCheckbox()):(e.hideForm(),e.hideSaveNewCheckbox())},this.onCreateAccountChange=function(){a(this).is(":checked")?e.showSaveNewCheckbox():e.hideSaveNewCheckbox()},this.onDisplay=function(){0===a(":input.woocommerce-SavedPaymentMethods-tokenInput:checked",c).length&&a(":input.woocommerce-SavedPaymentMethods-tokenInput:last",c).prop("checked",!0),0===c.data("count")&&a(".woocommerce-SavedPaymentMethods-new",c).hide(),a(":input.woocommerce-SavedPaymentMethods-tokenInput:checked",c).trigger("change"),a("input#createaccount").length&&!a("input#createaccount").is(":checked")&&e.hideSaveNewCheckbox()},this.hideForm=function(){a(".wc-payment-form",d).hide()},this.showForm=function(){a(".wc-payment-form",d).show()},this.showSaveNewCheckbox=function(){a(".woocommerce-SavedPaymentMethods-saveNew",d).show()},this.hideSaveNewCheckbox=function(){a(".woocommerce-SavedPaymentMethods-saveNew",d).hide()},a(":input.woocommerce-SavedPaymentMethods-tokenInput",c).change(this.onTokenChange),a("input#createaccount").change(this.onCreateAccountChange),this.onDisplay()}return b}();a(document.body).on("updated_checkout wc-credit-card-form-init",function(){var c=a("ul.woocommerce-SavedPaymentMethods");c.each(function(){new b(this)})})})}(jQuery);
| ver. 1.4 |
Github
|
.
| PHP 7.0.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings