Forum Replies Created

Viewing 15 replies - 1 through 15 (of 47 total)
  • Thread Starter ReactorShop

    (@reactorshop)

    This is what’s causing the issue (from wp-includes/class-wp-theme.php):

    public function load_textdomain() {
    	if ( isset( $this->textdomain_loaded ) )
    		return $this->textdomain_loaded;
    
    	$textdomain = $this->get('TextDomain');
    	if ( ! $textdomain ) {
    		$this->textdomain_loaded = false;
    		return false;
    	}
    
    	if ( is_textdomain_loaded( $textdomain ) ) {
    		$this->textdomain_loaded = true;
    		return true;
    	}
    
    	$path = $this->get_stylesheet_directory();
    	if ( $domainpath = $this->get('DomainPath') ) <------ THIS!
    		$path .= $domainpath;
    	else
    		$path .= '/languages'; <------ IT TAKES THIS DEFAULT VALUE!
    
    	$this->textdomain_loaded = load_theme_textdomain( $textdomain, $path );
    	return $this->textdomain_loaded;
    }

    Which is called by this function (in that same file):

    public function display( $header, $markup = true, $translate = true ) {
    	$value = $this->get( $header );
    	if ( false === $value ) {
    		return false;
    	}
    
    	if ( $translate && ( empty( $value ) || ! $this->load_textdomain() ) )
    		$translate = false;
    
    	if ( $translate )
    		$value = $this->translate_header( $header, $value ); <-- THIS
    
    	if ( $markup )
    		$value = $this->markup_header( $header, $value, $translate );
    
    	return $value;
    }

    Where $header == ‘AutorURI’ and $value = ‘https://presscustomizr.com/&#8217;

    Which is called by the class construct in …/themes/customizr/inc/init.php

    if ( ! class_exists( 'TC___' ) ) :
      class TC___ {
        //Access any method or var of the class with classname::$instance -> var or method():
        static $instance;
        public $tc_core;
        public $is_customizing;
        public static $theme_name;
        public static $tc_option_group;
    
        function __construct () {
          self::$instance =& $this;
    
          /* GETS INFORMATIONS FROM STYLE.CSS */
          // get themedata version wp 3.4+
          if( function_exists( 'wp_get_theme' ) ) {
            //get WP_Theme object of customizr
            $tc_theme                     = wp_get_theme();
    
            //Get infos from parent theme if using a child theme
            $tc_theme = $tc_theme -> parent() ? $tc_theme -> parent() : $tc_theme;
    
            $tc_base_data['prefix']       = $tc_base_data['title'] = $tc_theme -> name;
            $tc_base_data['version']      = $tc_theme -> version;
            $tc_base_data['authoruri']    = $tc_theme -> {'Author URI'}; <--- THIS!
          }

    So,

    1. The Customizr class construct assigns the theme’s Autor URI, among other values.
    2. The WordPress Theme class decides that the Autor URI needs translation.
    3. Since the Customizr translation domain is not loaded yet, the WordPress theme class decides to load it on its own, assigning default values.
    4. The translation file is not found, so the customizr domain is not loaded.

    Thread Starter ReactorShop

    (@reactorshop)

    It can’t be loaded because it’s looking for the translation files in a …/themes/customizr/languages/ folder that doesn’t exist.

    The folder where the translations files are located is …/themes/customizr/inc/lang/

    “Grid View Lite is active. We’ve detected that your product image thumbnails are not scaled to size.”

    This means that the images shown are downscaled and cropped into a square default size of 148×148 to be shown in grid view, unless you selected a different square size at WPEC’s Presentation admin tab.

    You may buy the pro version to get those images automatically downscaled to 148x? or ?x148 without being cropped, as any normally rectangular sized picture would be downscaled.

    The other option is to add filters to a plugin to convert the 148×148 downscaled product pictures to 148x? or ?x148, depending if the image largest size is the base or the side, respectively.

    Please insert this code snippet into a plugin or your theme’s function.php file:

    /*Fixes the infinite loop when trying to log into the admin page (from a HTTPS page
    */into a HTTP page) by setting the WordPress cookie as not secure.
    function rsssl_secure_cookie( $secure_cookie, $credentials ) {
    	return FALSE;
    }
    add_filter( 'secure_signon_cookie', 'rsssl_secure_cookie', 10, 2 );
    Thread Starter ReactorShop

    (@reactorshop)

    Got it. I was missing the last closing curly brace.

    Thank you for the heads up with the is_ssl() function. I’m switching my website from port 80 to port 443 and back depending if the page displayed requires user input or not (for now I’m doing this in my testing environment). The production server and my testing environment run Apache.

    I can’t change that script because it’s not hosted in my website and as you noticed, that translation website doesn’t support ssl connections. That’s why I’m excluding it from my HTTPS pages.

    Thank you for your help.

    I have an ajax call problem related to insecure urls included in SSL connections too, but not with Buddypress. It might be related:

    a) I use admin_url( ‘admin-ajax.php’ ) to assign the admin-ajax.php file url to my jQuery code. Let’s suppose that I want this url to have HTTPS because the present page/post requires it.

    b) This function uses WordPress’ get_admin_url:

    function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) {
    	$url = get_site_url($blog_id, 'wp-admin/', $scheme); //<<<---- No $path == 'admin-ajax.php'
    
    	if ( $path && is_string( $path ) )
    		$url .= ltrim( $path, '/' );
    
    	return apply_filters( 'admin_url', $url, $path, $blog_id ); <<<----- Here's $path == 'admin-ajax.php'
    }

    Please note that the get_site_url filter doesn’t get ‘admin-ajax.php’ ($path variable) as a parameter. Hooking to ‘admin_url’ provides you with the $path variable.

    c) If we follow the execution inside the get_site_url filter, we see at the bottom where WordPress HTTPS hooks too (the ‘site_url’ hook).

    function get_site_url( $blog_id = null, $path = '', $scheme = null ) {
    	if ( empty( $blog_id ) || !is_multisite() ) {
    		$url = get_option( 'siteurl' );
    	} else {
    		switch_to_blog( $blog_id );
    		$url = get_option( 'siteurl' );
    		restore_current_blog();
    	}
    
    	$url = set_url_scheme( $url, $scheme );
    
    	if ( $path && is_string( $path ) )
    		$url .= '/' . ltrim( $path, '/' );
    
    	return apply_filters( 'site_url', $url, $path, $scheme, $blog_id );
    }

    There’s a $path variable, but its value is ‘wp-admin/’ != ‘admin-ajax.php’.

    d) Here’s where WordPress HTTPS switches HTTPS to HTTP:

    public function site_url( $url, $path, $scheme, $blog_id ) {
    	$force_ssl = apply_filters('force_ssl', null, 0, $url); //<<- $force_ssl is returned false
    
    	if ( $scheme != 'http' && $force_ssl ) {
    		$url = $this->getPlugin()->makeUrlHttps($url);
    	} else if ( !is_null($force_ssl) && !$force_ssl ) {
    		$url = $this->getPlugin()->makeUrlHttp($url); <<-- So, HTTPS is now HTTP.
    	}
    	return $url;
    }

    Why $force_ssl is returned as false? This ‘force_ssl’ hooked filter doesn’t find ‘admin-ajax.php’ inside the $url variable, because of what was explained in b):

    public function secure_admin( $force_ssl, $post_id = 0, $url = '' ) {
    	if ( $url != '' && $this->getPlugin()->isUrlLocal($url) && ( strpos($url, 'wp-admin') !== false || strpos($url, 'wp-login') !== false ) ) {
    		if ( $this->getPlugin()->getSetting('exclusive_https') && !( ( defined('FORCE_SSL_ADMIN') && constant('FORCE_SSL_ADMIN') ) || $this->getPlugin()->getSetting('ssl_admin') ) ) {
    			$force_ssl = false;
    		//TODO When logged in to HTTP and visiting an HTTPS page, admin links will always be forced to HTTPS, even if the user is not logged in via HTTPS. I need to find a way to detect this.
    		} else if ( ( $this->getPlugin()->isSsl() && !$this->getPlugin()->getSetting('exclusive_https') ) || ( ( defined('FORCE_SSL_ADMIN') && constant('FORCE_SSL_ADMIN') ) || $this->getPlugin()->getSetting('ssl_admin') ) ) {
    			$force_ssl = true;
    		}
    		if ( strpos($url, 'admin-ajax.php') !== false ) { //<<--- The check fails here
    			if ( $this->getPlugin()->isSsl() ) {
    				$force_ssl = true;
    			} else {
    				$force_ssl = false; //<<-- So, $force_ssl is set to false
    			}
    		}
    	}
    
    	return $force_ssl;
    }

    And there’s another filter hooked to ‘force_ssl’ that looks for a file, when the url doesn’t include one, as seen on b):

    public function secure_element( $force_ssl, $post_id = 0, $url = '' ) {
    	if ( $url != '' && $this->getPlugin()->isUrlLocal($url) ) {
    		$filename = basename($url); <<---- filename check here
    		foreach( $this->getPlugin()->getFileExtensions() as $extension ) {
    			if ( preg_match('/\.' . $extension . '(\?|$)/', $filename) ) {
    				if ( $this->getPlugin()->isSsl() ) {
    					$force_ssl = true;
    				} else {
    					$force_ssl = false;
    				}
    			}
    		}
    	}
    	return $force_ssl;
    }

    e) After all ‘force_ssl’ hooked filters are applied, we’re returned to d), where $this->getPlugin()->makeUrlHttp($url) is evaluated, switching HTTPS to HTTP.

    In conclusion, ajax requests looking for ‘admin-ajax.php’ should be handled in the ‘admin_url’ hook ( see b) ), instead of ‘site_url’.

    If any additional information is needed to clarify this situation, please don’t hesitate to ask.

    This solution worked for my WordPress multisite installation:

    a) Edit each post or page you need HTTPS for and select “Secure post” in the HTTPS widget located below the “Update” button. Then click “Update”.

    (Don’t do this! -> After doing this, In a new browser I got into my website, and even though I started with HTTP at my home URL, the moment I selected an HTTPS forced page, all the following pages I clicked were forced into HTTPS, even though they weren’t supposed to be)

    b) Go into the specific site child blog dashboard (do not do this in the Network admin HTTPS sidebar menu)

    c) Click the HTTPS side bar menu (or click on it inside the sidebar “Settings” menu)

    d) Click “Force SSL Exclusively”.

    e) Click the “Save Changes” button.

    I hope this helps those with multisite installations.

    Thread Starter ReactorShop

    (@reactorshop)

    The nonce is passed with PLL 1.4dev18 without the need of modifications, so the situation originating this post is solved.

    From the TODO I listed above, in order to translate TML’s custom user links permalinks, which I would suggest to enter them using the default language permalinks, I did this:

    function p4tml_user_links( $user_links ) {
    	foreach( $user_links as $key => $user_link ) {
    		$user_links[$key]['title'] = __( $user_link['title'] );
    		$user_links[$key]['url'] = p4we_translate_post_url( $user_link['url'] );
    	}
    	return $user_links;
    }
    add_filter( 'tml_user_links', 'p4tml_user_links', 11 );

    The p4we_language_conditions_are_met() function indicated inside the p4we_translate_post_url() function, only checks if the current language is different than the default language.

    You have to make sure that the translated custom user link title exists inside the ‘default’ translation domain, or conditionally select a different domain which will contain it, or use pll__ to maintain it inside the Strings Translation admin page.

    As always, thank you very much for your support, Chouby.

    Have a nice weekend!

    Thread Starter ReactorShop

    (@reactorshop)

    Chouby, please, let me congratulate you on this work.

    The situation is solved:

    WP e-Commerce’s add to cart Fancy Notification translated with Polylang

    I started checking yesterday what to do about it. As I said before, jQuery is not easy.

    Regarding the calendar plugin jQuery you showed me, $.ajaxSetup use is not recommended by the jQuery team:

    jQuery.ajaxSetup use not recommended

    I was looking for an alternative when I saw your post.

    Thank you, Chouby.

    Thread Starter ReactorShop

    (@reactorshop)

    I forgot something.

    The last filter in my previous post is hooked like this:

    function p4tml_page_link( $link, $action, $query ) {
    	if( ! empty( $action ) )
    		return p4we_translate_post_url( $link, FALSE, FALSE, $action );
    	else
    		return $link;
    }
    add_filter( 'tml_page_link', 'p4tml_page_link', 10, 3 );

    Sorry

    Thread Starter ReactorShop

    (@reactorshop)

    Don’t worry, Chouby. jQuery is not easy.

    WP e-Commerce’s shopping cart widget currently doesn’t update when using cache plugins.

    A fix it’s on its way, but in the meantime I had to add to my plugin a plain mini shopping cart placed in the side bar and a small jQuery code snippet to update it.

    I hope you do find a way to detect the front end ajax requests. Besides WP e-Commerce, Theme My Login does some requests too, so if you register a new user, the process starts in the correct language but ends asking for the user registration information using the default language because of this. It’s reasonable to think that others plugins would be coded to send translated server responses too.

    Regarding the work I’ve done, it has taken me long because even though it started with interfacing Polylang with WP e-Commerce, in the course of doing this I noticed and had to fix WP e-Commerce behavior not related to translations by using its hooks, provided pull requests to fix its USPS and UPS shipping modules, created shipping modules to rate 2 Mexican shipping companies (Estafeta and Redpack), and worked on a partitioning problem/3D bin packing algorithm to reduce shipping costs by combining shipment packages that fit into a shipping box that meets shipper’s restrictions.

    Regarding PLL, other improvement opportunity I saw in your plugin is that the server redirect query string is not considered when forming a translated URL. I fixed this by hooking to ‘pll_translation_url’, checking and, if necessary, recreating the URL and appending this string to the end. I need that string appended to the URL because WP e-Commerce handles the customer information in “tabs”, which are identified by the server in this string.

    Seeing that you have interacted with Theme My Login before, here’s the code I had to add to my plugin to fix the links translations:

    function p4we_my_login_domain() {
    	global $l10n;
    
    	$locale = get_locale();
    	$mofile = WP_PLUGIN_DIR . '/theme-my-login/language/' . 'theme-my-login-' . $locale . '.mo';
    	if( file_exists( $mofile ) )
    		load_textdomain( 'default', $mofile );
    }
    add_action( 'plugins_loaded', 'p4we_my_login_domain', 9 ); //User links titles are read with a priority of 10 when plugins_loaded actions are applied.
    
    function p4we_tml_user_links( $user_links ) {
    	foreach( $user_links as $key => $user_link ) {
    		$user_links[$key]['title'] = __( $user_link['title'] );
    	}
    	return $user_links;
    }
    add_filter( 'tml_user_links', 'p4we_tml_user_links', 11 ); //Fixes user links titles translations before they're picked up by the theme.
    
    function p4we_tml_title( $title ) {
    	return __( $title );
    }
    add_filter( 'tml_title', 'p4we_tml_title', 11 ); //Fixes TML //Fixes TML titles translations before they're picked up by the theme.

    Thank you, Chouby.

    Thread Starter ReactorShop

    (@reactorshop)

    The issue that I have is that the plugin which is making this request is not created by me (WP e-Commerce), so a pull request as specific as this might not be accepted by their team.

    I will modify the ajax request and maintain it by myself.

    By the way, when you get a chance, please take a look at my website so that you check how far I’ve gone integrating Polylang to WP e-Commerce, Theme My Login and the Customizr theme:

    https://www.ReactorShop.com

    Theme My Login is a little tricky to translate, because it loads its translations MO file really late and on its own ‘theme_my_login’ domain, but if you check the plugin code, in reality it uses the default domain to look for translations.

    I had to merge their MO file with WordPress’ default MO file using the ‘init’ hook in order for its translations to be found.

    I’m far from releasing a Polylang/WP e-commerce plugin, because it currently only takes into account my specific website setup.

    Thank you, Chouby!

    Thread Starter ReactorShop

    (@reactorshop)

    Hi Chouby,

    It was working as I entered it (I’m not only removing a filter from this hook, but replacing it with other that has the same priority and all remaining hooked filters are being applied).

    But I’m considering your recommendation as good (better) practice, so I already tested it and it’s working as you indicated.

    Thank you, Chouby!

    Thread Starter ReactorShop

    (@reactorshop)

    Perfect! This is how it was fixed.

    1. Put the 1.2dev59 parse_query filter into a new plugin, like this:

    function pll_wpsc_parse_query($query) {
    	global $polylang;
    
    	if(isset($polylang->choose_lang)) {
    		$qv = $query->query_vars;
    
    		// allow filtering recent posts and secondary queries by the current language
    		// take care not to break queries for non visible post types such as nav_menu_items
    		// do not filter if lang is set to an empty value
    		if (/*$query->is_home &&*/ !isset($qv['lang']) && (empty($qv['post_type']) || $polylang->model->is_translated_post_type($qv['post_type'])))
    			$query->set('lang', $polylang->curlang->slug);
    
    		// modifies query vars when the language is queried
    		if (!empty($qv['lang'])) {
    			// remove pages query when the language is set unless we do a search
    			if (empty($qv['post_type']) && !$query->is_search)
    				$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 (!$query->is_comment_feed && !$query->is_post_type_archive && !$query->is_date && !$query->is_author && !$query->is_category && !$query->is_tag && !$query->is_tax('post_format'))
    				$query->is_archive = false;
    
    			// unset the is_tax flag for authors pages and post types archives
    			// FIXME Should I do this for other cases?
    			if ($query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search) {
    				$query->is_tax = false;
    				unset($query->queried_object);
    			}
    		}
    
    		// to avoid conflict beetwen taxonomies
    		if (isset($query->tax_query->queries))
    			foreach ($query->tax_query->queries as $tax)
    				if (pll_is_translated_taxonomy($tax['taxonomy']))
    					unset($query->query_vars['lang']);
    	}
    	return $query;
    }
    add_filter('parse_query', 'pll_wpsc_parse_query', 6);

    2. Add another filter in that same plugin, which will be applied with priority 5, to remove PLL’s 1.3.1 parse_query filter before it gets applied:

    function pll_remove_new_parse_query($query) {
    	global $polylang;
    	remove_filter('parse_query', array(&$polylang, 'parse_query'),6);
    	return $query;
    }
    add_filter('parse_query', 'pll_remove_new_parse_query', 5);

    And now, everyone is happy and this situation is solved.

    Thank you, Chouby!

    Thread Starter ReactorShop

    (@reactorshop)

    I’m sorry, my bad. Hit the wrong buttons.

    Regarding what you asked me to do, here’s is what I did:

    I took PLL 1.2dev59 parse_query (my last known good config. I wasn’t aware of PLL 1.2.4 until I received the 1.3 upgrade notification):

    public function parse_query($query) {
    		$qv = $query->query_vars;
    
    		// allow filtering recent posts and secondary queries by the current language
    		// take care not to break queries for non visible post types such as nav_menu_items
    		// do not filter if lang is set to an empty value
    		if (/*$query->is_home &&*/ !isset($qv['lang']) && (empty($qv['post_type']) || $this->model->is_translated_post_type($qv['post_type'])))
    			$query->set('lang', $this->curlang->slug);
    
    		// modifies query vars when the language is queried
    		if (!empty($qv['lang'])) {
    			// remove pages query when the language is set unless we do a search
    			if (empty($qv['post_type']) && !$query->is_search)
    				$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 (!$query->is_comment_feed && !$query->is_post_type_archive && !$query->is_date && !$query->is_author && !$query->is_category && !$query->is_tag && !$query->is_tax('post_format'))
    				$query->is_archive = false;
    
    			// unset the is_tax flag for authors pages and post types archives
    			// FIXME Should I do this for other cases?
    			if ($query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search) {
    				$query->is_tax = false;
    				unset($query->queried_object);
    			}
    		}
    
    		// to avoid conflict beetwen taxonomies
    		if (isset($query->tax_query->queries))
    			foreach ($query->tax_query->queries as $tax)
    				if (pll_is_translated_taxonomy($tax['taxonomy']))
    					unset($query->query_vars['lang']);
    	}

    and used it to replace PLL 1.3.1

    public function parse_query($query) {
    		$qv = $query->query_vars;
    
    		// to avoid conflict beetwen taxonomies
    		// FIXME generalize post format like taxonomies (untranslated but filtered)
    		$has_tax = false;
    		if (isset($query->tax_query->queries))
    			foreach ($query->tax_query->queries as $tax)
    				if ('post_format' != $tax['taxonomy'])
    					$has_tax = true;
    
    		// allow filtering recent posts and secondary queries by the current language
    		// take care not to break queries for non visible post types such as nav_menu_items
    		// do not filter if lang is set to an empty value
    		// do not filter single page and translated taxonomies to avoid conflicts
    		if (!empty($this->curlang) && !isset($qv['lang']) && !$has_tax && empty($qv['page_id']) && empty($qv['pagename']) && (empty($qv['post_type']) || $this->model->is_translated_post_type($qv['post_type']))) {
    			$this->choose_lang->set_lang_query_var($query, $this->curlang);
    		}
    
    		// modifies query vars when the language is queried
    		if (!empty($qv['lang'])) {
    			// remove pages query when the language is set unless we do a search
    			if (empty($qv['post_type']) && !$query->is_search)
    				$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 (!$query->is_comment_feed && !$query->is_post_type_archive && !$query->is_date && !$query->is_author && !$query->is_category && !$query->is_tag && !$query->is_tax('post_format'))
    				$query->is_archive = false;
    
    			// unset the is_tax flag for authors pages and post types archives
    			// FIXME Should I do this for other cases?
    			if ($query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search) {
    				$query->is_tax = false;
    				unset($query->queried_object);
    			}
    		}
    	}

    And it’s working now.

    I’m not looking for you to switch to an approach that may destabilize PLL. Maybe another approach would be to add a filter hook so that these differences may be dealt with another plugin?

Viewing 15 replies - 1 through 15 (of 47 total)