Forum Replies Created

Viewing 15 replies - 31 through 45 (of 47 total)
  • ReactorShop

    (@reactorshop)

    Hi Chouby. I continued testing, and now I have this to comment:

    I moved the filters I’m generating to make Polylang work with WP e-Commerce into a plugin. One specific filter that I created in my child theme function file was being added after WP e-Commerce initialized some variables that I was trying to modify with it.

    Now, let’s say that my website is currently being shown in Spanish. If I use the widget language switcher to display it in English, these are the variable values I get from Polylang:

    When WordPress’ 1st loop starts, right after using the widget language switcher to select English, and a breakpoint stops execution inside my filter (the current language is now English, as expected)

    During the 2nd and 3rd WordPress loop, the current language is now Spanish when the breakpoint stops the execution inside my filter. Not good. Why is this happening?)

    After the 3rd loop, the website is displayed.

    Right after the WordPress cron job starts, and the program execution is stopped at the breakpoint inside my filter. The current language is set to false!

    I’m just comparing pll_current_language() vs pll_default_language() to see if the modification needs to be done. Then I use pll_get_post to obtain the translated post.

    Is there something I can check to fix this?

    Thank you, Chouby!

    ReactorShop

    (@reactorshop)

    Perfect!

    I can confirm it’s working the same way as before applying PLL 12dev56.

    Keep up the good work!

    Thank you, Chouby!

    ReactorShop

    (@reactorshop)

    Some say a picture is worth a 1000 words.

    Here’s the issue I have when switching to English

    Here’s the issue I have when switching to Spanish

    This happens when I use PLL 1.2dev56, not with 1.2dev55 if I lower the parse_query filter priority to 6, nor with PLL 1.1.6 or below.

    EDIT: I added define(‘PLL_AUTO_TRANSLATE’, ‘false’); in the wp-config.php file, as requested, cleared WP Super Cache cache and browser cache and I still get what’s shown in the pictures.

    ReactorShop

    (@reactorshop)

    No change from 1.1.6 to 1.2dev55, if on 1.2dev55 I lower the parse_query filter priority to 6, as I described 10 posts above to avoid the page’s 404s.

    1.2dev56 introduces the issues I described.

    I only get the posts in english inside the custom page, no matter which language I switch to, or after modifying $wp_query->queried_object and $wp_query->queried_object_id with the translated custom page ID as needed by WP e-Commerce, I get ALL the posts in both languages in the same custom page, no matter which language I switch to.

    Is this related to PLL_AUTO_TRANSLATE?

    ReactorShop

    (@reactorshop)

    I had to update $wp_query->queried_object and $wp_query->queried_object_id, because every time the WP e-Commerce function that gets the post id by short code would evaluate $wp_query->queried_object_id, it would get back the PLL’s Spanish Language Model ID after my filter was applied (I’m guessing evaluating pll_get_post will leave that information there), instead of the english custom page post ID WP e-Commerce was expecting, which wasn’t convenient for me either.

    ReactorShop

    (@reactorshop)

    Polylang has only minor, non show stopping issues when used with WP e-Commerce.

    The only situations I find, for the moment, is that the custom pages slugs, when viewing a single product, are the only items not translated in the complete permalink and that certain functionality is tied to their specific english custom pages post ID. For the last issue, I added a filter which fixes that, as described below. Everything else works fine.

    To answer your questions, for the first issue, this is how it worked up until PLL 1.1.6 and PLL 1.2dev551 (lowering the parse_query filter priority to 6):

    The custom products page will show:

    In English:
    https://www.mywebsite.com/en/products-page/

    In Spanish:
    https://www.mywebsite.com/es/pagina-de-productos/

    Which is still the same behavior now obtained with PLL 1.2dev56.

    Up until PLL 1.1.6 and PLL 1.2dev551, the custom products posts permalinks shown in a grid view inside the custom products page are:

    In English:

    https://www.mywebsite.com/en/products-page/<english product category>/<english product slug>

    In Spanish:

    https://www.mywebsite.com/es/products-page/<spanish product category>/<spanish product slug>

    But now with PLL 1.2dev56 I only get the English version for either language.

    Since WP e-Commerce uses the post ID to identify that their custom page is shown in order to apply to it their grid view template, I created a filter in my child theme’s function.php file, and hooked it to the function they use to get their english custom page id and used pll_get_post to send back the translated custom page post ID instead, and to update $wp_query->queried_object and $wp_query->queried_object_id with the translated post info, since WP e-Commerce uses queried_object_id to verify that it is in fact their custom page post ID.

    It works great showing the translated custom posts in the grid view inside the translated custom page up unit PLL 1.2dev551, but with PLL 1.2dev56 I now get all the posts in both languages in either language of the custom products page post.

    Each custom product post now shows their expected permalink, based on their language, though.

    For the second issue, I find it odd, because when WP e-Commerce creates the custom products page, it declares it with a ‘page’ type, and later on I find in $wp_query that its type is referred to as ‘wpsc-product’, which is the custom products posts (not page) type. I have other WP e-Commerce related plugins, so maybe one of them is at fault here. I’ll have to check, though.

    So, what could have happened in PLL 1.2dev56 that might create the first issue’s behavior?

    Thank you, Chouby!

    EDIT PS: The PLL’s change in behavior I had for the first issue (from always showing the posts permalinks from English posts in both languages to showing ALL the posts permalinks from both languages IN both languages) is happening after I started updating $wp_query->queried_object and $wp_query->queried_object_id with the custom products page information as WP e-Commerce requires. I’m guessing PLL is using either of them to validate something.

    ReactorShop

    (@reactorshop)

    I can report that the 404 is corrected now.

    But now the translated custom posts (‘wpsc-products’) are not shown. $GLOBALS[‘post’] has their english counter parts instead, when using a language different than english.

    So, after clicking the custom page permalink shown like this:

    https://www.mywebsite.com/es/pagina-de-productos/

    All the products (wpsc-product) custom posts permalinks inside that page show their permalinks like this (using a language different than english):

    https://www.mywebsite.com/en/products-page/<english category>/<english product slug>

    The products page permalink still remains in spanish. The ‘products-page’ slug is the only one I expected to be in english, because it’s the behavior I’ve been carrying since I started using Polylang.

    I’m still checking what is now causing this with PLL 1.2dev56

    And here’s something I found (I don’t know if this existed before PLL 1.2dev56):

    Inside the file …polylang/frontend/frontend-auto-translate.php, there’s a pre_get_posts($query) function. At line 140 it shows the following foreach:

    // 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 = pll_get_post($id)) && $tr = get_post($tr_id)) ? $tr->post_name : $qv[$key];
    			}
    		}

    I have a Wp e-Commerce custom page that shows the following data when reaching that foreach:

    $qv['name'] == NULL;
    $qv['pagename'] == 'products-page'];
    $qv['post_type'] == 'wpsc-product';

    That custom page is stored in the wp_posts table with a ‘post_type’ == ‘page’, so PLL’s query doesn’t find the post ID since the post types don’t match.

    I switched the ‘post_type’ part of the query for a post_status=’publish’, and the query found the english version of that post, and in the next row, it found the translated page, so $qv[‘pagename’] is now set to the translated name as expected.

    Using post_status = ‘publish’, I’m limiting the post IDs this query might bring back. but I’m not sure if that’s good enough, though.

    I’ll continue testing to see what else I can find.

    Ignore what I wrote in my previous post.

    I did further testing, and found out that if I only lower the priority of the filter located at line 38 in the fronted-filters.php file from:

    add_filter('parse_query', array(&$this, 'parse_query'), 4);

    to

    add_filter('parse_query', array(&$this, 'parse_query'), 6);

    I no longer get the 404 error when displaying the translated WP e-Commerce’s custom post products page.

    I don’t know why. The only other WP e-Commerce filters/actions I find hooked to parse_query are:

    add_filter( 'parse_query', 'wpsc_mark_product_query', 12 );

    and to pre_get_posts:

    add_filter( 'pre_get_posts', 'wpsc_split_the_query', 8 );
    add_action( 'pre_get_posts', array( &$hide_subcatsprods, 'get_posts' ) );
    add_filter( 'pre_get_posts', 'wpsc_generate_product_query', 11 );
    add_action( 'pre_get_posts', 'wpsc_product_list_exclude_child_categories', 15 );

    I’m sorry for misleading.

    Thank you, Chouby.

    Thank you for the explanation, Chouby.

    I started “learning” PHP with WordPress about 3 weeks ago, so I still either don’t get or don’t know the whole inner workings of WordPress. Any help or orientation is really appreciated.

    Now, let’s go to my next finding.

    Moving Polylang’s pre_get_posts filters to the parse_query filters is causing me a situation similar to the one I described 2 posts above.

    WP e-Commerce filters are again rewriting Polylang’s filters work. Here’s their filter hooked to pre_get_posts, changing the translated custom post id to the english custom post id.

    add_filter( 'pre_get_posts', 'wpsc_generate_product_query', 11 );
    function wpsc_generate_product_query( $query ) {
    	global $wp_query;
    	$prod_page = wpsc_get_the_post_id_by_shortcode('[productspage]');
    	$prod_page = get_post($prod_page);
    	remove_filter( 'pre_get_posts', 'wpsc_generate_product_query', 11 );
    	$query->query_vars['taxonomy'] = null;
    	$query->query_vars['term'] = null;
    
    	// default product selection
    	if ( $query->query_vars['pagename'] != '' ) {
    		$query->query_vars['post_type'] = 'wpsc-product';
    		$query->query_vars['pagename']  = '';
    		$query->is_page     = false;
    		$query->is_tax      = false;
    		$query->is_archive  = true;
    		$query->is_singular = false;
    		$query->is_single   = false;
    	}
    
    	// If wpsc_item is not null, we are looking for a product or a product category, check for category
    	if ( isset( $query->query_vars['wpsc_item'] ) && ($query->query_vars['wpsc_item'] != '') ) {
    		$test_term = get_term_by( 'slug', $query->query_vars['wpsc_item'], 'wpsc_product_category' );
    		if ( $test_term->slug == $query->query_vars['wpsc_item'] ) {
    			// if category exists (slug matches slug), set products to value of wpsc_item
    			$query->query_vars['products'] = $query->query_vars['wpsc_item'];
    		} else {
    			// otherwise set name to value of wpsc_item
    			$query->query_vars['name'] = $query->query_vars['wpsc_item'];
    		}
    	}
    
    	if ( isset( $query->query_vars['products'] ) && ($query->query_vars['products'] != null) && ($query->query_vars['name'] != null) ) {
    		unset( $query->query_vars['taxonomy'] );
    		unset( $query->query_vars['term'] );
    		$query->query_vars['post_type'] = 'wpsc-product';
    		$query->is_tax      = false;
    		$query->is_archive  = true;
    		$query->is_singular = false;
    		$query->is_single   = false;
    	}
    	if( isset($wp_query->query_vars['wpsc_product_category']) && !isset($wp_query->query_vars['wpsc-product'])){
    		$query->query_vars['wpsc_product_category'] = $wp_query->query_vars['wpsc_product_category'];
    		$query->query_vars['taxonomy'] = $wp_query->query_vars['taxonomy'];
    		$query->query_vars['term'] = $wp_query->query_vars['term'];
    	}elseif( '' != ($default_category = get_option('wpsc_default_category')) && !isset($wp_query->query_vars['wpsc-product'])){
    		$default_term = get_term($default_category,'wpsc_product_category');
    		if(!empty($default_term) && empty($wp_query->query_vars['category_name'])){
    			$query->query_vars['taxonomy'] = 'wpsc_product_category';
    			$query->query_vars['term'] = $default_term->slug;
    			$query->is_tax = true;
    		}elseif(isset($wp_query->query_vars['name']) && $wp_query->is_404 && $wp_query->query_vars['category_name'] != $prod_page->post_name){
    			unset( $query->query_vars['taxonomy'] );
    			unset( $query->query_vars['term'] );
    			$query->query_vars['wpsc-product'] = $wp_query->query_vars['name'];
    			$query->query_vars['name'] = $wp_query->query_vars['name'];
    
    		}else{
    			$query->is_tax = true;
    			$term =	get_term_by('slug',$wp_query->query_vars['name'], 'wpsc_product_category' );
    			if(!empty($term)){
    				$query->query_vars['taxonomy'] = 'wpsc_product_category';
    				$query->query_vars['wpsc_product_category__in'] = array($term->term_taxonomy_id);
    				$query->query_vars['wpsc_product_category'] = $wp_query->query_vars['name'];
    				$query->query_vars['term'] = $wp_query->query_vars['name'];
    			}elseif(is_numeric($default_category)){
    				$query->query_vars['taxonomy'] = 'wpsc_product_category';
    			}else{
    				$query->is_tax = false;
    			}
    		}
    	}
    	//If Product Tag Taxonomy
    	if (isset($wp_query->query_vars['product_tag']) && $wp_query->query_vars['product_tag']){
    		$query->query_vars['product_tag'] = $wp_query->query_vars['product_tag'];
    		$query->query_vars['term'] = $wp_query->query_vars['term'];
    		$query->query_vars['taxonomy'] = 'product_tag';
    		$query->is_tax      = true;
    	}
    	if(1 == get_option('use_pagination')){
    		$query->query_vars['posts_per_page'] = get_option('wpsc_products_per_page');
    		if( isset( $_GET['items_per_page'] ) ) {
    			if ( is_numeric( $_GET['items_per_page'] ) ) {
    				$query->query_vars['posts_per_page'] = (int) $_GET['items_per_page'];
    			} elseif ( $_GET['items_per_page'] == 'all' ) {
    				$query->query_vars['posts_per_page'] = -1;
    				$query->query_vars['nopaging'] = 1;
    			}
    		}
    	} else {
    		$query->query_vars['posts_per_page'] = -1;
    		$query->query_vars['nopaging'] = 1;
    	}
    	if ( $query->is_tax == true )
    		new wpsc_products_by_category( $query );
    	return $query;
    }

    These are the modifications I had to revert in your code in order for it to work as it was before with PLL 1.2dev54 (without 404s):

    diff -r polylang12dev55/frontend/choose-lang.php polylang12dev54/frontend/choose-lang.php
    33c33
    > 		add_filter('pre_get_posts', array(&$this, 'parse_main_query'), 1); // sets the language in special cases
    ---
    < 		add_filter('parse_query', array(&$this, 'parse_main_query'), 2); // sets the language in special cases
    diff -r polylang12dev55/frontend/frontend-filters.php polylang12dev54/frontend/frontend-filters.php
    38c38
    > 		add_filter('pre_get_posts', array(&$this, 'pre_get_posts'), 5); // filters posts according to the language
    ---
    < 		add_filter('parse_query', array(&$this, 'parse_query'), 4); // filters posts according to the language
    139c138
    > 	public function pre_get_posts($query) {
    ---
    < 	public function parse_query($query) {

    By the way, I’m now testing Polylang using PHP 5.4.17. I haven’t detect any situation when compared to PHP 5.2.X, which I was using before.

    If you require any additional information regarding this situation, feel free to ask me.

    Thank you, Chouby!

    I’m not sure if it’s the same situation described above, but after further testing PLL 1.2dev54, I found out why the Yoast’s SEO wpml-config.xml file was not loading into my Polylang’s String Translation tab.

    I have a WordPress multi-site installation, and I install all my plugins from my Network Admin Dashboard and do a site wide network activation.

    If you do this, when you go out of your Network Admin Dashboard into a specific site dashboard and look for plugins, you’re going to find none. This happens unless you deactivate them in your Network Admin Dashboard. Then you are going to find them on a per-site basis and will have the option to activate them for a specific site only.

    For me, this represents that if I do a get_option(‘active_plugins’), I’m going to get no plugin information at all.

    Polylang currently checks for plugins activated on a single site installation or per-site basis only:

    ...polylang/include/wpml-compat.php, line 472
    
                    // plugins
    		foreach (get_option('active_plugins') as $plugin) {
    			if (file_exists($file = dirname(POLYLANG_DIR).'/'.dirname($plugin).'/wpml-config.xml'))
    				$this->xml_parse(file_get_contents($file), dirname($plugin));
    		}

    What I did, is to check for get_site_option(‘active_sitewide_plugins’), and this will pull all the network activated plugins paths, and this will allow Polylang to read and integrate their wpml-config.xml data into the String Translation tab:

    // network activated plugins
    		foreach (get_site_option( 'active_sitewide_plugins') as $plugin => $time ) {
    			if (file_exists($file = dirname(POLYLANG_DIR).'/'.dirname($plugin).'/wpml-config.xml'))
    				$this->xml_parse(file_get_contents($file), dirname($plugin));
    		}

    And now all of Yoast’s SEO metadata is shown to me at the Strings Translation tab ready for me to translate.

    It’s important to keep both code snippets in that file because of what I described in the bold paragraph.

    Chouby, I hope you can add this to the next Polylangs’ dev.

    Thank you, Chouby!

    Thank you, Chouby,

    I can confirm that the findings I reported are fixed now with PLL 1.2dev54.

    I have a new finding for you to check out:

    Up until PLL 1.1.6, the WP e-Commerce products page custom post type (wpsc-product) permalink structure would be modified like this (in my case):

    https://www.mydomain.com/en/products-page/<product category>/<product slug/
    https://www.mydomain.com/es/products-page/<translated product category>/<translated product slug/

    Now, with PLL 1.2dev54, the language slug is missing:

    https://www.mydomain.com/products-page/<product category>/<product slug/
    https://www.mydomain.com/products-page/<translated product category>/<translated product slug/

    This is what I traced:

    /* The child theme is about to display a product using the WP e-Commerce theme backed up grid view script */
    
    ...themes/twentytwelve-dark/wpsc-grid_view.php
    
    ...
    	<div class="product_grid_display group">
    		<?php while (wpsc_have_products()) :  wpsc_the_product(); ?>
    			<div class="product_grid_item product_view_<?php echo wpsc_the_product_id(); ?>">
    
    				<?php if(wpsc_the_product_thumbnail()) :?>
    					<div class="item_image">
    						<a href="<?php echo wpsc_the_product_permalink(); ?>">   // <--- Here's the product permalink request.
    ...
    
    ...wp-includes/link-template.php
    
    function get_post_permalink( $id = 0, $leavename = false, $sample = false ) { // line 178
    ...
    	$post_link = $wp_rewrite->get_extra_permastruct($post->post_type);   // line 186 $post->post_type == 'wpsc-product'
    ...
    
    ...wp-includes/rewrite.php
    
    function extra_permastructs( $id = 0, $leavename = false, $sample = false ) {
    ...
    if ( isset($this->extra_permastructs[$name]) )             // line 1042
         return $this->extra_permastructs[$name]['struct'];    // WP_Rewrite->extra_permastructs['wpsc-product']['struct'] == products-page/%wpsc_product_category%/%wpsc-product%
    
    ...wp-includes/link-template.php
    
    function get_post_permalink( $id = 0, $leavename = false, $sample = false ) { // line 178
    ...
    	$post_link = str_replace("%$post->post_type%", $slug, $post_link);    // line 198 $slug == <product slug>, $post_link == products-page/%wpsc_product_category%/<product slug>
    ...
    	$post_link = home_url( user_trailingslashit($post_link) );            // line 200 $post_link == https://www.mywebsite.com/products-page/%wpsc_product_category%/<product slug>/
    ...
    	return apply_filters('post_type_link', $post_link, $post, $leavename, $sample); // line 209
    
    ...wp-includes/plugin.php
    
    function apply_filters($tag, $value) {                       // line 137 $tag == 'post_type_link'
    
    	foreach( (array) current($wp_filter[$tag]) as $the_ )    // line 170
    		if ( !is_null($the_['function']) ){                  // the_['function'][0] == 'PLL_Frontend_Filters', the_['function'][1] == 'post_link'
    			$args[1] = $value;                               // $args[1] = 'https://www.mywebsite.com/products-page/%wpsc_product_category%/<product slug>/'
    			$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
    	}
    
    ...polylang/include/filters-base.php
    
    public function post_link($link, $post) {         // line 45 $link ==  'https://www.mywebsite.com/products-page/%wpsc_product_category%/<product slug>/'
    	static $links = array();                      // $links['https://www.mywebsite.com/pagina-de-productos/'] == https://www.mywebsite.com/es/pagina-de-productos/'
                                                      // $links['https://www.mywebsite.com/products-page/'] == https://www.mywebsite.com/en/products-page/
                                                      // $links['https://www.mywebsite.com/contacto/'] == https://www.mywebsite.com/es/contacto/
    ...
    
    	return $links[$link] = $post->post_status != 'publish' ? $link : $this->links_model->add_language_to_link($link, $this->model->get_post_language($post->ID)); // line 58
    
    ...polylang/include/links-directory.php
    
    public function add_language_to_link($url, $lang) {                                                                        // line 43
    ...
    	$base = $this->options['rewrite'] ? '' : 'language/';                                                                  // line 48 $base == NULL (don't want /language/ appended to permalink)
    	$slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base.$lang->slug.'/';  // $slug == 'es/'
    	return str_replace($this->home.'/'.$wp_rewrite->root, $this->home.'/'.$wp_rewrite->root.$slug, $url);                  // $this->home == 'https://www.mywebsite.com', $wp_rewrite->root == NULL, $url == https://www.mywebsite.com/products-page/%wpsc_product_category%/<product slug>/
    
    ...wp-includes/plugin.php
    
    function apply_filters($tag, $value) {                                                                  // line 137 $tag == 'post_type_link'
    
    foreach( (array) current($wp_filter[$tag]) as $the_ )                                                   // line 170
    	if ( !is_null($the_['function']) ){                                                                 // the_['function'][0] == 'wpsc_product_link'    (WARNING: PLL_Frontend_Filters' post_link filter was applied too soon!!!!!!)
    		$args[1] = $value;                                                                              // $args[1] = 'https://www.mywebsite.com/es/products-page/%wpsc_product_category%/<product slug>/'
    		$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
    	}
    
    ...wp-e-commerce/wpsc-core/wpsc-functions.php
    
    function wpsc_product_link( $permalink, $post, $leavename ) {                // line 1318 $permalink == 'https://www.mywebsite.com/es/products-page/%wpsc_product_category%/<product slug>/'
    	global $wp_query, $wpsc_page_titles, $wpsc_query, $wp_current_filter;
    	$rewritecode = array(                                                    // $rewritecode[0] == %wpsc_product_category%
    		'%wpsc_product_category%',                                           // $rewritecode[1] == %postname%
    		$leavename ? '' : '%postname%',
    	);
    	if ( is_object( $post ) ) {
    		// In wordpress 2.9 we got a post object
    		$post_id = $post->ID;                                                // gets the $post_id as an integer value
    	} else {
    		// In wordpress 3.0 we get a post ID
    	$post_id = $post;
    	$post = get_post( $post_id );
    	}
    
    	// Only applies to WPSC products, don't stop on permalinks of other CPTs
    	// Fixes https://code.google.com/p/wp-e-commerce/issues/detail?id=271
    	if ($post->post_type != 'wpsc-product')
    		return $permalink;
    
    	$permalink_structure = get_option( 'permalink_structure' );    // $permalink_structure == /blog/%category%/%postname%/
    
    	// This may become customiseable later
    	$our_permalink_structure = str_replace( basename( home_url() ), '', $wpsc_page_titles['products'] ) . "/%wpsc_product_category%/%postname%/";  // $our_permalink_structure == products-page/%wpsc_product_category%/%postname%/ (here's the problem!!!!)
    	// Mostly the same conditions used for posts, but restricted to items with a post type of "wpsc-product "
    
    	if ( '' != $permalink_structure && !in_array( $post->post_status, array( 'draft', 'pending' ) ) ) {
    		$product_categories = wpsc_get_product_terms( $post_id, 'wpsc_product_category' );       // $product_categories == <array of translated product categories>
    		$product_category_slugs = array( );
    		foreach ( $product_categories as $product_category ) {
    			$product_category_slugs[] = $product_category->slug;                                 // $product_categories_slugs == <array of translated product categories slugs>
    		}
    		// If the product is associated with multiple categories, determine which one to pick
    		if ( count( $product_categories ) == 0 ) {
    			$category_slug = 'uncategorized';
    		} elseif ( count( $product_categories ) > 1 ) {
    			if ( (isset( $wp_query->query_vars['products'] ) && $wp_query->query_vars['products'] != null) && in_array( $wp_query->query_vars['products'], $product_category_slugs ) ) {
    				$product_category = $wp_query->query_vars['products'];
    			} else {
    				$link = $product_categories[0]->slug;
    				if ( ! in_array( 'wp_head', $wp_current_filter) && isset( $wpsc_query->query_vars['wpsc_product_category'] ) ) {
    					$current_cat = $wpsc_query->query_vars['wpsc_product_category'];
    					if ( in_array( $current_cat, $product_category_slugs ) )
    						$link = $current_cat;
    				}
    
    				$product_category = $link;                        // $product_category == <current product's product category>
    			}
    			$category_slug = $product_category;
    		} else {
    			// If the product is associated with only one category, we only have one choice
    			if ( !isset( $product_categories[0] ) )
    				$product_categories[0] = '';
    
    			$product_category = $product_categories[0];
    
    			if ( !is_object( $product_category ) )
    				$product_category = new stdClass();
    
    			if ( !isset( $product_category->slug ) )
    				$product_category->slug = null;
    
    			$category_slug = $product_category->slug;
    		}
    
    		$post_name = $post->post_name;                            // $post_name == <product slug>
    
    		if ( get_option( 'product_category_hierarchical_url', 0 ) ) {
    			$selected_term = get_term_by( 'slug', $category_slug, 'wpsc_product_category' );
    			if ( is_object( $selected_term ) ) {
    				$term_chain = array( $selected_term->slug );
    				while ( $selected_term->parent ) {
    					$selected_term = get_term( $selected_term->parent, 'wpsc_product_category' );
    					array_unshift( $term_chain, $selected_term->slug );
    				}
    				$category_slug = implode( '/', $term_chain );
    			}
    		}
    
    		if( isset( $category_slug ) && empty( $category_slug ) )
    			$category_slug = 'product';                             // $category_slug == <current product's product category>
    
    		$category_slug = apply_filters( 'wpsc_product_permalink_cat_slug', $category_slug, $post_id );
    
    		$rewritereplace = array(                                    //$rewritereplace == array of (<current product's product category>, <product slug>)
    			$category_slug,
    			$post_name
    		);
    
    		$permalink = str_replace( $rewritecode, $rewritereplace, $our_permalink_structure );  //$permalink == products-page/<current product's product category>/<product slug>/
    		$permalink = user_trailingslashit( $permalink, 'single' );
    
    		$permalink = home_url( $permalink );  //$permalink == https://www.mywebsite.com/products-page/<current product's product category>/<product slug>/ (and the language slug is gone!!!!)
    	}
    	return apply_filters( 'wpsc_product_permalink', $permalink, $post->ID );
    }
    	add_filter( 'post_type_link', 'wpsc_product_link', 10, 3 ); // <--- Here's the wpsc_product_link filter setting.

    So, PLL’s post_link filter actions are overwritten by the wpsc_product_link filter actions.

    To temporarily fix this, I decreased the PLL’s post_link filter priority from 10 to 11, and now I get the language slug the same way as it was shown with PLL 1.1.6.

    It seems to me that this is related to the order in which WordPress loads all the plugins.

    I remember that the plugins are sorted alphabetically and then loaded, so the Polylang’s filters might be added before the WP e-Commerce filter, and since both filters have the same priority, the Polylang filter is applied first.

    Well, at least that’s my theory.

    I’ll continue testing to see what else do I find.

    Again, thank you Chouby!

    Thank you, Chouby,

    To continue testing, here’s my temporary fix to that find:

    /* .../polylang/frontend/frontend-nav-menu.php  line 157*/
    
    public function nav_menu_locations($menus) {
    		$curlang = pll_current_language();
    
    		if(!is_bool($menus)) // Added an if to only enter the foreach loop if $menus is not bool.
    			foreach ($menus as $loc => $menu) {
    				if (($pos = strpos($loc, '___')) && substr($loc, $pos+3) == $curlang)
    					$arr[substr($loc, 0, $pos)] = $menu;
    			}
    
    		return empty($arr) ? $menus : array_merge($menus, $arr);
    	}

    And here’s another find:

    If the last time you loaded your website was on a language different than english, or if, for example, you type:

    https://www.mywebsite.com/es/ (or any other slug that is not /en/)

    The website will load using the last language stored in your cookie or as the permalink requests (both as expected), but the language switcher will always show English (the first entry in the switcher list).

    I traced the situation to this function:

    /* ...polylang/include/walker-dropdown.php  line 18 */
    
    	function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) {
    		$value = isset($args['value']) && $args['value'] ? $args['value'] : 'slug';
    		$output .= sprintf(
    			"\t".'<option value="%s"%s>%s</option>'."\n",
    			esc_attr($element->$value),
    			isset($args['selected']) && $args['selected'] == $element->$value ? ' selected="selected"' : '',
    			esc_html($element->name)
    		);
    	}

    At first glance, I couldn’t find any instance of $args[‘selected’] being set throughout Polylang’s plugin files.

    In order to continue testing, I fixed it like this:

    function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) {
    		$value = isset($args['value']) && $args['value'] ? $args['value'] : 'slug';
    		// Add to $args['selected'] the language slug value if $element matches current
    		// language to preselect it in the widget language switcher.
    		if(pll_current_language() == $element->slug) {
    			$args['selected'] = $element->$value;
    		} else {
    			if(isset($args['selected'])) {
    				unset($args['selected']); // They don't exist.
    			}
    		}
    		$output .= sprintf(
    			"\t".'<option value="%s"%s>%s</option>'."\n",
    			esc_attr($element->$value),
    			isset($args['selected']) && $args['selected'] == $element->$value ? ' selected="selected"' : '',
    			esc_html($element->name)
    		);
    	}

    And now the widget’s selected language updates and switches languages as expected.

    I’ll continue testing to see what other findings I can contribute.

    Thank you, Chouby!

    Hello Chouby,

    I downloaded the 1.2 beta version today and began testing.

    My server is logging an invalid argument warning. I’m including a “trace” for this error below:

    /* Trail starts when WordPress processes the navigation menu for the twentytwelve theme*/
    
     /* ...themes/twentytwelve/header.php */
    
    <body <?php body_class(); ?>>
    <div id="page" class="hfeed site">
    	<header id="masthead" class="site-header" role="banner">
    		<hgroup>
    			<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
    			<h2 class="site-description"><?php bloginfo( 'description' ); ?></h2>
    		</hgroup>
    
    		<nav id="site-navigation" class="main-navigation" role="navigation">
    			<h3 class="menu-toggle"><?php _e( 'Menu', 'twentytwelve' ); ?></h3>
    			<a class="assistive-text" href="#content" title="<?php esc_attr_e( 'Skip to content', 'twentytwelve' ); ?>"><?php _e( 'Skip to content', 'twentytwelve' ); ?></a>
    			<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu' ) ); ?>       /* calls the wp_nav_menu function */
    			.
    			.
    			.
    
    /* .../wp-includes/nav-menu-template.php line 147 */
    
    function wp_nav_menu( $args = array() ) {
    	static $menu_id_slugs = array();
    
    	$defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
    	'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
    	'depth' => 0, 'walker' => '', 'theme_location' => '' );     /* <-- menu == NULL */
    
    	$args = wp_parse_args( $args, $defaults );
    	$args = apply_filters( 'wp_nav_menu_args', $args );
    	$args = (object) $args;                                     
    
    	// Get the nav menu based on the requested menu
    	$menu = wp_get_nav_menu_object( $args->menu );				/* <-- $menu == false */
    
    	// Get the nav menu based on the theme_location
    	if ( ! $menu && $args->theme_location && ( $locations = get_nav_menu_locations() )   /* <-- calls get_nav_menu_location() next */
    	&& isset( $locations[ $args->theme_location ] ) )  $menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] );
    	.
    	.
    	.
    
    /* ...wp-includes/nav-menu.php line 129 */
    
    function get_nav_menu_locations() {
    	$locations = get_theme_mod( 'nav_menu_locations' ); 		/* evaluates get_theme_mod() next */
    	return ( is_array( $locations ) ) ? $locations : array();
    }
    
    /* ...wp-includes/theme.php line 776 */
    
    function get_theme_mod( $name, $default = false ) {  	/* $name == 'nav_menu_location', $default == false */
    	$mods = get_theme_mods();							/* evaluates get_theme mods() next */
    	.
    	.
    	.
    
    /* ...wp-includes/theme.php line 746 */
    
    function get_theme_mods() {
    	$theme_slug = get_option( 'stylesheet' ); 								/* $theme_slug == 'twentytwelve-dark'; (my twentytwelve based child theme) */
    	if ( false === ( $mods = get_option( "theme_mods_$theme_slug" ) ) ) {   /* value from db cache == a:2:{i:0;b:0;s:18:"nav_menu_locations";N;} */
    		$theme_name = get_option( 'current_theme' );
    		if ( false === $theme_name )
    			$theme_name = wp_get_theme()->get('Name');
    		$mods = get_option( "mods_$theme_name" ); // Deprecated location.
    		if ( is_admin() && false !== $mods ) {
    			update_option( "theme_mods_$theme_slug", $mods );
    			delete_option( "mods_$theme_name" );
    		}
    	}
    	return $mods;															/* $mods == array ( [0] => false, [nav_menu_locations] => NULL )*/
    }																			/* returns to get_theme_mod() next */
    
    /* ...wp-includes/theme.php line 776 */
    
    function get_theme_mod( $name, $default = false ) {
    	$mods = get_theme_mods();										
    
    	if ( isset( $mods[ $name ] ) )									/* $mods['nav_menu_location'] == NULL */
    		return apply_filters( "theme_mod_$name", $mods[ $name ] );
    
    	if ( is_string( $default ) )									/* $default is boolean */
    		$default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() );
    
    	return apply_filters( "theme_mod_$name", $default );			/* this filter is applied with $default == false */
    }
    
    /* ...wp-includes/plugin.php line 137 */
    function apply_filters($tag, $value) {								/* $tag == theme_mod_nav_menu_locations, $value == false */
    .
    .
    .
    
    do {
    		foreach( (array) current($wp_filter[$tag]) as $the_ )   /* the_ == array ( [0] ==> 'PLL_Frontend_Nav_Menu' , [1] ==> 'nav_menu_locations' ) */
    			if ( !is_null($the_['function']) ){
    				$args[1] = $value;								/* $args == array ([0] ==> 'theme_mod_nav_menu_locations', [1] ==> false ) */
    				$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
    			}
    
    	} while ( next($wp_filter[$tag]) !== false );
    	.
    	.
    	.
    
    /* ...polylang/frontend/frontend-nav-menu.php line 157 */
    
    public function nav_menu_locations($menus) {     /* $menus = false */
    		$curlang = pll_current_language();
    
    		foreach ($menus as $loc => $menu) {    /* <-- $menus == false --> Server Error Log: PHP Warning:  Invalid argument supplied for foreach() in ...polylang/frontend/frontend-nav-menu.php on line 160 */
    			if (($pos = strpos($loc, '___')) && substr($loc, $pos+3) == $curlang)
    				$arr[substr($loc, 0, $pos)] = $menu;
    		}
    
    		return empty($arr) ? $menus : array_merge($menus, $arr);
    	}       /* returns false to nav-menu.php next */

    I figured that I can condition the foreach cycle to be processed if $menus is not boolean, but I don’t know if there are any repercussions for Polylang due to this error later on.

    I discovered today which plugin is causing my website to break with 404s all over the place when combining Polylang, Yoast SEO, WP e-Commerce, WP Super Cache and a small bunch of other (really great) plugins.

    It’s the WP e-Commerce Predictive Search plugin. It’s not enough to deactivate it or uninstall it. The damage is already done.

    I had to revert to a backup done earlier today and it worked as it was before.

    Just so you all know.

    My WordPress website broke with 404s all over the place, so I reinstalled WordPress, again, yesterday morning. I decided to install only the plugins that I deemed absolutely necessary and let the more complex ones (e.g. WP Super Cache) at their default settings, without customization.

    My website it’s been working fine for a while now (it was taking less than 4 hours to brake as I customized it before), so my guess is that certain custom settings from WP Super Cache (maybe the use of mod_rewrite instead of PHP to serve cached files) or Better WP Security (I didn’t install it this time) might be causing the Polylang plugin or the whole WordPress installation to brake.

    It’s working fine using the language code (/en/ or /es/) added to all urls when using pretty permalinks, as it is your recommended setting when using Yoast SEO. The permalink part for the WP e-Commerce pages titles switch to English, when containing a post, but that’s something that I can live with.

    I’ve set up a localhost mirror copy of my website in my mac, using it’s native Apache and PHP installations, and I’ve been going through it with Netbeans, but it takes a lot of time to debug a system so big and complex, and sometimes time is limited.

    That’s why, Chouby, I totally understand and respect the work you’ve been doing with the Polylang plugin. We just hope that you get the time to fix these situations at a later release.

    Thank you, Chouby!

Viewing 15 replies - 31 through 45 (of 47 total)