Skip to content

Instantly share code, notes, and snippets.

@BrendonKoz
Created August 14, 2012 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BrendonKoz/3351064 to your computer and use it in GitHub Desktop.
Save BrendonKoz/3351064 to your computer and use it in GitHub Desktop.
Script to parse a Polaris Library Systems' exported XML report of a record set in order to dynamically post to a (pre-installed) Wordpress site (as a blog post). XMLRPC must be enabled in WP Settings. Was used for monthly "new materials" posts. Adapt to y
<?php
$username = 'your_wp_username';
$password = 'your_wp_password';
$blogURI = 'http://www.example.com/wordpress/';
$ignored_categories = array('Blogroll'); //store categories to ignore in an array for easier blocking
$blogAPI = $blogURI . 'xmlrpc.php';
$data = array();
$publish = false;
$categories = array();
$client = new IXR_Client($blogAPI);
if(!$client->query('wp.getCategories', '', $username, $password)){
die('An error occurred - '.$client->getErrorCode().":".$client->getErrorMessage());
}
$result = $client->getResponse();
/* example payload return
Array
(
[0] => Array
(
[categoryId] => 5
[parentId] => 0
[description] =>
[categoryName] => DVDs
[htmlUrl] => http://127.0.0.1/wordpress/?cat=5
[rssUrl] => http://127.0.0.1/wordpress?feed=rss2&cat=5
)
)
*/
foreach($result as $cat){
if(!in_array($cat['categoryName'], $ignored_categories)){
$categories[$cat['categoryId']] = $cat['categoryName'];
}
}
if(isset($_POST['submit']) && !empty($_FILES['xmlfile']['name']) && !$_FILES['xmlfile']['error']){
if(!move_uploaded_file($_FILES['xmlfile']['tmp_name'], getcwd() . '/xmlfile.xml')){
die('Unable to access uploaded file. Please try again!');
}
define('XML_FILE', './xmlfile.xml'); //find temp uploaded file
if(filesize(XML_FILE) != $_FILES['xmlfile']['size']) die('There was an error uploading. Please try again!');
# if($_POST['sort'] !== 'title_dropauthor') define('AUTHOR', 'BrowseAuthor');
define('SORT_BY_AUTHOR', ($_POST['sort'] === 'author') ? true : false);
# define('TITLE', 'browsetitle');
define('FIND_ELEMENT_TAG', 'Detail');
define('ANCHOR', 'http://pac.sals.edu/polaris/view.aspx?ctx=90.1033.0.0.6');
define('WRONG_FILE_TYPE_MSG', 'This file does not appear to be a valid XML file type. Please double check the file you choose to upload and try again. <a href="javascript:history.back();">Go back</a>.');
$post_author_id = 2; //1 is admin, 2 is "Staff"
$content = '';
$month = ctype_alpha($_POST['month']) ? $_POST['month'] : date('F');
$category = ctype_alpha(str_replace(' ', '', $_POST['category'])) ? $_POST['category'] : 'Uncategorized';
$title = 'New '.$category.' for '.$month;
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
@$dom->load(XML_FILE) or die(WRONG_FILE_TYPE_MSG);
$nodes = $dom->getElementsByTagName(FIND_ELEMENT_TAG);
$length = $nodes->length;
if($length > 0){
if($nodes->item(0)->getAttribute('ISBN')){
//this is the dynamically created xml report
define('TITLE', 'Title');
if($_POST['sort'] !== 'title_dropauthor') define('AUTHOR', 'Author');
}else{
//this is a report created from a record set
define('TITLE', 'browsetitle');
if($_POST['sort'] !== 'title_dropauthor') define('AUTHOR', 'BrowseAuthor');
}
$stored_vals = array();
$attributes = array();
if(defined('AUTHOR')) $attributes[] = AUTHOR;
$attributes[] = TITLE;
$headings = defined('AUTHOR') ? array('Author', 'Title') : array('Title');
for($index = 0; $index < $length; $index++){
foreach($attributes as $attribute){
$stored_vals[$index][$attribute] = $nodes->item($index)->getAttribute($attribute);
}
}
cleanArrayData($stored_vals);
$content = tableFromArray($stored_vals, 'data', 'new materials', $headings);
$data['title'] = $title;
$data['description'] = $content;
$data['categories'] = array($category);
//run mw.newPost XMLRPC call to insert entry
if(!$client->query('metaWeblog.newPost', '', $username, $password, $data, $publish)){
die('An error occurred - '.$client->getErrorCode().":".$client->getErrorMessage());
}
unlink(XML_FILE);
echo '<p>You\'ve successfully created a draft entry in Wordpress. Please <a href="'.$blogURI.'wp-admin/">login to the system</a> and go check over the data within the draft entry <strong><em>(fix typos, incorrect characters, and duplicates)</em></strong>. When done, publish it to make it viewable by patrons.</p>';
echo '<p>Alternatively, you may also PREVIEW the article by <a href="'.$blogURI.'?p='.$client->getResponse().'">clicking here</a></p>';
echo '<p>Do you wish to <a href="javascript:history.back();">process and upload another</a>?</p>';
}else{
echo '<p>'.WRONG_FILE_TYPE_MSG.'</p>';
echo '<pre>';
print_r($nodes);
echo '</pre>';
}
}else{
if(isset($_POST['submit'])){
echo ' <p class="error_msg">You must browse to, and choose a downloaded XML report file to upload. Please <a href="javascript:history.back();">go back</a> and try again.</p>';
}else if(isset($_FILES['xmlfile']['error']) && !empty($_FILES['xmlfile']['error'])){
echo ' <p class="error_msg">There was an error uploading the file. Please <a href="javascript:history.back();">go back</a> and try again.</p>';
}else{
echo ' <p>This is a form used to upload record sets from Polaris Reporting services to our Wordpress blog. '
.'By using this form, only a <em>draft</em> entry will be saved - to publish the content and have it be viewable online, a Wordpress user must log '
.'in and publish the report.</p><p>If you\'re entering a record set for DVDs or another type of item which is normally <em>without</em> an Author, make sure to choose the proper '
.'sorting option (remove author). Please note that if you submit the form too quickly, or accidentally - this will only create a draft at this stage. You can always start anew '
.'and remove the older entry, or modify the draft entry prior to publishing.</p>'."\n";
echo ' <form enctype="multipart/form-data" method="post" action="" style="margin-top:1.5em; font-size:135%;">' . "\n";
echo ' <p><label for="xmlfile">Locate the Item Record Set Report XML file:</label>' . "\n";
echo ' <input type="file" name="xmlfile" id="xmlfile" style="width:50%;" /></p>' . "\n";
echo ' <p><label for="category">Choose a New Materials\' category:</label>' . "\n";
echo ' <select name="category" id="category">' . "\n";
foreach($categories as $cat){
if($cat === 'Uncategorized'){
echo ' <option value="'.$cat.'" selected="selected">'.$cat.'</option>' . "\n";
}else{
echo ' <option value="'.$cat.'">'.$cat.'</option>' . "\n";
}
}
//fix for strtotime and "next month"
function firstDayOfMonth($uts = null){
$today = is_null($uts) ? getDate() : getDate($uts);
$first_day = getdate(mktime(0,0,0,$today['mon'],1,$today['year']));
return $first_day[0];
}
$firstDay = date('Y-m-d', firstDayOfMonth());
echo ' </select></p>' . "\n";
echo ' <p><label for="month">Choose a month:</label>'."\n";
echo ' <select size="3" name="month" id="month" style="z-index:-999;">'."\n";
echo ' <option value="'.date('F', strtotime($firstDay.' -1 month')).'">'.date('F', strtotime($firstDay.' -1 month')).'</option>'."\n";
echo ' <option value="'.date('F').'" selected="selected">'.date('F').'</option>'."\n";
echo ' <option value="'.date('F', strtotime($firstDay.' +1 month')).'">'.date('F', strtotime($firstDay.' +1 month')).'</option>'."\n";
echo ' </select>'."\n";
echo ' <p><label for="sort">Choose a sorting option:</label>'."\n";
echo ' <select name="sort" id="sort" style="z-index:-999;">'."\n";
echo ' <option value="author">Sort by Author</option>'."\n";
echo ' <option value="title_keepauthor">Sort by Title - Keep the Author Field</option>'."\n";
echo ' <option value="title_dropauthor">Sort by Title - Remove the Author Field</option>'."\n";
echo ' </select></p>'."\n";
echo ' <p><input type="submit" name="submit" value="Process Draft Report" class="submit_button" style="font-size:70%;" /></p>' . "\n";
echo ' </form>' . "\n";
}
}
/************* Functions *************/
function cleanArrayData(&$dataArr){
$index = 0;
foreach($dataArr as $entry){
foreach($entry as $key => $value){
switch($key){
case TITLE:
$dataArr[$index][$key] = htmlentities(preg_replace('/ \[.+?\] ?/u', '', $value), ENT_NOQUOTES, 'UTF-8');
break;
default:
if($key == AUTHOR)
{
$dataArr[$index][$key] = htmlentities(preg_replace('/(?:, \d{4}-(?:\d{4})?\.?|\.)$/u', '', $value), ENT_NOQUOTES, 'UTF-8');
}
break;
}
}
$index++;
}
$sort_method = SORT_BY_AUTHOR ? 'sortItems' : 'sortByTitle';
usort($dataArr, $sort_method);
}
//sort specifically for this data, sort by AUTHOR if exists in dataset, else by TITLE
function sortItems($a, $b){
//defaults to author sort, falls back to title if no authors found
if(isset($a[AUTHOR])){
$a = strtoupper($a[AUTHOR]);
$b = strtoupper($b[AUTHOR]);
if($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}else if(isset($a[TITLE])){
$a = strtoupper($a[TITLE]);
$b = strtoupper($b[TITLE]);
if($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
}
function sortByTitle($a, $b){
if(isset($a[TITLE])){
$a = strtoupper($a[TITLE]);
$b = strtoupper($b[TITLE]);
if($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
return 0; //return the same list if no title found -- can't sort!
}
function tableFromArray($array, $class, $summary = '', $headers, $width = '100%'){
$bad_chars = array('&', '#', '+'); //characters that don't sit well with Polaris' PAC
$tdwidth = 100 / count($array[0]);
$html = '&nbsp;';
$html .= '<table class="'.$class.'" cellspacing="0" cellpadding="0" summary="'.$summary.'" style="width:'.$width.';">' . "\n";
$html .= ' <tr>'."\n";
foreach($headers as $header){
$html .= " <th width=\"$tdwidth%\">$header</th>\n";
}
$html .= ' </tr>'."\n";
foreach($array as $itemInfo){
$anchor = ANCHOR;
$html .= ' <tr>' . "\n";
foreach($itemInfo as $type => $info){
$source = $info;
$info = html_entity_decode($info); //must be done for the anchor tag
$info = str_replace($bad_chars, '', $info);
if(defined('AUTHOR') && $type === AUTHOR && !empty($info)){
$anchor .= '&amp;author='.urlencode($info);
}else if(defined('TITLE') && $type === TITLE && !empty($info)){
#$anchor .= '&amp;title='.urlencode($info);
#$anchor .= '&amp;keyword='.urlencode($info); //changed 12/01/09 to fix mappings from 3.3->3.5
$anchor .= '&amp;title='.urlencode($info); //changed 2/23/10 to continue to fix mappings
}
$anchor .= (strpos($anchor, 'author') === false) ? '&amp;author=' : ''; //added 2/23/10
$anchor = str_replace('%3B', '', $anchor);
$anchor = str_replace('++', '+', $anchor);
if(defined('TITLE') && $type === TITLE){
$html .= ' <td width="'.$tdwidth.'%" valign="top"><a href="'.$anchor.'">'.$source.'</a></td>' . "\n";
}else{
$html .= ' <td width="'.$tdwidth.'%" valign="top">'.$source.'</td>' . "\n";
}
}
$html .= ' </tr>' . "\n";
}
$html .= '</table>';
//fix Wordpress' retarded handling of tables to allow some typing AFTER the table...stupid wordpress...
$html .= '&nbsp;';
return $html;
}
?>
@BrendonKoz
Copy link
Author

Please note: The code above was cleaned up and made semi-generic from another project. In cleaning it up I forgot to include the class-IXR.php file from within the Wordpress folder itself. Everything needed is already provided by Wordpress and this code - but this code will require the inclusion of that file from Wordpress in order to function properly. Oops! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment