Postie - Version 1.9.44

Version Description

(2020-03-23) = * refactoring to separate email fetch from email processing * add postie_register_shortcode_pre action for registering Postie shortcodes

Download this release

Release Info

Developer WayneAllen
Plugin Icon 128x128 Postie
Version 1.9.44
Comparing to
See all releases

Code changes from version 1.9.43 to 1.9.44

docs/Changes.txt CHANGED
@@ -35,6 +35,10 @@ All script, style and body tags are stripped from html emails.
35
  Attachments are now processed in the order they were attached.
36
 
37
  == CHANGELOG ==
 
 
 
 
38
  = 1.9.43 (2020-02-18) =
39
  * Begin migration of shortcode support into Postie main
40
 
35
  Attachments are now processed in the order they were attached.
36
 
37
  == CHANGELOG ==
38
+ = 1.9.44 (2020-03-23) =
39
+ * refactoring to separate email fetch from email processing
40
+ * add postie_register_shortcode_pre action for registering Postie shortcodes
41
+
42
  = 1.9.43 (2020-02-18) =
43
  * Begin migration of shortcode support into Postie main
44
 
docs/Postie.txt CHANGED
@@ -6,8 +6,8 @@ Plugin URI: http://PostiePlugin.com/
6
  Tags: e-mail, email, post-by-email
7
  Requires PHP: 5.3
8
  Requires at least: 4.0
9
- Tested up to: 5.3
10
- Stable tag: 1.9.43
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
6
  Tags: e-mail, email, post-by-email
7
  Requires PHP: 5.3
8
  Requires at least: 4.0
9
+ Tested up to: 5.4
10
+ Stable tag: 1.9.44
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
postie-api.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie-config.class.php');
4
  require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie.class.php');
 
5
 
6
  /*
7
  * These are the only official public methods for accessing postie functionality
@@ -16,7 +17,9 @@ function lookup_category($trial_category, $category_match) {
16
  }
17
 
18
  function RemoveExtraCharactersInEmailAddress($address) {
19
- return postie_RemoveExtraCharactersInEmailAddress($address);
 
 
20
  }
21
 
22
  function EchoError($v) {
2
 
3
  require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie-config.class.php');
4
  require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie.class.php');
5
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie-message.php');
6
 
7
  /*
8
  * These are the only official public methods for accessing postie functionality
17
  }
18
 
19
  function RemoveExtraCharactersInEmailAddress($address) {
20
+ $c = new PostieConfig();
21
+ $m = new PostieMessage(array(), $c->config_read());
22
+ return $m->remove_extra_characters_in_email_address($address);
23
  }
24
 
25
  function EchoError($v) {
postie-config.class.php CHANGED
@@ -10,6 +10,8 @@ class PostieConfigOptions {
10
  const CategoryColon = 'category_colon';
11
  const PostFormat = 'post_format';
12
  const ImageResize = 'image_resize';
 
 
13
 
14
  }
15
 
@@ -174,11 +176,11 @@ class PostieConfig {
174
  'icon_size' => 32,
175
  'auto_gallery' => false,
176
  'image_new_window' => false,
177
- 'image_placeholder' => "#img%#",
178
  'images_append' => true,
179
  'imagetemplate' => $wordpress_default,
180
  'imagetemplates' => $imageTemplates,
181
- 'input_protocol' => "pop3",
182
  'input_connection' => 'sockets',
183
  'interval' => 'twiceperhour',
184
  'mail_server' => NULL,
@@ -186,9 +188,9 @@ class PostieConfig {
186
  'mail_userid' => NULL,
187
  'mail_password' => NULL,
188
  'maxemails' => 0,
189
- 'message_start' => "",
190
- 'message_end' => "",
191
- 'message_encoding' => "UTF-8",
192
  'message_dequote' => true,
193
  'post_status' => 'publish',
194
  'prefer_text_type' => 'plain',
10
  const CategoryColon = 'category_colon';
11
  const PostFormat = 'post_format';
12
  const ImageResize = 'image_resize';
13
+ const DefaultTitle = 'default_title';
14
+ const TurnAuthorizationOff = 'turn_authorization_off';
15
 
16
  }
17
 
176
  'icon_size' => 32,
177
  'auto_gallery' => false,
178
  'image_new_window' => false,
179
+ 'image_placeholder' => '#img%#',
180
  'images_append' => true,
181
  'imagetemplate' => $wordpress_default,
182
  'imagetemplates' => $imageTemplates,
183
+ 'input_protocol' => 'pop3',
184
  'input_connection' => 'sockets',
185
  'interval' => 'twiceperhour',
186
  'mail_server' => NULL,
188
  'mail_userid' => NULL,
189
  'mail_password' => NULL,
190
  'maxemails' => 0,
191
+ 'message_start' => '',
192
+ 'message_end' => '',
193
+ 'message_encoding' => 'UTF-8',
194
  'message_dequote' => true,
195
  'post_status' => 'publish',
196
  'prefer_text_type' => 'plain',
postie-message.php ADDED
@@ -0,0 +1,1413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class PostieMessage {
4
+
5
+ private $email;
6
+ private $config;
7
+ private $poster = 0;
8
+ private $post_id = 0;
9
+ private $is_reply = false;
10
+ public $content = '';
11
+ public $subject = '';
12
+
13
+ public function __construct($email, $config) {
14
+
15
+ $this->config = $config;
16
+
17
+ if (is_array($email)) {
18
+ if (!isset($email['html'])) {
19
+ $email['html'] = '';
20
+ }
21
+ if (!isset($email['text'])) {
22
+ $email['text'] = '';
23
+ }
24
+ if (!empty($email['html'])) {
25
+ DebugEcho("getemails: html");
26
+ $email['html'] = filter_CleanHtml($email['html']);
27
+ } else {
28
+ DebugEcho("getemails: no html");
29
+ }
30
+
31
+ if ($config['prefer_text_convert']) {
32
+ if ($config['prefer_text_type'] == 'plain' && trim($email['text']) == '' && trim($email['html']) != '') {
33
+ DebugEcho('get_mail: switching to html');
34
+ $this->config['prefer_text_type'] = 'html';
35
+ }
36
+ if ($config['prefer_text_type'] == 'html' && trim($email['html']) == '' && trim($email['text']) != '') {
37
+ DebugEcho('get_mail: switching to plain');
38
+ $this->config['prefer_text_type'] = 'plain';
39
+ }
40
+ }
41
+ }
42
+
43
+ $this->email = $email;
44
+ }
45
+
46
+ function is_debugmode() {
47
+ return (defined('POSTIE_DEBUG') && POSTIE_DEBUG == true);
48
+ }
49
+
50
+ function is_empty() {
51
+ return $this->email == null;
52
+ }
53
+
54
+ function is_read() {
55
+ return $this->email == 'already read';
56
+ }
57
+
58
+ function do_shortcodes($action, $details) {
59
+ //get and save WP shortcodes
60
+ global $shortcode_tags;
61
+ $tmpshortcode = $shortcode_tags;
62
+ $shortcode_tags = array();
63
+
64
+ //add Postie specific shortcodes
65
+ DebugEcho("process: filter: Before $action");
66
+ do_action($action);
67
+
68
+ //make the post details available to the shortcode handlers
69
+ global $postie_post;
70
+ $postie_post = $details;
71
+
72
+ //fix quoting
73
+ $content = $postie_post['post_content'];
74
+ $char = array('&quot;', '&#8216;', '&#8217;', '&#8220;', '&#8221;', '&#8242;', '&#8243;');
75
+ $replace = array('"', "'", "'", '"', '"', "'", '"');
76
+ $content = str_replace($char, $replace, $content);
77
+
78
+ $postie_post['post_content'] = do_shortcode($content);
79
+
80
+ //restore the WP shortcodes
81
+ $shortcode_tags = $tmpshortcode;
82
+ }
83
+
84
+ function preprocess() {
85
+ DebugEcho("preprocess: Starting");
86
+ $this->disable_revisions();
87
+
88
+ /* in order to do attachments correctly, we need to associate the
89
+ attachments with a post. So we add the post here, then update it */
90
+ $tmpPost = array('post_title' => 'tmptitle', 'post_content' => 'tmpPost', 'post_status' => 'draft');
91
+ $this->post_id = wp_insert_post($tmpPost, true);
92
+ if (!is_wp_error($this->post_id)) {
93
+ DebugEcho("preprocess: tmp post id is $this->post_id");
94
+ } else {
95
+ EchoError("preprocess: wp_insert_post failed: " . $this->post_id->get_error_message());
96
+ DebugDump($this->post_id->get_error_messages());
97
+ DebugDump($this->post_id->get_error_data());
98
+ $this->notify_error("preprocess: wp_insert_post failed creating placeholder", $this->post_id->get_error_message());
99
+ }
100
+ DebugEcho("preprocess: Done");
101
+ }
102
+
103
+ function process() {
104
+ DebugEcho("process: Starting");
105
+
106
+ if (is_wp_error($this->post_id)) {
107
+ EchoError('process: Ignoring email - failed creating placeholder.');
108
+ return;
109
+ }
110
+
111
+ //Check poster to see if a valid person
112
+ $this->poster = $this->validate_poster();
113
+ if (empty($this->poster)) {
114
+ EchoError('process: Ignoring email - not authorized.');
115
+ return;
116
+ }
117
+
118
+ DebugEcho("process: filter: pre postie_post_pre");
119
+ $this->email = apply_filters('postie_post_pre', $this->email);
120
+
121
+ $this->content = $this->get_content();
122
+
123
+ $this->get_subject();
124
+
125
+ $details = $this->create_post();
126
+
127
+ $this->do_shortcodes('postie_register_shortcode_pre', $details);
128
+
129
+ DebugEcho("process: filter: Before postie_post_before");
130
+ $details = apply_filters('postie_post', $details);
131
+ $details = apply_filters('postie_post_before', $details, $this->email['headers']);
132
+ DebugEcho("process: filter: After postie_post_before");
133
+ DebugDump($details);
134
+
135
+ if (empty($details)) {
136
+ // It is possible that the filter has removed the post, in which case, it should not be posted.
137
+ // And if we created a placeholder post (because this was not a reply to an existing post),
138
+ // then it should be removed
139
+ if (!$this->is_reply) {
140
+ wp_delete_post($this->post_id);
141
+ DebugEcho("post_email: postie_post filter cleared the post, not saving. deleted $this->post_id");
142
+ } else {
143
+ DebugEcho("post_email: postie_post ended up with no post array.");
144
+ }
145
+ return;
146
+ }
147
+
148
+
149
+
150
+ $postid = $this->save_post($details, $this->is_reply);
151
+
152
+ $recipients = array();
153
+ $dest = $this->config['confirmation_email'];
154
+ if ($dest == 'sender' || $dest == 'both') {
155
+ $recipients[] = $details['email_author'];
156
+ }
157
+ if ($dest == 'admin' || $dest == 'both') {
158
+ foreach (get_users(array('role' => 'administrator', 'blog_id' => get_current_blog_id())) as $user) {
159
+ $recipients[] = $user->user_email;
160
+ }
161
+ }
162
+ if (!($dest == 'admin' || $dest == 'sender' || $dest == 'both' || $dest == '')) {
163
+ $user = get_user_by('login', $dest);
164
+ $recipients[] = $user->user_email;
165
+ }
166
+
167
+ DebugEcho("post_email: sending notifications");
168
+ $this->email_notify($this->email, $recipients, $postid);
169
+
170
+ if ($this->is_debugmode()) {
171
+ $post = get_post($this->post_id);
172
+ DebugEcho("post_email: resulting post");
173
+ DebugDump($post);
174
+ }
175
+
176
+ DebugEcho("process: Done");
177
+
178
+ return $details;
179
+ }
180
+
181
+ function postprocess() {
182
+
183
+ $this->restore_revisions();
184
+ DebugEcho("postprocess: Done");
185
+ }
186
+
187
+ /**
188
+ * This method works around a problem with email address with extra <> in the email address
189
+ * @param string
190
+ * @return string
191
+ */
192
+ function remove_extra_characters_in_email_address($address) {
193
+ $matches = array();
194
+ if (preg_match('/^[^<>]+<([^<> ()]+)>$/', $address, $matches)) {
195
+ $address = $matches[1];
196
+ DebugEcho("RemoveExtraCharactersInEmailAddress: $address (1)");
197
+ DebugDump($matches);
198
+ } else if (preg_match('/<([^<> ()]+)>/', $address, $matches)) {
199
+ $address = $matches[1];
200
+ DebugEcho("RemoveExtraCharactersInEmailAddress: $address (2)");
201
+ }
202
+
203
+ return $address;
204
+ }
205
+
206
+ /**
207
+ * This compares the current address to the list of authorized addresses
208
+ * @param string - email address
209
+ * @return boolean
210
+ */
211
+ function is_email_authorized($address, $authorized) {
212
+ $r = false;
213
+ if (is_array($authorized)) {
214
+ $a = strtolower(trim($address));
215
+ if (!empty($a)) {
216
+ $r = in_array($a, array_map('strtolower', $authorized));
217
+ }
218
+ }
219
+ return $r;
220
+ }
221
+
222
+ /**
223
+ * Determines if the sender is a valid user.
224
+ * @return integer|NULL
225
+ */
226
+ function validate_poster() {
227
+ $poster = null;
228
+ $from = '';
229
+
230
+ if (array_key_exists('headers', $this->email) && array_key_exists('from', $this->email['headers'])) {
231
+ $from = $this->email['headers']['from']['mailbox'] . '@' . $this->email['headers']['from']['host'];
232
+ $from = apply_filters('postie_filter_email', $from);
233
+ DebugEcho("validate_poster: post postie_filter_email $from");
234
+
235
+ $toEmail = '';
236
+ if (isset($this->email['headers']['to'])) {
237
+ $toEmail = $this->email['headers']['to'][0]['mailbox'] . '@' . $this->email['headers']['to'][0]['host'];
238
+ }
239
+
240
+ $replytoEmail = '';
241
+ if (isset($this->email['headers']['reply-to'])) {
242
+ $replytoEmail = $this->email['headers']['reply-to']['mailbox'] . '@' . $this->email['headers']['reply-to']['host'];
243
+ }
244
+
245
+ $from = apply_filters("postie_filter_email2", $from, $toEmail, $replytoEmail);
246
+ DebugEcho("validate_poster: post postie_filter_email2 $from");
247
+ } else {
248
+ DebugEcho("validate_poster: No 'from' header found");
249
+ DebugDump($this->email['headers']);
250
+ }
251
+
252
+ if (array_key_exists('headers', $this->email)) {
253
+ $from = apply_filters("postie_filter_email3", $from, $this->email['headers']);
254
+ DebugEcho("validate_poster: post postie_filter_email3 $from");
255
+ }
256
+
257
+ $resentFrom = '';
258
+ if (array_key_exists('headers', $this->email) && array_key_exists('resent-from', $this->email['headers'])) {
259
+ $resentFrom = $this->remove_extra_characters_in_email_address(trim($this->email['headers']['resent-from']));
260
+ }
261
+
262
+ //See if the email address is one of the special authorized ones
263
+ $user_ID = '';
264
+ if (!empty($from)) {
265
+ DebugEcho("validate_poster: Confirming Access For $from ");
266
+ $user = get_user_by('email', $from);
267
+ if ($user !== false) {
268
+ if (is_user_member_of_blog($user->ID)) {
269
+ $user_ID = $user->ID;
270
+ } else {
271
+ DebugEcho("validate_poster: $from is not user of blog " . get_current_blog_id());
272
+ }
273
+ }
274
+ }
275
+
276
+ if (!empty($user_ID)) {
277
+ $user = new WP_User($user_ID);
278
+ if ($user->has_cap('post_via_postie')) {
279
+ DebugEcho("validate_poster: $user_ID has 'post_via_postie' permissions");
280
+ $poster = $user_ID;
281
+
282
+ DebugEcho("validate_poster: pre postie_author $poster");
283
+ $poster = apply_filters("postie_author", $poster);
284
+ DebugEcho("validate_poster: post postie_author $poster");
285
+ } else {
286
+ DebugEcho("validate_poster $user_ID does not have 'post_via_postie' permissions");
287
+ $user_ID = "";
288
+ }
289
+ }
290
+
291
+ if (empty($user_ID) && ($this->config['turn_authorization_off'] || $this->is_email_authorized($from, $this->config['authorized_addresses']) || $this->is_email_authorized($resentFrom, $this->config['authorized_addresses']))) {
292
+ DebugEcho("validate_poster: looking up default user " . $this->config['admin_username']);
293
+ $user = get_user_by('login', $this->config['admin_username']);
294
+ if ($user === false) {
295
+ EchoError("Your 'Default Poster' setting '" . $this->config['admin_username'] . "' is not a valid WordPress user (2)");
296
+ $poster = 1;
297
+ } else {
298
+ $poster = $user->ID;
299
+ DebugEcho("validate_poster: pre postie_author (default) $poster");
300
+ $poster = apply_filters("postie_author", $poster);
301
+ DebugEcho("validate_poster: post postie_author (default) $poster");
302
+ }
303
+ DebugEcho("validate_poster: found user '$poster'");
304
+ }
305
+
306
+ if (!$poster) {
307
+ EchoError('Invalid sender: ' . htmlentities($from) . "! Not adding email!");
308
+ if ($this->config['forward_rejected_mail']) {
309
+ $this->email_reject();
310
+ EchoError("A copy of the message has been forwarded to the administrator.");
311
+ }
312
+ return '';
313
+ }
314
+
315
+ //actually log in as the user
316
+ if ($this->config['force_user_login'] == true) {
317
+ $user = get_user_by('id', $poster);
318
+ if ($user) {
319
+ DebugEcho("validate_poster: logging in as {$user->user_login}");
320
+ wp_set_current_user($poster);
321
+ //wp_set_auth_cookie($poster);
322
+ do_action('wp_login', $user->user_login, $user);
323
+ } else {
324
+ DebugEcho("validate_poster: couldn't find $poster to force login");
325
+ }
326
+ }
327
+ return $poster;
328
+ }
329
+
330
+ function header_encode($value) {
331
+ return "=?utf-8?b?" . base64_encode($value) . "?= ";
332
+ }
333
+
334
+ function email_reject() {
335
+ DebugEcho("email_reject: start");
336
+
337
+ $recipients = array(get_option('admin_email'));
338
+ $returnToSender = $this->config['return_to_sender'];
339
+
340
+ $blogname = get_option('blogname');
341
+ $from = $this->email['headers']['from']['mailbox'] . '@' . $this->email['headers']['from']['host'];
342
+
343
+ $subject = $this->email['headers']['subject'];
344
+ if ($returnToSender) {
345
+ DebugEcho("email_reject: return to sender $from");
346
+ array_push($recipients, $from);
347
+ }
348
+
349
+ $eblogname = $this->header_encode($blogname);
350
+ $adminemail = get_option('admin_email');
351
+
352
+ $headers = array();
353
+ $headers[] = "From: $eblogname <$adminemail>";
354
+
355
+ DebugEcho("email_reject: To:");
356
+ DebugDump($recipients);
357
+ DebugEcho("email_reject: header:");
358
+ DebugDump($headers);
359
+
360
+ $message = "An unauthorized message has been sent to $blogname.\n";
361
+ $message .= "Sender: $from\n";
362
+ $message .= "Subject: $subject\n";
363
+ $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 email found below.";
364
+ $message .= "\n\nOtherwise, the email has already been deleted from the server and you can ignore this message.";
365
+ $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";
366
+ $message .= "\n\nThe original content of the email has been attached.\n\n";
367
+
368
+ $recipients = apply_filters('postie_email_reject_recipients', $recipients, $this->email);
369
+ if (count($recipients) == 0) {
370
+ DebugEcho("email_reject: no recipients after postie_email_reject_recipients filter");
371
+ return;
372
+ } else {
373
+ DebugEcho("email_reject: post postie_email_reject_recipients");
374
+ DebugDump($recipients);
375
+ }
376
+
377
+ $subject = $blogname . ": Unauthorized Post Attempt from $from";
378
+ $subject = apply_filters('postie_email_reject_subject', $subject, $this->email);
379
+ DebugEcho("email_reject: post postie_email_reject_subject: $subject");
380
+
381
+ $message = apply_filters('postie_email_reject_body', $message, $this->email);
382
+ DebugEcho("email_reject: post postie_email_reject_body: $message");
383
+
384
+ $attachTxt = wp_tempnam() . '.txt';
385
+ file_put_contents($attachTxt, $this->email['text']);
386
+
387
+ $attachHtml = wp_tempnam() . '.htm';
388
+ file_put_contents($attachHtml, $this->email['html']);
389
+
390
+ wp_mail($recipients, $subject, $message, $headers, array($attachTxt, $attachHtml));
391
+
392
+ unlink($attachTxt);
393
+ unlink($attachHtml);
394
+ }
395
+
396
+ function disable_revisions() {
397
+ global $_wp_post_type_features, $_postie_revisions;
398
+
399
+ $_postie_revisions = false;
400
+ if (isset($_wp_post_type_features['post']) && isset($_wp_post_type_features['post']['revisions'])) {
401
+ $_postie_revisions = $_wp_post_type_features['post']['revisions'];
402
+ unset($_wp_post_type_features['post']['revisions']);
403
+ }
404
+ }
405
+
406
+ function restore_revisions() {
407
+ global $_wp_post_type_features, $_postie_revisions;
408
+
409
+ if ($_postie_revisions) {
410
+ $_wp_post_type_features['post']['revisions'] = $_postie_revisions;
411
+ }
412
+ }
413
+
414
+ function create_post() {
415
+ DebugEcho("create_post: prefer_text_type: " . $this->config['prefer_text_type']);
416
+
417
+ $fulldebug = $this->is_debugmode();
418
+ $fulldebugdump = false;
419
+
420
+ if (array_key_exists('message-id', $this->email['headers'])) {
421
+ DebugEcho("Message Id is :" . htmlentities($this->email['headers']['message-id']));
422
+ if ($fulldebugdump) {
423
+ DebugDump($this->email);
424
+ }
425
+ }
426
+
427
+ if ($fulldebugdump) {
428
+ DebugDump($this->email);
429
+ }
430
+
431
+ $this->save_attachments($this->post_id, $this->poster);
432
+
433
+ $this->content = filter_RemoveSignature($this->content, $this->config);
434
+ if ($fulldebug) {
435
+ DebugEcho("post filter_RemoveSignature: $this->content");
436
+ }
437
+
438
+ $this->content = filter_Newlines($this->content, $this->config);
439
+ if ($fulldebug) {
440
+ DebugEcho("post filter_Newlines: $this->content");
441
+ }
442
+
443
+ $post_excerpt = tag_Excerpt($this->content, $this->config);
444
+ if ($fulldebug) {
445
+ DebugEcho("post tag_Excerpt: $this->content");
446
+ }
447
+
448
+ $postAuthorDetails = $this->post_author_details();
449
+ if ($fulldebug) {
450
+ DebugEcho("post getPostAuthorDetails: $this->content");
451
+ }
452
+
453
+ $message_date = NULL;
454
+ $delay = 0;
455
+ if (array_key_exists('date', $this->email['headers']) && !empty($this->email['headers']['date'])) {
456
+ DebugEcho("date header: {$this->email['headers']['date']}");
457
+ if ($this->config['ignore_email_date']) {
458
+ $message_date = current_time('mysql');
459
+ DebugEcho("system date: $message_date");
460
+ } else {
461
+ $message_date = $this->email['headers']['date'];
462
+ DebugEcho("decoded date: $message_date");
463
+ list($message_date, $delay) = tag_Delay($this->content, $message_date, $this->config);
464
+ if ($fulldebug) {
465
+ DebugEcho("post tag_Delay: $this->content");
466
+ }
467
+ }
468
+ } else {
469
+ DebugEcho('date header missing');
470
+ $message_date = current_time('mysql');
471
+ }
472
+
473
+ $post_date = tag_Date($this->content, $message_date);
474
+ if ($fulldebug) {
475
+ DebugEcho("post tag_Date: $this->content");
476
+ }
477
+
478
+
479
+ //do post type before category to keep the subject line correct
480
+ $post_type_format = tag_PostType($this->subject, $this->config);
481
+ if ($fulldebug) {
482
+ DebugEcho("post tag_PostType: $this->content");
483
+ }
484
+
485
+ $default_categoryid = $this->config['default_post_category'];
486
+
487
+ DebugEcho("pre postie_category_default: '$default_categoryid'");
488
+ $default_categoryid = apply_filters('postie_category_default', $default_categoryid);
489
+ DebugEcho("post postie_category_default: '$default_categoryid'");
490
+
491
+ $post_categories = tag_Categories($this->subject, $default_categoryid, $this->config, $this->post_id);
492
+ if ($fulldebug) {
493
+ DebugEcho("post tag_Categories: $this->content");
494
+ }
495
+
496
+ $post_tags = tag_Tags($this->content, $this->config);
497
+ if ($fulldebug) {
498
+ DebugEcho("post tag_Tags: $this->content");
499
+ }
500
+
501
+ $comment_status = tag_AllowCommentsOnPost($this->content);
502
+ if ($fulldebug) {
503
+ DebugEcho("post tag_AllowCommentsOnPost: $this->content");
504
+ }
505
+
506
+ $post_status = tag_Status($this->content, $this->config);
507
+ if ($fulldebug) {
508
+ DebugEcho("post tag_Status: $this->content");
509
+ }
510
+
511
+ //handle CID before linkify
512
+ $this->content = filter_ReplaceImageCIDs($this->content, $this->email);
513
+ if ($fulldebug) {
514
+ DebugEcho("post filter_ReplaceImageCIDs: $this->content");
515
+ }
516
+
517
+ if ($this->config['converturls']) {
518
+ $this->content = filter_Linkify($this->content);
519
+ if ($fulldebug) {
520
+ DebugEcho("post filter_Linkify: $this->content");
521
+ }
522
+ }
523
+
524
+ if ($this->config['reply_as_comment'] == true) {
525
+ $id = $this->parent_post($this->subject);
526
+ if (empty($id)) {
527
+ DebugEcho("Not a reply");
528
+ $id = $this->post_id;
529
+ $this->is_reply = false;
530
+ } else {
531
+ DebugEcho("Reply detected");
532
+ $this->is_reply = true;
533
+ if (true == $this->config['strip_reply']) {
534
+ // strip out quoted content
535
+ $lines = explode("\n", $this->content);
536
+ $newContents = '';
537
+ foreach ($lines as $line) {
538
+ if (preg_match("/^>.*/i", $line) == 0 &&
539
+ preg_match("/^(from|subject|to|date):.*?/iu", $line) == 0 &&
540
+ preg_match("/^-+.*?(from|subject|to|date).*?/iu", $line) == 0 &&
541
+ preg_match("/^on.*?wrote:$/iu", $line) == 0 &&
542
+ preg_match("/^-+\s*forwarded\s*message\s*-+/iu", $line) == 0) {
543
+ $newContents .= "$line\n";
544
+ }
545
+ }
546
+ if ((strlen($newContents) <> strlen($this->content)) && ('html' == $this->config['prefer_text_type'])) {
547
+ DebugEcho("Attempting to fix reply html (before): $newContents");
548
+ $newContents = $this->load_html($newContents)->__toString();
549
+ DebugEcho("Attempting to fix reply html (after): $newContents");
550
+ }
551
+ $this->content = $newContents;
552
+ }
553
+ wp_delete_post($this->post_id);
554
+ }
555
+ } else {
556
+ $id = $this->post_id;
557
+ DebugEcho("Replies will not be processed as comments");
558
+ }
559
+
560
+ if ($delay > 0 && $post_status == 'publish') {
561
+ DebugEcho("publish in future");
562
+ $post_status = 'future';
563
+ }
564
+
565
+ $this->content = filter_Start($this->content, $this->config);
566
+ if ($fulldebug) {
567
+ DebugEcho("post filter_Start: $this->content");
568
+ }
569
+
570
+ $this->content = filter_End($this->content, $this->config);
571
+ if ($fulldebug) {
572
+ DebugEcho("post filter_End: $this->content");
573
+ }
574
+
575
+ $this->content = filter_ReplaceImagePlaceHolders($this->content, $this->email, $this->config, $id, $this->config['image_placeholder']);
576
+ if ($fulldebug) {
577
+ DebugEcho("post filter_ReplaceImagePlaceHolders: $this->content");
578
+ }
579
+
580
+ if ($post_excerpt) {
581
+ $post_excerpt = filter_ReplaceImagePlaceHolders($post_excerpt, $this->email, $this->config, $id, '#eimg%#');
582
+ DebugEcho("excerpt: $post_excerpt");
583
+ if ($fulldebug) {
584
+ DebugEcho("post excerpt ReplaceImagePlaceHolders: $this->content");
585
+ }
586
+ }
587
+
588
+ //handle inline images after linkify
589
+ if ('plain' == $this->config['prefer_text_type']) {
590
+ $this->content = filter_ReplaceInlineImage($this->content, $this->email, $this->config);
591
+ if ($fulldebug) {
592
+ DebugEcho("post filter_ReplaceInlineImage: $this->content");
593
+ }
594
+ }
595
+
596
+ $this->content = filter_AttachmentTemplates($this->content, $this->email, $this->post_id, $this->config);
597
+
598
+ $details = array(
599
+ 'post_author' => $this->poster,
600
+ 'comment_author' => $postAuthorDetails['author'],
601
+ 'comment_author_url' => $postAuthorDetails['comment_author_url'],
602
+ 'user_ID' => $postAuthorDetails['user_ID'],
603
+ 'email_author' => $postAuthorDetails['email'],
604
+ 'post_date' => $post_date,
605
+ 'post_date_gmt' => get_gmt_from_date($post_date),
606
+ 'post_content' => $this->content,
607
+ 'post_title' => $this->subject,
608
+ 'post_type' => $post_type_format['post_type'],
609
+ 'ping_status' => get_option('default_ping_status'),
610
+ 'post_category' => $post_categories,
611
+ 'tags_input' => $post_tags,
612
+ 'comment_status' => $comment_status,
613
+ 'post_name' => $this->subject,
614
+ 'post_excerpt' => $post_excerpt,
615
+ 'ID' => $id,
616
+ 'post_status' => $post_status
617
+ );
618
+
619
+ //don't need to specify the post format to get a "standard" post
620
+ if ($post_type_format['post_format'] !== 'standard') {
621
+ //need to set post format differently since it is a type of taxonomy
622
+ DebugEcho("Setting post format to {$post_type_format['post_format']}");
623
+ wp_set_post_terms($this->post_id, $post_type_format['post_format'], 'post_format');
624
+ }
625
+
626
+ return $details;
627
+ }
628
+
629
+ function save_post($details, $isReply) {
630
+ $post_ID = 0;
631
+ $details['post_content'] = str_replace('\\', '\\\\', $details['post_content']); //replace all backslashs with double backslashes since WP will remove single backslash
632
+ if (!$isReply) {
633
+ DebugEcho("postie_save_post: about to insert post");
634
+ $post_ID = wp_insert_post($details, true);
635
+ if (is_wp_error($post_ID)) {
636
+ EchoError("PostToDB Error: " . $post_ID->get_error_message());
637
+ DebugDump($post_ID->get_error_messages());
638
+ DebugDump($post_ID->get_error_data());
639
+ wp_delete_post($details['ID']);
640
+
641
+ $this->notify_error("Failed to create {$details['post_type']}: {$details['post_title']}", "Error: " . $post_ID->get_error_message() . "\n\n" . $details['post_content']);
642
+
643
+ $post_ID = null;
644
+ } else {
645
+ DebugEcho("postie_save_post: post inserted");
646
+ }
647
+ } else {
648
+ DebugEcho("postie_save_post: inserting comment");
649
+ $comment = array(
650
+ 'comment_author' => $details['comment_author'],
651
+ 'comment_post_ID' => $details['ID'],
652
+ 'comment_author_email' => $details['email_author'],
653
+ 'comment_date' => $details['post_date'],
654
+ 'comment_date_gmt' => $details['post_date_gmt'],
655
+ 'comment_content' => $details['post_content'],
656
+ 'comment_author_url' => $details['comment_author_url'],
657
+ 'comment_author_IP' => '',
658
+ 'comment_approved' => 1,
659
+ 'comment_agent' => '',
660
+ 'comment_type' => '',
661
+ 'comment_parent' => 0,
662
+ 'user_id' => $details['user_ID']
663
+ );
664
+ $comment = apply_filters('postie_comment_before', $comment);
665
+ DebugEcho("postie_save_post: post postie_comment_before");
666
+ DebugDump($comment);
667
+
668
+ $post_ID = wp_new_comment($comment);
669
+
670
+ DebugEcho("doing postie_comment_after");
671
+ do_action('postie_comment_after', $comment);
672
+ }
673
+
674
+ if ($post_ID) {
675
+ DebugEcho("doing postie_post_after");
676
+ do_action('postie_post_after', $details);
677
+ }
678
+
679
+ return $post_ID;
680
+ }
681
+
682
+ function notify_error($subject, $message) {
683
+ $recipients = array();
684
+ if ($this->config['postie_log_error_notify'] == '(Nobody)') {
685
+ return;
686
+ }
687
+ if ($this->config['postie_log_error_notify'] == '(All Admins)') {
688
+ foreach (get_users(array('role' => 'administrator', 'blog_id' => get_current_blog_id())) as $user) {
689
+ $recipients[] = $user->user_email;
690
+ }
691
+ if (count($recipients) == 0) {
692
+ return;
693
+ }
694
+ } else {
695
+ $user = get_user_by('login', $this->config['postie_log_error_notify']);
696
+ if ($user === false) {
697
+ return;
698
+ }
699
+ $recipients[] = $user->user_login;
700
+ }
701
+
702
+ $message = "This message has been sent from " . get_site_url() . ". You can disable or control who receives them by changing the Postie 'Notify on Error' setting.\n\n" . $message;
703
+ wp_mail($recipients, $subject, $message);
704
+ }
705
+
706
+ function email_notify($recipients, $postid) {
707
+ DebugEcho("email_notify: start");
708
+
709
+ if (empty($postid)) {
710
+ DebugEcho("email_notify: no post id");
711
+ return;
712
+ }
713
+
714
+ $myemailadd = get_option("admin_email");
715
+ $blogname = get_option("blogname");
716
+ $eblogname = "=?utf-8?b?" . base64_encode($blogname) . "?= ";
717
+ $posturl = get_permalink($postid);
718
+ $subject = $this->email['headers']['subject'];
719
+
720
+ $sendheaders = array("From: $eblogname <$myemailadd>");
721
+
722
+ $post_status = get_post_status($postid);
723
+
724
+ $mailtext = "Your email '$subject' has been successfully imported into $blogname $posturl with the current status of '$post_status'.\n";
725
+
726
+ $recipients = apply_filters('postie_email_notify_recipients', $recipients, $this->email, $postid);
727
+ if (count($recipients) == 0) {
728
+ DebugEcho("email_notify: no recipients after postie_email_notify_recipients filter");
729
+ return;
730
+ } else {
731
+ DebugEcho("email_notify: post postie_email_notify_recipients");
732
+ DebugDump($recipients);
733
+ }
734
+ $subject = "Email imported to $blogname ($post_status)";
735
+ $subject = apply_filters('postie_email_notify_subject', $subject, $this->email, $postid);
736
+ DebugEcho("email_notify: post postie_email_notify_subject: $subject");
737
+
738
+ $mailtext = apply_filters('postie_email_notify_body', $mailtext, $this->email, $postid);
739
+ DebugEcho("email_notify: post postie_email_notify_body: $mailtext");
740
+
741
+ wp_mail($recipients, $subject, $mailtext, $sendheaders);
742
+ }
743
+
744
+ function save_attachments($post_id, $poster) {
745
+ DebugEcho('save_attachments: ---- start');
746
+
747
+ if (!isset($this->email['attachment'])) {
748
+ $this->email['attachment'] = array();
749
+ }
750
+ if (!isset($this->email['inline'])) {
751
+ $this->email['inline'] = array();
752
+ }
753
+ if (!isset($this->email['related'])) {
754
+ $this->email['related'] = array();
755
+ }
756
+
757
+ DebugEcho("save_attachments: [attachment]");
758
+ $this->save_attachments_worker($this->email['attachment'], $post_id, $poster);
759
+ DebugEcho("save_attachments: [inline]");
760
+ $this->save_attachments_worker($this->email['inline'], $post_id, $poster);
761
+ DebugEcho("save_attachments: [related]");
762
+ $this->save_attachments_worker($this->email['related'], $post_id, $poster);
763
+
764
+ DebugEcho("save_attachments: ==== end");
765
+ }
766
+
767
+ function save_attachments_worker(&$attachments, $post_id, $poster) {
768
+ DebugEcho("save_attachments_worker: start");
769
+ foreach ($attachments as &$attachment) {
770
+ foreach ($attachment as $key => $value) {
771
+ if ($key != 'data') {
772
+ DebugEcho("save_attachments_worker: [$key]: $value");
773
+ }
774
+ }
775
+ if (array_key_exists('filename', $attachment) && !empty($attachment['filename'])) {
776
+ DebugEcho('save_attachments_worker: ' . $attachment['filename']);
777
+
778
+ if ($this->is_banned_filename($attachment['filename'])) {
779
+ DebugEcho("save_attachments_worker: skipping banned filename " . $attachment['filename']);
780
+ continue;
781
+ }
782
+
783
+ if (false === apply_filters('postie_include_attachment', true, $attachment)) {
784
+ DebugEcho("save_attachments_worker: skipping filename by filter " . $attachment['filename']);
785
+ continue;
786
+ }
787
+ } else {
788
+ DebugEcho('save_attachments_worker: un-named attachment');
789
+ }
790
+
791
+ $this->save_attachment($attachment, $post_id, $poster);
792
+
793
+ $filename = $attachment['wp_filename'];
794
+ $fileext = $attachment['ext'];
795
+ $mparts = explode('/', $attachment['mimetype']);
796
+ $mimetype_primary = $mparts[0];
797
+ $mimetype_secondary = $mparts[1];
798
+ DebugEcho("save_attachments_worker: mime primary: $mimetype_primary");
799
+
800
+ $attachment['primary'] = $mimetype_primary;
801
+ $attachment['exclude'] = false;
802
+
803
+ $file_id = $attachment['wp_id'];
804
+ $file = wp_get_attachment_url($file_id);
805
+
806
+ switch ($mimetype_primary) {
807
+ case 'text':
808
+ DebugEcho("save_attachments_worker: text attachment");
809
+ $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $this->config['icon_set'], $this->config['icon_size']);
810
+ $attachment['template'] = "<a href='$file'>" . $icon . $filename . '</a>' . "\n";
811
+ break;
812
+
813
+ case 'image':
814
+ DebugEcho("save_attachments_worker: image attachment");
815
+ $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $this->config['imagetemplate'], $filename) . "\n";
816
+ break;
817
+
818
+ case 'audio':
819
+ DebugEcho("save_attachments_worker: audio attachment");
820
+ if (in_array($fileext, $this->config['audiotypes'])) {
821
+ DebugEcho("save_attachments_worker: using audio template: $mimetype_secondary");
822
+ $audioTemplate = $this->config['audiotemplate'];
823
+ } else {
824
+ DebugEcho("save_attachments_worker: using default audio template: $mimetype_secondary");
825
+ $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $this->config['icon_set'], $this->config['icon_size']);
826
+ $audioTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
827
+ }
828
+ $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $audioTemplate, $filename);
829
+ break;
830
+
831
+ case 'video':
832
+ DebugEcho("save_attachments_worker: video attachment");
833
+ if (in_array($fileext, $this->config['video1types'])) {
834
+ DebugEcho("save_attachments_worker: using video1 template: $fileext");
835
+ $videoTemplate = $this->config['video1template'];
836
+ } elseif (in_array($fileext, $this->config['video2types'])) {
837
+ DebugEcho("save_attachments_worker: using video2 template: $fileext");
838
+ $videoTemplate = $this->config['video2template'];
839
+ } else {
840
+ DebugEcho("save_attachments_worker: using default template: $fileext");
841
+ $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $this->config['icon_set'], $this->config['icon_size']);
842
+ $videoTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
843
+ }
844
+ $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $videoTemplate, $filename);
845
+ break;
846
+
847
+ default :
848
+ DebugEcho("save_attachments_worker: generic attachment ($mimetype_primary)");
849
+ $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $this->config['icon_set'], $this->config['icon_size']);
850
+ $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $this->config['generaltemplate'], $filename, $icon) . "\n";
851
+ break;
852
+ }
853
+ DebugEcho("save_attachments_worker: done with $filename");
854
+ }
855
+ DebugEcho("save_attachments_worker: end");
856
+ }
857
+
858
+ function save_attachment(&$attachment, $post_id, $poster) {
859
+
860
+ if (isset($attachment['filename']) && !empty($attachment['filename'])) {
861
+ $filename = $attachment['filename'];
862
+ } else {
863
+ DebugEcho("save_attachment: generating file name");
864
+ $filename = uniqid();
865
+ $mparts = explode('/', $attachment['mimetype']);
866
+ $attachment['filename'] = $filename . '.' . $mparts[1];
867
+ }
868
+
869
+ DebugEcho("save_attachment: pre sanitize file name '$filename'");
870
+ //DebugDump($part);
871
+ $filename = sanitize_file_name($filename);
872
+ $attachment['wp_filename'] = $filename;
873
+
874
+ DebugEcho("save_attachment: file name '$filename'");
875
+
876
+ $mparts = explode('/', $attachment['mimetype']);
877
+ $mimetype_primary = $mparts[0];
878
+ $mimetype_secondary = $mparts[1];
879
+
880
+ $fileext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
881
+ $attachment['ext'] = $fileext;
882
+ if (empty($fileext) && $mimetype_primary == 'image') {
883
+ $attachment['ext'] = $mimetype_secondary;
884
+ $filename = $filename . '.' . $mimetype_secondary;
885
+ $attachment['wp_filename'] = $filename;
886
+ $fileext = $mimetype_secondary;
887
+ DebugEcho("save_attachment: blank image extension, changed to $mimetype_secondary ($filename)");
888
+ }
889
+ DebugEcho("save_attachment: extension '$fileext'");
890
+
891
+ $typeinfo = wp_check_filetype($filename);
892
+ //DebugDump($typeinfo);
893
+ if (!empty($typeinfo['type'])) {
894
+ DebugEcho("save_attachment: secondary lookup found " . $typeinfo['type']);
895
+ $mimeparts = explode('/', strtolower($typeinfo['type']));
896
+ $mimetype_primary = $mimeparts[0];
897
+ $mimetype_secondary = $mimeparts[1];
898
+ } else {
899
+ DebugEcho("save_attachment: secondary lookup failed, checking configured extensions");
900
+ if (in_array($fileext, $this->config['audiotypes'])) {
901
+ DebugEcho("save_attachment: found audio extension");
902
+ $mimetype_primary = 'audio';
903
+ $mimetype_secondary = $fileext;
904
+ } elseif (in_array($fileext, array_merge($this->config['video1types'], $this->config['video2types']))) {
905
+ DebugEcho("save_attachment: found video extension");
906
+ $mimetype_primary = 'video';
907
+ $mimetype_secondary = $fileext;
908
+ } else {
909
+ DebugEcho("save_attachment: found no extension");
910
+ }
911
+ }
912
+ $attachment['mimetype'] = "$mimetype_primary/$mimetype_secondary";
913
+ DebugEcho("save_attachment: mimetype $mimetype_primary/$mimetype_secondary");
914
+
915
+ $attachment['wp_id'] = 0;
916
+
917
+ switch ($mimetype_primary) {
918
+ case 'text':
919
+ DebugEcho("save_attachment: ctype_primary: text");
920
+ //DebugDump($part);
921
+
922
+ DebugEcho("save_attachment: text Attachement: $filename");
923
+ $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
924
+ if (!is_wp_error($file_id)) {
925
+ $attachment['wp_id'] = $file_id;
926
+ DebugEcho("save_attachment: text attachment: adding '$filename'");
927
+ } else {
928
+ EchoError($file_id->get_error_message());
929
+ $this->notify_error("Failed to add text media file: $filename", $file_id->get_error_message());
930
+ }
931
+
932
+ break;
933
+
934
+ case 'image':
935
+ DebugEcho("save_attachment: image Attachement: $filename");
936
+ $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
937
+ if (!is_wp_error($file_id)) {
938
+ $attachment['wp_id'] = $file_id;
939
+ //set the first image we come across as the featured image
940
+ if ($this->config['featured_image'] && !has_post_thumbnail($post_id)) {
941
+ DebugEcho("save_attachment: featured image: $file_id");
942
+ set_post_thumbnail($post_id, $file_id);
943
+ }
944
+ } else {
945
+ EchoError("save_attachment image error: " . $file_id->get_error_message());
946
+ $this->notify_error("Failed to add image media file: $filename", $file_id->get_error_message());
947
+ }
948
+ break;
949
+
950
+ case 'audio':
951
+ DebugEcho("save_attachment: audio Attachement: $filename");
952
+ $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
953
+ if (!is_wp_error($file_id)) {
954
+ $attachment['wp_id'] = $file_id;
955
+ } else {
956
+ EchoError("save_attachment audio error: " . $file_id->get_error_message());
957
+ $this->notify_error("Failed to add audio media file: $filename", $file_id->get_error_message());
958
+ }
959
+ break;
960
+
961
+ case 'video':
962
+ DebugEcho("save_attachment: video Attachement: $filename");
963
+ $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
964
+ if (!is_wp_error($file_id)) {
965
+ $attachment['wp_id'] = $file_id;
966
+ } else {
967
+ EchoError("save_attachment video error: " . $file_id->get_error_message());
968
+ $this->notify_error("Failed to add video file: $filename", $file_id->get_error_message());
969
+ }
970
+ break;
971
+
972
+ default:
973
+ DebugEcho("save_attachment: found file type: " . $mimetype_primary);
974
+ if (in_array($mimetype_primary, $this->config['supported_file_types'])) {
975
+ //pgp signature - then forget it
976
+ if ($mimetype_secondary == 'pgp-signature') {
977
+ DebugEcho("save_attachment: found pgp-signature - done");
978
+ break;
979
+ }
980
+ $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
981
+ if (!is_wp_error($file_id)) {
982
+ $attachment['wp_id'] = $file_id;
983
+ $file = wp_get_attachment_url($file_id);
984
+ DebugEcho("save_attachment: uploaded $file_id ($file)");
985
+ } else {
986
+ EchoError("save_attachment file error: " . $file_id->get_error_message());
987
+ $this->notify_error("Failed to add media file: $filename", $file_id->get_error_message());
988
+ }
989
+ } else {
990
+ EchoError("$filename has an unsupported MIME type $mimetype_primary and was not added.");
991
+ DebugEcho("save_attachment: Not in supported filetype list: '$mimetype_primary'");
992
+ DebugDump($this->config['supported_file_types']);
993
+ $this->notify_error("Unsupported MIME type: $mimetype_primary", "$filename has an unsupported MIME type $mimetype_primary and was not added.\nSupported types:\n" . print_r($config['supported_file_types'], true));
994
+ }
995
+ break;
996
+ }
997
+ }
998
+
999
+ /**
1000
+ * Choose an appropriate file icon based on the extension and mime type of
1001
+ * the attachment
1002
+ */
1003
+ function choose_attachment_icon($file, $primary, $secondary, $iconSet = 'silver', $size = '32') {
1004
+ if ($iconSet == 'none') {
1005
+ return('');
1006
+ }
1007
+ $fileName = basename($file);
1008
+ $parts = explode('.', $fileName);
1009
+ $ext = $parts[count($parts) - 1];
1010
+ $docExts = array('doc', 'docx');
1011
+ $docMimes = array('msword', 'vnd.ms-word', 'vnd.openxmlformats-officedocument.wordprocessingml.document');
1012
+ $pptExts = array('ppt', 'pptx');
1013
+ $pptMimes = array('mspowerpoint', 'vnd.ms-powerpoint', 'vnd.openxmlformats-officedocument.');
1014
+ $xlsExts = array('xls', 'xlsx');
1015
+ $xlsMimes = array('msexcel', 'vnd.ms-excel', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet');
1016
+ $iWorkMimes = array('zip', 'octet-stream');
1017
+ $mpgExts = array('mpg', 'mpeg', 'mp2');
1018
+ $mpgMimes = array('mpg', 'mpeg', 'mp2');
1019
+ $mp3Exts = array('mp3');
1020
+ $mp3Mimes = array('mp3', 'mpeg3', 'mpeg');
1021
+ $mp4Exts = array('mp4', 'm4v');
1022
+ $mp4Mimes = array('mp4', 'mpeg4', 'octet-stream');
1023
+ $aacExts = array('m4a', 'aac');
1024
+ $aacMimes = array('m4a', 'aac', 'mp4');
1025
+ $aviExts = array('avi');
1026
+ $aviMimes = array('avi', 'x-msvideo');
1027
+ $movExts = array('mov');
1028
+ $movMimes = array('mov', 'quicktime');
1029
+ if ($ext == 'pdf' && $secondary == 'pdf') {
1030
+ $fileType = 'pdf';
1031
+ } else if ($ext == 'pages' && in_array($secondary, $iWorkMimes)) {
1032
+ $fileType = 'pages';
1033
+ } else if ($ext == 'numbers' && in_array($secondary, $iWorkMimes)) {
1034
+ $fileType = 'numbers';
1035
+ } else if ($ext == 'key' && in_array($secondary, $iWorkMimes)) {
1036
+ $fileType = 'key';
1037
+ } else if (in_array($ext, $docExts) && in_array($secondary, $docMimes)) {
1038
+ $fileType = 'doc';
1039
+ } else if (in_array($ext, $pptExts) && in_array($secondary, $pptMimes)) {
1040
+ $fileType = 'ppt';
1041
+ } else if (in_array($ext, $xlsExts) && in_array($secondary, $xlsMimes)) {
1042
+ $fileType = 'xls';
1043
+ } else if (in_array($ext, $mp4Exts) && in_array($secondary, $mp4Mimes)) {
1044
+ $fileType = 'mp4';
1045
+ } else if (in_array($ext, $movExts) && in_array($secondary, $movMimes)) {
1046
+ $fileType = 'mov';
1047
+ } else if (in_array($ext, $aviExts) && in_array($secondary, $aviMimes)) {
1048
+ $fileType = 'avi';
1049
+ } else if (in_array($ext, $mp3Exts) && in_array($secondary, $mp3Mimes)) {
1050
+ $fileType = 'mp3';
1051
+ } else if (in_array($ext, $mpgExts) && in_array($secondary, $mpgMimes)) {
1052
+ $fileType = 'mpg';
1053
+ } else if (in_array($ext, $aacExts) && in_array($secondary, $aacMimes)) {
1054
+ $fileType = 'aac';
1055
+ } else {
1056
+ $fileType = 'default';
1057
+ }
1058
+ $fileName = "/icons/$iconSet/$fileType-$size.png";
1059
+ if (!file_exists(POSTIE_ROOT . $fileName)) {
1060
+ $fileName = "/icons/$iconSet/default-$size.png";
1061
+ }
1062
+ $iconHtml = "<img src='" . POSTIE_URL . $fileName . "' alt='$fileType icon' />";
1063
+ DebugEcho("icon: $iconHtml");
1064
+ return $iconHtml;
1065
+ }
1066
+
1067
+ function parse_template($fileid, $type, $template, $orig_filename, $icon = "") {
1068
+ $template = trim($template);
1069
+ DebugEcho("parseTemplate: before '$template'");
1070
+
1071
+ $attachment = get_post($fileid);
1072
+ if (!empty($attachment)) {
1073
+ $uploadDir = wp_upload_dir();
1074
+ $fileName = basename($attachment->guid);
1075
+ $fileType = pathinfo($fileName, PATHINFO_EXTENSION);
1076
+ $absFileName = $uploadDir['path'] . '/' . $fileName;
1077
+ $relFileName = str_replace(ABSPATH, '', $absFileName);
1078
+ $fileLink = wp_get_attachment_url($fileid);
1079
+ $pageLink = get_attachment_link($fileid);
1080
+
1081
+ $template = str_replace('{TITLE}', $attachment->post_title, $template);
1082
+ $template = str_replace('{ID}', $fileid, $template);
1083
+
1084
+ if ($type == 'image') {
1085
+ $widths = array();
1086
+ $heights = array();
1087
+ $img_urls = array();
1088
+
1089
+ /*
1090
+ * Possible enhancement: support all sizes returned by get_intermediate_image_sizes()
1091
+ */
1092
+ $sizes = array('thumbnail', 'medium', 'large');
1093
+ for ($i = 0; $i < count($sizes); $i++) {
1094
+ $iinfo = image_downsize($fileid, $sizes[$i]);
1095
+ if (false !== $iinfo) {
1096
+ $img_urls[$i] = $iinfo[0];
1097
+ $widths[$i] = $iinfo[1];
1098
+ $heights[$i] = $iinfo[2];
1099
+ }
1100
+ }
1101
+ DebugEcho('parseTemplate: Sources');
1102
+ DebugDump($img_urls);
1103
+ DebugEcho('parseTemplate: Heights');
1104
+ DebugDump($heights);
1105
+ DebugEcho('parseTemplate: Widths');
1106
+ DebugDump($widths);
1107
+
1108
+ $template = str_replace('{THUMBNAIL}', $img_urls[0], $template);
1109
+ $template = str_replace('{THUMB}', $img_urls[0], $template);
1110
+ $template = str_replace('{MEDIUM}', $img_urls[1], $template);
1111
+ $template = str_replace('{LARGE}', $img_urls[2], $template);
1112
+ $template = str_replace('{THUMBWIDTH}', $widths[0] . 'px', $template);
1113
+ $template = str_replace('{THUMBHEIGHT}', $heights[0] . 'px', $template);
1114
+ $template = str_replace('{MEDIUMWIDTH}', $widths[1] . 'px', $template);
1115
+ $template = str_replace('{MEDIUMHEIGHT}', $heights[1] . 'px', $template);
1116
+ $template = str_replace('{LARGEWIDTH}', $widths[2] . 'px', $template);
1117
+ $template = str_replace('{LARGEHEIGHT}', $heights[2] . 'px', $template);
1118
+ }
1119
+
1120
+ $template = str_replace('{FULL}', $fileLink, $template);
1121
+ $template = str_replace('{FILELINK}', $fileLink, $template);
1122
+ $template = str_replace('{FILETYPE}', $fileType, $template);
1123
+ $template = str_replace('{PAGELINK}', $pageLink, $template);
1124
+ $template = str_replace('{FILENAME}', $orig_filename, $template);
1125
+ $template = str_replace('{IMAGE}', $fileLink, $template);
1126
+ $template = str_replace('{URL}', $fileLink, $template);
1127
+ $template = str_replace('{RELFILENAME}', $relFileName, $template);
1128
+ $template = str_replace('{ICON}', $icon, $template);
1129
+ $template = str_replace('{FILEID}', $fileid, $template);
1130
+
1131
+ $template = $template . (empty($template) ? '' : '<br />');
1132
+ DebugEcho("parseTemplate: after: '$template'");
1133
+ return $template;
1134
+ } else {
1135
+ EchoError("parseTemplate: couldn't get attachment $fileid");
1136
+ return '';
1137
+ }
1138
+ }
1139
+
1140
+ /**
1141
+ * This function determines if the mime attachment is on the BANNED_FILE_LIST
1142
+ * @param string
1143
+ * @return boolean
1144
+ */
1145
+ function is_banned_filename($filename) {
1146
+ if (preg_match('/ATT\d\d\d\d\d.txt/i', $filename)) {
1147
+ return true;
1148
+ }
1149
+
1150
+ $bannedFiles = $this->config['banned_files_list'];
1151
+
1152
+ if (empty($filename) || empty($bannedFiles)) {
1153
+ return false;
1154
+ }
1155
+
1156
+ foreach ($bannedFiles as $bannedFile) {
1157
+ if (fnmatch($bannedFile, $filename)) {
1158
+ EchoError("Ignoring attachment: $filename - it is on the banned files list.");
1159
+ $this->notify_error("Ignoring attachment: $filename - it is on the banned files list.", "Ignoring attachment: $filename - it is on the banned files list.");
1160
+ return true;
1161
+ }
1162
+ }
1163
+ return false;
1164
+ }
1165
+
1166
+ function get_content() {
1167
+ $meta_return = '';
1168
+ if ($this->config['prefer_text_type'] == 'html') {
1169
+ if (isset($this->email['html'])) {
1170
+ DebugEcho('get_content: html');
1171
+ $meta_return = $this->email['html'];
1172
+ }
1173
+ } else {
1174
+ if (isset($this->email['text'])) {
1175
+ DebugEcho('get_content: plain');
1176
+ $meta_return = $this->email['text'];
1177
+ }
1178
+ }
1179
+ return $meta_return;
1180
+ }
1181
+
1182
+ /**
1183
+ * This function looks for a subject at the beginning surrounded by # and then removes that from the content
1184
+ */
1185
+ function tag_Subject() {
1186
+ DebugEcho("tag_Subject: Looking for subject in email body");
1187
+
1188
+ if (strlen($this->content) == 0 || substr($this->content, 0, 1) != "#") {
1189
+ DebugEcho("tag_Subject: No inline subject found [1]");
1190
+ return;
1191
+ }
1192
+ //make sure the first line isn't #img
1193
+ if (strtolower(substr($this->content, 1, 3)) != 'img') {
1194
+ $subjectEndIndex = strpos($this->content, "#", 1);
1195
+ if (!$subjectEndIndex > 0) {
1196
+ DebugEcho("tag_Subject: No subject found [2]");
1197
+ return;
1198
+ }
1199
+ $this->subject = substr($this->content, 1, $subjectEndIndex - 1);
1200
+ $this->content = substr($this->content, $subjectEndIndex + 1, strlen($this->content));
1201
+ DebugEcho("tag_Subject: Subject found in body: $this->subject");
1202
+ }
1203
+ }
1204
+
1205
+ /**
1206
+ * This function handles finding and setting the correct subject
1207
+ */
1208
+ function get_subject() {
1209
+ //assign the default title/subject
1210
+ $this->subject = $this->config[PostieConfigOptions::DefaultTitle];
1211
+
1212
+ if (empty($this->email['headers']['subject'])) {
1213
+ DebugEcho("get_subject: No subject in email");
1214
+ if ($this->config['allow_subject_in_mail']) {
1215
+ $this->tag_Subject();
1216
+ }
1217
+ $this->email['headers']['subject'] = $this->subject;
1218
+ } else {
1219
+ $this->subject = $this->email['headers']['subject'];
1220
+ DebugEcho(("get_subject: Predecoded subject: $this->subject"));
1221
+
1222
+ if ($this->config['allow_subject_in_mail']) {
1223
+ $this->tag_Subject();
1224
+ }
1225
+ }
1226
+ if (!$this->config['allow_html_in_subject']) {
1227
+ DebugEcho("get_subject: subject before htmlentities: $this->subject");
1228
+ $this->subject = htmlentities($this->subject, ENT_COMPAT);
1229
+ DebugEcho("get_subject: subject after htmlentities: $this->subject");
1230
+ }
1231
+
1232
+ //This is for ISO-2022-JP - Can anyone confirm that this is still neeeded?
1233
+ // escape sequence is 'ESC $ B' == 1b 24 42 hex.
1234
+ if (strpos($this->subject, "\x1b\x24\x42") !== false) {
1235
+ // found iso-2022-jp escape sequence in subject... convert!
1236
+ DebugEcho("get_subject: extra parsing for ISO-2022-JP");
1237
+ $this->subject = iconv("ISO-2022-JP", "UTF-8//TRANSLIT", $this->subject);
1238
+ }
1239
+ DebugEcho("get_subject: '$this->subject'");
1240
+ }
1241
+
1242
+ function post_author_details() {
1243
+
1244
+ $theEmail = $this->email['headers']['from']['mailbox'] . '@' . $this->email['headers']['from']['host'];
1245
+
1246
+ $regAuthor = get_user_by('email', $theEmail);
1247
+ if ($regAuthor) {
1248
+ $theAuthor = $regAuthor->user_login;
1249
+ $theUrl = $regAuthor->user_url;
1250
+ $theID = $regAuthor->ID;
1251
+ } else {
1252
+ $theAuthor = $this->get_name_from_email($theEmail);
1253
+ $theUrl = '';
1254
+ $theID = '';
1255
+ }
1256
+
1257
+ $theDetails = array(
1258
+ 'author' => $theAuthor,
1259
+ 'comment_author_url' => $theUrl,
1260
+ 'user_ID' => $theID,
1261
+ 'email' => $theEmail
1262
+ );
1263
+
1264
+ return $theDetails;
1265
+ }
1266
+
1267
+ /**
1268
+ * This function gleans the name from an email address if available. If not
1269
+ * it just returns the username (everything before @)
1270
+ */
1271
+ function get_name_from_email($address) {
1272
+ $name = "";
1273
+ $matches = array();
1274
+ if (preg_match('/^([^<>]+)<([^<> ()]+)>$/', $address, $matches)) {
1275
+ $name = $matches[1];
1276
+ } else if (preg_match('/<([^<>@ ()]+)>/', $address, $matches)) {
1277
+ $name = $matches[1];
1278
+ } else if (preg_match('/(.+?)@(.+)/', $address, $matches)) {
1279
+ $name = $matches[1];
1280
+ }
1281
+
1282
+ return trim($name);
1283
+ }
1284
+
1285
+ function load_html($text) {
1286
+ return str_get_html($text, true, true, DEFAULT_TARGET_CHARSET, false);
1287
+ }
1288
+
1289
+ function media_handle_upload($attachment, $post_id, $poster) {
1290
+
1291
+ $tmpFile = tempnam(get_temp_dir(), 'postie');
1292
+ if ($tmpFile !== false) {
1293
+ $fp = fopen($tmpFile, 'w');
1294
+ if ($fp) {
1295
+ fwrite($fp, $attachment['data']);
1296
+ fclose($fp);
1297
+ DebugEcho("media_handle_upload: wrote data to '$tmpFile'");
1298
+ } else {
1299
+ EchoError("media_handle_upload: Could not write to temp file: '$tmpFile' ");
1300
+ $this->notify_error("media_handle_upload: Could not write to temp file: '$tmpFile' ", "media_handle_upload: Could not write to temp file: '$tmpFile' ");
1301
+ }
1302
+ } else {
1303
+ EchoError("media_handle_upload: Could not create temp file in " . get_temp_dir());
1304
+ $this->notify_error("media_handle_upload: Could not create temp file in " . get_temp_dir(), "media_handle_upload: Could not create temp file in " . get_temp_dir());
1305
+ }
1306
+
1307
+ $file_array = array(
1308
+ 'name' => $attachment['wp_filename'],
1309
+ 'type' => $attachment['mimetype'],
1310
+ 'tmp_name' => $tmpFile,
1311
+ 'error' => 0,
1312
+ 'size' => filesize($tmpFile)
1313
+ );
1314
+ DebugDump($file_array);
1315
+
1316
+ DebugEcho("doing postie_file_added_pre");
1317
+ do_action('postie_file_added_pre', $post_id, $file_array);
1318
+
1319
+ DebugEcho("media_handle_sideload: adding " . $file_array['name']);
1320
+
1321
+ $id = media_handle_sideload($file_array, $post_id);
1322
+
1323
+ if (!is_wp_error($id)) {
1324
+ DebugEcho("media_handle_upload: changing post_author to $poster");
1325
+
1326
+ $mediapath = get_attached_file($id);
1327
+
1328
+ $title = $file_array['name'];
1329
+ $excerpt = '';
1330
+ //TODO once WordPress is fixed this can be removed. https://core.trac.wordpress.org/ticket/39521
1331
+ if (0 === strpos($attachment['mimetype'], 'image/') && $image_meta = wp_read_image_metadata($mediapath)) {
1332
+ if (trim($image_meta['title']) && !is_numeric(sanitize_title($image_meta['title']))) {
1333
+ $title = $image_meta['title'];
1334
+ DebugEcho("media_handle_upload: changing post_title to $title");
1335
+ }
1336
+
1337
+ if (trim($image_meta['caption'])) {
1338
+ $excerpt = $image_meta['caption'];
1339
+ DebugEcho("media_handle_upload: changing post_excerpt to $excerpt");
1340
+ }
1341
+ }
1342
+
1343
+ wp_update_post(array(
1344
+ 'ID' => $id,
1345
+ 'post_author' => $poster,
1346
+ 'post_title' => $title,
1347
+ 'post_excerpt' => $excerpt,
1348
+ ));
1349
+
1350
+ $file_array['tmp_name'] = $mediapath;
1351
+ DebugEcho("media_handle_upload: doing postie_file_added");
1352
+ do_action('postie_file_added', $post_id, $id, $file_array);
1353
+ } else {
1354
+ EchoError("There was an error adding the attachment: " . $id->get_error_message());
1355
+ DebugDump($id->get_error_messages());
1356
+ DebugDump($id->get_error_data());
1357
+ $this->notify_error("There was an error adding the attachment: " . $attachment['wp_filename'], $id->get_error_message());
1358
+ }
1359
+
1360
+ return $id;
1361
+ }
1362
+
1363
+ /* we check whether or not the email is a reply to a previously
1364
+ * published post. First we check whether it starts with Re:, and then
1365
+ * we see if the remainder matches an already existing post. If so,
1366
+ * then we add that post id to the details array, which will cause the
1367
+ * existing post to be overwritten, instead of a new one being
1368
+ * generated
1369
+ */
1370
+
1371
+ function parent_post(&$subject) {
1372
+ global $wpdb;
1373
+
1374
+ $id = NULL;
1375
+ DebugEcho("GetParentPostForReply: Looking for parent '$subject'");
1376
+ // see if subject starts with Re:
1377
+ $matches = array();
1378
+ if (preg_match("/(^Re:)(.*)/iu", $subject, $matches)) {
1379
+ DebugEcho("GetParentPostForReply: Re: detected");
1380
+ $subject = trim($matches[2]);
1381
+ // strip out category info into temporary variable
1382
+ $tmpSubject = $subject;
1383
+ if (preg_match('/(.+): (.*)/u', $tmpSubject, $matches)) {
1384
+ $tmpSubject = trim($matches[2]);
1385
+ $matches[1] = array($matches[1]);
1386
+ } else if (preg_match_all('/\[(.[^\[]*)\]/', $tmpSubject, $matches)) {
1387
+ $tmpSubject_matches = array();
1388
+ preg_match("/](.[^\[]*)$/", $tmpSubject, $tmpSubject_matches);
1389
+ $tmpSubject = trim($tmpSubject_matches[1]);
1390
+ } else if (preg_match_all('/-(.[^-]*)-/', $tmpSubject, $matches)) {
1391
+ preg_match("/-(.[^-]*)$/", $tmpSubject, $tmpSubject_matches);
1392
+ $tmpSubject = trim($tmpSubject_matches[1]);
1393
+ }
1394
+ DebugEcho("GetParentPostForReply: tmpSubject: $tmpSubject");
1395
+ $checkExistingPostQuery = "SELECT ID FROM $wpdb->posts WHERE post_title LIKE %s AND post_status = 'publish' AND comment_status = 'open' AND post_type=%s ORDER BY post_date DESC";
1396
+ if ($id = $wpdb->get_var($wpdb->prepare($checkExistingPostQuery, $tmpSubject, $this->config[PostieConfigOptions::PostType]))) {
1397
+ if (!empty($id)) {
1398
+ DebugEcho("GetParentPostForReply: id: $id");
1399
+ } else {
1400
+ DebugEcho("GetParentPostForReply: No parent id found");
1401
+ }
1402
+ }
1403
+ } else {
1404
+ DebugEcho("GetParentPostForReply: No parent found");
1405
+ }
1406
+
1407
+ $id = apply_filters('postie_parent_post', $id, $this->email);
1408
+ DebugEcho("GetParentPostForReply: After postie_parent_post: $id");
1409
+
1410
+ return $id;
1411
+ }
1412
+
1413
+ }
postie-tags.php CHANGED
@@ -240,31 +240,6 @@ function tag_Delay(&$content, $message_date, $config) {
240
  return array($corrected_date->format(DATE_W3C), $delay);
241
  }
242
 
243
- /**
244
- * This function takes the content of the message - looks for a subject at the beginning surrounded by # and then removes that from the content
245
- */
246
- function tag_Subject($content, $defaultTitle) {
247
- DebugEcho("tag_Subject: Looking for subject in email body");
248
- if (substr($content, 0, 1) != "#") {
249
- DebugEcho("tag_Subject: No inline subject found, using supplied default [1] '$defaultTitle'");
250
- return(array($defaultTitle, $content));
251
- }
252
- //make sure the first line isn't #img
253
- if (strtolower(substr($content, 1, 3)) != "img") {
254
- $subjectEndIndex = strpos($content, "#", 1);
255
- if (!$subjectEndIndex > 0) {
256
- DebugEcho("tag_Subject: No subject found, using default [2]");
257
- return(array($defaultTitle, $content));
258
- }
259
- $subject = substr($content, 1, $subjectEndIndex - 1);
260
- $content = substr($content, $subjectEndIndex + 1, strlen($content));
261
- DebugEcho("tag_Subject: Subject found in body: $subject");
262
- return array($subject, $content);
263
- } else {
264
- return(array($defaultTitle, $content));
265
- }
266
- }
267
-
268
  function tag_Excerpt(&$content, $config) {
269
  $post_excerpt = '';
270
  $matches = array();
240
  return array($corrected_date->format(DATE_W3C), $delay);
241
  }
242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  function tag_Excerpt(&$content, $config) {
244
  $post_excerpt = '';
245
  $matches = array();
postie.class.php CHANGED
@@ -39,6 +39,10 @@ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . "postie-tags.php");
39
 
40
  class Postie {
41
 
 
 
 
 
42
  function get_mail() {
43
  $config = postie_config_read();
44
  if (true == $config['postie_log_error'] || (defined('POSTIE_DEBUG') && true == POSTIE_DEBUG)) {
@@ -110,217 +114,6 @@ class Postie {
110
  return false;
111
  }
112
 
113
- function save_attachments(&$email, $post_id, $config, $poster) {
114
- DebugEcho('save_attachments: ---- start');
115
-
116
- if (!isset($email['attachment'])) {
117
- $email['attachment'] = array();
118
- }
119
- if (!isset($email['inline'])) {
120
- $email['inline'] = array();
121
- }
122
- if (!isset($email['related'])) {
123
- $email['related'] = array();
124
- }
125
-
126
- DebugEcho("save_attachments: [attachment]");
127
- $this->save_attachments_worker($email['attachment'], $post_id, $config, $poster);
128
- DebugEcho("save_attachments: [inline]");
129
- $this->save_attachments_worker($email['inline'], $post_id, $config, $poster);
130
- DebugEcho("save_attachments: [related]");
131
- $this->save_attachments_worker($email['related'], $post_id, $config, $poster);
132
-
133
-
134
- DebugEcho("save_attachments: ==== end");
135
- }
136
-
137
- /**
138
- * This function determines if the mime attachment is on the BANNED_FILE_LIST
139
- * @param string
140
- * @return boolean
141
- */
142
- function is_banned_filename($filename, $bannedFiles) {
143
- if (preg_match('/ATT\d\d\d\d\d.txt/i', $filename)) {
144
- return true;
145
- }
146
-
147
- if (empty($filename) || empty($bannedFiles)) {
148
- return false;
149
- }
150
- foreach ($bannedFiles as $bannedFile) {
151
- if (fnmatch($bannedFile, $filename)) {
152
- EchoError("Ignoring attachment: $filename - it is on the banned files list.");
153
- $this->notify_error("Ignoring attachment: $filename - it is on the banned files list.", "Ignoring attachment: $filename - it is on the banned files list.");
154
- return true;
155
- }
156
- }
157
- return false;
158
- }
159
-
160
- function save_attachments_worker(&$attachments, $post_id, $config, $poster) {
161
- DebugEcho("save_attachments_worker: start");
162
- foreach ($attachments as &$attachment) {
163
- foreach ($attachment as $key => $value) {
164
- if ($key != 'data') {
165
- DebugEcho("save_attachments_worker: [$key]: $value");
166
- }
167
- }
168
- if (array_key_exists('filename', $attachment) && !empty($attachment['filename'])) {
169
- DebugEcho('save_attachments_worker: ' . $attachment['filename']);
170
-
171
- if ($this->is_banned_filename($attachment['filename'], $config['banned_files_list'])) {
172
- DebugEcho("save_attachments_worker: skipping banned filename " . $attachment['filename']);
173
- continue;
174
- }
175
-
176
- if (false === apply_filters('postie_include_attachment', true, $attachment)) {
177
- DebugEcho("save_attachments_worker: skipping filename by filter " . $attachment['filename']);
178
- continue;
179
- }
180
- } else {
181
- DebugEcho('save_attachments_worker: un-named attachment');
182
- }
183
-
184
- $this->save_attachment($attachment, $post_id, $config, $poster);
185
-
186
- $filename = $attachment['wp_filename'];
187
- $fileext = $attachment['ext'];
188
- $mparts = explode('/', $attachment['mimetype']);
189
- $mimetype_primary = $mparts[0];
190
- $mimetype_secondary = $mparts[1];
191
- DebugEcho("save_attachments_worker: mime primary: $mimetype_primary");
192
-
193
- $attachment['primary'] = $mimetype_primary;
194
- $attachment['exclude'] = false;
195
-
196
- $file_id = $attachment['wp_id'];
197
- $file = wp_get_attachment_url($file_id);
198
-
199
- switch ($mimetype_primary) {
200
- case 'text':
201
- DebugEcho("save_attachments_worker: text attachment");
202
- $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $config['icon_set'], $config['icon_size']);
203
- $attachment['template'] = "<a href='$file'>" . $icon . $filename . '</a>' . "\n";
204
- break;
205
-
206
- case 'image':
207
- DebugEcho("save_attachments_worker: image attachment");
208
- $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $config['imagetemplate'], $filename) . "\n";
209
- break;
210
-
211
- case 'audio':
212
- DebugEcho("save_attachments_worker: audio attachment");
213
- if (in_array($fileext, $config['audiotypes'])) {
214
- DebugEcho("save_attachments_worker: using audio template: $mimetype_secondary");
215
- $audioTemplate = $config['audiotemplate'];
216
- } else {
217
- DebugEcho("save_attachments_worker: using default audio template: $mimetype_secondary");
218
- $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $config['icon_set'], $config['icon_size']);
219
- $audioTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
220
- }
221
- $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $audioTemplate, $filename);
222
- break;
223
-
224
- case 'video':
225
- DebugEcho("save_attachments_worker: video attachment");
226
- if (in_array($fileext, $config['video1types'])) {
227
- DebugEcho("save_attachments_worker: using video1 template: $fileext");
228
- $videoTemplate = $config['video1template'];
229
- } elseif (in_array($fileext, $config['video2types'])) {
230
- DebugEcho("save_attachments_worker: using video2 template: $fileext");
231
- $videoTemplate = $config['video2template'];
232
- } else {
233
- DebugEcho("save_attachments_worker: using default template: $fileext");
234
- $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $config['icon_set'], $config['icon_size']);
235
- $videoTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
236
- }
237
- $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $videoTemplate, $filename);
238
- break;
239
-
240
- default :
241
- DebugEcho("save_attachments_worker: generic attachment ($mimetype_primary)");
242
- $icon = $this->choose_attachment_icon($file, $mimetype_primary, $mimetype_secondary, $config['icon_set'], $config['icon_size']);
243
- $attachment['template'] = $this->parse_template($file_id, $mimetype_primary, $config['generaltemplate'], $filename, $icon) . "\n";
244
- break;
245
- }
246
- DebugEcho("save_attachments_worker: done with $filename");
247
- }
248
- DebugEcho("save_attachments_worker: end");
249
- }
250
-
251
- function parse_template($fileid, $type, $template, $orig_filename, $icon = "") {
252
- $template = trim($template);
253
- DebugEcho("parseTemplate: before '$template'");
254
-
255
- $attachment = get_post($fileid);
256
- if (!empty($attachment)) {
257
- $uploadDir = wp_upload_dir();
258
- $fileName = basename($attachment->guid);
259
- $fileType = pathinfo($fileName, PATHINFO_EXTENSION);
260
- $absFileName = $uploadDir['path'] . '/' . $fileName;
261
- $relFileName = str_replace(ABSPATH, '', $absFileName);
262
- $fileLink = wp_get_attachment_url($fileid);
263
- $pageLink = get_attachment_link($fileid);
264
-
265
- $template = str_replace('{TITLE}', $attachment->post_title, $template);
266
- $template = str_replace('{ID}', $fileid, $template);
267
-
268
- if ($type == 'image') {
269
- $widths = array();
270
- $heights = array();
271
- $img_urls = array();
272
-
273
- /*
274
- * Possible enhancement: support all sizes returned by get_intermediate_image_sizes()
275
- */
276
- $sizes = array('thumbnail', 'medium', 'large');
277
- for ($i = 0; $i < count($sizes); $i++) {
278
- $iinfo = image_downsize($fileid, $sizes[$i]);
279
- if (false !== $iinfo) {
280
- $img_urls[$i] = $iinfo[0];
281
- $widths[$i] = $iinfo[1];
282
- $heights[$i] = $iinfo[2];
283
- }
284
- }
285
- DebugEcho('parseTemplate: Sources');
286
- DebugDump($img_urls);
287
- DebugEcho('parseTemplate: Heights');
288
- DebugDump($heights);
289
- DebugEcho('parseTemplate: Widths');
290
- DebugDump($widths);
291
-
292
- $template = str_replace('{THUMBNAIL}', $img_urls[0], $template);
293
- $template = str_replace('{THUMB}', $img_urls[0], $template);
294
- $template = str_replace('{MEDIUM}', $img_urls[1], $template);
295
- $template = str_replace('{LARGE}', $img_urls[2], $template);
296
- $template = str_replace('{THUMBWIDTH}', $widths[0] . 'px', $template);
297
- $template = str_replace('{THUMBHEIGHT}', $heights[0] . 'px', $template);
298
- $template = str_replace('{MEDIUMWIDTH}', $widths[1] . 'px', $template);
299
- $template = str_replace('{MEDIUMHEIGHT}', $heights[1] . 'px', $template);
300
- $template = str_replace('{LARGEWIDTH}', $widths[2] . 'px', $template);
301
- $template = str_replace('{LARGEHEIGHT}', $heights[2] . 'px', $template);
302
- }
303
-
304
- $template = str_replace('{FULL}', $fileLink, $template);
305
- $template = str_replace('{FILELINK}', $fileLink, $template);
306
- $template = str_replace('{FILETYPE}', $fileType, $template);
307
- $template = str_replace('{PAGELINK}', $pageLink, $template);
308
- $template = str_replace('{FILENAME}', $orig_filename, $template);
309
- $template = str_replace('{IMAGE}', $fileLink, $template);
310
- $template = str_replace('{URL}', $fileLink, $template);
311
- $template = str_replace('{RELFILENAME}', $relFileName, $template);
312
- $template = str_replace('{ICON}', $icon, $template);
313
- $template = str_replace('{FILEID}', $fileid, $template);
314
-
315
- $template = $template . (empty($template) ? '' : '<br />');
316
- DebugEcho("parseTemplate: after: '$template'");
317
- return $template;
318
- } else {
319
- EchoError("parseTemplate: couldn't get attachment $fileid");
320
- return '';
321
- }
322
- }
323
-
324
  function show_filters_for($hook = '') {
325
  global $wp_filter;
326
  if (empty($hook) || !isset($wp_filter[$hook])) {
@@ -331,725 +124,6 @@ class Postie {
331
  //DebugDump($wp_filter[$hook]->callbacks);
332
  }
333
 
334
- function save_attachment(&$attachment, $post_id, $config, $poster) {
335
-
336
- if (isset($attachment['filename']) && !empty($attachment['filename'])) {
337
- $filename = $attachment['filename'];
338
- } else {
339
- DebugEcho("save_attachment: generating file name");
340
- $filename = uniqid();
341
- $mparts = explode('/', $attachment['mimetype']);
342
- $attachment['filename'] = $filename . '.' . $mparts[1];
343
- }
344
-
345
- DebugEcho("save_attachment: pre sanitize file name '$filename'");
346
- //DebugDump($part);
347
- $filename = sanitize_file_name($filename);
348
- $attachment['wp_filename'] = $filename;
349
-
350
- DebugEcho("save_attachment: file name '$filename'");
351
-
352
- $mparts = explode('/', $attachment['mimetype']);
353
- $mimetype_primary = $mparts[0];
354
- $mimetype_secondary = $mparts[1];
355
-
356
- $fileext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
357
- $attachment['ext'] = $fileext;
358
- if (empty($fileext) && $mimetype_primary == 'image') {
359
- $attachment['ext'] = $mimetype_secondary;
360
- $filename = $filename . '.' . $mimetype_secondary;
361
- $attachment['wp_filename'] = $filename;
362
- $fileext = $mimetype_secondary;
363
- DebugEcho("save_attachment: blank image extension, changed to $mimetype_secondary ($filename)");
364
- }
365
- DebugEcho("save_attachment: extension '$fileext'");
366
-
367
- $typeinfo = wp_check_filetype($filename);
368
- //DebugDump($typeinfo);
369
- if (!empty($typeinfo['type'])) {
370
- DebugEcho("save_attachment: secondary lookup found " . $typeinfo['type']);
371
- $mimeparts = explode('/', strtolower($typeinfo['type']));
372
- $mimetype_primary = $mimeparts[0];
373
- $mimetype_secondary = $mimeparts[1];
374
- } else {
375
- DebugEcho("save_attachment: secondary lookup failed, checking configured extensions");
376
- if (in_array($fileext, $config['audiotypes'])) {
377
- DebugEcho("save_attachment: found audio extension");
378
- $mimetype_primary = 'audio';
379
- $mimetype_secondary = $fileext;
380
- } elseif (in_array($fileext, array_merge($config['video1types'], $config['video2types']))) {
381
- DebugEcho("save_attachment: found video extension");
382
- $mimetype_primary = 'video';
383
- $mimetype_secondary = $fileext;
384
- } else {
385
- DebugEcho("save_attachment: found no extension");
386
- }
387
- }
388
- $attachment['mimetype'] = "$mimetype_primary/$mimetype_secondary";
389
- DebugEcho("save_attachment: mimetype $mimetype_primary/$mimetype_secondary");
390
-
391
- $attachment['wp_id'] = 0;
392
-
393
- switch ($mimetype_primary) {
394
- case 'text':
395
- DebugEcho("save_attachment: ctype_primary: text");
396
- //DebugDump($part);
397
-
398
- DebugEcho("save_attachment: text Attachement: $filename");
399
- $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
400
- if (!is_wp_error($file_id)) {
401
- $attachment['wp_id'] = $file_id;
402
- DebugEcho("save_attachment: text attachment: adding '$filename'");
403
- } else {
404
- EchoError($file_id->get_error_message());
405
- $this->notify_error("Failed to add text media file: $filename", $file_id->get_error_message());
406
- }
407
-
408
- break;
409
-
410
- case 'image':
411
- DebugEcho("save_attachment: image Attachement: $filename");
412
- $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
413
- if (!is_wp_error($file_id)) {
414
- $attachment['wp_id'] = $file_id;
415
- //set the first image we come across as the featured image
416
- if ($config['featured_image'] && !has_post_thumbnail($post_id)) {
417
- DebugEcho("save_attachment: featured image: $file_id");
418
- set_post_thumbnail($post_id, $file_id);
419
- }
420
- } else {
421
- EchoError("save_attachment image error: " . $file_id->get_error_message());
422
- $this->notify_error("Failed to add image media file: $filename", $file_id->get_error_message());
423
- }
424
- break;
425
-
426
- case 'audio':
427
- DebugEcho("save_attachment: audio Attachement: $filename");
428
- $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
429
- if (!is_wp_error($file_id)) {
430
- $attachment['wp_id'] = $file_id;
431
- } else {
432
- EchoError("save_attachment audio error: " . $file_id->get_error_message());
433
- $this->notify_error("Failed to add audio media file: $filename", $file_id->get_error_message());
434
- }
435
- break;
436
-
437
- case 'video':
438
- DebugEcho("save_attachment: video Attachement: $filename");
439
- $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
440
- if (!is_wp_error($file_id)) {
441
- $attachment['wp_id'] = $file_id;
442
- } else {
443
- EchoError("save_attachment video error: " . $file_id->get_error_message());
444
- $this->notify_error("Failed to add video file: $filename", $file_id->get_error_message());
445
- }
446
- break;
447
-
448
- default:
449
- DebugEcho("save_attachment: found file type: " . $mimetype_primary);
450
- if (in_array($mimetype_primary, $config['supported_file_types'])) {
451
- //pgp signature - then forget it
452
- if ($mimetype_secondary == 'pgp-signature') {
453
- DebugEcho("save_attachment: found pgp-signature - done");
454
- break;
455
- }
456
- $file_id = $this->media_handle_upload($attachment, $post_id, $poster);
457
- if (!is_wp_error($file_id)) {
458
- $attachment['wp_id'] = $file_id;
459
- $file = wp_get_attachment_url($file_id);
460
- DebugEcho("save_attachment: uploaded $file_id ($file)");
461
- } else {
462
- EchoError("save_attachment file error: " . $file_id->get_error_message());
463
- $this->notify_error("Failed to add media file: $filename", $file_id->get_error_message());
464
- }
465
- } else {
466
- EchoError("$filename has an unsupported MIME type $mimetype_primary and was not added.");
467
- DebugEcho("save_attachment: Not in supported filetype list: '$mimetype_primary'");
468
- DebugDump($config['supported_file_types']);
469
- $this->notify_error("Unsupported MIME type: $mimetype_primary", "$filename has an unsupported MIME type $mimetype_primary and was not added.\nSupported types:\n" . print_r($config['supported_file_types'], true));
470
- }
471
- break;
472
- }
473
- }
474
-
475
- function notify_error($subject, $message) {
476
- $recipients = array();
477
- $config = postie_config_read();
478
- if ($config['postie_log_error_notify'] == '(Nobody)') {
479
- return;
480
- }
481
- if ($config['postie_log_error_notify'] == '(All Admins)') {
482
- foreach (get_users(array('role' => 'administrator', 'blog_id' => get_current_blog_id())) as $user) {
483
- $recipients[] = $user->user_email;
484
- }
485
- if (count($recipients) == 0) {
486
- return;
487
- }
488
- } else {
489
- $user = get_user_by('login', $config['postie_log_error_notify']);
490
- if ($user === false) {
491
- return;
492
- }
493
- $recipients[] = $user->user_login;
494
- }
495
-
496
- $message = "This message has been sent from " . get_site_url() . ". You can disable or control who receives them by changing the Postie 'Notify on Error' setting.\n\n" . $message;
497
- wp_mail($recipients, $subject, $message);
498
- }
499
-
500
- function media_handle_upload($attachment, $post_id, $poster) {
501
-
502
- $tmpFile = tempnam(get_temp_dir(), 'postie');
503
- if ($tmpFile !== false) {
504
- $fp = fopen($tmpFile, 'w');
505
- if ($fp) {
506
- fwrite($fp, $attachment['data']);
507
- fclose($fp);
508
- DebugEcho("media_handle_upload: wrote data to '$tmpFile'");
509
- } else {
510
- EchoError("media_handle_upload: Could not write to temp file: '$tmpFile' ");
511
- $this->notify_error("media_handle_upload: Could not write to temp file: '$tmpFile' ", "media_handle_upload: Could not write to temp file: '$tmpFile' ");
512
- }
513
- } else {
514
- EchoError("media_handle_upload: Could not create temp file in " . get_temp_dir());
515
- $this->notify_error("media_handle_upload: Could not create temp file in " . get_temp_dir(), "media_handle_upload: Could not create temp file in " . get_temp_dir());
516
- }
517
-
518
- $file_array = array(
519
- 'name' => $attachment['wp_filename'],
520
- 'type' => $attachment['mimetype'],
521
- 'tmp_name' => $tmpFile,
522
- 'error' => 0,
523
- 'size' => filesize($tmpFile)
524
- );
525
- DebugDump($file_array);
526
-
527
- DebugEcho("doing postie_file_added_pre");
528
- do_action('postie_file_added_pre', $post_id, $file_array);
529
-
530
- DebugEcho("media_handle_sideload: adding " . $file_array['name']);
531
-
532
- $id = media_handle_sideload($file_array, $post_id);
533
-
534
- if (!is_wp_error($id)) {
535
- DebugEcho("media_handle_upload: changing post_author to $poster");
536
-
537
- $mediapath = get_attached_file($id);
538
-
539
- $title = $file_array['name'];
540
- $excerpt = '';
541
- //TODO once WordPress is fixed this can be removed. https://core.trac.wordpress.org/ticket/39521
542
- if (0 === strpos($attachment['mimetype'], 'image/') && $image_meta = wp_read_image_metadata($mediapath)) {
543
- if (trim($image_meta['title']) && !is_numeric(sanitize_title($image_meta['title']))) {
544
- $title = $image_meta['title'];
545
- DebugEcho("media_handle_upload: changing post_title to $title");
546
- }
547
-
548
- if (trim($image_meta['caption'])) {
549
- $excerpt = $image_meta['caption'];
550
- DebugEcho("media_handle_upload: changing post_excerpt to $excerpt");
551
- }
552
- }
553
-
554
- wp_update_post(array(
555
- 'ID' => $id,
556
- 'post_author' => $poster,
557
- 'post_title' => $title,
558
- 'post_excerpt' => $excerpt,
559
- ));
560
-
561
- $file_array['tmp_name'] = $mediapath;
562
- DebugEcho("media_handle_upload: doing postie_file_added");
563
- do_action('postie_file_added', $post_id, $id, $file_array);
564
- } else {
565
- EchoError("There was an error adding the attachment: " . $id->get_error_message());
566
- DebugDump($id->get_error_messages());
567
- DebugDump($id->get_error_data());
568
- $this->notify_error("There was an error adding the attachment: " . $attachment['wp_filename'], $id->get_error_message());
569
- }
570
-
571
- return $id;
572
- }
573
-
574
- function get_content(&$email, $config) {
575
- DebugEcho('get_content: ---- start');
576
- $meta_return = '';
577
- if ($config['prefer_text_type'] == 'html') {
578
- if (isset($email['html'])) {
579
- $meta_return = $email['html'];
580
- }
581
- } else {
582
- if (isset($email['text'])) {
583
- $meta_return = $email['text'];
584
- }
585
- }
586
- return $meta_return;
587
- }
588
-
589
- /**
590
- * This function handles finding and setting the correct subject
591
- * @return array - (subject,content)
592
- */
593
- function get_subject(&$mimeDecodedEmail, &$content, $config) {
594
- //assign the default title/subject
595
- if (empty($mimeDecodedEmail['headers']['subject'])) {
596
- DebugEcho("get_subject: No subject in email");
597
- if ($config['allow_subject_in_mail']) {
598
- list($subject, $content) = tag_Subject($content, $config['default_title']);
599
- } else {
600
- DebugEcho("get_subject: Using default subject");
601
- $subject = $config['default_title'];
602
- }
603
- $mimeDecodedEmail['headers']['subject'] = $subject;
604
- } else {
605
- $subject = $mimeDecodedEmail['headers']['subject'];
606
- DebugEcho(("get_subject: Predecoded subject: $subject"));
607
-
608
- if ($config['allow_subject_in_mail']) {
609
- list($subject, $content) = tag_Subject($content, $subject);
610
- }
611
- }
612
- if (!$config['allow_html_in_subject']) {
613
- DebugEcho("get_subject: subject before htmlentities: $subject");
614
- $subject = htmlentities($subject, ENT_COMPAT);
615
- DebugEcho("get_subject: subject after htmlentities: $subject");
616
- }
617
-
618
- //This is for ISO-2022-JP - Can anyone confirm that this is still neeeded?
619
- // escape sequence is 'ESC $ B' == 1b 24 42 hex.
620
- if (strpos($subject, "\x1b\x24\x42") !== false) {
621
- // found iso-2022-jp escape sequence in subject... convert!
622
- DebugEcho("get_subject: extra parsing for ISO-2022-JP");
623
- $subject = iconv("ISO-2022-JP", "UTF-8//TRANSLIT", $subject);
624
- }
625
- DebugEcho("get_subject: '$subject'");
626
- return $subject;
627
- }
628
-
629
- function create_post($poster, $mimeDecodedEmail, $post_id, &$is_reply, $config) {
630
- DebugEcho("create_post: prefer_text_type: " . $config['prefer_text_type']);
631
-
632
- $fulldebug = $this->is_debugmode();
633
- $fulldebugdump = false;
634
-
635
- if (array_key_exists('message-id', $mimeDecodedEmail['headers'])) {
636
- DebugEcho("Message Id is :" . htmlentities($mimeDecodedEmail['headers']['message-id']));
637
- if ($fulldebugdump) {
638
- DebugDump($mimeDecodedEmail);
639
- }
640
- }
641
-
642
- if ($fulldebugdump) {
643
- DebugDump($mimeDecodedEmail);
644
- }
645
-
646
- $this->save_attachments($mimeDecodedEmail, $post_id, $config, $poster);
647
-
648
- $content = $this->get_content($mimeDecodedEmail, $config);
649
-
650
- $subject = $this->get_subject($mimeDecodedEmail, $content, $config);
651
-
652
- $content = filter_RemoveSignature($content, $config);
653
- if ($fulldebug) {
654
- DebugEcho("post filter_RemoveSignature: $content");
655
- }
656
-
657
- $content = filter_Newlines($content, $config);
658
- if ($fulldebug) {
659
- DebugEcho("post filter_Newlines: $content");
660
- }
661
-
662
- $post_excerpt = tag_Excerpt($content, $config);
663
- if ($fulldebug) {
664
- DebugEcho("post tag_Excerpt: $content");
665
- }
666
-
667
- $postAuthorDetails = $this->post_author_details($mimeDecodedEmail);
668
- if ($fulldebug) {
669
- DebugEcho("post getPostAuthorDetails: $content");
670
- }
671
-
672
- $message_date = NULL;
673
- $delay = 0;
674
- if (array_key_exists("date", $mimeDecodedEmail['headers']) && !empty($mimeDecodedEmail['headers']['date'])) {
675
- DebugEcho("date header: {$mimeDecodedEmail['headers']['date']}");
676
- if ($config['ignore_email_date']) {
677
- $message_date = current_time('mysql');
678
- DebugEcho("system date: $message_date");
679
- } else {
680
- $message_date = $mimeDecodedEmail['headers']['date'];
681
- DebugEcho("decoded date: $message_date");
682
- list($message_date, $delay) = tag_Delay($content, $message_date, $config);
683
- if ($fulldebug) {
684
- DebugEcho("post tag_Delay: $content");
685
- }
686
- }
687
- } else {
688
- DebugEcho("date header missing");
689
- $message_date = current_time('mysql');
690
- }
691
-
692
- $post_date = tag_Date($content, $message_date);
693
- if ($fulldebug) {
694
- DebugEcho("post tag_Date: $content");
695
- }
696
-
697
-
698
- //do post type before category to keep the subject line correct
699
- $post_type_format = tag_PostType($subject, $config);
700
- if ($fulldebug) {
701
- DebugEcho("post tag_PostType: $content");
702
- }
703
-
704
- $default_categoryid = $config['default_post_category'];
705
-
706
- DebugEcho("pre postie_category_default: '$default_categoryid'");
707
- $default_categoryid = apply_filters('postie_category_default', $default_categoryid);
708
- DebugEcho("post postie_category_default: '$default_categoryid'");
709
-
710
- $post_categories = tag_Categories($subject, $default_categoryid, $config, $post_id);
711
- if ($fulldebug) {
712
- DebugEcho("post tag_Categories: $content");
713
- }
714
-
715
- $post_tags = tag_Tags($content, $config);
716
- if ($fulldebug) {
717
- DebugEcho("post tag_Tags: $content");
718
- }
719
-
720
- $comment_status = tag_AllowCommentsOnPost($content);
721
- if ($fulldebug) {
722
- DebugEcho("post tag_AllowCommentsOnPost: $content");
723
- }
724
-
725
- $post_status = tag_Status($content, $config);
726
- if ($fulldebug) {
727
- DebugEcho("post tag_Status: $content");
728
- }
729
-
730
- //handle CID before linkify
731
- $content = filter_ReplaceImageCIDs($content, $mimeDecodedEmail);
732
- if ($fulldebug) {
733
- DebugEcho("post filter_ReplaceImageCIDs: $content");
734
- }
735
-
736
- if ($config['converturls']) {
737
- $content = filter_Linkify($content);
738
- if ($fulldebug) {
739
- DebugEcho("post filter_Linkify: $content");
740
- }
741
- }
742
-
743
- if ($config['reply_as_comment'] == true) {
744
- $id = $this->parent_post($subject, $mimeDecodedEmail, $config);
745
- if (empty($id)) {
746
- DebugEcho("Not a reply");
747
- $id = $post_id;
748
- $is_reply = false;
749
- } else {
750
- DebugEcho("Reply detected");
751
- $is_reply = true;
752
- if (true == $config['strip_reply']) {
753
- // strip out quoted content
754
- $lines = explode("\n", $content);
755
- $newContents = '';
756
- foreach ($lines as $line) {
757
- if (preg_match("/^>.*/i", $line) == 0 &&
758
- preg_match("/^(from|subject|to|date):.*?/iu", $line) == 0 &&
759
- preg_match("/^-+.*?(from|subject|to|date).*?/iu", $line) == 0 &&
760
- preg_match("/^on.*?wrote:$/iu", $line) == 0 &&
761
- preg_match("/^-+\s*forwarded\s*message\s*-+/iu", $line) == 0) {
762
- $newContents .= "$line\n";
763
- }
764
- }
765
- if ((strlen($newContents) <> strlen($content)) && ('html' == $config['prefer_text_type'])) {
766
- DebugEcho("Attempting to fix reply html (before): $newContents");
767
- $newContents = $this->load_html($newContents)->__toString();
768
- DebugEcho("Attempting to fix reply html (after): $newContents");
769
- }
770
- $content = $newContents;
771
- }
772
- wp_delete_post($post_id);
773
- }
774
- } else {
775
- $id = $post_id;
776
- DebugEcho("Replies will not be processed as comments");
777
- }
778
-
779
- if ($delay > 0 && $post_status == 'publish') {
780
- DebugEcho("publish in future");
781
- $post_status = 'future';
782
- }
783
-
784
- $content = filter_Start($content, $config);
785
- if ($fulldebug) {
786
- DebugEcho("post filter_Start: $content");
787
- }
788
-
789
- $content = filter_End($content, $config);
790
- if ($fulldebug) {
791
- DebugEcho("post filter_End: $content");
792
- }
793
-
794
- $content = filter_ReplaceImagePlaceHolders($content, $mimeDecodedEmail, $config, $id, $config['image_placeholder']);
795
- if ($fulldebug) {
796
- DebugEcho("post filter_ReplaceImagePlaceHolders: $content");
797
- }
798
-
799
- if ($post_excerpt) {
800
- $post_excerpt = filter_ReplaceImagePlaceHolders($post_excerpt, $mimeDecodedEmail, $config, $id, '#eimg%#');
801
- DebugEcho("excerpt: $post_excerpt");
802
- if ($fulldebug) {
803
- DebugEcho("post excerpt ReplaceImagePlaceHolders: $content");
804
- }
805
- }
806
-
807
- //handle inline images after linkify
808
- if ('plain' == $config['prefer_text_type']) {
809
- $content = filter_ReplaceInlineImage($content, $mimeDecodedEmail, $config);
810
- if ($fulldebug) {
811
- DebugEcho("post filter_ReplaceInlineImage: $content");
812
- }
813
- }
814
-
815
- $content = filter_AttachmentTemplates($content, $mimeDecodedEmail, $post_id, $config);
816
-
817
- if (trim($subject) == '') {
818
- $subject = $config['default_title'];
819
- DebugEcho("post parsing subject is blank using: " . $config['default_title']);
820
- }
821
-
822
- $details = array(
823
- 'post_author' => $poster,
824
- 'comment_author' => $postAuthorDetails['author'],
825
- 'comment_author_url' => $postAuthorDetails['comment_author_url'],
826
- 'user_ID' => $postAuthorDetails['user_ID'],
827
- 'email_author' => $postAuthorDetails['email'],
828
- 'post_date' => $post_date,
829
- 'post_date_gmt' => get_gmt_from_date($post_date),
830
- 'post_content' => $content,
831
- 'post_title' => $subject,
832
- 'post_type' => $post_type_format['post_type'],
833
- 'ping_status' => get_option('default_ping_status'),
834
- 'post_category' => $post_categories,
835
- 'tags_input' => $post_tags,
836
- 'comment_status' => $comment_status,
837
- 'post_name' => $subject,
838
- 'post_excerpt' => $post_excerpt,
839
- 'ID' => $id,
840
- 'post_status' => $post_status
841
- );
842
-
843
- //don't need to specify the post format to get a "standard" post
844
- if ($post_type_format['post_format'] !== 'standard') {
845
- //need to set post format differently since it is a type of taxonomy
846
- DebugEcho("Setting post format to {$post_type_format['post_format']}");
847
- wp_set_post_terms($post_id, $post_type_format['post_format'], 'post_format');
848
- }
849
-
850
- return $details;
851
- }
852
-
853
- function save_post($details, $isReply) {
854
- $post_ID = 0;
855
- $details['post_content'] = str_replace('\\', '\\\\', $details['post_content']); //replace all backslashs with double backslashes since WP will remove single backslash
856
- if (!$isReply) {
857
- DebugEcho("postie_save_post: about to insert post");
858
- $post_ID = wp_insert_post($details, true);
859
- if (is_wp_error($post_ID)) {
860
- EchoError("PostToDB Error: " . $post_ID->get_error_message());
861
- DebugDump($post_ID->get_error_messages());
862
- DebugDump($post_ID->get_error_data());
863
- wp_delete_post($details['ID']);
864
-
865
- $this->notify_error("Failed to create {$details['post_type']}: {$details['post_title']}", "Error: " . $post_ID->get_error_message() . "\n\n" . $details['post_content']);
866
-
867
- $post_ID = null;
868
- } else {
869
- DebugEcho("postie_save_post: post inserted");
870
- }
871
- } else {
872
- DebugEcho("postie_save_post: inserting comment");
873
- $comment = array(
874
- 'comment_author' => $details['comment_author'],
875
- 'comment_post_ID' => $details['ID'],
876
- 'comment_author_email' => $details['email_author'],
877
- 'comment_date' => $details['post_date'],
878
- 'comment_date_gmt' => $details['post_date_gmt'],
879
- 'comment_content' => $details['post_content'],
880
- 'comment_author_url' => $details['comment_author_url'],
881
- 'comment_author_IP' => '',
882
- 'comment_approved' => 1,
883
- 'comment_agent' => '',
884
- 'comment_type' => '',
885
- 'comment_parent' => 0,
886
- 'user_id' => $details['user_ID']
887
- );
888
- $comment = apply_filters('postie_comment_before', $comment);
889
- DebugEcho("postie_save_post: post postie_comment_before");
890
- DebugDump($comment);
891
-
892
- $post_ID = wp_new_comment($comment);
893
-
894
- DebugEcho("doing postie_comment_after");
895
- do_action('postie_comment_after', $comment);
896
- }
897
-
898
- if ($post_ID) {
899
- DebugEcho("doing postie_post_after");
900
- do_action('postie_post_after', $details);
901
- }
902
-
903
- return $post_ID;
904
- }
905
-
906
- function load_html($text) {
907
- return str_get_html($text, true, true, DEFAULT_TARGET_CHARSET, false);
908
- }
909
-
910
- /* we check whether or not the email is a reply to a previously
911
- * published post. First we check whether it starts with Re:, and then
912
- * we see if the remainder matches an already existing post. If so,
913
- * then we add that post id to the details array, which will cause the
914
- * existing post to be overwritten, instead of a new one being
915
- * generated
916
- */
917
-
918
- function parent_post(&$subject, $email, $config) {
919
- global $wpdb;
920
-
921
- $id = NULL;
922
- DebugEcho("GetParentPostForReply: Looking for parent '$subject'");
923
- // see if subject starts with Re:
924
- $matches = array();
925
- if (preg_match("/(^Re:)(.*)/iu", $subject, $matches)) {
926
- DebugEcho("GetParentPostForReply: Re: detected");
927
- $subject = trim($matches[2]);
928
- // strip out category info into temporary variable
929
- $tmpSubject = $subject;
930
- if (preg_match('/(.+): (.*)/u', $tmpSubject, $matches)) {
931
- $tmpSubject = trim($matches[2]);
932
- $matches[1] = array($matches[1]);
933
- } else if (preg_match_all('/\[(.[^\[]*)\]/', $tmpSubject, $matches)) {
934
- $tmpSubject_matches = array();
935
- preg_match("/](.[^\[]*)$/", $tmpSubject, $tmpSubject_matches);
936
- $tmpSubject = trim($tmpSubject_matches[1]);
937
- } else if (preg_match_all('/-(.[^-]*)-/', $tmpSubject, $matches)) {
938
- preg_match("/-(.[^-]*)$/", $tmpSubject, $tmpSubject_matches);
939
- $tmpSubject = trim($tmpSubject_matches[1]);
940
- }
941
- DebugEcho("GetParentPostForReply: tmpSubject: $tmpSubject");
942
- $checkExistingPostQuery = "SELECT ID FROM $wpdb->posts WHERE post_title LIKE %s AND post_status = 'publish' AND comment_status = 'open' AND post_type=%s ORDER BY post_date DESC";
943
- if ($id = $wpdb->get_var($wpdb->prepare($checkExistingPostQuery, $tmpSubject, $config[PostieConfigOptions::PostType]))) {
944
- if (!empty($id)) {
945
- DebugEcho("GetParentPostForReply: id: $id");
946
- } else {
947
- DebugEcho("GetParentPostForReply: No parent id found");
948
- }
949
- }
950
- } else {
951
- DebugEcho("GetParentPostForReply: No parent found");
952
- }
953
-
954
- $id = apply_filters('postie_parent_post', $id, $email);
955
- DebugEcho("GetParentPostForReply: After postie_parent_post: $id");
956
-
957
- return $id;
958
- }
959
-
960
- function post_author_details($mimeDecodedEmail) {
961
-
962
- $theEmail = $mimeDecodedEmail['headers']['from']['mailbox'] . '@' . $mimeDecodedEmail['headers']['from']['host'];
963
-
964
- $regAuthor = get_user_by('email', $theEmail);
965
- if ($regAuthor) {
966
- $theAuthor = $regAuthor->user_login;
967
- $theUrl = $regAuthor->user_url;
968
- $theID = $regAuthor->ID;
969
- } else {
970
- $theAuthor = $this->get_name_from_email($theEmail);
971
- $theUrl = '';
972
- $theID = '';
973
- }
974
-
975
- $theDetails = array(
976
- 'author' => $theAuthor,
977
- 'comment_author_url' => $theUrl,
978
- 'user_ID' => $theID,
979
- 'email' => $theEmail
980
- );
981
-
982
- return $theDetails;
983
- }
984
-
985
- /**
986
- * Choose an appropriate file icon based on the extension and mime type of
987
- * the attachment
988
- */
989
- function choose_attachment_icon($file, $primary, $secondary, $iconSet = 'silver', $size = '32') {
990
- if ($iconSet == 'none') {
991
- return('');
992
- }
993
- $fileName = basename($file);
994
- $parts = explode('.', $fileName);
995
- $ext = $parts[count($parts) - 1];
996
- $docExts = array('doc', 'docx');
997
- $docMimes = array('msword', 'vnd.ms-word', 'vnd.openxmlformats-officedocument.wordprocessingml.document');
998
- $pptExts = array('ppt', 'pptx');
999
- $pptMimes = array('mspowerpoint', 'vnd.ms-powerpoint', 'vnd.openxmlformats-officedocument.');
1000
- $xlsExts = array('xls', 'xlsx');
1001
- $xlsMimes = array('msexcel', 'vnd.ms-excel', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet');
1002
- $iWorkMimes = array('zip', 'octet-stream');
1003
- $mpgExts = array('mpg', 'mpeg', 'mp2');
1004
- $mpgMimes = array('mpg', 'mpeg', 'mp2');
1005
- $mp3Exts = array('mp3');
1006
- $mp3Mimes = array('mp3', 'mpeg3', 'mpeg');
1007
- $mp4Exts = array('mp4', 'm4v');
1008
- $mp4Mimes = array('mp4', 'mpeg4', 'octet-stream');
1009
- $aacExts = array('m4a', 'aac');
1010
- $aacMimes = array('m4a', 'aac', 'mp4');
1011
- $aviExts = array('avi');
1012
- $aviMimes = array('avi', 'x-msvideo');
1013
- $movExts = array('mov');
1014
- $movMimes = array('mov', 'quicktime');
1015
- if ($ext == 'pdf' && $secondary == 'pdf') {
1016
- $fileType = 'pdf';
1017
- } else if ($ext == 'pages' && in_array($secondary, $iWorkMimes)) {
1018
- $fileType = 'pages';
1019
- } else if ($ext == 'numbers' && in_array($secondary, $iWorkMimes)) {
1020
- $fileType = 'numbers';
1021
- } else if ($ext == 'key' && in_array($secondary, $iWorkMimes)) {
1022
- $fileType = 'key';
1023
- } else if (in_array($ext, $docExts) && in_array($secondary, $docMimes)) {
1024
- $fileType = 'doc';
1025
- } else if (in_array($ext, $pptExts) && in_array($secondary, $pptMimes)) {
1026
- $fileType = 'ppt';
1027
- } else if (in_array($ext, $xlsExts) && in_array($secondary, $xlsMimes)) {
1028
- $fileType = 'xls';
1029
- } else if (in_array($ext, $mp4Exts) && in_array($secondary, $mp4Mimes)) {
1030
- $fileType = 'mp4';
1031
- } else if (in_array($ext, $movExts) && in_array($secondary, $movMimes)) {
1032
- $fileType = 'mov';
1033
- } else if (in_array($ext, $aviExts) && in_array($secondary, $aviMimes)) {
1034
- $fileType = 'avi';
1035
- } else if (in_array($ext, $mp3Exts) && in_array($secondary, $mp3Mimes)) {
1036
- $fileType = 'mp3';
1037
- } else if (in_array($ext, $mpgExts) && in_array($secondary, $mpgMimes)) {
1038
- $fileType = 'mpg';
1039
- } else if (in_array($ext, $aacExts) && in_array($secondary, $aacMimes)) {
1040
- $fileType = 'aac';
1041
- } else {
1042
- $fileType = 'default';
1043
- }
1044
- $fileName = "/icons/$iconSet/$fileType-$size.png";
1045
- if (!file_exists(POSTIE_ROOT . $fileName)) {
1046
- $fileName = "/icons/$iconSet/default-$size.png";
1047
- }
1048
- $iconHtml = "<img src='" . POSTIE_URL . $fileName . "' alt='$fileType icon' />";
1049
- DebugEcho("icon: $iconHtml");
1050
- return $iconHtml;
1051
- }
1052
-
1053
  function save_email_debug($raw, $email) {
1054
  if ($this->is_debugmode()) {
1055
  //DebugDump($email);
@@ -1070,502 +144,89 @@ class Postie {
1070
  }
1071
  }
1072
 
1073
- function get_emails($type, $server, $port, $email, $password, $protocol, $deleteMessages, $maxemails, $config) {
 
 
 
 
 
 
 
 
 
 
 
 
1074
 
1075
- DebugEcho("getemails: Connecting to $server:$port ($protocol)");
 
 
 
 
1076
 
1077
- $connectiontype = $config['input_connection'];
 
 
1078
 
1079
- try {
1080
- DebugEcho("getemails: procol: $protocol");
1081
- if ($connectiontype == 'curl') {
1082
- $conn = new pCurlConnection($type, trim($server), $email, $password, $port, ($protocol == 'imap-ssl' || $protocol == 'pop3-ssl'));
1083
- } else {
1084
- $conn = new pSocketConnection($type, trim($server), $email, $password, $port, ($protocol == 'imap-ssl' || $protocol == 'pop3-ssl'));
1085
- }
 
 
1086
 
1087
- if ($type == 'imap') {
1088
- $srv = new pImapMailServer($conn);
1089
- } else {
1090
- $srv = new pPop3MailServer($conn);
1091
- }
1092
 
1093
- DebugEcho("getemails: listing messages");
1094
- $mailbox = new fMailbox($type, $conn, $srv);
1095
  $messages = $mailbox->listMessages($maxemails);
1096
 
1097
- DebugEcho(sprintf(__("There are %d messages to process", 'postie'), count($messages)));
1098
 
1099
  DebugDump($messages);
1100
 
1101
  $message_number = 0;
1102
  foreach ($messages as $message) {
1103
  $message_number++;
1104
- DebugEcho("$message_number: ------------------------------------");
1105
- DebugEcho("getemails: fetch {$message['uid']}");
1106
-
1107
- $email = $mailbox->fetchMessage($message['uid']);
1108
-
1109
- if (!empty($email['html'])) {
1110
- DebugEcho("getemails: html");
1111
- $email['html'] = filter_CleanHtml($email['html']);
1112
- } else {
1113
- DebugEcho("getemails: no html");
1114
- }
1115
 
 
1116
 
1117
- //DebugDump($email);
1118
- //sanity check to see if there is any info in the message
1119
- if ($email == NULL) {
1120
  $message = __('Dang, message is empty!', 'postie');
1121
- EchoError("$message_number: $message");
 
1122
  continue;
1123
- } else if ($email == 'already read') {
1124
  $message = __("Message is already marked 'read'.", 'postie');
1125
- DebugEcho("$message_number: $message");
 
1126
  continue;
1127
  }
1128
 
1129
- $tmp_config = $config;
1130
- if ($config['prefer_text_convert']) {
1131
- if ($config['prefer_text_type'] == 'plain' && trim($email['text']) == '' && trim($email['html']) != '') {
1132
- DebugEcho('get_mail: switching to html');
1133
- $tmp_config['prefer_text_type'] = 'html';
1134
- }
1135
- if ($config['prefer_text_type'] == 'html' && trim($email['html']) == '' && trim($email['text']) != '') {
1136
- DebugEcho('get_mail: switching to plain');
1137
- $tmp_config['prefer_text_type'] = 'plain';
1138
- }
1139
- }
1140
 
1141
- //Check poster to see if a valid person
1142
- $poster = $this->validate_poster($email, $tmp_config);
1143
- if (!empty($poster)) {
1144
- $this->post_email($poster, $email, $tmp_config);
1145
- DebugEcho("$message_number: processed");
1146
- } else {
1147
- EchoError('Ignoring email - not authorized.');
1148
- }
1149
- flush();
1150
 
1151
  if ($deleteMessages) {
1152
- DebugEcho("getemails: deleting {$message['uid']}");
1153
  $mailbox->deleteMessages($message['uid']);
1154
  }
1155
  }
1156
 
1157
- DebugEcho("getemails: closing connection");
1158
  $mailbox->close();
1159
 
1160
  DebugEcho("Mail fetch complete, $message_number emails");
1161
  } catch (Exception $e) {
1162
- EchoError("getemails: " . $e->getMessage());
1163
- }
1164
- }
1165
-
1166
- /**
1167
- * This function handles determining the protocol and fetching the mail
1168
- * @return array
1169
- */
1170
- function fetch_mail($server, $port, $email, $password, $protocol, $deleteMessages, $maxemails, $config) {
1171
- $emails = array();
1172
- if (!$server || !$port || !$email) {
1173
- EchoError("Missing Configuration For Mail Server");
1174
- return $emails;
1175
- }
1176
- if ($server == "pop.gmail.com") {
1177
- DebugEcho("MAKE SURE POP IS TURNED ON IN SETTING AT Gmail");
1178
- }
1179
- switch (strtolower($protocol)) {
1180
- case 'imap':
1181
- case 'imap-ssl':
1182
- $emails = $this->get_emails('imap', $server, $port, $email, $password, $protocol, $deleteMessages, $maxemails, $config);
1183
- break;
1184
- case 'pop3':
1185
- case 'pop3-ssl':
1186
- default:
1187
- $emails = $this->get_emails('pop3', $server, $port, $email, $password, $protocol, $deleteMessages, $maxemails, $config);
1188
- }
1189
-
1190
- return $emails;
1191
- }
1192
-
1193
- function disable_revisions($restore = false) {
1194
- global $_wp_post_type_features, $_postie_revisions;
1195
-
1196
- if (!$restore) {
1197
- $_postie_revisions = false;
1198
- if (isset($_wp_post_type_features['post']) && isset($_wp_post_type_features['post']['revisions'])) {
1199
- $_postie_revisions = $_wp_post_type_features['post']['revisions'];
1200
- unset($_wp_post_type_features['post']['revisions']);
1201
- }
1202
- } else {
1203
- if ($_postie_revisions) {
1204
- $_wp_post_type_features['post']['revisions'] = $_postie_revisions;
1205
- }
1206
- }
1207
- }
1208
-
1209
- function email_notify($email, $recipients, $postid) {
1210
- DebugEcho("email_notify: start");
1211
-
1212
- if (empty($postid)) {
1213
- DebugEcho("email_notify: no post id");
1214
- return;
1215
- }
1216
-
1217
- $myemailadd = get_option("admin_email");
1218
- $blogname = get_option("blogname");
1219
- $eblogname = "=?utf-8?b?" . base64_encode($blogname) . "?= ";
1220
- $posturl = get_permalink($postid);
1221
- $subject = $email['headers']['subject'];
1222
-
1223
- $sendheaders = array("From: $eblogname <$myemailadd>");
1224
-
1225
- $post_status = get_post_status($postid);
1226
-
1227
- $mailtext = "Your email '$subject' has been successfully imported into $blogname $posturl with the current status of '$post_status'.\n";
1228
-
1229
- $recipients = apply_filters('postie_email_notify_recipients', $recipients, $email, $postid);
1230
- if (count($recipients) == 0) {
1231
- DebugEcho("email_notify: no recipients after postie_email_notify_recipients filter");
1232
- return;
1233
- } else {
1234
- DebugEcho("email_notify: post postie_email_notify_recipients");
1235
- DebugDump($recipients);
1236
- }
1237
- $subject = "Email imported to $blogname ($post_status)";
1238
- $subject = apply_filters('postie_email_notify_subject', $subject, $email, $postid);
1239
- DebugEcho("email_notify: post postie_email_notify_subject: $subject");
1240
-
1241
- $mailtext = apply_filters('postie_email_notify_body', $mailtext, $email, $postid);
1242
- DebugEcho("email_notify: post postie_email_notify_body: $mailtext");
1243
-
1244
- wp_mail($recipients, $subject, $mailtext, $sendheaders);
1245
- }
1246
-
1247
- /**
1248
- * This is the main handler for all of the processing
1249
- */
1250
- function post_email($poster, $mimeDecodedEmail, $config) {
1251
- $this->disable_revisions();
1252
- //extract($config);
1253
-
1254
- /* in order to do attachments correctly, we need to associate the
1255
- attachments with a post. So we add the post here, then update it */
1256
- $tmpPost = array('post_title' => 'tmptitle', 'post_content' => 'tmpPost', 'post_status' => 'draft');
1257
- $post_id = wp_insert_post($tmpPost, true);
1258
- if (!is_wp_error($post_id)) {
1259
- DebugEcho("post_email: tmp post id is $post_id");
1260
-
1261
- $is_reply = false;
1262
-
1263
- DebugEcho("post_email: pre postie_post_pre");
1264
- $mimeDecodedEmail = apply_filters('postie_post_pre', $mimeDecodedEmail);
1265
-
1266
- $details = $this->create_post($poster, $mimeDecodedEmail, $post_id, $is_reply, $config);
1267
-
1268
- DebugEcho("post_email: Before postie_post_before filter");
1269
-
1270
- $details = apply_filters('postie_post', $details);
1271
- $details = apply_filters('postie_post_before', $details, $mimeDecodedEmail['headers']);
1272
- DebugEcho("post_email: After postie_post_before filter");
1273
- DebugDump($details);
1274
-
1275
-
1276
-
1277
- if (empty($details)) {
1278
- // It is possible that the filter has removed the post, in which case, it should not be posted.
1279
- // And if we created a placeholder post (because this was not a reply to an existing post),
1280
- // then it should be removed
1281
- if (!$is_reply) {
1282
- wp_delete_post($post_id);
1283
- DebugEcho("post_email: postie_post filter cleared the post, not saving. deleted $post_id");
1284
- } else {
1285
- DebugEcho("post_email: postie_post ended up with no post array.");
1286
- }
1287
- } else {
1288
- //get and save WP shortcodes
1289
- global $shortcode_tags;
1290
- $tmpshortcode = $shortcode_tags;
1291
- $shortcode_tags = array();
1292
-
1293
- //add Postie specific shortcodes
1294
- do_action('postie_register_shortcode');
1295
-
1296
- //make the post details available to the shortcode handlers
1297
- global $postie_post;
1298
- $postie_post = $details;
1299
-
1300
- //fix quoting
1301
- $content = $postie_post['post_content'];
1302
- $char = array('&quot;', '&#8216;', '&#8217;', '&#8220;', '&#8221;', '&#8242;', '&#8243;');
1303
- $replace = array('"', "'", "'", '"', '"', "'", '"');
1304
- $content = str_replace($char, $replace, $content);
1305
-
1306
- $postie_post['post_content'] = do_shortcode($content);
1307
-
1308
- //restore the WP shortcodes
1309
- $shortcode_tags = $tmpshortcode;
1310
-
1311
- $postid = $this->save_post($details, $is_reply);
1312
-
1313
- $recipients = array();
1314
- $dest = $config['confirmation_email'];
1315
- if ($dest == 'sender' || $dest == 'both') {
1316
- $recipients[] = $details['email_author'];
1317
- }
1318
- if ($dest == 'admin' || $dest == 'both') {
1319
- foreach (get_users(array('role' => 'administrator', 'blog_id' => get_current_blog_id())) as $user) {
1320
- $recipients[] = $user->user_email;
1321
- }
1322
- }
1323
- if (!($dest == 'admin' || $dest == 'sender' || $dest == 'both' || $dest == '')) {
1324
- $user = get_user_by('login', $dest);
1325
- $recipients[] = $user->user_email;
1326
- }
1327
-
1328
- DebugEcho("post_email: sending notifications");
1329
- $this->email_notify($mimeDecodedEmail, $recipients, $postid);
1330
-
1331
- if ($this->is_debugmode()) {
1332
- $post = get_post($post_id);
1333
- DebugEcho("post_email: resulting post");
1334
- DebugDump($post);
1335
- }
1336
- }
1337
- } else {
1338
- EchoError("post_email: wp_insert_post failed: " . $post_id->get_error_message());
1339
- DebugDump($post_id->get_error_messages());
1340
- DebugDump($post_id->get_error_data());
1341
- $this->notify_error("post_email: wp_insert_post failed creating placeholder", $post_id->get_error_message());
1342
- }
1343
- $this->disable_revisions(true);
1344
- DebugEcho("post_email: Done");
1345
- }
1346
-
1347
- /**
1348
- * This function gleans the name from an email address if available. If not
1349
- * it just returns the username (everything before @)
1350
- */
1351
- function get_name_from_email($address) {
1352
- $name = "";
1353
- $matches = array();
1354
- if (preg_match('/^([^<>]+)<([^<> ()]+)>$/', $address, $matches)) {
1355
- $name = $matches[1];
1356
- } else if (preg_match('/<([^<>@ ()]+)>/', $address, $matches)) {
1357
- $name = $matches[1];
1358
- } else if (preg_match('/(.+?)@(.+)/', $address, $matches)) {
1359
- $name = $matches[1];
1360
- }
1361
-
1362
- return trim($name);
1363
- }
1364
-
1365
- /**
1366
- * This method works around a problem with email address with extra <> in the email address
1367
- * @param string
1368
- * @return string
1369
- */
1370
- function remove_extra_characters_in_email_address($address) {
1371
- $matches = array();
1372
- if (preg_match('/^[^<>]+<([^<> ()]+)>$/', $address, $matches)) {
1373
- $address = $matches[1];
1374
- DebugEcho("RemoveExtraCharactersInEmailAddress: $address (1)");
1375
- DebugDump($matches);
1376
- } else if (preg_match('/<([^<> ()]+)>/', $address, $matches)) {
1377
- $address = $matches[1];
1378
- DebugEcho("RemoveExtraCharactersInEmailAddress: $address (2)");
1379
- }
1380
-
1381
- return $address;
1382
- }
1383
-
1384
- /**
1385
- * This compares the current address to the list of authorized addresses
1386
- * @param string - email address
1387
- * @return boolean
1388
- */
1389
- function is_email_authorized($address, $authorized) {
1390
- $r = false;
1391
- if (is_array($authorized)) {
1392
- $a = strtolower(trim($address));
1393
- if (!empty($a)) {
1394
- $r = in_array($a, array_map('strtolower', $authorized));
1395
- }
1396
- }
1397
- return $r;
1398
- }
1399
-
1400
- function header_encode($value) {
1401
- return "=?utf-8?b?" . base64_encode($value) . "?= ";
1402
- }
1403
-
1404
- function email_reject($email, $recipients, $returnToSender) {
1405
- DebugEcho("email_reject: start");
1406
-
1407
- $blogname = get_option('blogname');
1408
- $from = $email['headers']['from']['mailbox'] . '@' . $email['headers']['from']['host'];
1409
-
1410
- $subject = $email['headers']['subject'];
1411
- if ($returnToSender) {
1412
- DebugEcho("email_reject: return to sender $from");
1413
- array_push($recipients, $from);
1414
- }
1415
-
1416
- $eblogname = $this->header_encode($blogname);
1417
- $adminemail = get_option('admin_email');
1418
-
1419
- $headers = array();
1420
- $headers[] = "From: $eblogname <$adminemail>";
1421
-
1422
- DebugEcho("email_reject: To:");
1423
- DebugDump($recipients);
1424
- DebugEcho("email_reject: header:");
1425
- DebugDump($headers);
1426
-
1427
- $message = "An unauthorized message has been sent to $blogname.\n";
1428
- $message .= "Sender: $from\n";
1429
- $message .= "Subject: $subject\n";
1430
- $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 email found below.";
1431
- $message .= "\n\nOtherwise, the email has already been deleted from the server and you can ignore this message.";
1432
- $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";
1433
- $message .= "\n\nThe original content of the email has been attached.\n\n";
1434
-
1435
- $recipients = apply_filters('postie_email_reject_recipients', $recipients, $email);
1436
- if (count($recipients) == 0) {
1437
- DebugEcho("email_reject: no recipients after postie_email_reject_recipients filter");
1438
- return;
1439
- } else {
1440
- DebugEcho("email_reject: post postie_email_reject_recipients");
1441
- DebugDump($recipients);
1442
- }
1443
-
1444
- $subject = $blogname . ": Unauthorized Post Attempt from $from";
1445
- $subject = apply_filters('postie_email_reject_subject', $subject, $email);
1446
- DebugEcho("email_reject: post postie_email_reject_subject: $subject");
1447
-
1448
- $message = apply_filters('postie_email_reject_body', $message, $email);
1449
- DebugEcho("email_reject: post postie_email_reject_body: $message");
1450
-
1451
- $attachTxt = wp_tempnam() . '.txt';
1452
- file_put_contents($attachTxt, $email['text']);
1453
-
1454
- $attachHtml = wp_tempnam() . '.htm';
1455
- file_put_contents($attachHtml, $email['html']);
1456
-
1457
- wp_mail($recipients, $subject, $message, $headers, array($attachTxt, $attachHtml));
1458
-
1459
- unlink($attachTxt);
1460
- unlink($attachHtml);
1461
- }
1462
-
1463
- /**
1464
- * Determines if the sender is a valid user.
1465
- * @return integer|NULL
1466
- */
1467
- function validate_poster(&$mimeDecodedEmail, $config) {
1468
- extract($config);
1469
- $poster = NULL;
1470
- $from = '';
1471
- if (array_key_exists('headers', $mimeDecodedEmail) && array_key_exists('from', $mimeDecodedEmail['headers'])) {
1472
- $from = $mimeDecodedEmail['headers']['from']['mailbox'] . '@' . $mimeDecodedEmail['headers']['from']['host'];
1473
- $from = apply_filters('postie_filter_email', $from);
1474
- DebugEcho("validate_poster: post postie_filter_email $from");
1475
-
1476
- $toEmail = '';
1477
- if (isset($mimeDecodedEmail['headers']['to'])) {
1478
- $toEmail = $mimeDecodedEmail['headers']['to'][0]['mailbox'] . '@' . $mimeDecodedEmail['headers']['to'][0]['host'];
1479
- }
1480
-
1481
- $replytoEmail = '';
1482
- if (isset($mimeDecodedEmail['headers']['reply-to'])) {
1483
- $replytoEmail = $mimeDecodedEmail['headers']['reply-to']['mailbox'] . '@' . $mimeDecodedEmail['headers']['reply-to']['host'];
1484
- }
1485
-
1486
- $from = apply_filters("postie_filter_email2", $from, $toEmail, $replytoEmail);
1487
- DebugEcho("validate_poster: post postie_filter_email2 $from");
1488
- } else {
1489
- DebugEcho("validate_poster: No 'from' header found");
1490
- DebugDump($mimeDecodedEmail['headers']);
1491
- }
1492
-
1493
- if (array_key_exists("headers", $mimeDecodedEmail)) {
1494
- $from = apply_filters("postie_filter_email3", $from, $mimeDecodedEmail['headers']);
1495
- DebugEcho("validate_poster: post postie_filter_email3 $from");
1496
- }
1497
-
1498
- $resentFrom = '';
1499
- if (array_key_exists('headers', $mimeDecodedEmail) && array_key_exists('resent-from', $mimeDecodedEmail['headers'])) {
1500
- $resentFrom = $this->remove_extra_characters_in_email_address(trim($mimeDecodedEmail['headers']['resent-from']));
1501
- }
1502
-
1503
- //See if the email address is one of the special authorized ones
1504
- $user_ID = '';
1505
- if (!empty($from)) {
1506
- DebugEcho("validate_poster: Confirming Access For $from ");
1507
- $user = get_user_by('email', $from);
1508
- if ($user !== false) {
1509
- if (is_user_member_of_blog($user->ID)) {
1510
- $user_ID = $user->ID;
1511
- } else {
1512
- DebugEcho("validate_poster: $from is not user of blog " . get_current_blog_id());
1513
- }
1514
- }
1515
- }
1516
-
1517
- if (!empty($user_ID)) {
1518
- $user = new WP_User($user_ID);
1519
- if ($user->has_cap("post_via_postie")) {
1520
- DebugEcho("validate_poster: $user_ID has 'post_via_postie' permissions");
1521
- $poster = $user_ID;
1522
-
1523
- DebugEcho("validate_poster: pre postie_author $poster");
1524
- $poster = apply_filters("postie_author", $poster);
1525
- DebugEcho("validate_poster: post postie_author $poster");
1526
- } else {
1527
- DebugEcho("validate_poster $user_ID does not have 'post_via_postie' permissions");
1528
- $user_ID = "";
1529
- }
1530
- }
1531
-
1532
- if (empty($user_ID) && ($config['turn_authorization_off'] || $this->is_email_authorized($from, $config['authorized_addresses']) || $this->is_email_authorized($resentFrom, $config['authorized_addresses']))) {
1533
- DebugEcho("validate_poster: looking up default user " . $config['admin_username']);
1534
- $user = get_user_by('login', $config['admin_username']);
1535
- if ($user === false) {
1536
- EchoError("Your 'Default Poster' setting '" . $config['admin_username'] . "' is not a valid WordPress user (2)");
1537
- $poster = 1;
1538
- } else {
1539
- $poster = $user->ID;
1540
- DebugEcho("validate_poster: pre postie_author (default) $poster");
1541
- $poster = apply_filters("postie_author", $poster);
1542
- DebugEcho("validate_poster: post postie_author (default) $poster");
1543
- }
1544
- DebugEcho("validate_poster: found user '$poster'");
1545
- }
1546
-
1547
- if (!$poster) {
1548
- EchoError('Invalid sender: ' . htmlentities($from) . "! Not adding email!");
1549
- if ($config['forward_rejected_mail']) {
1550
- $this->email_reject($mimeDecodedEmail, array(get_option('admin_email')), $config['return_to_sender']);
1551
- EchoError("A copy of the message has been forwarded to the administrator.");
1552
- }
1553
- return '';
1554
- }
1555
-
1556
- //actually log in as the user
1557
- if ($config['force_user_login'] == true) {
1558
- $user = get_user_by('id', $poster);
1559
- if ($user) {
1560
- DebugEcho("validate_poster: logging in as {$user->user_login}");
1561
- wp_set_current_user($poster);
1562
- //wp_set_auth_cookie($poster);
1563
- do_action('wp_login', $user->user_login, $user);
1564
- } else {
1565
- DebugEcho("validate_poster: couldn't find $poster to force login");
1566
- }
1567
  }
1568
- return $poster;
1569
  }
1570
 
1571
  function postie_environment_encoding($force_display = false) {
39
 
40
  class Postie {
41
 
42
+ function load_html($text) {
43
+ return str_get_html($text, true, true, DEFAULT_TARGET_CHARSET, false);
44
+ }
45
+
46
  function get_mail() {
47
  $config = postie_config_read();
48
  if (true == $config['postie_log_error'] || (defined('POSTIE_DEBUG') && true == POSTIE_DEBUG)) {
114
  return false;
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  function show_filters_for($hook = '') {
118
  global $wp_filter;
119
  if (empty($hook) || !isset($wp_filter[$hook])) {
124
  //DebugDump($wp_filter[$hook]->callbacks);
125
  }
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  function save_email_debug($raw, $email) {
128
  if ($this->is_debugmode()) {
129
  //DebugDump($email);
144
  }
145
  }
146
 
147
+ function get_mailbox($server, $port, $email, $password, $protocol, $config) {
148
+ $protocol = strtolower($protocol);
149
+ if ($protocol == 'imap' || $protocol == 'imap-ssl') {
150
+ $type = 'imap';
151
+ } else {
152
+ $type = 'pop3';
153
+ }
154
+ $connectiontype = $config['input_connection'];
155
+ if ($connectiontype == 'curl') {
156
+ $conn = new pCurlConnection($type, trim($server), $email, $password, $port, ($protocol == 'imap-ssl' || $protocol == 'pop3-ssl'));
157
+ } else {
158
+ $conn = new pSocketConnection($type, trim($server), $email, $password, $port, ($protocol == 'imap-ssl' || $protocol == 'pop3-ssl'));
159
+ }
160
 
161
+ if ($type == 'imap') {
162
+ $srv = new pImapMailServer($conn);
163
+ } else {
164
+ $srv = new pPop3MailServer($conn);
165
+ }
166
 
167
+ $mailbox = new fMailbox($type, $conn, $srv);
168
+ return $mailbox;
169
+ }
170
 
171
+ /**
172
+ * This function handles determining the protocol and fetching the mail
173
+ */
174
+ function fetch_mail($server, $port, $email, $password, $protocol, $deleteMessages, $maxemails, $config) {
175
+ $emails = array();
176
+ if (!$server || !$port || !$email) {
177
+ EchoError("Missing Configuration For Mail Server");
178
+ return $emails;
179
+ }
180
 
181
+ DebugEcho("fetch_mail: Connecting to $server:$port ($protocol)");
 
 
 
 
182
 
183
+ try {
184
+ $mailbox = $this->get_mailbox($server, $port, $email, $password, $protocol, $config);
185
  $messages = $mailbox->listMessages($maxemails);
186
 
187
+ DebugEcho(sprintf(__("fetch_mail: There are %d messages to process", 'postie'), count($messages)));
188
 
189
  DebugDump($messages);
190
 
191
  $message_number = 0;
192
  foreach ($messages as $message) {
193
  $message_number++;
194
+ DebugEcho("fetch_mail: $message_number: ------------------------------------");
195
+ DebugEcho("fetch_mail: fetch {$message['uid']}");
 
 
 
 
 
 
 
 
 
196
 
197
+ $email = new PostieMessage($mailbox->fetchMessage($message['uid']), $config);
198
 
199
+ if ($email->is_empty()) {
 
 
200
  $message = __('Dang, message is empty!', 'postie');
201
+ EchoError("fetch_mail: $message_number: ");
202
+ DebugDump($message);
203
  continue;
204
+ } else if ($email->is_read()) {
205
  $message = __("Message is already marked 'read'.", 'postie');
206
+ DebugEcho("fetch_mail: $message_number");
207
+ DebugDump($message);
208
  continue;
209
  }
210
 
211
+ $email->preprocess();
212
+ $email->process();
213
+ $email->postprocess();
 
 
 
 
 
 
 
 
214
 
215
+ DebugEcho("fetch_mail: $message_number: processed");
 
 
 
 
 
 
 
 
216
 
217
  if ($deleteMessages) {
218
+ DebugEcho("fetch_mail: deleting {$message['uid']}");
219
  $mailbox->deleteMessages($message['uid']);
220
  }
221
  }
222
 
223
+ DebugEcho("fetch_mail: closing connection");
224
  $mailbox->close();
225
 
226
  DebugEcho("Mail fetch complete, $message_number emails");
227
  } catch (Exception $e) {
228
+ EchoError("fetch_mail: " . $e->getMessage());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  }
 
230
  }
231
 
232
  function postie_environment_encoding($force_display = false) {
postie.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Postie
5
  Plugin URI: http://PostiePlugin.com/
6
  Description: Create posts via email. Significantly upgrades the Post by Email features of WordPress.
7
- Version: 1.9.43
8
  Author: Wayne Allen
9
  Author URI: http://PostiePlugin.com/
10
  License: GPL3
@@ -28,7 +28,7 @@
28
  */
29
 
30
  /*
31
- $Id: postie.php 2246605 2020-02-19 05:59:59Z WayneAllen $
32
  */
33
 
34
  if (!defined('WPINC')) {
4
  Plugin Name: Postie
5
  Plugin URI: http://PostiePlugin.com/
6
  Description: Create posts via email. Significantly upgrades the Post by Email features of WordPress.
7
+ Version: 1.9.44
8
  Author: Wayne Allen
9
  Author URI: http://PostiePlugin.com/
10
  License: GPL3
28
  */
29
 
30
  /*
31
+ $Id: postie.php 2266315 2020-03-24 03:55:51Z WayneAllen $
32
  */
33
 
34
  if (!defined('WPINC')) {
readme.txt CHANGED
@@ -6,8 +6,8 @@ Plugin URI: http://PostiePlugin.com/
6
  Tags: e-mail, email, post-by-email
7
  Requires PHP: 5.3
8
  Requires at least: 4.0
9
- Tested up to: 5.3
10
- Stable tag: 1.9.43
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
@@ -107,6 +107,10 @@ All script, style and body tags are stripped from html emails.
107
  Attachments are now processed in the order they were attached.
108
 
109
  == CHANGELOG ==
 
 
 
 
110
  = 1.9.43 (2020-02-18) =
111
  * Begin migration of shortcode support into Postie main
112
 
6
  Tags: e-mail, email, post-by-email
7
  Requires PHP: 5.3
8
  Requires at least: 4.0
9
+ Tested up to: 5.4
10
+ Stable tag: 1.9.44
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
107
  Attachments are now processed in the order they were attached.
108
 
109
  == CHANGELOG ==
110
+ = 1.9.44 (2020-03-23) =
111
+ * refactoring to separate email fetch from email processing
112
+ * add postie_register_shortcode_pre action for registering Postie shortcodes
113
+
114
  = 1.9.43 (2020-02-18) =
115
  * Begin migration of shortcode support into Postie main
116