xiligroup dev

Forum Replies Created

Visualisation du message 10 (221 sur 230, 527 au total)
  • Auteur
    Articles
  • in reply to: The date, simply put… #2929

    xiligroup dev
    Keymaster

    Have you examine the demo child theme v1.1 ?

    http://multilingual.wpmu.xilione.com/308/episode-n°2-creation-dun-site-multilingue-avec-xili-language/

    To have the right date, you must use dating as in twentyten and don’t forget to translate date format in .mo (via xili-dictionary or poedit)…

    (If you are easy in php, you can also see the source code to discover the methods used by plugin to translate).

    Good work

    in reply to: affichage contenu d'une page dans article #2928

    xiligroup dev
    Keymaster

    Good observation:

    Today, filter ‘the_content’ is used for contents… can you verify that the cited shortcodes used are working from a plugin using canonical method…


    xiligroup dev
    Keymaster

    Cet article (rédigé en anglais comme ses codes source en exemple) décrit une extension

    • qui utilise l’ensemble des bibliothèques xmlrpc maintenant disponibles dans WP depuis la version 3.1.x
    • qui permet de publier un clone de l’article originel sur un autre site WP…

    C’est un exemple assez simple destiné aux webmestres ayant des connaissances en php et en source WP mais qui contient quelques astuces…

    in reply to: Cloud with only one font size ? #2575

    xiligroup dev
    Keymaster

    Question :

    I would like to ask for assistance regarding tags. I would like my tags to be of one size vs. having a bigger font size on tags with more content. is this possible?

    Answer :

    – If you use widget for the cloud : it is easy, largest and smallest size must be set as the same.

    – if you use template tag : the param are the same as the current cloud plus those added by xili-tidy-tags see readme and codex: http://codex.wordpress.org/Function_Reference/wp_tag_cloud

    ;-)


    xiligroup dev
    Keymaster

    To begin…
    This post is published to relate recent experiments with xmlrpc protocol now fully available in WordPress (version >3.1) source code (server and client like desktop clients listed in codex).
    Researchs on other tests on web were not fully successful because some posts are incomplete or too old according recent adds in WP code and specially about processes to sent media and attach it to remote post.

    The context

    One master (local) WP site and a target (remote) WP site where to send a post (or a part of this) when published locally.

    Technical context

    • WordPress 3.1.3 on both sites and error.log available on both servers…
    • One website named local containing a plugin working as a xmlrpc client : the purpose of this article.
    • Another target site named remote accepting xmlrpc input (and login/pass with editing capabilities).
    • TIPS : to test use the error_log ( ‘message’) php function (and not echo or print_r) !

    The testing process

    We will create a small plugin without admin UI. When a local post is published, a remote post is created through xmlrpc with his attachment copied to target site. On local post a custom field is added and contains the ID of the post on the remote site.

    This process is simple and can fully improved with, by example, cron tasks with sub-selection.

    By traveling inside the source code, you will discover some tips and tricks.

    < ?php
    /*
    Plugin Name: xili-xmlrpc
    Plugin URI: https://dev.xiligroup.com/
    Description: xili-xmlrpc is a tool to post from one site to another.
    Author: dev.xiligroup.com - MS
    Version: 0.5.0
    Author URI: https://dev.xiligroup.com
    */
    
    
    define('XILIXMLRPC_VER','0.5.0'); /* used in admin UI */
    
    include_once(ABSPATH . WPINC . '/class-IXR.php'); /* not included in wp-settings */
    include_once(ABSPATH . WPINC . '/class-wp-http-ixr-client.php'); /* not included in wp-settings */
    
    /**
     * Class without admin UI
     *
     */
    class xili_xmlrpc {
    	
    	var $test_url = 'http://subdomain.domain.tld/xmlrpc.php';
    	var $remote_login = 'adlog';
    	var $remote_passwd = 'thepasswd';
    	var $remote_server = 'remoteslug'; // shortname used in custom field
    	
    	var $currentrequest = null;
    	var $currentdate = true; // option to update target/remote date with now !
    	
    	/**
    	 * hook when post is published - minimum for test
    	 *
    	 */
    	function xili_xmlrpc () {
    		add_action( 'publish_post', array( &$this,'send_post_to') );
    	}
    	
    

    The start of the source code is easy readable.
    The first function is the hook when a post is published and now the function fired :

    	/**
    	 * function fired when a post is published
    	 *
    	 * @param post ID
    	 *
    	 */
    	function send_post_to ( $post_id ) {
    		 
    		$to_post_id = get_post_meta ( $post_id , $this->remote_server, true );
    		
    		$this -> create_remote_categories_if ( $post_id );
    		
    		if ( $to_post_id > 0 ) { // mise à jour
    			$remote_id = $this->edit_post_to ( $post_id ); /* not used now */
    			
    		} else {
    			$guids = $this->send_attachments ( $post_id );
    			$remote_id = $this->new_post_to ( $post_id ) ;
    			if ( $remote_id ) {
    			 		update_post_meta ( $post_id , $this->remote_server, $this->currentrequest ) ;
    			}
    			// update content after changing attachment url
    			if ( $guids ) {	
    				//error_log ( '- array -');
    				$remote_id = $this->edit_post_to ( $post_id, $guids ); // create attachments link to parent in remote
    			}
    			// get attached medias
    			$medias = $this->get_attached_medias ( $post_id , 'image') ;
    			$remote_images = array();
    			if ( $medias ) { //print_r( $medias );
    				// create remote links of medias images
    				foreach ( $medias as $oneimage ) {
    					$remote_images[] = array ( 
    					'link' => $oneimage['link'], 
    					'file' => $oneimage['metadata']['file'], 
    					'thumbnail' => array ( 'link' => $oneimage['thumbnail'], 
    											'file' => $oneimage['metadata']['sizes']['thumbnail']['file'] ), 
    					'medium' => array ('file' => $oneimage['metadata']['sizes']['medium']['file'] ), 
    					'post-thumbnail' => array('file' => $oneimage['metadata']['sizes']['post-thumbnail']['file'] )   
    					);
    				}
    				// synchronize 
    				$search = array(); //local remaining link
    				$replace = array();
    				foreach ( $guids as $one_id => $one_attachment ) {
    					
    					foreach ( $remote_images as $oneimage ) {
    						if ( $one_attachment['remote'] == $oneimage['link'] ) { //error_log ( '----> '.$oneimage['link'] );
    							$remote_folder = str_replace ($oneimage['thumbnail']['file'], "", $oneimage['thumbnail']['link'] );
    							
    							$replace[] = $remote_folder.$oneimage['medium']['file']; //error_log ( '---med replace-> '.$remote_folder.$oneimage['medium']['file'] );
    							$src_m = wp_get_attachment_image_src($one_id, 'medium');
    							$search[] = $src_m[0]; // error_log ( '---med search-> '.$src_m[0] );
    							$replace[] = $oneimage['thumbnail']['link'];
    							$src = wp_get_attachment_image_src($one_id, 'thumbnail');  
    							$search[] = $src[0];
    						}
    					}	
    				}
    				if ( $replace ) {	
    				    // error_log ( '- array replace -');
    					$remote_id = $this->edit_post_to ( $post_id, $guids, array ('search' => $search, 'replace' => $replace) );
    				}
    			}
    			
    		}
    		// send the attachments
    		
    	}
    

    In this main function, the step by step tips when creating a new remote one is :
    Send the attachment BEFORE the new post containing link in content to attachment. (if the content don't contain media links, attachments (child to parent) are impossible.
    Create the new post,
    Save the remote ID inside custom field of the local post,
    Attach medias links in the content of the remote post.
    After doing a fitting table of links inside contents (local and remote): updating remote content of post.

    ...

    Other functions used by the main presented above :

    A new post is created on remote with datas from local one (the links (src or...) inside content are not yet updated and link to local wp site:

    	/**
    	 * Create a new remote post from a local one
    	 *
    	 * @param local post ID
    	 *
    	 */
    	function new_post_to ( $post_id ) {
    		
    		$rpc = new WP_HTTP_IXR_Client( $this->test_url );
    		$original_post = & get_post ($id = $post_id);
    		
    		$post = array(
    		    'title' => $original_post->post_title,
    		    'categories' => wp_get_object_terms($post_id, 'category', array('fields'=>'names') ),
    		    'mt_keywords' => wp_get_object_terms($post_id, 'post_tag', array('fields'=>'names') ),
    		    'description' => $original_post->post_content,
    		    'wp_slug' => $original_post->post_name
    		);
    		
    		$params = array(
    		    0,
    		    $this->remote_login,
    		    $this->remote_passwd,
    		    $post,
    		    'publish'
    		);
    		
    		$status = $rpc->query(
    			'metaWeblog.newPost',
    			$params	
    		);
    		
    		$this->currentrequest = $rpc->getResponse(); 
    		return $status; // ID or false
    	}
    	

    Edit and update the remote post according optional 2nd and 3rd parameters:

    /**
    	 * edit the local post clone content before to edit the remote one
    	 *
    	 * @param local ID
    	 * @param guids of local images or attachments
    	 * @param array of local - remote src or url inside content to proceed search and replace
    	 */
    	function edit_post_to ( $post_id , $guids = array(), $search_replace = array() ) {
    		
    		$rpc = new WP_HTTP_IXR_Client( $this->test_url );
    		$original_post = & get_post ($id = $post_id);
    		
    		if ( $guids ) {
    			$post_content = $original_post->post_content ;
    			foreach ( $guids as $one_id => $one ) {
    				$post_content = str_replace ( $one['local'], $one['remote'], $post_content );
    			}
    			if ( isset( $search_replace ['search']) ) 
    				$post_content = str_replace ($search_replace ['search'], $search_replace ['replace'], $post_content);
    	
    		} else {
    			$post_content = $original_post->post_content ;
    		}
    		
    		$post = array(
    		    'title' => $original_post->post_title,
    		    'categories' => wp_get_object_terms($post_id, 'category', array('fields'=>'names') ),
    		    'mt_keywords' => wp_get_object_terms($post_id, 'post_tag', array('fields'=>'names') ),
    		    'description' => $post_content,
    		    'wp_slug' => $original_post->post_name
    		);
    		
    		if ( $this->currentdate ) {
    			$newDate = new IXR_Date(strtotime('now'));
    			$post['dateCreated'] =  $newDate;
    		}
    		
    		$to_post_id = get_post_meta ( $post_id , $this->remote_server, true );
    		
    		if ( $to_post_id > 0 ) {
    			$params = array(
    		    	$to_post_id,
    		    	$this->remote_login,
    		    	$this->remote_passwd,
    		    	$post,
    		    	'publish'
    			);
    		
    			$status = $rpc->query(
    				'metaWeblog.editPost',
    				$params	
    			);
    		
    		/*
    		if(!$status) {
    		    echo 'Error [' . $rpc->getErrorCode() . ']: ' . $rpc->getErrorMessage();
    		    exit();
    		}
    		*/
    			$request = $rpc->getResponse(); 
    		
    			return $status; // ID or false
    		
    		} else {
    			
    			return false ;
    		}
    	}

    This function must be launched BEFORE a new post containing attachment is created.
    Why ?
    Because the xmlrpc server process analyze the content of the post (links inside) and yet don't use the parent/child way.

    /** 
    	 * create a remote attachment
    	 * use metaWeblog.newMediaObject
    	 */
    	function send_attachments ( $post_id ) {
    		
    		// get_attachments
    		$attachments = & get_children( array(
    			'post_parent' => $post_id,
        		'post_type'   => 'attachment',
    			) 
    		);
    		if ( $attachments != array() ) {
    		
    			$rpc = new WP_HTTP_IXR_Client( $this->test_url );
    			$to_post_id = get_post_meta ( $post_id , $this->remote_server, true );
    			// 
    			$guids = array();
    			foreach ( $attachments as $attachment_id => $attachment ) {
    				
    				
    				
    				$params = array(
    						0,
    				    	$this->remote_login,
    				    	$this->remote_passwd,
    				    	array( 
    				    		'name' => basename( get_attached_file( $attachment_id ) ), //$attachment->post_title,
    							'type' => $attachment->post_mime_type,
    							'bits' => new IXR_Base64 ( file_get_contents ( get_attached_file( $attachment_id ) ) )  // get_attached_file( $attachment_id)
    						)
    					);
    		
    				//error_log ('***'.$params[3]['bits']->getXml() );
    				$status = $rpc->query(
    						'metaWeblog.newMediaObject',
    						$params	
    					);
    				if(!$status) {
    		    			error_log ( 'Error [' . $rpc->getErrorCode() . ']: ' . $rpc->getErrorMessage() );
    					}	
    				if ( $status ) {
    					
    					$request = $rpc->getResponse(); //error_log( print_r( $request ) );
    					$guids[$attachment_id] = array( 'local' => $attachment->guid, 'remote' => $request['url'] );
    						error_log ( $request['url'] );
    
    					
    					/*
    					
    					*/
    				}
    	
    			}
    			
    			return $guids;
    		}	
    			
    		return array();	
    	}
    

    Used to collect remote infos about attachments sent to target WP site.

    	/**
    	 * get attached medias
    	 *
    	 *
    	 *
    	 */
    	function get_attached_medias ( $post_id = 0, $mime_type = '' ) {
    		
    		$rpc = new WP_HTTP_IXR_Client( $this->test_url );
    		$remote_post_id = get_post_meta ( $post_id , $this->remote_server, true );
    		
    		// get recent
    		$params = array(
    			0,
    	    	$this->remote_login,
    	    	$this->remote_passwd,
    	    	array(
    	    	'mime_type' => $mime_type,
    	    	'parent_id' => $remote_post_id
    		)
    		);
    		
    		$status = $rpc->query(
    			'wp.getMediaLibrary',
    			$params	
    		);
    		if ( $status ) {
    			$requestattach = $rpc->getResponse(); //print_r($requestattach);
    			
    			return $requestattach ;
    			//$guids[$attachment_id] = array( 'local' => $attachment->guid, 'remote' => $requestattach[0]['link'] );
    			error_log ( $requestattach[0]['link'] );
    		}
    		if(!$status) {
       			error_log ( 'Error [' . $rpc->getErrorCode() . ']: ' . $rpc->getErrorMessage() );
    		}
    		return array();
    	}
    	

    Before ending the class of the plugin, a function that create categories on remote site if they not exists. Here in the example, we copy without choice the categories. but on a final release or for the special way of publishing, it is forecast to sub-select or to use a translation table.

    	/** 
    	 * If remote category don't exist, create it
    	 *
    	 */
    	function create_remote_categories_if ( $post_id ) {
    		
    		$thecats = wp_get_object_terms($post_id, 'category', array('fields'=>'names') ) ;
    		
    		$rpc = new WP_HTTP_IXR_Client( $this->test_url );
    		
    		$params = array(
    				0,
    		    	$this->remote_login,
    		    	$this->remote_passwd
    			);
    		
    		$status = $rpc->query(
    				'metaWeblog.getCategories',
    				$params	
    			);
    		if ( $status ) {
    			
    			$request = $rpc->getResponse();
    			
    			//print_r( $request );
    			
    			$remotecatsnames = array();
    			foreach ( $request as $remotecategory ) {
    				
    				$remotecatsnames[] =  $remotecategory ['categoryName'] ;
    			}
    			
    			foreach ( $thecats as $onecatname ) { // error_log ( $onecatname ) ;
    			
    				if ( !in_array ( $onecatname,  $remotecatsnames ) ) { //error_log ( $onecatname ) ;
    					$params = array(
    						0,
    		    			$this->remote_login,
    		    			$this->remote_passwd,
    		    			array("name" => $onecatname)
    					);
    		
    					$status = $rpc->query(
    						'wp.newCategory',
    						$params	
    					);
    					if(!$status) {
    		    			error_log ( 'Error [' . $rpc->getErrorCode() . ']: ' . $rpc->getErrorMessage() );
    					}
    					if ( $status )  error_log ( $onecatname ) ;
    					
    				}
    			}
    		}
    	}
    	
    } // end class
    
    /**
     * plugin class instantiation
     *
     */
    $xili_xmlrpc = new xili_xmlrpc ();
    
    
    

    When the plugin is activated, and when a post is published in the local WP containing the plugin with right parameters, a post is created on the remote WP.

    And for annexe, a function to get a remote post not yet used because, in the test, we only create a new post but don't modify it after the first creating process including attachements (if exists).

    	/**
    	 * get_post from remote with his remote ID
    	 *
    	 */
    	function get_post_from ( $post_id ) { // 
    		
    		$rpc = new WP_HTTP_IXR_Client( $this->test_url );
    		
    		$params = array(
    		    $post_id,
    		    $this->remote_login,
    		    $this->remote_passwd,
    		);
    		
    		$status = $rpc->query(
    			'metaWeblog.getPost',
    			$params		
    		);
    		
    		if(!$status) {
    		    //echo 'Error [' . $rpc->getErrorCode() . ']: ' . $rpc->getErrorMessage();
    		    //exit();
    		    return false;
    		} else {
    			$request = $rpc->getResponse();
    			return $request ;
    		}
    		//print_r($request);
    	}

    Infos for readers :
    Around one day to go deep in xmlrpc processes and functions in WP Source Code.
    Around two hours to write this post.

    Enjoy it !

    Michel of dev.xiligroup team

    in reply to: Shortcode: xili-tidy-tags #2073

    xiligroup dev
    Keymaster

    Since version 1.0 of xili-tidy-tags plugin, this shortcode insertable in content is based on template tag named xili_tidy_tag_cloud(). It displays a list inside the content of a post.

    Inside the content of your post (as shown here at end)

    [xili-tidy-tags params="tagsgroup=trademark&largest=10&smallest=10" glue=" | "]

    [xili-tidy-tags params="tagsgroup=trademark&largest=10&smallest=10" glue=" | "]
    In this cas, the group of tags named ‘trademark’ will be display inside a paragraph of a post. The params are defined as in `xili_tidy_tag_cloud()` and as in `wp_tag_cloud()`. The glue is chars inserted between the tags (if omitted default is a space).

    in reply to: Widget : Languages list #2069

    xiligroup dev
    Keymaster

    Display the list of available languages in theme (sidebar).
    This widget is based on the template tag named xili_language_list()
    [caption id="attachment_2172" align="aligncenter" width="266" caption="widget language list (in fr)"]widget language list (in fr)[/caption]

    Features:

    Type of lists
    Formatting tags

    Also contains conditional feature when to display.

    in reply to: Template tag : xiliml_the_other_posts #2065

    xiligroup dev
    Keymaster

    in loop display the link of other posts defined as in other languages (example under title or after end content)

    Example of use in theme main loop

    type of file : single.php or content-single.php (in twentyeleven-xili child theme)

    Params: current post ID, link title term.

    in reply to: Widget : Tidy tags cloud #2063

    xiligroup dev
    Keymaster

    Display in tidy way group(s) of tags

    [caption id="attachment_2180" align="aligncenter" width="269" caption="widget to display tag cloud "]widget  to display tag cloud [/caption]

    Parameters:

    A second group can be merged to the first.
    Sizes min and max, and number of tags can be set.
    Sort by and order,
    and as cloud or list display mode

    Here is this example: only tags belonging to group named « Trademark » will be shown as below

    [caption id="attachment_2182" align="aligncenter" width="290" caption="tags of group trademarks"]tags of group trademarks[/caption]


    xiligroup dev
    Keymaster

    La mise à jour de l’extension 0.9.7 pour diaporama avec le javascript floom concerne :

    • la prise en compte de la façon sont créées la colonne post_name lors du téléchargement des images (depuis la 3.0, le champ TIFF (image description) est utilisée. Cela peut donc influencer la sous-sélection via le champ personnalisé ‘floom_subname’. Il est donc possible dans les réglages de choisir la colonne où le LIKE de la requête fera effet.
    • Le code source est revu en mode OOP. (Object Oriented Programming)

    Utilisez le forum pour relater expériences ou questions.

Visualisation du message 10 (221 sur 230, 527 au total)