Created
March 21, 2013 19:51
-
-
Save raamdev/5216142 to your computer and use it in GitHub Desktop.
Adds support for Post Formats to the WordPress Postie plugin. You can now specify a post format in the email subject like this: "Aside :: My Aside-formatted post". My changes to postie-functions.php can be found on lines L232, L305, L402, L803, and L2421.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
$Id: postie-functions.php 683869 2013-03-18 21:39:57Z WayneAllen $ | |
*/ | |
//to turn on debug output add the following line to wp-config.php | |
//define('POSTIE_DEBUG', true); | |
if (!function_exists('mb_str_replace')) { | |
function mb_str_replace($search, $replace, $subject, &$count = 0) { | |
if (!is_array($subject)) { | |
// Normalize $search and $replace so they are both arrays of the same length | |
$searches = is_array($search) ? array_values($search) : array($search); | |
$replacements = is_array($replace) ? array_values($replace) : array($replace); | |
$replacements = array_pad($replacements, count($searches), ''); | |
foreach ($searches as $key => $search) { | |
$parts = mb_split(preg_quote($search), $subject); | |
$count += count($parts) - 1; | |
$subject = implode($replacements[$key], $parts); | |
} | |
} else { | |
// Call mb_str_replace for each subject in array, recursively | |
foreach ($subject as $key => $value) { | |
$subject[$key] = mb_str_replace($search, $replace, $value, $count); | |
} | |
} | |
return $subject; | |
} | |
} | |
function postie_disable_revisions($restore = false) { | |
global $_wp_post_type_features, $_postie_revisions; | |
if (!$restore) { | |
$_postie_revisions = false; | |
if (isset($_wp_post_type_features['post']) && isset($_wp_post_type_features['post']['revisions'])) { | |
$_postie_revisions = $_wp_post_type_features['post']['revisions']; | |
unset($_wp_post_type_features['post']['revisions']); | |
} | |
} else { | |
if ($_postie_revisions) { | |
$_wp_post_type_features['post']['revisions'] = $_postie_revisions; | |
} | |
} | |
} | |
/* this function is necessary for wildcard matching on non-posix systems */ | |
if (!function_exists('fnmatch')) { | |
function fnmatch($pattern, $string) { | |
$pattern = strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' => | |
'.', '\[' => '[', '\]' => ']')); | |
return @preg_match( | |
'/^' . strtr(addcslashes($pattern, '/\\.+^$(){}=!<>|'), array('*' => '.*', '?' => '.?')) . '$/i', $string | |
); | |
} | |
} | |
function LogInfo($v) { | |
error_log("Postie: $v"); | |
} | |
function EchoInfo($v) { | |
if (php_sapi_name() == "cli") { | |
echo "$v\n"; | |
} else { | |
if (headers_sent()) { | |
echo "<pre>" . htmlspecialchars($v) . "</pre>\n"; | |
} | |
} | |
LogInfo($v); | |
} | |
function DebugDump($v) { | |
if (IsDebugMode()) { | |
$o = print_r($v, true); | |
if (php_sapi_name() == "cli") { | |
echo "$o\n"; | |
} else { | |
if (headers_sent()) { | |
echo "<pre>\n"; | |
EchoInfo($o); | |
echo "</pre>\n"; | |
} | |
} | |
} | |
} | |
function DebugEcho($v) { | |
if (IsDebugMode()) { | |
EchoInfo($v); | |
} | |
} | |
function tag_Date(&$content, $message_date) { | |
DebugEcho("tag_Date\n---\n$content\n---"); | |
if (1 === preg_match("/^date:\s?(.*)$/im", $content, $matches)) { | |
$newdate = strtotime($matches[1]); | |
if (false !== $newdate) { | |
$t = date("H:i:s", $newdate); | |
DebugEcho("time: $t"); | |
$format = "Y-m-d"; | |
if ($t != '00:00:00') { | |
$format.= " H:i:s"; | |
} | |
$message_date = date($format, $newdate); | |
$content = trim(str_replace($matches[0], '', $content)); | |
} | |
} else { | |
DebugEcho("No date found"); | |
} | |
return $message_date; | |
} | |
function CreatePost($poster, $mimeDecodedEmail, $post_id, &$is_reply, $config) { | |
$fulldebug = false; | |
extract($config); | |
$attachments = array( | |
"html" => array(), //holds the html for each image | |
"cids" => array(), //holds the cids for HTML email | |
"image_files" => array() //holds the files for each image | |
); | |
if (array_key_exists('message-id', $mimeDecodedEmail->headers)) { | |
EchoInfo("Message Id is :" . htmlentities($mimeDecodedEmail->headers["message-id"])); | |
if ($fulldebug) | |
DebugDump($mimeDecodedEmail); | |
} | |
filter_PreferedText($mimeDecodedEmail, $prefer_text_type); | |
if ($fulldebug) | |
DebugDump($mimeDecodedEmail); | |
$content = GetContent($mimeDecodedEmail, $attachments, $post_id, $poster, $config); | |
if ($fulldebug) | |
DebugEcho("the content is $content"); | |
$subject = GetSubject($mimeDecodedEmail, $content, $config); | |
filter_RemoveSignature($content, $config); | |
if ($fulldebug) | |
DebugEcho("post sig: $content"); | |
$post_excerpt = tag_Excerpt($content, $filternewlines, $convertnewline); | |
if ($fulldebug) | |
DebugEcho("post excerpt: $content"); | |
$postAuthorDetails = getPostAuthorDetails($subject, $content, $mimeDecodedEmail); | |
if ($fulldebug) | |
DebugEcho("post author: $content"); | |
$message_date = NULL; | |
if (array_key_exists("date", $mimeDecodedEmail->headers) && !empty($mimeDecodedEmail->headers["date"])) { | |
$cte = ""; | |
$cs = ""; | |
if (property_exists($mimeDecodedEmail, 'content-transfer-encoding') && array_key_exists('content-transfer-encoding', $mimeDecodedEmail->headers)) { | |
$cte = $mimeDecodedEmail->headers["content-transfer-encoding"]; | |
} | |
if (property_exists($mimeDecodedEmail, 'ctype_parameters') && array_key_exists('charset', $mimeDecodedEmail->ctype_parameters)) { | |
$cs = $mimeDecodedEmail->ctype_parameters["charset"]; | |
} | |
$message_date = HandleMessageEncoding($cte, $cs, $mimeDecodedEmail->headers["date"], $message_encoding, $message_dequote); | |
} | |
$message_date = tag_Date($content, $message_date); | |
list($post_date, $post_date_gmt, $delay) = filter_Delay($content, $message_date, $time_offset); | |
if ($fulldebug) | |
DebugEcho("post date: $content"); | |
filter_ubb2HTML($content); | |
if ($fulldebug) | |
DebugEcho("post ubb: $content"); | |
$post_categories = tag_categories($subject, $default_post_category, $category_match); | |
if ($fulldebug) | |
DebugEcho("post category: $content"); | |
$post_tags = tag_Tags($content, $default_post_tags); | |
if ($fulldebug) | |
DebugEcho("post tag: $content"); | |
$comment_status = tag_AllowCommentsOnPost($content); | |
if ($fulldebug) | |
DebugEcho("post comment: $content"); | |
if ($converturls) { | |
$content = filter_Videos($content, $shortcode); //videos first so linkify doesn't mess with them | |
if ($fulldebug) | |
DebugEcho("post video: $content"); | |
$content = filter_linkify($content); | |
if ($fulldebug) | |
DebugEcho("post linkify: $content"); | |
} | |
filter_VodafoneHandler($content, $attachments, $config); | |
if ($fulldebug) | |
DebugEcho("post vodafone: $content"); | |
filter_ReplaceImageCIDs($content, $attachments, $config); | |
if ($fulldebug) | |
DebugEcho("post cid: $content"); | |
filter_ReplaceImagePlaceHolders($content, $attachments["html"], $config); | |
if ($fulldebug) | |
DebugEcho("post body img: $content"); | |
if ($post_excerpt) { | |
filter_ReplaceImagePlaceHolders($post_excerpt, $attachments["html"], $config); | |
if ($fulldebug) | |
DebugEcho("post excerpt img: $content"); | |
} | |
$customImages = tag_CustomImageField($content, $attachments, $config); | |
if ($fulldebug) | |
DebugEcho("post custom: $content"); | |
$post_type = tag_PostType($subject); | |
if ($fulldebug) | |
DebugEcho("post type: $content"); | |
/* Added by Raam Dev <raam@raamdev.com> */ | |
$post_format = tag_PostFormat($subject); | |
if ($fulldebug) | |
DebugEcho("post format: $content"); | |
$id = GetParentPostForReply($subject); | |
if (empty($id)) { | |
$id = $post_id; | |
$is_reply = false; | |
if ($add_meta == 'yes') { | |
if ($wrap_pre == 'yes') { | |
$content = $postAuthorDetails['content'] . "<pre>\n" . $content . "</pre>\n"; | |
$content = "<pre>\n" . $content . "</pre>\n"; | |
} else { | |
$content = $postAuthorDetails['content'] . $content; | |
$content = $content; | |
} | |
} else { | |
if ($wrap_pre == 'yes') { | |
$content = "<pre>\n" . $content . "</pre>\n"; | |
} | |
} | |
} else { | |
EchoInfo("Reply detected"); | |
$is_reply = true; | |
// strip out quoted content | |
$lines = explode("\n", $content); | |
$newContents = ''; | |
foreach ($lines as $line) { | |
if (preg_match("/^>.*/i", $line) == 0 && | |
preg_match("/^(from|subject|to|date):.*?/i", $line) == 0 && | |
preg_match("/^-+.*?(from|subject|to|date).*?/i", $line) == 0 && | |
preg_match("/^on.*?wrote:$/i", $line) == 0 && | |
preg_match("/^-+\s*forwarded\s*message\s*-+/i", $line) == 0) { | |
$newContents.="$line\n"; | |
} | |
} | |
$content = $newContents; | |
wp_delete_post($post_id); | |
} | |
if ($delay != 0 && $post_status == 'publish') { | |
$post_status = 'future'; | |
} else { | |
$post_status = $post_status; | |
} | |
filter_newlines($content, $config); | |
if ($fulldebug) | |
DebugEcho("post newline: $content"); | |
filter_Start($content, $config); | |
if ($fulldebug) | |
DebugEcho("post start: $content"); | |
filter_End($content, $config); | |
if ($fulldebug) | |
DebugEcho("post end: $content"); | |
DebugEcho("excerpt: $post_excerpt"); | |
$details = array( | |
'post_author' => $poster, | |
'comment_author' => $postAuthorDetails['author'], | |
'comment_author_url' => $postAuthorDetails['comment_author_url'], | |
'user_ID' => $postAuthorDetails['user_ID'], | |
'email_author' => $postAuthorDetails['email'], | |
'post_date' => $post_date, | |
'post_date_gmt' => $post_date_gmt, | |
'post_content' => $content, | |
'post_title' => $subject, | |
'post_type' => $post_type, /* Added by Raam Dev <raam@raamdev.com> */ | |
'post_format' => $post_format, /* Added by Raam Dev <raam@raamdev.com> */ | |
'ping_status' => get_option('default_ping_status'), | |
'post_category' => $post_categories, | |
'tags_input' => $post_tags, | |
'comment_status' => $comment_status, | |
'post_name' => sanitize_title($subject), | |
'post_excerpt' => $post_excerpt, | |
'ID' => $id, | |
'customImages' => $customImages, | |
'post_status' => $post_status | |
); | |
return $details; | |
} | |
/** | |
* This is the main handler for all of the processing | |
*/ | |
function PostEmail($poster, $mimeDecodedEmail, $config) { | |
postie_disable_revisions(); | |
extract($config); | |
/* in order to do attachments correctly, we need to associate the | |
attachments with a post. So we add the post here, then update it */ | |
$tmpPost = array('post_title' => 'tmptitle', 'post_content' => 'tmpPost'); | |
$post_id = wp_insert_post($tmpPost); | |
EchoInfo("new post id is $post_id"); | |
$is_reply = false; | |
$details = CreatePost($poster, $mimeDecodedEmail, $post_id, $is_reply, $config); | |
$details = apply_filters('postie_post', $details); | |
DebugEcho(("Post postie_post filter")); | |
DebugDump($details); | |
if (empty($details)) { | |
// It is possible that the filter has removed the post, in which case, it should not be posted. | |
// And if we created a placeholder post (because this was not a reply to an existing post), | |
// then it should be removed | |
if (!$is_reply) { | |
wp_delete_post($post_id); | |
} | |
} else { | |
DisplayEmailPost($details); | |
PostToDB($details, $is_reply, true, $custom_image_field); | |
if ($confirmation_email != '') { | |
if ($confirmation_email == 'sender') { | |
$recipients = array($postAuthorDetails['email']); | |
} elseif ($confirmation_email == 'admin') { | |
$recipients = array(get_option("admin_email")); | |
} elseif ($confirmation_email == 'both') { | |
$recipients = array($postAuthorDetails['email'], | |
get_option("admin_email")); | |
} | |
MailToRecipients($mimeDecodedEmail, false, $recipients, false, false); | |
} | |
} | |
postie_disable_revisions(true); | |
DebugEcho("Done"); | |
} | |
/** FUNCTIONS * */ | |
/* | |
* Added by Raam Dev <raam@raamdev.com> | |
* Adds support for handling Custom Post Types by adding the | |
* Custom Post Type name to the email subject separated by | |
* $custom_post_type_delim, e.g. "Movies // My Favorite Movie" | |
*/ | |
function tag_PostType(&$subject) { | |
$custom_post_type_delim = "//"; | |
if (strpos($subject, $custom_post_type_delim) !== FALSE) { | |
// Captures the custom post type in the subject before $custom_post_type_delim | |
$separated_subject = explode($custom_post_type_delim, $subject); | |
$custom_post_type = $separated_subject[0]; | |
$subject = trim($separated_subject[1]); | |
DebugEcho("post type: found possible type '$custom_post_type'"); | |
$custom_post_type = trim(strtolower($custom_post_type)); | |
// Check if custom post type exists, if not, set default post type of 'post' | |
$known_post_types = get_post_types(); | |
DebugDump($known_post_types); | |
if (in_array($custom_post_type, array_map('strtolower', $known_post_types))) { | |
$post_type = $custom_post_type; | |
DebugEcho("post type: found type '$post_type'"); | |
} else { | |
$post_type = 'post'; | |
} | |
} else { | |
$post_type = 'post'; | |
} | |
return $post_type; | |
} | |
/* | |
* Added by Raam Dev <raam@raamdev.com> | |
* Adds support for specifying Post Formats by adding the | |
* Post Format name to the email subject separated by | |
* $post_format_delim, e.g. "Aside :: My Example Post" | |
*/ | |
function tag_PostFormat(&$subject) { | |
$post_format_delim = "::"; | |
if (strpos($subject, $post_format_delim) !== FALSE) { | |
// Captures the post format in the subject before $post_format_delim | |
$separated_subject = explode($post_format_delim, $subject); | |
$post_format = $separated_subject[0]; | |
$subject = trim($separated_subject[1]); | |
DebugEcho("post format: found possible format '$post_format'"); | |
$post_format = trim(strtolower($post_format)); | |
// Check if post format exists, if not, set default post format of standard (no post format) | |
// Post formats are fixed; see http://codex.wordpress.org/Post_Formats#Supported_Formats | |
$known_post_formats = array('aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat'); | |
DebugDump($known_post_formats); | |
if (in_array($post_format, array_map('strtolower', $known_post_formats))) { | |
DebugEcho("post format: found format '$post_format'"); | |
} else { | |
// Blank post format is the Standard post format | |
$post_format = ''; | |
} | |
} else { | |
// Blank post format is the Standard post format | |
$post_format = ''; | |
} | |
return $post_format; | |
} | |
function filter_linkify($text) { | |
# It turns urls into links, and video urls into embedded players | |
//DebugEcho("begin: filter_linkify"); | |
$html = LoadDOM($text); | |
if ($html) { | |
//DebugEcho("filter_linkify: " . $html->save()); | |
foreach ($html->find('text') as $element) { | |
//DebugEcho("filter_linkify: " . $element->innertext); | |
$element->innertext = make_links($element->innertext); | |
} | |
$ret = $html->save(); | |
} else { | |
$ret = make_links($text); | |
} | |
//DebugEcho("end: filter_linkify"); | |
return $ret; | |
} | |
function LoadDOM($text) { | |
return str_get_html($text, true, true, DEFAULT_TARGET_CHARSET, false); | |
} | |
function filter_Videos($text, $shortcode = false) { | |
# It turns urls into links, and video urls into embedded players | |
//DebugEcho("begin: filter_Videos"); | |
$html = LoadDOM($text); | |
if ($html) { | |
foreach ($html->find('text') as $element) { | |
$element->innertext = linkifyVideo($element->innertext, $shortcode); | |
} | |
$ret = $html->save(); | |
} else { | |
$ret = linkifyVideo($text, $shortcode); | |
} | |
//DebugEcho("end: filter_Videos"); | |
return $ret; | |
} | |
function linkifyVideo($text, $shortcode = false) { | |
//$text = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1:", $text); | |
//DebugEcho("linkify1: $text"); | |
// pad it with a space so we can match things at the start of the 1st line. | |
$ret = ' ' . $text; | |
if (strpos($ret, 'youtube') !== false) { | |
// try to embed youtube videos | |
$youtube = "#(^|[\n ]|>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9-]+).*?([ \n]|$|<)#is"; | |
if ($shortcode) { | |
$youtube_replace = "\\1[youtube \\3]\\4"; | |
} else { | |
$youtube_replace = "\\1<embed width='425' height='344' allowfullscreen='true' allowscriptaccess='always' type='application/x-shockwave-flash' src='http://www.youtube.com/v/\\3&hl=en&fs=1' />\\4"; | |
} | |
$ret = preg_replace($youtube, $youtube_replace, $ret); | |
DebugEcho("youtube: $ret"); | |
} | |
if (strpos($ret, 'vimeo') !== false) { | |
// try to embed vimeo videos | |
# : http://vimeo.com/6348141 | |
$vimeo = "#(^|[\n ]|>)[\w]+?://(www\.)?vimeo\.com/([_a-zA-Z0-9-]+).*?([ \n]|$|<)#is"; | |
if ($shortcode) { | |
$vimeo_replace = "\\1[vimeo \\3]\\4"; | |
} else { | |
$vimeo_replace = "\\1<object width='400' height='300'><param name='allowfullscreen' value='true' /><param name='allowscriptaccess' value='always' /><param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=\\3&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1' /><embed src='http://vimeo.com/moogaloop.swf?clip_id=\\3&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' width='400' height='300'></embed></object>\\4"; | |
} | |
$ret = preg_replace($vimeo, $vimeo_replace, $ret); | |
DebugEcho("vimeo: $ret"); | |
} | |
// Remove our padding.. | |
$ret = substr($ret, 1); | |
return $ret; | |
} | |
function make_links($text) { | |
return preg_replace( | |
array( | |
'/(?(?=<a[^>]*>.+<\/a>) | |
(?:<a[^>]*>.+<\/a>) | |
| | |
([^="\']?)((?:https?|ftp|bf2|):\/\/[^<> \n\r]+) | |
)/iex', | |
'/<a([^>]*)target="?[^"\']+"?/i', | |
'/<a([^>]+)>/i', | |
'/(^|\s)(www.[^<> \n\r]+)/iex', | |
'/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+) | |
(\\.[A-Za-z0-9-]+)*)/iex' | |
), array( | |
"stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\">\\2</a>\\3':'\\0'))", | |
'<a\\1', | |
'<a\\1 >', | |
"stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\">\\2</a>\\3':'\\0'))", | |
"stripslashes((strlen('\\2')>0?'<a href=\"mailto:\\0\">\\0</a>':'\\0'))" | |
), $text | |
); | |
} | |
/* we check whether or not the e-mail is a forwards or a redirect. If it is | |
* a fwd, then we glean the author details from the body of the post. | |
* Otherwise we get them from the headers | |
*/ | |
function getPostAuthorDetails(&$subject, &$content, &$mimeDecodedEmail) { | |
global $wpdb; | |
$theDate = $mimeDecodedEmail->headers['date']; | |
$theEmail = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["from"])); | |
$regAuthor = get_user_by('email', $theEmail); | |
if ($regAuthor) { | |
$theAuthor = $regAuthor->user_login; | |
$theUrl = $regAuthor->user_url; | |
$theID = $regAuthor->ID; | |
} else { | |
$theAuthor = GetNameFromEmail($mimeDecodedEmail->headers['from']); | |
$theUrl = ''; | |
$theID = ''; | |
} | |
// see if subject starts with Fwd: | |
if (preg_match("/(^Fwd:) (.*)/", $subject, $matches)) { | |
DebugEcho("Fwd: detected"); | |
$subject = trim($matches[2]); | |
if (preg_match("/\nfrom:(.*?)\n/i", $content, $matches)) { | |
$theAuthor = GetNameFromEmail($matches[1]); | |
$mimeDecodedEmail->headers['from'] = $theAuthor; | |
} | |
if (preg_match("/\ndate:(.*?)\n/i", $content, $matches)) { | |
$theDate = $matches[1]; | |
DebugEcho("date in Fwd: $theDate"); | |
$mimeDecodedEmail->headers['date'] = $theDate; | |
} | |
// now get rid of forwarding info in the content | |
$lines = preg_split("/\r\n/", $content); | |
$newContents = ''; | |
foreach ($lines as $line) { | |
if (preg_match("/^(from|subject|to|date):.*?/i", $line, $matches) == 0 && preg_match("/^-+\s*forwarded\s*message\s*-+/i", $line, $matches) == 0) { | |
$newContents.=preg_replace("/\r/", "", $line) . "\n"; | |
} | |
} | |
$content = $newContents; | |
} | |
$theDetails = array( | |
'content' => "<div class='postmetadata alt'>On $theDate, $theAuthor" . | |
" posted:</div>", | |
'emaildate' => $theDate, | |
'author' => $theAuthor, | |
'comment_author_url' => $theUrl, | |
'user_ID' => $theID, | |
'email' => $theEmail | |
); | |
return $theDetails; | |
} | |
/* we check whether or not the e-mail is a reply to a previously | |
* published post. First we check whether it starts with Re:, and then | |
* we see if the remainder matches an already existing post. If so, | |
* then we add that post id to the details array, which will cause the | |
* existing post to be overwritten, instead of a new one being | |
* generated | |
*/ | |
function GetParentPostForReply(&$subject) { | |
global $wpdb; | |
$id = NULL; | |
// see if subject starts with Re: | |
if (preg_match("/(^Re:)(.*)/i", $subject, $matches)) { | |
$subject = trim($matches[2]); | |
// strip out category info into temporary variable | |
$tmpSubject = $subject; | |
if (preg_match('/(.+): (.*)/', $tmpSubject, $matches)) { | |
$tmpSubject = trim($matches[2]); | |
$matches[1] = array($matches[1]); | |
} else if (preg_match_all('/\[(.[^\[]*)\]/', $tmpSubject, $matches)) { | |
preg_match("/](.[^\[]*)$/", $tmpSubject, $tmpSubject_matches); | |
$tmpSubject = trim($tmpSubject_matches[1]); | |
} else if (preg_match_all('/-(.[^-]*)-/', $tmpSubject, $matches)) { | |
preg_match("/-(.[^-]*)$/", $tmpSubject, $tmpSubject_matches); | |
$tmpSubject = trim($tmpSubject_matches[1]); | |
} | |
$checkExistingPostQuery = "SELECT ID FROM $wpdb->posts WHERE '$tmpSubject' = post_title"; | |
if ($id = $wpdb->get_var($wpdb->prepare($checkExistingPostQuery, array()))) { | |
if (is_array($id)) { | |
$id = $id[count($id) - 1]; | |
} | |
} | |
} | |
return $id; | |
} | |
function postie_ShowReadMe() { | |
include(POSTIE_ROOT . DIRECTORY_SEPARATOR . "postie_read_me.php"); | |
} | |
/** | |
* This sets up the configuration menu | |
*/ | |
function PostieMenu() { | |
if (function_exists('add_options_page')) { | |
if (current_user_can('manage_options')) { | |
add_options_page("Postie", "Postie", 'manage_options', POSTIE_ROOT . "/postie.php", "ConfigurePostie"); | |
} | |
} | |
} | |
/** | |
* This handles actually showing the form. Called by WordPress | |
*/ | |
function ConfigurePostie() { | |
include(POSTIE_ROOT . DIRECTORY_SEPARATOR . "config_form.php"); | |
} | |
/** | |
* This function handles determining the protocol and fetching the mail | |
* @return array | |
*/ | |
function FetchMail($server = NULL, $port = NULL, $email = NULL, $password = NULL, $protocol = NULL, $offset = NULL, $test = NULL, $deleteMessages = true, $maxemails = 0) { | |
$emails = array(); | |
if (!$server || !$port || !$email) { | |
EchoInfo("Missing Configuration For Mail Server"); | |
return $emails; | |
} | |
if ($server == "pop.gmail.com") { | |
EchoInfo("MAKE SURE POP IS TURNED ON IN SETTING AT Gmail"); | |
} | |
switch (strtolower($protocol)) { | |
case 'smtp': //direct | |
$fd = fopen("php://stdin", "r"); | |
$input = ""; | |
while (!feof($fd)) { | |
$input .= fread($fd, 1024); | |
} | |
fclose($fd); | |
$emails[0] = $input; | |
break; | |
case 'imap': | |
case 'imap-ssl': | |
case 'pop3-ssl': | |
if (!HasIMAPSupport()) { | |
EchoInfo("Sorry - you do not have IMAP php module installed - it is required for this mail setting."); | |
} else { | |
$emails = IMAPMessageFetch($server, $port, $email, $password, $protocol, $offset, $test, $deleteMessages, $maxemails); | |
} | |
break; | |
case 'pop3': | |
default: | |
$emails = POP3MessageFetch($server, $port, $email, $password, $protocol, $offset, $test, $deleteMessages, $maxemails); | |
} | |
return $emails; | |
} | |
/** | |
* Handles fetching messages from an imap server | |
*/ | |
function IMAPMessageFetch($server = NULL, $port = NULL, $email = NULL, $password = NULL, $protocol = NULL, $offset = NULL, $test = NULL, $deleteMessages = true, $maxemails = 0) { | |
require_once("postieIMAP.php"); | |
$emails = array(); | |
$mail_server = &PostieIMAP::Factory($protocol); | |
EchoInfo("Connecting to $server:$port ($protocol)"); | |
if ($mail_server->connect($server, $port, $email, $password)) { | |
$msg_count = $mail_server->getNumberOfMessages(); | |
} else { | |
EchoInfo("Mail Connection Time Out"); | |
EchoInfo("Common Reasons: Server Down, Network Issue, Port/Protocol MisMatch "); | |
EchoInfo("The Server said:" . $mail_server->error()); | |
$msg_count = 0; | |
} | |
// loop through messages | |
for ($i = 1; $i <= $msg_count; $i++) { | |
$emails[$i] = $mail_server->fetchEmail($i); | |
if ($deleteMessages) { | |
$mail_server->deleteMessage($i); | |
} | |
if ($maxemails != 0 && $i >= $maxemails) { | |
DebugEcho("Max emails ($maxemails)"); | |
break; | |
} | |
} | |
if ($deleteMessages) { | |
$mail_server->expungeMessages(); | |
} | |
//clean up | |
$mail_server->disconnect(); | |
return $emails; | |
} | |
/** | |
* Retrieves email via POP3 | |
*/ | |
function POP3MessageFetch($server = NULL, $port = NULL, $email = NULL, $password = NULL, $protocol = NULL, $offset = NULL, $test = NULL, $deleteMessages = true, $maxemails = 0) { | |
require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'class-pop3.php'); | |
$emails = array(); | |
$pop3 = new POP3(); | |
EchoInfo("Connecting to $server:$port ($protocol)"); | |
if ($pop3->connect($server, $port)) { | |
$msg_count = $pop3->login($email, $password); | |
if ($msg_count === false) { | |
$msg_count = 0; | |
} | |
} else { | |
if (strpos($pop3->ERROR, "POP3: premature NOOP OK, NOT an RFC 1939 Compliant server") === false) { | |
EchoInfo("Mail Connection Time Out. Common Reasons: Server Down, Network Issue, Port/Protocol MisMatch"); | |
} | |
EchoInfo("The Server said: $pop3->ERROR"); | |
$msg_count = 0; | |
} | |
DebugEcho("message count: $msg_count"); | |
// loop through messages | |
//$msgs = $pop3->pop_list(); | |
//DebugEcho("POP3MessageFetch: messages"); | |
//DebugDump($msgs); | |
for ($i = 1; $i <= $msg_count; $i++) { | |
$m = $pop3->get($i); | |
if ($m !== false) { | |
if (is_array($m)) { | |
$emails[$i] = implode('', $m); | |
if ($deleteMessages) { | |
if (!$pop3->delete($i)) { | |
EchoInfo('POP3MessageFetch: cannot delete message $i ' . $pop3->ERROR); | |
$pop3->reset(); | |
exit; | |
} | |
} | |
} else { | |
DebugEcho("POP3MessageFetch: message $i not an array"); | |
} | |
} else { | |
EchoInfo("POP3MessageFetch: message $i $pop3->ERROR"); | |
} | |
if ($maxemails != 0 && $i >= $maxemails) { | |
DebugEcho("Max emails ($maxemails)"); | |
break; | |
} | |
} | |
//clean up | |
$pop3->quit(); | |
return $emails; | |
} | |
/** | |
* This function handles putting the actual entry into the database | |
* @param array - categories to be posted to | |
* @param array - details of the post | |
*/ | |
function PostToDB($details, $isReply, $postToDb = true, $customImageField = false) { | |
if ($postToDb) { | |
if (!$isReply) { | |
$post_ID = wp_insert_post($details, true); | |
if (is_wp_error($post_ID)) { | |
EchoInfo("Error: " . $post_ID->get_error_message()); | |
wp_delete_post($details['ID']); | |
} | |
/* Added by Raam Dev <raam@raamdev.com> */ | |
set_post_format($post_ID , $details['post_format']); | |
} else { | |
$comment = array( | |
'comment_author' => $details['comment_author'], | |
'comment_post_ID' => $details['ID'], | |
'comment_author_email' => $details['email_author'], | |
'comment_date' => $details['post_date'], | |
'comment_date_gmt' => $details['post_date_gmt'], | |
'comment_content' => $details['post_content'], | |
'comment_author_url' => $details['comment_author_url'], | |
'comment_author_IP' => '', | |
'comment_approved' => 1, | |
'comment_agent' => '', | |
'comment_type' => '', | |
'comment_parent' => 0, | |
'user_id' => $details['user_ID'] | |
); | |
$post_ID = wp_insert_comment($comment); | |
} | |
if ($customImageField && $post_ID) { | |
DebugEcho("Saving custom image fields"); | |
//DebugDump($details['customImages']); | |
if (count($details['customImages']) > 1) { | |
$imageField = 1; | |
foreach ($details['customImages'] as $image) { | |
add_post_meta($post_ID, 'image' . $imageField, $image); | |
$imageField++; | |
} | |
} | |
} | |
} | |
} | |
/** | |
* This function determines if the mime attachment is on the BANNED_FILE_LIST | |
* @param string | |
* @return boolean | |
*/ | |
function isBannedFileName($filename, $bannedFiles) { | |
if (empty($filename) || empty($bannedFiles)) | |
return false; | |
foreach ($bannedFiles as $bannedFile) { | |
if (fnmatch($bannedFile, $filename)) { | |
EchoInfo("Ignoring attachment: $filename - it is on the banned files list."); | |
return true; | |
} | |
} | |
return false; | |
} | |
function GetContent($part, &$attachments, $post_id, $poster, $config) { | |
extract($config); | |
//global $charset, $encoding; | |
DebugEcho('----'); | |
$meta_return = ''; | |
DebugEcho("primary= " . $part->ctype_primary . ", secondary = " . $part->ctype_secondary); | |
DecodeBase64Part($part); | |
//look for banned file names | |
if (property_exists($part, 'ctype_parameters') && is_array($part->ctype_parameters) && array_key_exists('name', $part->ctype_parameters)) | |
if (isBannedFileName($part->ctype_parameters['name'], $banned_files_list)) | |
return NULL; | |
if ($part->ctype_primary == "application" && $part->ctype_secondary == "octet-stream") { | |
if (property_exists($part, 'disposition') && $part->disposition == "attachment") { | |
$image_endings = array("jpg", "png", "gif", "jpeg", "pjpeg"); | |
foreach ($image_endings as $type) { | |
if (preg_match("/.$type\$/i", $part->d_parameters["filename"])) { | |
$part->ctype_primary = "image"; | |
$part->ctype_secondary = $type; | |
break; | |
} | |
} | |
} else { | |
$mimeDecodedEmail = DecodeMIMEMail($part->body); | |
filter_PreferedText($mimeDecodedEmail, $prefer_text_type); | |
foreach ($mimeDecodedEmail->parts as $section) { | |
$meta_return .= GetContent($section, $attachments, $post_id, $poster, $config); | |
} | |
} | |
} | |
if ($part->ctype_primary == "multipart" && $part->ctype_secondary == "appledouble") { | |
DebugEcho("multipart appledouble"); | |
$mimeDecodedEmail = DecodeMIMEMail("Content-Type: multipart/mixed; boundary=" . $part->ctype_parameters["boundary"] . "\n" . $part->body); | |
filter_PreferedText($mimeDecodedEmail, $prefer_text_type); | |
filter_AppleFile($mimeDecodedEmail); | |
foreach ($mimeDecodedEmail->parts as $section) { | |
$meta_return .= GetContent($section, $attachments, $post_id, $poster, $config); | |
} | |
} else { | |
$filename = ""; | |
if (property_exists($part, 'ctype_parameters') && is_array($part->ctype_parameters) && array_key_exists('name', $part->ctype_parameters)) { | |
// fix filename (remove non-standard characters) | |
//$filename = preg_replace("/[^\x9\xA\xD\x20-\x7F]/", "", $part->ctype_parameters['name']); | |
$filename = $part->ctype_parameters['name']; | |
} elseif (property_exists($part, 'd_parameters') && is_array($part->d_parameters) && array_key_exists('filename', $part->d_parameters)) { | |
$filename = $part->d_parameters['filename']; | |
} | |
DebugEcho("Filename: $filename"); | |
switch (strtolower($part->ctype_primary)) { | |
case 'multipart': | |
DebugEcho("multipart: " . count($part->parts)); | |
//DebugDump($part); | |
filter_PreferedText($part, $prefer_text_type); | |
foreach ($part->parts as $section) { | |
//DebugDump($section->headers); | |
$meta_return .= GetContent($section, $attachments, $post_id, $poster, $config); | |
} | |
break; | |
case 'text': | |
DebugEcho("ctype_primary: text"); | |
//DebugDump($part); | |
$charset = ""; | |
if (property_exists($part, 'ctype_parameters') && array_key_exists('charset', $part->ctype_parameters) && !empty($part->ctype_parameters['charset'])) { | |
$charset = $part->ctype_parameters['charset']; | |
DebugEcho("charset: $charset"); | |
} | |
$encoding = ""; | |
if (array_key_exists('content-transfer-encoding', $part->headers) && !empty($part->headers['content-transfer-encoding'])) { | |
$encoding = $part->headers['content-transfer-encoding']; | |
DebugEcho("encoding: $encoding"); | |
} | |
if (array_key_exists('content-transfer-encoding', $part->headers)) { | |
//DebugDump($part); | |
$part->body = HandleMessageEncoding($encoding, $charset, $part->body, $message_encoding, $message_dequote); | |
if (!empty($charset)) { | |
$part->ctype_parameters['charset'] = ""; //reset so we don't double decode | |
} | |
//DebugDump($part); | |
} | |
if (array_key_exists('disposition', $part) && $part->disposition == 'attachment') { | |
DebugEcho("text Attachement: $filename"); | |
if (!preg_match('/ATT\d\d\d\d\d.txt/i', $filename)) { | |
$file_id = postie_media_handle_upload($part, $post_id, $poster); | |
if (!is_wp_error($file_id)) { | |
$file = wp_get_attachment_url($file_id); | |
$icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size); | |
$attachments["html"][$filename] = "<a href='$file'>" . $icon . $filename . '</a>' . "\n"; | |
} else { | |
LogInfo($file_id->get_error_message()); | |
} | |
} else { | |
DebugEcho("text attachment: skipping"); | |
} | |
} else { | |
//go through each sub-section | |
if ($part->ctype_secondary == 'enriched') { | |
//convert enriched text to HTML | |
DebugEcho("enriched"); | |
$meta_return .= filter_etf2HTML($part->body) . "\n"; | |
} elseif ($part->ctype_secondary == 'html') { | |
//strip excess HTML | |
DebugEcho("html"); | |
$meta_return .= filter_CleanHtml($part->body) . "\n"; | |
} elseif ($part->ctype_secondary == 'plain') { | |
DebugEcho("plain text"); | |
//DebugDump($part); | |
DebugEcho("body text"); | |
if ($allow_html_in_body) { | |
DebugEcho("html allowed"); | |
$meta_return .= $part->body; | |
//$meta_return = "<div>$meta_return</div>\n"; | |
} else { | |
DebugEcho("html not allowed (htmlentities)"); | |
$meta_return .= htmlentities($part->body); | |
} | |
$meta_return = filter_StripPGP($meta_return); | |
//DebugEcho("meta return: $meta_return"); | |
} else { | |
DebugEcho("text Attachement wo disposition: $filename"); | |
$file_id = postie_media_handle_upload($part, $post_id, $poster); | |
if (!is_wp_error($file_id)) { | |
$file = wp_get_attachment_url($file_id); | |
$icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size); | |
$attachments["html"][$filename] = "<a href='$file'>" . $icon . $filename . '</a>' . "\n"; | |
} else { | |
LogInfo($file_id->get_error_message()); | |
} | |
} | |
} | |
break; | |
case 'image': | |
DebugEcho("image Attachement: $filename"); | |
$file_id = postie_media_handle_upload($part, $post_id, $poster); | |
if (!is_wp_error($file_id)) { | |
$file = wp_get_attachment_url($file_id); | |
$cid = ""; | |
if (array_key_exists('content-id', $part->headers)) { | |
$cid = trim($part->headers["content-id"], "<>"); | |
DebugEcho("found cid: $cid"); | |
} | |
$the_post = get_post($file_id); | |
$attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary, $imagetemplate, $filename); | |
if ($cid) { | |
$attachments["cids"][$cid] = array($file, count($attachments["html"]) - 1); | |
DebugEcho("CID Attachement: $cid"); | |
} | |
} else { | |
LogInfo("image error: " . $file_id->get_error_message()); | |
} | |
break; | |
case 'audio': | |
//DebugDump($part->headers); | |
DebugEcho("audio Attachement: $filename"); | |
$file_id = postie_media_handle_upload($part, $post_id, $poster); | |
if (!is_wp_error($file_id)) { | |
$file = wp_get_attachment_url($file_id); | |
$cid = ""; | |
if (array_key_exists('content-id', $part->headers)) { | |
$cid = trim($part->headers["content-id"], "<>"); | |
DebugEcho("audio Attachement cid: $cid"); | |
} | |
if (in_array($part->ctype_secondary, $audiotypes)) { | |
DebugEcho("using audio template: $part->ctype_secondary"); | |
$audioTemplate = $audiotemplate; | |
} else { | |
DebugEcho("using default audio template: $part->ctype_secondary"); | |
$icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size); | |
$audioTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>'; | |
} | |
$attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary, $audioTemplate, $filename); | |
} else { | |
LogInfo("audio error: " . $file_id->get_error_message()); | |
} | |
break; | |
case 'video': | |
DebugEcho("video Attachement: $filename"); | |
$file_id = postie_media_handle_upload($part, $post_id, $poster); | |
if (!is_wp_error($file_id)) { | |
$file = wp_get_attachment_url($file_id); | |
$cid = ""; | |
if (array_key_exists('content-id', $part->headers)) { | |
$cid = trim($part->headers["content-id"], "<>"); | |
DebugEcho("video Attachement cid: $cid"); | |
} | |
//DebugDump($part); | |
if (in_array(strtolower($part->ctype_secondary), $video1types)) { | |
DebugEcho("using video1 template: $part->ctype_secondary"); | |
$videoTemplate = $video1template; | |
} elseif (in_array(strtolower($part->ctype_secondary), $video2types)) { | |
DebugEcho("using video2 template: $part->ctype_secondary"); | |
$videoTemplate = $video2template; | |
} else { | |
DebugEcho("using default template: $part->ctype_secondary"); | |
$icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size); | |
$videoTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>'; | |
} | |
$attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary, $videoTemplate, $filename); | |
//echo "videoTemplate = $videoTemplate\n"; | |
} else { | |
LogInfo($file_id->get_error_message()); | |
} | |
break; | |
default: | |
DebugEcho("found file type: " . $part->ctype_primary); | |
if (in_array(strtolower($part->ctype_primary), $supported_file_types)) { | |
//pgp signature - then forget it | |
if ($part->ctype_secondary == 'pgp-signature') { | |
DebugEcho("found pgp-signature - done"); | |
break; | |
} | |
$file_id = postie_media_handle_upload($part, $post_id, $poster); | |
if (!is_wp_error($file_id)) { | |
$file = wp_get_attachment_url($file_id); | |
DebugEcho("uploaded $file_id ($file)"); | |
$icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size); | |
DebugEcho("default: $icon $filename"); | |
$attachments["html"][$filename] = "<a href='$file'>" . $icon . $filename . '</a>' . "\n"; | |
if (array_key_exists('content-id', $part->headers)) { | |
$cid = trim($part->headers["content-id"], "<>"); | |
if ($cid) { | |
$attachments["cids"][$cid] = array($file, count($attachments["html"]) - 1); | |
} | |
} else { | |
DebugEcho("No content-id"); | |
} | |
} else { | |
LogInfo($file_id->get_error_message()); | |
} | |
} else { | |
DebugEcho("Not in supported filetype list"); | |
DebugDump($supported_file_types); | |
} | |
break; | |
} | |
} | |
DebugEcho("meta_return: " . substr($meta_return, 0, 500)); | |
DebugEcho("===="); | |
return $meta_return; | |
} | |
function filter_ubb2HTML(&$text) { | |
// Array of tags with opening and closing | |
$tagArray['img'] = array('open' => '<img src="', 'close' => '">'); | |
$tagArray['b'] = array('open' => '<b>', 'close' => '</b>'); | |
$tagArray['i'] = array('open' => '<i>', 'close' => '</i>'); | |
$tagArray['u'] = array('open' => '<u>', 'close' => '</u>'); | |
$tagArray['url'] = array('open' => '<a href="', 'close' => '">\\1</a>'); | |
$tagArray['email'] = array('open' => '<a href="mailto:', 'close' => '">\\1</a>'); | |
$tagArray['url=(.*)'] = array('open' => '<a href="', 'close' => '">\\2</a>'); | |
$tagArray['email=(.*)'] = array('open' => '<a href="mailto:', 'close' => '">\\2</a>'); | |
$tagArray['color=(.*)'] = array('open' => '<font color="', 'close' => '">\\2</font>'); | |
$tagArray['size=(.*)'] = array('open' => '<font size="', 'close' => '">\\2</font>'); | |
$tagArray['font=(.*)'] = array('open' => '<font face="', 'close' => '">\\2</font>'); | |
// Array of tags with only one part | |
$sTagArray['br'] = array('tag' => '<br>'); | |
$sTagArray['hr'] = array('tag' => '<hr>'); | |
foreach ($tagArray as $tagName => $replace) { | |
$tagEnd = preg_replace('/\W/Ui', '', $tagName); | |
$text = preg_replace("|\[$tagName\](.*)\[/$tagEnd\]|Ui", "$replace[open]\\1$replace[close]", $text); | |
} | |
foreach ($sTagArray as $tagName => $replace) { | |
$text = preg_replace("|\[$tagName\]|Ui", "$replace[tag]", $text); | |
} | |
return $text; | |
} | |
// This function turns Enriched Text into something similar to HTML | |
// Very basic at the moment, only supports some functionality and dumps the rest | |
// FIXME: fix colours: <color><param>FFFF,C2FE,0374</param>some text </color> | |
function filter_etf2HTML($content) { | |
$search = array( | |
'/<bold>/', | |
'/<\/bold>/', | |
'/<underline>/', | |
'/<\/underline>/', | |
'/<italic>/', | |
'/<\/italic>/', | |
'/<fontfamily><param>.*<\/param>/', | |
'/<\/fontfamily>/', | |
'/<x-tad-bigger>/', | |
'/<\/x-tad-bigger>/', | |
'/<bigger>/', | |
'</bigger>/', | |
'/<color>/', | |
'/<\/color>/', | |
'/<param>.+<\/param>/' | |
); | |
$replace = array( | |
'<b>', | |
'</b>', | |
'<u>', | |
'</u>', | |
'<i>', | |
'</i>', | |
'', | |
'', | |
'', | |
'', | |
'', | |
'', | |
'', | |
'', | |
'' | |
); | |
// strip extra line breaks | |
$content = preg_replace($search, $replace, $content); | |
return trim($content); | |
} | |
// This function cleans up HTML in the e-mail | |
function filter_CleanHtml($content) { | |
$html = str_get_html($content); | |
if ($html) { | |
DebugEcho("Looking for invalid tags"); | |
foreach ($html->find('script, style, head') as $node) { | |
DebugEcho("Removing: " . $node->outertext); | |
$node->outertext = ''; | |
} | |
$html->load($html->save()); | |
$b = $html->find('body'); | |
if ($b) { | |
$content = "<div>" . $b[0]->innertext . "</div>\n"; | |
} | |
} else { | |
DebugEcho("No HTML found"); | |
} | |
return $content; | |
} | |
/** | |
* Determines if the sender is a valid user. | |
* @return integer|NULL | |
*/ | |
function ValidatePoster(&$mimeDecodedEmail, $config) { | |
$test_email = ''; | |
extract($config); | |
global $wpdb; | |
$poster = NULL; | |
$from = ""; | |
if (array_key_exists('from', $mimeDecodedEmail->headers)) { | |
$from = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["from"])); | |
} else { | |
DebugEcho("No 'from' header found"); | |
DebugDump($mimeDecodedEmail->headers); | |
} | |
$resentFrom = ""; | |
if (array_key_exists('resent-from', $mimeDecodedEmail->headers)) { | |
$resentFrom = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["resent-from"])); | |
} | |
//See if the email address is one of the special authorized ones | |
if (!empty($from)) { | |
EchoInfo("Confirming Access For $from "); | |
$sql = 'SELECT id FROM ' . $wpdb->users . ' WHERE user_email=\'' . addslashes($from) . "' LIMIT 1;"; | |
$user_ID = $wpdb->get_var($sql); | |
} else { | |
$user_ID = ""; | |
} | |
if (!empty($user_ID)) { | |
$user = new WP_User($user_ID); | |
if ($user->has_cap("post_via_postie")) { | |
$poster = $user_ID; | |
EchoInfo("posting as user $poster"); | |
} else { | |
$poster = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_login = '$admin_username'"); | |
} | |
} elseif ($turn_authorization_off || isEmailAddressAuthorized($from, $authorized_addresses) || isEmailAddressAuthorized($resentFrom, $authorized_addresses)) { | |
$poster = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_login = '$admin_username'"); | |
} | |
$validSMTP = isValidSmtpServer($mimeDecodedEmail, $smtp); | |
if (!$poster || !$validSMTP) { | |
EchoInfo('Invalid sender: ' . htmlentities($from) . "! Not adding email!"); | |
if ($forward_rejected_mail) { | |
$admin_email = get_option("admin_email"); | |
if (MailToRecipients($mimeDecodedEmail, $test_email, array($admin_email), $return_to_sender)) { | |
EchoInfo("A copy of the message has been forwarded to the administrator."); | |
} else { | |
EchoInfo("The message was unable to be forwarded to the adminstrator."); | |
} | |
} | |
return ''; | |
} | |
return $poster; | |
} | |
function isValidSmtpServer($mimeDecodedEmail, $smtpservers) { | |
if (empty($smtpservers)) | |
return true; | |
foreach ((array) $mimeDecodedEmail->headers['received'] as $received) { | |
foreach ($smtpservers as $smtp) { | |
if (stristr($received, $smtp) !== false) { | |
EchoInfo("Sent from valid SMTP server."); | |
return true; | |
} | |
} | |
} | |
EchoInfo("Sent from invalid SMTP server."); | |
return false; | |
} | |
/** | |
* Looks at the content for the start of the message and removes everything before that | |
* If the pattern is not found everything is returned | |
* @param string | |
* @param string | |
*/ | |
function filter_Start(&$content, $config) { | |
$start = $config['message_start']; | |
if ($start) { | |
$pos = strpos($content, $start); | |
if ($pos === false) { | |
return $content; | |
} | |
DebugEcho("start filter $start"); | |
$content = substr($content, $pos + strlen($start), strlen($content)); | |
} | |
} | |
/** | |
* Looks at the content for the start of the signature and removes all text | |
* after that point | |
* @param string | |
* @param array - a list of patterns to determine if it is a sig block | |
*/ | |
function filter_RemoveSignature(&$content, $config) { | |
if ($config['drop_signature']) { | |
if (empty($config['sig_pattern_list'])) | |
return; | |
//DebugEcho("looking for signature in: $content"); | |
$pattern = '/^(' . implode('|', $config['sig_pattern_list']) . ')\s?$/m'; | |
DebugEcho("sig pattern: $pattern"); | |
$html = LoadDOM($content); | |
if ($html !== false) { | |
filter_RemoveSignatureWorker($html->root, $pattern); | |
$content = $html->save(); | |
} else { | |
DebugEcho("sig non-html"); | |
$arrcontent = explode("\n", $content); | |
$strcontent = ''; | |
for ($i = 0; $i < count($arrcontent); $i++) { | |
$line = trim($arrcontent[$i]); | |
if (preg_match($pattern, trim($line))) { | |
DebugEcho("signature found: removing"); | |
break; | |
} | |
$strcontent .= $line; | |
} | |
$content = $strcontent; | |
} | |
} | |
} | |
function filter_RemoveSignatureWorker(&$html, $pattern) { | |
$found = false; | |
if (preg_match($pattern, trim($html->plaintext), $matches)) { | |
DebugEcho("signature found in base: removing"); | |
DebugDump($matches); | |
$found = true; | |
$i = stripos($html->innertext, $matches[1]); | |
$presig = substr($html->innertext, 0, $i); | |
DebugEcho("sig new text: '$presig'"); | |
$html->innertext = $presig; | |
} | |
foreach ($html->children() as $e) { | |
//DebugEcho("sig: " . $e->plaintext); | |
if (!$found && preg_match($pattern, trim($e->plaintext))) { | |
DebugEcho("signature found: removing"); | |
$found = true; | |
} | |
if ($found) { | |
$e->outertext = ''; | |
} else { | |
$found = filter_RemoveSignatureWorker($e, $pattern); | |
} | |
} | |
return $found; | |
} | |
/** | |
* Looks at the content for the given tag and removes all text | |
* after that point | |
* @param string | |
* @param filter | |
*/ | |
function filter_End(&$content, $config) { | |
$end = $config['message_end']; | |
if ($end) { | |
$pos = strpos($content, $end); | |
if ($pos === false) | |
return $content; | |
DebugEcho("end filter: $end"); | |
$content = substr($content, 0, $pos); | |
} | |
} | |
//filter content for new lines | |
function filter_newlines(&$content, $config) { | |
if ($config['filternewlines']) { | |
$search = array( | |
"/\r\n/", | |
"/\n\n/", | |
"/\r\n\r\n/", | |
"/\r/", | |
"/\n/" | |
); | |
$replace = array( | |
"LINEBREAK", | |
"LINEBREAK", | |
'LINEBREAK', | |
'LINEBREAK', | |
'LINEBREAK' | |
); | |
$result = preg_replace($search, $replace, $content); | |
if ($config['convertnewline']) { | |
$content = preg_replace('/(LINEBREAK)/', "<br />\n", $result); | |
} else { | |
$content = preg_replace('/(LINEBREAK)/', " ", $result); | |
} | |
} | |
} | |
//strip pgp stuff | |
function filter_StripPGP($content) { | |
$search = array( | |
'/-----BEGIN PGP SIGNED MESSAGE-----/', | |
'/Hash: SHA1/' | |
); | |
$replace = array( | |
' ', | |
'' | |
); | |
return preg_replace($search, $replace, $content); | |
} | |
function ConvertUTF8ToISO_8859_1($contenttransferencoding, $currentcharset, $body) { | |
if ((strtolower($currentcharset) != 'iso-8859-1')) { | |
$contenttransferencoding = strtolower($contenttransferencoding); | |
if ($contenttransferencoding == 'base64') { | |
$body = utf8_decode($body); | |
} | |
if ($contenttransferencoding == 'quoted-printable') { | |
$body = iconv($currentcharset, "UTF-8//TRANSLIT", quoted_printable_decode($body)); | |
} | |
} | |
return $body; | |
} | |
function HandleMessageEncoding($contenttransferencoding, $charset, $body, $blogEncoding = 'utf-8', $dequote = true) { | |
$charset = strtolower($charset); | |
$contenttransferencoding = strtolower($contenttransferencoding); | |
DebugEcho("before HandleMessageEncoding"); | |
DebugEcho("charset: $charset"); | |
DebugEcho("encoding: $contenttransferencoding"); | |
//DebugDump($body); | |
if ($contenttransferencoding == 'base64') { | |
DebugEcho("HandleMessageEncoding: base64 detected"); | |
$body = base64_decode($body); | |
} | |
if ($dequote && $contenttransferencoding == 'quoted-printable') { | |
DebugEcho("quoted-printable detected"); | |
$body = quoted_printable_decode($body); | |
} | |
DebugEcho("after HandleMessageEncoding"); | |
if (!empty($charset) && strtolower($charset) != 'default' && strtolower($charset) != strtolower($blogEncoding)) { | |
DebugEcho("converting from $charset to $blogEncoding"); | |
//DebugEcho("before: $body"); | |
$body = iconv($charset, $blogEncoding . '//TRANSLIT', $body); | |
//DebugEcho("after: $body"); | |
} | |
return $body; | |
} | |
function ConvertToUTF_8($charset, $body) { | |
DebugEcho("convert to utf-8"); | |
return iconv($charset, "UTF-8//TRANSLIT", $body); | |
} | |
/** | |
* This function handles decoding base64 if needed | |
*/ | |
function DecodeBase64Part(&$part) { | |
if (array_key_exists('content-transfer-encoding', $part->headers)) { | |
if (strtolower($part->headers['content-transfer-encoding']) == 'base64') { | |
DebugEcho("DecodeBase64Part: base64 detected"); | |
//DebugDump($part); | |
if (isset($part->disposition) && $part->disposition == 'attachment') { | |
$part->body = base64_decode($part->body); | |
} else if (is_array($part->ctype_parameters) && array_key_exists('charset', $part->ctype_parameters)) { | |
$part->body = iconv($part->ctype_parameters['charset'], 'UTF-8//TRANSLIT', base64_decode($part->body)); | |
DebugEcho("convertef from: " . $part->ctype_parameters['charset']); | |
$part->ctype_parameters['charset'] = 'default'; //so we don't double decode | |
} else { | |
$part->body = base64_decode($part->body); | |
} | |
$part->headers['content-transfer-encoding'] = ''; | |
} | |
} | |
} | |
/** | |
* Checks for the comments tag | |
* @return boolean | |
*/ | |
function tag_AllowCommentsOnPost(&$content) { | |
$comments_allowed = get_option('default_comment_status'); // 'open' or 'closed' | |
if (preg_match("/comments:([0|1|2])/i", $content, $matches)) { | |
$content = preg_replace("/comments:$matches[1]/i", "", $content); | |
if ($matches[1] == "1") { | |
$comments_allowed = "open"; | |
} else if ($matches[1] == "2") { | |
$comments_allowed = "registered_only"; | |
} else { | |
$comments_allowed = "closed"; | |
} | |
} | |
return $comments_allowed; | |
} | |
/** | |
* Needed to be able to modify the content to remove the usage of the delay tag | |
* | |
* todo split delay tag from date logic | |
*/ | |
function filter_Delay(&$content, $message_date = NULL, $offset = 0) { | |
$delay = 0; | |
if (preg_match("/delay:(-?[0-9dhm]+)/i", $content, $matches) && trim($matches[1])) { | |
DebugEcho("found delay: " . $matches[1]); | |
$days = 0; | |
$hours = 0; | |
$minutes = 0; | |
if (preg_match("/(-?[0-9]+)d/i", $matches[1], $dayMatches)) { | |
$days = $dayMatches[1]; | |
} | |
if (preg_match("/(-?[0-9]+)h/i", $matches[1], $hourMatches)) { | |
$hours = $hourMatches[1]; | |
} | |
if (preg_match("/(-?[0-9]+)m/i", $matches[1], $minuteMatches)) { | |
$minutes = $minuteMatches[1]; | |
} | |
$delay = (($days * 24 + $hours) * 60 + $minutes) * 60; | |
DebugEcho("calculated delay: $delay"); | |
$content = preg_replace("/delay:$matches[1]/i", "", $content); | |
} | |
if (empty($message_date)) { | |
$dateInSeconds = time(); | |
} else { | |
$dateInSeconds = strtotime($message_date); | |
} | |
$dateInSeconds += $delay; | |
$post_date = gmdate('Y-m-d H:i:s', $dateInSeconds + ($offset * 3600)); | |
$post_date_gmt = gmdate('Y-m-d H:i:s', $dateInSeconds); | |
DebugEcho("post date: $post_date / $post_date_gmt"); | |
return array($post_date, $post_date_gmt, $delay); | |
} | |
/** | |
* This function takes the content of the message - looks for a subject at the begining surrounded by # and then removes that from the content | |
*/ | |
function tag_subject($content, $defaultTitle) { | |
DebugEcho("Looking for subject in email body"); | |
if (substr($content, 0, 1) != "#") { | |
DebugEcho("No subject found, using default [1]"); | |
return(array($defaultTitle, $content)); | |
} | |
$subjectEndIndex = strpos($content, "#", 1); | |
if (!$subjectEndIndex > 0) { | |
DebugEcho("No subject found, using default [2]"); | |
return(array($defaultTitle, $content)); | |
} | |
$subject = substr($content, 1, $subjectEndIndex - 1); | |
$content = substr($content, $subjectEndIndex + 1, strlen($content)); | |
return array($subject, $content); | |
} | |
/** | |
* This method sorts thru the mime parts of the message. It is looking for files labeled - "applefile" - current | |
* this part of the file attachment is not supported | |
* @param object | |
*/ | |
function filter_AppleFile(&$mimeDecodedEmail) { | |
$newParts = array(); | |
$found = false; | |
for ($i = 0; $i < count($mimeDecodedEmail->parts); $i++) { | |
if ($mimeDecodedEmail->parts[$i]->ctype_secondary == "applefile") { | |
$found = true; | |
LogInfo("Removing 'applefile'"); | |
} else { | |
$newParts[] = $mimeDecodedEmail->parts[$i]; | |
} | |
} | |
if ($found && $newParts) { | |
$mimeDecodedEmail->parts = $newParts; //This is now the filtered list of just the preferred type. | |
} | |
} | |
function postie_media_handle_upload($part, $post_id, $poster, $post_data = array()) { | |
$overrides = array('test_form' => false); | |
$tmpFile = tempnam(get_temp_dir(), 'postie'); | |
$fp = fopen($tmpFile, 'w'); | |
if ($fp) { | |
fwrite($fp, $part->body); | |
fclose($fp); | |
} else { | |
EchoInfo("could not write to temp file: '$tmpFile' "); | |
} | |
$name = 'postie-media.' . $part->ctype_secondary; | |
if (property_exists($part, 'ctype_parameters') && is_array($part->ctype_parameters)) { | |
if (array_key_exists('name', $part->ctype_parameters) && $part->ctype_parameters['name'] != '') { | |
$name = $part->ctype_parameters['name']; | |
} | |
if (array_key_exists('filename', $part->ctype_parameters) && $part->ctype_parameters['filename'] != '') { | |
$name = $part->ctype_parameters['filename']; | |
} | |
} | |
if (property_exists($part, 'd_parameters') && is_array($part->d_parameters) && array_key_exists('filename', $part->d_parameters) && $part->d_parameters['filename'] != '') { | |
$name = $part->d_parameters['filename']; | |
} | |
DebugEcho("name: $name, size: " . filesize($tmpFile)); | |
//DebugDump($part); | |
$the_file = array('name' => $name, | |
'tmp_name' => $tmpFile, | |
'size' => filesize($tmpFile), | |
'error' => '' | |
); | |
if (stristr('.zip', $name)) { | |
DebugEcho("exploding zip file"); | |
$parts = explode('.', $name); | |
$ext = $parts[count($parts) - 1]; | |
$type = $part->primary . '/' . $part->secondary; | |
$the_file['ext'] = $ext; | |
$the_file['type'] = $type; | |
$overrides['test_type'] = false; | |
} | |
$time = current_time('mysql'); | |
$post = get_post($post_id); | |
if (substr($post->post_date, 0, 4) > 0) { | |
DebugEcho("using post date"); | |
$time = $post->post_date; | |
} | |
$file = postie_handle_upload($the_file, $overrides, $time); | |
//unlink($tmpFile); | |
if (isset($file['error'])) { | |
DebugDump($file['error']); | |
//throw new Exception($file['error']); | |
return new WP_Error('upload_error', $file['error']); | |
} | |
$url = $file['url']; | |
$type = $file['type']; | |
$file = $file['file']; | |
$title = preg_replace('/\.[^.]+$/', '', basename($file)); | |
$content = ''; | |
// use image exif/iptc data for title and caption defaults if possible | |
if (file_exists(ABSPATH . '/wp-admin/includes/image.php')) { | |
include_once(ABSPATH . '/wp-admin/includes/image.php'); | |
if ($image_meta = @wp_read_image_metadata($file)) { | |
if (trim($image_meta['title'])) { | |
$title = $image_meta['title']; | |
DebugEcho("Using metadata title: $title"); | |
} | |
if (trim($image_meta['caption'])) { | |
$content = $image_meta['caption']; | |
DebugEcho("Using metadata caption: $caption"); | |
} | |
} | |
} | |
// Construct the attachment array | |
$attachment = array_merge(array( | |
'post_mime_type' => $type, | |
'guid' => $url, | |
'post_parent' => $post_id, | |
'post_title' => $title, | |
'post_excerpt' => $content, | |
'post_content' => $content, | |
'post_author' => $poster | |
), $post_data); | |
// Save the data | |
$id = wp_insert_attachment($attachment, $file, $post_id); | |
DebugEcho("attachement id: $id"); | |
if (!is_wp_error($id)) { | |
$amd = wp_generate_attachment_metadata($id, $file); | |
DebugEcho("wp_generate_attachment_metadata"); | |
DebugDump($amd); | |
wp_update_attachment_metadata($id, $amd); | |
DebugEcho("wp_update_attachment_metadata complete"); | |
} else { | |
EchoInfo("There was an error adding the attachement: " . $id->get_error_message()); | |
} | |
return $id; | |
} | |
function postie_handle_upload(&$file, $overrides = false, $time = null) { | |
// The default error handler. | |
if (!function_exists('wp_handle_upload_error')) { | |
function wp_handle_upload_error(&$file, $message) { | |
return array('error' => $message); | |
} | |
} | |
// You may define your own function and pass the name in $overrides['upload_error_handler'] | |
$upload_error_handler = 'wp_handle_upload_error'; | |
// $_POST['action'] must be set and its value must equal $overrides['action'] or this: | |
$action = 'wp_handle_upload'; | |
// Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. | |
$upload_error_strings = array(false, | |
__("The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>."), | |
__("The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form."), | |
__("The uploaded file was only partially uploaded."), | |
__("No file was uploaded."), | |
'', | |
__("Missing a temporary folder."), | |
__("Failed to write file to disk.")); | |
// Install user overrides. Did we mention that this voids your warranty? | |
if (is_array($overrides)) | |
extract($overrides, EXTR_OVERWRITE); | |
// A successful upload will pass this test. It makes no sense to override this one. | |
if ($file['error'] > 0) | |
return $upload_error_handler($file, $upload_error_strings[$file['error']]); | |
// A non-empty file will pass this test. | |
if (!($file['size'] > 0 )) | |
return $upload_error_handler($file, __('File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.')); | |
// A properly uploaded file will pass this test. There should be no reason to override this one. | |
if (!file_exists($file['tmp_name'])) | |
return $upload_error_handler($file, __('Specified file failed upload test.')); | |
// A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. | |
$wp_filetype = wp_check_filetype($file['name']); | |
DebugEcho("postie_handle_upload: detected file type for " . $file['name']); | |
DebugDump($wp_filetype); | |
extract($wp_filetype); | |
if ((!$type || !$ext ) && !current_user_can('unfiltered_upload')) | |
return $upload_error_handler($file, __('File type does not meet security guidelines. Try another.')); | |
if (!$ext) | |
$ext = ltrim(strrchr($file['name'], '.'), '.'); | |
if (!$type) | |
$type = $file['type']; | |
// A writable uploads dir will pass this test. Again, there's no point overriding this one. | |
if (!( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] )) | |
return $upload_error_handler($file, $uploads['error']); | |
// fix filename (encode non-standard characters) | |
$file['name'] = filename_fix($file['name']); | |
$filename = wp_unique_filename($uploads['path'], $file['name']); | |
DebugEcho("wp_unique_filename: $filename"); | |
// Move the file to the uploads dir | |
$new_file = $uploads['path'] . "/$filename"; | |
if (false === @ rename($file['tmp_name'], $new_file)) { | |
DebugEcho("upload: rename failed"); | |
DebugEcho("new file: $new_file"); | |
//DebugDump($file); | |
//DebugDump($uploads); | |
return $upload_error_handler($file, sprintf(__('The uploaded file could not be moved to %s.'), $uploads['path'])); | |
} | |
// Set correct file permissions | |
$stat = stat(dirname($new_file)); | |
$perms = $stat['mode'] & 0000666; | |
@ chmod($new_file, $perms); | |
// Compute the URL | |
$url = $uploads['url'] . "/$filename"; | |
$return = apply_filters('wp_handle_upload', array('file' => $new_file, 'url' => $url, 'type' => $type)); | |
return $return; | |
} | |
function filename_fix($filename) { | |
return str_replace('%', '', urlencode($filename)); | |
} | |
/** | |
* This method sorts thru the mime parts of the message. It is looking for a certain type of text attachment. If | |
* that type is present it filters out all other text types. If it is not - then nothing is done | |
* @param object | |
*/ | |
function filter_PreferedText($mimeDecodedEmail, $preferTextType) { | |
DebugEcho("FilterTextParts: begin " . count($mimeDecodedEmail->parts)); | |
$newParts = array(); | |
$found = false; | |
for ($i = 0; $i < count($mimeDecodedEmail->parts); $i++) { | |
DebugEcho("part: $i " . $mimeDecodedEmail->parts[$i]->ctype_primary . "/" . $mimeDecodedEmail->parts[$i]->ctype_secondary); | |
if (array_key_exists('disposition', $mimeDecodedEmail->parts[$i]) && $mimeDecodedEmail->parts[$i]->disposition == 'attachment') { | |
DebugEcho("attachment"); | |
$newParts[] = $mimeDecodedEmail->parts[$i]; | |
} else { | |
if ($mimeDecodedEmail->parts[$i]->ctype_primary == "text") { | |
$ctype = $mimeDecodedEmail->parts[$i]->ctype_secondary; | |
if ($ctype == 'html' || $ctype == 'plain') { | |
DebugEcho("checking prefered type"); | |
if ($ctype == $preferTextType) { | |
DebugEcho("keeping: $ctype"); | |
DebugEcho(substr($mimeDecodedEmail->parts[$i]->body, 0, 500)); | |
$newParts[] = $mimeDecodedEmail->parts[$i]; | |
} else { | |
DebugEcho("removing: $ctype"); | |
} | |
} else { | |
DebugEcho("keeping: {$mimeDecodedEmail->parts[$i]->ctype_primary}"); | |
$newParts[] = $mimeDecodedEmail->parts[$i]; | |
} | |
} else { | |
DebugEcho("keeping: {$mimeDecodedEmail->parts[$i]->ctype_primary}"); | |
$newParts[] = $mimeDecodedEmail->parts[$i]; | |
} | |
} | |
} | |
if ($newParts) { | |
//This is now the filtered list of just the preferred type. | |
DebugEcho(count($newParts) . " parts"); | |
$mimeDecodedEmail->parts = $newParts; | |
} | |
DebugEcho("FilterTextParts: end"); | |
} | |
/** | |
* This function can be used to send confirmation or rejection e-mails | |
* It accepts an object containing the entire message | |
*/ | |
function MailToRecipients(&$mail_content, $testEmail = false, $recipients = array(), $returnToSender, $reject = true) { | |
DebugEcho("send mail"); | |
if ($testEmail) { | |
return false; | |
} | |
$user = get_userdata('1'); | |
$myname = $user->user_nicename; | |
$myemailadd = get_option("admin_email"); | |
$blogname = get_option("blogname"); | |
$blogurl = get_option("siteurl"); | |
if (count($recipients) == 0) { | |
DebugEcho("send mail: no recipients"); | |
return false; | |
} | |
$from = trim($mail_content->headers["from"]); | |
$subject = $mail_content->headers['subject']; | |
if ($returnToSender) { | |
array_push($recipients, $from); | |
} | |
$headers = "From: Wordpress <" . $myemailadd . ">\r\n"; | |
foreach ($recipients as $recipient) { | |
$recipient = trim($recipient); | |
if (!empty($recipient)) { | |
$headers .= "Cc: " . $recipient . "\r\n"; | |
} | |
} | |
// Set email subject | |
if ($reject) { | |
DebugEcho("send mail: sending reject mail"); | |
$alert_subject = $blogname . ": Unauthorized Post Attempt from $from"; | |
if (is_array($mail_content->ctype_parameters) && array_key_exists('boundary', $mail_content->ctype_parameters) && $mail_content->ctype_parameters['boundary']) { | |
$boundary = $mail_content->ctype_parameters["boundary"]; | |
} else { | |
$boundary = uniqid("B_"); | |
} | |
// Set sender details | |
$headers.="Content-Type:multipart/alternative; boundary=\"$boundary\"\r\n"; | |
$message = "An unauthorized message has been sent to $blogname.\n"; | |
$message .= "Sender: $from\n"; | |
$message .= "Subject: $subject\n"; | |
$message .= "\n\nIf you wish to allow posts from this address, please add " . $from . " to the registered users list and manually add the content of the e-mail found below."; | |
$message .= "\n\nOtherwise, the e-mail has already been deleted from the server and you can ignore this message."; | |
$message .= "\n\nIf you would like to prevent postie from forwarding mail in the future, please change the FORWARD_REJECTED_MAIL setting in the Postie settings panel"; | |
$message .= "\n\nThe original content of the e-mail has been attached.\n\n"; | |
$mailtext = "--$boundary\r\n"; | |
$mailtext .= "Content-Type: text/plain;format=flowed;charset=\"iso-8859-1\";reply-type=original\n"; | |
$mailtext .= "Content-Transfer-Encoding: 7bit\n"; | |
$mailtext .= "\n"; | |
$mailtext .= "$message\n"; | |
if ($mail_content->parts) { | |
$mailparts = $mail_content->parts; | |
} else { | |
$mailparts[] = $mail_content; | |
} | |
foreach ($mailparts as $part) { | |
$mailtext .= "--$boundary\r\n"; | |
if (array_key_exists('content-type', $part->headers)) | |
$mailtext .= "Content-Type: " . $part->headers["content-type"] . "\n"; | |
if (array_key_exists('content-transfer-encoding', $part->headers)) | |
$mailtext .= "Content-Transfer-Encoding: " . $part->headers["content-transfer-encoding"] . "\n"; | |
if (array_key_exists('content-disposition', $part->headers)) { | |
$mailtext .= "Content-Disposition: " . $part->headers["content-disposition"] . "\n"; | |
} | |
$mailtext .= "\n"; | |
if (property_exists($part, 'body')) | |
$mailtext .= $part->body; | |
} | |
} else { | |
DebugEcho("send mail: sending success mail"); | |
$alert_subject = "Successfully posted to $blogname"; | |
$mailtext = "Your post '$subject' has been successfully published to $blogname <$blogurl>.\n"; | |
} | |
wp_mail($myemailadd, $alert_subject, $mailtext, $headers); | |
return true; | |
} | |
/** | |
* This function handles the basic mime decoding | |
* @param string | |
* @return array | |
*/ | |
function DecodeMIMEMail($email, $decodeHeaders = false) { | |
$params = array(); | |
$params['include_bodies'] = true; | |
$params['decode_bodies'] = false; | |
$params['decode_headers'] = $decodeHeaders; | |
$params['input'] = $email; | |
$md = new Mail_mimeDecode($email); | |
$decoded = $md->decode($params); | |
if (empty($decoded->parts)) | |
$decoded->parts = array(); // have an empty array at minimum, so that it is safe for "foreach" | |
return $decoded; | |
} | |
/** | |
* This is used for debugging the mimeDecodedEmail of the mail | |
*/ | |
function DisplayMIMEPartTypes($mimeDecodedEmail) { | |
foreach ($mimeDecodedEmail->parts as $part) { | |
EchoInfo($part->ctype_primary . " / " . $part->ctype_secondary . "/ " . $part->headers['content-transfer-encoding']); | |
} | |
} | |
/** | |
* This compares the current address to the list of authorized addresses | |
* @param string - email address | |
* @return boolean | |
*/ | |
function isEmailAddressAuthorized($address, $authorized) { | |
$r = false; | |
if (is_array($authorized)) { | |
$a = strtolower(trim($address)); | |
if (!empty($a)) { | |
$isAuthorized = in_array(strtolower($a), array_map('strtolower', $authorized)); | |
$r = $isAuthorized; | |
} | |
} | |
return $r; | |
} | |
/** | |
* This method works around a problem with email address with extra <> in the email address | |
* @param string | |
* @return string | |
*/ | |
function RemoveExtraCharactersInEmailAddress($address) { | |
$matches = array(); | |
if (preg_match('/^[^<>]+<([^<> ()]+)>$/', $address, $matches)) { | |
$address = $matches[1]; | |
} else if (preg_match('/<([^<> ()]+)>/', $address, $matches)) { | |
$address = $matches[1]; | |
} | |
return $address; | |
} | |
/** | |
* This function gleans the name from the 'from:' header if available. If not | |
* it just returns the username (everything before @) | |
*/ | |
function GetNameFromEmail($address) { | |
$name = ""; | |
$matches = array(); | |
if (preg_match('/^([^<>]+)<([^<> ()]+)>$/', $address, $matches)) { | |
$name = $matches[1]; | |
} else if (preg_match('/<([^<>@ ()]+)>/', $address, $matches)) { | |
$name = $matches[1]; | |
} else if (preg_match('/(.+?)@(.+)/', $address, $matches)) { | |
$name = $matches[1]; | |
} | |
return trim($name); | |
} | |
/** | |
* Choose an appropriate file icon based on the extension and mime type of | |
* the attachment | |
*/ | |
function chooseAttachmentIcon($file, $primary, $secondary, $iconSet = 'silver', $size = '32') { | |
if ($iconSet == 'none') | |
return(''); | |
$fileName = basename($file); | |
$parts = explode('.', $fileName); | |
$ext = $parts[count($parts) - 1]; | |
$docExts = array('doc', 'docx'); | |
$docMimes = array('msword', 'vnd.ms-word', 'vnd.openxmlformats-officedocument.wordprocessingml.document'); | |
$pptExts = array('ppt', 'pptx'); | |
$pptMimes = array('mspowerpoint', 'vnd.ms-powerpoint', 'vnd.openxmlformats-officedocument.'); | |
$xlsExts = array('xls', 'xlsx'); | |
$xlsMimes = array('msexcel', 'vnd.ms-excel', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet'); | |
$iWorkMimes = array('zip', 'octet-stream'); | |
$mpgExts = array('mpg', 'mpeg', 'mp2'); | |
$mpgMimes = array('mpg', 'mpeg', 'mp2'); | |
$mp3Exts = array('mp3'); | |
$mp3Mimes = array('mp3', 'mpeg3', 'mpeg'); | |
$mp4Exts = array('mp4', 'm4v'); | |
$mp4Mimes = array('mp4', 'mpeg4', 'octet-stream'); | |
$aacExts = array('m4a', 'aac'); | |
$aacMimes = array('m4a', 'aac', 'mp4'); | |
$aviExts = array('avi'); | |
$aviMimes = array('avi', 'x-msvideo'); | |
$movExts = array('mov'); | |
$movMimes = array('mov', 'quicktime'); | |
if ($ext == 'pdf' && $secondary == 'pdf') { | |
$fileType = 'pdf'; | |
} else if ($ext == 'pages' && in_array($secondary, $iWorkMimes)) { | |
$fileType = 'pages'; | |
} else if ($ext == 'numbers' && in_array($secondary, $iWorkMimes)) { | |
$fileType = 'numbers'; | |
} else if ($ext == 'key' && in_array($secondary, $iWorkMimes)) { | |
$fileType = 'key'; | |
} else if (in_array($ext, $docExts) && in_array($secondary, $docMimes)) { | |
$fileType = 'doc'; | |
} else if (in_array($ext, $pptExts) && in_array($secondary, $pptMimes)) { | |
$fileType = 'ppt'; | |
} else if (in_array($ext, $xlsExts) && in_array($secondary, $xlsMimes)) { | |
$fileType = 'xls'; | |
} else if (in_array($ext, $mp4Exts) && in_array($secondary, $mp4Mimes)) { | |
$fileType = 'mp4'; | |
} else if (in_array($ext, $movExts) && in_array($secondary, $movMimes)) { | |
$fileType = 'mov'; | |
} else if (in_array($ext, $aviExts) && in_array($secondary, $aviMimes)) { | |
$fileType = 'avi'; | |
} else if (in_array($ext, $mp3Exts) && in_array($secondary, $mp3Mimes)) { | |
$fileType = 'mp3'; | |
} else if (in_array($ext, $mpgExts) && in_array($secondary, $mpgMimes)) { | |
$fileType = 'mpg'; | |
} else if (in_array($ext, $aacExts) && in_array($secondary, $aacMimes)) { | |
$fileType = 'aac'; | |
} else { | |
$fileType = 'default'; | |
} | |
$fileName = "/icons/$iconSet/$fileType-$size.png"; | |
if (!file_exists(POSTIE_ROOT . $fileName)) | |
$fileName = "/icons/$iconSet/default-$size.png"; | |
$iconHtml = "<img src='" . POSTIE_URL . $fileName . "' alt='$fileType icon' />"; | |
DebugEcho("icon: $iconHtml"); | |
return $iconHtml; | |
} | |
function parseTemplate($id, $type, $template, $orig_filename) { | |
$size = 'medium'; | |
/* we check template for thumb, thumbnail, large, full and use that as | |
size. If not found, we default to medium */ | |
if ($type == 'image') { | |
$sizes = array('thumbnail', 'medium', 'large'); | |
$hwstrings = array(); | |
$widths = array(); | |
$heights = array(); | |
for ($i = 0; $i < count($sizes); $i++) { | |
list( $img_src[$i], $widths[$i], $heights[$i] ) = image_downsize($id, $sizes[$i]); | |
$hwstrings[$i] = image_hwstring($widths[$i], $heights[$i]); | |
} | |
} | |
$attachment = get_post($id); | |
$the_parent = get_post($attachment->post_parent); | |
$uploadDir = wp_upload_dir(); | |
$fileName = basename($attachment->guid); | |
$absFileName = $uploadDir['path'] . '/' . $fileName; | |
$relFileName = str_replace(ABSPATH, '', $absFileName); | |
$fileLink = wp_get_attachment_url($id); | |
$pageLink = get_attachment_link($id); | |
$template = str_replace('{TITLE}', $attachment->post_title, $template); | |
$template = str_replace('{ID}', $id, $template); | |
if ($type == 'image') { | |
$template = str_replace('{THUMBNAIL}', $img_src[0], $template); | |
$template = str_replace('{THUMB}', $img_src[0], $template); | |
$template = str_replace('{MEDIUM}', $img_src[1], $template); | |
$template = str_replace('{LARGE}', $img_src[2], $template); | |
$template = str_replace('{THUMBWIDTH}', $widths[0] . 'px', $template); | |
$template = str_replace('{THUMBHEIGHT}', $heights[0] . 'px', $template); | |
$template = str_replace('{MEDIUMWIDTH}', $widths[1] . 'px', $template); | |
$template = str_replace('{MEDIUMHEIGHT}', $heights[1] . 'px', $template); | |
$template = str_replace('{LARGEWIDTH}', $widths[2] . 'px', $template); | |
$template = str_replace('{LARGEHEIGHT}', $heights[2] . 'px', $template); | |
} | |
$template = str_replace('{FULL}', $fileLink, $template); | |
$template = str_replace('{FILELINK}', $fileLink, $template); | |
$template = str_replace('{PAGELINK}', $pageLink, $template); | |
$template = str_replace('{FILENAME}', $orig_filename, $template); | |
$template = str_replace('{IMAGE}', $fileLink, $template); | |
$template = str_replace('{URL}', $fileLink, $template); | |
$template = str_replace('{RELFILENAME}', $relFileName, $template); | |
$template = str_replace('{POSTTITLE}', $the_parent->post_title, $template); | |
if ($attachment->post_excerpt != '') { | |
$template = str_replace('{CAPTION}', $attachment->post_excerpt, $template); | |
} elseif (!preg_match("/$attachment->post_title/i", $fileName)) { | |
$template = str_replace('{CAPTION}', $attachment->post_title, $template); | |
} else { | |
} | |
DebugEcho("template: $template"); | |
return $template . '<br />'; | |
} | |
/** | |
* When sending in HTML email the html refers to the content-id(CID) of the image - this replaces | |
* the cid place holder with the actual url of the image sent in | |
* @param string - text of post | |
* @param array - array of HTML for images for post | |
*/ | |
function filter_ReplaceImageCIDs(&$content, &$attachments, $config) { | |
if ($config['prefer_text_type'] == "html" && count($attachments["cids"])) { | |
DebugEcho("ReplaceImageCIDs"); | |
$used = array(); | |
foreach ($attachments["cids"] as $key => $info) { | |
$key = str_replace('/', '\/', $key); | |
$pattern = "/cid:$key/"; | |
if (preg_match($pattern, $content)) { | |
$content = preg_replace($pattern, $info[0], $content); | |
$used[] = $info[1]; //Index of html to ignore | |
} | |
} | |
DebugEcho("# cid attachments: " . count($used)); | |
$html = array(); | |
$att = array_values($attachments["html"]); //make sure there are numeric indexes | |
DebugEcho('$attachments'); | |
//DebugDump($attachments); | |
DebugEcho('$used'); | |
//DebugDump($used); | |
for ($i = 0; $i < count($attachments["html"]); $i++) { | |
if (!in_array($i, $used)) { | |
$html[] = $att[$i]; | |
} | |
} | |
foreach ($attachments['html'] as $key => $value) { | |
if (!in_array($value, $used)) { | |
$html[$key] = $value; | |
} | |
} | |
$attachments["html"] = $html; | |
//DebugDump($attachments); | |
} | |
} | |
/** | |
* This function handles replacing image place holder #img1# with the HTML for that image | |
* @param string - text of post | |
* @param array - array of HTML for images for post | |
*/ | |
function filter_ReplaceImagePlaceHolders(&$content, $attachments, $config) { | |
if (!$config['custom_image_field']) { | |
if (!$config['allow_html_in_body']) { | |
$content = html_entity_decode($content, ENT_QUOTES); | |
} | |
$startIndex = $config['start_image_count_at_zero'] ? 0 : 1; | |
if (!empty($attachments) && $config['auto_gallery']) { | |
$imageTemplate = '[gallery]'; | |
if ($config['images_append']) { | |
$content .= "\n$imageTemplate"; | |
DebugEcho("Auto gallery: append"); | |
} else { | |
$content = "$imageTemplate\n" . $content; | |
DebugEcho("Auto gallery: prepend"); | |
} | |
return; | |
} | |
$pics = ""; | |
$i = 0; | |
foreach ($attachments as $attachementName => $imageTemplate) { | |
// looks for ' #img1# ' etc... and replaces with image | |
$img_placeholder_temp = str_replace("%", intval($startIndex + $i), $config['image_placeholder']); | |
$img_placeholder_temp = rtrim($img_placeholder_temp, '#'); | |
$eimg_placeholder_temp = str_replace("%", intval($startIndex + $i), "#eimg%#"); | |
$eimg_placeholder_temp = rtrim($eimg_placeholder_temp, '#'); | |
DebugEcho("img_placeholder_temp: $img_placeholder_temp"); | |
if (stristr($content, $img_placeholder_temp) || stristr($content, $eimg_placeholder_temp)) { | |
// look for caption | |
DebugEcho("Found $img_placeholder_temp or $eimg_placeholder_temp"); | |
$caption = ''; | |
if (preg_match("/$img_placeholder_temp caption=(.*?)#/i", $content, $matches)) { | |
//DebugDump($matches); | |
$caption = trim($matches[1]); | |
if (strlen($caption) > 2 && ($caption[0] == "'" || $caption[0] == '"')) { | |
$caption = substr($caption, 1, strlen($caption) - 2); | |
} | |
DebugEcho("caption: $caption"); | |
$img_placeholder_temp = substr($matches[0], 0, -1); | |
$eimg_placeholder_temp = substr($matches[0], 0, -1); | |
DebugEcho($img_placeholder_temp); | |
DebugEcho($eimg_placeholder_temp); | |
} else { | |
DebugEcho("No caption found"); | |
} | |
//DebugEcho("parameterize templete: " . $imageTemplate); | |
$imageTemplate = mb_str_replace('{CAPTION}', htmlspecialchars($caption, ENT_QUOTES), $imageTemplate); | |
//DebugEcho("populated templete: " . $imageTemplate); | |
$img_placeholder_temp.='#'; | |
$eimg_placeholder_temp.='#'; | |
$content = str_ireplace($img_placeholder_temp, $imageTemplate, $content); | |
$content = str_ireplace($eimg_placeholder_temp, $imageTemplate, $content); | |
} else { | |
DebugEcho("No $img_placeholder_temp or $eimg_placeholder_temp found"); | |
$imageTemplate = str_replace('{CAPTION}', '', $imageTemplate); | |
/* if using the gallery shortcode, don't add pictures at all */ | |
if (!preg_match("/\[gallery[^\[]*\]/", $content, $matches)) { | |
$pics .= $imageTemplate; | |
} else { | |
DebugEcho("gallery detected, not inserting images"); | |
} | |
} | |
$i++; | |
} | |
if ($config['images_append']) { | |
$content .= $pics; | |
} else { | |
$content = $pics . $content; | |
} | |
} | |
} | |
/** | |
* This function handles finding and setting the correct subject | |
* @return array - (subject,content) | |
*/ | |
function GetSubject(&$mimeDecodedEmail, &$content, $config) { | |
extract($config); | |
global $charset; | |
//assign the default title/subject | |
if (!array_key_exists('subject', $mimeDecodedEmail->headers) || empty($mimeDecodedEmail->headers['subject'])) { | |
DebugEcho("No subject in email"); | |
if ($allow_subject_in_mail) { | |
list($subject, $content) = tag_subject($content, $default_title); | |
} else { | |
DebugEcho("Using default subject"); | |
$subject = $default_title; | |
} | |
$mimeDecodedEmail->headers['subject'] = $subject; | |
} else { | |
$subject = $mimeDecodedEmail->headers['subject']; | |
DebugEcho(("Predecoded subject: $subject")); | |
if (!$allow_html_in_subject) { | |
DebugEcho("subject before htmlentities: $subject"); | |
$subject = htmlentities($subject, ENT_COMPAT, $message_encoding); | |
DebugEcho("subject after htmlentities: $subject"); | |
} | |
} | |
//This is for ISO-2022-JP - Can anyone confirm that this is still neeeded? | |
// escape sequence is 'ESC $ B' == 1b 24 42 hex. | |
if (strpos($subject, "\x1b\x24\x42") !== false) { | |
// found iso-2022-jp escape sequence in subject... convert! | |
DebugEcho("extra parsing for ISO-2022-JP"); | |
$subject = iconv("ISO-2022-JP", "UTF-8//TRANSLIT", $subject); | |
} | |
DebugEcho("Subject: $subject"); | |
return $subject; | |
} | |
/** | |
* this function determines tags for the post | |
* | |
*/ | |
function tag_Tags(&$content, $defaultTags) { | |
$post_tags = array(); | |
//try and determine tags | |
if (preg_match('/tags: ?(.*)$/im', $content, $matches)) { | |
if (!empty($matches[1])) { | |
DebugEcho("Found tags: $matches[1]"); | |
$content = str_replace($matches[0], "", $content); | |
$post_tags = preg_split("/,\s*/", trim($matches[1])); | |
//DebugDump($post_tags); | |
} | |
} | |
if (count($post_tags) == 0 && is_array($defaultTags)) { | |
$post_tags = $defaultTags; | |
} | |
return $post_tags; | |
} | |
/** | |
* this function determines excerpt for the post | |
* | |
*/ | |
function tag_Excerpt(&$content, $filterNewLines, $convertNewLines) { | |
$post_excerpt = ''; | |
if (preg_match('/:excerptstart ?(.*):excerptend/s', $content, $matches)) { | |
$content = str_replace($matches[0], "", $content); | |
$post_excerpt = $matches[1]; | |
DebugEcho("excerpt found: $post_excerpt"); | |
if ($filterNewLines) { | |
DebugEcho("filtering newlines from excerpt"); | |
filter_newlines($post_excerpt, $convertNewLines); | |
} | |
} | |
return $post_excerpt; | |
} | |
/** | |
* This function determines the categories ids for the post | |
* @return array | |
*/ | |
function tag_categories(&$subject, $defaultCategory, $category_match) { | |
$original_subject = $subject; | |
$post_categories = array(); | |
$matchtypes = array(); | |
$matches = array(); | |
if (preg_match_all('/\[(.[^\[]*)\]/', $subject, $matches)) { // [<category1>] [<category2>] <Subject> | |
preg_match("/]([^\[]*)$/", $subject, $subject_matches); | |
//DebugDump($subject_matches); | |
$subject = trim($subject_matches[1]); | |
$matchtypes[] = $matches; | |
} | |
if (preg_match_all('/-(.[^-]*)-/', $subject, $matches)) { // -<category>- -<category2>- <Subject> | |
preg_match("/-(.[^-]*)$/", $subject, $subject_matches); | |
$subject = trim($subject_matches[1]); | |
$matchtypes[] = $matches; | |
} | |
if (preg_match('/(.+): (.*)/', $subject, $matches)) { // <category>:<Subject> | |
$category = lookup_category($matches[1], $category_match); | |
if (!empty($category)) { | |
DebugEcho("colon category: $category"); | |
$subject = trim($matches[2]); | |
$post_categories[] = $category; | |
} | |
} | |
foreach ($matchtypes as $matches) { | |
if (count($matches)) { | |
foreach ($matches[1] as $match) { | |
$category = lookup_category($match, $category_match); | |
if (!empty($category)) { | |
$post_categories[] = $category; | |
} | |
} | |
} | |
} | |
if (!count($post_categories)) { | |
$post_categories[] = $defaultCategory; | |
$subject = $original_subject; | |
} | |
return $post_categories; | |
} | |
function lookup_category($trial_category, $category_match) { | |
global $wpdb; | |
$trial_category = trim($trial_category); | |
$found_category = NULL; | |
EchoInfo("lookup_category: $trial_category"); | |
$term = get_term_by('name', $trial_category, 'category'); | |
if ($term !== false) { | |
DebugEcho("category: found by name $trial_category"); | |
//DebugDump($term); | |
//then category is a named and found | |
return $term->term_id; | |
} | |
$term = get_term_by('id', intval($trial_category), 'category'); | |
if ($term !== false) { | |
DebugEcho("category: found by id $trial_category"); | |
//DebugDump($term); | |
//then cateogry was an ID and found | |
return $term->term_id; | |
} | |
if ($category_match) { | |
DebugEcho("category wildcard lookup: $trial_category"); | |
$sql_sub_name = 'SELECT term_id FROM ' . $wpdb->terms . ' WHERE name LIKE \'' . addslashes($trial_category) . '%\' limit 1'; | |
$found_category = $wpdb->get_var($sql_sub_name); | |
DebugEcho("category wildcard found: $found_category"); | |
} | |
return intval($found_category); //force to integer | |
} | |
/** | |
* This function just outputs a simple html report about what is being posted in | |
*/ | |
function DisplayEmailPost($details) { | |
//DebugDump($details); | |
// Report | |
EchoInfo('Post Author: ' . $details["post_author"]); | |
EchoInfo('Date: ' . $details["post_date"]); | |
foreach ($details["post_category"] as $category) { | |
EchoInfo('Category: ' . $category); | |
} | |
EchoInfo('Ping Status: ' . $details["ping_status"]); | |
EchoInfo('Comment Status: ' . $details["comment_status"]); | |
EchoInfo('Subject: ' . $details["post_title"]); | |
EchoInfo('Postname: ' . $details["post_name"]); | |
EchoInfo('Post Id: ' . $details["ID"]); | |
EchoInfo('Post Type: ' . $details["post_type"]); /* Added by Raam Dev <raam@raamdev.com> */ | |
EchoInfo('Post Format: ' . $details["post_format"]); /* Added by Raam Dev <raam@raamdev.com> */ | |
//EchoInfo('Posted content: '.$details["post_content"]); | |
} | |
/** | |
* Takes a value and builds a simple simple yes/no select box | |
* @param string | |
* @param string | |
* @param string | |
* @param string | |
*/ | |
function BuildBooleanSelect($label, $id, $current_value, $recommendation = NULL) { | |
$html = "<tr> | |
<th scope='row'>" . $label . ":"; | |
if (!empty($recommendation)) { | |
$html.='<br /><span class = "recommendation">' . $recommendation . '</span>'; | |
} | |
$html.="</th> | |
<td><select name='$id' id='$id'> | |
<option value='1'>" . __("Yes", 'postie') . "</option> | |
<option value='0' " . (!$current_value ? "selected='selected'" : "") . ">" . __("No", 'postie') . '</option> | |
</select>'; | |
$html.="</td>\n</tr>"; | |
return $html; | |
} | |
/** | |
* This takes an array and display a text box for editing | |
* @param string | |
* @param string | |
* @param array | |
* @param string | |
*/ | |
function BuildTextArea($label, $id, $current_value, $recommendation = NULL) { | |
$html = "<tr> <th scope='row'>" . $label . ":"; | |
if ($recommendation) { | |
$html.="<br /><span class='recommendation'>" . $recommendation . "</span>"; | |
} | |
$html.="</th>"; | |
$html .="<td><br /><textarea cols=40 rows=3 name='$id' id='$id'>"; | |
$current_value = preg_split("/[,\r\n]+/", esc_attr(trim($current_value))); | |
if (is_array($current_value)) { | |
foreach ($current_value as $item) { | |
$html .= "$item\n"; | |
} | |
} | |
$html .= "</textarea></td></tr>"; | |
return $html; | |
} | |
/** | |
* This function resets all the configuration options to the default | |
*/ | |
function config_ResetToDefault() { | |
$newconfig = config_GetDefaults(); | |
$config = get_option('postie-settings'); | |
$save_keys = array('mail_password', 'mail_server', 'mail_server_port', 'mail_userid', 'input_protocol'); | |
foreach ($save_keys as $key) | |
$newconfig[$key] = $config[$key]; | |
update_option('postie-settings', $newconfig); | |
config_Update($newconfig); | |
return $newconfig; | |
} | |
/** | |
* This function used to handle updating the configuration. | |
* @return boolean | |
*/ | |
function config_Update($data) { | |
UpdatePostiePermissions($data["role_access"]); | |
// We also update the cron settings | |
if ($data['interval'] != '') { | |
postie_decron(); | |
if ($data['interval'] != 'manual') { | |
postie_cron($data['interval']); | |
} | |
} | |
} | |
/** | |
* return an array of the config defaults | |
*/ | |
function config_GetDefaults() { | |
include('templates/audio_templates.php'); | |
include('templates/image_templates.php'); | |
include('templates/video1_templates.php'); | |
include('templates/video2_templates.php'); | |
return array( | |
'add_meta' => 'no', | |
'admin_username' => 'admin', | |
'allow_html_in_body' => true, | |
'allow_html_in_subject' => true, | |
'allow_subject_in_mail' => true, | |
'audiotemplate' => $simple_link, | |
'audiotypes' => array('m4a', 'mp3', 'ogg', 'wav', 'mpeg'), | |
'authorized_addresses' => array(), | |
'banned_files_list' => array(), | |
'confirmation_email' => '', | |
'convertnewline' => false, | |
'converturls' => true, | |
'custom_image_field' => false, | |
'default_post_category' => NULL, | |
'category_match' => true, | |
'default_post_tags' => array(), | |
'default_title' => "Live From The Field", | |
'delete_mail_after_processing' => true, | |
'drop_signature' => true, | |
'filternewlines' => true, | |
'forward_rejected_mail' => true, | |
'icon_set' => 'silver', | |
'icon_size' => 32, | |
'auto_gallery' => false, | |
'image_new_window' => false, | |
'image_placeholder' => "#img%#", | |
'images_append' => true, | |
'imagetemplate' => $wordpress_default, | |
'imagetemplates' => $imageTemplates, | |
'input_protocol' => "pop3", | |
'interval' => 'twiceperhour', | |
'mail_server' => NULL, | |
'mail_server_port' => 110, | |
'mail_userid' => NULL, | |
'mail_password' => NULL, | |
'maxemails' => 0, | |
'message_start' => ":start", | |
'message_end' => ":end", | |
'message_encoding' => "UTF-8", | |
'message_dequote' => true, | |
'post_status' => 'publish', | |
'prefer_text_type' => "plain", | |
'return_to_sender' => false, | |
'role_access' => array(), | |
'selected_audiotemplate' => 'simple_link', | |
'selected_imagetemplate' => 'wordpress_default', | |
'selected_video1template' => 'simple_link', | |
'selected_video2template' => 'simple_link', | |
'shortcode' => false, | |
'sig_pattern_list' => array('--', '---'), | |
'smtp' => array(), | |
'start_image_count_at_zero' => false, | |
'supported_file_types' => array('application'), | |
'turn_authorization_off' => false, | |
'time_offset' => get_option('gmt_offset'), | |
'video1template' => $simple_link, | |
'video1types' => array('mp4', 'mpeg4', '3gp', '3gpp', '3gpp2', '3gp2', 'mov', 'mpeg', 'quicktime'), | |
'video2template' => $simple_link, | |
'video2types' => array('x-flv'), | |
'video1templates' => $video1Templates, | |
'video2templates' => $video2Templates, | |
'wrap_pre' => 'no' | |
); | |
} | |
/** | |
* ======================================================= | |
* the following functions are only used to retrieve the old (pre 1.4) config, to convert it | |
* to the new format | |
*/ | |
function config_GetListOfArrayConfig() { | |
return(array('SUPPORTED_FILE_TYPES', 'AUTHORIZED_ADDRESSES', | |
'SIG_PATTERN_LIST', 'BANNED_FILES_LIST', 'VIDEO1TYPES', | |
'VIDEO2TYPES', 'AUDIOTYPES', 'SMTP')); | |
} | |
function config_Read() { | |
$config = get_option('postie-settings'); | |
return config_ValidateSettings($config); | |
} | |
/** | |
* This function retrieves the old-format config (pre 1.4) from the database | |
* @return array | |
*/ | |
function config_ReadOld() { | |
$config = array(); | |
global $wpdb; | |
$wpdb->query("SHOW TABLES LIKE '" . $GLOBALS["table_prefix"] . "postie_config'"); | |
if ($wpdb->num_rows > 0) { | |
$data = $wpdb->get_results("SELECT label,value FROM " . $GLOBALS["table_prefix"] . "postie_config;"); | |
if (is_array($data)) { | |
foreach ($data as $row) { | |
if (in_array($row->label, config_GetListOfArrayConfig())) { | |
$config[$row->label] = unserialize($row->value); | |
} else { | |
$config[$row->label] = $row->value; | |
} | |
} | |
} | |
} | |
return $config; | |
} | |
/** | |
* This function processes the old-format config (pre 1.4) for conversion to the 1.4 format | |
* @return array | |
* @access private | |
*/ | |
function config_UpgradeOld() { | |
$config = config_ReadOld(); | |
if (!isset($config["ADMIN_USERNAME"])) | |
$config["ADMIN_USERNAME"] = 'admin'; | |
if (!isset($config["PREFER_TEXT_TYPE"])) | |
$config["PREFER_TEXT_TYPE"] = "plain"; | |
if (!isset($config["DEFAULT_TITLE"])) | |
$config["DEFAULT_TITLE"] = "Live From The Field"; | |
if (!isset($config["INPUT_PROTOCOL"])) | |
$config["INPUT_PROTOCOL"] = "pop3"; | |
if (!isset($config["IMAGE_PLACEHOLDER"])) | |
$config["IMAGE_PLACEHOLDER"] = "#img%#"; | |
if (!isset($config["IMAGES_APPEND"])) | |
$config["IMAGES_APPEND"] = true; | |
if (!isset($config["ALLOW_SUBJECT_IN_MAIL"])) | |
$config["ALLOW_SUBJECT_IN_MAIL"] = true; | |
if (!isset($config["DROP_SIGNATURE"])) | |
$config["DROP_SIGNATURE"] = true; | |
if (!isset($config["MESSAGE_START"])) | |
$config["MESSAGE_START"] = ":start"; | |
if (!isset($config["MESSAGE_END"])) | |
$config["MESSAGE_END"] = ":end"; | |
if (!isset($config["FORWARD_REJECTED_MAIL"])) | |
$config["FORWARD_REJECTED_MAIL"] = true; | |
if (!isset($config["RETURN_TO_SENDER"])) | |
$config["RETURN_TO_SENDER"] = false; | |
if (!isset($config["CONFIRMATION_EMAIL"])) | |
$config["CONFIRMATION_EMAIL"] = ''; | |
if (!isset($config["ALLOW_HTML_IN_SUBJECT"])) | |
$config["ALLOW_HTML_IN_SUBJECT"] = true; | |
if (!isset($config["ALLOW_HTML_IN_BODY"])) | |
$config["ALLOW_HTML_IN_BODY"] = true; | |
if (!isset($config["START_IMAGE_COUNT_AT_ZERO"])) | |
$config["START_IMAGE_COUNT_AT_ZERO"] = false; | |
if (!isset($config["MESSAGE_ENCODING"])) | |
$config["MESSAGE_ENCODING"] = "UTF-8"; | |
if (!isset($config["MESSAGE_DEQUOTE"])) | |
$config["MESSAGE_DEQUOTE"] = true; | |
if (!isset($config["TURN_AUTHORIZATION_OFF"])) | |
$config["TURN_AUTHORIZATION_OFF"] = false; | |
if (!isset($config["CUSTOM_IMAGE_FIELD"])) | |
$config["CUSTOM_IMAGE_FIELD"] = false; | |
if (!isset($config["CONVERTNEWLINE"])) | |
$config["CONVERTNEWLINE"] = false; | |
if (!isset($config["SIG_PATTERN_LIST"])) | |
$config["SIG_PATTERN_LIST"] = array('--', '---'); | |
if (!isset($config["BANNED_FILES_LIST"])) | |
$config["BANNED_FILES_LIST"] = array(); | |
if (!isset($config["SUPPORTED_FILE_TYPES"])) | |
$config["SUPPORTED_FILE_TYPES"] = array("application"); | |
if (!isset($config["AUTHORIZED_ADDRESSES"])) | |
$config["AUTHORIZED_ADDRESSES"] = array(); | |
if (!isset($config["MAIL_SERVER"])) | |
$config["MAIL_SERVER"] = NULL; | |
if (!isset($config["MAIL_SERVER_PORT"])) | |
$config["MAIL_SERVER_PORT"] = NULL; | |
if (!isset($config["MAIL_USERID"])) | |
$config["MAIL_USERID"] = NULL; | |
if (!isset($config["MAIL_PASSWORD"])) | |
$config["MAIL_PASSWORD"] = NULL; | |
if (!isset($config["DEFAULT_POST_CATEGORY"])) | |
$config["DEFAULT_POST_CATEGORY"] = NULL; | |
if (!isset($config["DEFAULT_POST_TAGS"])) | |
$config["DEFAULT_POST_TAGS"] = NULL; | |
if (!isset($config["TIME_OFFSET"])) | |
$config["TIME_OFFSET"] = get_option('gmt_offset'); | |
if (!isset($config["WRAP_PRE"])) | |
$config["WRAP_PRE"] = 'no'; | |
if (!isset($config["CONVERTURLS"])) | |
$config["CONVERTURLS"] = true; | |
if (!isset($config["SHORTCODE"])) | |
$config["SHORTCODE"] = false; | |
if (!isset($config["ADD_META"])) | |
$config["ADD_META"] = 'no'; | |
$config['ICON_SETS'] = array('silver', 'black', 'white', 'custom', 'none'); | |
if (!isset($config["ICON_SET"])) | |
$config["ICON_SET"] = 'silver'; | |
$config['ICON_SIZES'] = array(32, 48, 64); | |
if (!isset($config["ICON_SIZE"])) | |
$config["ICON_SIZE"] = 32; | |
//audio | |
include('templates/audio_templates.php'); | |
if (!isset($config["SELECTED_AUDIOTEMPLATE"])) | |
$config['SELECTED_AUDIOTEMPLATE'] = 'simple_link'; | |
$config['AUDIOTEMPLATES'] = $audioTemplates; | |
if (!isset($config["SELECTED_VIDEO1TEMPLATE"])) | |
$config['SELECTED_VIDEO1TEMPLATE'] = 'simple_link'; | |
if (!isset($config["AUDIOTEMPLATE"])) | |
$config["AUDIOTEMPLATE"] = $simple_link; | |
//video1 | |
if (!isset($config["VIDEO1TYPES"])) | |
$config['VIDEO1TYPES'] = array('mp4', 'mpeg4', '3gp', '3gpp', '3gpp2', '3gp2', 'mov', 'mpeg', 'quicktime'); | |
if (!isset($config["AUDIOTYPES"])) | |
$config['AUDIOTYPES'] = array('m4a', 'mp3', 'ogg', 'wav', 'mpeg'); | |
if (!isset($config["SELECTED_VIDEO2TEMPLATE"])) | |
$config['SELECTED_VIDEO2TEMPLATE'] = 'simple_link'; | |
include('templates/video1_templates.php'); | |
$config['VIDEO1TEMPLATES'] = $video1Templates; | |
if (!isset($config["VIDEO1TEMPLATE"])) | |
$config["VIDEO1TEMPLATE"] = $simple_link; | |
//video2 | |
if (!isset($config["VIDEO2TYPES"])) | |
$config['VIDEO2TYPES'] = array('x-flv'); | |
if (!isset($config["POST_STATUS"])) | |
$config["POST_STATUS"] = 'publish'; | |
if (!isset($config["IMAGE_NEW_WINDOW"])) | |
$config["IMAGE_NEW_WINDOW"] = false; | |
if (!isset($config["FILTERNEWLINES"])) | |
$config["FILTERNEWLINES"] = true; | |
include('templates/video2_templates.php'); | |
$config['VIDEO2TEMPLATES'] = $video2Templates; | |
if (!isset($config["VIDEO2TEMPLATE"])) | |
$config["VIDEO2TEMPLATE"] = $simple_link; | |
//image | |
if (!isset($config["SELECTED_IMAGETEMPLATE"])) | |
$config['SELECTED_IMAGETEMPLATE'] = 'wordpress_default'; | |
if (!isset($config["SMTP"])) | |
$config["SMTP"] = array(); | |
include('templates/image_templates.php'); | |
if (!isset($config["IMAGETEMPLATE"])) | |
$config["IMAGETEMPLATE"] = $wordpress_default; | |
$config['IMAGETEMPLATES'] = $imageTemplates; | |
return($config); | |
} | |
/** | |
* This function returns the old | |
-format config (pre 1.4) | |
* @return array | |
*/ | |
function config_GetOld() { | |
$config = config_UpgradeOld(); | |
//These should only be modified if you are testing | |
$config["DELETE_MAIL_AFTER_PROCESSING"] = true; | |
$config["POST_TO_DB"] = true; | |
$config["TEST_EMAIL"] = false; | |
$config["TEST_EMAIL_ACCOUNT"] = "blogtest"; | |
$config["TEST_EMAIL_PASSWORD"] = "yourpassword"; | |
if (file_exists(POSTIE_ROOT . '/postie_test_variables.php')) { | |
include(POSTIE_ROOT . '/postie_test_variables.php'); | |
} | |
//include(POSTIE_ROOT . "/../postie-test.php"); | |
// These are computed | |
$config["TIME_OFFSET"] = get_option('gmt_offset'); | |
$config["POSTIE_ROOT"] = POSTIE_ROOT; | |
for ($i = 0; $i < count($config["AUTHORIZED_ADDRESSES"]); $i++) { | |
$config["AUTHORIZED_ADDRESSES"][$i] = strtolower($config["AUTHORIZED_ADDRESSES"][$i]); | |
} | |
return $config; | |
} | |
/** | |
* end of functions u sed to retrieve the old (pre 1.4) config | |
* ======================================================= | |
*/ | |
/** | |
* Returns a list of config keys that should be arrays | |
* @return array | |
*/ | |
function config_ArrayedSettings() { | |
return array( | |
', ' => array('audiotypes', 'video1types', 'video2types', 'default_post_tags'), | |
"\n" => array('smtp', 'authorized_addresses', 'supported_file_types', 'banned_files_list', 'sig_pattern_list')); | |
} | |
/** | |
* Detects if they can do IMAP | |
* @return boolean | |
*/ | |
function HasIMAPSupport($display = true) { | |
$function_list = array("imap_open", | |
"imap_delete", | |
"imap_expunge", | |
"imap_body", | |
"imap_fetchheader"); | |
return(HasFunctions($function_list, $display)); | |
} | |
function HasMbStringInstalled() { | |
$function_list = array("mb_detect_encoding"); | |
return(HasFunctions($function_list)); | |
} | |
function HasIconvInstalled($display = true) { | |
$function_list = array("iconv"); | |
return(HasFunctions($function_list, $display)); | |
} | |
/** | |
* Handles verifing that a list of functions exists | |
* @return boolean | |
* @param array | |
*/ | |
function HasFunctions($function_list, $display = true) { | |
foreach ($function_list as $function) { | |
if (!function_exists($function)) { | |
if ($display) { | |
EchoInfo("Missing $function"); | |
} | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* This function tests to see if postie is its own directory | |
*/ | |
function isPostieInCorrectDirectory() { | |
$dir_parts = explode(DIRECTORY_SEPARATOR, dirname(__FILE__)); | |
$last_dir = array_pop($dir_parts); | |
if ($last_dir != "postie") { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* This function looks for markdown which causes problems with postie | |
*/ | |
function isMarkdownInstalled() { | |
if (in_array("markdown.php", get_option("active_plugins"))) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* validates the config form output, fills in any gaps by using the defaults, | |
* and ensures that arrayed items are stored as such | |
*/ | |
function config_ValidateSettings($in) { | |
//DebugDump($in); | |
$out = array(); | |
// use the default as a template: | |
// if a field is present in the defaults, we want to store it; otherwise we discard it | |
$allowed_keys = config_GetDefaults(); | |
foreach ($allowed_keys as $key => $default) | |
$out[$key] = array_key_exists($key, $in) ? $in[$key] : $default; | |
// some fields are always forced to lower case: | |
$lowercase = array('authorized_addresses', 'smtp', 'supported_file_types', 'video1types', 'video2types', 'audiotypes'); | |
foreach ($lowercase as $field) { | |
$out[$field] = ( is_array($out[$field]) ) ? array_map("strtolower", $out[$field]) : strtolower($out[$field]); | |
} | |
$arrays = config_ArrayedSettings(); | |
foreach ($arrays as $sep => $fields) { | |
foreach ($fields as $field) { | |
if (!is_array($out[$field])) | |
$out[$field] = explode($sep, trim($out[$field])); | |
foreach ($out[$field] as $key => $val) { | |
$tst = trim($val); | |
if | |
(empty($tst)) { | |
unset($out[$field][$key]); | |
} else { | |
$out[$field][$key] = $tst; | |
} | |
} | |
} | |
} | |
config_Update($out); | |
return $out; | |
} | |
/** | |
* registers the settings and the admin optionspage | |
*/ | |
function postie_admin_settings() { | |
register_setting('postie-settings', 'postie-settings', 'config_ValidateSettings'); | |
} | |
/** | |
* This function handles setting up the basic permissions | |
*/ | |
function UpdatePostiePermissions($role_access) { | |
global $wp_roles; | |
if (is_object($wp_roles)) { | |
$admin = $wp_roles->get_role("administrator"); | |
$admin->add_cap("config_postie"); | |
$admin->add_cap("post_via_postie"); | |
if (!is_array($role_access)) { | |
$role_access = array(); | |
} | |
foreach ($wp_roles->role_names as $roleId => $name) { | |
$role = $wp_roles->get_role($roleId); | |
if ($roleId != "administrator") { | |
if (array_key_exists($roleId, $role_access)) { | |
$role->add_cap("post_via_postie"); | |
//DebugEcho("added $roleId"); | |
} else { | |
$role->remove_cap("post_via_postie"); | |
//DebugEcho("removed $roleId"); | |
} | |
} | |
} | |
} | |
} | |
function IsDebugMode() { | |
return (defined('POSTIE_DEBUG') && POSTIE_DEBUG == true); | |
} | |
function SafeFileName($filename) { | |
return str_replace(array('\\', '/', ':', '*', '?', '"', '<', '>', '|'), array('', '', '', '', '', '', '', '', ''), $filename); | |
} | |
function DebugEmailOutput($email, $mimeDecodedEmail) { | |
if (IsDebugMode()) { | |
//DebugDump($email); | |
//DebugDump($mimeDecodedEmail); | |
$dname = POSTIE_ROOT . DIRECTORY_SEPARATOR . "test_emails" . DIRECTORY_SEPARATOR; | |
if (is_dir($dname)) { | |
$fname = $dname . SafeFileName($mimeDecodedEmail->headers["message-id"]); | |
$file = fopen($fname . ".txt ", "w"); | |
fwrite($file, $email); | |
fclose($file); | |
$file = fopen($fname . "-mime.txt ", "w"); | |
fwrite($file, print_r($mimeDecodedEmail, true)); | |
fclose($file); | |
$file = fopen($fname . ".php ", "w"); | |
fwrite($file, serialize($email)); | |
fclose($file); | |
} else { | |
DebugEcho("The directory $dname does not exist, creating this optional directory will allow saving copies of emails for debugging purposes."); | |
} | |
} | |
} | |
function tag_CustomImageField(&$content, &$attachments, $config) { | |
$customImages = array(); | |
if ($config['custom_image_field']) { | |
DebugEcho("Looking for custom images"); | |
//DebugDump($attachments["html"]); | |
foreach ($attachments["html"] as $key => $value) { | |
//DebugEcho("checking " . htmlentities($value)); | |
if (preg_match("/src\s*=\s*['\"]([^'\"]*)['\"]/i", $value, $matches)) { | |
DebugEcho("found custom image: " . $matches[1]); | |
array_push($customImages, $matches[1]); | |
} | |
} | |
} | |
return $customImages; | |
} | |
/** | |
* Special Vodafone handler - their messages are mostly vendor trash - this strips them down. | |
*/ | |
function filter_VodafoneHandler(&$content, &$attachments, $config) { | |
if (preg_match('/You have been sent a message from Vodafone mobile/', $content)) { | |
DebugEcho("Vodafone message"); | |
$index = strpos($content, "TEXT:"); | |
if (strpos !== false) { | |
$alt_content = substr($content, $index, strlen($content)); | |
if (preg_match("/<font face=\"verdana,helvetica,arial\" class=\"standard\" color=\"#999999\"><b>(.*)<\/b>/", $alt_content, $matches)) { | |
//The content is now just the text of the message | |
$content = $matches[1]; | |
//Now to clean up the attachments | |
$vodafone_images = array("live.gif", "smiley.gif", "border_left_txt.gif", "border_top.gif", "border_bot.gif", "border_right.gif", "banner1.gif", "i_text.gif", "i_picture.gif",); | |
while (list($key, $value) = each($attachments['cids'])) { | |
if (!in_array($key, $vodafone_images)) { | |
$content .= "<br/>" . $attachments['html'][$attachments['cids'][$key][1]]; | |
} | |
} | |
} | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment