Calling XmlRpc of WordPress with Zend Framework (Zend_XmlRpc_Client) and adding the default thumbnail to a post

This code is in 2 parts

First part, we download an image somewhere using Zend_Http_Client

Second part, we use xmlrpc to upload the image into wordpress as a media and to create a post using this media as featured image or default image of main thumbnail, whatever the name is

Let’s have a look at the first part:
Downloading an image with Zend_Http_Client
this is quite simple

				require_once 'Zend/Http/Client.php';
				$config=array(
					'adapter'=>'Zend_Http_Client_Adapter_Curl'
				);
				$Zend_Http_Client = new Zend_Http_Client($imageUrl,$config);
				try{
					$result = $Zend_Http_Client->request('GET');
				}catch(Exception $e){
					print_r($e);
				}
				$data = $result->getBody();
				//file_put_contents('/tmp/test.jpg',$data); // this is just to test the image if you are unsure

second part, storing the image in wordpress and creating a post with custom field: _thumbnail_id set to this image

To store a media object we will use the metaWeblog.newMediaObject XmlRpc method

				require_once 'Zend/XmlRpc/Client.php';
				require_once 'Zend/XmlRpc/Value/Base64.php';
				require_once 'Zend/XmlRpc/Value/Struct.php';
				require_once 'Zend/XmlRpc/Value/Array.php';
				$xmlRpcClient = new Zend_XmlRpc_Client('http://www.example.com/myblog/xmlrpc.php');
				try{
					$thumbnail = $xmlRpcClient->call(
						'metaWeblog.newMediaObject',
						array(0,
							'login',
							'pass',
							array(
								'name'=>'test.jpg',
								'type'=>'image/jpeg',
								'bits'=>new Zend_XmlRpc_Value_Base64($data),
							)
						)
					);
// ...

in the thumbnail object we don’t get the id… because it’s not possible to get the id unless you hack wordpress

WP file: wp-include/class-wp-xml-rpc.php

method: function mw_newMediaObject($args) {

modification: add the id in the return:

return apply_filters(
	'wp_handle_upload',
	array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type )
	, 'upload'
	);

by:

return apply_filters(
	'wp_handle_upload',
	array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type, 'id'=>$id )
	, 'upload'
	);
// ...
		$struct = new Zend_XmlRpc_Value_Struct(
					array('key'=>'_thumbnail_id', 'value'=>$thumbnail['id'])
				);
		$result = $xmlRpcClient->call(
			'metaWeblog.newPost',
			array(0,
			'login',
			'pass',
			array(
				'post_type'=>'post',
				'title'=>'New article with thumb',
				'description'=>'Article text',
				'custom_fields'=>array($struct),
			),
			false)
		);
	}catch(Exception $e){
		print_r($e);
	}

Of course, this won’t work… because no one is allowed to access private custom_fields such as _thumbnail_id …

A second WP hack is necessary here:

file: wp-includes/meta.php
function: is_protected_meta

add an exception for _thumbnail_id

function is_protected_meta( $meta_key, $meta_type = null ) {
        if($meta_key == '_thumbnail_id'){
                $protected=false;
        }else{
                $protected = (  '_' == $meta_key[0] );
        }
        return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
}

Without a nice documentation that was the best I could do in few time.

Another approach could be to create a new XmlRpc method, which do both in once avoiding the weakness of reusing an internal id in a second call, but still XmlRpc use add_meta which is a really ugly way to add meta in a post as everything has to be put in $_POST …

If anyone has a better approach (using xmlrpc) feel free to submit the suggestion.

A third approach could be to write a plugin… that’s next step

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*