This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

This topic contains 4 replies, has 2 voices.

Last updated by epa-villa-arsonE 1 month, 3 weeks ago.

Assigned support staff: Bigul.

Author Posts
August 17, 2019 at 4:03 am #4409383

epa-villa-arsonE

Hello,
WPML don't support custom post status, at least not entirely.
We have a custom post status called "archived".
On single post set to this status, icl_get_languages() method returns null.
All our posts set to this status are translated.
So I came with a solution : see code below

- I can get the translated post and the original post from this SQL queries
- Has WPML is filtering post ID's when "WPML > Languages > Make themes work multilingual > Adjust IDs for multilingual functionality" is on, the result is I can't get the permalinks of the translations.

My question is : how to bypass ID's filtering just for this method. I don't wan't to disable "Adjust IDs for multilingual functionality" globally.

Thank you for your time.

/**
* WPML Language List Selector
*/ 
public static function getLanguagesMenu(){
	$html = '';
	if ( function_exists('icl_object_id') ) {
	    $languages = self::wpmlCustomPostStatus( icl_get_languages('skip_missing=Y&orderby=custom') ) ;
	    if(!empty($languages)){
	        foreach($languages as $l){
	        	$class = $l['active'] ?? 'active';
	                $html .= '<li class="language-list-element menu-item menu-item-type-post_type '.$class.' '.strtolower($l['language_code']).'"><a href="'.$l['url'].'" >' . ucfirst(strtolower($l['language_code'])) . '</a></li>'; 
	        }
	        
    	}
	}
	return $html;
}



/**
* Get WPML Languages For Archived Post Status
*/
private static function wpmlCustomPostStatus($languages) {
	if(get_post_status() == 'archived' && empty($languages) ){
	    
	    global $wpdb;
	    
	  $transGroupID = $wpdb->get_var( $wpdb->prepare( "SELECT trid FROM wp_icl_translations WHERE element_id= %d AND element_type LIKE 'post_post'", get_the_id() ) );
	    
	    $langCode = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NOT NULL",$transGroupID) );
	    $langID = $wpdb->get_var($wpdb->prepare("SELECT element_id FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NOT NULL",$transGroupID) );
	    
	    $originalCode = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NULL",$transGroupID) );
	    $originalID = $wpdb->get_var($wpdb->prepare("SELECT element_id FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NULL",$transGroupID) );
	    
	    $translations = is_array($langID) && is_array($langCode) ? array_combine($langCode,$langID) : array($langCode => $langID);
	    $all = array_merge($translations,array($originalCode => $originalID));
	    
	    /**
	    * WPML Filters permalinks 
	    * Disable Option : WPML > Languages > Make themes work multilingual > Adjust IDs for multilingual functionality
	    * To Make It Work!
	    */
	    //print_r(get_post_permalink($langID));
        
        foreach($translations as $lang => $id){
            $languages[$lang] = array( 
            	'language_code' => $lang,
            	'url' => get_post_permalink($id),
            	'active' => $id == get_the_ID() ? 1 : 0 
            );
        }

    }

    return $languages;
}
August 17, 2019 at 6:20 pm #4410697

Bigul
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Hello,

Welcome to the WPML support forum. I will do my best to help you to resolve these issues. Please let me know the following details for tracking the issue.

a) When you are calling the function(codes) shared in the first thread

b) Please share with me the exact steps to reproduce the issue on your site

--
Thanks!

Bigul

August 20, 2019 at 2:18 am #4419901

epa-villa-arsonE

Hello,
Thank you for the follow-up. These methods are called on each page the post status is "archived".
I put my methods in a plugin. You have to create a custom post status called "archived" (or change line 56 in code below) and a menu called "main-menu", activate the plugin and then switch on and off "WPML > Languages > Make themes work multilingual > Adjust IDs for multilingual functionality" to see the bug. On the front, on single post pages with archived status:
- language links are set to original post when on.
- Language links are corrects when off.

<?php
/**
 * @package WPML Custom Post Status
 */
/*
Plugin Name: WPML Custom Post Status
Plugin URI: <em><u>hidden link</u></em>
Description: WPML Handle Custom Post Status
Version: 1.0
Author: Afterglow Web Agency
Author URI: <em><u>hidden link</u></em>
Text Domain: wpmlcps
License: GPLv2
*/

if( !class_exists('WpmlCps') ) {

    class WpmlCps {


    	public function __construct() {
    		add_filter( 'wp_nav_menu_items',array($this,'addLangSelector'), 10, 2);
    	}



    	/**
		* Menu Concat Language List Selector
		*/ 
    	public function addLangSelector($items,$args) {
		    return $args->theme_location == 'main-menu' ? $items .= $this->getLanguagesMenu() : $items;
		}



		/**
		* WPML Language List Selector
		*/ 
		private function getLanguagesMenu(){
			$html = '';
			if ( function_exists('icl_object_id') ) {
			    $languages = $this->wpmlCustomPostStatus(icl_get_languages('skip_missing=Y&orderby=custom')) ;
			    if(!empty($languages)){
			        foreach($languages as $l){
			        	$class = $l['active'] ?? 'active';
			                $html .= '<li class="language-list-element menu-item menu-item-type-post_type '.$class.' '.strtolower($l['language_code']).'"><a href="'.$l['url'].'" >' . ucfirst(strtolower($l['language_code'])) . '</a></li>'; 
			        }
			        
		    	}
			}
			return $html;
		}


		private function wpmlCustomPostStatus($languages) {
			if(get_post_status() == 'archived' && empty($languages) ){
			    
			    global $wpdb;

			    $transGroupID = $wpdb->get_var( $wpdb->prepare( "SELECT trid FROM wp_icl_translations WHERE element_id= %d AND element_type LIKE 'post_post'", get_the_id() ) );
         
		        $langCode = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NOT NULL",$transGroupID) );
		        $langID = $wpdb->get_var($wpdb->prepare("SELECT element_id FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NOT NULL",$transGroupID) );
		         
		        $originalCode = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NULL",$transGroupID) );
		        $originalID = $wpdb->get_var($wpdb->prepare("SELECT element_id FROM wp_icl_translations WHERE trid= %d AND element_type LIKE 'post_post' AND source_language_code IS NULL",$transGroupID) );
		         
		        $translations = is_array($langID) && is_array($langCode) ? array_combine($langCode,$langID) : array($langCode => $langID);
		        $all = array_merge($translations,array($originalCode => $originalID));
         
		       
		        foreach($all as $lang => $id){
		            $languages[$lang] = array( 
		            	'language_code' => $lang,
		            	'url' => get_post_permalink($id),
		            	'active' => $id == get_the_ID() ? 1 : 0 
		            );
		        }
				
		    }

		    return $languages;
		}


	}//END CLASS

	new WpmlCps;

}//END IF CLASS EXISTS

August 20, 2019 at 4:51 pm #4425501

Bigul
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Hello,

Thank you for the updates. But I am not able to reproduce the issue exactly in my test installation.

Therefore I have created a test site in our Sandbox server. It is a fresh installation. Please visit the following URL and try to reproduce the issue. It will help us a lot and we can directly forward it to our developers for further debugging.

hidden link

Also please let me know the exact steps to reproduce the issue on the test site.

--
Thanks!

Bigul

August 21, 2019 at 11:57 pm #4435343

epa-villa-arsonE

Ok, I could make it work with a plugin called Edit Flow and by modifying it a little (just one parameter). Looking at the code in plugins/edit-flow/modules/custom-status/custom-status.php there is some fixes for Worpdress core to correctly handle custom post status.
I will extract what I need and build my plugin.
Thank you for you follow-up.
Have a great day.