Remote Control Wordpress through XMLRPC! Sounds good?;) : 5ubliminal's TellinYa

<a href="http://www.tellinya.com/art2/174/">Remote Control Wordpress through XMLRPC! Sounds good?;) : 5ubliminal's TellinYa</a>
Must Reads: Web Scraping | Link Farming | Code Snippets | SEO Freeware
Reveal More!
14.05.2008 I updated this class adding a new post function metaWeblog compatible provided by Maximus Marius from seo 4you. I added a few tweaks to it, tested it and it works. You can now enjoy tags support. I also added another fix mentioned by netizen. All fixes are commented and credited in the source code.
Thanks guyz!
I really do not like WordPress!

No matter what I need I code it myself. So I don't pay attention to pre-made blogs. But I thought a bit and tried WordPress. I still don't like it but I like the way you can play with it. Especially the automatition part implemented in XMLRPC. After looking into Wordpress a bit to implement the Pingback function I decided to go deeper.

I sat down and took a better look at the source file and the XMLRPC functions. Then implemented a 99% functional PHP Class to handle WordPress remotely using the provided APIs. I tested it and it works. Actually I did this with on single dirty thought in my mind: Blogfarms!

Possibilities are limitless! … any1 can be a farmer

You can do anything with this class. You can put 100 blogs on steroids and post to them automatically with links to the posts of others. If you also send a pingback you might get a free comment that can do a lot for you!

You can even post machine generated content to them with links and so on. It's your imagination that needs to work from here on and of course … your coding skills!

There's a catch!

I want you to share with me the uses you find for this class. It's a pre-condition to using it. The comment form is below. And Pssst … do notice the Teddy Bear on the right. If you hit the jackpot any donations will be appreciated. And remember to use the comment form below and let me know how it performs.

Get the script here:


Click the box to get the PHP WordPress Auto-Posting Script!

And how to use it … live samples:

<?
$wp 
= new eWordpressApi("http://www.blog.com/xmlrpc.php","username","password");
$title "Post title";
$text "Some post text";
$category = array(1,2); // Assuming you have categories with IDs: 1,2
$postID $wp->newPost($title,$text,$category);
if(
is_array($postID)) echo "Die, damn bug!";
?>

Let's disect the script a bit.

The script is built using the internal XMLRPC functions of PHP. It's required to have the module enabled. The script relies on the WordPress XMLRPC API which is a soup made of Blogger API, MovableType API, WordPress API and one more. I only used the first three.

It lacks the newPage function which is not really needed and I did not implement it … yet. Still post handling works perfectly as much as I tested it. If you find a bug yell! I'll look into it.

If should work with blogger.com but I never tested it. Only WordPress testing was done. So … hit me back if it works on Blogger. Remeber, on Blogger you need the APIid in the cunstructor changed to whatever you have.

And the 'Official Documentation':

Below you will find each function of the WordPress automatition class with it's informations. I should be easy to digest by any average coder. Don't ask me where to use it. Figure it out yourself:) And lemme know.

<?
function __construct($rpc$user$pass){
/* ---------------------------------------------------------------
For cunstruction use your username, password and URL of the XMLRPC
server : http://www.blog.com/xmlrpc.php . Check out tutorial on page
http://www.tellinya.com/art2/173/ for an autodiscovery function.
--------------------------------------------------------------- */
}

function 
eWordpressApi($rpc$user$pass){
/* Dummy constructor for older PHP (before 5) */
}

function 
doRpcRequest($url,$method,$params,$returnbool=0){
/* ---------------------------------------------------------------
Internal function that sends the request to the XMLRPC server.
To use a different XMLRPC implementation that the PHP one this
is where you have to play around!
--------------------------------------------------------------- */
}

function 
xml2Post($postXml){
/* ---------------------------------------------------------------
Internal function that convert XML representation of a Wordpress
post to a PHP array.
--------------------------------------------------------------- */
}

function 
xml2Page($postXml){
/* ---------------------------------------------------------------
Internal function that convert XML representation of a Wordpress
pager (like the About page) to a PHP array.
--------------------------------------------------------------- */
}

function 
post2Xml($title$text$categories){
/* ---------------------------------------------------------------
Internal function that converts a PHP array to XML representation
of a Wordpress post.
--------------------------------------------------------------- */
}

function 
getPost($postID,$mtFull=false){
/* ---------------------------------------------------------------
This function will retrieve a post from the blog. You need the POST
ID and the options $mtFull asks the script to use MovableType API
for extended informations compared to the Blogger API short version.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
getPosts($postIDs,$mtFull=false){
/* ---------------------------------------------------------------
Helper function that does exactly as the above but takes an array
of IDs. Any of these 2 functions can be used for single integers or
arrays as they will call each other as needed.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
deletePost($postID){
/* ---------------------------------------------------------------
This function will delete a POST by its ID.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
deletePosts($postIDs){
/* ---------------------------------------------------------------
Helper function that does exactly as the above but takes an array
of IDs. Any of these 2 functions can be used for single integers or
arrays as they will call each other as needed.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
newPost($postTitle$postText$postCategories$publish=true){
/* ---------------------------------------------------------------
This function will post a new topic. Paramaters are selfexplanatory.
If $publish is true the post is published immediately otherwise
it's placed inside drafts. $postCategories is a numeric array or
a string with category IDs separated by ,
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
editPost($postID$postTitle$postText$postCategories$publish=true){
/* ---------------------------------------------------------------
This function will edit an existing post. Paramaters are selfexplanatory.
If $publish is true the post is published immediately otherwise
it's placed inside drafts. $postCategories is a numeric array or
a string with category IDs separated by ,
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
getRecentPosts($numPosts$blogID=0){
/* ---------------------------------------------------------------
This function will get the latest POSTS including title, description
and categories. I advise against using it. Use the getRecentPostIDs
instead and then just query each ID to get post info.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
getRecentPostIDs($numPosts$blogID=0){
/* ---------------------------------------------------------------
This function will get the latest POSTS IDs so you can query each
of them to get post info useing getPost().
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
getAllPosts($blogID=0){
/* ---------------------------------------------------------------
This function is a helper function. The getRecentPosts with $numPosts
set to 0 will return the same thing. All the POSTS.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
getAllPostIDs($blogID=0){
/* ---------------------------------------------------------------
This function is a helper function. The getRecentPostIDs with $numPosts
set to 0 will return the same thing. All the POSTS IDs.
--------------------------------------------------------------- */
// - Blogger Type API Function -
}

function 
getPage($pageID,$blogID=0){
/* ---------------------------------------------------------------
This function will get a page by ID. A page is not a post. It's
like the About page. You know better.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
deletePage($pageID,$blogID=0){
/* ---------------------------------------------------------------
This function will delete a page. It returns an array of undeleted
pages or true.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
deletePages($pageIDs,$blogID=0){
/* ---------------------------------------------------------------
Helper function that does exactly as the above but takes an array
of IDs. Any of these 2 functions can be used for single integers or
arrays as they will call each other as needed. It returns an array
of undeleted pages or true.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
listPages($blogID=0){
/* ---------------------------------------------------------------
This function will list pages with short info about them.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
getPages($blogID=0){
/* ---------------------------------------------------------------
This function will list pages with longer info about them.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
getPageIDs($blogID=0){
/* ---------------------------------------------------------------
This function will list only page IDs so you can query further
informations using getPage().
--------------------------------------------------------------- */
// - WordPress Type API Function -
}
;
function 
getCategories($blogID=0){
/* ---------------------------------------------------------------
This function will list categories with details using wordPress API
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
getCategoryIDs($blogID=0){
/* ---------------------------------------------------------------
This function will list only category ID and name. It returns an
array $entry[$categoryID]=$categoryName. Use IDs for new POSTs
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
newCategory($categoryName,$blogID=0){
/* ---------------------------------------------------------------
This function will create a new category.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
getAuthors($blogID=0){
/* ---------------------------------------------------------------
This function will list Authors of Blog.
--------------------------------------------------------------- */
// - WordPress Type API Function -
}

function 
publishPost($postID){
/* ---------------------------------------------------------------
This function will Publish posts from Drafts.
--------------------------------------------------------------- */
// - MovableType Type API Function -
}
?>

It's best to leave default parameters untouched unless you know what you're doing. I have the bad habbit of using functions in my code decalred in other libraries I include by default. So if this won't work and you have XMLRPC enabled let me know where it fails so I can add the missing functions. Had no time / mood to double check it:)

Last but not least.

Hope you enjoy it, don't forget the Teddy Bear on the right and any comments / linkbacks are mandatory welcome. Regards.

40 Comments Posted By Readers :

Add your comment
#1 netizen from Switzerland web
Posted on Monday, 15 October, 2007
*thumbs up* just tested it out, works fine. thanks for that piece of software, just a few steps left ;)
#2 5ubliminal web
Posted on Tuesday, 16 October, 2007
Dude … get in touch with me. Send an email with your Yahoo! or MSN or ICQ ID over.

PS:A linkback to the script would be nice and I would check out my new code I put on site.
#3 mark from Germany web
Posted on Sunday, 16 December, 2007
hm i tested it and when i try:
$wp = new eWordpressApi("http://blog.tld/xmlrpc.php","user","pass");
$del = $wp->deletePages(1);


i'm getting the following error:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 17126736 bytes) in /root/wordpress-api.class.php on line 334

i tried increasing memory but that didnt solve the problem,
besides it shouldnt need 128MB of mem and that still wasnt enough..any ideas?
#4 5ubliminal web
Posted on Sunday, 16 December, 2007
I used the deletePage feature just once under developement but made some tweaks right before publishing it.
The problem is I did not test it again as I focused on posts not pages which are different.

Hence my error and thank you for noticing. In the deletePage function first line says: if(!is_array($pageID)). Replace this with if(is_array($pageID)) .
If the parameter is array deletePage passes to deletePages, but deletePages passes to deletePage if it's not an array. I made a mistake with ! in the deletePage function and they loop forever.

Thanks a lot and if you find any other problems … do let me know!

PS: I also uploaded a fixed verison so you could just redownload.
#5 mark from Germany web
Posted on Monday, 17 December, 2007
thx :) couldnt figure thatone out.. i'm just starting to get into php ..but i know C so its more easy i guess ..a lot seems familiar
#6 5ubliminal web
Posted on Monday, 17 December, 2007
I've come from C++ background too. Had 7 yrs. of serious C++ when I got into PHP 2yrs ago.
Syntax matches and pretty much same concept so transition is easy.

But C++ is still my true love as it can do all PHP can but multithreading.:)
#7 mark from Germany web
Posted on Monday, 17 December, 2007
hehe yes multithreads are fun :)
although i'm into pure ansi C ..i cant get used to C++
i just code C in vim on linux, but for all this seo stuff
php/bash script seems the way to go as it easily saves
you a lot of time compared if you would do the same in C.
for automation its fun, but i'm still just beginning so i get
stuck a lot lately with my scripts..
#8 5ubliminal web
Posted on Monday, 17 December, 2007
I'll give you the best piece of advice one can give you about learning PHP. Don't dive right into scripts. Grab a book, reach a medium level then start going deeper.
This will help you a lot with learning time. You waste a lot more time trying to comprehend scripts then learning stuff from books and then moving on.

There's an entire anti-books movement online and everyone thinks they can become coders by reading tutorials.
I'm not saying this is you as you know C and that's gives you a headstart but do not waste time trying to descipher PHP from scripts found online with no solid basics.
Go for a book first and you'll save a lot more time and things will be a lot clearer.

My 2cents for you :)
#9 Dan from United States web
Posted on Monday, 31 December, 2007
I'm trying to figure out how to set the post_date using XMLRPC. So far I haven't had any luck, each API seems to hardcode it in using

$post_date = current_time('mysql');

Has anyone found a way to modify the post_date using the APIs without modifying the XMLRPC.php that is built into wordpress?

It seems like all the blogging apps out there do it but I don't see how.
#10 5ubliminal web
Posted on Monday, 31 December, 2007
I dont' think there's a way to go so deep in the blog. But using the MT API might work.
I made this class with the simpe aim of posting :) I added several other functions but I did not care to go that deep.

Subscribe to RSS and I'll let you know if I can help you in about one week.
If I do it, I'll write a post about it.

Happy New Year m8!
#11 netizen from Switzerland web
Posted on Monday, 14 January, 2008
i've got a little fix for

function newCategory($categoryName,$blogID=0)

change


array_push($params, (string)$categoryName);


to


array_push($params, array("name"=>$categoryName));


to fix categories named only with one letter
#12 5ubliminal web
Posted on Tuesday, 15 January, 2008
Thanks;) I'll check it out and make the change.
#13 ed from United States web
Posted on Friday, 07 March, 2008
Great set of functions - I just used it to clean up a script I've been using for myself so it was easier for others to use. Basically taking a sitemap and posting the links to a blog to use an external sitemap for indexing.
#14 Yoyo from Romania
Posted on Thursday, 13 March, 2008
I copied the contents of http://www.tellinya.com/read/2007/10/02/remote-control-wordpress-through-xmlrpc-sounds-good/wordpress-api.html
in postxmlrpc.php
at the bottom added the sample code and I get this error:

Fatal error: Call to undefined function xmlrpc_encode_request() in /opt/lampp/htdocs/test/wordpress/postxmlrpc.php on line 40
#15 5ubliminal web
Posted on Thursday, 13 March, 2008
EN: Make sure you have the xmlrpc extension enabled in php.ini. Get it from php.net if you can't find it in ext folder.

Asigura-te ca ai activate extensiile xmlrpc in php. Sunt extensii optionale si le activezi din php.ini.
De asemena sa existe DLL-ul in directorul ext/ sau il gasesti pe site-ul php.net la PHP full download cu extensii.

Noroc;)
#16 Yoyo from Romania
Posted on Friday, 14 March, 2008
La raspuns in romaneste nu ma asteptam :)
Eram pe *nix si xampp nu are suport XMLRPC default. Acum merge. Mersi.

In 2.5 au facut o schimbare si suporta si custom fields. http://trac.wordpress.org/ticket/5148
O sa faci un update pentru custom fields?

Translation:
There's a new update in the API using a new feature: custom fields. Will you implement it also?
#17 5ubliminal web
Posted on Friday, 14 March, 2008
I'll look into it soon … in the next few weeks. Currently I'm in neck deep-er in other projects that can't be delayed. (pt.EN)

Am o aversie fata de WP dar o sa ma uit si o sa le implementez in viitorul apropiat (1-2 saptamani).
In momentul de fata sunt afundat pana la peste gat in niste proiecte in C++ (tot de SEO) si cand termin il fac.
Subscrie la RSS si o sa pun un post nou cand voi face update.

Bafta.
PS: Eram sigur ca nu te asteptai;)
#18 Freeware Downloads from United States
Posted on Thursday, 20 March, 2008
Hey Romania its your version of php :.... update to 5.2.3 and above. If you can Google around... I think there was a work around released.
#19 long from France
Posted on Thursday, 08 May, 2008
Hi,

Thank you very much for your work, its really what im looking for !
But, i'd like to know if we can have a way to add tags to post using this API ?

Thx
#20 5ubliminal web
Posted on Friday, 09 May, 2008
I think it can be done but I don't have the time right now for this. I can point you here where you can see all the XMLRPC commands and try the metaweblog ones.
You could look into my code and try to extend. It should be easy fi you can do some reverse engineering of code.

I might implement them but not this month.
Regards.
#21 long from France
Posted on Friday, 09 May, 2008
thanks a lot for your help
#22 Maximus Marius from Poland web
Posted on Tuesday, 13 May, 2008
//-- Code provided has been removed from the comment, added to the PHP Class Body and credited accordingly.

5ubliminal: Thanks!
I was planning to add these but no time right now.
If you add other missing functions send'em over.
I'll test them and add them to the class.
#23 me
Posted on Wednesday, 14 May, 2008
How about inserting comments? Thanks! Keep up the excelent work!
#24 underworld from Great Britain web
Posted on Thursday, 05 June, 2008
Hey dude,
Came across the issue where you can't post tags AND categories (WP blogs) - you just got to post with tags first then edit adding categories.

[... code was removed and will be added to the class in the next few days]
#25 5ubliminal web
Posted on Thursday, 05 June, 2008
I added this to my main class, credited you in the source as I did with the other contributors and I'll also credit you on the site.
I'll test it out tomorrow and update the post as soon as everything settles down after my last post.:)

Thanks.
PS: I removed the code from your comment because it was violated by my basic-pseudo-blog-engine.
#26 underworld from Great Britain web
Posted on Thursday, 05 June, 2008
no worries dude - it's all about giving back :D

look forward to seeing what comes of your latest thoughts

uW
#27 Marius Maximus from Poland web
Posted on Saturday, 07 June, 2008
Where is it preint ?

your code: "preint($request); "
#28 5ubliminal web
Posted on Saturday, 07 June, 2008
preint = echo "
";print_r(...);echo "
"; :)

Forgot it there. It's for debugging purposes. I'll update it tomorrow as I have another user contributed function to add.
Thanks.
#29 Marius Maximus from Poland web
Posted on Monday, 09 June, 2008
Can I use your code in my application ?
Can You write licence :)
#30 5ubliminal web
Posted on Monday, 09 June, 2008
Depends on the application :) Commercial? Share some details with me.
#31 Marius Maximus from Poland web
Posted on Saturday, 14 June, 2008
I found small error in function xml2Post.
I tested your class on my test blog

include('WordpressApi.php');
$wp = new eWordpressApi("http://wp25.miernik.info/xmlrpc.php","blahblagblah","blebleble");
$wynik = $wp->getAllPosts();
print_r($wynik);

I found one post where function xml2Post didn't return 'content', 'title', 'category'. All data are in input data but preg_match can't find it.
It is post with error return
http://wp25.miernik.info/aaaaaaaa-2/


You can test it, in file test2.txt i write my data with i have error :(

$postXml['content'] = file_get_contents(http://wp25.miernik.info/test2.txt);
if(preg_match(
"/^(.*?)".
"(.*)(.*)$/Ui"
,$postXml['content'],$pcs)
){
$postXml['content']=$pcs[3];
$postXml['title']=$pcs[1];
$postXml['category']=explode(",",$pcs[2]);
}
#32 5ubliminal web
Posted on Saturday, 14 June, 2008
I need access so I can test that post. Mail me the login info for the test WP install so I can test it.
It works well for me. Didn't find one not to work.
#33 Marius Maximus from Poland web
Posted on Saturday, 14 June, 2008
I don't know very well regexp but i change
"/Ui" to "/is" and now all is OK.
What mean /U in regexp?
#34 5ubliminal web
Posted on Saturday, 14 June, 2008
My bad. The s was important and I added it too. Funny thing is it wroked even if I forgot it.
U turns .* to .*? . Without U .*@ will find farthest @.
With U or .*?@ it will find closest @.
#35 Marius Maximus from Poland web
Posted on Sunday, 15 June, 2008
I found new error :)

When post don't have "Title" or content is empty your preg_match dont't have result :(

Perhaps You should change one preg_match to tree preg_match(s)
One for Title (.*?)
One for Category (.*)
One for Content substr($postXml['content'], strrpos($postXml['content'],">") )
#36 5ubliminal web
Posted on Sunday, 15 June, 2008
I never imagined a post could be empty or not have a title. It's against nature.
Do they allow you to post titeless / textless posts? I haven't tried this one.

But I'll check some freak errors like this. Who would post with no title?
#37 Marius Maximus from Poland web
Posted on Sunday, 15 June, 2008
Sometimes people are strange :)
#38 Christian from United States web
Posted on Thursday, 19 June, 2008
Excellent post. Thanks for the information.
#39 bh seo from United States web
Posted on Thursday, 26 June, 2008
I'm getting a strange error suddenly -- and I can't figure out why. Same server as I have it working - php5, xmlrpc is enabled, etc..


Fatal error: Call to undefined function preint()

(That chunk of code)
function doRpcRequest($url,$method,$params,$returnbool=0)
{
$request = xmlrpc_encode_request($method, $params);
preint($request);

************************************************
My request:
*************************************************
$wp = new eWordpressApi("$url","$user","$pass");
$title = "$title";
$text = "$change";
$category = array(1,2);
$postID = $wp->newPost($title,$text,$category);
if(is_array($postID)) echo "Opps - I'm broken. What did you do wrong?";

All my variables there are valid - I've echoed them out to check.
#40 5ubliminal web
Posted on Thursday, 26 June, 2008
Remove the preint line. It's a modified version of print_r I use for debugging and forgot it there.
Post Feedback 
Name *
Mail *
URL
« Anti-Spam
» URL will only go live after a review. Comments are moderated. «
5ubliminal's TellinYa.com SEO & SEM Blog © 2007 - All rights reserved unless mentioned otherwise .
Rendered On : [Sunday, 06 July, 2008 - 04:19:19 GMT]   No Ajax / Flash Used Here
" Remote Control Wordpress through XMLRPC! Sounds good?;) : 5ubliminal's TellinYa "