#!/usr/bin/env php Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. No representations are made about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. Created: 23-Nov-2010 Command-line PHP script to post to WordPress without authentication, e.g., for use by cron or other shell scripts. DO NOT make this runnable by the web server! That would be a huge security hole. If $USER is able to connect to the WordPress SQL database, then they have free reign already. All this does it make it easy for them to to insert a new post into it properly. Arguments: --user wp-author-name --body html --subject html (optional) --tags a,b,c (optional) --music text (optional) --location text (optional) --closed (optional -- disallow comments) --draft (optional -- don't actually publish it) Prints the ID of the newly-created post on stdout. */ global $progname; $progname = $argv[0]; function usage() { global $progname; error_log ("usage: $progname --user U --body B [--subject S]\n" . "\t[--date D] [--tags T] [--music M] [--location L] [--draft]"); exit (1); } $user = ''; $subj = ''; $body = ''; $date = ''; for ($i = 1; $i < count($argv); $i++) { $k = $argv[$i]; switch ($k) { case '--user': $user = $argv[++$i]; break; case '--subject': $subj = $argv[++$i]; break; case '--date': $date = $argv[++$i]; break; case '--body': $body = $argv[++$i]; break; case '--tags': $tags = $argv[++$i]; break; case '--music': $music = $argv[++$i]; break; case '--location': $loc = $argv[++$i]; break; case '--closed': $closed = 1; break; case '--draft': $draftp = 1; break; default: usage(); break; } } if (!$user || !$body) usage(); if ($date) { $date = strtotime ($date); } else { $date = time(); } require_once('wp-load.php'); require_once(ABSPATH . 'wp-admin/includes/admin.php'); // Convert a user name to a user id if it's not already numeric. if (! preg_match('/^\d+$/', $user)) { $ouser = $user; $user = get_userdatabylogin($user)->ID; if ($user <= 0) { error_log ("$progname: bad user: $ouser"); exit(1); } } // We have to create the post as a draft, then change its status to // published later, because there's no way to set meta tags on a post // before it has been inserted; but those tags have to be present // before it is published. $post = array(); $post['post_status'] = 'draft'; $post['post_author'] = $user; $post['post_content'] = $body; $post['comment_status'] = ($closed ? 'closed' : 'open'); $post['post_title'] = $subj; $post['post_name'] = wp_unique_post_slug (sanitize_title ($subj), 0, 'publish', 'post', 0); // Need to do this or it posts in GMT instead of local timezone. date_default_timezone_set (get_option ("timezone_string")); $post['post_date'] = date ('Y-m-d H:i:s', $date); $post['post_date_gmt'] = gmdate ('Y-m-d H:i:s', $date); if ($tags) $post['tags_input'] = $tags; // for Simple Twitter Connect. Yes it really needs to be in $_POST, // not in the $post array. global $_POST; $_POST['stc_auto_publish'] = 1; kses_remove_filters(); // assume all HTML is valid as-is. $id = wp_insert_post ($post, 1); if (empty ($post['post_name'])) { // If post_name came out blank, set it to the ID. $post['post_name'] = $id; $wpdb->update ($wpdb->posts, array ('post_name' => $post['post_name']), array ('ID' => $id)); } if (is_wp_error($id)) { error_log("$progname: Error: " . htmlspecialchars($ret->get_error_message())); exit(1); } if (empty ($post['post_name'])) { // If post_name came out blank, set it to the ID. $post['post_name'] = $id; $wpdb->update ($wpdb->posts, array ('post_name' => $post['post_name']), array ('ID' => $id)); } // Convert entities to Unicode for these fields. if ($loc) $loc = html_entity_decode ($loc, ENT_QUOTES, 'UTF-8'); if ($music) $music = html_entity_decode ($music, ENT_QUOTES, 'UTF-8'); if ($loc) add_post_meta ($id, 'location', $loc, true); if ($music) add_post_meta ($id, 'music', $music, true); if (! $draftp) { wp_publish_post ($id); } print "$id\n"; exit (0);