Postie - Version 1.4.5

Version Description

  • TODO - fix corruption of rtf attachments
  • TODO - add port checking in tests
  • TODO - non-image uploads get ignored in content when using autogallery - see replaceimageplaceholders
Download this release

Release Info

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

Code changes from version 1.4.4 to 1.4.5

Files changed (47) hide show
  1. CREDITS +7 -5
  2. Revision +2 -2
  3. config_form.php +710 -702
  4. faq.html +85 -83
  5. fetchmails.php +83 -83
  6. filterPostie.php.sample +2 -2
  7. get_mail.php +23 -41
  8. languages/makepot.cmd +1 -0
  9. languages/postie.pot +166 -320
  10. makepot +0 -5
  11. package.xml +433 -421
  12. postie-functions.php +2177 -2160
  13. postie.php +192 -166
  14. postie_test.php +60 -73
  15. readme.html +2120 -56
  16. readme.txt +38 -16
  17. templates/image_templates.php +3 -3
  18. updateVersion.cmd +21 -0
  19. util/wp-i18n/add-textdomain.php +110 -0
  20. util/wp-i18n/cron-svn-pots.php +117 -0
  21. util/wp-i18n/extract/ExtractTest.php +154 -0
  22. util/wp-i18n/extract/TODO +1 -0
  23. util/wp-i18n/extract/extract.php +209 -0
  24. util/wp-i18n/importers-i18n.php +195 -0
  25. util/wp-i18n/makepot.php +561 -0
  26. util/wp-i18n/not-gettexted.php +234 -0
  27. util/wp-i18n/pomo/entry.php +78 -0
  28. util/wp-i18n/pomo/mo.php +257 -0
  29. util/wp-i18n/pomo/po.php +384 -0
  30. util/wp-i18n/pomo/sample/app.php +63 -0
  31. util/wp-i18n/pomo/sample/languages/app-side.pot +21 -0
  32. util/wp-i18n/pomo/sample/languages/app.pot +34 -0
  33. util/wp-i18n/pomo/sample/languages/bg-side.mo +0 -0
  34. util/wp-i18n/pomo/sample/languages/bg-side.po +19 -0
  35. util/wp-i18n/pomo/sample/languages/bg.mo +0 -0
  36. util/wp-i18n/pomo/sample/languages/bg.po +32 -0
  37. util/wp-i18n/pomo/streams.php +209 -0
  38. util/wp-i18n/pomo/translations.php +275 -0
  39. util/wp-i18n/pot-ext-meta.php +76 -0
  40. util/wp-i18n/setup_locale +40 -0
  41. util/wp-i18n/t/data/not-gettexted-0-result.php +24 -0
  42. util/wp-i18n/t/data/not-gettexted-0-work.php +24 -0
  43. util/wp-i18n/t/data/not-gettexted-0.mo +0 -0
  44. util/wp-i18n/t/data/not-gettexted-0.php +24 -0
  45. util/wp-i18n/t/data/not-gettexted-0.po +21 -0
  46. util/wp-i18n/t/run.sh +2 -0
  47. util/wp-i18n/t/test_not-gettexted.php +48 -0
CREDITS CHANGED
@@ -1,9 +1,11 @@
1
  Copyright (c) 2003-2005 The Wordpress Team
2
  Copyright (c) 2004-2005 - John B. Hewitt - jb@stcpl.com.au
3
- Copyright (c) 2004 - Dan Cech - dcech@lansmash.com
4
- Copyright (c) 2005 - Dirk Elmendorf - dirk@economysizegeek.com
5
- Copyright (c) 2005 - David Luden
6
- Copyright (c) 2005 - Adrian Heydecker - http://wavestyle.ch
7
- Copyright (c) 2005 - Jay Talbot - webmaster@jaytalbot.com
 
 
8
 
9
  Licensed under the GNU GPL. For full terms see the file COPYING
1
  Copyright (c) 2003-2005 The Wordpress Team
2
  Copyright (c) 2004-2005 - John B. Hewitt - jb@stcpl.com.au
3
+ Copyright (c) 2004 Dan Cech - dcech@lansmash.com
4
+ Copyright (c) 2005 Dirk Elmendorf - dirk@economysizegeek.com
5
+ Copyright (c) 2005 David Luden
6
+ Copyright (c) 2005 Adrian Heydecker - http://wavestyle.ch
7
+ Copyright (c) 2005 Jay Talbot - webmaster@jaytalbot.com
8
+ Copyright (c) 2008-2012 Rob Felty http://robfelty.com/
9
+ Copyright (c) 2012 Wayne Allen http://postieplugin.com/
10
 
11
  Licensed under the GNU GPL. For full terms see the file COPYING
Revision CHANGED
@@ -1,2 +1,2 @@
1
- Revision: 584134
2
- Last Changed Date: 2011-12-12 23:28:29 -0500 (Mon, 12 Dec 2011)
1
+ Revision: 622321
2
+ Last Changed Date: 2012-11-07 14:50:48 -0800 (Wed, 07 Nov 2012)
config_form.php CHANGED
@@ -1,730 +1,738 @@
1
  <div class="wrap">
2
- <h2>
3
- <a style='text-decoration:none' href='options-general.php?page=postie/postie.php'>
4
- <img src="<?php
5
- echo ' ../wp-content/plugins/postie/images/mail.png'; ?>" alt="postie" /><?php
6
- _e('Postie Options', 'postie');
7
- ?></a>
8
- </h2>
9
- <?php
10
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie-functions.php');
11
- if (isset($_POST["action"])) {
12
- switch($_POST["action"]) {
13
- case "reset":
14
- ResetPostieConfig();
15
- $message = 1;
16
- break;
17
- case "cronless":
18
- check_postie();
19
- $message = 1;
20
- break;
21
- case "test":
22
- include('postie_test.php');
23
- exit;
24
- break;
25
- case "runpostie":
26
- echo "Checking for mail manually\n";
27
- include('get_mail.php');
28
- exit;
29
- break;
30
- default:
31
- $message = 2;
32
- break;
33
- }
34
- }
35
- global $wpdb,$wp_roles;
36
 
37
- $title = __('Postie Options', 'postie');
38
- $parent_file = 'options-general.php';
39
- $config = get_option( 'postie-settings');
40
- if ( empty ($config) ) $config = ResetPostieConfig();
41
- if ( defined ( 'POSTIE_DEBUG' ) ) var_dump( $config );
42
- $arrays = get_arrayed_settings();
 
 
43
  // some fields are stored as arrays, because that makes back-end processing much easier
44
  // and we need to convert those fields to strings here, for the options form
45
- foreach ( $arrays as $sep => $fields ) {
46
- foreach ( $fields as $field ) {
47
- $config[$field] = implode( $sep, $config[$field] );
48
- }
49
- }
50
- extract($config);
51
- if ($interval=='manual') {
52
- wp_clear_scheduled_hook('check_postie_hook');
53
- }
54
-
55
- $messages[1] = __("Configuration successfully updated!",'postie');
56
- $messages[2] = __("Error - unable to save configuration",'postie');
57
 
58
- ?>
59
- <?php if (isset($_GET['message'])) : ?>
60
- <div class="updated"><p><?php _e($messages[$_GET['message']], 'postie'); ?></p></div>
61
- <?php endif; ?>
62
- <form name="postie-options" method="post">
63
- <input type="hidden" name="action" value="reset" />
64
- <input name="Submit" value="<?php _e("Reset Settings To Defaults", 'postie')?> &raquo" type="submit" class='button'>
65
- </form>
66
- <form name="postie-options" method='post'>
67
- <input type="hidden" name="action" value="runpostie" />
68
- <input name="Submit" value="<?php _e("Run Postie", 'postie');?> &raquo;" type="submit" class='button'>
69
- <?php _e("(To run the check mail script manually)", 'postie');?>
70
- </form>
71
- <form name="postie-options" method="post">
72
- <input type="hidden" name="action" value="test" />
73
- <input name="Submit" value="<?php _e("Test Config", 'postie');?>&raquo;" type="submit" class='button'>
74
- <?php _e("this will run a special script to test your configuration options", 'postie');?>
75
- </form>
76
- <form name="postie-options" method="post" action='options.php'>
77
- <?php settings_fields( 'postie-settings' ); ?>
78
- <input type="hidden" name="action" value="config" />
79
- <div id="simpleTabs">
80
- <div class="simpleTabs-nav">
81
- <ul>
82
- <li id="simpleTabs-nav-1"><?php _e('Mailserver' , 'postie') ?></li>
83
- <li id="simpleTabs-nav-2"><?php _e('User' , 'postie') ?></li>
84
- <li id="simpleTabs-nav-3"><?php _e('Message' , 'postie') ?></li>
85
- <li id="simpleTabs-nav-4"><?php _e('Image' , 'postie') ?></li>
86
- <li id="simpleTabs-nav-5"><?php _e('Video and Audio' , 'postie') ?></li>
87
- <li id="simpleTabs-nav-6"><?php _e('Attachments' , 'postie') ?></li>
88
- <li id="simpleTabs-nav-7"><?php _e('Help' , 'postie') ?></li>
89
- <li id="simpleTabs-nav-8"><?php _e('FAQ' , 'postie') ?></li>
90
- </ul>
91
- </div>
92
- <div id="simpleTabs-content-1" class="simpleTabs-content">
93
- <table class='form-table'>
 
 
94
 
95
- <tr>
96
- <th scope="row"><?php _e('Mail Protocol:', 'postie') ?> </th>
97
- <td>
98
- <select name='postie-settings[input_protocol]' id='postie-settings-input_protocol'>
99
- <option value="pop3" <?php if( $input_protocol == "pop3" ) { echo " selected='selected' ";} ?>>POP3</option>
100
- <?php if (HasIMAPSupport(false)):?>
101
- <option value="imap" <?php if($input_protocol == "imap") { echo "selected";} ?>>IMAP</option>
102
- <option value="pop3-ssl" <?php if($input_protocol == "pop3-ssl") { echo "selected";} ?>>POP3-SSL</option>
103
- <option value="imap-ssl" <?php if($input_protocol == "imap-ssl") { echo "selected";} ?>>IMAP-SSL</option>
104
- </select>
105
- <?php else:?>
106
- </select>
107
- <span class="recommendation">IMAP/IMAP-SSL/POP3-SSL unavailable</span>
108
- <?php endif;?>
109
- </select>
110
-
111
- </td>
112
- </tr>
113
- <tr>
114
- <th scope="row"><?php _e('Port:', 'postie') ?><br />
115
- <span class='recommendation'><?php _e("Standard Ports:", 'postie');?><br />
116
- <?php _e("POP3", 'postie');?> - 110<br />
117
- <?php _e("IMAP", 'postie');?> - 143<br />
118
- <?php _e("IMAP-SSL", 'postie');?>- 993 <br />
119
- <?php _e("POP3-SSL", 'postie');?> - 995 <br />
120
- </span>
121
- </th>
122
- <td>
123
- <input name='postie-settings[mail_server_port]' type="text" id='postie-settings-mail_server_port' value="<?php echo $mail_server_port;?>" size="6" />
124
- </td>
125
- </tr>
126
- <tr>
127
- <th scope="row"><?php _e('Postie Time Correction:', 'postie') ?>
128
- <br />
129
- <span class='recommendation'><?php _e("Should be the same as your normal offset - but this lets you adjust it in cases where that doesn't work.", 'postie');?></span>
130
- </th>
131
- <td><input name='postie-settings[time_offset]' type="text" id='postie-settings-time_offset' size="2" value="<?php echo $time_offset; ?>" />
132
- <?php _e('hours', 'postie') ?>
133
 
134
- </td>
135
- </tr>
136
- <tr valign="top">
137
- <th scope="row"><?php _e('Mail Server:', 'postie') ?></th>
138
- <td><input name='postie-settings[mail_server]' type="text" id='postie-settings-mail_server' value="<?php echo $mail_server;?>" size="40" />
139
- </td>
140
- </tr>
141
- <tr valign="top">
142
- <th width="33%" scope="row"><?php _e('Mail Userid:', 'postie') ?></th>
143
- <td><input name='postie-settings[mail_userid]' type="text" id='postie-settings-mail_userid' value="<?php echo $mail_userid; ?>" size="40" /></td>
144
- </tr>
145
- <tr valign="top">
146
- <th scope="row"><?php _e('Mail Password:', 'postie') ?></th>
147
- <td>
148
- <input name='postie-settings[mail_password]' type="text" id='postie-settings-mail_password' value="<?php echo $mail_password; ?>" size="40" />
149
- </td>
150
- </tr>
151
- <tr><th>
152
- <?php _e('Check for mail every', 'postie') ?>
153
- </th>
154
- <td>
155
- <select name='postie-settings[interval]' id='postie-settings-interval'>
156
- <option value="weekly" <?php if($interval == "weekly") { echo "selected='selected'";} ?>><?php _e('Once weekly', 'postie') ?></option>
157
- <option value="daily"<?php if($interval == "daily") { echo "selected='selected'";} ?>><?php _e('daily', 'postie') ?></option>
158
- <option value="hourly" <?php if($interval == "hourly") { echo "selected='selected'";} ?>><?php _e('hourly', 'postie') ?></option>
159
- <option value="twiceperhour" <?php if($interval == "twiceperhour") { echo "selected='selected'";} ?>><?php _e('twice per hour', 'postie') ?></option>
160
- <option value="tenminutes" <?php if($interval == "tenminutes") { echo "selected='selected'";} ?>><?php _e('every ten minutes', 'postie') ?></option>
161
- <option value="manual" <?php if($interval == "manual") { echo
162
- "selected='selected'";} ?>><?php _e('check manually', 'postie') ?></option>
163
- </select>
164
- </td>
165
- </tr>
166
- <?php echo BuildBooleanSelect("Delete email after
167
- posting",'postie-settings[delete_mail_after_processing]',$delete_mail_after_processing,"Only set to no for testing purposes");?>
168
- </table>
169
- </div>
170
- <div id="simpleTabs-content-2" class="simpleTabs-content">
171
- <table class='form-table'>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
- <?php echo BuildBooleanSelect("Allow Anyone To Post Via
174
- Email","postie-settings[turn_authorization_off]",$turn_authorization_off,"Changing this to yes is NOT RECOMMEDED - anything that gets sent in will automatically be posted. This could make it easier to compromise your server - YOU HAVE BEEN WARNED.");?>
175
- <tr>
176
- <th scope="row"><?php _e('Roles That Can Post:', 'postie') ?>
177
- <br />
178
- <span class='recommendation'><?php _e("This allows you to grant access to other users to post if they have the proper access level", 'postie');?></span></th>
179
- <td>
180
- <table>
181
- <tr><th>Administrator role can always post.</th>
182
- <?php
183
- foreach($wp_roles->role_names as $roleId => $name) {
184
- $name=translate_with_context($name);
185
- $role = &$wp_roles->get_role($roleId);
186
- if ($roleId != "administrator") { ?>
187
- <tr><td>
188
- <input type='checkbox' value='1' name='postie-settings[role_access][<?php echo $roleId; ?>]' <?php if ($role->has_cap("post_via_postie")) echo
189
- 'checked="checked"'; ?> >
190
- <?php echo $name; ?>
191
- </td></tr>
192
- <?php
193
- }
194
- }
195
- ?>
196
- </table>
197
- </td>
198
- </tr>
199
- <tr>
200
- <th width="33%" valign="top" scope="row"><?php _e('Post status:', 'postie') ?> </th>
201
- <td>
202
- <select name='postie-settings[post_status]' id='postie-settings-post_status'>
203
- <option value="publish" <?php if($post_status == "publish") { echo
204
- "selected";} ?>>Published</option>
205
- <option value="draft" <?php if($post_status == "draft") { echo
206
- "selected";} ?>>Draft</option>
207
- <option value="pending" <?php if($post_status == "pending") { echo
208
- "selected";} ?>>Pending Review</option>
209
- <option value="private" <?php if($post_status == "private") { echo
210
- "selected";} ?>>Private</option>
211
- </select> </td>
212
- </tr>
213
- <?php echo BuildTextArea("Authorized
214
- Addresses","postie-settings[authorized_addresses]",$authorized_addresses,"Put each email address on a single line. Posts from emails in this list will be treated as if they came from the admin. If you would prefer to have users post under their own name - create a WordPress user with the correct access level.");?>
215
- <tr>
216
- <th width="33%" valign="top" scope="row">
217
- <?php _e('Admin username:') ?> </th>
218
- <td>
219
- <input name='postie-settings[admin_username]' type="text" id='postie-settings-admin_username'
220
- value="<?php echo $admin_username; ?>" size="50" /> </td>
221
- </tr>
222
- </table>
223
- </div>
224
- <div id="simpleTabs-content-3" class="simpleTabs-content">
225
- <table class='form-table'>
226
- <tr valign="top">
227
- <th scope="row"><?php _e('Default post by mail category:', 'postie') ?></th>
228
- <td>
229
- <?php
230
- $defaultCat=$default_post_category;
231
- wp_dropdown_categories("name=postie-settings[default_post_category]&hierarchical=1&selected=$defaultCat&hide_empty=0"); ?>
232
- </tr>
233
- <tr valign="top">
234
- <th scope="row">
235
- <?php _e('Default post by mail tag(s)', 'postie') ?><br /><span
236
- class='recommendation'><?php _e('separated by commas', 'postie')
237
- ?></span></th>
238
- <td><input type='text' name='postie-settings[default_post_tags]'
239
- id='postie-settings-default_post_tags' value='<?php echo
240
- $default_post_tags ?>' />
241
- </td>
242
- </tr>
243
- <tr>
244
- <th width="33%" valign="top" scope="row"><?php _e('Default Title:', 'postie') ?> </th>
245
- <td>
246
- <input name='postie-settings[default_title]' type="text" id='postie-settings-default_title' value="<?php echo $default_title; ?>" size="50" /><br />
247
- <br />
248
- </td>
249
- </tr>
250
- <tr>
251
- <th width="33%" valign="top" scope="row"><?php _e('Preferred
252
- Text Type:', 'postie') ?> </th>
253
- <td>
254
- <select name='postie-settings[prefer_text_type]' id='postie-settings-prefer_text_type'>
255
- <option value="plain">plain</option>
256
- <option value="html" <?php if($prefer_text_type == "html") { echo "selected";} ?>>html</option>
257
- </select><br />
258
- </td>
259
- </tr>
260
- <?php echo BuildBooleanSelect("Forward Rejected Mail","postie-settings[forward_rejected_mail]",$forward_rejected_mail);?>
261
- <?php echo BuildBooleanSelect("Allow Subject In Mail","postie-settings[allow_subject_in_mail]",$allow_subject_in_mail);?>
262
- <?php echo BuildBooleanSelect("Allow HTML In Mail Subject","postie-settings[allow_html_in_subject]",$allow_html_in_subject);?>
263
- <?php echo BuildBooleanSelect("Allow HTML In Mail Body","postie-settings[allow_html_in_body]",$allow_html_in_body);?>
264
- <tr>
265
- <th width="33%" valign="top" scope="row"><?php _e('Tag Of
266
- Message Start:', 'postie') ?> <br />
267
- <span class='recommendation'><?php _e('Use to remove any text from a message that the email provider puts at the top of the message', 'postie') ?></span></th>
268
- <td>
269
- <input name='postie-settings[message_start]' type="text" id='postie-settings-message_start' value="<?php echo $message_start; ?>" size="20" /><br />
270
- </td>
271
- </tr>
272
- <tr>
273
- <th width="33%" valign="top" scope="row"><?php _e('Tag Of
274
- Message End:', 'postie') ?> <br />
275
- <span class='recommendation'><?php _e('Use to remove any text from a message that the email provider puts at the end of the message', 'postie') ?></span></th>
276
- <td>
277
- <input name='postie-settings[message_end]' type="text" id='postie-settings-message_end' value="<?php echo $message_end; ?>" size="20" /><br />
278
- </td>
279
- </tr>
280
- </table>
281
- <a style='cursor:pointer' onclick='showAdvanced("message-advanced", "message-advanced-arrow");'><span id="message-advanced-arrow">&#9654;</span> Advanced options</a>
282
- <div id="message-advanced" style='display:none;'>
283
- <table class='form-table'>
284
- <?php echo BuildBooleanSelect("Wrap content in pre tags","postie-settings[wrap_pre]",$wrap_pre);?>
285
- <?php echo BuildBooleanSelect("Filter newlines", "postie-settings[filternewlines]",$filternewlines,
286
- "Set to no if using markdown or textitle syntax");?>
287
- <?php echo BuildBooleanSelect("Replace newline characters with html line breaks (&lt;br /&gt;)","postie-settings[convertnewline]",$convertnewline);?>
288
- <?php echo BuildBooleanSelect("Return rejected mail to sender","postie-settings[return_to_sender]",$return_to_sender);?>
289
- <tr>
290
- <th>
291
- <?php _e("Send post confirmation e-mail to" , 'postie') ?>
292
- </th>
293
- <td>
294
- <select name='postie-settings[confirmation_email]'
295
- id='postie-settings-confirmation_email'>
296
- <option value="sender" <?php if($confirmation_email == "sender") {
297
- echo "selected";} ?>><?php _e('sender', 'postie') ?></option>
298
- <option value="admin" <?php if($confirmation_email == "admin") { echo
299
- "selected";} ?>><?php _e('administrator', 'postie') ?></option>
300
- <option value="both" <?php if($confirmation_email == "both") { echo
301
- "selected";} ?>><?php _e('sender and administrator', 'postie') ?></option>
302
- <option value="" <?php if($confirmation_email == "") { echo
303
- "selected";} ?>><?php _e('none', 'postie') ?></option>
304
- </select>
305
- </td>
306
- </tr>
307
-
308
- <?php echo BuildBooleanSelect("Automatically convert urls to links","postie-settings[converturls]",$converturls);?>
309
- <?php echo BuildBooleanSelect("Use shortcode for embedding video (youtube and others)","postie-settings[shortcode]",$shortcode);?>
310
- <tr>
311
- <th width="33%" valign="top" scope="row"><?php _e('Encoding for pages and feeds:', 'postie') ?> </th>
312
- <td>
313
- <input name='postie-settings[message_encoding]' type="text" id='postie-settings-message_encoding' value="<?php echo $message_encoding; ?>" size="10" />
314
- <span class='recommendation'>UTF-8 <?php _e("should handle ISO-8859-1 as well", 'postie');?></span>
315
- </td>
316
- </tr>
317
- <?php echo BuildBooleanSelect("Decode Quoted Printable
318
- Data","postie-settings[message_dequote]",$message_dequote);?>
319
- <?php echo BuildTextArea("Supported File
320
- Types","postie-settings[supported_file_types]",$supported_file_types,"Put each type on a single line.");?>
321
- <?php echo BuildTextArea("Banned File
322
- Names","postie-settings[banned_files_list]",$banned_files_list,"Put each file name on a single line.Files matching this list will never be posted to your blog. You can use wildcards such as *.xls, or *.* for all files");?>
323
- <?php echo BuildBooleanSelect("Drop The Signature From Mail","postie-settings[drop_signature]",$drop_signature);?>
324
- <?php echo BuildTextArea("Signature
325
- Patterns","postie-settings[sig_pattern_list]",$sig_pattern_list,"Put each pattern on a separate line and make sure to escape any special characters.");?>
326
- <?php echo BuildTextArea("Allowed SMTP
327
- servers","postie-settings[smtp]",$smtp,"Only allow messages which have been sent throught the following smtp servers. Put each server on a separate line. Leave blank to not check smtp servers.");?>
328
- </table>
329
- </div> <!-- advanced options -->
330
  </div>
331
- <div id="simpleTabs-content-4" class="simpleTabs-content">
332
- <table class='form-table'>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
- <?php echo BuildBooleanSelect("Automatically insert image
336
- gallery","postie-settings[auto_gallery]",$auto_gallery,"If any
337
- images are attached, they will automatically be inserted as a
338
- gallery");?>
339
- <?php echo BuildBooleanSelect("Post Images At End","postie-settings[images_append]",$images_append,"No means they will be put before the text of the message.");?>
340
- <?php echo BuildBooleanSelect("Start Image Count At
341
- 0","postie-settings[start_image_count_at_zero]",$start_image_count_at_zero);?>
342
- <tr>
343
- <th width="33%" valign="top" scope="row"><?php _e('Image Place Holder Tag:', 'postie') ?> </th>
344
- <td>
345
- <input name='postie-settings[image_placeholder]' type="text" id='postie-settings-image_placeholder' value="<?php echo $image_placeholder; ?>" size="50" /><br />
346
- </td>
347
- </tr>
348
- <tr>
349
- <th width="33%" valign="top" scope="row"><?php _e('Image
350
- Template', 'postie') ?><br />
351
- <span class='recommendation'><?php _e('Choose a default template,
352
- then customize to your liking in the text box',
353
- 'postie');?></span><br /><br />
354
- <span class='recommendation'><?php _e('Sizes for thumbnail, medium, and large images can be chosen in the <a href="options-media.php">Media Settings</a>. The samples here use the default sizes, and will not reflect the sizes you have chosen.', 'postie');?></span>
355
- </th>
356
- <td>
357
- <input type='hidden' id='postie-settings-selected_imagetemplate' name='postie-settings[selected_imagetemplate]'
358
- value="<?php echo attribute_escape($selected_imagetemplate) ?>" />
359
- <select name='imagetemplateselect' id='imagetemplateselect'
360
- onchange="changeStyle('imageTemplatePreview','postie-settings-imagetemplate',
361
- 'imagetemplateselect', 'postie-settings-selected_imagetemplate','smiling.jpg');" />
362
- <?php
363
- include('templates/image_templates.php');
364
- $styleOptions = $imageTemplates;
365
- $selected=$selected_imagetemplate;
366
- foreach ($styleOptions as $key=>$value) {
367
- if ($key!='selected') {
368
- if ($key==$selected) {
369
- $select=' selected=selected ';
370
- } else {
371
- $select=' ';
372
- }
373
- if ($key=='custom')
374
- $value = $imagetemplate;
375
- echo '<option' . $select . 'value="'.
376
- attribute_escape($value) . '" >'.$key . '</option>';
377
- }
378
- }
379
- ?>
380
- </select>
381
- &nbsp;&nbsp;
382
- <?php _e('Preview', 'postie'); ?>
383
- <span id='imageTemplatePreview' alt='preview'></span>
384
- <textarea onchange='changeStyle("imageTemplatePreview", "postie-settings-imagetemplate",
385
- "imagetemplateselect", "postie-settings-selected_imagetemplate", "smiling.jpg", true);' cols='70' rows='7' id='postie-settings-imagetemplate'
386
- name='postie-settings[imagetemplate]'><?php echo attribute_escape($imagetemplate) ?></textarea>
387
- </td>
388
- </tr>
389
- <?php echo BuildBooleanSelect("Use custom image
390
- field","postie-settings[custom_image_field]",$custom_image_field,"When true, images will not appear in the post. Instead the url to the image will be input into a custom field named 'image'.");?>
391
- </table>
392
- </div>
393
 
394
- <!--
395
- ########## VIDEO AND AUDIO OPTIONS ###################
396
- -->
397
 
398
- <div id="simpleTabs-content-5" class="simpleTabs-content">
399
- <table class='form-table'>
400
 
401
- <tr><th scope='row'><?php _e('Video template 1', 'postie') ?><br />
402
- <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie') ?></span></th>
403
- <?php $templateDir = get_option('siteurl') . '/' . PLUGINDIR . '/postie/templates'; ?>
404
- <td>
405
- <input type='hidden' id='postie-settings-selected_video1template' name='postie-settings[selected_video1template]'
406
- value="<?php echo attribute_escape($selected_video1template) ?>" />
407
- <select name='video1templateselect' id='video1templateselect'
408
- onchange="changeStyle('video1TemplatePreview','postie-settings-video1template',
409
- 'video1templateselect', 'postie-settings-selected_video1template','hi.mp4');" />
410
- <?php
411
- include('templates/video1_templates.php');
412
- $styleOptions=$video1Templates;
413
- $selected=$selected_video1template;
414
- foreach ($styleOptions as $key=>$value) {
415
- if ($key!='selected') {
416
- if ($key==$selected) {
417
- $select=' selected=selected ';
418
- } else {
419
- $select=' ';
420
- }
421
- if ($key=='custom')
422
- $value = $video1template;
423
- echo '<option' . $select . 'value="'.
424
- attribute_escape($value) . '" >'.$key . '</option>';
425
- }
426
- }
427
- ?>
428
- </select>
429
- &nbsp;&nbsp;
430
- <?php _e('Preview', 'postie'); ?>
431
- <span id='video1TemplatePreview' alt='preview'></span>
432
- <textarea onchange="changeStyle('video1TemplatePreview','postie-settings-video1template',
433
- 'video1templateselect', 'postie-settings-selected_video1template','hi.mp4',true);" cols='70' rows='7' id='postie-settings-video1template'
434
- name='postie-settings[video1template]'><?php echo attribute_escape($video1template) ?></textarea>
435
- </td>
436
- </tr>
437
- <tr>
438
- <th width="33%" valign="top" scope="row">
439
- <?php _e('Video 1 file types:') ?><br /><span class='recommendation'>
440
- <?php _e('Use the video template 1 for these files types (separated by
441
- commas)', 'postie') ?></span> </th>
442
- <td>
443
- <input name='postie-settings[video1types]' type="text" id='postie-settings-video1types'
444
- value="<?php if ($video1types!='') echo $video1types; ?>" size="40" /> </td>
445
- </tr>
446
- <tr><th scope='row'><?php _e('Video template 2', 'postie') ?><br />
447
- <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie') ?></span></th>
448
- <td>
449
- <input type='hidden' id='postie-settings-selected_video2template' name='postie-settings[selected_video2template]'
450
- value="<?php echo attribute_escape($selected_video2template) ?>" />
451
- <select name='video2templateselect' id='video2templateselect'
452
- onchange="changeStyle('video2TemplatePreview','postie-settings-video2template',
453
- 'video2templateselect', 'postie-settings-selected_video2template','hi.flv');" />
454
- <?php
455
- include('templates/video2_templates.php');
456
- $styleOptions=$video2Templates;
457
- $selected=$selected_video2template;
458
- foreach ($styleOptions as $key=>$value) {
459
- if ($key!='selected') {
460
- if ($key==$selected) {
461
- $select=' selected=selected ';
462
- } else {
463
- $select=' ';
464
- }
465
- if ($key=='custom')
466
- $value = $video2template;
467
- echo '<option' . $select . 'value="'.
468
- attribute_escape($value) . '" >'.$key . '</option>';
469
- }
470
- }
471
- ?>
472
- </select>
473
- &nbsp;&nbsp;
474
- <?php _e('Preview', 'postie'); ?>
475
- <span id='video2TemplatePreview' alt='preview'></span>
476
- <textarea onchange="changeStyle('video2TemplatePreview','postie-settings-video2template',
477
- 'video2templateselect', 'postie-settings-selected_video2template','hi.flv',true);" cols='70' rows='7' id='postie-settings-video2template'
478
- name='postie-settings[video2template]'><?php echo attribute_escape($video2template) ?></textarea>
479
- </td>
480
- </tr>
481
- <tr>
482
- <th width="33%" valign="top" scope="row">
483
- <?php _e('Video 2 file types:') ?><br /><span class='recommendation'>
484
- <?php _e('Use the video template 2 for these files types (separated by
485
- commas)', 'postie') ?></span> </th>
486
- <td>
487
- <input name='postie-settings[video2types]' type="text" id='postie-settings-video2types'
488
- value="<?php if ($video2types!='') echo $video2types; ?>" size="40" /> </td>
489
- </tr>
490
- <tr><th scope='row'><?php _e('Audio template', 'postie') ?><br />
491
- <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie') ?></span></th>
492
- <td>
493
- <input type='hidden' id='postie-settings-selected_audiotemplate' name='postie-settings[selected_audiotemplate]'
494
- value="<?php echo attribute_escape($selected_audiotemplate) ?>" />
495
- <select name='audiotemplateselect' id='audiotemplateselect'
496
- onchange="changeStyle('audioTemplatePreview','postie-settings-audiotemplate',
497
- 'audiotemplateselect', 'postie-settings-selected_audiotemplate','funky.mp3', false);" />
498
- <?php
499
- include('templates/audio_templates.php');
500
- $styleOptions=$audioTemplates;
501
- $selected=$selected_audiotemplate;
502
- foreach ($styleOptions as $key=>$value) {
503
- if ($key!='selected') {
504
- if ($key==$selected) {
505
- $select=' selected=selected ';
506
- } else {
507
- $select=' ';
508
- }
509
- if ($key=='custom')
510
- $value = $audiotemplate;
511
- echo '<option' . $select . 'value="'.
512
- attribute_escape($value) . '" >'.$key . '</option>';
513
- }
514
- }
515
- ?>
516
- </select>
517
- &nbsp;&nbsp;
518
- <?php _e('Preview', 'postie'); ?>
519
- <span id='audioTemplatePreview' alt='preview'></span>
520
- <textarea onchange="changeStyle('audioTemplatePreview','postie-settings-audiotemplate',
521
- 'audiotemplateselect', 'postie-settings-selected_audiotemplate','funky.mp3', true);" cols='70' rows='7' id='postie-settings-audiotemplate'
522
- name='postie-settings[audiotemplate]'><?php echo attribute_escape($audiotemplate) ?></textarea>
523
- </td>
524
- </tr>
525
- <tr>
526
- <th width="33%" valign="top" scope="row">
527
- <?php _e('Audio file types:') ?><br /><span class='recommendation'>
528
- <?php _e('Use the audio template for these files types (separated by
529
- commas)', 'postie') ?></span> </th>
530
- <td>
531
- <input name='postie-settings[audiotypes]' type="text" id='postie-settings-audiotypes'
532
- value="<?php if ($audiotypes!='') echo $audiotypes; ?>" size="40" /> </td>
533
- </tr>
534
- </table>
535
- </td>
536
- </tr>
537
- </table>
538
- </div>
539
- <div id="simpleTabs-content-6" class="simpleTabs-content">
540
- <table class='form-table'>
541
 
542
- <tr><th scope='row'><?php _e('Attachment icon set', 'postie') ?><br />
543
- <td>
544
- <input type='hidden' id='postie-settings-icon_set' name='postie-settings[icon_set]'
545
- value="<?php echo attribute_escape($icon_set) ?>" />
 
546
 
547
- <?php
548
- $icon_sets=array('silver','black','white','custom', 'none');
549
- $icon_sizes=array(32,48,64);
550
- ?>
551
- <select name='icon_set_select' id='icon_set_select'
552
- onchange="changeIconSet(this);" />
553
- <?php
554
- $styleOptions=$icon_sets;
555
- $selected=$icon_set;
556
- foreach ($styleOptions as $key) {
557
- if ($key!='selected') {
558
- if ($key==$selected) {
559
- $select=' selected=selected ';
560
- } else {
561
- $select=' ';
562
- }
563
- echo '<option' . $select . 'value="'.
564
- attribute_escape($key) . '" >'.$key . '</option>';
565
- }
566
- }
567
- ?>
568
- </select>
569
- </td>
570
- </tr>
571
- <tr><th scope='row'><?php _e('Attachment icon size (in pixels)', 'postie') ?><br />
572
- <td>
573
- <input type='hidden' id='postie-settings-icon_size' name='postie-settings[icon_size]'
574
- value="<?php echo attribute_escape($icon_size) ?>" />
575
- <select name='icon_size_select' id='icon_size_select'
576
- onchange="changeIconSet(this, true);" />
577
- <?php
578
- $styleOptions=$icon_sizes;
579
- $selected=$icon_size;
580
- foreach ($styleOptions as $key) {
581
- if ($key!='selected') {
582
- if ($key==$selected) {
583
- $select=' selected=selected ';
584
- } else {
585
- $select=' ';
586
- }
587
- echo '<option' . $select . 'value="'.
588
- attribute_escape($key) . '" >'.$key . '</option>';
589
- }
590
- }
591
- ?>
592
- </select>
593
- </td>
594
- </tr>
595
- <tr>
596
- <th style='height:64px'>
597
- <?php _e('Preview', 'postie'); ?>
598
- </th>
599
- <td>
600
- <span id='postie-settings-attachment_preview'></span>
601
- </td>
602
- </tr>
603
- </tr>
604
- </table>
605
- </div>
606
- <div id="simpleTabs-content-7" class="simpleTabs-content">
607
- <?php include('readme.html'); ?>
608
- </div>
609
- <div id="simpleTabs-content-8" class="simpleTabs-content">
610
- <?php include('faq.html'); ?>
611
- </div>
612
 
613
- <p class="submit">
614
- <input type="hidden" name="action" value="update" />
615
 
616
- <input type="hidden" name="page_options"
617
- value="postie-settings" />
618
 
619
- <input type="submit" name="Submit" value="<?php _e('Save Changes') ?>" />
620
 
621
- </p>
622
- </form>
623
  </div>
624
- <p>
625
- <a href="http://validator.w3.org/check?uri=referer"><img
626
- src="/images/valid-xhtml10.png" alt="Valid XHTML 1.0!" style="height:20px;
627
- width:65px; border:0;" /></a> <a
628
- href="http://jigsaw.w3.org/css-validator/check/referer"><img
629
- style="border:0;width:65px;height:20px;" src="/images/vcss.gif" alt="Valid
630
- CSS!" /></a><br />
631
- </p>
632
 
633
- <?php $iconDir = get_option('siteurl') . '/' . PLUGINDIR . '/postie/icons'; ?>
634
  <script type="text/javascript">
635
- jQuery(document).ready(function() {
636
- jQuery("#simpleTabs").simpleTabs({
637
- fadeSpeed: "medium", // @param : low, medium, fast
638
- defautContent: 1, // @param : number ( simpleTabs-nav-number)
639
- autoNav: "false", // @param : true or false
640
- closeTabs : "false" // @param : true or false;
641
- });
642
 
643
- });
644
- function changeIconSet(selectBox, size) {
645
- var iconSet=document.getElementById('postie-settings-icon_set');
646
- var iconSize=document.getElementById('postie-settings-icon_size');
647
- var preview=document.getElementById('postie-settings-attachment_preview');
648
- var iconDir = '<?php echo $iconDir ?>/';
649
- if (size==true) {
650
- var hiddenInput=iconSize
651
- } else {
652
- var hiddenInput=iconSet;
653
- }
654
- for(i=0; i<selectBox.options.length; i++) {
655
- if (selectBox.options[i].selected == true) {
656
- hiddenInput.value=selectBox.options[i].value;
 
 
 
 
 
 
 
 
 
 
 
 
 
657
  }
658
- }
659
- var fileTypes= new Array('doc', 'pdf', 'xls', 'ppt');
660
- preview.innerHTML='';
661
- for (j=0; j<fileTypes.length; j++) {
662
- preview.innerHTML+="<img src='" + iconDir + iconSet.value + '/' +
663
- fileTypes[j] + '-' + iconSize.value + ".png' />";
664
- }
665
- preview.innerHTML+='<br />Here is some sample text with a link to a ' +
666
- 'word document that I think you might find interesting<br />' +
667
- "<a href='#'><img style='text-decoration:none' src='" +
668
- iconDir + iconSet.value + '/doc' +
669
- '-' + iconSize.value + ".png' />Interesting document</a>";
670
- }
671
- function changeStyle(preview,template,select,selected,sample,custom) {
672
- var preview = document.getElementById(preview);
673
- var pageStyles = document.getElementById(select);
674
- var selectedStyle;
675
- var hiddenStyle=document.getElementById(selected);
676
- var pageStyle = document.getElementById(template);
677
- if (custom==true) {
678
- selectedStyle=pageStyles.options[pageStyles.options.length-1];
679
- selectedStyle.value=pageStyle.value;
680
- selectedStyle.selected=true;
681
- } else {
682
- for(i=0; i<pageStyles.options.length; i++) {
683
- if (pageStyles.options[i].selected == true) {
684
- selectedStyle=pageStyles.options[i];
685
- }
 
 
 
 
 
 
 
686
  }
687
- }
688
- hiddenStyle.value=selectedStyle.innerHTML
689
- var previewHTML=selectedStyle.value;
690
- var fileLink = '<?php echo $templateDir ?>/' + sample;
691
- var thumb = '<?php echo $templateDir ?>/' + sample.replace(/\.jpg/,
692
- '-150x150.jpg');
693
- var medium = '<?php echo $templateDir ?>/' + sample.replace(/\.jpg/,
694
- '-300x200.jpg');
695
- var large = '<?php echo $templateDir ?>/' + sample.replace(/\.jpg/,
696
- '-1024x682.jpg');
697
- previewHTML=previewHTML.replace(/{FILELINK}/g, fileLink);
698
- previewHTML=previewHTML.replace(/{IMAGE}/g, fileLink);
699
- previewHTML=previewHTML.replace(/{FILENAME}/, sample);
700
- previewHTML=previewHTML.replace(/{THUMB(NAIL|)}/, thumb);
701
- previewHTML=previewHTML.replace(/{MEDIUM}/, medium);
702
- previewHTML=previewHTML.replace(/{LARGE}/, large);
703
- previewHTML=previewHTML.replace(/{CAPTION}/g, 'Spencer smiling');
704
- preview.innerHTML=previewHTML;
705
- pageStyle.value=selectedStyle.value;
706
- }
707
 
708
- function showAdvanced(advancedId, arrowId) {
709
- var advanced = document.getElementById(advancedId);
710
- var arrow = document.getElementById(arrowId);
711
- if (advanced.style.display=='none') {
712
- advanced.style.display='block';
713
- arrow.innerHTML='&#9660;';
714
- } else {
715
- advanced.style.display='none';
716
- arrow.innerHTML='&#9654;';
717
- }
718
- }
719
- changeStyle('imageTemplatePreview','postie-settings-imagetemplate', 'imagetemplateselect',
720
- 'postie-settings-selected_imagetemplate','smiling.jpg', false);
721
- changeStyle('audioTemplatePreview','postie-settings-audiotemplate',
722
- 'audiotemplateselect',
723
- 'postie-settings-selected_audiotemplate','funky.mp3', false);
724
- changeStyle('video1TemplatePreview','postie-settings-video1template', 'video1templateselect',
725
- 'postie-settings-selected_video1template','hi.mp4', false);
726
- changeStyle('video2TemplatePreview','postie-settings-video2template',
727
- 'video2templateselect',
728
- 'postie-settings-selected_video2template','hi.flv', false);
729
- changeIconSet(document.getElementById('icon_set_select'));
730
  </script>
1
  <div class="wrap">
2
+ <h2>
3
+ <a style='text-decoration:none' href='options-general.php?page=postie/postie.php'>
4
+ <img src="../wp-content/plugins/postie/images/mail.png" alt="postie" /><?php _e('Postie Options', 'postie'); ?>
5
+ </a>
6
+ </h2>
7
+ <?php
8
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie-functions.php');
9
+ if (isset($_POST["action"])) {
10
+ switch ($_POST["action"]) {
11
+ case "reset":
12
+ ResetPostieConfig();
13
+ $message = 1;
14
+ break;
15
+ case "cronless":
16
+ check_postie();
17
+ $message = 1;
18
+ break;
19
+ case "test":
20
+ include('postie_test.php');
21
+ exit;
22
+ break;
23
+ case "runpostie":
24
+ echo "Checking for mail manually\n";
25
+ include('get_mail.php');
26
+ exit;
27
+ break;
28
+ default:
29
+ $message = 2;
30
+ break;
31
+ }
32
+ }
33
+ global $wpdb, $wp_roles;
 
 
34
 
35
+ $title = __('Postie Options', 'postie');
36
+ $parent_file = 'options-general.php';
37
+ $config = get_option('postie-settings');
38
+ if (empty($config))
39
+ $config = ResetPostieConfig();
40
+ if (defined('POSTIE_DEBUG'))
41
+ var_dump($config);
42
+ $arrays = get_arrayed_settings();
43
  // some fields are stored as arrays, because that makes back-end processing much easier
44
  // and we need to convert those fields to strings here, for the options form
45
+ foreach ($arrays as $sep => $fields) {
46
+ foreach ($fields as $field) {
47
+ $config[$field] = implode($sep, $config[$field]);
48
+ }
49
+ }
50
+ extract($config);
51
+ if ($interval == 'manual') {
52
+ wp_clear_scheduled_hook('check_postie_hook');
53
+ }
 
 
 
54
 
55
+ $messages[1] = __("Configuration successfully updated!", 'postie');
56
+ $messages[2] = __("Error - unable to save configuration", 'postie');
57
+ ?>
58
+ <?php if (isset($_GET['message'])) : ?>
59
+ <div class="updated"><p><?php _e($messages[$_GET['message']], 'postie'); ?></p></div>
60
+ <?php endif; ?>
61
+ <form name="postie-options" method="post">
62
+ <input type="hidden" name="action" value="reset" />
63
+ <input name="Submit" value="<?php _e("Reset Settings To Defaults", 'postie') ?> &raquo;" type="submit" class='button'>
64
+ </form>
65
+ <form name="postie-options" method='post'>
66
+ <input type="hidden" name="action" value="runpostie" />
67
+ <input name="Submit" value="<?php _e("Run Postie", 'postie'); ?> &raquo;" type="submit" class='button'>
68
+ <?php _e("(To run the check mail script manually)", 'postie'); ?>
69
+ </form>
70
+ <form name="postie-options" method="post">
71
+ <input type="hidden" name="action" value="test" />
72
+ <input name="Submit" value="<?php _e("Test Config", 'postie'); ?>&raquo;" type="submit" class='button'>
73
+ <?php _e("this will run a special script to test your configuration options", 'postie'); ?>
74
+ </form>
75
+ <form name="postie-options" method="post" action='options.php'>
76
+ <?php settings_fields('postie-settings'); ?>
77
+ <input type="hidden" name="action" value="config" />
78
+ <div id="simpleTabs">
79
+ <div class="simpleTabs-nav">
80
+ <ul>
81
+ <li id="simpleTabs-nav-1"><?php _e('Mailserver', 'postie') ?></li>
82
+ <li id="simpleTabs-nav-2"><?php _e('User', 'postie') ?></li>
83
+ <li id="simpleTabs-nav-3"><?php _e('Message', 'postie') ?></li>
84
+ <li id="simpleTabs-nav-4"><?php _e('Image', 'postie') ?></li>
85
+ <li id="simpleTabs-nav-5"><?php _e('Video and Audio', 'postie') ?></li>
86
+ <li id="simpleTabs-nav-6"><?php _e('Attachments', 'postie') ?></li>
87
+ <li id="simpleTabs-nav-7"><?php _e('Help', 'postie') ?></li>
88
+ <li id="simpleTabs-nav-8"><?php _e('FAQ', 'postie') ?></li>
89
+ </ul>
90
+ </div>
91
+ <div id="simpleTabs-content-1" class="simpleTabs-content">
92
+ <table class='form-table'>
93
 
94
+ <tr>
95
+ <th scope="row"><?php _e('Mail Protocol:', 'postie') ?> </th>
96
+ <td>
97
+ <select name='postie-settings[input_protocol]' id='postie-settings-input_protocol'>
98
+ <option value="pop3" <?php echo (($input_protocol == "pop3") ? " selected='selected' " : "") ?>>POP3</option>
99
+ <?php if (HasIMAPSupport(false)): ?>
100
+ <option value="imap" <?php echo ($input_protocol == "imap") ? "selected='selected' " : "" ?>>IMAP</option>
101
+ <option value="pop3-ssl" <?php echo ($input_protocol == "pop3-ssl") ? "selected='selected' " : "" ?>>POP3-SSL</option>
102
+ <option value="imap-ssl" <?php echo ($input_protocol == "imap-ssl") ? "selected='selected' " : "" ?>>IMAP-SSL</option>
103
+ <?php endif; ?>
104
+ </select>
105
+ <?php if (!HasIMAPSupport(false)): ?>
106
+ <span class="recommendation">IMAP/IMAP-SSL/POP3-SSL unavailable</span>
107
+ <?php endif; ?>
108
+ </td>
109
+ </tr>
110
+ <tr>
111
+ <th scope="row"><?php _e('Port:', 'postie') ?><br />
112
+ <span class='recommendation'><?php _e("Standard Ports:", 'postie'); ?><br />
113
+ <?php _e("POP3", 'postie'); ?> - 110<br />
114
+ <?php _e("IMAP", 'postie'); ?> - 143<br />
115
+ <?php _e("IMAP-SSL", 'postie'); ?>- 993 <br />
116
+ <?php _e("POP3-SSL", 'postie'); ?> - 995 <br />
117
+ </span>
118
+ </th>
119
+ <td>
120
+ <input name='postie-settings[mail_server_port]' type="text" id='postie-settings-mail_server_port' value="<?php echo $mail_server_port; ?>" size="6" />
121
+ </td>
122
+ </tr>
123
+ <tr>
124
+ <th scope="row"><?php _e('Postie Time Correction:', 'postie') ?>
125
+ <br />
126
+ <span class='recommendation'><?php _e("Should be the same as your normal offset - but this lets you adjust it in cases where that doesn't work.", 'postie'); ?></span>
127
+ </th>
128
+ <td><input name='postie-settings[time_offset]' type="text" id='postie-settings-time_offset' size="2" value="<?php echo $time_offset; ?>" />
129
+ <?php _e('hours', 'postie') ?>
 
 
130
 
131
+ </td>
132
+ </tr>
133
+ <tr valign="top">
134
+ <th scope="row"><?php _e('Mail Server:', 'postie') ?></th>
135
+ <td><input name='postie-settings[mail_server]' type="text" id='postie-settings-mail_server' value="<?php echo $mail_server; ?>" size="40" />
136
+ </td>
137
+ </tr>
138
+ <tr valign="top">
139
+ <th width="33%" scope="row"><?php _e('Mail Userid:', 'postie') ?></th>
140
+ <td><input name='postie-settings[mail_userid]' type="text" id='postie-settings-mail_userid' value="<?php echo $mail_userid; ?>" size="40" /></td>
141
+ </tr>
142
+ <tr valign="top">
143
+ <th scope="row"><?php _e('Mail Password:', 'postie') ?></th>
144
+ <td>
145
+ <input name='postie-settings[mail_password]' type="text" id='postie-settings-mail_password' value="<?php echo $mail_password; ?>" size="40" />
146
+ </td>
147
+ </tr>
148
+ <tr><th>
149
+ <?php _e('Check for mail every', 'postie') ?>
150
+ </th>
151
+ <td>
152
+ <select name='postie-settings[interval]' id='postie-settings-interval'>
153
+ <option value="weekly" <?php
154
+ if ($interval == "weekly") {
155
+ echo "selected='selected'";
156
+ }
157
+ ?>><?php _e('Once weekly', 'postie') ?></option>
158
+ <option value="daily"<?php
159
+ if ($interval == "daily") {
160
+ echo "selected='selected'";
161
+ }
162
+ ?>><?php _e('daily', 'postie') ?></option>
163
+ <option value="hourly" <?php
164
+ if ($interval == "hourly") {
165
+ echo "selected='selected'";
166
+ }
167
+ ?>><?php _e('hourly', 'postie') ?></option>
168
+ <option value="twiceperhour" <?php
169
+ if ($interval == "twiceperhour") {
170
+ echo "selected='selected'";
171
+ }
172
+ ?>><?php _e('twice per hour', 'postie') ?></option>
173
+ <option value="tenminutes" <?php
174
+ if ($interval == "tenminutes") {
175
+ echo "selected='selected'";
176
+ }
177
+ ?>><?php _e('every ten minutes', 'postie') ?></option>
178
+ <option value="manual" <?php
179
+ if ($interval == "manual") {
180
+ echo
181
+ "selected='selected'";
182
+ }
183
+ ?>><?php _e('check manually', 'postie') ?></option>
184
+ </select>
185
+ </td>
186
+ </tr>
187
+ <?php echo BuildBooleanSelect("Delete email after posting", 'postie-settings[delete_mail_after_processing]', $delete_mail_after_processing, "Only set to no for testing purposes"); ?>
188
+ </table>
189
+ </div>
190
+ <div id="simpleTabs-content-2" class="simpleTabs-content">
191
+ <table class='form-table'>
192
 
193
+ <?php echo BuildBooleanSelect("Allow Anyone To Post Via Email", "postie-settings[turn_authorization_off]", $turn_authorization_off, "Changing this to yes is NOT RECOMMEDED - anything that gets sent in will automatically be posted. This could make it easier to compromise your server - YOU HAVE BEEN WARNED."); ?>
194
+ <tr>
195
+ <th scope="row"><?php _e('Roles That Can Post:', 'postie') ?>
196
+ <br />
197
+ <span class='recommendation'><?php _e("This allows you to grant access to other users to post if they have the proper access level", 'postie'); ?></span></th>
198
+ <td>
199
+ <table>
200
+ <tr><th>Administrator role can always post.</th>
201
+ <?php
202
+ foreach ($wp_roles->role_names as $roleId => $name) {
203
+ $name = translate_with_context($name);
204
+ $role = &$wp_roles->get_role($roleId);
205
+ if ($roleId != "administrator") {
206
+ ?>
207
+ <tr>
208
+ <td>
209
+ <input type='checkbox' value='1' name='postie-settings[role_access][<?php echo $roleId; ?>]' <?php echo ($role->has_cap("post_via_postie")) ? 'checked="checked"' : "" ?> >
210
+ <?php echo $name; ?>
211
+ </td>
212
+ </tr>
213
+ <?php
214
+ }
215
+ }
216
+ ?>
217
+ </table>
218
+ </td>
219
+ </tr>
220
+ <tr>
221
+ <th width="33%" valign="top" scope="row"><?php _e('Post status:', 'postie') ?> </th>
222
+ <td>
223
+ <select name='postie-settings[post_status]' id='postie-settings-post_status'>
224
+ <option value="publish" <?php
225
+ if ($post_status == "publish") {
226
+ echo
227
+ "selected";
228
+ }
229
+ ?>>Published</option>
230
+ <option value="draft" <?php
231
+ if ($post_status == "draft") {
232
+ echo
233
+ "selected";
234
+ }
235
+ ?>>Draft</option>
236
+ <option value="pending" <?php
237
+ if ($post_status == "pending") {
238
+ echo
239
+ "selected";
240
+ }
241
+ ?>>Pending Review</option>
242
+ <option value="private" <?php
243
+ if ($post_status == "private") {
244
+ echo
245
+ "selected";
246
+ }
247
+ ?>>Private</option>
248
+ </select> </td>
249
+ </tr>
250
+ <?php echo BuildTextArea("Authorized Addresses", "postie-settings[authorized_addresses]", $authorized_addresses, "Put each email address on a single line. Posts from emails in this list will be treated as if they came from the admin. If you would prefer to have users post under their own name - create a WordPress user with the correct access level."); ?>
251
+ <tr>
252
+ <th width="33%" valign="top" scope="row">
253
+ <?php _e('Admin username:') ?> </th>
254
+ <td>
255
+ <input name='postie-settings[admin_username]' type="text" id='postie-settings-admin_username'
256
+ value="<?php echo $admin_username; ?>" size="50" /> </td>
257
+ </tr>
258
+ </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  </div>
260
+ <div id="simpleTabs-content-3" class="simpleTabs-content">
261
+ <table class='form-table'>
262
+ <tr valign="top">
263
+ <th scope="row"><?php _e('Default post by mail category:', 'postie') ?></th>
264
+ <td>
265
+ <?php
266
+ $defaultCat = $default_post_category;
267
+ wp_dropdown_categories("name=postie-settings[default_post_category]&hierarchical=1&selected=$defaultCat&hide_empty=0");
268
+ ?>
269
+ </tr>
270
+ <tr valign="top">
271
+ <th scope="row">
272
+ <?php _e('Default post by mail tag(s)', 'postie') ?><br />
273
+ <span
274
+ class='recommendation'><?php _e('separated by commas', 'postie') ?>
275
+ </span>
276
+ </th>
277
+ <td>
278
+ <input type='text' name='postie-settings[default_post_tags]' id='postie-settings-default_post_tags' value='<?php echo $default_post_tags ?>' />
279
+ </td>
280
+ </tr>
281
+ <tr>
282
+ <th width="33%" valign="top" scope="row"><?php _e('Default Title:', 'postie') ?> </th>
283
+ <td>
284
+ <input name='postie-settings[default_title]' type="text" id='postie-settings-default_title' value="<?php echo $default_title; ?>" size="50" /><br />
285
+ <br />
286
+ </td>
287
+ </tr>
288
+ <tr>
289
+ <th width="33%" valign="top" scope="row"><?php _e('Preferred Text Type:', 'postie') ?> </th>
290
+ <td>
291
+ <select name='postie-settings[prefer_text_type]' id='postie-settings-prefer_text_type'>
292
+ <option value="plain">plain</option>
293
+ <option value="html" <?php ($prefer_text_type == "html") ? "selected" : "" ?>>html</option>
294
+ </select><br />
295
+ </td>
296
+ </tr>
297
+ <?php echo BuildBooleanSelect("Forward Rejected Mail", "postie-settings[forward_rejected_mail]", $forward_rejected_mail); ?>
298
+ <?php echo BuildBooleanSelect("Allow Subject In Mail", "postie-settings[allow_subject_in_mail]", $allow_subject_in_mail); ?>
299
+ <?php echo BuildBooleanSelect("Allow HTML In Mail Subject", "postie-settings[allow_html_in_subject]", $allow_html_in_subject); ?>
300
+ <?php echo BuildBooleanSelect("Allow HTML In Mail Body", "postie-settings[allow_html_in_body]", $allow_html_in_body); ?>
301
+ <tr>
302
+ <th width="33%" valign="top" scope="row"><?php _e('Tag Of Message Start:', 'postie') ?> <br />
303
+ <span class='recommendation'><?php _e('Use to remove any text from a message that the email provider puts at the top of the message', 'postie') ?></span></th>
304
+ <td>
305
+ <input name='postie-settings[message_start]' type="text" id='postie-settings-message_start' value="<?php echo $message_start; ?>" size="20" /><br />
306
+ </td>
307
+ </tr>
308
+ <tr>
309
+ <th width="33%" valign="top" scope="row"><?php _e('Tag Of Message End:', 'postie') ?> <br />
310
+ <span class='recommendation'><?php _e('Use to remove any text from a message that the email provider puts at the end of the message', 'postie') ?></span></th>
311
+ <td>
312
+ <input name='postie-settings[message_end]' type="text" id='postie-settings-message_end' value="<?php echo $message_end; ?>" size="20" /><br />
313
+ </td>
314
+ </tr>
315
+ </table>
316
+ <a style='cursor:pointer;' onclick='showAdvanced("message-advanced", "message-advanced-arrow");'><span id="message-advanced-arrow">&#9654;</span> Advanced options</a>
317
+ <div id="message-advanced" style='display:none;'>
318
+ <table class='form-table'>
319
+ <?php
320
+ echo BuildBooleanSelect("Wrap content in pre tags", "postie-settings[wrap_pre]", $wrap_pre);
321
+ echo BuildBooleanSelect("Filter newlines", "postie-settings[filternewlines]", $filternewlines, "Set to no if using markdown or textitle syntax");
322
+ echo BuildBooleanSelect("Replace newline characters with html line breaks (&lt;br /&gt;)", "postie-settings[convertnewline]", $convertnewline);
323
+ echo BuildBooleanSelect("Return rejected mail to sender", "postie-settings[return_to_sender]", $return_to_sender);
324
+ ?>
325
+ <tr>
326
+ <th>
327
+ <?php _e("Send post confirmation e-mail to", 'postie') ?>
328
+ </th>
329
+ <td>
330
+ <select name='postie-settings[confirmation_email]'
331
+ id='postie-settings-confirmation_email'>
332
+ <option value="sender" <?php echo($confirmation_email == "sender") ? "selected" : "" ?>><?php _e('sender', 'postie') ?></option>
333
+ <option value="admin" <?php echo ($confirmation_email == "admin") ? "selected" : "" ?>><?php _e('administrator', 'postie') ?></option>
334
+ <option value="both" <?php echo ($confirmation_email == "both") ? "selected" : "" ?>><?php _e('sender and administrator', 'postie') ?></option>
335
+ <option value="" <?php echo ($confirmation_email == "") ? "selected" : "" ?>><?php _e('none', 'postie') ?></option>
336
+ </select>
337
+ </td>
338
+ </tr>
339
 
340
+ <?php
341
+ echo BuildBooleanSelect("Automatically convert urls to links", "postie-settings[converturls]", $converturls);
342
+ echo BuildBooleanSelect("Use shortcode for embedding video (youtube and others)", "postie-settings[shortcode]", $shortcode);
343
+ ?>
344
+ <tr>
345
+ <th width="33%" valign="top" scope="row"><?php _e('Encoding for pages and feeds:', 'postie') ?> </th>
346
+ <td>
347
+ <input name='postie-settings[message_encoding]' type="text" id='postie-settings-message_encoding' value="<?php echo $message_encoding; ?>" size="10" />
348
+ <span class='recommendation'>UTF-8 <?php _e("should handle ISO-8859-1 as well", 'postie'); ?></span>
349
+ </td>
350
+ </tr>
351
+ <?php echo BuildBooleanSelect("Decode Quoted Printable Data", "postie-settings[message_dequote]", $message_dequote); ?>
352
+ <?php echo BuildTextArea("Supported File Types", "postie-settings[supported_file_types]", $supported_file_types, "Put each type on a single line."); ?>
353
+ <?php echo BuildTextArea("Banned File Names", "postie-settings[banned_files_list]", $banned_files_list, "Put each file name on a single line.Files matching this list will never be posted to your blog. You can use wildcards such as *.xls, or *.* for all files"); ?>
354
+ <?php echo BuildBooleanSelect("Drop The Signature From Mail", "postie-settings[drop_signature]", $drop_signature); ?>
355
+ <?php echo BuildTextArea("Signature Patterns", "postie-settings[sig_pattern_list]", $sig_pattern_list, "Put each pattern on a separate line and make sure to escape any special characters."); ?>
356
+ <?php echo BuildTextArea("Allowed SMTP servers", "postie-settings[smtp]", $smtp, "Only allow messages which have been sent throught the following smtp servers. Put each server on a separate line. Leave blank to not check smtp servers."); ?>
357
+ </table>
358
+ </div> <!-- advanced options -->
359
+ </div>
360
+ <div id="simpleTabs-content-4" class="simpleTabs-content">
361
+ <table class='form-table'>
362
 
363
+ <?php
364
+ echo BuildBooleanSelect("Automatically insert image gallery", "postie-settings[auto_gallery]", $auto_gallery, "If any images are attached, they will automatically be inserted as a gallery");
365
+ echo BuildBooleanSelect("Post Images At End", "postie-settings[images_append]", $images_append, "No means they will be put before the text of the message.");
366
+ echo BuildBooleanSelect("Start Image Count At 0", "postie-settings[start_image_count_at_zero]", $start_image_count_at_zero);
367
+ ?>
368
+ <tr>
369
+ <th width="33%" valign="top" scope="row"><?php _e('Image Place Holder Tag:', 'postie') ?> </th>
370
+ <td>
371
+ <input name='postie-settings[image_placeholder]' type="text" id='postie-settings-image_placeholder' value="<?php echo $image_placeholder; ?>" size="50" /><br />
372
+ </td>
373
+ </tr>
374
+ <tr>
375
+ <th width="33%" valign="top" scope="row"><?php _e('Image Template', 'postie') ?><br />
376
+ <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie'); ?></span><br /><br />
377
+ <span class='recommendation'><?php _e('Sizes for thumbnail, medium, and large images can be chosen in the <a href="options-media.php">Media Settings</a>. The samples here use the default sizes, and will not reflect the sizes you have chosen.', 'postie'); ?></span>
378
+ </th>
379
+ <td>
380
+ <input type='hidden' id='postie-settings-selected_imagetemplate' name='postie-settings[selected_imagetemplate]'
381
+ value="<?php echo attribute_escape($selected_imagetemplate) ?>" />
382
+ <select name='imagetemplateselect' id='imagetemplateselect'
383
+ onchange="changeStyle('imageTemplatePreview','postie-settings-imagetemplate',
384
+ 'imagetemplateselect', 'postie-settings-selected_imagetemplate','smiling.jpg');" >
385
+ <?php
386
+ include('templates/image_templates.php');
387
+ $styleOptions = $imageTemplates;
388
+ $selected = $selected_imagetemplate;
389
+ foreach ($styleOptions as $key => $value) {
390
+ if ($key != 'selected') {
391
+ if ($key == $selected) {
392
+ $select = ' selected=selected ';
393
+ } else {
394
+ $select = ' ';
395
+ }
396
+ if ($key == 'custom')
397
+ $value = $imagetemplate;
398
+ echo '<option' . $select . 'value="' .
399
+ attribute_escape($value) . '" >' . $key . '</option>';
400
+ }
401
+ }
402
+ ?>
403
+ </select>
404
+ &nbsp;&nbsp;
405
+ <?php _e('Preview', 'postie'); ?>
406
+ <div id='imageTemplatePreview'></div>
407
+ <textarea onchange='changeStyle("imageTemplatePreview", "postie-settings-imagetemplate", "imagetemplateselect",
408
+ "postie-settings-selected_imagetemplate", "smiling.jpg", true);' cols='70' rows='7' id='postie-settings-imagetemplate' name='postie-settings[imagetemplate]'>
409
+ <?php echo attribute_escape($imagetemplate) ?>
410
+ </textarea>
411
+ </td>
412
+ </tr>
413
+ <?php echo BuildBooleanSelect("Use custom image field", "postie-settings[custom_image_field]", $custom_image_field, "When true, images will not appear in the post. Instead the url to the image will be input into a custom field named 'image'."); ?>
414
+ </table>
415
+ </div>
 
 
 
 
 
416
 
417
+ <!--
418
+ ########## VIDEO AND AUDIO OPTIONS ###################
419
+ -->
420
 
421
+ <div id="simpleTabs-content-5" class="simpleTabs-content">
422
+ <table class='form-table'>
423
 
424
+ <tr><th scope='row'><?php _e('Video template 1', 'postie') ?><br />
425
+ <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie') ?></span></th>
426
+ <?php $templateDir = get_option('siteurl') . '/' . PLUGINDIR . '/postie/templates'; ?>
427
+ <td>
428
+ <input type='hidden' id='postie-settings-selected_video1template' name='postie-settings[selected_video1template]'
429
+ value="<?php echo attribute_escape($selected_video1template) ?>" />
430
+ <select name='video1templateselect' id='video1templateselect'
431
+ onchange="changeStyle('video1TemplatePreview','postie-settings-video1template', 'video1templateselect', 'postie-settings-selected_video1template','hi.mp4');" />
432
+ <?php
433
+ include('templates/video1_templates.php');
434
+ $styleOptions = $video1Templates;
435
+ $selected = $selected_video1template;
436
+ foreach ($styleOptions as $key => $value) {
437
+ if ($key != 'selected') {
438
+ if ($key == $selected) {
439
+ $select = ' selected=selected ';
440
+ } else {
441
+ $select = ' ';
442
+ }
443
+ if ($key == 'custom')
444
+ $value = $video1template;
445
+ echo '<option' . $select . 'value="' .
446
+ attribute_escape($value) . '" >' . $key . '</option>';
447
+ }
448
+ }
449
+ ?>
450
+ </select>
451
+ &nbsp;&nbsp;
452
+ <?php _e('Preview', 'postie'); ?>
453
+ <div id='video1TemplatePreview'></div>
454
+ <textarea onchange="changeStyle('video1TemplatePreview','postie-settings-video1template',
455
+ 'video1templateselect', 'postie-settings-selected_video1template','hi.mp4',true);" cols='70' rows='7' id='postie-settings-video1template'
456
+ name='postie-settings[video1template]'><?php echo attribute_escape($video1template) ?></textarea>
457
+ </td>
458
+ </tr>
459
+ <tr>
460
+ <th width="33%" valign="top" scope="row">
461
+ <?php _e('Video 1 file types:') ?><br /><span class='recommendation'>
462
+ <?php _e('Use the video template 1 for these files types (separated by commas)', 'postie') ?></span> </th>
463
+ <td>
464
+ <input name='postie-settings[video1types]' type="text" id='postie-settings-video1types'
465
+ value="<?php if ($video1types != '') echo $video1types; ?>" size="40" /> </td>
466
+ </tr>
467
+ <tr><th scope='row'><?php _e('Video template 2', 'postie') ?><br />
468
+ <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie') ?></span></th>
469
+ <td>
470
+ <input type='hidden' id='postie-settings-selected_video2template' name='postie-settings[selected_video2template]'
471
+ value="<?php echo attribute_escape($selected_video2template) ?>" />
472
+ <select name='video2templateselect' id='video2templateselect'
473
+ onchange="changeStyle('video2TemplatePreview','postie-settings-video2template',
474
+ 'video2templateselect', 'postie-settings-selected_video2template','hi.flv');" >
475
+ <?php
476
+ include('templates/video2_templates.php');
477
+ $styleOptions = $video2Templates;
478
+ $selected = $selected_video2template;
479
+ foreach ($styleOptions as $key => $value) {
480
+ if ($key != 'selected') {
481
+ if ($key == $selected) {
482
+ $select = ' selected=selected ';
483
+ } else {
484
+ $select = ' ';
485
+ }
486
+ if ($key == 'custom')
487
+ $value = $video2template;
488
+ echo '<option' . $select . 'value="' . attribute_escape($value) . '" >' . $key . '</option>';
489
+ }
490
+ }
491
+ ?>
492
+ </select>
493
+ &nbsp;&nbsp;
494
+ <?php _e('Preview', 'postie'); ?>
495
+ <div id='video2TemplatePreview'></div>
496
+ <textarea onchange="changeStyle('video2TemplatePreview','postie-settings-video2template',
497
+ 'video2templateselect', 'postie-settings-selected_video2template','hi.flv',true);" cols='70' rows='7' id='postie-settings-video2template'
498
+ name='postie-settings[video2template]'>
499
+ <?php echo attribute_escape($video2template) ?>
500
+ </textarea>
501
+ </td>
502
+ </tr>
503
+ <tr>
504
+ <th width="33%" valign="top" scope="row">
505
+ <?php _e('Video 2 file types:') ?><br /><span class='recommendation'>
506
+ <?php _e('Use the video template 2 for these files types (separated by commas)', 'postie') ?></span> </th>
507
+ <td>
508
+ <input name='postie-settings[video2types]' type="text" id='postie-settings-video2types'
509
+ value="<?php if ($video2types != '') echo $video2types; ?>" size="40" /> </td>
510
+ </tr>
511
+ <tr><th scope='row'><?php _e('Audio template', 'postie') ?><br />
512
+ <span class='recommendation'><?php _e('Choose a default template, then customize to your liking in the text box', 'postie') ?></span></th>
513
+ <td>
514
+ <input type='hidden' id='postie-settings-selected_audiotemplate' name='postie-settings[selected_audiotemplate]'
515
+ value="<?php echo attribute_escape($selected_audiotemplate) ?>" />
516
+ <select name='audiotemplateselect' id='audiotemplateselect'
517
+ onchange="changeStyle('audioTemplatePreview','postie-settings-audiotemplate',
518
+ 'audiotemplateselect', 'postie-settings-selected_audiotemplate','funky.mp3', false);" >
519
+ <?php
520
+ include('templates/audio_templates.php');
521
+ $styleOptions = $audioTemplates;
522
+ $selected = $selected_audiotemplate;
523
+ foreach ($styleOptions as $key => $value) {
524
+ if ($key != 'selected') {
525
+ if ($key == $selected) {
526
+ $select = ' selected=selected ';
527
+ } else {
528
+ $select = ' ';
529
+ }
530
+ if ($key == 'custom')
531
+ $value = $audiotemplate;
532
+ echo '<option' . $select . 'value="' .
533
+ attribute_escape($value) . '" >' . $key . '</option>';
534
+ }
535
+ }
536
+ ?>
537
+ </select>
538
+ &nbsp;&nbsp;
539
+ <?php _e('Preview', 'postie'); ?>
540
+ <div id='audioTemplatePreview'></div>
541
+ <textarea onchange="changeStyle('audioTemplatePreview','postie-settings-audiotemplate',
542
+ 'audiotemplateselect', 'postie-settings-selected_audiotemplate','funky.mp3', true);" cols='70' rows='7' id='postie-settings-audiotemplate'
543
+ name='postie-settings[audiotemplate]'><?php echo attribute_escape($audiotemplate) ?></textarea>
544
+ </td>
545
+ </tr>
546
+ <tr>
547
+ <th width="33%" valign="top" scope="row">
548
+ <?php _e('Audio file types:') ?><br />
549
+ <span class='recommendation'>
550
+ <?php _e('Use the audio template for these files types (separated by commas)', 'postie') ?>
551
+ </span>
552
+ </th>
553
+ <td>
554
+ <input name='postie-settings[audiotypes]' type="text" id='postie-settings-audiotypes' value="<?php if ($audiotypes != '') echo $audiotypes; ?>" size="40" />
555
+ </td>
556
+ </tr>
557
+ </table>
558
+ </div>
559
+ <div id="simpleTabs-content-6" class="simpleTabs-content">
560
+ <table class='form-table'>
 
 
 
561
 
562
+ <tr>
563
+ <th scope='row'><?php _e('Attachment icon set', 'postie') ?><br /></th>
564
+ <td>
565
+ <input type='hidden' id='postie-settings-icon_set' name='postie-settings[icon_set]'
566
+ value="<?php echo attribute_escape($icon_set) ?>" />
567
 
568
+ <?php
569
+ $icon_sets = array('silver', 'black', 'white', 'custom', 'none');
570
+ $icon_sizes = array(32, 48, 64);
571
+ ?>
572
+ <select name='icon_set_select' id='icon_set_select' onchange="changeIconSet(this);" >
573
+ <?php
574
+ $styleOptions = $icon_sets;
575
+ $selected = $icon_set;
576
+ foreach ($styleOptions as $key) {
577
+ if ($key != 'selected') {
578
+ if ($key == $selected) {
579
+ $select = ' selected=selected ';
580
+ } else {
581
+ $select = ' ';
582
+ }
583
+ echo '<option' . $select . 'value="' . attribute_escape($key) . '" >' . $key . '</option>';
584
+ }
585
+ }
586
+ ?>
587
+ </select>
588
+ </td>
589
+ </tr>
590
+ <tr><th scope='row'><?php _e('Attachment icon size (in pixels)', 'postie') ?><br />
591
+ <td>
592
+ <input type='hidden' id='postie-settings-icon_size' name='postie-settings[icon_size]'
593
+ value="<?php echo attribute_escape($icon_size) ?>" />
594
+ <select name='icon_size_select' id='icon_size_select' onchange="changeIconSet(this, true);" >
595
+ <?php
596
+ $styleOptions = $icon_sizes;
597
+ $selected = $icon_size;
598
+ foreach ($styleOptions as $key) {
599
+ if ($key != 'selected') {
600
+ if ($key == $selected) {
601
+ $select = ' selected=selected ';
602
+ } else {
603
+ $select = ' ';
604
+ }
605
+ echo '<option' . $select . 'value="' . attribute_escape($key) . '" >' . $key . '</option>';
606
+ }
607
+ }
608
+ ?>
609
+ </select>
610
+ </td>
611
+ </tr>
612
+ <tr>
613
+ <th style='height:64px'>
614
+ <?php _e('Preview', 'postie'); ?>
615
+ </th>
616
+ <td>
617
+ <span id='postie-settings-attachment_preview'></span>
618
+ </td>
619
+ </tr>
620
+ </table>
621
+ </div>
622
+ <div id="simpleTabs-content-7" class="simpleTabs-content">
623
+ <?php include('readme.html'); ?>
624
+ </div>
625
+ <div id="simpleTabs-content-8" class="simpleTabs-content">
626
+ <?php include('faq.html'); ?>
627
+ </div>
 
 
 
 
 
628
 
629
+ <p class="submit">
630
+ <input type="hidden" name="action" value="update" />
631
 
632
+ <input type="hidden" name="page_options"
633
+ value="postie-settings" />
634
 
635
+ <input type="submit" name="Submit" value="<?php _e('Save Changes') ?>" />
636
 
637
+ </p>
638
+ </form>
639
  </div>
 
 
 
 
 
 
 
 
640
 
641
+ <?php $iconDir = get_option('siteurl') . '/' . PLUGINDIR . '/postie/icons'; ?>
642
  <script type="text/javascript">
643
+ jQuery(document).ready(function() {
644
+ jQuery("#simpleTabs").simpleTabs({
645
+ fadeSpeed: "medium", // @param : low, medium, fast
646
+ defautContent: 1, // @param : number ( simpleTabs-nav-number)
647
+ autoNav: "false", // @param : true or false
648
+ closeTabs : "false" // @param : true or false;
649
+ });
650
 
651
+ });
652
+ function changeIconSet(selectBox, size) {
653
+ var iconSet=document.getElementById('postie-settings-icon_set');
654
+ var iconSize=document.getElementById('postie-settings-icon_size');
655
+ var preview=document.getElementById('postie-settings-attachment_preview');
656
+ var iconDir = '<?php echo $iconDir ?>/';
657
+ if (size==true) {
658
+ var hiddenInput=iconSize
659
+ } else {
660
+ var hiddenInput=iconSet;
661
+ }
662
+ for(i=0; i<selectBox.options.length; i++) {
663
+ if (selectBox.options[i].selected == true) {
664
+ hiddenInput.value=selectBox.options[i].value;
665
+ }
666
+ }
667
+ var fileTypes= new Array('doc', 'pdf', 'xls', 'ppt');
668
+ preview.innerHTML='';
669
+ for (j=0; j<fileTypes.length; j++) {
670
+ preview.innerHTML+="<img src='" + iconDir + iconSet.value + '/' +
671
+ fileTypes[j] + '-' + iconSize.value + ".png' />";
672
+ }
673
+ preview.innerHTML+='<br />Here is some sample text with a link to a ' +
674
+ 'word document that I think you might find interesting<br />' +
675
+ "<a href='#'><img style='text-decoration:none' src='" +
676
+ iconDir + iconSet.value + '/doc' +
677
+ '-' + iconSize.value + ".png' />Interesting document</a>";
678
  }
679
+ function changeStyle(preview,template,select,selected,sample,custom) {
680
+ var preview = document.getElementById(preview);
681
+ var pageStyles = document.getElementById(select);
682
+ var selectedStyle;
683
+ var hiddenStyle=document.getElementById(selected);
684
+ var pageStyle = document.getElementById(template);
685
+ if (custom==true) {
686
+ selectedStyle=pageStyles.options[pageStyles.options.length-1];
687
+ selectedStyle.value=pageStyle.value;
688
+ selectedStyle.selected=true;
689
+ } else {
690
+ for(i=0; i<pageStyles.options.length; i++) {
691
+ if (pageStyles.options[i].selected == true) {
692
+ selectedStyle=pageStyles.options[i];
693
+ }
694
+ }
695
+ }
696
+ hiddenStyle.value=selectedStyle.innerHTML
697
+ var previewHTML=selectedStyle.value;
698
+ var fileLink = '<?php echo $templateDir ?>/' + sample;
699
+ var thumb = '<?php echo $templateDir ?>/' + sample.replace(/\.jpg/,
700
+ '-150x150.jpg');
701
+ var medium = '<?php echo $templateDir ?>/' + sample.replace(/\.jpg/,
702
+ '-300x200.jpg');
703
+ var large = '<?php echo $templateDir ?>/' + sample.replace(/\.jpg/,
704
+ '-1024x682.jpg');
705
+ previewHTML=previewHTML.replace(/{FILELINK}/g, fileLink);
706
+ previewHTML=previewHTML.replace(/{IMAGE}/g, fileLink);
707
+ previewHTML=previewHTML.replace(/{FILENAME}/, sample);
708
+ previewHTML=previewHTML.replace(/{THUMB(NAIL|)}/, thumb);
709
+ previewHTML=previewHTML.replace(/{MEDIUM}/, medium);
710
+ previewHTML=previewHTML.replace(/{LARGE}/, large);
711
+ previewHTML=previewHTML.replace(/{CAPTION}/g, 'Spencer smiling');
712
+ preview.innerHTML=previewHTML;
713
+ pageStyle.value=selectedStyle.value;
714
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
 
716
+ function showAdvanced(advancedId, arrowId) {
717
+ var advanced = document.getElementById(advancedId);
718
+ var arrow = document.getElementById(arrowId);
719
+ if (advanced.style.display=='none') {
720
+ advanced.style.display='block';
721
+ arrow.innerHTML='&#9660;';
722
+ } else {
723
+ advanced.style.display='none';
724
+ arrow.innerHTML='&#9654;';
725
+ }
726
+ }
727
+ changeStyle('imageTemplatePreview','postie-settings-imagetemplate', 'imagetemplateselect',
728
+ 'postie-settings-selected_imagetemplate','smiling.jpg', false);
729
+ changeStyle('audioTemplatePreview','postie-settings-audiotemplate',
730
+ 'audiotemplateselect',
731
+ 'postie-settings-selected_audiotemplate','funky.mp3', false);
732
+ changeStyle('video1TemplatePreview','postie-settings-video1template', 'video1templateselect',
733
+ 'postie-settings-selected_video1template','hi.mp4', false);
734
+ changeStyle('video2TemplatePreview','postie-settings-video2template',
735
+ 'video2templateselect',
736
+ 'postie-settings-selected_video2template','hi.flv', false);
737
+ changeIconSet(document.getElementById('icon_set_select'));
738
  </script>
faq.html CHANGED
@@ -1,24 +1,26 @@
1
- <li id='question-0'><a href='#answer-0'>How can I get postie to display inline images?</a></li>
2
- <li id='question-1'><a href='#answer-1'>Mail is not showing up right when I send html (rich formatted) e-mail!</a></li>
3
- <li id='question-2'><a href='#answer-2'>Do I need to any code to my theme for postie to work?</a></li>
4
- <li id='question-3'><a href='#answer-3'>I read somewhere to add an iframe to my footer. Should I do this?</a></li>
5
- <li id='question-4'><a href='#answer-4'>My mail host requires SSL, but postie will not allow me to select pop3-ssl or imap-ssl</a></li>
6
- <li id='question-5'><a href='#answer-5'>Can I use postie to check a gmail account?</a></li>
7
- <li id='question-6'><a href='#answer-6'>My posts show up as being posted by 'admin' instead of me. Why?</a></li>
8
- <li id='question-7'><a href='#answer-7'>Images aren't showing up at all?</a></li>
9
- <li id='question-8'><a href='#answer-8'>Can I delete the wp-files directory needed by postie version &lt;1.3.0?</a></li>
10
- <li id='question-9'><a href='#answer-9'>How can I get rid of stupid stuff my e-mail provider adds to my messages?</a></li>
11
- <li id='question-10'><a href='#answer-10'>How can I add custom attachment icons?</a></li>
12
- <li id='question-11'><a href='#answer-11'>Can I add special text to the body of the post when using postie?</a></li>
13
- <li id='question-12'><a href='#answer-12'>Can I add special text to the title of the post when using postie?</a></li>
14
- <li id='question-13'><a href='#answer-13'>Can I select tags or categories based on the content of the e-mail?</a></li>
15
- <li id='question-14'><a href='#answer-14'>Is the IMAP extension required for postie?</a></li>
16
- <li id='question-15'><a href='#answer-15'>How can I embed youtube or vimeo videos?</a></li>
 
 
17
  <h3>Frequently Asked Questions</h3>
18
- <h4 id='answer-0'>How can I get postie to display inline images?</h4>
19
 
20
  <p>Make sure that you send e-mail formatted as html (richtext), and set postie to
21
- prefer html messages (in the message tab of the postie settings)</p>
22
 
23
  <h4 id='answer-1'>Mail is not showing up right when I send html (rich formatted) e-mail!</h4>
24
 
@@ -31,88 +33,88 @@ prefer html messages (in the message tab of the postie settings)</p>
31
  <h4 id='answer-3'>I read somewhere to add an iframe to my footer. Should I do this?</h4>
32
 
33
  <p>No. Do not add an iframe in your footer to get postie to check mail
34
- periodically. To check e-mail periodically, either set-up a cron job, or use
35
- cronless postie. See installation instructions</p>
36
 
37
  <h4 id='answer-4'>My mail host requires SSL, but postie will not allow me to select pop3-ssl or imap-ssl</h4>
38
 
39
  <p>You must have php-imap installed on your server for this to work. Ask your
40
- hosting provider about this.</p>
41
 
42
  <h4 id='answer-5'>Can I use postie to check a gmail account?</h4>
43
 
44
  <p>Yes. You can use either pop3-ssl or imap-ssl with a gmail account. Before
45
- attempting to use with postie, make sure that you enable pop or imap in your
46
- gmail preferences.</p>
47
-
48
- <ul>
49
- <li>Pop3 settings:
50
-
51
- <ul>
52
- <li>protocol - pop3-ssl</li>
53
- <li>server - pop.gmail.com</li>
54
- <li>port - 995</li>
55
- <li>userid - your username (e.g. if your e-mail address is <a href="mailto:foo@gmail.com">foo@gmail.com</a>,
56
- this would be just foo)</li>
57
- <li>password - your password </li>
58
- </ul></li>
59
- <li>IMAP settings:
60
 
61
  <ul>
62
- <li>protocol - imap-ssl</li>
63
- <li>server - imap.gmail.com</li>
64
- <li>port - 993</li>
65
- <li>userid - your username (e.g. if your e-mail address is <a href="mailto:foo@gmail.com">foo@gmail.com</a>,
66
- this would be just foo)</li>
67
- <li>password - your password </li>
68
- </ul></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  </ul>
70
 
71
  <h4 id='answer-6'>My posts show up as being posted by 'admin' instead of me. Why?</h4>
72
 
73
  <p>If your admin account is linked to <a href="mailto:bar@gmail.com">bar@gmail.com</a>, and you send mail from
74
- <a href="mailto:bar@gmail.com">bar@gmail.com</a>, it will show up as being posted by admin. If you have a
75
- wordpress user named "John Doe", which is linked to <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a>, make
76
- sure that you send e-mails from <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a>. It doesn't matter which
77
- e-mail address postie is checking. That is, if you send mail from
78
- <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a> to <a href="mailto:foo@gmail.com">foo@gmail.com</a>, it gets posted as "John Doe".</p>
79
 
80
  <p>If you send an e-mail to your postie address from an e-mail address that is no
81
- t linked to a wordpress user, it will get posted as admin.</p>
82
 
83
  <h4 id='answer-7'>Images aren't showing up at all?</h4>
84
 
85
  <p>There are a couple possible reasons for this. First, check to see if you can
86
- add an image through wordpress's normal posting mechanism. If not, then there
87
- is probably 1 or 2 problems:
88
- 1. Your server does not have the php-gd library installed. Ask your hosting
89
- provider about this.</p>
90
 
91
  <ol>
92
- <li>Your wp-content/uploads directory is not writable by the webserver. Make
93
- sure that it is</li>
94
  </ol>
95
 
96
  <h4 id='answer-8'>Can I delete the wp-files directory needed by postie version &lt;1.3.0?</h4>
97
 
98
  <p>If you have posts published already by older versions of postie, getting rid
99
- of those directories will delete any files you might have had associated with
100
- those old posts. If you don't have any such posts, then you can safely delete
101
- them.</p>
102
 
103
  <h4 id='answer-9'>How can I get rid of stupid stuff my e-mail provider adds to my messages?</h4>
104
 
105
  <p>To strip off stuff that they add at the beginning of a message, start your
106
- post with :start</p>
107
 
108
  <p>To strip off stuff that they add at the end of a message, end your
109
- post with :end</p>
110
 
111
  <h4 id='answer-10'>How can I add custom attachment icons?</h4>
112
 
113
  <p>Simply upload the icons you want to the postie/icons/custom directory. You
114
- must name the icons according to the following scheme:
115
- {filetype}-{size}.png</p>
116
 
117
  <p>For example, for word documents, you could use:</p>
118
 
@@ -120,57 +122,57 @@ must name the icons according to the following scheme:
120
  </code></pre>
121
 
122
  <p>for a 32x32 pixel icon. (You can actually create any size icon you want, but
123
- if you name it 32, then it will only be used if you select to use size 32
124
- icons)</p>
125
 
126
  <p>See the other directories in icons for more examples.</p>
127
 
128
  <p>Currently the following filetypes are supported:</p>
129
 
130
  <ul>
131
- <li>doc - microsoft word (including docx)</li>
132
- <li>ppt - microsoft powerpoint (including pptx)</li>
133
- <li>xls - microsoft excel (including xlsx)</li>
134
- <li>numbers - iWork numbres spreadsheet</li>
135
- <li>pages - iWork pages document</li>
136
- <li>key - iWork keynote presentation</li>
137
- <li>pdf - portable document format</li>
138
- <li>rtf - rich text format</li>
139
- <li>txt - plain text document</li>
140
  </ul>
141
 
142
  <h4 id='answer-11'>Can I add special text to the body of the post when using postie?</h4>
143
 
144
  <p>Yes. You can create your own function, and use the postie_post filter.
145
- Two short examples are included in the filterPostie.php.sample file</p>
146
 
147
  <h4 id='answer-12'>Can I add special text to the title of the post when using postie?</h4>
148
 
149
  <p>Yes. You can create your own function, and use the postie_post filter.
150
- Two short examples are included in the filterPostie.php.sample file</p>
151
 
152
  <h4 id='answer-13'>Can I select tags or categories based on the content of the e-mail?</h4>
153
 
154
  <p>Yes. You can create your own function, and use the postie_post filter.
155
- See the filterPostie.php.sample file for examples.</p>
156
 
157
  <h4 id='answer-14'>Is the IMAP extension required for postie?</h4>
158
 
159
  <p>The IMAP extension is not required, but it is strongly recommended, especially
160
- is you are using non-English text. There is more information on php.net about
161
- installing the IMAP extension. If you have control over your server, it is
162
- often not hard to install.</p>
163
 
164
  <p>On Ubuntu, try
165
- sudo apt-get install php5-imap</p>
166
 
167
  <p>On Fedora, try
168
- sudo yuminstall php-imap</p>
169
 
170
  <p>The IMAP extension is known to be installed on the following popular webhosts:
171
- * Dreamhost</p>
172
 
173
  <h4 id='answer-15'>How can I embed youtube or vimeo videos?</h4>
174
 
175
  <p>Simply put the url in the body of your e-mail. (Make sure that you have the
176
- option to convert url into links turned on)</p>
1
+ <ul>
2
+ <li id='question-0'><a href='#answer-0'>How can I get postie to display inline images?</a></li>
3
+ <li id='question-1'><a href='#answer-1'>Mail is not showing up right when I send html (rich formatted) e-mail!</a></li>
4
+ <li id='question-2'><a href='#answer-2'>Do I need to any code to my theme for postie to work?</a></li>
5
+ <li id='question-3'><a href='#answer-3'>I read somewhere to add an iframe to my footer. Should I do this?</a></li>
6
+ <li id='question-4'><a href='#answer-4'>My mail host requires SSL, but postie will not allow me to select pop3-ssl or imap-ssl</a></li>
7
+ <li id='question-5'><a href='#answer-5'>Can I use postie to check a gmail account?</a></li>
8
+ <li id='question-6'><a href='#answer-6'>My posts show up as being posted by 'admin' instead of me. Why?</a></li>
9
+ <li id='question-7'><a href='#answer-7'>Images aren't showing up at all?</a></li>
10
+ <li id='question-8'><a href='#answer-8'>Can I delete the wp-files directory needed by postie version &lt;1.3.0?</a></li>
11
+ <li id='question-9'><a href='#answer-9'>How can I get rid of stupid stuff my e-mail provider adds to my messages?</a></li>
12
+ <li id='question-10'><a href='#answer-10'>How can I add custom attachment icons?</a></li>
13
+ <li id='question-11'><a href='#answer-11'>Can I add special text to the body of the post when using postie?</a></li>
14
+ <li id='question-12'><a href='#answer-12'>Can I add special text to the title of the post when using postie?</a></li>
15
+ <li id='question-13'><a href='#answer-13'>Can I select tags or categories based on the content of the e-mail?</a></li>
16
+ <li id='question-14'><a href='#answer-14'>Is the IMAP extension required for postie?</a></li>
17
+ <li id='question-15'><a href='#answer-15'>How can I embed youtube or vimeo videos?</a></li>
18
+ </ul>
19
  <h3>Frequently Asked Questions</h3>
20
+ <h4 id='answer-0'>How can I get postie to display inline images?</h4>
21
 
22
  <p>Make sure that you send e-mail formatted as html (richtext), and set postie to
23
+ prefer html messages (in the message tab of the postie settings)</p>
24
 
25
  <h4 id='answer-1'>Mail is not showing up right when I send html (rich formatted) e-mail!</h4>
26
 
33
  <h4 id='answer-3'>I read somewhere to add an iframe to my footer. Should I do this?</h4>
34
 
35
  <p>No. Do not add an iframe in your footer to get postie to check mail
36
+ periodically. To check e-mail periodically, either set-up a cron job, or use
37
+ cronless postie. See installation instructions</p>
38
 
39
  <h4 id='answer-4'>My mail host requires SSL, but postie will not allow me to select pop3-ssl or imap-ssl</h4>
40
 
41
  <p>You must have php-imap installed on your server for this to work. Ask your
42
+ hosting provider about this.</p>
43
 
44
  <h4 id='answer-5'>Can I use postie to check a gmail account?</h4>
45
 
46
  <p>Yes. You can use either pop3-ssl or imap-ssl with a gmail account. Before
47
+ attempting to use with postie, make sure that you enable pop or imap in your
48
+ gmail preferences.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  <ul>
51
+ <li>Pop3 settings:
52
+
53
+ <ul>
54
+ <li>protocol - pop3-ssl</li>
55
+ <li>server - pop.gmail.com</li>
56
+ <li>port - 995</li>
57
+ <li>userid - your username (e.g. if your e-mail address is <a href="mailto:foo@gmail.com">foo@gmail.com</a>,
58
+ this would be just foo)</li>
59
+ <li>password - your password </li>
60
+ </ul></li>
61
+ <li>IMAP settings:
62
+
63
+ <ul>
64
+ <li>protocol - imap-ssl</li>
65
+ <li>server - imap.gmail.com</li>
66
+ <li>port - 993</li>
67
+ <li>userid - your username (e.g. if your e-mail address is <a href="mailto:foo@gmail.com">foo@gmail.com</a>,
68
+ this would be just foo)</li>
69
+ <li>password - your password </li>
70
+ </ul></li>
71
  </ul>
72
 
73
  <h4 id='answer-6'>My posts show up as being posted by 'admin' instead of me. Why?</h4>
74
 
75
  <p>If your admin account is linked to <a href="mailto:bar@gmail.com">bar@gmail.com</a>, and you send mail from
76
+ <a href="mailto:bar@gmail.com">bar@gmail.com</a>, it will show up as being posted by admin. If you have a
77
+ wordpress user named "John Doe", which is linked to <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a>, make
78
+ sure that you send e-mails from <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a>. It doesn't matter which
79
+ e-mail address postie is checking. That is, if you send mail from
80
+ <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a> to <a href="mailto:foo@gmail.com">foo@gmail.com</a>, it gets posted as "John Doe".</p>
81
 
82
  <p>If you send an e-mail to your postie address from an e-mail address that is no
83
+ t linked to a wordpress user, it will get posted as admin.</p>
84
 
85
  <h4 id='answer-7'>Images aren't showing up at all?</h4>
86
 
87
  <p>There are a couple possible reasons for this. First, check to see if you can
88
+ add an image through wordpress's normal posting mechanism. If not, then there
89
+ is probably 1 or 2 problems:
90
+ 1. Your server does not have the php-gd library installed. Ask your hosting
91
+ provider about this.</p>
92
 
93
  <ol>
94
+ <li>Your wp-content/uploads directory is not writable by the webserver. Make
95
+ sure that it is</li>
96
  </ol>
97
 
98
  <h4 id='answer-8'>Can I delete the wp-files directory needed by postie version &lt;1.3.0?</h4>
99
 
100
  <p>If you have posts published already by older versions of postie, getting rid
101
+ of those directories will delete any files you might have had associated with
102
+ those old posts. If you don't have any such posts, then you can safely delete
103
+ them.</p>
104
 
105
  <h4 id='answer-9'>How can I get rid of stupid stuff my e-mail provider adds to my messages?</h4>
106
 
107
  <p>To strip off stuff that they add at the beginning of a message, start your
108
+ post with :start</p>
109
 
110
  <p>To strip off stuff that they add at the end of a message, end your
111
+ post with :end</p>
112
 
113
  <h4 id='answer-10'>How can I add custom attachment icons?</h4>
114
 
115
  <p>Simply upload the icons you want to the postie/icons/custom directory. You
116
+ must name the icons according to the following scheme:
117
+ {filetype}-{size}.png</p>
118
 
119
  <p>For example, for word documents, you could use:</p>
120
 
122
  </code></pre>
123
 
124
  <p>for a 32x32 pixel icon. (You can actually create any size icon you want, but
125
+ if you name it 32, then it will only be used if you select to use size 32
126
+ icons)</p>
127
 
128
  <p>See the other directories in icons for more examples.</p>
129
 
130
  <p>Currently the following filetypes are supported:</p>
131
 
132
  <ul>
133
+ <li>doc - microsoft word (including docx)</li>
134
+ <li>ppt - microsoft powerpoint (including pptx)</li>
135
+ <li>xls - microsoft excel (including xlsx)</li>
136
+ <li>numbers - iWork numbres spreadsheet</li>
137
+ <li>pages - iWork pages document</li>
138
+ <li>key - iWork keynote presentation</li>
139
+ <li>pdf - portable document format</li>
140
+ <li>rtf - rich text format</li>
141
+ <li>txt - plain text document</li>
142
  </ul>
143
 
144
  <h4 id='answer-11'>Can I add special text to the body of the post when using postie?</h4>
145
 
146
  <p>Yes. You can create your own function, and use the postie_post filter.
147
+ Two short examples are included in the filterPostie.php.sample file</p>
148
 
149
  <h4 id='answer-12'>Can I add special text to the title of the post when using postie?</h4>
150
 
151
  <p>Yes. You can create your own function, and use the postie_post filter.
152
+ Two short examples are included in the filterPostie.php.sample file</p>
153
 
154
  <h4 id='answer-13'>Can I select tags or categories based on the content of the e-mail?</h4>
155
 
156
  <p>Yes. You can create your own function, and use the postie_post filter.
157
+ See the filterPostie.php.sample file for examples.</p>
158
 
159
  <h4 id='answer-14'>Is the IMAP extension required for postie?</h4>
160
 
161
  <p>The IMAP extension is not required, but it is strongly recommended, especially
162
+ is you are using non-English text. There is more information on php.net about
163
+ installing the IMAP extension. If you have control over your server, it is
164
+ often not hard to install.</p>
165
 
166
  <p>On Ubuntu, try
167
+ sudo apt-get install php5-imap</p>
168
 
169
  <p>On Fedora, try
170
+ sudo yuminstall php-imap</p>
171
 
172
  <p>The IMAP extension is known to be installed on the following popular webhosts:
173
+ * Dreamhost</p>
174
 
175
  <h4 id='answer-15'>How can I embed youtube or vimeo videos?</h4>
176
 
177
  <p>Simply put the url in the body of your e-mail. (Make sure that you have the
178
+ option to convert url into links turned on)</p>
fetchmails.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
 
2
  //if ($_POST['fetchmails']) {
3
- include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR."wp-config.php");
4
- require_once (dirname(__FILE__). DIRECTORY_SEPARATOR . '../postie/mimedecode.php');
5
- require_once (dirname(__FILE__). DIRECTORY_SEPARATOR . '../postie/postie-functions.php');
6
- init();
7
- fetch_mails();
8
- exit;
 
9
  //}
10
  function init() {
11
- /* Sets up database table if it doesn't already exist */
12
- global $wpdb, $aandcpostie_version;
13
- $table_name=$wpdb->prefix . 'postie_addresses';
14
- if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
15
- echo "creating table\n";
16
- $sql = "CREATE TABLE " . $table_name . " (
17
  id mediumint(9) NOT NULL AUTO_INCREMENT,
18
  server text NOT NULL,
19
  port smallint(4) DEFAULT '110' NOT NULL,
@@ -25,19 +27,19 @@ function init() {
25
  UNIQUE KEY id (id)
26
  );";
27
 
28
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
29
- dbDelta($sql);
30
- }
31
  $addresses = array(
32
- 0=> array(
33
- 'server'=>'yourserver.com',
34
- 'port' =>'993',
35
- 'email' => 'youruser',
36
- 'passwd' => 'yourpword',
37
- 'protocol' => 'imap-ssl',
38
- 'offset' => '-5',
39
- 'category' => 5
40
- )
41
  # 1=> array(
42
  # 'server'=>'another.com',
43
  # 'port' =>'993',
@@ -46,74 +48,72 @@ function init() {
46
  # 'protocol' => 'imap-ssl',
47
  # 'offset' => '-5'
48
  # )
49
- );
50
- insert_new_addresses($table_name, $addresses);
51
  }
 
52
  function insert_new_addresses($table_name, $addresses) {
53
- /* insert addresses into table */
54
- global $wpdb;
55
- $fetch_query = 'SELECT email, server FROM ' . $table_name;
56
- $existingAddresses=$wpdb->get_results($fetch_query);
57
- $existingArray=array();
58
- foreach ($existingAddresses as $existAdd) {
59
- array_push($existingArray, $existAdd->email . '@' . $existAdd->server);
60
- }
61
- foreach ($addresses as $address) {
62
- extract($address);
63
- $emailAddress = "$email@$server";
64
- if (!in_array($emailAddress, $existingArray)) {
65
- $query = "INSERT INTO " . $table_name .
66
- " (server, port, email, passwd, protocol, offset, category) " .
67
- "VALUES ('$server', $port, '$email', '$passwd', '$protocol', '$offset', '$category')";
68
- } else {
69
- echo "updating\n";
70
- $query = "UPDATE $table_name set server='$server', port='$port',
71
  email='$email', passwd='$passwd',
72
  protocol='$protocol', offset='$offset', category='$category' WHERE
73
  email='$email' AND server='$server'";
 
 
74
  }
75
- $results = $wpdb->query($wpdb->prepare($query));
76
- }
77
  }
78
 
79
  function fetch_mails() {
80
- global $wpdb;
81
- /* checks mail from various mailboxes and posts those e-mails */
82
- //Load up some usefull libraries
83
-
84
- //Retreive emails
85
- $fetch_query = 'SELECT * FROM ' . $wpdb->prefix . 'postie_addresses';
86
- $mailboxes=$wpdb->get_results($fetch_query);
87
- print_r($mailboxes);
88
- $config=get_config();
89
- foreach ($mailboxes as $mailbox) {
90
- $emails = FetchMail($mailbox->server, $mailbox->port,
91
- $mailbox->email, $mailbox->passwd, $mailbox->protocol);
92
- //loop through messages
93
- foreach ($emails as $email) {
94
- //sanity check to see if there is any info in the message
95
- if ($email == NULL ) {
96
- print 'Dang, message is empty!';
97
- continue;
98
- }
99
-
100
- $mimeDecodedEmail = DecodeMimeMail($email);
101
- $from = RemoveExtraCharactersInEmailAddress(
102
- trim($mimeDecodedEmail->headers["from"]));
103
 
104
- //Check poster to see if a valid person
105
- $poster = ValidatePoster($mimeDecodedEmail, $config);
106
- if (!empty($poster)) {
107
- if ($config['TEST_EMAIL'])
108
- DebugEmailOutput($email,$mimeDecodedEmail);
109
- if ($mailbox->category)
110
- $config['DEFAULT_POST_CATEGORY'] = $mailbox->category;
111
- PostEmail($poster,$mimeDecodedEmail, $config);
112
- }
113
- else {
114
- print("<p>Ignoring email - not authorized.\n");
115
- }
116
- } // end looping over messages
117
- }
118
  }
 
119
  ?>
1
  <?php
2
+
3
  //if ($_POST['fetchmails']) {
4
+ include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . "wp-config.php");
5
+ require_once (dirname(__FILE__) . DIRECTORY_SEPARATOR . '../postie/mimedecode.php');
6
+ require_once (dirname(__FILE__) . DIRECTORY_SEPARATOR . '../postie/postie-functions.php');
7
+ init();
8
+ fetch_mails();
9
+ exit;
10
+
11
  //}
12
  function init() {
13
+ /* Sets up database table if it doesn't already exist */
14
+ global $wpdb, $aandcpostie_version;
15
+ $table_name = $wpdb->prefix . 'postie_addresses';
16
+ if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
17
+ echo "creating table\n";
18
+ $sql = "CREATE TABLE " . $table_name . " (
19
  id mediumint(9) NOT NULL AUTO_INCREMENT,
20
  server text NOT NULL,
21
  port smallint(4) DEFAULT '110' NOT NULL,
27
  UNIQUE KEY id (id)
28
  );";
29
 
30
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
31
+ dbDelta($sql);
32
+ }
33
  $addresses = array(
34
+ 0 => array(
35
+ 'server' => 'yourserver.com',
36
+ 'port' => '993',
37
+ 'email' => 'youruser',
38
+ 'passwd' => 'yourpword',
39
+ 'protocol' => 'imap-ssl',
40
+ 'offset' => '-5',
41
+ 'category' => 5
42
+ )
43
  # 1=> array(
44
  # 'server'=>'another.com',
45
  # 'port' =>'993',
48
  # 'protocol' => 'imap-ssl',
49
  # 'offset' => '-5'
50
  # )
51
+ );
52
+ insert_new_addresses($table_name, $addresses);
53
  }
54
+
55
  function insert_new_addresses($table_name, $addresses) {
56
+ /* insert addresses into table */
57
+ global $wpdb;
58
+ $fetch_query = 'SELECT email, server FROM ' . $table_name;
59
+ $existingAddresses = $wpdb->get_results($fetch_query);
60
+ $existingArray = array();
61
+ foreach ($existingAddresses as $existAdd) {
62
+ array_push($existingArray, $existAdd->email . '@' . $existAdd->server);
63
+ }
64
+ foreach ($addresses as $address) {
65
+ extract($address);
66
+ $emailAddress = "$email@$server";
67
+ if (!in_array($emailAddress, $existingArray)) {
68
+ $query = "INSERT INTO " . $table_name .
69
+ " (server, port, email, passwd, protocol, offset, category) " .
70
+ "VALUES ('$server', $port, '$email', '$passwd', '$protocol', '$offset', '$category')";
71
+ } else {
72
+ echo "updating\n";
73
+ $query = "UPDATE $table_name set server='$server', port='$port',
74
  email='$email', passwd='$passwd',
75
  protocol='$protocol', offset='$offset', category='$category' WHERE
76
  email='$email' AND server='$server'";
77
+ }
78
+ $results = $wpdb->query($wpdb->prepare($query));
79
  }
 
 
80
  }
81
 
82
  function fetch_mails() {
83
+ global $wpdb;
84
+ /* checks mail from various mailboxes and posts those e-mails */
85
+ //Load up some usefull libraries
86
+ //Retreive emails
87
+ $fetch_query = 'SELECT * FROM ' . $wpdb->prefix . 'postie_addresses';
88
+ $mailboxes = $wpdb->get_results($fetch_query);
89
+ print_r($mailboxes);
90
+ $config = get_config();
91
+ foreach ($mailboxes as $mailbox) {
92
+ $emails = FetchMail($mailbox->server, $mailbox->port, $mailbox->email, $mailbox->passwd, $mailbox->protocol);
93
+ //loop through messages
94
+ foreach ($emails as $email) {
95
+ //sanity check to see if there is any info in the message
96
+ if ($email == NULL) {
97
+ print 'Dang, message is empty!';
98
+ continue;
99
+ }
100
+
101
+ $mimeDecodedEmail = DecodeMimeMail($email);
 
 
 
 
102
 
103
+ //Check poster to see if a valid person
104
+ $poster = ValidatePoster($mimeDecodedEmail, $config);
105
+ if (!empty($poster)) {
106
+ if ($config['TEST_EMAIL'])
107
+ DebugEmailOutput($email, $mimeDecodedEmail);
108
+ if ($mailbox->category)
109
+ $config['DEFAULT_POST_CATEGORY'] = $mailbox->category;
110
+ PostEmail($poster, $mimeDecodedEmail, $config);
111
+ }
112
+ else {
113
+ print("<p>Ignoring email - not authorized.\n");
114
+ }
115
+ } // end looping over messages
116
+ }
117
  }
118
+
119
  ?>
filterPostie.php.sample CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /*
3
  Plugin Name: Postie Filter
4
- Plugin URI: http://blog.robfelty.com/plugins/postie
5
  Description: Adds my own custom filter to messages posted by postie
6
  Version: 1.4
7
  Author: Robert Felty
8
- Author URI: http://blog.robfelty.com/
9
  */
10
 
11
  /*
1
  <?php
2
  /*
3
  Plugin Name: Postie Filter
4
+ Plugin URI: http://PostiePlugin.com/
5
  Description: Adds my own custom filter to messages posted by postie
6
  Version: 1.4
7
  Author: Robert Felty
8
+ Author URI: http://robfelty.com/
9
  */
10
 
11
  /*
get_mail.php CHANGED
@@ -1,70 +1,52 @@
1
  <?php
2
 
3
- //Load up some usefull libraries
4
- include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR."wp-config.php");
5
- require_once (dirname(__FILE__). DIRECTORY_SEPARATOR . 'mimedecode.php');
6
- require_once (dirname(__FILE__). DIRECTORY_SEPARATOR . 'postie-functions.php');
7
-
8
 
9
- /* END OF USER VARIABLES */
10
- //some variables
11
- //error_reporting(2037);
12
-
13
- //Retreive emails
14
  print("<pre>\n");
15
  print("This is the postie plugin\n");
16
  print("time:" . time() . "\n");
17
  include('Revision');
18
  $config = get_option('postie-settings');
19
  extract($config);
20
- $emails = FetchMail($mail_server, $mail_server_port, $mail_userid,
21
- $mail_password, $input_protocol, $time_offset, $test_email,
22
- $delete_mail_after_processing);
23
  //loop through messages
24
  foreach ($emails as $email) {
25
- if (function_exists('memory_get_usage'))
26
- echo "memory at start of e-mail processing:" . memory_get_usage() . "\n";
27
  //sanity check to see if there is any info in the message
28
- if ($email == NULL ) {
29
- $message= __('Dang, message is empty!', 'postie');
30
- continue;
31
- } else if ($email=='already read') {
32
- $message = "\n" . __("There does not seem to be any new mail.", 'postie') .
33
- "\n";
34
- continue;
35
  }
36
- // check for XSS attacks - we disallow any javascript, meta, onload, or base64
37
- if (preg_match("/.*(script|onload|meta|base64).*/is", $email)) {
38
- echo "possible XSS attack - ignoring email\n";
39
- continue;
40
  }
41
 
42
- $message='';
43
  $mimeDecodedEmail = DecodeMIMEMail($email, true);
44
- $from = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["from"]));
45
- /*
46
- if ($from != "") {
47
- continue;
48
- }
49
- */
50
 
51
  //Check poster to see if a valid person
52
  $poster = ValidatePoster($mimeDecodedEmail, $config);
53
  if (!empty($poster)) {
54
- if ($test_email)
55
- DebugEmailOutput($email,$mimeDecodedEmail);
56
- PostEmail($poster,$mimeDecodedEmail, $config);
57
  }
58
  else {
59
  print("<p>Ignoring email - not authorized.\n");
60
  }
61
- if (function_exists('memory_get_usage'))
62
- echo "memory at end of e-mail processing:" . memory_get_usage() . "\n";
63
  } // end looping over messages
64
  print $message;
65
  print("</pre>\n");
66
-
67
- /* END PROGRAM */
68
 
69
- // end of script
70
  ?>
1
  <?php
2
 
3
+ include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . "wp-config.php");
4
+ require_once (dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mimedecode.php');
5
+ require_once (dirname(__FILE__) . DIRECTORY_SEPARATOR . 'postie-functions.php');
 
 
6
 
 
 
 
 
 
7
  print("<pre>\n");
8
  print("This is the postie plugin\n");
9
  print("time:" . time() . "\n");
10
  include('Revision');
11
  $config = get_option('postie-settings');
12
  extract($config);
13
+ $emails = FetchMail($mail_server, $mail_server_port, $mail_userid, $mail_password, $input_protocol, $time_offset, $test_email, $delete_mail_after_processing);
14
+ $message = 'Done.';
 
15
  //loop through messages
16
  foreach ($emails as $email) {
17
+ if (function_exists('memory_get_usage'))
18
+ echo "memory at start of e-mail processing:" . memory_get_usage() . "\n";
19
  //sanity check to see if there is any info in the message
20
+ if ($email == NULL) {
21
+ $message = __('Dang, message is empty!', 'postie');
22
+ continue;
23
+ } else if ($email == 'already read') {
24
+ $message = "\n" . __("There does not seem to be any new mail.", 'postie') .
25
+ "\n";
26
+ continue;
27
  }
28
+ // check for XSS attacks - we disallow any javascript, meta, onload, or base64
29
+ if (preg_match("@((%3C|<)/?script|<meta|document\.|\.cookie|\.createElement|onload\s*=|(eval|base64)\()@is", $email)) {
30
+ echo "possible XSS attack - ignoring email\n";
31
+ continue;
32
  }
33
 
 
34
  $mimeDecodedEmail = DecodeMIMEMail($email, true);
 
 
 
 
 
 
35
 
36
  //Check poster to see if a valid person
37
  $poster = ValidatePoster($mimeDecodedEmail, $config);
38
  if (!empty($poster)) {
39
+ if ($test_email)
40
+ DebugEmailOutput($email, $mimeDecodedEmail);
41
+ PostEmail($poster, $mimeDecodedEmail, $config);
42
  }
43
  else {
44
  print("<p>Ignoring email - not authorized.\n");
45
  }
46
+ if (function_exists('memory_get_usage'))
47
+ echo "memory at end of e-mail processing:" . memory_get_usage() . "\n";
48
  } // end looping over messages
49
  print $message;
50
  print("</pre>\n");
 
 
51
 
 
52
  ?>
languages/makepot.cmd ADDED
@@ -0,0 +1 @@
 
1
+ php.exe ..\util\wp-i18n\makepot.php wp-plugin .. postie.pot
languages/postie.pot CHANGED
@@ -1,569 +1,415 @@
1
- # SOME DESCRIPTIVE TITLE.
2
- # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
- # This file is distributed under the same license as the PACKAGE package.
4
- # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
- #
6
- #, fuzzy
7
  msgid ""
8
  msgstr ""
9
- "Project-Id-Version: PACKAGE VERSION\n"
10
- "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2009-08-25 22:42-0400\n"
12
- "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
- "Language-Team: LANGUAGE <LL@li.org>\n"
15
  "MIME-Version: 1.0\n"
16
- "Content-Type: text/plain; charset=CHARSET\n"
17
  "Content-Transfer-Encoding: 8bit\n"
 
 
 
18
 
19
- #: config_form.php:156
20
- msgid ""
21
- "Changing this to yes is NOT RECOMMEDED - anything that gets sent in will "
22
- "automatically be posted. This could make it easier to compromise your server "
23
- "- YOU HAVE BEEN WARNED."
24
- msgstr ""
25
-
26
- #: config_form.php:196
27
- msgid ""
28
- "Put each email address on a single line. Posts from emails in this list will "
29
- "be treated as if they came from the admin. If you would prefer to have users "
30
- "post under their own name - create a WordPress user with the correct access "
31
- "level."
32
- msgstr ""
33
-
34
- #: config_form.php:269
35
- msgid "Set to no if using markdown or textitle syntax"
36
- msgstr ""
37
-
38
- #: config_form.php:285
39
- msgid "Put each type on a single line."
40
- msgstr ""
41
-
42
- #: config_form.php:286
43
- msgid ""
44
- "Put each file name on a single line.Files matching this list will never be "
45
- "posted to your blog. You can use wildcards such as *.xls, or *.* for all "
46
- "files"
47
- msgstr ""
48
-
49
- #: config_form.php:288
50
- msgid ""
51
- "Put each pattern on a separate line and make sure to escape any special "
52
- "characters."
53
- msgstr ""
54
-
55
- #: config_form.php:290
56
- msgid ""
57
- "Only allow messages which have been sent throught the following smtp "
58
- "servers. Put each server on a separate line. Leave blank to not check stmp "
59
- "servers."
60
- msgstr ""
61
-
62
- #: config_form.php:299
63
- msgid "No means they will be put before the text of the message."
64
- msgstr ""
65
-
66
- #: config_form.php:347
67
- msgid ""
68
- "When true, images will not appear in the post. Instead the url to the image "
69
- "will be input into a custom field named 'image'."
70
- msgstr ""
71
-
72
- #: config_form.php:4 config_form.php:41
73
  msgid "Postie Options"
74
  msgstr ""
75
 
76
- #: config_form.php:44
77
  msgid "Configuration successfully updated!"
78
  msgstr ""
79
 
80
- #: config_form.php:45
81
  msgid "Error - unable to save configuration"
82
  msgstr ""
83
 
84
- #: config_form.php:53
85
  msgid "Reset Settings To Defaults"
86
  msgstr ""
87
 
88
- #: config_form.php:57
89
  msgid "Run Postie"
90
  msgstr ""
91
 
92
- #: config_form.php:58
93
  msgid "(To run the check mail script manually)"
94
  msgstr ""
95
 
96
- #: config_form.php:62
97
  msgid "Test Config"
98
  msgstr ""
99
 
100
- #: config_form.php:63
101
  msgid "this will run a special script to test your configuration options"
102
  msgstr ""
103
 
104
- #: config_form.php:69
105
  msgid "Mailserver"
106
  msgstr ""
107
 
108
- #: config_form.php:70
109
  msgid "User"
110
  msgstr ""
111
 
112
- #: config_form.php:71
113
  msgid "Message"
114
  msgstr ""
115
 
116
- #: config_form.php:72
117
  msgid "Image"
118
  msgstr ""
119
 
120
- #: config_form.php:73
121
  msgid "Video and Audio"
122
  msgstr ""
123
 
124
- #: config_form.php:74
125
- msgid "Attachments"
126
- msgstr ""
127
-
128
- #: config_form.php:75
129
- msgid "Help"
130
- msgstr ""
131
-
132
- #: config_form.php:76
133
- msgid "FAQ"
134
- msgstr ""
135
-
136
- #: config_form.php:84
137
- msgid "Cronless postie should check for mail"
138
- msgstr ""
139
-
140
  #: config_form.php:86
141
- msgid "Once weekly"
142
  msgstr ""
143
 
144
  #: config_form.php:87
145
- msgid "daily"
146
  msgstr ""
147
 
148
  #: config_form.php:88
149
- msgid "hourly"
150
- msgstr ""
151
-
152
- #: config_form.php:89
153
- msgid "twice per hour"
154
- msgstr ""
155
-
156
- #: config_form.php:90
157
- msgid "every ten minutes"
158
  msgstr ""
159
 
160
- #: config_form.php:99
161
  msgid "Mail Protocol:"
162
  msgstr ""
163
 
164
- #: config_form.php:108
165
- msgid "IMAP/IMAP-SSL/POP3-SSL unavailable"
166
- msgstr ""
167
-
168
- #: config_form.php:114
169
  msgid "Port:"
170
  msgstr ""
171
 
172
- #: config_form.php:115
173
  msgid "Standard Ports:"
174
  msgstr ""
175
 
176
- #: config_form.php:116
177
  msgid "POP3"
178
  msgstr ""
179
 
180
- #: config_form.php:117
181
  msgid "IMAP"
182
  msgstr ""
183
 
184
- #: config_form.php:118
185
  msgid "IMAP-SSL"
186
  msgstr ""
187
 
188
- #: config_form.php:119
189
  msgid "POP3-SSL"
190
  msgstr ""
191
 
192
- #: config_form.php:127
193
  msgid "Postie Time Correction:"
194
  msgstr ""
195
 
196
- #: config_form.php:129
197
- msgid ""
198
- "Should be the same as your normal offset - but this lets you adjust it in "
199
- "cases where that doesn't work."
200
  msgstr ""
201
 
202
- #: config_form.php:132
203
  msgid "hours"
204
  msgstr ""
205
 
206
- #: config_form.php:137
207
  msgid "Mail Server:"
208
  msgstr ""
209
 
210
- #: config_form.php:142
211
  msgid "Mail Userid:"
212
  msgstr ""
213
 
214
- #: config_form.php:146
215
  msgid "Mail Password:"
216
  msgstr ""
217
 
218
- #: config_form.php:156
219
- msgid "Allow Anyone To Post Via Email"
220
  msgstr ""
221
 
222
- #: config_form.php:158
223
- msgid "Roles That Can Post:"
224
- msgstr ""
225
-
226
- #: config_form.php:160
227
- msgid ""
228
- "This allows you to grant access to other users to post if they have the "
229
- "proper access level"
230
  msgstr ""
231
 
232
- #: config_form.php:183
233
- msgid "Post status:"
234
  msgstr ""
235
 
236
- #: config_form.php:196
237
- msgid "Authorized Addresses"
238
  msgstr ""
239
 
240
- #: config_form.php:199
241
- msgid "Admin username:"
242
  msgstr ""
243
 
244
- #: config_form.php:209
245
- msgid "Default post by mail category:"
246
  msgstr ""
247
 
248
- #: config_form.php:217
249
- msgid "Default post by mail tag(s)"
250
  msgstr ""
251
 
252
- #: config_form.php:218
253
- msgid "separated by commas"
254
  msgstr ""
255
 
256
- #: config_form.php:226
257
- msgid "Default Title:"
258
  msgstr ""
259
 
260
- #: config_form.php:233
261
- msgid ""
262
- "Preferred\n"
263
- " Text Type:"
264
  msgstr ""
265
 
266
- #: config_form.php:242
267
- msgid "Forward Rejected Mail"
268
  msgstr ""
269
 
270
- #: config_form.php:243
271
- msgid "Allow Subject In Mail"
272
  msgstr ""
273
 
274
- #: config_form.php:244
275
- msgid "Allow HTML In Mail Subject"
276
  msgstr ""
277
 
278
- #: config_form.php:245
279
- msgid "Allow HTML In Mail Body"
280
  msgstr ""
281
 
282
- #: config_form.php:247
283
- msgid ""
284
- "Tag Of\n"
285
- " Message Start:"
286
  msgstr ""
287
 
288
- #: config_form.php:249
289
- msgid ""
290
- "Use to remove any text from a message that the email provider puts at the "
291
- "top of the message"
292
  msgstr ""
293
 
294
- #: config_form.php:255
295
- msgid ""
296
- "Tag Of\n"
297
- " Message End:"
298
  msgstr ""
299
 
300
- #: config_form.php:257
301
- msgid ""
302
- "Use to remove any text from a message that the email provider puts at the "
303
- "end of the message"
304
  msgstr ""
305
 
306
- #: config_form.php:266
307
- msgid "Wrap content in pre tags"
308
  msgstr ""
309
 
310
- #: config_form.php:267
311
- msgid "Filter newlines"
312
  msgstr ""
313
 
314
- #: config_form.php:270
315
- msgid ""
316
- "Replace newline characters with\n"
317
- " html line breaks (&lt;br\n"
318
- " /&gt;)"
319
  msgstr ""
320
 
321
- #: config_form.php:273
322
- msgid "Return rejected mail to sender"
323
  msgstr ""
324
 
325
- #: config_form.php:274
326
- msgid "Send post confirmation e-mail to sender"
327
  msgstr ""
328
 
329
- #: config_form.php:275
330
- msgid "Automatically convert urls to links"
331
  msgstr ""
332
 
333
- #: config_form.php:276
334
- msgid "Use shortcode for embedding video (youtube and others)"
335
  msgstr ""
336
 
337
- #: config_form.php:278
338
  msgid "Encoding for pages and feeds:"
339
  msgstr ""
340
 
341
- #: config_form.php:281
342
  msgid "should handle ISO-8859-1 as well"
343
  msgstr ""
344
 
345
- #: config_form.php:284
346
- msgid "Decode Quoted Printable Data"
347
- msgstr ""
348
-
349
- #: config_form.php:285
350
- msgid "Supported File Types"
351
- msgstr ""
352
-
353
- #: config_form.php:286
354
- msgid "Banned File Names"
355
- msgstr ""
356
-
357
- #: config_form.php:287
358
- msgid "Drop The Signature From Mail"
359
- msgstr ""
360
-
361
- #: config_form.php:288
362
- msgid "Signature Patterns"
363
- msgstr ""
364
-
365
- #: config_form.php:289
366
- msgid ""
367
- "Allowed SMTP\n"
368
- " servers"
369
- msgstr ""
370
-
371
- #: config_form.php:298
372
- msgid ""
373
- "Post Images At\n"
374
- " End"
375
- msgstr ""
376
-
377
- #: config_form.php:300
378
- msgid "Start Image Count At 0"
379
- msgstr ""
380
-
381
- #: config_form.php:302
382
  msgid "Image Place Holder Tag:"
383
  msgstr ""
384
 
385
- #: config_form.php:308
386
- msgid ""
387
- "Image\n"
388
- " Template"
389
  msgstr ""
390
 
391
- #: config_form.php:310
392
- msgid ""
393
- "Choose a default template,\n"
394
- " then customize to your liking in the text box"
395
  msgstr ""
396
 
397
- #: config_form.php:313
398
- msgid ""
399
- "Sizes for thumbnail, medium, and large images can be chosen in the <a href="
400
- "\"options-media.php\">Media Settings</a>. The samples here use the default "
401
- "sizes, and will not reflect the sizes you have chosen."
402
  msgstr ""
403
 
404
- #: config_form.php:340 config_form.php:385 config_form.php:427
405
- #: config_form.php:471 config_form.php:545
406
  msgid "Preview"
407
  msgstr ""
408
 
409
- #: config_form.php:347
410
- msgid "Use custom image field"
411
- msgstr ""
412
-
413
- #: config_form.php:358
414
  msgid "Video template 1"
415
  msgstr ""
416
 
417
- #: config_form.php:359 config_form.php:402 config_form.php:444
418
- msgid ""
419
- "Choose a default template, then customize to your liking in the text box"
420
- msgstr ""
421
-
422
- #: config_form.php:394
423
  msgid "Video 1 file types:"
424
  msgstr ""
425
 
426
- #: config_form.php:395
427
- msgid ""
428
- "Use the video template 1 for these files types (separated by\n"
429
- " commas)"
430
  msgstr ""
431
 
432
- #: config_form.php:401
433
  msgid "Video template 2"
434
  msgstr ""
435
 
436
- #: config_form.php:436
437
  msgid "Video 2 file types:"
438
  msgstr ""
439
 
440
- #: config_form.php:437
441
- msgid ""
442
- "Use the video template 2 for these files types (separated by\n"
443
- " commas)"
444
  msgstr ""
445
 
446
- #: config_form.php:443
447
  msgid "Audio template"
448
  msgstr ""
449
 
450
- #: config_form.php:480
451
  msgid "Audio file types:"
452
  msgstr ""
453
 
454
- #: config_form.php:481
455
- msgid ""
456
- "Use the audio template for these files types (separated by\n"
457
- " commas)"
458
  msgstr ""
459
 
460
- #: config_form.php:495
461
  msgid "Attachment icon set"
462
  msgstr ""
463
 
464
- #: config_form.php:519
465
  msgid "Attachment icon size (in pixels)"
466
  msgstr ""
467
 
468
- #: config_form.php:560
469
- msgid "Update Options"
470
  msgstr ""
471
 
472
- #: cronless_postie.php:37 postie.php:66
473
- msgid "Edit Plugins"
474
- msgstr ""
475
-
476
- #: get_mail.php:29
477
  msgid "Dang, message is empty!"
478
  msgstr ""
479
 
480
- #: get_mail.php:32 postie-functions.php:382
481
  msgid "There does not seem to be any new mail."
482
  msgstr ""
483
 
484
- #: postie-functions.php:1327
485
- msgid ""
486
- "The uploaded file exceeds the <code>upload_max_filesize</code> directive in "
487
- "<code>php.ini</code>."
488
  msgstr ""
489
 
490
- #: postie-functions.php:1328
491
- msgid ""
492
- "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was "
493
- "specified in the HTML form."
494
  msgstr ""
495
 
496
- #: postie-functions.php:1329
497
  msgid "The uploaded file was only partially uploaded."
498
  msgstr ""
499
 
500
- #: postie-functions.php:1330
501
  msgid "No file was uploaded."
502
  msgstr ""
503
 
504
- #: postie-functions.php:1332
505
  msgid "Missing a temporary folder."
506
  msgstr ""
507
 
508
- #: postie-functions.php:1333
509
  msgid "Failed to write file to disk."
510
  msgstr ""
511
 
512
- #: postie-functions.php:1349
513
  msgid "Invalid form submission."
514
  msgstr ""
515
 
516
- #: postie-functions.php:1357
517
- msgid ""
518
- "File is empty. Please upload something more substantial. This error could "
519
- "also be caused by uploads being disabled in your php.ini."
520
  msgstr ""
521
 
522
- #: postie-functions.php:1361
523
  msgid "Specified file failed upload test."
524
  msgstr ""
525
 
526
- #: postie-functions.php:1369
527
  msgid "File type does not meet security guidelines. Try another."
528
  msgstr ""
529
 
530
- #: postie-functions.php:1387
531
- #, php-format
532
  msgid "The uploaded file could not be moved to %s."
533
  msgstr ""
534
 
535
- #: postie-functions.php:1986
536
  msgid "Yes"
537
  msgstr ""
538
 
539
- #: postie-functions.php:1988
540
  msgid "No"
541
  msgstr ""
542
 
543
- #: postie.php:97
 
 
 
 
544
  msgid "Postie is almost ready."
545
  msgstr ""
546
 
547
- #: postie.php:98
548
- #, php-format
549
  msgid "You must <a href=\"%1$s\">enter your email settings</a> for it to work."
550
  msgstr ""
551
 
552
- #: postie.php:105
553
  msgid "Warning: the IMAP php extension is not installed."
554
  msgstr ""
555
 
556
- #: postie.php:106
557
- msgid ""
558
- "Postie may not function correctly without this extension (especially for non-"
559
- "English messages)."
560
  msgstr ""
561
 
562
- #: postie.php:109
563
- #, php-format
564
  msgid "Please see the <a href=\"%1$s\">FAQ </a> for more information."
565
  msgstr ""
566
 
567
- #: postie_test.php:8
568
  msgid "Postie Diagnosis"
569
  msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2012
2
+ # This file is distributed under the same license as the package.
 
 
 
 
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: \n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/src\n"
7
+ "POT-Creation-Date: 2012-11-14 22:30:13+00:00\n"
 
 
 
8
  "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2012-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #: config_form.php:4 config_form.php:35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  msgid "Postie Options"
17
  msgstr ""
18
 
19
+ #: config_form.php:55
20
  msgid "Configuration successfully updated!"
21
  msgstr ""
22
 
23
+ #: config_form.php:56
24
  msgid "Error - unable to save configuration"
25
  msgstr ""
26
 
27
+ #: config_form.php:63
28
  msgid "Reset Settings To Defaults"
29
  msgstr ""
30
 
31
+ #: config_form.php:67
32
  msgid "Run Postie"
33
  msgstr ""
34
 
35
+ #: config_form.php:68
36
  msgid "(To run the check mail script manually)"
37
  msgstr ""
38
 
39
+ #: config_form.php:72
40
  msgid "Test Config"
41
  msgstr ""
42
 
43
+ #: config_form.php:73
44
  msgid "this will run a special script to test your configuration options"
45
  msgstr ""
46
 
47
+ #: config_form.php:81
48
  msgid "Mailserver"
49
  msgstr ""
50
 
51
+ #: config_form.php:82
52
  msgid "User"
53
  msgstr ""
54
 
55
+ #: config_form.php:83
56
  msgid "Message"
57
  msgstr ""
58
 
59
+ #: config_form.php:84
60
  msgid "Image"
61
  msgstr ""
62
 
63
+ #: config_form.php:85
64
  msgid "Video and Audio"
65
  msgstr ""
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  #: config_form.php:86
68
+ msgid "Attachments"
69
  msgstr ""
70
 
71
  #: config_form.php:87
72
+ msgid "Help"
73
  msgstr ""
74
 
75
  #: config_form.php:88
76
+ msgid "FAQ"
 
 
 
 
 
 
 
 
77
  msgstr ""
78
 
79
+ #: config_form.php:95
80
  msgid "Mail Protocol:"
81
  msgstr ""
82
 
83
+ #: config_form.php:111
 
 
 
 
84
  msgid "Port:"
85
  msgstr ""
86
 
87
+ #: config_form.php:112
88
  msgid "Standard Ports:"
89
  msgstr ""
90
 
91
+ #: config_form.php:113
92
  msgid "POP3"
93
  msgstr ""
94
 
95
+ #: config_form.php:114
96
  msgid "IMAP"
97
  msgstr ""
98
 
99
+ #: config_form.php:115
100
  msgid "IMAP-SSL"
101
  msgstr ""
102
 
103
+ #: config_form.php:116
104
  msgid "POP3-SSL"
105
  msgstr ""
106
 
107
+ #: config_form.php:124
108
  msgid "Postie Time Correction:"
109
  msgstr ""
110
 
111
+ #: config_form.php:126
112
+ msgid "Should be the same as your normal offset - but this lets you adjust it in cases where that doesn't work."
 
 
113
  msgstr ""
114
 
115
+ #: config_form.php:129
116
  msgid "hours"
117
  msgstr ""
118
 
119
+ #: config_form.php:134
120
  msgid "Mail Server:"
121
  msgstr ""
122
 
123
+ #: config_form.php:139
124
  msgid "Mail Userid:"
125
  msgstr ""
126
 
127
+ #: config_form.php:143
128
  msgid "Mail Password:"
129
  msgstr ""
130
 
131
+ #: config_form.php:149
132
+ msgid "Check for mail every"
133
  msgstr ""
134
 
135
+ #: config_form.php:157
136
+ msgid "Once weekly"
 
 
 
 
 
 
137
  msgstr ""
138
 
139
+ #: config_form.php:162
140
+ msgid "daily"
141
  msgstr ""
142
 
143
+ #: config_form.php:167
144
+ msgid "hourly"
145
  msgstr ""
146
 
147
+ #: config_form.php:172
148
+ msgid "twice per hour"
149
  msgstr ""
150
 
151
+ #: config_form.php:177
152
+ msgid "every ten minutes"
153
  msgstr ""
154
 
155
+ #: config_form.php:183
156
+ msgid "check manually"
157
  msgstr ""
158
 
159
+ #: config_form.php:195
160
+ msgid "Roles That Can Post:"
161
  msgstr ""
162
 
163
+ #: config_form.php:197
164
+ msgid "This allows you to grant access to other users to post if they have the proper access level"
165
  msgstr ""
166
 
167
+ #: config_form.php:221
168
+ msgid "Post status:"
 
 
169
  msgstr ""
170
 
171
+ #: config_form.php:253
172
+ msgid "Admin username:"
173
  msgstr ""
174
 
175
+ #: config_form.php:263
176
+ msgid "Default post by mail category:"
177
  msgstr ""
178
 
179
+ #: config_form.php:272
180
+ msgid "Default post by mail tag(s)"
181
  msgstr ""
182
 
183
+ #: config_form.php:274
184
+ msgid "separated by commas"
185
  msgstr ""
186
 
187
+ #: config_form.php:282
188
+ msgid "Default Title:"
 
 
189
  msgstr ""
190
 
191
+ #: config_form.php:289
192
+ msgid "Preferred Text Type:"
 
 
193
  msgstr ""
194
 
195
+ #: config_form.php:302
196
+ msgid "Tag Of Message Start:"
 
 
197
  msgstr ""
198
 
199
+ #: config_form.php:303
200
+ msgid "Use to remove any text from a message that the email provider puts at the top of the message"
 
 
201
  msgstr ""
202
 
203
+ #: config_form.php:309
204
+ msgid "Tag Of Message End:"
205
  msgstr ""
206
 
207
+ #: config_form.php:310
208
+ msgid "Use to remove any text from a message that the email provider puts at the end of the message"
209
  msgstr ""
210
 
211
+ #: config_form.php:327
212
+ msgid "Send post confirmation e-mail to"
 
 
 
213
  msgstr ""
214
 
215
+ #: config_form.php:332
216
+ msgid "sender"
217
  msgstr ""
218
 
219
+ #: config_form.php:333
220
+ msgid "administrator"
221
  msgstr ""
222
 
223
+ #: config_form.php:334
224
+ msgid "sender and administrator"
225
  msgstr ""
226
 
227
+ #: config_form.php:335
228
+ msgid "none"
229
  msgstr ""
230
 
231
+ #: config_form.php:345
232
  msgid "Encoding for pages and feeds:"
233
  msgstr ""
234
 
235
+ #: config_form.php:348
236
  msgid "should handle ISO-8859-1 as well"
237
  msgstr ""
238
 
239
+ #: config_form.php:369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  msgid "Image Place Holder Tag:"
241
  msgstr ""
242
 
243
+ #: config_form.php:375
244
+ msgid "Image Template"
 
 
245
  msgstr ""
246
 
247
+ #: config_form.php:376 config_form.php:425 config_form.php:468
248
+ #: config_form.php:512
249
+ msgid "Choose a default template, then customize to your liking in the text box"
 
250
  msgstr ""
251
 
252
+ #: config_form.php:377
253
+ msgid "Sizes for thumbnail, medium, and large images can be chosen in the <a href=\"options-media.php\">Media Settings</a>. The samples here use the default sizes, and will not reflect the sizes you have chosen."
 
 
 
254
  msgstr ""
255
 
256
+ #: config_form.php:405 config_form.php:452 config_form.php:494
257
+ #: config_form.php:539 config_form.php:614
258
  msgid "Preview"
259
  msgstr ""
260
 
261
+ #: config_form.php:424
 
 
 
 
262
  msgid "Video template 1"
263
  msgstr ""
264
 
265
+ #: config_form.php:461
 
 
 
 
 
266
  msgid "Video 1 file types:"
267
  msgstr ""
268
 
269
+ #: config_form.php:462
270
+ msgid "Use the video template 1 for these files types (separated by commas)"
 
 
271
  msgstr ""
272
 
273
+ #: config_form.php:467
274
  msgid "Video template 2"
275
  msgstr ""
276
 
277
+ #: config_form.php:505
278
  msgid "Video 2 file types:"
279
  msgstr ""
280
 
281
+ #: config_form.php:506
282
+ msgid "Use the video template 2 for these files types (separated by commas)"
 
 
283
  msgstr ""
284
 
285
+ #: config_form.php:511
286
  msgid "Audio template"
287
  msgstr ""
288
 
289
+ #: config_form.php:548
290
  msgid "Audio file types:"
291
  msgstr ""
292
 
293
+ #: config_form.php:550
294
+ msgid "Use the audio template for these files types (separated by commas)"
 
 
295
  msgstr ""
296
 
297
+ #: config_form.php:563
298
  msgid "Attachment icon set"
299
  msgstr ""
300
 
301
+ #: config_form.php:590
302
  msgid "Attachment icon size (in pixels)"
303
  msgstr ""
304
 
305
+ #: config_form.php:635
306
+ msgid "Save Changes"
307
  msgstr ""
308
 
309
+ #: get_mail.php:21
 
 
 
 
310
  msgid "Dang, message is empty!"
311
  msgstr ""
312
 
313
+ #: get_mail.php:24 postie-functions.php:449
314
  msgid "There does not seem to be any new mail."
315
  msgstr ""
316
 
317
+ #: postie-functions.php:1387
318
+ msgid "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>."
 
 
319
  msgstr ""
320
 
321
+ #: postie-functions.php:1388
322
+ msgid "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form."
 
 
323
  msgstr ""
324
 
325
+ #: postie-functions.php:1389
326
  msgid "The uploaded file was only partially uploaded."
327
  msgstr ""
328
 
329
+ #: postie-functions.php:1390
330
  msgid "No file was uploaded."
331
  msgstr ""
332
 
333
+ #: postie-functions.php:1392
334
  msgid "Missing a temporary folder."
335
  msgstr ""
336
 
337
+ #: postie-functions.php:1393
338
  msgid "Failed to write file to disk."
339
  msgstr ""
340
 
341
+ #: postie-functions.php:1409
342
  msgid "Invalid form submission."
343
  msgstr ""
344
 
345
+ #: postie-functions.php:1417
346
+ msgid "File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini."
 
 
347
  msgstr ""
348
 
349
+ #: postie-functions.php:1421
350
  msgid "Specified file failed upload test."
351
  msgstr ""
352
 
353
+ #: postie-functions.php:1429
354
  msgid "File type does not meet security guidelines. Try another."
355
  msgstr ""
356
 
357
+ #: postie-functions.php:1449
 
358
  msgid "The uploaded file could not be moved to %s."
359
  msgstr ""
360
 
361
+ #: postie-functions.php:2059
362
  msgid "Yes"
363
  msgstr ""
364
 
365
+ #: postie-functions.php:2061
366
  msgid "No"
367
  msgstr ""
368
 
369
+ #: postie.php:82
370
+ msgid "Edit Plugins"
371
+ msgstr ""
372
+
373
+ #: postie.php:161
374
  msgid "Postie is almost ready."
375
  msgstr ""
376
 
377
+ #: postie.php:162
 
378
  msgid "You must <a href=\"%1$s\">enter your email settings</a> for it to work."
379
  msgstr ""
380
 
381
+ #: postie.php:172
382
  msgid "Warning: the IMAP php extension is not installed."
383
  msgstr ""
384
 
385
+ #: postie.php:173
386
+ msgid "Postie may not function correctly without this extension (especially for non-English messages)."
 
 
387
  msgstr ""
388
 
389
+ #: postie.php:176
 
390
  msgid "Please see the <a href=\"%1$s\">FAQ </a> for more information."
391
  msgstr ""
392
 
393
+ #: postie_test.php:10
394
  msgid "Postie Diagnosis"
395
  msgstr ""
396
+
397
+ #: postie_test.php:41
398
+ msgid "Only required for international character set support"
399
+ msgstr ""
400
+
401
+ #: postie_test.php:45 postie_test.php:49
402
+ msgid "yes"
403
+ msgstr ""
404
+
405
+ #: util/wp-i18n/pomo/sample/app.php:56
406
+ msgid "Welcome %s!"
407
+ msgstr ""
408
+
409
+ #: util/wp-i18n/pomo/sample/app.php:60
410
+ msgid "A string with low priority!"
411
+ msgstr ""
412
+
413
+ #: util/wp-i18n/pomo/sample/app.php:62
414
+ msgid "Bye\n"
415
+ msgstr ""
makepot DELETED
@@ -1,5 +0,0 @@
1
- #!/bin/bash
2
- find . -iname '*php' >files.tmp
3
- xgettext --language=PHP --keyword=__ --keyword=_e --keyword=__ngettext:1,2 --keyword=BuildBooleanSelect:1 --keyword=BuildTextArea:1 -F -n --from-code=UTF8 -o languages/postie.pot -f files.tmp
4
- xgettext --language=PHP --keyword=BuildBooleanSelect:4 --keyword=BuildTextArea:4 -F -n --from-code=UTF8 -j -o languages/postie.pot -f files.tmp
5
- rm files.tmp
 
 
 
 
 
package.xml CHANGED
@@ -1,426 +1,438 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <package packagerversion="1.6.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
3
- <name>Mail_Mime</name>
4
- <channel>pear.php.net</channel>
5
- <summary>Mail_Mime provides classes to create mime messages.</summary>
6
- <description>Mail_Mime provides classes to deal with the creation and manipulation of mime messages.
7
- It allows people to create Email messages consisting of:
8
- * Text Parts
9
- * HTML Parts
10
- * Inline HTML Images
11
- * Attachments
12
- * Attached messages
13
-
14
- Starting with version 1.4.0, it also allows non US-ASCII chars in filenames, subjects, recipients, etc, etc.</description>
15
- <lead>
16
- <name>Cipriano Groenendal</name>
17
- <user>cipri</user>
18
- <email>cipri@php.net</email>
19
- <active>yes</active>
20
- </lead>
21
- <date>2007-06-21</date>
22
- <time>21:10:11</time>
23
- <version>
24
- <release>1.5.2</release>
25
- <api>1.3.1</api>
26
- </version>
27
- <stability>
28
- <release>stable</release>
29
- <api>stable</api>
30
- </stability>
31
- <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
32
- <notes>* Fix Bug #11381: domain name is attached to content-id, trailing greater-than sign is
33
- not remove [cipri]</notes>
34
- <contents>
35
- <dir name="/">
36
- <file baseinstalldir="Mail" md5sum="a2899bc69329c9533205aeb4221ab775" name="scripts/phail.php" role="doc" />
37
- <file baseinstalldir="Mail" md5sum="edd138f6c5497ae2b5d63620a67a931e" name="tests/class-filename.phpt" role="test" />
38
- <file baseinstalldir="Mail" md5sum="494526cc12e4edec45e0207f569d57d9" name="tests/encoding_case.phpt" role="test" />
39
- <file baseinstalldir="Mail" md5sum="1016a2a921d414f52fbc6d3a028945f4" name="tests/sleep_wakeup_EOL-bug3488-part1.phpt" role="test" />
40
- <file baseinstalldir="Mail" md5sum="61c745f92e8162e6e2971464a15990d4" name="tests/sleep_wakeup_EOL-bug3488-part2.phpt" role="test" />
41
- <file baseinstalldir="Mail" md5sum="494526cc12e4edec45e0207f569d57d9" name="tests/tabs_quoted_printable.phpt" role="test" />
42
- <file baseinstalldir="Mail" md5sum="844305aaa9ca4820a1672ba6da0a94c7" name="tests/test_Bug_30_1.phpt" role="test" />
43
- <file baseinstalldir="Mail" md5sum="2d0bd00382e3f9c5f2e3e9512b731d68" name="tests/test_Bug_30_2.phpt" role="test" />
44
- <file baseinstalldir="Mail" md5sum="83d326b6ca7d9f704ff2544edeb601ab" name="tests/test_Bug_30_3.phpt" role="test" />
45
- <file baseinstalldir="Mail" md5sum="c2ea41bc1d78cb2b88e4514d8044a98d" name="tests/test_Bug_30_4.phpt" role="test" />
46
- <file baseinstalldir="Mail" md5sum="6af58588ed4e35df8845f6704d7384ba" name="tests/test_Bug_3513_1.phpt" role="test" />
47
- <file baseinstalldir="Mail" md5sum="efaa5d82baea0b46560752817d455bf4" name="tests/test_Bug_3513_2.phpt" role="test" />
48
- <file baseinstalldir="Mail" md5sum="27020435d9432ebece744308e803030f" name="tests/test_Bug_3513_3.phpt" role="test" />
49
- <file baseinstalldir="Mail" md5sum="dc2b1be6fab962386f16f6d710cf2d0a" name="tests/test_Bug_7561_1.phpt" role="test" />
50
- <file baseinstalldir="Mail" md5sum="cd9c56b628649f92f067920d2e8a6214" name="tests/test_Bug_8223_1.phpt" role="test" />
51
- <file baseinstalldir="Mail" md5sum="51888d86ce4fb58fc89a366736f5910a" name="tests/test_Bug_8386_1.phpt" role="test" />
52
- <file baseinstalldir="Mail" md5sum="440c46d4ea863539caec007af431b307" name="tests/test_Bug_8541_1.phpt" role="test" />
53
- <file baseinstalldir="Mail" md5sum="a1f598cf82774fde322ac4f3f3a7e0be" name="tests/test_Bug_9558_1.phpt" role="test" />
54
- <file baseinstalldir="Mail" md5sum="5adfb0668904b72d2c04073f55f8144c" name="tests/test_Bug_9722_1.phpt" role="test" />
55
- <file baseinstalldir="Mail" md5sum="18160c212dd0042bf21eb703e58de9ce" name="tests/test_Bug_9725_1.phpt" role="test" />
56
- <file baseinstalldir="Mail" md5sum="e07949f077db4cfeaad0bffe9d4d37da" name="tests/test_Bug_9976_1.phpt" role="test" />
57
- <file baseinstalldir="Mail" md5sum="fcc6eeedeb8ae7ddcf1637c048ab7f93" name="tests/test_Bug_10298_1.phpt" role="test" />
58
- <file baseinstalldir="Mail" md5sum="c64c1115b7fe7f3a8d8c6fd8f8d7c268" name="tests/test_Bug_10596_1.phpt" role="test" />
59
- <file baseinstalldir="Mail" md5sum="0eacb8c485ade073b61fe2daeae3124f" name="tests/test_Bug_10816_1.phpt" role="test" />
60
- <file baseinstalldir="Mail" md5sum="93a00275edb0d9e94364ae11175741d1" name="mime.php" role="php" />
61
- <file baseinstalldir="Mail" md5sum="53aedbcc104a9bd15cf96e5511b6498b" name="mimePart.php" role="php" />
62
- <file baseinstalldir="Mail" md5sum="194810c478066eaeb28f51116b88e25a" name="xmail.dtd" role="data" />
63
- <file baseinstalldir="Mail" md5sum="61cea06fb6b4bd3a4b5e2d37384e14a9" name="xmail.xsl" role="data" />
64
- </dir>
65
- </contents>
66
- <dependencies>
67
- <required>
68
- <php>
69
- <min>4.0.0</min>
70
- </php>
71
- <pearinstaller>
72
- <min>1.6.0</min>
73
- </pearinstaller>
74
- <subpackage>
75
- <name>Mail_mimeDecode</name>
76
  <channel>pear.php.net</channel>
77
- </subpackage>
78
- </required>
79
- </dependencies>
80
- <phprelease />
81
- <changelog>
82
- <release>
83
- <version>
84
- <release>1.0</release>
85
- <api>1.0</api>
86
- </version>
87
- <stability>
88
- <release>stable</release>
89
- <api>stable</api>
90
- </stability>
91
- <date>2001-12-28</date>
92
- <license uri="http://www.php.net/license">PHP</license>
93
- <notes>This is the initial release of the Mime_Mail package.</notes>
94
- </release>
95
- <release>
96
- <version>
97
- <release>1.1</release>
98
- <api>1.1</api>
99
- </version>
100
- <stability>
101
- <release>stable</release>
102
- <api>stable</api>
103
- </stability>
104
- <date>2002-04-03</date>
105
- <license uri="http://www.php.net/license">PHP</license>
106
- <notes>This is a maintenance release with various bugfixes and minor enhancements.</notes>
107
- </release>
108
- <release>
109
- <version>
110
- <release>1.2</release>
111
- <api>1.2</api>
112
- </version>
113
- <stability>
114
- <release>stable</release>
115
- <api>stable</api>
116
- </stability>
117
- <date>2002-07-14</date>
118
- <license uri="http://www.php.net/license">PHP</license>
119
- <notes>o Added header encoding
120
- o Altered mimePart to put boundary parameter on newline
121
- o Changed addFrom() to setFrom()
122
- o Added setSubject()
123
- o Made mimePart inherit crlf setting from mime</notes>
124
- </release>
125
- <release>
126
- <version>
127
- <release>1.2.1</release>
128
- <api>1.2.1</api>
129
- </version>
130
- <stability>
131
- <release>stable</release>
132
- <api>stable</api>
133
- </stability>
134
- <date>2002-07-27</date>
135
- <license uri="http://www.php.net/license">PHP</license>
136
- <notes>o License change
137
- o Applied a few changes From Ilia Alshanetsky</notes>
138
- </release>
139
- <release>
140
- <version>
141
- <release>1.3.0RC1</release>
142
- <api>1.3.0RC1</api>
143
- </version>
144
- <stability>
145
- <release>beta</release>
146
- <api>beta</api>
147
- </stability>
148
- <date>2005-03-20</date>
149
- <license uri="http://www.php.net/license">PHP</license>
150
- <notes>o First release in over 2.5 years (!)
151
- o MANY bugfixes (see the bugtracker)
152
- o added a few tests</notes>
153
- </release>
154
- <release>
155
- <version>
156
- <release>1.3.0</release>
157
- <api>1.3.0</api>
158
- </version>
159
- <stability>
160
- <release>stable</release>
161
- <api>stable</api>
162
- </stability>
163
- <date>2005-04-01</date>
164
- <license uri="http://www.php.net/license">PHP</license>
165
- <notes>o First (stable) release in over 2.5 years (!)
166
- o MANY bugfixes (see the bugtracker)
167
- o added a few tests
168
- o one small fix after RC1 (bug #3940)</notes>
169
- </release>
170
- <release>
171
- <version>
172
- <release>1.3.1</release>
173
- <api>1.3.1</api>
174
- </version>
175
- <stability>
176
- <release>stable</release>
177
- <api>stable</api>
178
- </stability>
179
- <date>2005-07-13</date>
180
- <license uri="http://www.php.net/license">PHP</license>
181
- <notes>A bugfix release:</notes>
182
- </release>
183
- <release>
184
- <version>
185
- <release>1.4.0a1</release>
186
- <api>1.3.1</api>
187
- </version>
188
- <stability>
189
- <release>alpha</release>
190
- <api>stable</api>
191
- </stability>
192
- <date>2007-03-08</date>
193
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
194
- <notes>* Changed License to BSD Style license, as that&apos;s what the code was since the beginning [cipri]
195
- * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri]
196
- * Fix Bug #3513: support of RFC2231 in header fields. [cipri]
197
- * Fix Bug #4696: addAttachment crash [cipri]
198
- * Fix Bug #5333: Only variables should be returned by reference; triggers notices since php 4.4.0 [cipri]
199
- * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring overload [cipri]
200
- * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri]
201
- * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri]
202
- * Fix Bug #8541: mimePart.php line delimiter is \r [cipri]
203
- * Fix Bug #9347: Notices about references [cweiske]
204
- * Fix Bug #9558: Broken multiline headers [cipri]
205
- * Fix Bug #9956: Notices being thrown [cipri]
206
- * Fix Bug #9976: Subject encoded twice [cipri]
207
- * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri]
208
- * Implement Feature #3636: Allow specification of charsets and encoding [cipri]
209
- * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri]
210
- * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri]
211
- * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri]
212
- * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri]
213
- * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri]</notes>
214
- </release>
215
- <release>
216
- <version>
217
- <release>1.4.0a2</release>
218
- <api>1.3.1</api>
219
- </version>
220
- <stability>
221
- <release>alpha</release>
222
- <api>stable</api>
223
- </stability>
224
- <date>2007-04-05</date>
225
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
226
- <notes>* Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows
227
- platform [cipri]
228
- * Fix Bug #9725: multipart/related &amp; alternative wrong order [cipri]
229
- * Fix Bug #10146: mbstring fails to recognize encodings. [cipri]
230
- * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri]
231
- * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri]
232
- * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]
233
- * Fix Bug #10596: Incorrect handling of text and html &apos;0&apos; bodies [cipri]</notes>
234
- </release>
235
- <release>
236
- <version>
237
- <release>1.4.0a3</release>
238
- <api>1.3.1</api>
239
- </version>
240
- <stability>
241
- <release>alpha</release>
242
- <api>stable</api>
243
- </stability>
244
- <date>2007-04-05</date>
245
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
246
- <notes>* Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri]
247
- * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]</notes>
248
- </release>
249
- <release>
250
- <version>
251
- <release>1.4.0RC1</release>
252
- <api>1.3.1</api>
253
- </version>
254
- <stability>
255
- <release>beta</release>
256
- <api>stable</api>
257
- </stability>
258
- <date>2007-04-12</date>
259
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
260
- <notes>* Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri]</notes>
261
- </release>
262
- <release>
263
- <version>
264
- <release>1.4.0RC2</release>
265
- <api>1.3.1</api>
266
- </version>
267
- <stability>
268
- <release>beta</release>
269
- <api>stable</api>
270
- </stability>
271
- <date>2007-04-22</date>
272
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
273
- <notes>* Fix Bug #10791: Unit tests fail [cipri]
274
- * Fix Bug #10792: No unit tests for recently fixed bugs [cipri]
275
- * Fix Bug #10793: Long headers don&apos;t get wrapped since fix for Bug #10298 [cipri]</notes>
276
- </release>
277
- <release>
278
- <version>
279
- <release>1.4.0RC3</release>
280
- <api>1.3.1</api>
281
- </version>
282
- <stability>
283
- <release>beta</release>
284
- <api>stable</api>
285
- </stability>
286
- <date>2007-04-24</date>
287
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
288
- <notes>* Fix Bug #10816: Unwanted linebreak at the end of output [cipri]</notes>
289
- </release>
290
- <release>
291
- <version>
292
- <release>1.4.0RC4</release>
293
- <api>1.3.1</api>
294
- </version>
295
- <stability>
296
- <release>beta</release>
297
- <api>stable</api>
298
- </stability>
299
- <date>2007-04-28</date>
300
- <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
301
- <notes>* Fix Bug #3513: support of RFC2231 in header fields. [cipri]
302
- * Fix Bug #10838: bad use of MIME encoding in header. [cipri]</notes>
303
- </release>
304
- <release>
305
- <version>
306
- <release>1.4.0</release>
307
- <api>1.3.1</api>
308
- </version>
309
- <stability>
310
- <release>stable</release>
311
- <api>stable</api>
312
- </stability>
313
- <date>2007-05-05</date>
314
- <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
315
- <notes>Release nots:
316
- * No more notices in PHP 5 /4.4.0.
317
- * Improved inline HTML image function.
318
- * Improved header encoding with foreign charsets.
319
- * Improved long header rendering.
320
- * More control over used Charsets and encoding schemes.
321
- * More configurable attachments and inline images.
322
- * Full RFC 2047 Support
323
- * Full RFC 2231 Support
324
- * Unit-tests
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
- Fixed bugs:
327
- * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri]
328
- * Fix Bug #3513: support of RFC2231 in header fields. [cipri]
329
- * Fix Bug #4696: addAttachment crash [cipri]
330
- * Fix Bug #5333: Only variables should be returned by reference; triggers notices since
331
- php 4.4.0 [cipri]
332
- * Fix Bug #5400: Do not return function reference [cipri]
333
- * Fix Bug #5710: Little reference bugs [cipri]
334
- * Fix Bug #5890: Only variable references should be returned by reference [cipri]
335
- * Fix Bug #6260: Just a notice with PHP5 [cipri]
336
- * Fix Bug #6261: php 5.1.1 upgrade [cipri]
337
- * Fix Bug #6663: Notice about reference passing [cipri]
338
- * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring
339
- overload [cipri]
340
- * Fix Bug #7713: PHP5 Notice: Only variable references should be returned by reference [cipri]
341
- * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri]
342
- * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri]
343
- * Fix Bug #8541: mimePart.php line delimiter is \r [cipri]
344
- * Fix Bug #8812: user header updates overwritten [cipri]
345
- * Fix Bug #9347: Notices about references [cweiske]
346
- * Fix Bug #9558: Broken multiline headers [cipri]
347
- * Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows
348
- platform [cipri]
349
- * Fix Bug #9725: multipart/related &amp; alternative wrong order [cipri]
350
- * Fix Bug #9956: Notices being thrown [cipri]
351
- * Fix Bug #9976: Subject encoded twice [cipri]
352
- * Fix Bug #10146: mbstring fails to recognize encodings. [cipri]
353
- * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri]
354
- * Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri]
355
- * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri]
356
- * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]
357
- * Fix Bug #10596: Incorrect handling of text and html &apos;0&apos; bodies [cipri]
358
- * Fix Bug #10791: Unit tests fail [cipri]
359
- * Fix Bug #10792: No unit tests for recently fixed bugs [cipri]
360
- * Fix Bug #10793: Long headers don&apos;t get wrapped since fix for Bug #10298 [cipri]
361
- * Fix Bug #10816: Unwanted linebreak at the end of output [cipri]
362
- * Fix Bug #10838: bad use of MIME encoding in header. [cipri]
363
- Implemented Features:
364
- * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri]
365
- * Implement Feature #3636: Allow specification of charsets and encoding [cipri]
366
- * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri]
367
- * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri]
368
- * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri]
369
- * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri]
370
- * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri]
371
- * Implement Feature #10604: Put an option to specify Content-Location in the header [cipri]</notes>
372
- </release>
373
- <release>
374
- <version>
375
- <release>1.5.0a1</release>
376
- <api>1.3.1</api>
377
- </version>
378
- <stability>
379
- <release>alpha</release>
380
- <api>stable</api>
381
- </stability>
382
- <date>2007-06-10</date>
383
- <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
384
- <notes>Split off mail_MimeDecode</notes>
385
- </release>
386
- <release>
387
- <version>
388
- <release>1.5.0RC1</release>
389
- <api>1.3.1</api>
390
- </version>
391
- <stability>
392
- <release>beta</release>
393
- <api>stable</api>
394
- </stability>
395
- <date>2007-06-10</date>
396
- <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
397
- <notes>Split off mail_MimeDecode</notes>
398
- </release>
399
- <release>
400
- <version>
401
- <release>1.5.0</release>
402
- <api>1.3.1</api>
403
- </version>
404
- <stability>
405
- <release>stable</release>
406
- <api>stable</api>
407
- </stability>
408
- <date>2007-06-17</date>
409
- <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
410
- <notes>Split off Mail_MimeDecode</notes>
411
- </release>
412
- <release>
413
- <version>
414
- <release>1.5.1</release>
415
- <api>1.3.1</api>
416
- </version>
417
- <stability>
418
- <release>stable</release>
419
- <api>stable</api>
420
- </stability>
421
- <date>2007-06-20</date>
422
- <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
423
- <notes>* Fix Bug #11344: Error at line 644 in mime.php [cipri]</notes>
424
- </release>
425
- </changelog>
 
426
  </package>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <package packagerversion="1.6.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
3
+ <name>Mail_Mime</name>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  <channel>pear.php.net</channel>
5
+ <summary>Mail_Mime provides classes to create mime messages.</summary>
6
+ <description>Mail_Mime provides classes to deal with the creation and manipulation of mime messages.
7
+ It allows people to create Email messages consisting of:
8
+ * Text Parts
9
+ * HTML Parts
10
+ * Inline HTML Images
11
+ * Attachments
12
+ * Attached messages
13
+
14
+ Starting with version 1.4.0, it also allows non US-ASCII chars in filenames, subjects, recipients, etc, etc.
15
+ </description>
16
+ <lead>
17
+ <name>Cipriano Groenendal</name>
18
+ <user>cipri</user>
19
+ <email>cipri@php.net</email>
20
+ <active>yes</active>
21
+ </lead>
22
+ <date>2007-06-21</date>
23
+ <time>21:10:11</time>
24
+ <version>
25
+ <release>1.5.2</release>
26
+ <api>1.3.1</api>
27
+ </version>
28
+ <stability>
29
+ <release>stable</release>
30
+ <api>stable</api>
31
+ </stability>
32
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
33
+ <notes>* Fix Bug #11381: domain name is attached to content-id, trailing greater-than sign is
34
+ not remove [cipri]
35
+ </notes>
36
+ <contents>
37
+ <dir name="/">
38
+ <file baseinstalldir="Mail" md5sum="a2899bc69329c9533205aeb4221ab775" name="scripts/phail.php" role="doc" />
39
+ <file baseinstalldir="Mail" md5sum="edd138f6c5497ae2b5d63620a67a931e" name="tests/class-filename.phpt" role="test" />
40
+ <file baseinstalldir="Mail" md5sum="494526cc12e4edec45e0207f569d57d9" name="tests/encoding_case.phpt" role="test" />
41
+ <file baseinstalldir="Mail" md5sum="1016a2a921d414f52fbc6d3a028945f4" name="tests/sleep_wakeup_EOL-bug3488-part1.phpt" role="test" />
42
+ <file baseinstalldir="Mail" md5sum="61c745f92e8162e6e2971464a15990d4" name="tests/sleep_wakeup_EOL-bug3488-part2.phpt" role="test" />
43
+ <file baseinstalldir="Mail" md5sum="494526cc12e4edec45e0207f569d57d9" name="tests/tabs_quoted_printable.phpt" role="test" />
44
+ <file baseinstalldir="Mail" md5sum="844305aaa9ca4820a1672ba6da0a94c7" name="tests/test_Bug_30_1.phpt" role="test" />
45
+ <file baseinstalldir="Mail" md5sum="2d0bd00382e3f9c5f2e3e9512b731d68" name="tests/test_Bug_30_2.phpt" role="test" />
46
+ <file baseinstalldir="Mail" md5sum="83d326b6ca7d9f704ff2544edeb601ab" name="tests/test_Bug_30_3.phpt" role="test" />
47
+ <file baseinstalldir="Mail" md5sum="c2ea41bc1d78cb2b88e4514d8044a98d" name="tests/test_Bug_30_4.phpt" role="test" />
48
+ <file baseinstalldir="Mail" md5sum="6af58588ed4e35df8845f6704d7384ba" name="tests/test_Bug_3513_1.phpt" role="test" />
49
+ <file baseinstalldir="Mail" md5sum="efaa5d82baea0b46560752817d455bf4" name="tests/test_Bug_3513_2.phpt" role="test" />
50
+ <file baseinstalldir="Mail" md5sum="27020435d9432ebece744308e803030f" name="tests/test_Bug_3513_3.phpt" role="test" />
51
+ <file baseinstalldir="Mail" md5sum="dc2b1be6fab962386f16f6d710cf2d0a" name="tests/test_Bug_7561_1.phpt" role="test" />
52
+ <file baseinstalldir="Mail" md5sum="cd9c56b628649f92f067920d2e8a6214" name="tests/test_Bug_8223_1.phpt" role="test" />
53
+ <file baseinstalldir="Mail" md5sum="51888d86ce4fb58fc89a366736f5910a" name="tests/test_Bug_8386_1.phpt" role="test" />
54
+ <file baseinstalldir="Mail" md5sum="440c46d4ea863539caec007af431b307" name="tests/test_Bug_8541_1.phpt" role="test" />
55
+ <file baseinstalldir="Mail" md5sum="a1f598cf82774fde322ac4f3f3a7e0be" name="tests/test_Bug_9558_1.phpt" role="test" />
56
+ <file baseinstalldir="Mail" md5sum="5adfb0668904b72d2c04073f55f8144c" name="tests/test_Bug_9722_1.phpt" role="test" />
57
+ <file baseinstalldir="Mail" md5sum="18160c212dd0042bf21eb703e58de9ce" name="tests/test_Bug_9725_1.phpt" role="test" />
58
+ <file baseinstalldir="Mail" md5sum="e07949f077db4cfeaad0bffe9d4d37da" name="tests/test_Bug_9976_1.phpt" role="test" />
59
+ <file baseinstalldir="Mail" md5sum="fcc6eeedeb8ae7ddcf1637c048ab7f93" name="tests/test_Bug_10298_1.phpt" role="test" />
60
+ <file baseinstalldir="Mail" md5sum="c64c1115b7fe7f3a8d8c6fd8f8d7c268" name="tests/test_Bug_10596_1.phpt" role="test" />
61
+ <file baseinstalldir="Mail" md5sum="0eacb8c485ade073b61fe2daeae3124f" name="tests/test_Bug_10816_1.phpt" role="test" />
62
+ <file baseinstalldir="Mail" md5sum="93a00275edb0d9e94364ae11175741d1" name="mime.php" role="php" />
63
+ <file baseinstalldir="Mail" md5sum="53aedbcc104a9bd15cf96e5511b6498b" name="mimePart.php" role="php" />
64
+ <file baseinstalldir="Mail" md5sum="194810c478066eaeb28f51116b88e25a" name="xmail.dtd" role="data" />
65
+ <file baseinstalldir="Mail" md5sum="61cea06fb6b4bd3a4b5e2d37384e14a9" name="xmail.xsl" role="data" />
66
+ </dir>
67
+ </contents>
68
+ <dependencies>
69
+ <required>
70
+ <php>
71
+ <min>4.0.0</min>
72
+ </php>
73
+ <pearinstaller>
74
+ <min>1.6.0</min>
75
+ </pearinstaller>
76
+ <subpackage>
77
+ <name>Mail_mimeDecode</name>
78
+ <channel>pear.php.net</channel>
79
+ </subpackage>
80
+ </required>
81
+ </dependencies>
82
+ <phprelease />
83
+ <changelog>
84
+ <release>
85
+ <version>
86
+ <release>1.0</release>
87
+ <api>1.0</api>
88
+ </version>
89
+ <stability>
90
+ <release>stable</release>
91
+ <api>stable</api>
92
+ </stability>
93
+ <date>2001-12-28</date>
94
+ <license uri="http://www.php.net/license">PHP</license>
95
+ <notes>This is the initial release of the Mime_Mail package.</notes>
96
+ </release>
97
+ <release>
98
+ <version>
99
+ <release>1.1</release>
100
+ <api>1.1</api>
101
+ </version>
102
+ <stability>
103
+ <release>stable</release>
104
+ <api>stable</api>
105
+ </stability>
106
+ <date>2002-04-03</date>
107
+ <license uri="http://www.php.net/license">PHP</license>
108
+ <notes>This is a maintenance release with various bugfixes and minor enhancements.</notes>
109
+ </release>
110
+ <release>
111
+ <version>
112
+ <release>1.2</release>
113
+ <api>1.2</api>
114
+ </version>
115
+ <stability>
116
+ <release>stable</release>
117
+ <api>stable</api>
118
+ </stability>
119
+ <date>2002-07-14</date>
120
+ <license uri="http://www.php.net/license">PHP</license>
121
+ <notes>o Added header encoding
122
+ o Altered mimePart to put boundary parameter on newline
123
+ o Changed addFrom() to setFrom()
124
+ o Added setSubject()
125
+ o Made mimePart inherit crlf setting from mime
126
+ </notes>
127
+ </release>
128
+ <release>
129
+ <version>
130
+ <release>1.2.1</release>
131
+ <api>1.2.1</api>
132
+ </version>
133
+ <stability>
134
+ <release>stable</release>
135
+ <api>stable</api>
136
+ </stability>
137
+ <date>2002-07-27</date>
138
+ <license uri="http://www.php.net/license">PHP</license>
139
+ <notes>o License change
140
+ o Applied a few changes From Ilia Alshanetsky
141
+ </notes>
142
+ </release>
143
+ <release>
144
+ <version>
145
+ <release>1.3.0RC1</release>
146
+ <api>1.3.0RC1</api>
147
+ </version>
148
+ <stability>
149
+ <release>beta</release>
150
+ <api>beta</api>
151
+ </stability>
152
+ <date>2005-03-20</date>
153
+ <license uri="http://www.php.net/license">PHP</license>
154
+ <notes>o First release in over 2.5 years (!)
155
+ o MANY bugfixes (see the bugtracker)
156
+ o added a few tests
157
+ </notes>
158
+ </release>
159
+ <release>
160
+ <version>
161
+ <release>1.3.0</release>
162
+ <api>1.3.0</api>
163
+ </version>
164
+ <stability>
165
+ <release>stable</release>
166
+ <api>stable</api>
167
+ </stability>
168
+ <date>2005-04-01</date>
169
+ <license uri="http://www.php.net/license">PHP</license>
170
+ <notes>o First (stable) release in over 2.5 years (!)
171
+ o MANY bugfixes (see the bugtracker)
172
+ o added a few tests
173
+ o one small fix after RC1 (bug #3940)
174
+ </notes>
175
+ </release>
176
+ <release>
177
+ <version>
178
+ <release>1.3.1</release>
179
+ <api>1.3.1</api>
180
+ </version>
181
+ <stability>
182
+ <release>stable</release>
183
+ <api>stable</api>
184
+ </stability>
185
+ <date>2005-07-13</date>
186
+ <license uri="http://www.php.net/license">PHP</license>
187
+ <notes>A bugfix release:</notes>
188
+ </release>
189
+ <release>
190
+ <version>
191
+ <release>1.4.0a1</release>
192
+ <api>1.3.1</api>
193
+ </version>
194
+ <stability>
195
+ <release>alpha</release>
196
+ <api>stable</api>
197
+ </stability>
198
+ <date>2007-03-08</date>
199
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
200
+ <notes>* Changed License to BSD Style license, as that&apos;s what the code was since the beginning [cipri]
201
+ * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri]
202
+ * Fix Bug #3513: support of RFC2231 in header fields. [cipri]
203
+ * Fix Bug #4696: addAttachment crash [cipri]
204
+ * Fix Bug #5333: Only variables should be returned by reference; triggers notices since php 4.4.0 [cipri]
205
+ * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring overload [cipri]
206
+ * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri]
207
+ * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri]
208
+ * Fix Bug #8541: mimePart.php line delimiter is \r [cipri]
209
+ * Fix Bug #9347: Notices about references [cweiske]
210
+ * Fix Bug #9558: Broken multiline headers [cipri]
211
+ * Fix Bug #9956: Notices being thrown [cipri]
212
+ * Fix Bug #9976: Subject encoded twice [cipri]
213
+ * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri]
214
+ * Implement Feature #3636: Allow specification of charsets and encoding [cipri]
215
+ * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri]
216
+ * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri]
217
+ * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri]
218
+ * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri]
219
+ * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri]
220
+ </notes>
221
+ </release>
222
+ <release>
223
+ <version>
224
+ <release>1.4.0a2</release>
225
+ <api>1.3.1</api>
226
+ </version>
227
+ <stability>
228
+ <release>alpha</release>
229
+ <api>stable</api>
230
+ </stability>
231
+ <date>2007-04-05</date>
232
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
233
+ <notes>* Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows
234
+ platform [cipri]
235
+ * Fix Bug #9725: multipart/related &amp; alternative wrong order [cipri]
236
+ * Fix Bug #10146: mbstring fails to recognize encodings. [cipri]
237
+ * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri]
238
+ * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri]
239
+ * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]
240
+ * Fix Bug #10596: Incorrect handling of text and html &apos;0&apos; bodies [cipri]
241
+ </notes>
242
+ </release>
243
+ <release>
244
+ <version>
245
+ <release>1.4.0a3</release>
246
+ <api>1.3.1</api>
247
+ </version>
248
+ <stability>
249
+ <release>alpha</release>
250
+ <api>stable</api>
251
+ </stability>
252
+ <date>2007-04-05</date>
253
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
254
+ <notes>* Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri]
255
+ * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]
256
+ </notes>
257
+ </release>
258
+ <release>
259
+ <version>
260
+ <release>1.4.0RC1</release>
261
+ <api>1.3.1</api>
262
+ </version>
263
+ <stability>
264
+ <release>beta</release>
265
+ <api>stable</api>
266
+ </stability>
267
+ <date>2007-04-12</date>
268
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
269
+ <notes>* Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri]</notes>
270
+ </release>
271
+ <release>
272
+ <version>
273
+ <release>1.4.0RC2</release>
274
+ <api>1.3.1</api>
275
+ </version>
276
+ <stability>
277
+ <release>beta</release>
278
+ <api>stable</api>
279
+ </stability>
280
+ <date>2007-04-22</date>
281
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
282
+ <notes>* Fix Bug #10791: Unit tests fail [cipri]
283
+ * Fix Bug #10792: No unit tests for recently fixed bugs [cipri]
284
+ * Fix Bug #10793: Long headers don&apos;t get wrapped since fix for Bug #10298 [cipri]
285
+ </notes>
286
+ </release>
287
+ <release>
288
+ <version>
289
+ <release>1.4.0RC3</release>
290
+ <api>1.3.1</api>
291
+ </version>
292
+ <stability>
293
+ <release>beta</release>
294
+ <api>stable</api>
295
+ </stability>
296
+ <date>2007-04-24</date>
297
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
298
+ <notes>* Fix Bug #10816: Unwanted linebreak at the end of output [cipri]</notes>
299
+ </release>
300
+ <release>
301
+ <version>
302
+ <release>1.4.0RC4</release>
303
+ <api>1.3.1</api>
304
+ </version>
305
+ <stability>
306
+ <release>beta</release>
307
+ <api>stable</api>
308
+ </stability>
309
+ <date>2007-04-28</date>
310
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">bsd style</license>
311
+ <notes>* Fix Bug #3513: support of RFC2231 in header fields. [cipri]
312
+ * Fix Bug #10838: bad use of MIME encoding in header. [cipri]
313
+ </notes>
314
+ </release>
315
+ <release>
316
+ <version>
317
+ <release>1.4.0</release>
318
+ <api>1.3.1</api>
319
+ </version>
320
+ <stability>
321
+ <release>stable</release>
322
+ <api>stable</api>
323
+ </stability>
324
+ <date>2007-05-05</date>
325
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
326
+ <notes>Release nots:
327
+ * No more notices in PHP 5 /4.4.0.
328
+ * Improved inline HTML image function.
329
+ * Improved header encoding with foreign charsets.
330
+ * Improved long header rendering.
331
+ * More control over used Charsets and encoding schemes.
332
+ * More configurable attachments and inline images.
333
+ * Full RFC 2047 Support
334
+ * Full RFC 2231 Support
335
+ * Unit-tests
336
 
337
+ Fixed bugs:
338
+ * Fix Bug #30: Mail_Mime: _encodeHeaders is not RFC-2047 compliant. [cipri]
339
+ * Fix Bug #3513: support of RFC2231 in header fields. [cipri]
340
+ * Fix Bug #4696: addAttachment crash [cipri]
341
+ * Fix Bug #5333: Only variables should be returned by reference; triggers notices since
342
+ php 4.4.0 [cipri]
343
+ * Fix Bug #5400: Do not return function reference [cipri]
344
+ * Fix Bug #5710: Little reference bugs [cipri]
345
+ * Fix Bug #5890: Only variable references should be returned by reference [cipri]
346
+ * Fix Bug #6260: Just a notice with PHP5 [cipri]
347
+ * Fix Bug #6261: php 5.1.1 upgrade [cipri]
348
+ * Fix Bug #6663: Notice about reference passing [cipri]
349
+ * Fix Bug #7561: Mail_mimePart::_quotedPrintableEncode() misbehavior with mbstring
350
+ overload [cipri]
351
+ * Fix Bug #7713: PHP5 Notice: Only variable references should be returned by reference [cipri]
352
+ * Fix Bug #8223: Incorrectly encoded quoted-printable headers [cipri]
353
+ * Fix Bug #8386: HTML body not correctly encoded if attachments present [cipri]
354
+ * Fix Bug #8541: mimePart.php line delimiter is \r [cipri]
355
+ * Fix Bug #8812: user header updates overwritten [cipri]
356
+ * Fix Bug #9347: Notices about references [cweiske]
357
+ * Fix Bug #9558: Broken multiline headers [cipri]
358
+ * Fix Bug #9722: _quotedPrintableEncode does not encode dot at start of line on Windows
359
+ platform [cipri]
360
+ * Fix Bug #9725: multipart/related &amp; alternative wrong order [cipri]
361
+ * Fix Bug #9956: Notices being thrown [cipri]
362
+ * Fix Bug #9976: Subject encoded twice [cipri]
363
+ * Fix Bug #10146: mbstring fails to recognize encodings. [cipri]
364
+ * Fix Bug #10158: Inline images not displayed on Mozilla Thunderbird [cipri]
365
+ * Fix Bug #10232: Gmail creates double line break when \r\n is used [cipri]
366
+ * Fix Bug #10298: Mail_mime, double Quotes and Specialchars in from and to Adress [cipri]
367
+ * Fix Bug #10306: Strings with Double Quotes get encoded wrongly [cipri]
368
+ * Fix Bug #10596: Incorrect handling of text and html &apos;0&apos; bodies [cipri]
369
+ * Fix Bug #10791: Unit tests fail [cipri]
370
+ * Fix Bug #10792: No unit tests for recently fixed bugs [cipri]
371
+ * Fix Bug #10793: Long headers don&apos;t get wrapped since fix for Bug #10298 [cipri]
372
+ * Fix Bug #10816: Unwanted linebreak at the end of output [cipri]
373
+ * Fix Bug #10838: bad use of MIME encoding in header. [cipri]
374
+ Implemented Features:
375
+ * Implement Feature #2952: Mail_mime::headers() saves extra headers [cipri]
376
+ * Implement Feature #3636: Allow specification of charsets and encoding [cipri]
377
+ * Implement Feature #4057: Mail_Mime: Add name parameter for Content-Type [cipri]
378
+ * Implement Feature #4504: addHTMLImage does not work in cases when filename contains a path [cipri]
379
+ * Implement Feature #5837: Mail_Mime: Build message for Net_SMTP [cipri]
380
+ * Implement Feature #5934: Mail_Mime: choice for content disposition [cipri]
381
+ * Implement Feature #6568: Mail_Mime: inline images referenced in CSS definitions not replaced. [cipri]
382
+ * Implement Feature #10604: Put an option to specify Content-Location in the header [cipri]
383
+ </notes>
384
+ </release>
385
+ <release>
386
+ <version>
387
+ <release>1.5.0a1</release>
388
+ <api>1.3.1</api>
389
+ </version>
390
+ <stability>
391
+ <release>alpha</release>
392
+ <api>stable</api>
393
+ </stability>
394
+ <date>2007-06-10</date>
395
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
396
+ <notes>Split off mail_MimeDecode</notes>
397
+ </release>
398
+ <release>
399
+ <version>
400
+ <release>1.5.0RC1</release>
401
+ <api>1.3.1</api>
402
+ </version>
403
+ <stability>
404
+ <release>beta</release>
405
+ <api>stable</api>
406
+ </stability>
407
+ <date>2007-06-10</date>
408
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
409
+ <notes>Split off mail_MimeDecode</notes>
410
+ </release>
411
+ <release>
412
+ <version>
413
+ <release>1.5.0</release>
414
+ <api>1.3.1</api>
415
+ </version>
416
+ <stability>
417
+ <release>stable</release>
418
+ <api>stable</api>
419
+ </stability>
420
+ <date>2007-06-17</date>
421
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
422
+ <notes>Split off Mail_MimeDecode</notes>
423
+ </release>
424
+ <release>
425
+ <version>
426
+ <release>1.5.1</release>
427
+ <api>1.3.1</api>
428
+ </version>
429
+ <stability>
430
+ <release>stable</release>
431
+ <api>stable</api>
432
+ </stability>
433
+ <date>2007-06-20</date>
434
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD Style</license>
435
+ <notes>* Fix Bug #11344: Error at line 644 in mime.php [cipri]</notes>
436
+ </release>
437
+ </changelog>
438
  </package>
postie-functions.php CHANGED
@@ -1,26 +1,55 @@
1
  <?php
2
- $revisions= WP_POST_REVISIONS;
3
- define('WP_POST_REVISIONS', false);
4
- //define('POSTIE_DEBUG', true);
5
- if (!ini_get('safe_mode')) {
6
- $original_mem_limit = ini_get('memory_limit');
7
- ini_set('memory_limit', -1);
8
- ini_set('max_execution_time', 300);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
 
11
  //include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR."wp-admin" . DIRECTORY_SEPARATOR . "upgrade-functions.php");
12
  /*
13
- $Id: postie-functions.php 458511 2011-11-02 04:01:06Z robfelty $
14
- */
15
 
16
- /*TODO
17
  * html purify
18
  * USE built-in php message decoding to improve speed
19
  * Add custom fields
20
  * support for flexible upload plugin
21
  * iso 8859-2 support
22
  * add private post function
23
- http://forum.robfelty.com/topic/how-to-private-posts-from-postie?replies=2#post-1515
24
  * category per e-mail address
25
  */
26
 
@@ -28,212 +57,207 @@ $Id: postie-functions.php 458511 2011-11-02 04:01:06Z robfelty $
28
 
29
  /* this function is necessary for wildcard matching on non-posix systems */
30
  if (!function_exists('fnmatch')) {
31
- function fnmatch($pattern, $string) {
32
- $pattern = strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' =>
33
- '.', '\[' => '[', '\]' => ']'));
34
- return @preg_match(
35
- '/^' . strtr(addcslashes($pattern, '/\\.+^$(){}=!<>|'),
36
- array('*' => '.*', '?' => '.?')) . '$/i', $string
37
- );
38
- }
 
39
  }
40
 
41
  /**
42
- * This is the main handler for all of the processing
43
- */
44
- function PostEmail($poster,$mimeDecodedEmail,$config) {
45
- extract($config);
46
- $post_to_db=true;
47
-
48
- $attachments = array(
49
- "html" => array(), //holds the html for each image
50
- "cids" => array(), //holds the cids for HTML email
51
- "image_files" => array() //holds the files for each image
52
- );
53
- print("<p>Message Id is :" .
54
- htmlentities($mimeDecodedEmail->headers["message-id"]) . "</p><br/>\n");
55
- if ( defined ( 'POSTIE_DEBUG' ) ){
56
- foreach($mimeDecodedEmail->parts as $parts) {
57
- print("<p>".$parts->ctype_primary ." ".$parts->ctype_secondary) ."</p>\n";
58
- }
59
- echo "<p>Email is:</p>";
60
- var_dump($mimeDecodedEmail);
61
- }
62
- FilterTextParts($mimeDecodedEmail, $prefer_text_type);
63
- $tmpPost=array('post_title'=> 'tmptitle',
64
- 'post_content'=>'tmpPost');
65
- /* in order to do attachments correctly, we need to associate the
66
- attachments with a post. So we add the post here, then update it
67
- */
68
- $post_id = wp_insert_post($tmpPost);
69
- if( defined( 'POSTIE_DEBUG' ) ) {
70
- echo "the id is $post_id\n";
71
- }
72
- $content = GetContent($mimeDecodedEmail,$attachments,$post_id, $poster, $config);
73
- if( defined( 'POSTIE_DEBUG' ) ) {
74
- echo "the content is $content\n";
75
- }
76
- $subject = GetSubject($mimeDecodedEmail,$content, $config);
77
- if( defined( 'POSTIE_DEBUG' ) ) {
78
- echo "the subject is $subject, right after calling GetSubject\n";
79
- }
80
- $customImages = SpecialMessageParsing($content,$attachments, $config);
81
- $post_excerpt = GetPostExcerpt($content, $filternewlines,
82
- $convertnewline);
83
- $postAuthorDetails=getPostAuthorDetails($subject,$content,
84
- $mimeDecodedEmail);
85
- $message_date = NULL;
86
- if (array_key_exists("date",$mimeDecodedEmail->headers)
87
- && !empty($mimeDecodedEmail->headers["date"])) {
88
- $message_date=HandleMessageEncoding(
89
- $mimeDecodedEmail->headers["content-transfer-encoding"],
90
- $mimeDecodedEmail->ctype_parameters["charset"],
91
- $mimeDecodedEmail->headers["date"], $message_encoding, $message_dequote);
92
- //$message_date = $mimeDecodedEmail->headers['date'];
93
- }
94
- list($post_date,$post_date_gmt, $delay) = DeterminePostDate($content,
95
- $message_date,$time_offset);
96
- ubb2HTML($content);
97
-
98
- if ($converturls)
99
- $content=clickableLink($content, $shortcode);
100
-
101
- //$content = FixEmailQuotes($content);
102
-
103
- $id=checkReply($subject);
104
- $post_categories = GetPostCategories($subject,
105
- $default_post_category);
106
- $post_tags = postie_get_tags($content, $default_post_tags);
107
- $comment_status = AllowCommentsOnPost($content);
108
-
109
- if ((empty($id) || is_null($id))) {
110
- $id=$post_id;
111
- $isReply=false;
112
- if ($add_meta=='yes') {
113
- if ($wrap_pre=='yes') {
114
- $content = $postAuthorDetails['content'] . "<pre>\n" . $content . "</pre>\n";
115
- $content = "<pre>\n" . $content . "</pre>\n";
116
- } else {
117
- $content = $postAuthorDetails['content'] . $content;
118
- $content = $content;
119
- }
120
- } else {
121
- if ($wrap_pre=='yes') {
122
- $content = "<pre>\n" . $content . "</pre>\n";
123
- }
124
  }
125
- } else {
126
- $isReply=true;
127
- // strip out quoted content
128
- $lines=explode("\n",$content);
129
- //$lines=preg_split('/([\r\n]|<br \/>)/',$content);
130
- $newContents='';
131
- foreach ($lines as $line) {
132
- //$match=preg_match("/^>.*/i",$line);
133
- //echo "line=$line, match=$match";
134
- if (preg_match("/^>.*/i",$line)==0 &&
135
- preg_match("/^(from|subject|to|date):.*?/i",$line)==0 &&
136
- preg_match("/^-+.*?(from|subject|to|date).*?/i",$line)==0 &&
137
- preg_match("/^on.*?wrote:$/i",$line)==0 &&
138
- preg_match("/^-+\s*forwarded\s*message\s*-+/i",$line)==0) {
139
- $newContents.="$line\n";
140
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
142
- $content=$newContents;
143
- wp_delete_post($post_id);
144
- }
145
- if ($filternewlines)
146
- $content = FilterNewLines($content, $convertnewline);
147
-
148
-
149
- if ($delay!=0 && $post_status=='publish') {
150
- $post_status='future';
151
- } else {
152
- $post_status=$post_status;
153
- }
154
- // DEBUG
155
- $details = array(
156
- 'post_author' => $poster,
157
- 'comment_author' => $postAuthorDetails['author'],
158
- 'comment_author_url' => $postAuthorDetails['comment_author_url'],
159
- 'user_ID' => $postAuthorDetails['user_ID'],
160
- 'email_author' => $postAuthorDetails['email'],
161
- 'post_date' => $post_date,
162
- // 'post_date_gmt' => $post_date_gmt,
163
- // 'post_content' => apply_filters('content_save_pre',$content),
164
- 'post_content' => $content,
165
- 'post_title' => $subject,
166
- // 'post_modified' => $post_date,
167
- // 'post_modified_gmt' => $post_date_gmt,
168
- 'ping_status' => get_option('default_ping_status'),
169
- 'post_category' => $post_categories,
170
- 'tags_input' => $post_tags,
171
- 'comment_status' => $comment_status,
172
- 'post_name' => sanitize_title($subject),
173
- 'post_excerpt' => $post_excerpt,
174
- 'ID' => $id,
175
- 'customImages' => $customImages,
176
- 'post_status' => $post_status
177
- );
178
- $details = apply_filters('postie_post', $details);
179
- if ( empty( $details ) ) {
180
- // It is possible that the filter has removed the post, in which case, it should not be posted.
181
- // And if we created a placeholder post (because this was not a reply to an existing post),
182
- // then it should be removed
183
- if ( !$is_reply ) {
184
- wp_delete_post($post_id);
185
- }
186
- } else {
187
- DisplayEmailPost($details);
188
- PostToDB($details,$isReply, $post_to_db,
189
- $custom_image_field);
190
- if ($confirmation_email!='') {
191
- if ($confirmation_email=='sender') {
192
- $recipients = array($postAuthorDetails['email']);
193
- } elseif ($confirmation_email=='admin') {
194
- $recipients = array(get_option("admin_email"));
195
- } elseif ($confirmation_email=='both') {
196
- $recipients = array($postAuthorDetails['email'],
197
- get_option("admin_email"));
198
- }
199
- MailToRecipients($mimeDecodedEmail, false,
200
- $recipients, false, false);
201
  }
202
- }
 
203
  }
204
- /** FUNCTIONS **/
205
 
 
 
 
 
206
 
207
- function clickableLink($text, $shortcode=false) {
208
- # this functions deserves credit to the fine folks at phpbb.com
209
- # It turns urls into links, and video urls into embedded players
210
 
211
- $text = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1:",
212
- $text);
213
-
214
- // pad it with a space so we can match things at the start of the 1st line.
215
- $ret = ' ' . $text;
216
- if (strpos($ret, 'youtube') !== false) {
217
- // try to embed youtube videos
218
- $youtube="#(^|[\n ]|>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9-]+).*?([ \n]|$|<)#is";
219
- #$youtube="#(^|[\n ]|<p[^<]*>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9]+).*?([ \n]|$|</p>)#is";
220
- if ($shortcode) {
221
- $youtube_replace= "\\1[youtube \\3]\\4";
222
- } else {
223
- $youtube_replace= "\\1<embed width='425' height='344' allowfullscreen='true' allowscriptaccess='always' type='application/x-shockwave-flash' src=\"http://www.youtube.com/v/\\3&hl=en&fs=1\" />\\4";
224
  }
225
- $ret = preg_replace($youtube,$youtube_replace, $ret);
226
- }
227
 
228
- if (strpos($ret, 'vimeo') !== false) {
229
- // try to embed vimeo videos
230
  # : http://vimeo.com/6348141
231
- $vimeo="#(^|[\n ]|>)[\w]+?://(www\.)?vimeo\.com/([_a-zA-Z0-9-]+).*?([ \n]|$|<)#is";
232
- #$youtube="#(^|[\n ]|<p[^<]*>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9]+).*?([ \n]|$|</p>)#is";
233
- if ($shortcode) {
234
- $vimeo_replace= "\\1[vimeo \\3]\\4";
235
- } else {
236
- $vimeo_replace = "\\1<object width='400' height='300'><param name='allowfullscreen'
237
  value='true' /><param name='allowscriptaccess' value='always' /><param
238
  name='movie'
239
  value='http://vimeo.com/moogaloop.swf?clip_id=\\3&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1'
@@ -241,267 +265,255 @@ function clickableLink($text, $shortcode=false) {
241
  src='http://vimeo.com/moogaloop.swf?clip_id=\\3&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1'
242
  type='application/x-shockwave-flash' allowfullscreen='true'
243
  allowscriptaccess='always' width='400' height='300'></embed></object>\\4";
244
- //$vimeo_replace= "\\1<embed width='425' height='344' allowfullscreen='true' allowscriptaccess='always' type='application/x-shockwave-flash' src=\"http://www.youtube.com/v/\\3&hl=en&fs=1\" />\\4";
245
- }
246
- $ret = preg_replace($vimeo,$vimeo_replace, $ret);
247
- }
248
-
249
- // matches an "xxxx://yyyy" URL at the start of a line, or after a space.
250
- // xxxx can only be alpha characters.
251
- // yyyy is anything up to the first space, newline, comma, double quote or <
252
- $ret = preg_replace("#(^|[\n ])<?([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)>?#is",
253
- "\\1<a href=\"\\2\" >\\2</a>", $ret);
254
-
255
- // matches a "www|ftp.xxxx.yyyy[/zzzz]" kinda lazy URL thing
256
- // Must contain at least 2 dots. xxxx contains either alphanum, or "-"
257
- // zzzz is optional.. will contain everything up to the first space, newline,
258
- // comma, double quote or <.
259
- $ret = preg_replace("#(^|[\n ])<?((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)>?#is",
260
- "\\1<a href=\"http://\\2\" >\\2</a>", $ret);
261
-
262
- // matches an email@domain type address at the start of a line, or after a space.
263
- // Note: Only the followed chars are valid; alphanums, "-", "_" and or ".".
264
- $ret = preg_replace(
265
- "#(^|[\n ])([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i",
266
- "\\1<a href=\"mailto:\\2@\\3\">\\2@\\3</a>", $ret);
267
- // Remove our padding..
268
- $ret = substr($ret, 1);
269
- return $ret;
270
- }
271
-
272
- function getPostAuthorDetails(&$subject,&$content,&$mimeDecodedEmail) {
273
- /* we check whether or not the e-mail is a forwards or a redirect. If it is
274
- * a fwd, then we glean the author details from the body of the post.
275
- * Otherwise we get them from the headers
276
- */
277
- global $wpdb;
278
- // see if subject starts with Fwd:
279
- if (preg_match("/(^Fwd:) (.*)/", $subject, $matches)) {
280
- $subject=trim($matches[2]);
281
- if (preg_match("/\nfrom:(.*?)\n/i",$content,$matches)) {
282
- $theAuthor=GetNameFromEmail($matches[1]);
283
- $mimeDecodedEmail->headers['from']=$theAuthor;
284
- }
285
- if (preg_match("/\ndate:(.*?)\n/i",$content,$matches)) {
286
- $theDate=$matches[1];
287
- $mimeDecodedEmail->headers['date']=$theDate;
288
- }
289
- } else {
290
- $theDate=$mimeDecodedEmail->headers['date'];
291
- $theEmail = RemoveExtraCharactersInEmailAddress(trim(
292
- $mimeDecodedEmail->headers["from"]));
293
- $regAuthor=get_user_by('email', $theEmail);
294
- if ($regAuthor) {
295
- $theAuthor=$regAuthor->user_login;
296
- $theUrl=$regAuthor->user_url;
297
- $theID= $regAuthor->ID;
298
  } else {
299
- $theAuthor=GetNameFromEmail($mimeDecodedEmail->headers['from']);
300
- $theUrl='';
301
- $theID='';
302
- }
303
- }
304
- // now get rid of forwarding info in the content
305
- $lines=preg_split("/\r\n/",$content);
306
- $newContents='';
307
- foreach ($lines as $line) {
308
- if (preg_match("/^(from|subject|to|date):.*?/i",$line,$matches)==0 &&
309
- // preg_match("/^$/i",$line,$matches)==0 &&
310
- preg_match("/^-+\s*forwarded\s*message\s*-+/i",$line,$matches)==0) {
311
- $newContents.=preg_replace("/\r/","",$line) . "\n" ;
312
- }
313
- }
314
- $content=$newContents;
315
- $theDetails=array(
316
- 'content' =>"<div class='postmetadata alt'>On $theDate, $theAuthor" .
317
- " posted:</div>",
318
- 'emaildate' => $theDate,
319
- 'author' => $theAuthor,
320
- 'comment_author_url' => $theUrl,
321
- 'user_ID' => $theID,
322
- 'email' => $theEmail
323
- );
324
- return($theDetails);
 
 
 
 
 
 
 
 
 
325
  }
326
 
327
  function checkReply(&$subject) {
328
- /* we check whether or not the e-mail is a reply to a previously
329
- * published post. First we check whether it starts with Re:, and then
330
- * we see if the remainder matches an already existing post. If so,
331
- * then we add that post id to the details array, which will cause the
332
- * existing post to be overwritten, instead of a new one being
333
- * generated
334
- */
335
-
336
- global $wpdb;
337
- // see if subject starts with Re:
338
- if (preg_match("/(^Re:) (.*)/i", $subject, $matches)) {
339
- $subject=trim($matches[2]);
340
- // strip out category info into temporary variable
341
- $tmpSubject=$subject;
342
- if ( preg_match('/(.+): (.*)/', $tmpSubject, $matches)) {
343
- $tmpSubject = trim($matches[2]);
344
- $matches[1] = array($matches[1]);
345
- }
346
- else if (preg_match_all('/\[(.[^\[]*)\]/', $tmpSubject, $matches)) {
347
- preg_match("/](.[^\[]*)$/",$tmpSubject,$tmpSubject_matches);
348
- $tmpSubject = trim($tmpSubject_matches[1]);
349
- }
350
- else if ( preg_match_all('/-(.[^-]*)-/', $tmpSubject, $matches) ) {
351
- preg_match("/-(.[^-]*)$/",$tmpSubject,$tmpSubject_matches);
352
- $tmpSubject = trim($tmpSubject_matches[1]);
353
- }
354
- $checkExistingPostQuery= "SELECT ID FROM $wpdb->posts WHERE
355
  '$tmpSubject' = post_title";
356
- if ($id=$wpdb->get_var($wpdb->prepare($checkExistingPostQuery))) {
357
- if (is_array($id)) {
358
- $id=$id[count($id)-1];
359
- }
360
- } else {
361
- $id=NULL;
 
362
  }
363
- }
364
- return($id);
365
  }
366
 
367
  function postie_read_me() {
368
- include(POSTIE_ROOT . DIRECTORY_SEPARATOR. "postie_read_me.php");
369
  }
 
370
  /**
371
- * This sets up the configuration menu
372
- */
373
  function PostieMenu() {
374
- if( function_exists('add_options_page') ) {
375
- if (current_user_can('manage_options')) {
376
- add_options_page("Postie", "Postie" ,
377
- 0, POSTIE_ROOT . "/postie.php", "ConfigurePostie");
378
  }
379
- }
380
  }
 
381
  /**
382
- * This handles actually showing the form
383
- */
384
  function ConfigurePostie() {
385
- include(POSTIE_ROOT . DIRECTORY_SEPARATOR. "config_form.php");
386
  }
387
 
388
  /**
389
- * This function handles determining the protocol and fetching the mail
390
- * @return array
391
- */
392
- function FetchMail($server=NULL, $port=NULL, $email=NULL, $password=NULL,
393
- $protocol=NULL, $offset=NULL, $test=NULL, $deleteMessages=true) {
394
- $emails = array();
395
- if (!$server || !$port || !$email) {
396
- die("Missing Configuration For Mail Server\n");
397
- }
398
- if ($server == "pop.gmail.com") {
399
- print("\nMAKE SURE POP IS TURNED ON IN SETTING AT Gmail\n");
400
- }
401
- switch ( strtolower($protocol) ) {
402
- case 'smtp': //direct
403
- $fd = fopen("php://stdin", "r");
404
- $input = "";
405
- while (!feof($fd)) {
406
- $input .= fread($fd, 1024);
407
- }
408
- fclose($fd);
409
- $emails[0] = $input;
410
- break;
411
- case 'imap':
412
- case 'imap-ssl':
413
- case 'pop3-ssl':
414
- HasIMAPSupport(false);
415
- if ($test) {
416
- $emails = TestIMAPMessageFetch();
417
- } else {
418
- $emails = IMAPMessageFetch($server, $port, $email,
419
- $password, $protocol, $offset, $test, $deleteMessages);
420
- }
421
- break;
422
- case 'pop3':
423
- default:
424
- if ($test) {
425
- $emails = TestPOP3MessageFetch();
426
- } else {
427
- $emails =POP3MessageFetch ($server, $port, $email,
428
- $password, $protocol, $offset, $test, $deleteMessages);
429
- }
430
- }
431
- if (!$emails)
432
- die("\n" . __('There does not seem to be any new mail.', 'postie') . "\n");
433
- return($emails);
434
  }
435
- /**
436
- *Handles fetching messages from an imap server
437
- */
438
- function TestIMAPMessageFetch ( ) {
439
- print("**************RUNING IN TESTING MODE************\n");
440
- $config = get_postie_config();
441
- extract( $config );
442
- $email = $test_email_account;
443
- $password = $test_email_password;
444
- return(IMAPMessageFetch($mail_server, $mail_server_port,
445
- $email, $password, $input_protocol,
446
- $time_offset, $test_email));
447
 
 
 
 
 
 
 
 
 
 
 
448
  }
 
449
  /**
450
- *Handles fetching messages from an imap server
451
- */
452
- function IMAPMessageFetch ($server=NULL, $port=NULL, $email=NULL,
453
- $password=NULL, $protocol=NULL, $offset=NULL, $test=NULL,
454
- $deleteMessages=true) {
455
  require_once("postieIMAP.php");
456
 
457
  $mail_server = &PostieIMAP::Factory($protocol);
458
  print("\nConnecting to $server:$port ($protocol) \n");
459
- if (!$mail_server->connect($server, $port,$email,$password)) {
460
  print("Mail Connection Time Out\n
461
  Common Reasons: \n
462
  Server Down \n
463
  Network Issue \n
464
  Port/Protocol MisMatch \n
465
  ");
466
- die("The Server said:".$mail_server->error()."\n");
467
  }
468
  $msg_count = $mail_server->getNumberOfMessages();
469
  $emails = array();
470
- // loop through messages
471
- for ($i=1; $i <= $msg_count; $i++) {
472
- $emails[$i] = $mail_server->fetchEmail($i);
 
 
 
 
473
  if ($deleteMessages) {
474
- $mail_server->deleteMessage($i);
475
- }
476
- }
477
- if ( $deleteMessages) {
478
- $mail_server->expungeMessages();
479
- }
480
- //clean up
481
- $mail_server->disconnect();
482
- return $emails;
483
- }
484
- function TestPOP3MessageFetch ( ) {
485
- print("**************RUNING IN TESTING MODE************\n");
486
- $config = get_postie_config();
487
- extract( $config );
488
- $email = $test_email_account;
489
- $password = $test_email_password;
490
- return(POP3MessageFetch($mail_server, $mail_server_port,
491
- $email, $password, $input_protocol,
492
- $time_offset, $test_email));
493
  }
 
494
  /**
495
- *Retrieves email via POP3
496
- */
497
- function POP3MessageFetch ($server=NULL, $port=NULL, $email=NULL,
498
- $password=NULL, $protocol=NULL, $offset=NULL, $test=NULL,
499
- $deleteMessages=true) {
500
- require_once(ABSPATH.WPINC.DIRECTORY_SEPARATOR.'class-pop3.php');
501
- $pop3 = &new POP3();
502
  print("\nConnecting to $server:$port ($protocol)) \n");
503
  if (!$pop3->connect($server, $port)) {
504
- if (strpos($pop3->ERROR,"POP3: premature NOOP OK, NOT an RFC 1939 Compliant server") === false) {
505
  print("Mail Connection Time Out\n
506
  Common Reasons: \n
507
  Server Down \n
@@ -512,760 +524,751 @@ function POP3MessageFetch ($server=NULL, $port=NULL, $email=NULL,
512
  }
513
  }
514
 
515
- //Check to see if there is any mail, if not die
516
- $msg_count = $pop3->login($email, $password);
517
- if ($msg_count===false) {
518
- $pop3->quit();
519
- // we should die if $msg_count is false, but the core wordpress pop3 needs
520
- // to be fixed before we can do that
521
- // die("there was a problem logging in. Please check username and password.");
522
  return(array());
523
- }
524
 
525
- // loop through messages
526
- for ($i=1; $i <= $msg_count; $i++) {
527
- $emails[$i] = implode ('',$pop3->get($i));
528
  if ($deleteMessages) {
529
- if( !$pop3->delete($i) ) {
530
- echo 'Oops '.$pop3->ERROR.'\n';
531
- $pop3->reset();
532
- exit;
533
- } else {
534
- echo "Mission complete, message $i deleted.\n";
535
- }
536
- }
537
- else {
538
  print("Not deleting messages!\n");
539
  }
540
- }
541
- //clean up
542
- $pop3->quit();
543
- return $emails;
544
  }
 
545
  /**
546
- * This function handles putting the actual entry into the database
547
- * @param array - categories to be posted to
548
- * @param array - details of the post
549
- */
550
- function PostToDB($details,$isReply, $postToDb=true, $customImageField=false) {
551
- if ($postToDb) {
552
- //$_POST['publish'] = true; //Added to make subscribe2 work - it will only handle it if the global varilable _POST is set
553
- if (!$isReply) {
554
- $post_ID = wp_insert_post($details);
555
- } else {
556
- $comment = array(
557
- 'comment_author'=>$details['comment_author'],
558
- 'comment_post_ID' =>$details['ID'],
559
- 'comment_author_email' => $details['email_author'],
560
- 'comment_date' =>$details['post_date'],
561
- 'comment_date_gmt' =>$details['post_date_gmt'],
562
- 'comment_content' =>$details['post_content'],
563
- 'comment_author_url' =>$details['comment_author_url'],
564
- 'comment_author_IP' =>'',
565
- 'comment_approved' =>1,
566
- 'comment_agent' =>'',
567
- 'comment_type' =>'',
568
- 'comment_parent' => 0,
569
- 'user_id' => $details['user_ID']
570
- );
571
-
572
- $post_ID = wp_insert_comment($comment);
573
- }
574
- if ($customImageField) {
575
- if (count($details['customImages'])>1) {
576
- $imageField=1;
577
- foreach ($details['customImages'] as $image) {
578
- add_post_meta($post_ID, 'image'. $imageField, $image);
579
- $imageField++;
580
- }
581
- } else {
582
- add_post_meta($post_ID, 'image', $details['customImages'][0]);
583
- }
 
584
  }
585
- }
586
  }
587
 
588
  /**
589
- * This function determines if the mime attachment is on the BANNED_FILE_LIST
590
- * @param string
591
- * @return boolean
592
- */
593
  function BannedFileName($filename, $bannedFiles) {
594
- if ( empty( $filename ) || empty( $bannedFiles ) ) return false;
595
- foreach ($bannedFiles as $bannedFile) {
596
- if (fnmatch($bannedFile, $filename)) {
597
- print("<p>Ignoring $filename - it is on the banned files list.");
598
- return(true);
 
 
599
  }
600
- }
601
- return(false);
602
  }
603
 
604
  //tear apart the meta part for useful information
605
- function GetContent ($part,&$attachments, $post_id, $poster, $config) {
606
- extract($config);
607
- global $charset, $encoding;
608
- /*
609
- if (!function_exists(imap_mime_header_decode))
610
- echo "you need to install the php-imap extension for full functionality, including mime header decoding\n";
611
- */
612
- $meta_return = NULL;
613
- echo "primary= " . $part->ctype_primary . ", secondary = " . $part->ctype_secondary . "\n";
614
- DecodeBase64Part($part);
615
- if (BannedFileName($part->ctype_parameters['name'],
616
- $banned_files_list))
617
- return(NULL);
618
- if ($part->ctype_primary == "application"
619
- && $part->ctype_secondary == "octet-stream") {
620
- if ($part->disposition == "attachment") {
621
- $image_endings = array("jpg","png","gif","jpeg","pjpeg");
622
- foreach ($image_endings as $type) {
623
- if (eregi(".$type\$",$part->d_parameters["filename"])) {
624
- $part->ctype_primary = "image";
625
- $part->ctype_secondary = $type;
626
- break;
627
- }
628
- }
629
- } else {
630
- $mimeDecodedEmail = DecodeMIMEMail($part->body);
631
- FilterTextParts($mimeDecodedEmail, $prefer_text_type);
632
- foreach($mimeDecodedEmail->parts as $section) {
633
- $meta_return .= GetContent($section,$attachments,$post_id, $poster, $config);
634
- }
635
- }
636
- }
637
- if ($part->ctype_primary == "multipart"
638
- && $part->ctype_secondary == "appledouble") {
639
- $mimeDecodedEmail = DecodeMIMEMail("Content-Type: multipart/mixed; boundary=".$part->ctype_parameters["boundary"]."\n".$part->body);
640
- FilterTextParts($mimeDecodedEmail, $prefer_text_type);
641
- FilterAppleFile($mimeDecodedEmail);
642
- foreach($mimeDecodedEmail->parts as $section) {
643
- $meta_return .= GetContent($section,$attachments,$post_id, $poster, $config);
644
- }
645
- } else {
646
- // fix filename (remove non-standard characters)
647
- $filename = preg_replace("/[^\x9\xA\xD\x20-\x7F]/", "",
648
- $part->ctype_parameters['name']);
649
- switch ( strtolower($part->ctype_primary) ) {
650
- case 'multipart':
651
- FilterTextParts($part, $prefer_text_type);
652
- foreach ($part->parts as $section) {
653
- $meta_return .= GetContent($section,$attachments,$post_id, $poster, $config);
654
- }
655
- break;
656
- case 'text':
657
- $tmpcharset=trim($part->ctype_parameters['charset']);
658
- if ($tmpcharset!='')
659
- $charset=$tmpcharset;
660
- $tmpencoding=trim($part->headers['content-transfer-encoding']);
661
- if ($tmpencoding!='')
662
- $encoding=$tmpencoding;
663
-
664
- $part->body=HandleMessageEncoding($part->headers["content-transfer-encoding"],
665
- $part->ctype_parameters["charset"],
666
- $part->body, $message_encoding, $message_dequote);
667
-
668
- //go through each sub-section
669
- if ($part->ctype_secondary=='enriched') {
670
- //convert enriched text to HTML
671
- $meta_return .= etf2HTML($part->body ) . "\n";
672
- } elseif ($part->ctype_secondary=='html') {
673
- //strip excess HTML
674
- //$meta_return .= HTML2HTML($part->body ) . "\n";
675
- $meta_return .= $part->body . "\n";
676
- } else {
677
- //regular text, so just strip the pgp signature
678
- if (ALLOW_HTML_IN_BODY) {
679
- $meta_return .= $part->body . "\n";
680
- } else {
681
- $meta_return .= htmlentities( $part->body ) . "\n";
682
  }
683
- $meta_return = StripPGP($meta_return);
684
- }
685
- break;
686
-
687
- case 'image':
688
- $file_id = postie_media_handle_upload($part, $post_id, $poster);
689
- $file = wp_get_attachment_url($file_id);
690
-
691
- $cid = trim($part->headers["content-id"],"<>");; //cids are in <cid>
692
- $the_post=get_post($file_id);
693
- $attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary,
694
- $imagetemplate);
695
- if ($cid) {
696
- $attachments["cids"][$cid] = array($file,
697
- count($attachments["html"]) - 1);
698
- }
699
- break;
700
- case 'audio':
701
- $file_id = postie_media_handle_upload($part, $post_id, $poster);
702
- $file = wp_get_attachment_url($file_id);
703
- $cid = trim($part->headers["content-id"],"<>");; //cids are in <cid>
704
- if ( in_array( $part->ctype_secondary, $audiotypes ) ) {
705
- $audioTemplate=$audiotemplate;
706
- } else {
707
- $icon=chooseAttachmentIcon($file, $part->ctype_primary,
708
- $part->ctype_secondary, $icon_set,
709
- $icon_size);
710
- $audioTemplate='<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
711
- }
712
- $attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary,
713
- $audioTemplate);
714
- break;
715
- case 'video':
716
- $file_id = postie_media_handle_upload($part, $post_id, $poster);
717
- $file = wp_get_attachment_url($file_id);
718
- $cid = trim($part->headers["content-id"],"<>");; //cids are in <cid>
719
- if ( in_array( strtolower( $part->ctype_secondary ), $video1types ) ) {
720
- $videoTemplate=$video1template;
721
- } elseif ( in_array( strtolower( $part->ctype_secondary ), $video2types ) ) {
722
- $videoTemplate=$video2template;
723
  } else {
724
- $icon=chooseAttachmentIcon($file, $part->ctype_primary,
725
- $part->ctype_secondary, $icon_set,
726
- $icon_size);
727
- $videoTemplate='<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
728
- }
729
- $attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary,
730
- $videoTemplate);
731
- //echo "videoTemplate = $videoTemplate\n";
732
- break;
733
-
734
- default:
735
- if ( in_array( strtolower( $part->ctype_primary ), $supported_file_types ) ) {
736
- //pgp signature - then forget it
737
- if ( $part->ctype_secondary == 'pgp-signature' )
738
- break;
739
- $file_id = postie_media_handle_upload($part, $post_id, $poster);
740
- $file = wp_get_attachment_url($file_id);
741
- $cid = trim($part->headers["content-id"],"<>");; //cids are in <cid>
742
- $icon=chooseAttachmentIcon($file, $part->ctype_primary,
743
- $part->ctype_secondary, $icon_set,
744
- $icon_size);
745
- $attachments["html"][$filename] = "<a href='$file'>" .
746
- $icon . $filename . '</a>' . "\n";
747
- if ($cid) {
748
- $attachments["cids"][$cid] = array($file,
749
- count($attachments["html"]) - 1);
750
- }
751
  }
752
- break;
753
- }
754
- }
755
- return($meta_return);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
756
  }
757
 
758
  function ubb2HTML(&$text) {
759
- // Array of tags with opening and closing
760
- $tagArray['img'] = array('open'=>'<img src="','close'=>'">');
761
- $tagArray['b'] = array('open'=>'<b>','close'=>'</b>');
762
- $tagArray['i'] = array('open'=>'<i>','close'=>'</i>');
763
- $tagArray['u'] = array('open'=>'<u>','close'=>'</u>');
764
- $tagArray['url'] = array('open'=>'<a href="','close'=>'">\\1</a>');
765
- $tagArray['email'] = array('open'=>'<a href="mailto:','close'=>'">\\1</a>');
766
- $tagArray['url=(.*)'] = array('open'=>'<a href="','close'=>'">\\2</a>');
767
- $tagArray['email=(.*)'] = array('open'=>'<a href="mailto:','close'=>'">\\2</a>');
768
- $tagArray['color=(.*)'] = array('open'=>'<font color="','close'=>'">\\2</font>');
769
- $tagArray['size=(.*)'] = array('open'=>'<font size="','close'=>'">\\2</font>');
770
- $tagArray['font=(.*)'] = array('open'=>'<font face="','close'=>'">\\2</font>');
771
- // Array of tags with only one part
772
- $sTagArray['br'] = array('tag'=>'<br>');
773
- $sTagArray['hr'] = array('tag'=>'<hr>');
774
-
775
- foreach($tagArray as $tagName=>$replace) {
776
- $tagEnd = preg_replace('/\W/Ui','',$tagName);
777
- $text = preg_replace("|\[$tagName\](.*)\[/$tagEnd\]|Ui","$replace[open]\\1$replace[close]",$text);
778
- }
779
- foreach($sTagArray as $tagName=>$replace) {
780
- $text = preg_replace("|\[$tagName\]|Ui","$replace[tag]",$text);
781
- }
782
- return $text;
783
  }
784
 
785
-
786
  // This function turns Enriched Text into something similar to HTML
787
  // Very basic at the moment, only supports some functionality and dumps the rest
788
  // FIXME: fix colours: <color><param>FFFF,C2FE,0374</param>some text </color>
789
- function etf2HTML ( $content ) {
790
-
791
- $search = array(
792
- '/<bold>/',
793
- '/<\/bold>/',
794
- '/<underline>/',
795
- '/<\/underline>/',
796
- '/<italic>/',
797
- '/<\/italic>/',
798
- '/<fontfamily><param>.*<\/param>/',
799
- '/<\/fontfamily>/',
800
- '/<x-tad-bigger>/',
801
- '/<\/x-tad-bigger>/',
802
- '/<bigger>/',
803
- '</bigger>/',
804
- '/<color>/',
805
- '/<\/color>/',
806
- '/<param>.+<\/param>/'
807
- );
808
-
809
- $replace = array (
810
- '<b>',
811
- '</b>',
812
- '<u>',
813
- '</u>',
814
- '<i>',
815
- '</i>',
816
- '',
817
- '',
818
- '',
819
- '',
820
- '',
821
- '',
822
- '',
823
- '',
824
- ''
825
- );
826
- // strip extra line breaks
827
- $content = preg_replace($search,$replace,$content);
828
- return trim($content);
829
- }
830
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
831
 
832
  // This function cleans up HTML in the e-mail
833
- function HTML2HTML ( $content ) {
834
- $search = array(
835
- '/<html [^<]*>/is',
836
- '/<\/html>/i',
837
- '/<\/?title>/i',
838
- '/<body[^<]*>/i',
839
- '/<\/body>/i',
840
- '/<\/?head>/i',
841
- '/<meta[^<]*>/i',
842
- '/<style[^<]*>.*<\/style>/is',
843
- '/<!--.*?-->/is',
844
- '/<\/?o:[^<]*>/i',
845
- '/<!DOCTYPE[^<]*>/',
846
- //'/<img src=[\'"][^<]*>/'
847
  // '/<img src="cid:(.*)" .*>/'
848
- );
849
 
850
- $replace = array (
851
- '',
852
- '',
853
- '',
854
- '',
855
- '',
856
- '',
857
- '',
858
- '',
859
- '',
860
- '',
861
- '',
862
- ''
863
- );
864
- // strip extra line breaks
865
- $content = preg_replace($search,$replace,trim($content));
866
- return ($content);
867
  }
868
 
869
-
870
-
871
  /**
872
- * Determines if the sender is a valid user.
873
- * @return integer|NULL
874
- */
875
- function ValidatePoster( &$mimeDecodedEmail, $config ) {
876
- extract($config);
877
- global $wpdb;
878
- $poster = NULL;
879
- $from = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["from"]));
880
- $resentFrom = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["resent-from"]));
881
- /*
882
- if ( empty($from) ) {
883
  echo 'Invalid Sender - Emtpy! ';
884
  return;
885
- }
886
- */
887
-
888
- //See if the email address is one of the special authorized ones
889
- print("Confirming Access For $from \n");
890
- $sql = 'SELECT id FROM '. $wpdb->users.' WHERE user_email=\'' . addslashes($from) . "' LIMIT 1;";
891
- $user_ID= $wpdb->get_var($sql);
892
- if (!empty($user_ID)) {
893
- $user = new WP_User($user_ID);
894
- if ($user->has_cap("post_via_postie")) {
895
- $poster = $user_ID;
896
- echo "posting as user $poster";
897
- } else {
898
- $poster = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE
899
  user_login = '$admin_username'");
900
- }
901
- } elseif ($turn_authorization_off ||
902
- CheckEmailAddress($from, $authorized_addresses) ||
903
- CheckEmailAddress($resentFrom, $authorized_addresses)) {
904
- $poster = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE
905
  user_login = '$admin_username'");
906
- }
907
- $validSMTP=checkSMTP($mimeDecodedEmail, $smtp);
908
- if (!$poster || !$validSMTP) {
909
- echo 'Invalid sender: ' . htmlentities($from) . "! Not adding email!\n";
910
- if ($forward_rejected_mail) {
911
- $admin_email = get_option("admin_email");
912
- if (MailToRecipients($mimeDecodedEmail, $test_email,
913
- array($admin_email), $return_to_sender)) {
914
- echo "A copy of the message has been forwarded to the administrator.\n";
915
- } else {
916
- echo "The message was unable to be forwarded to the adminstrator.\n";
917
- }
918
  }
919
- return;
920
- }
921
- return $poster;
 
 
 
 
 
 
 
 
 
 
 
922
  }
923
 
924
  function post_as_admin($admin_username) {
925
- print("$from is authorized to post as the administrator\n");
926
- //$from = get_option("admin_email");
927
- //$adminUser=$admin_username;
928
- //echo "adminUser='$adminUser'";
929
- return $poster;
930
  }
931
 
932
  function checkSMTP($mimeDecodedEmail, $smtpservers) {
933
- if ( empty( $smtpservers ) ) return true;
934
- foreach ( (array) $mimeDecodedEmail->headers['received'] as $received ) {
935
- foreach ($smtpservers as $smtp) {
936
- if ( stristr( $received, $smtp ) !== false ) return true;
 
 
 
937
  }
938
- }
939
- return false;
940
  }
941
 
942
  /**
943
- * Looks at the content for the start of the message and removes everything before that
944
- * If the pattern is not found everything is returned
945
- * @param string
946
- * @param string
947
- */
948
- function StartFilter(&$content,$start) {
949
- $pos = strpos($content,$start);
950
- if ( $pos === false) {
951
- return($content);
952
- }
953
- $content = substr($content, $pos + strlen($start), strlen($content));
954
  }
955
 
956
  /**
957
- * Looks at the content for the start of the signature and removes all text
958
- * after that point
959
- * @param string
960
- * @param array - a list of patterns to determine if it is a sig block
961
- */
962
- function remove_signature( $content, $filterList ) {
963
- if (empty($filterList))
964
- return $content;
965
- $arrcontent = explode("\n", $content);
966
- $strcontent = '';
967
- $pattern='/^(' . implode( '|', $filterList ) . ')/';
968
- for ($i = 0; $i<=count($arrcontent); $i++) {
969
- $line = trim($arrcontent[$i]);
970
- $nextline = $arrcontent[$i+1];
971
- if (preg_match($pattern,trim($line))) {
972
- //if (!strpos(trim($line), $pattern)==0) {
973
- //print("<p>Found in $line");
974
- break;
975
- }
976
- $strcontent .= $line ."\n";
977
- }
978
- return $strcontent;
979
  }
 
980
  /**
981
- * Looks at the content for the given tag and removes all text
982
- * after that point
983
- * @param string
984
- * @param filter
985
- */
986
- function EndFilter( &$content, $end ) {
987
- $pos = strpos( $content, $end );
988
- if ( $pos === false )
989
- return $content;
990
- return $content = substr($content, 0, $pos);
991
  }
992
 
993
  //filter content for new lines
994
- function FilterNewLines ( $content, $convertNewLines=false ) {
995
- $search = array (
996
- "/\r\n/",
997
- "/\r/",
998
- "/\n\n/",
999
- "/\r\n\r\n/",
1000
- "/\n/"
1001
- );
1002
- $replace = array (
1003
- "\n",
1004
- "\n",
1005
- 'ACTUAL_NEW_LINE',
1006
- 'ACTUAL_NEW_LINE',
1007
- 'LINEBREAK'
1008
- );
1009
- // strip extra line breaks, and replace double line breaks with paragraph
1010
- // tags
1011
- $result = preg_replace($search,$replace,$content);
1012
- //$newContent='<p>' . preg_replace('/ACTUAL_NEW_LINE/',"</p>\n<p>",$result);
1013
-
1014
- $newContent=preg_replace('/(ACTUAL_NEW_LINE|LINEBREAK\s*LINEBREAK)/',"\n\n",$result);
1015
- //$newContent=preg_replace('/<p>LINEBREAK$/', '', $newContent);
1016
- if ($convertNewLines) {
1017
- $newContent= preg_replace('/LINEBREAK/',"<br />\n",$newContent);
1018
- if( defined( 'POSTIE_DEBUG' ) ) {
1019
- echo "converting newlines\n";
1020
- }
1021
- } else {
1022
- $newContent= preg_replace('/LINEBREAK/'," ",$newContent);
1023
- if( defined( 'POSTIE_DEBUG' ) ) {
1024
- echo "not converting newlines\n";
1025
- }
1026
- }
1027
- return($newContent);
1028
- }
1029
- function FixEmailQuotes ( $content ) {
1030
- # place e-mails quotes (indicated with >) in blockquote and pre tags
1031
- $search = array (
1032
- "/^>/"
1033
- );
1034
- $replace = array (
1035
- '<br />&gt;'
1036
- );
1037
- // strip extra line breaks, and replace double line breaks with paragraph
1038
- // tags
1039
- $result = preg_replace($search,$replace,$content);
1040
- //return('<p>' . preg_replace('/ACTUAL_NEW_LINE/',"<\/p>\n<p>",$result)
1041
- //. '</p>');
1042
- return($result);
 
1043
  }
1044
 
1045
  //strip pgp stuff
1046
- function StripPGP ( $content ) {
1047
- $search = array (
1048
- '/-----BEGIN PGP SIGNED MESSAGE-----/',
1049
- '/Hash: SHA1/'
1050
- );
1051
- $replace = array (
1052
- ' ',
1053
- ''
1054
- );
1055
- // strip extra line breaks
1056
- $return = preg_replace($search,$replace,$content);
1057
- return $return;
1058
- }
1059
-
1060
- function ConvertToISO_8859_1($encoding,$charset, $body, $blogEncoding ) {
1061
- $charset = strtolower($charset);
1062
- $encoding = strtolower($encoding);
1063
- if (strtolower($blogEncoding == "iso-8859-1") && (strtolower($charset) != 'iso-8859-1')) {
1064
- if( $encoding == 'base64' || $encoding == 'quoted-printable' ) {
1065
- $body = utf8_decode($body);
1066
- }
1067
- }
1068
- return($body);
1069
- }
1070
- function HandleMessageEncoding($encoding, $charset,$body,
1071
- $blogEncoding='utf-8', $dequote=true) {
1072
- $charset = strtolower($charset);
1073
- $encoding = strtolower($encoding);
1074
- /*
1075
- if ($encoding == '') {
1076
- $encoding = '7bit';
1077
- }
1078
- */
1079
- if ( $dequote && strtolower($encoding) == 'quoted-printable' ) {
1080
- //echo "handling quoted printable";
1081
- $body = quoted_printable_decode($body);
1082
- //echo "now body is:\n\n $body\n\n";
1083
- }
1084
- //HandleQuotedPrintable($encoding, $body, $dequote);
1085
- if ($blogEncoding=='iso-8859-1') {
1086
- $text=ConvertToISO_8859_1($encoding,$charset,$body, $blogEncoding);
1087
- }
1088
- else {
1089
- $text=ConvertToUTF_8($encoding,$charset,$body);
1090
- }
1091
- return($text);
1092
- }
1093
- function ConvertToUTF_8($encoding,$charset,$body) {
1094
- $charset = strtolower($charset);
1095
- $encoding = strtolower($encoding);
1096
-
1097
- switch($charset) {
1098
- case "iso-8859-1":
1099
- $body = utf8_encode($body);
1100
- break;
1101
- case "iso-2022-jp":
1102
- $body = iconv("ISO-2022-JP","UTF-8//TRANSLIT",$body);
1103
- break;
1104
- case ($charset=="windows-1252" || $charset=="cp-1252" ||
1105
- $charset=="cp 1252"):
1106
- $body = cp1252_to_utf8($body);
1107
- break;
1108
- case ($charset=="windows-1256" || $charset=="cp-1256" ||
1109
- $charset=="cp 1256"):
1110
- $body = iconv("Windows-1256","UTF-8//TRANSLIT",$body);
1111
- break;
1112
- case 'koi8-r':
1113
- $body = iconv("koi8-r","UTF-8//TRANSLIT",$body);
1114
- break;
1115
- case 'iso-8859-2':
1116
- $body = iconv("iso-8859-2","UTF-8//TRANSLIT",$body);
1117
- break;
1118
- case "big5":
1119
- $body = iconv("BIG5","UTF-8//TRANSLIT",$body);
1120
- break;
1121
- case "gb2312":
1122
- $body = iconv("GB2312","UTF-8//TRANSLIT",$body);
1123
- break;
1124
- case "iso-8859-15":
1125
- $body = iconv("iso-8859-15","UTF-8//TRANSLIT",$body);
1126
- break;
1127
- }
1128
- return($body);
1129
  }
 
1130
  /* this function will convert windows-1252 (also known as cp-1252 to utf-8 */
 
1131
  function cp1252_to_utf8($str) {
1132
- $cp1252_map = array (
1133
- "\xc2\x80" => "\xe2\x82\xac",
1134
- "\xc2\x82" => "\xe2\x80\x9a",
1135
- "\xc2\x83" => "\xc6\x92",
1136
- "\xc2\x84" => "\xe2\x80\x9e",
1137
- "\xc2\x85" => "\xe2\x80\xa6",
1138
- "\xc2\x86" => "\xe2\x80\xa0",
1139
- "\xc2\x87" => "\xe2\x80\xa1",
1140
- "\xc2\x88" => "\xcb\x86",
1141
- "\xc2\x89" => "\xe2\x80\xb0",
1142
- "\xc2\x8a" => "\xc5\xa0",
1143
- "\xc2\x8b" => "\xe2\x80\xb9",
1144
- "\xc2\x8c" => "\xc5\x92",
1145
- "\xc2\x8e" => "\xc5\xbd",
1146
- "\xc2\x91" => "\xe2\x80\x98",
1147
- "\xc2\x92" => "\xe2\x80\x99",
1148
- "\xc2\x93" => "\xe2\x80\x9c",
1149
- "\xc2\x94" => "\xe2\x80\x9d",
1150
- "\xc2\x95" => "\xe2\x80\xa2",
1151
- "\xc2\x96" => "\xe2\x80\x93",
1152
- "\xc2\x97" => "\xe2\x80\x94",
1153
- "\xc2\x98" => "\xcb\x9c",
1154
- "\xc2\x99" => "\xe2\x84\xa2",
1155
- "\xc2\x9a" => "\xc5\xa1",
1156
- "\xc2\x9b" => "\xe2\x80\xba",
1157
- "\xc2\x9c" => "\xc5\x93",
1158
- "\xc2\x9e" => "\xc5\xbe",
1159
- "\xc2\x9f" => "\xc5\xb8"
1160
- );
1161
- return strtr ( utf8_encode ( $str ), $cp1252_map );
1162
  }
1163
 
1164
  /**
1165
- * This function handles decoding base64 if needed
1166
- */
1167
- function DecodeBase64Part( &$part ) {
1168
- if ( strtolower($part->headers['content-transfer-encoding']) == 'base64' ) {
1169
  $part->body = base64_decode($part->body);
1170
  }
1171
  }
1172
 
1173
- function HandleQuotedPrintable($encoding, &$body,$dequote=true ) {
1174
- if ( $dequote && strtolower($encoding) == 'quoted-printable' ) {
1175
- echo "handling quoted printable";
1176
- $body = quoted_printable_decode($body);
1177
  }
1178
  }
1179
 
1180
-
1181
  /**
1182
- * Checks for the comments tag
1183
- * @return boolean
1184
- */
1185
  function AllowCommentsOnPost(&$content) {
1186
  $comments_allowed = get_option('default_comment_status');
1187
- if (eregi("comments:([0|1|2])",$content,$matches)) {
1188
- $content = ereg_replace("comments:$matches[1]","",$content);
1189
  if ($matches[1] == "1") {
1190
  $comments_allowed = "open";
1191
- }
1192
- else if ($matches[1] == "2") {
1193
  $comments_allowed = "registered_only";
1194
- }
1195
- else {
1196
  $comments_allowed = "closed";
1197
  }
1198
  }
1199
  return($comments_allowed);
1200
  }
 
1201
  /**
1202
- * Needed to be able to modify the content to remove the usage of the delay tag
1203
- */
1204
- function DeterminePostDate(&$content, $message_date = NULL, $offset=0) {
1205
  $delay = 0;
1206
- if( defined( 'POSTIE_DEBUG' ) ) {
1207
- echo "inside Determine Post Date, message_date = $message_date\n";
1208
  }
1209
- if (eregi("delay:(-?[0-9dhm]+)",$content,$matches)
1210
- && trim($matches[1])) {
1211
- if (eregi("(-?[0-9]+)d",$matches[1],$dayMatches)) {
1212
  $days = $dayMatches[1];
1213
  }
1214
- if (eregi("(-?[0-9]+)h",$matches[1],$hourMatches)) {
1215
  $hours = $hourMatches[1];
1216
  }
1217
- if (eregi("(-?[0-9]+)m",$matches[1],$minuteMatches)) {
1218
  $minutes = $minuteMatches[1];
1219
  }
1220
  $delay = (($days * 24 + $hours) * 60 + $minutes) * 60;
1221
- $content = ereg_replace("delay:$matches[1]","",$content);
1222
  }
1223
- if (!empty($message_date) && $delay==0) {
1224
  $dateInSeconds = strtotime($message_date);
1225
- }
1226
- else {
1227
  $dateInSeconds = time() + $delay;
1228
  }
1229
- $post_date = gmdate('Y-m-d H:i:s',$dateInSeconds + ($offset * 3600));
1230
- $post_date_gmt = gmdate('Y-m-d H:i:s',$dateInSeconds);
1231
 
1232
- /*
1233
- echo "--------------------DELAY------------\n";
1234
- echo "delay=$delay, dateInSeconds = $dateInSeconds\n";
1235
- echo "post_date=$post_date\n";
1236
- echo "--------------------DELAY------------\n";
1237
- */
1238
- return(array($post_date,$post_date_gmt, $delay));
1239
  }
 
1240
  /**
1241
- * This function takes the content of the message - looks for a subject at the begining surrounded by # and then removes that from the content
1242
- */
1243
  function ParseInMessageSubject($content, $defaultTitle) {
1244
- if (substr($content,0,1) != "#") {
1245
  //print("<p>Didn't start with # '".substr(ltrim($content),0,10)."'");
1246
- return(array($defaultTitle,$content));
1247
  }
1248
- $subjectEndIndex = strpos($content,"#",1);
1249
  if (!$subjectEndIndex > 0) {
1250
- return(array($defaultTitle,$content));
1251
  }
1252
- $subject = substr($content,1,$subjectEndIndex - 1);
1253
- $content = substr($content,$subjectEndIndex + 1,strlen($content));
1254
- return(array($subject,$content));
1255
  }
 
1256
  /**
1257
- * This method sorts thru the mime parts of the message. It is looking for files labeled - "applefile" - current
1258
- * this part of the file attachment is not supported
1259
- *@param object
1260
- */
1261
  function FilterAppleFile(&$mimeDecodedEmail) {
1262
  $newParts = array();
1263
  $found = false;
1264
- for ($i = 0; $i < count($mimeDecodedEmail->parts); $i++) {
1265
  if ($mimeDecodedEmail->parts[$i]->ctype_secondary == "applefile") {
1266
  $found = true;
1267
- }
1268
- else {
1269
  $newParts[] = &$mimeDecodedEmail->parts[$i];
1270
  }
1271
  }
@@ -1273,1318 +1276,1332 @@ function FilterAppleFile(&$mimeDecodedEmail) {
1273
  $mimeDecodedEmail->parts = $newParts; //This is now the filtered list of just the preferred type.
1274
  }
1275
  }
 
1276
  function postie_media_handle_upload($part, $post_id, $poster, $post_data = array()) {
1277
- $overrides = array('test_form'=>false);
1278
- //$overrides = array('test_form'=>false, 'test_size'=>false,
1279
- // 'test_type'=>false);
1280
- $tmpFile=tempnam(getenv('TEMP'), 'postie');
1281
- if (!is_writable($tmpFile)) {
1282
- $uploadDir=wp_upload_dir();
1283
- $tmpFile=tempnam($uploadDir['path'], 'postie');
1284
- }
1285
- $fp = fopen($tmpFile, 'w');
1286
- if ($fp) {
1287
- fwrite($fp, $part->body);
1288
- fclose($fp);
1289
- } else {
1290
- echo "could not write to temp file: '$tmpFile' ";
1291
- }
1292
- if ($part->ctype_parameters['name']=='') {
1293
- if ($part->d_parameters['filename']!='') {
1294
- $name = $part->d_parameters['filename'];
1295
  } else {
1296
- $name = 'postie-media.'. $part->ctype_secondary;
1297
- }
1298
- } else {
1299
- $name = $part->ctype_parameters['name'];
1300
- }
1301
- $the_file = array('name' => $name,
1302
- 'tmp_name' => $tmpFile,
1303
- 'size' => filesize($tmpFile),
1304
- 'error' => ''
1305
- );
1306
- if (stristr('.zip', $name)) {
1307
- $parts=explode('.', $name);
1308
- $ext=$parts[count($parts)-1];
1309
- $type=$part->primary . '/' . $part->secondary;
1310
- $the_file['ext'] = $ext;
1311
- $the_file['type'] = $type;
1312
- $overrides['test_type'] = false;
1313
- }
1314
-
1315
- $time = current_time('mysql');
1316
- if ( $post = get_post($post_id) ) {
1317
- if ( substr( $post->post_date, 0, 4 ) > 0 )
1318
- $time = $post->post_date;
1319
- }
1320
-
1321
- $file = postie_handle_upload($the_file, $overrides, $time);
1322
- //unlink($tmpFile);
1323
-
1324
- if ( isset($file['error']) )
1325
- return new WP_Error( 'upload_error', $file['error'] );
1326
-
1327
- $url = $file['url'];
1328
- $type= $file['type'];
1329
- $file = $file['file'];
1330
- $title = preg_replace('/\.[^.]+$/', '', basename($file));
1331
- $content = '';
1332
-
1333
- // use image exif/iptc data for title and caption defaults if possible
1334
- include_once(ABSPATH . '/wp-admin/includes/image.php');
1335
- if ( $image_meta = @wp_read_image_metadata($file) ) {
1336
- if ( trim($image_meta['title']) )
1337
- $title = $image_meta['title'];
1338
- if ( trim($image_meta['caption']) )
1339
- $content = $image_meta['caption'];
1340
- }
1341
-
1342
- // Construct the attachment array
1343
- $attachment = array_merge( array(
1344
- 'post_mime_type' => $type,
1345
- 'guid' => $url,
1346
- 'post_parent' => $post_id,
1347
- 'post_title' => $title,
1348
- 'post_excerpt' => $content,
1349
- 'post_content' => $content,
1350
- 'post_author' => $poster
1351
- ), $post_data );
1352
-
1353
- // Save the data
1354
- $id = wp_insert_attachment($attachment, $file, $post_id);
1355
- if ( !is_wp_error($id) ) {
1356
- wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
1357
- }
1358
-
1359
- return $id;
1360
-
1361
- }
1362
-
1363
- function postie_handle_upload( &$file, $overrides = false, $time = null ) {
1364
- // The default error handler.
1365
- if (! function_exists( 'wp_handle_upload_error' ) ) {
1366
- function wp_handle_upload_error( &$file, $message ) {
1367
- return array( 'error'=>$message );
1368
- }
1369
- }
1370
-
1371
- // You may define your own function and pass the name in $overrides['upload_error_handler']
1372
- $upload_error_handler = 'wp_handle_upload_error';
1373
-
1374
- // You may define your own function and pass the name in $overrides['unique_filename_callback']
1375
- $unique_filename_callback = null;
1376
-
1377
- // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
1378
- $action = 'wp_handle_upload';
1379
-
1380
- // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
1381
- $upload_error_strings = array( false,
1382
- __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ),
1383
- __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ),
1384
- __( "The uploaded file was only partially uploaded." ),
1385
- __( "No file was uploaded." ),
1386
- '',
1387
- __( "Missing a temporary folder." ),
1388
- __( "Failed to write file to disk." ));
1389
-
1390
- // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
1391
- $test_form = true;
1392
- $test_size = true;
1393
-
1394
- // If you override this, you must provide $ext and $type!!!!
1395
- $test_type = true;
1396
- $mimes = false;
1397
-
1398
- // Install user overrides. Did we mention that this voids your warranty?
1399
- if ( is_array( $overrides ) )
1400
- extract( $overrides, EXTR_OVERWRITE );
1401
-
1402
- // A correct form post will pass this test.
1403
- if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) )
1404
- return $upload_error_handler( $file, __( 'Invalid form submission.' ));
1405
-
1406
- // A successful upload will pass this test. It makes no sense to override this one.
1407
- if ( $file['error'] > 0 )
1408
- return $upload_error_handler( $file, $upload_error_strings[$file['error']] );
1409
-
1410
- // A non-empty file will pass this test.
1411
- if ( $test_size && !($file['size'] > 0 ) )
1412
- return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.' ));
1413
-
1414
- // A properly uploaded file will pass this test. There should be no reason to override this one.
1415
- if (!file_exists( $file['tmp_name'] ) )
1416
- return $upload_error_handler( $file, __( 'Specified file failed upload test.'));
1417
- // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
1418
- if ( $test_type ) {
1419
- $wp_filetype = wp_check_filetype( $file['name'], $mimes );
1420
-
1421
- extract( $wp_filetype );
1422
-
1423
- if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
1424
- return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' ));
1425
-
1426
- if ( !$ext )
1427
- $ext = ltrim(strrchr($file['name'], '.'), '.');
1428
-
1429
- if ( !$type )
1430
- $type = $file['type'];
1431
- }
1432
-
1433
- // A writable uploads dir will pass this test. Again, there's no point overriding this one.
1434
- if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) )
1435
- return $upload_error_handler( $file, $uploads['error'] );
1436
-
1437
- // fix filename (remove non-standard characters)
1438
- $file['name'] = preg_replace("/[^\x9\xA\xD\x20-\x7F]/", "",
1439
- $file['name']);
1440
- $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback );
1441
-
1442
- // Move the file to the uploads dir
1443
- $new_file = $uploads['path'] . "/$filename";
1444
- if ( false === @ rename( $file['tmp_name'], $new_file ) ) {
1445
- return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) );
1446
- }
1447
-
1448
- // Set correct file permissions
1449
- $stat = stat( dirname( $new_file ));
1450
- $perms = $stat['mode'] & 0000666;
1451
- @ chmod( $new_file, $perms );
1452
-
1453
- // Compute the URL
1454
- $url = $uploads['url'] . "/$filename";
1455
-
1456
- $return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
1457
-
1458
- return $return;
1459
- }/**
1460
- * Searches for the existance of a certain MIME TYPE in the tree of mime attachments
1461
- * @param primary mime
1462
- * @param secondary mime
1463
- * @return boolean
1464
- */
1465
- function SearchForMIMEType($part,$primary,$secondary) {
 
 
 
 
 
 
 
 
1466
  if ($part->ctype_primary == $primary && $part->ctype_secondary == $secondary) {
1467
- return true;
1468
  }
1469
  if ($part->ctype_primary == "multipart") {
1470
  for ($i = 0; $i < count($part->parts); $i++) {
1471
- if (SearchForMIMEType($part->parts[$i], $primary,$secondary)) {
1472
  return true;
1473
  }
1474
  }
1475
  }
1476
  return false;
1477
  }
 
1478
  /**
1479
- * This method sorts thru the mime parts of the message. It is looking for a certain type of text attachment. If
1480
- * that type is present it filters out all other text types. If it is not - then nothing is done
1481
- *@param object
1482
- */
1483
  function FilterTextParts(&$mimeDecodedEmail, $preferTextType) {
1484
- $newParts = array();
1485
- $found = false;
1486
- for ($i = 0; $i < count($mimeDecodedEmail->parts); $i++) {
1487
- if (in_array($mimeDecodedEmail->parts[$i]->ctype_primary,
1488
- array("text","multipart"))) {
1489
- if (SearchForMIMEType($mimeDecodedEmail->parts[$i],"text",
1490
- $preferTextType)) {
1491
- $newParts[] = &$mimeDecodedEmail->parts[$i];
1492
- $found = true;
1493
- }
1494
- } else {
1495
- $newParts[] = &$mimeDecodedEmail->parts[$i];
 
 
 
1496
  }
1497
- }
1498
- if ($found && $newParts) {
1499
- //This is now the filtered list of just the preferred type.
1500
- $mimeDecodedEmail->parts = $newParts;
1501
- }
1502
  }
 
1503
  /**
1504
- * This function can be used to send confirmation or rejection e-mails
1505
- * It accepts an object containing the entire message
1506
- */
1507
- function MailToRecipients( &$mail_content,$testEmail=false,
1508
- $recipients=array(), $returnToSender, $reject=true) {
1509
- if ($testEmail) {
1510
- return;
1511
- }
1512
- $user = get_userdata('1');
1513
- $myname = $user->user_nicename;
1514
- $myemailadd = get_option("admin_email");
1515
- $blogname = get_option("blogname");
1516
- $blogurl = get_option("siteurl");
1517
- //array_push($recipients, $myemailadd);
1518
- if (count($recipients) == 0) {
1519
- return false;
1520
- }
1521
 
1522
  $from = trim($mail_content->headers["from"]);
1523
  $subject = $mail_content->headers['subject'];
1524
- if ($returnToSender) {
1525
- array_push($recipients, $from);
1526
- }
1527
-
1528
- $headers = "From: Wordpress <" .$myemailadd .">\r\n";
1529
- foreach ($recipients as $recipient) {
1530
- $recipient = trim($recipient);
1531
- if (! empty($recipient)) {
1532
- $headers .= "Cc: " . $recipient . "\r\n";
1533
- }
1534
- }
1535
- // Set email subject
1536
- if ($reject) {
1537
- $alert_subject = $blogname . ": Unauthorized Post Attempt from $from";
1538
- if ($mail_content->ctype_parameters['boundary']) {
1539
- $boundary = $mail_content->ctype_parameters["boundary"];
1540
- } else {
1541
- $boundary=uniqid("B_");
1542
  }
1543
- // Set sender details
1544
- /*
1545
- if (isset($mail_content->headers["mime-version"])) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1546
  $headers .= "Mime-Version: ". $mail_content->headers["mime-version"] . "\r\n";
1547
- }
1548
- if (isset($mail_content->headers["content-type"])) {
1549
  $headers .= "Content-Type: ". $mail_content->headers["content-type"] . "\r\n";
1550
- }
1551
- */
1552
-
1553
- $headers.="Content-Type:multipart/alternative; boundary=\"$boundary\"\r\n";
1554
- // SDM 20041123
1555
- // construct mail message
1556
- $message = "An unauthorized message has been sent to $blogname.\n";
1557
- $message .= "Sender: $from\n";
1558
- $message .= "Subject: $subject\n";
1559
- $message .= "\n\nIf you wish to allow posts from this address, please add " . $from. " to the registered users list and manually add the content of the e-mail found below.";
1560
- $message .= "\n\nOtherwise, the e-mail has already been deleted from the server and you can ignore this message.";
1561
- $message .= "\n\nIf you would like to prevent postie from forwarding mail
1562
  in the future, please change the FORWARD_REJECTED_MAIL setting in the Postie
1563
- settings panel";
1564
- $message .= "\n\nThe original content of the e-mail has been attached.\n\n";
1565
- $mailtext = "--$boundary\r\n";
1566
- $mailtext .= "Content-Type: text/plain;format=flowed;charset=\"iso-8859-1\";reply-type=original\n";
1567
- $mailtext .= "Content-Transfer-Encoding: 7bit\n";
1568
- $mailtext .= "\n";
1569
- $mailtext .= "$message\n";
1570
- if ($mail_content->parts) {
1571
- $mailparts=$mail_content->parts;
 
 
 
 
 
 
 
 
 
 
 
 
 
1572
  } else {
1573
- $mailparts[]=$mail_content;
1574
- }
1575
- foreach ($mailparts as $part) {
1576
- $mailtext .= "--$boundary\r\n";
1577
- $mailtext .= "Content-Type: ".$part->headers["content-type"] . "\n";
1578
- $mailtext .= "Content-Transfer-Encoding: ".$part->headers["content-transfer-encoding"] . "\n";
1579
- if (isset($part->headers["content-disposition"])) {
1580
- $mailtext .= "Content-Disposition: ".$part->headers["content-disposition"] . "\n";
1581
- }
1582
- $mailtext .= "\n";
1583
- $mailtext .= $part->body;
1584
  }
1585
- } else {
1586
- $alert_subject = "Successfully posted to $blogname";
1587
- $mailtext = "Your post '$subject' has been successfully published to " .
1588
- "$blogname <$blogurl>.\n";
1589
- }
1590
 
1591
-
1592
- // Send message
1593
- mail($myemailadd, $alert_subject, $mailtext, $headers);
1594
 
1595
- return true;
 
 
 
1596
  }
 
1597
  /**
1598
- * This function handles the basic mime decoding
1599
- * @param string
1600
- * @return array
1601
- */
1602
- function DecodeMIMEMail($email, $decodeHeaders=false) {
1603
  $params = array();
1604
  $params['include_bodies'] = true;
1605
  $params['decode_bodies'] = false;
1606
  $params['decode_headers'] = $decodeHeaders;
1607
  $params['input'] = $email;
1608
  //$decoded = imap_mime_header_decode($email);
1609
- $decoded = Mail_mimeDecode::decode($params);
1610
- if ( empty($decoded->parts) ) $decoded->parts = array(); // have an empty array at minimum, so that it is safe for "foreach"
 
1611
  return $decoded;
1612
  }
1613
-
1614
  /**
1615
- * This is used for debugging the mimeDecodedEmail of the mail
1616
- */
1617
  function DisplayMIMEPartTypes($mimeDecodedEmail) {
1618
- foreach($mimeDecodedEmail->parts as $part) {
1619
- print("<p>".$part->ctype_primary . " / ".$part->ctype_secondary . "/ ".$part->headers['content-transfer-encoding'] ."\n");
1620
  }
1621
  }
1622
 
1623
  /**
1624
- * This compares the current address to the list of authorized addresses
1625
- * @param string - email address
1626
- * @return boolean
1627
- */
1628
  function CheckEmailAddress($address, $authorized) {
1629
- $isAuthorized = in_array( strtolower($address), $authorized );
1630
- return $isAuthorized;
1631
  }
 
1632
  /**
1633
- *This method works around a problemw with email address with extra <> in the email address
1634
- * @param string
1635
- * @return string
1636
- */
1637
  function RemoveExtraCharactersInEmailAddress($address) {
1638
  $matches = array();
1639
- if (preg_match('/^[^<>]+<([^<> ()]+)>$/',$address,$matches)) {
1640
  $address = $matches[1];
1641
- }
1642
- else if (preg_match('/<([^<> ()]+)>/',$address,$matches)) {
1643
  $address = $matches[1];
1644
  }
1645
 
1646
  return($address);
1647
  }
1648
 
1649
- /**
1650
- * This function gleans the name from the 'from:' header if available. If not
1651
- * it just returns the username (everything before @)
1652
- */
1653
  function GetNameFromEmail($address) {
1654
  $matches = array();
1655
- if (preg_match('/^([^<>]+)<([^<> ()]+)>$/',$address,$matches)) {
1656
  $name = $matches[1];
1657
- }
1658
- else if (preg_match('/<([^<>@ ()]+)>/',$address,$matches)) {
1659
  $name = $matches[1];
1660
  }
1661
 
1662
  return($name);
1663
  }
1664
 
1665
- /**
1666
- * Choose an appropriate file icon based on the extension and mime type of
1667
- * the attachment
1668
- */
1669
- function chooseAttachmentIcon($file, $primary, $secondary, $iconSet='silver',
1670
- $size='32') {
1671
- if ($iconSet=='none')
1672
- return('');
1673
- $fileName=basename($file);
1674
- $parts=explode('.', $fileName);
1675
- $ext=$parts[count($parts)-1];
1676
- $docExts=array('doc', 'docx');
1677
- $docMimes=array('msword', 'vnd.ms-word',
1678
- 'vnd.openxmlformats-officedocument.wordprocessingml.document');
1679
- $pptExts=array('ppt','pptx');
1680
- $pptMimes=array('mspowerpoint', 'vnd.ms-powerpoint',
1681
- 'vnd.openxmlformats-officedocument.');
1682
- $xlsExts=array('xls', 'xlsx');
1683
- $xlsMimes=array('msexcel', 'vnd.ms-excel',
1684
- 'vnd.openxmlformats-officedocument.spreadsheetml.sheet');
1685
- $iWorkMimes=array('zip', 'octet-stream');
1686
- $mpgExts=array('mpg', 'mpeg', 'mp2');
1687
- $mpgMimes=array('mpg', 'mpeg', 'mp2');
1688
- $mp3Exts=array('mp3');
1689
- $mp3Mimes=array('mp3', 'mpeg3','mpeg');
1690
- $mp4Exts=array('mp4', 'm4v');
1691
- $mp4Mimes=array('mp4', 'mpeg4','octet-stream');
1692
- $aacExts=array('m4a', 'aac');
1693
- $aacMimes=array('m4a', 'aac', 'mp4');
1694
- $aviExts=array('avi');
1695
- $aviMimes=array('avi', 'x-msvideo');
1696
- $movExts=array('mov');
1697
- $movMimes=array('mov', 'quicktime');
1698
- if ($ext=='pdf' && $secondary=='pdf') {
1699
- $fileType='pdf';
1700
- } else if ($ext=='pages' && in_array($secondary, $iWorkMimes)) {
1701
- $fileType='pages';
1702
- } else if ($ext=='numbers' && in_array($secondary, $iWorkMimes)) {
1703
- $fileType='numbers';
1704
- } else if ($ext=='key' && in_array($secondary, $iWorkMimes)) {
1705
- $fileType='key';
1706
- } else if (in_array($ext, $docExts) && in_array($secondary, $docMimes)) {
1707
- $fileType='doc';
1708
- } else if (in_array($ext, $pptExts) && in_array($secondary, $pptMimes)) {
1709
- $fileType='ppt';
1710
- } else if (in_array($ext, $xlsExts) && in_array($secondary, $xlsMimes)) {
1711
- $fileType='xls';
1712
- } else if (in_array($ext, $mp4Exts) && in_array($secondary, $mp4Mimes)) {
1713
- $fileType='mp4';
1714
- } else if (in_array($ext, $movExts) && in_array($secondary, $movMimes)) {
1715
- $fileType='mov';
1716
- } else if (in_array($ext, $aviExts) && in_array($secondary, $aviMimes)) {
1717
- $fileType='avi';
1718
- } else if (in_array($ext, $mp3Exts) && in_array($secondary, $mp3Mimes)) {
1719
- $fileType='mp3';
1720
- } else if (in_array($ext, $mpgExts) && in_array($secondary, $mpgMimes)) {
1721
- $fileType='mpg';
1722
- } else if (in_array($ext, $aacExts) && in_array($secondary, $aacMimes)) {
1723
- $fileType='aac';
1724
- } else {
1725
- $fileType='default';
1726
- }
1727
- $fileName="/icons/$iconSet/$fileType-$size.png";
1728
- if (!file_exists(POSTIE_ROOT . $fileName))
1729
- $fileName="/icons/$iconSet/default-$size.png";
1730
- $iconHtml="<img src='" . POSTIE_URL . $fileName . "' alt='$fileType icon' />";
1731
- return($iconHtml);
1732
-
1733
- }
1734
-
1735
- function parseTemplate($id, $type, $template, $size='medium') {
1736
-
1737
- /* we check template for thumb, thumbnail, large, full and use that as
1738
- size. If not found, we default to medium */
1739
- if ($type=='image') {
1740
- $sizes=array('thumbnail', 'medium', 'large');
1741
- $hwstrings=array();
1742
- $widths=array();
1743
- $heights=array();
1744
- for ($i=0; $i<count($sizes); $i++) {
1745
- list( $img_src[$i], $widths[$i], $heights[$i] ) = image_downsize($id,
1746
- $sizes[$i]);
1747
- $hwstrings[$i] = image_hwstring($widths[$i], $heights[$i]);
1748
- }
1749
- }
1750
- $attachment=get_post($id);
1751
- $the_parent=get_post($attachment->post_parent);
1752
- $uploadDir=wp_upload_dir();
1753
- $fileName=basename($attachment->guid);
1754
- $absFileName=$uploadDir['path'] .'/'. $fileName;
1755
- $relFileName=str_replace(ABSPATH,'', $absFileName);
1756
- $fileLink=wp_get_attachment_url($id);
1757
- $pageLink=get_attachment_link($id);
1758
-
1759
- $template=str_replace('{TITLE}', $attachment->post_title, $template);
1760
- $template=str_replace('{ID}', $id, $template);
1761
- $template=str_replace('{THUMBNAIL}', $img_src[0], $template);
1762
- $template=str_replace('{THUMB}', $img_src[0], $template);
1763
- $template=str_replace('{MEDIUM}', $img_src[1], $template);
1764
- $template=str_replace('{LARGE}', $img_src[2], $template);
1765
- $template=str_replace('{FULL}', $fileLink, $template);
1766
- $template=str_replace('{FILELINK}', $fileLink, $template);
1767
- $template=str_replace('{PAGELINK}', $pageLink, $template);
1768
- $template=str_replace('{THUMBWIDTH}', $widths[0] . 'px', $template);
1769
- $template=str_replace('{THUMBHEIGHT}', $heights[0] . 'px', $template);
1770
- $template=str_replace('{MEDIUMWIDTH}', $widths[1] . 'px', $template);
1771
- $template=str_replace('{MEDIUMHEIGHT}', $heights[1] . 'px', $template);
1772
- $template=str_replace('{LARGEWIDTH}', $widths[2] . 'px', $template);
1773
- $template=str_replace('{LARGEHEIGHT}', $heights[2] . 'px', $template);
1774
- $template=str_replace('{FILENAME}', $fileName, $template);
1775
- $template=str_replace('{IMAGE}', $fileLink, $template);
1776
- $template=str_replace('{URL}', $fileLink, $template);
1777
- $template=str_replace('{RELFILENAME}', $relFileName, $template);
1778
- $template=str_replace('{POSTTITLE}', $the_parent->post_title, $template);
1779
- if ($attachment->post_excerpt!='') {
1780
- $template=str_replace('{CAPTION}', $attachment->post_excerpt, $template);
1781
- } elseif (!preg_match("/$attachment->post_title/i", $fileName)) {
1782
- $template=str_replace('{CAPTION}', $attachment->post_title, $template);
1783
- } else {
1784
- //$template=str_replace('{CAPTION}', '', $template);
1785
- }
1786
- return($template . '<br />');
1787
- }
1788
 
1789
  /**
1790
- * When sending in HTML email the html refers to the content-id(CID) of the image - this replaces
1791
- * the cid place holder with the actual url of the image sent in
1792
- * @param string - text of post
1793
- * @param array - array of HTML for images for post
1794
- */
1795
- function ReplaceImageCIDs(&$content,&$attachments) {
1796
  $used = array();
1797
  foreach ($attachments["cids"] as $key => $info) {
1798
  $key = str_replace('/', '\/', $key);
1799
  $pattern = "/cid:$key/";
1800
- if(preg_match($pattern,$content)) {
1801
- $content = preg_replace($pattern,$info[0],$content);
1802
  $used[] = $info[1]; //Index of html to ignore
1803
  }
1804
  }
1805
  $html = array();
1806
  for ($i = 0; $i < count($attachments["html"]); $i++) {
1807
- if (!in_array($i,$used)) {
1808
  $html[] = $attachments["html"][$i];
1809
  }
1810
  }
1811
  $attachments["html"] = $html;
1812
-
1813
  }
 
1814
  /**
1815
- * This function handles replacing image place holder #img1# with the HTML for that image
1816
- * @param string - text of post
1817
- * @param array - array of HTML for images for post
1818
- */
1819
- function ReplaceImagePlaceHolders(&$content,$attachments, $config) {
1820
- extract($config);
1821
- ($start_image_count_at_zero ? $startIndex = 0 :$startIndex = 1);
1822
- if (!empty($attachments) && $auto_gallery) {
1823
- $value = '[gallery]';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1824
  if ($images_append) {
1825
- $content .= $value;
1826
  } else {
1827
- $content = "$value\n". $content;
1828
- }
1829
- return;
1830
- }
1831
- $pictures= array();
1832
- ksort($attachments);
1833
- foreach ( $attachments as $i => $value ) {
1834
- // looks for ' #img1# ' etc... and replaces with image
1835
- $img_placeholder_temp = str_replace("%", intval($startIndex + $i), $image_placeholder);
1836
- $eimg_placeholder_temp = str_replace("%", intval($startIndex + $i),
1837
- "#eimg%#");
1838
- $img_placeholder_temp=rtrim($img_placeholder_temp,'#');
1839
- $eimg_placeholder_temp=rtrim($eimg_placeholder_temp,'#');
1840
- if ( stristr($content, $img_placeholder_temp) ||
1841
- stristr($content, $eimg_placeholder_temp) ) {
1842
- // look for caption
1843
- $caption='';
1844
- $content = preg_replace("/&#0?39;/", "'", $content);
1845
- $content = preg_replace("/&(#0?34|quot);/", "\"", $content);
1846
- if ( preg_match("/$img_placeholder_temp caption=['\"]?(.*?)['\"]?#/", $content, $matches)) {
1847
- $caption =$matches[1];
1848
- $img_placeholder_temp = substr($matches[0], 0, -1);
1849
- $eimg_placeholder_temp = substr($matches[0], 0, -1);
1850
- }
1851
- $value = str_replace('{CAPTION}', $caption, $value);
1852
- $img_placeholder_temp.='#';
1853
- $eimg_placeholder_temp.='#';
1854
- $content = str_replace($img_placeholder_temp, $value, $content);
1855
- $content = str_replace($eimg_placeholder_temp, $value, $content);
1856
- //print(htmlspecialchars("value=$value\n",ENT_QUOTES));
1857
- //print(htmlspecialchars("content=\n***\n$content\n***\n",ENT_QUOTES));
1858
- } else {
1859
- $value = str_replace('{CAPTION}', '', $value);
1860
- /* if using the gallery shortcode, don't add pictures at all */
1861
- if (!preg_match("/\[gallery[^\[]*\]/", $content, $matches)) {
1862
- $pics .= $value;
1863
- }
1864
  }
1865
- }
1866
- if ($images_append) {
1867
- $content .= $pics;
1868
- } else {
1869
- $content = $pics . $content;
1870
- }
1871
  }
 
1872
  /**
1873
- *This function handles finding and setting the correct subject
1874
- * @return array - (subject,content)
1875
- */
1876
- function GetSubject(&$mimeDecodedEmail,&$content, $config) {
1877
- extract($config);
1878
- global $charset;
1879
- //assign the default title/subject
1880
- if ( $mimeDecodedEmail->headers['subject'] == NULL ) {
1881
- if ($allow_subject_in_mail) {
1882
- list($subject,$content) =
1883
- ParseInMessageSubject($content,$default_title);
1884
- }
1885
- else {
1886
- $subject = $default_title;
1887
- }
1888
- $mimeDecodedEmail->headers['subject'] = $subject;
1889
- } else {
1890
- $subject = $mimeDecodedEmail->headers['subject'];
1891
- if ($mimeDecodedEmail->headers["content-transfer-encoding"]!='') {
1892
- $encoding = $mimeDecodedEmail->headers["content-transfer-encoding"];
1893
- } else if ($mimeDecodedEmail->ctype_parameters["content-transfer-encoding"]!='') {
1894
- $encoding = $mimeDecodedEmail->ctype_parameters["content-transfer-encoding"];
1895
  } else {
1896
- $encoding='7bit';
1897
- }
1898
- if (function_exists(imap_mime_header_decode)) {
1899
- $subject='';
1900
- //$elements=imap_mime_header_decode($mimeDecodedEmail->headers['subject']);
1901
- //$text = "=?utf-8?b?w6XDpMO2?= unicode";
1902
- $text=$mimeDecodedEmail->headers['subject'];
1903
- //$text="test emails with ISO 8859-2 cahracters ąęśćółńżźĄĘŚÓŁŃŻŹ";
1904
- //echo "text='$text'\n";
1905
- $elements = imap_mime_header_decode($text);
1906
- for ($i=0; $i<count($elements); $i++) {
1907
- $thischarset=$elements[$i]->charset;
1908
- if ($thischarset=='default')
1909
- $thischarset=$charset;
1910
- //echo "Charset: {$thischarset}\n";
1911
- //echo "Text: ". utf8_encode($elements[$i]->text). "\n\n";
1912
- $subject.=HandleMessageEncoding($encoding, $thischarset,
1913
- $elements[$i]->text, $message_encoding,
1914
- $message_dequote);
1915
- //echo "subject=$subject\n";
1916
- }
1917
- //echo "now subject= $subject\n";
1918
- //if ($element->charset!='') {
1919
- //$charset = $element[0]->charset;
1920
- //echo "charset='$charset'\n";
1921
- // }
1922
- }
1923
- if (!$allow_html_in_subject) {
1924
- $subject = htmlentities($subject);
1925
- }
1926
- }
1927
- //This is for ISO-2022-JP - Can anyone confirm that this is still neeeded?
1928
- // escape sequence is 'ESC $ B' == 1b 24 42 hex.
1929
- if (strpos($subject, "\x1b\x24\x42") !== false) {
1930
- // found iso-2022-jp escape sequence in subject... convert!
1931
- $subject = iconv("ISO-2022-JP//TRANSLIT", "UTF-8", $subject);
1932
- }
1933
- return($subject);
1934
- }
1935
- /**
1936
- * this function determines tags for the post
1937
- *
1938
- */
 
 
 
 
 
1939
  function postie_get_tags(&$content, $defaultTags) {
1940
- $post_tags = array();
1941
- //try and determine tags
1942
- if ( preg_match('/tags: ?(.*)\n/i', $content, $matches)) {
1943
- $content = str_replace($matches[0], "", $content);
1944
- $post_tags = preg_split("/,\s*/", $matches[1]);
1945
- }
1946
- if ( !count( $post_tags ) && !empty( $defaultTags ) ) {
1947
- $post_tags = $defaultTags;
1948
- }
1949
- return($post_tags);
1950
- }
1951
- /**
1952
- * this function determines excerpt for the post
1953
- *
1954
- */
 
1955
  function GetPostExcerpt(&$content, $filterNewLines, $convertNewLines) {
1956
- global $wpdb;
1957
- $post_excerpt = '';
1958
- if ( preg_match('/:excerptstart ?(.*):excerptend/s', $content, $matches)) {
1959
- $content = str_replace($matches[0], "", $content);
1960
- $post_excerpt = $matches[1];
1961
- if ($filterNewLines)
1962
- $post_excerpt = FilterNewLines($post_excerpt, $convertNewLines);
1963
- }
1964
- return($post_excerpt);
1965
  }
 
1966
  /**
1967
- * This function determines categories for the post
1968
- * @return array
1969
- */
1970
  function GetPostCategories(&$subject, $defaultCategory) {
1971
  global $wpdb;
1972
  $post_categories = array();
1973
  $matches = array();
1974
  //try and determine category
1975
- if ( preg_match('/(.+): (.*)/', $subject, $matches)) {
1976
  $subject = trim($matches[2]);
1977
  $matches[1] = array($matches[1]);
1978
- }
1979
- else if (preg_match_all('/\[(.[^\[]*)\]/', $subject, $matches)) {
1980
- preg_match("/](.[^\[]*)$/",$subject,$subject_matches);
1981
  $subject = trim($subject_matches[1]);
1982
- }
1983
- else if ( preg_match_all('/-(.[^-]*)-/', $subject, $matches) ) {
1984
- preg_match("/-(.[^-]*)$/",$subject,$subject_matches);
1985
  $subject = trim($subject_matches[1]);
1986
  }
1987
  if (count($matches)) {
1988
- foreach($matches[1] as $match) {
1989
  $match = trim($match);
1990
  $category = NULL;
1991
- print("Working on $match\n");
1992
 
1993
  $sql_name = 'SELECT term_id
1994
- FROM ' . $wpdb->terms. '
1995
  WHERE name=\'' . addslashes($match) . '\'';
1996
  $sql_id = 'SELECT term_id
1997
- FROM ' . $wpdb->terms. '
1998
  WHERE term_id=\'' . addslashes($match) . '\'';
1999
  $sql_sub_name = 'SELECT term_id
2000
- FROM ' . $wpdb->terms. '
2001
  WHERE name LIKE \'' . addslashes($match) . '%\' limit 1';
2002
-
2003
- if ( $category = $wpdb->get_var($sql_name) ) {
2004
  //then category is a named and found
2005
- } elseif ( $category = $wpdb->get_var($sql_id) ) {
2006
  //then cateogry was an ID and found
2007
- } elseif ( $category = $wpdb->get_var($sql_sub_name) ) {
2008
  //then cateogry is a start of a name and found
2009
- }
2010
  if ($category) {
2011
  $post_categories[] = $category;
2012
  }
2013
  }
2014
  }
2015
  if (!count($post_categories)) {
2016
- $post_categories[] = $defaultCategory;
2017
  }
2018
  return($post_categories);
2019
  }
 
2020
  /**
2021
- *This function just outputs a simple html report about what is being posted in
2022
- */
2023
  function DisplayEmailPost($details) {
2024
- if( defined( 'POSTIE_DEBUG' ) ) {
2025
- print_r($config);
2026
- print_r($details);
2027
- }
2028
- $theFinalContent=$details['post_content'];
2029
- // Report
2030
- print '</pre><p><b>Post Author</b>: ' . $details["post_author"]. '<br />' . "\n";
2031
- print '<b>Date</b>: ' . $details["post_date"] . '<br />' . "\n";
2032
- foreach($details["post_category"] as $category) {
2033
- print '<b>Category</b>: ' . $category . '<br />' . "\n";
2034
- }
2035
- print '<b>Ping Status</b>: ' . $details["ping_status"] . '<br />' . "\n";
2036
- print '<b>Comment Status</b>: ' . $details["comment_status"] . '<br />' . "\n";
2037
- print '<b>Subject</b>: ' . $details["post_title"]. '<br />' . "\n";
2038
- print '<b>Postname</b>: ' . $details["post_name"] . '<br />' . "\n";
2039
- print '<b>Post Id</b>: ' . $details["ID"] . '<br />' . "\n";
2040
- print '<b>Posted content:</b></p><hr />' .
2041
- $details["post_content"] . '<hr /><pre>';
2042
- //if (function_exists('memory_get_peak_usage'))
2043
  // echo "Memory used: ". memory_get_peak_usage(). "\n";
2044
  }
 
2045
  /**
2046
- * Takes a value and builds a simple simple yes/no select box
2047
- * @param string
2048
- * @param string
2049
- * @param string
2050
- * @param string
2051
- */
2052
- function BuildBooleanSelect($label,$id,$current_value,$recommendation = NULL) {
2053
- $string="<tr>
2054
- <th scope=\"row\">". __($label, 'postie').":</th>
2055
  <td><select name=\"$id\" id=\"$id\">
2056
- <option value=\"1\">".__("Yes", 'postie')."</option>
2057
- <option value=\"0\" ". (!$current_value ? "SELECTED" : NULL) .
2058
- ">".__("No", 'postie').'</option>
2059
  </select>';
2060
- if ($recommendation!=NULL) {
2061
- $string.='<span class="recommendation">'.__($recommendation,
2062
- 'postie').'</span>';
2063
  }
2064
  $string.="</td>\n</tr>";
2065
  return($string);
2066
  }
 
2067
  /**
2068
- * This takes an array and display a text box for editing
2069
- *@param string
2070
- *@param string
2071
- *@param array
2072
- *@param string
2073
- */
2074
- function BuildTextArea($label,$id,$current_value,$recommendation = NULL) {
2075
- $string = "<tr> <th scope=\"row\">".__($label, 'postie').":";
2076
- if ($recommendation) {
2077
- $string.="<br /><span class='recommendation'>".__($recommendation,
2078
- 'postie')."</span>";
2079
- }
2080
- $string.="</th>";
2081
-
2082
- $string .="<td><textarea cols=40 rows=3 name=\"$id\" id=\"$id\">";
2083
- $current_value = preg_split("/[,\r\n]+/", trim($current_value));
2084
- if (is_array($current_value)) {
2085
- foreach($current_value as $item) {
2086
- $string .= "$item\n";
2087
- }
2088
- }
2089
- $string .= "</textarea></td>
2090
  </tr>";
2091
- return($string);
2092
  }
 
2093
  /**
2094
- *This function resets all the configuration options to the default
2095
- */
2096
  function ResetPostieConfig() {
2097
- $newconfig = get_postie_config_defaults();
2098
- $config = get_option( 'postie-settings' ) ;
2099
- $save_keys=array( 'mail_password', 'mail_server', 'mail_server_port', 'mail_userid', 'iinput_protocol' );
2100
- foreach ( $save_keys as $key )
2101
- $newconfig[$key] = $config[$key];
2102
- update_option( 'postie-settings', $newconfig );
2103
- UpdatePostieConfig( $newconfig );
2104
- return $newconfig;
2105
  }
2106
 
2107
  /**
2108
- * This function used to handle updating the configuration.
2109
- *@return boolean
2110
- */
2111
  function UpdatePostieConfig($data) {
2112
- UpdatePostiePermissions( $data["role_access"] );
2113
- // We also update the cron settings
2114
- if ($data['interval']!='') {
2115
- postie_decron();
2116
- if ($data['interval']!='manual') {
2117
- postie_cron($interval=$data['interval']);
 
2118
  }
2119
- }
2120
- return(1);
2121
  }
 
2122
  /**
2123
- * return an array of the config defaults
2124
- */
2125
  function get_postie_config_defaults() {
2126
- include('templates/audio_templates.php');
2127
- include('templates/image_templates.php');
2128
- include('templates/video1_templates.php');
2129
- include('templates/video2_templates.php');
2130
- return array(
2131
- 'add_meta' => 'no',
2132
- 'admin_username' => 'admin',
2133
- 'allow_html_in_body' => true,
2134
- 'allow_html_in_subject' => true,
2135
- 'allow_subject_in_mail' => true,
2136
- 'audiotemplate' =>$simple_link,
2137
- 'audiotypes' => array( 'm4a', 'mp3','ogg', 'wav', 'mpeg' ),
2138
- 'authorized_addresses' => array(),
2139
- 'banned_files_list' => array(),
2140
- 'confirmation_email' => '',
2141
- 'convertnewline' => false,
2142
- 'converturls' => true,
2143
- 'custom_image_field' => false,
2144
- 'default_post_category' => NULL,
2145
- 'default_post_tags' => array(),
2146
- 'default_title' => "Live From The Field",
2147
- 'delete_mail_after_processing' => true,
2148
- 'drop_signature' => true,
2149
- 'filternewlines' => true,
2150
- 'forward_rejected_mail' => true,
2151
- 'icon_set' => 'silver',
2152
- 'icon_size' => 32,
2153
- 'auto_gallery' => false,
2154
- 'image_new_window' => false,
2155
- 'image_placeholder' => "#img%#",
2156
- 'images_append' => true,
2157
- 'imagetemplate' => $wordpress_default,
2158
- 'imagetemplates' => $imageTemplates,
2159
- 'input_protocol' => "pop3",
2160
- 'interval' => 'twiceperhour',
2161
- 'mail_server' => NULL,
2162
- 'mail_server_port' => 110,
2163
- 'mail_userid' => NULL,
2164
- 'mail_password' => NULL,
2165
- 'message_start' => ":start",
2166
- 'message_end' => ":end",
2167
- 'message_encoding' => "UTF-8",
2168
- 'message_dequote' => true,
2169
- 'post_status' => 'publish',
2170
- 'prefer_text_type' => "plain",
2171
- 'return_to_sender' => false,
2172
- 'role_access' => array(),
2173
- 'selected_audiotemplate' => 'simple_link',
2174
- 'selected_imagetemplate' => 'wordpress_default',
2175
- 'selected_video1template' => 'simple_link',
2176
- 'selected_video2template' => 'simple_link',
2177
- 'shortcode' => false,
2178
- 'sig_pattern_list' => array( '--', '- --' ),
2179
- 'smtp' => array(),
2180
- 'start_image_count_at_zero' => false,
2181
- 'supported_file_types' => array( 'video', 'application' ),
2182
- 'turn_authorization_off' => false,
2183
- 'time_offset' => get_option('gmt_offset'),
2184
- 'video1template' => $simple_link,
2185
- 'video1types' => array( 'mp4', 'mpeg4', '3gp', '3gpp', '3gpp2', '3gp2', 'mov', 'mpeg' ),
2186
- 'video2template' => $simple_link,
2187
- 'video2types' => array( 'x-flv' ),
2188
- 'video1templates' => $video1Templates,
2189
- 'video2templates' => $video2Templates,
2190
- 'wrap_pre' => 'no'
2191
  );
2192
  }
 
2193
  /**
2194
- *=======================================================
2195
- * the following functions are only used to retrieve the old (pre 1.4) config, to convert it
2196
- * to the new format
2197
- */
2198
  function GetListOfArrayConfig() {
2199
- return(array('SUPPORTED_FILE_TYPES','AUTHORIZED_ADDRESSES',
2200
- 'SIG_PATTERN_LIST','BANNED_FILES_LIST', 'VIDEO1TYPES',
2201
- 'VIDEO2TYPES', 'AUDIOTYPES', 'SMTP'));
2202
  }
 
2203
  /**
2204
- *This function retrieves the old-format config (pre 1.4) from the database
2205
- * @return array
2206
- */
2207
  function ReadDBConfig() {
2208
- $config = array();
2209
- global $wpdb;
2210
- $data = $wpdb->get_results("SELECT label,value FROM ". $GLOBALS["table_prefix"] . "postie_config;");
2211
- if (is_array($data)) {
2212
- foreach($data as $row) {
2213
- if (in_array($row->label,GetListOfArrayConfig())) {
2214
- $config[$row->label] = unserialize($row->value);
2215
- } else {
2216
- $config[$row->label] = $row->value;
2217
- }
 
2218
  }
2219
- }
2220
- return($config);
2221
  }
 
2222
  /**
2223
- * This function processes the old-format config (pre 1.4) for conversion to the 1.4 format
2224
- * @return array
2225
- * @access private
2226
- */
2227
  function GetDBConfig() {
2228
  $config = ReadDBConfig();
2229
- if (!isset($config["ADMIN_USERNAME"]))
2230
- $config["ADMIN_USERNAME"] = 'admin';
2231
- if (!isset($config["PREFER_TEXT_TYPE"]))
2232
- $config["PREFER_TEXT_TYPE"] = "plain";
2233
- if (!isset($config["DEFAULT_TITLE"]))
2234
- $config["DEFAULT_TITLE"] = "Live From The Field";
2235
- if (!isset($config["INPUT_PROTOCOL"]))
2236
- $config["INPUT_PROTOCOL"] = "pop3";
2237
- if (!isset($config["IMAGE_PLACEHOLDER"]))
2238
- $config["IMAGE_PLACEHOLDER"] = "#img%#";
2239
- if (!isset($config["IMAGES_APPEND"]))
2240
- $config["IMAGES_APPEND"] = true;
2241
- if (!isset($config["ALLOW_SUBJECT_IN_MAIL"]))
2242
- $config["ALLOW_SUBJECT_IN_MAIL"] = true;
2243
  if (!isset($config["DROP_SIGNATURE"]))
2244
- $config["DROP_SIGNATURE"] = true;
2245
- if (!isset($config["MESSAGE_START"]))
2246
- $config["MESSAGE_START"] = ":start";
2247
- if (!isset($config["MESSAGE_END"]))
2248
- $config["MESSAGE_END"] = ":end";
2249
- if (!isset($config["FORWARD_REJECTED_MAIL"]))
2250
- $config["FORWARD_REJECTED_MAIL"] = true;
2251
- if (!isset($config["RETURN_TO_SENDER"]))
2252
- $config["RETURN_TO_SENDER"] = false;
2253
- if (!isset($config["CONFIRMATION_EMAIL"]))
2254
- $config["CONFIRMATION_EMAIL"] = '';
2255
- if (!isset($config["ALLOW_HTML_IN_SUBJECT"]))
2256
- $config["ALLOW_HTML_IN_SUBJECT"] = true;
2257
- if (!isset($config["ALLOW_HTML_IN_BODY"]))
2258
- $config["ALLOW_HTML_IN_BODY"] = true;
2259
- if (!isset($config["START_IMAGE_COUNT_AT_ZERO"]))
2260
- $config["START_IMAGE_COUNT_AT_ZERO"] = false;
2261
- if (!isset($config["MESSAGE_ENCODING"]))
2262
- $config["MESSAGE_ENCODING"] = "UTF-8";
2263
- if (!isset($config["MESSAGE_DEQUOTE"]))
2264
- $config["MESSAGE_DEQUOTE"] = true;
2265
- if (!isset($config["TURN_AUTHORIZATION_OFF"]))
2266
- $config["TURN_AUTHORIZATION_OFF"] = false;
2267
- if (!isset($config["CUSTOM_IMAGE_FIELD"]))
2268
- $config["CUSTOM_IMAGE_FIELD"] = false;
2269
- if (!isset($config["CONVERTNEWLINE"]))
2270
- $config["CONVERTNEWLINE"] = false;
2271
- if (!isset($config["SIG_PATTERN_LIST"]))
2272
- $config["SIG_PATTERN_LIST"] = array('--','- --');
2273
  if (!isset($config["BANNED_FILES_LIST"]))
2274
- $config["BANNED_FILES_LIST"] = array();
2275
  if (!isset($config["SUPPORTED_FILE_TYPES"]))
2276
- $config["SUPPORTED_FILE_TYPES"] = array("video","application");
2277
- if (!isset($config["AUTHORIZED_ADDRESSES"]))
2278
- $config["AUTHORIZED_ADDRESSES"] = array();
2279
- if (!isset($config["MAIL_SERVER"]))
2280
- $config["MAIL_SERVER"] = NULL;
2281
- if (!isset($config["MAIL_SERVER_PORT"]))
2282
- $config["MAIL_SERVER_PORT"] = NULL;
2283
- if (!isset($config["MAIL_USERID"]))
2284
- $config["MAIL_USERID"] = NULL;
2285
- if (!isset($config["MAIL_PASSWORD"]))
2286
- $config["MAIL_PASSWORD"] = NULL;
2287
- if (!isset($config["DEFAULT_POST_CATEGORY"]))
2288
- $config["DEFAULT_POST_CATEGORY"] = NULL;
2289
- if (!isset($config["DEFAULT_POST_TAGS"]))
2290
- $config["DEFAULT_POST_TAGS"] = NULL;
2291
- if (!isset($config["TIME_OFFSET"]))
2292
- $config["TIME_OFFSET"] = get_option('gmt_offset');
2293
- if (!isset($config["WRAP_PRE"]))
2294
- $config["WRAP_PRE"] = 'no';
2295
- if (!isset($config["CONVERTURLS"]))
2296
- $config["CONVERTURLS"] = true;
2297
- if (!isset($config["SHORTCODE"]))
2298
- $config["SHORTCODE"] = false;
2299
- if (!isset($config["ADD_META"]))
2300
- $config["ADD_META"] = 'no';
2301
- $config['ICON_SETS']=array('silver','black','white','custom', 'none');
2302
- if (!isset($config["ICON_SET"]))
2303
- $config["ICON_SET"] = 'silver';
2304
- $config['ICON_SIZES']=array(32,48,64);
2305
- if (!isset($config["ICON_SIZE"]))
2306
- $config["ICON_SIZE"] = 32;
2307
- if (!isset($config["AUDIOTEMPLATE"]))
2308
- $config["AUDIOTEMPLATE"] =$simple_link;
2309
- if (!isset($config["SELECTED_AUDIOTEMPLATE"]))
2310
- $config['SELECTED_AUDIOTEMPLATE'] = 'simple_link';
2311
  include('templates/audio_templates.php');
2312
- $config['AUDIOTEMPLATES']=$audioTemplates;
2313
- if (!isset($config["SELECTED_VIDEO1TEMPLATE"]))
2314
- $config['SELECTED_VIDEO1TEMPLATE'] = 'simple_link';
2315
  include('templates/video1_templates.php');
2316
- $config['VIDEO1TEMPLATES']=$video1Templates;
2317
- if (!isset($config["VIDEO1TEMPLATE"]))
2318
- $config["VIDEO1TEMPLATE"] = $simple_link;
2319
- if (!isset($config["VIDEO1TYPES"]))
2320
- $config['VIDEO1TYPES'] = array('mp4', 'mpeg4', '3gp', '3gpp', '3gpp2',
2321
- '3gp2', 'mov', 'mpeg');
2322
- if (!isset($config["AUDIOTYPES"]))
2323
- $config['AUDIOTYPES'] = array('m4a', 'mp3', 'ogg', 'wav', 'mpeg');
2324
- if (!isset($config["SELECTED_VIDEO2TEMPLATE"]))
2325
- $config['SELECTED_VIDEO2TEMPLATE'] = 'simple_link';
2326
  include('templates/video2_templates.php');
2327
- $config['VIDEO2TEMPLATES']=$video2Templates;
2328
- if (!isset($config["VIDEO2TEMPLATE"]))
2329
- $config["VIDEO2TEMPLATE"] = $simple_link;
2330
- if (!isset($config["VIDEO2TYPES"]))
2331
- $config['VIDEO2TYPES'] = array('x-flv');
2332
- if (!isset($config["POST_STATUS"]))
2333
- $config["POST_STATUS"] = 'publish';
2334
- if (!isset($config["IMAGE_NEW_WINDOW"]))
2335
- $config["IMAGE_NEW_WINDOW"] = false;
2336
- if (!isset($config["FILTERNEWLINES"]))
2337
- $config["FILTERNEWLINES"] = true;
2338
  include('templates/image_templates.php');
2339
- $config['IMAGETEMPLATES']=$imageTemplates;
2340
  if (!isset($config["SELECTED_IMAGETEMPLATE"]))
2341
- $config['SELECTED_IMAGETEMPLATE'] = 'wordpress_default';
2342
- if (!isset($config["IMAGETEMPLATE"]))
2343
- $config["IMAGETEMPLATE"] = $wordpress_default;
2344
- if (!isset($config["SMTP"]))
2345
- $config["SMTP"] = array();
2346
  return($config);
2347
  }
 
2348
  /**
2349
- * This function returns the old-format config (pre 1.4)
2350
- * @return array
2351
- */
2352
  function GetConfig() {
2353
- $config = GetDBConfig();
2354
- //These should only be modified if you are testing
2355
- $config["DELETE_MAIL_AFTER_PROCESSING"] = true;
2356
- $config["POST_TO_DB"] = true;
2357
- $config["TEST_EMAIL"] = false;
2358
- $config["TEST_EMAIL_ACCOUNT"] = "blogtest";
2359
- $config["TEST_EMAIL_PASSWORD"] = "yourpassword";
2360
- if (file_exists(POSTIE_ROOT . '/postie_test_variables.php')) {
2361
- include(POSTIE_ROOT . '/postie_test_variables.php');
2362
- }
2363
- //include(POSTIE_ROOT . "/../postie-test.php");
2364
- // These are computed
2365
- $config["TIME_OFFSET"] = get_option('gmt_offset');
2366
- $config["POSTIE_ROOT"] = POSTIE_ROOT;
2367
- for ($i = 0; $i < count($config["AUTHORIZED_ADDRESSES"]); $i++) {
2368
- $config["AUTHORIZED_ADDRESSES"][$i] = strtolower($config["AUTHORIZED_ADDRESSES"][$i]);
2369
- }
2370
- return $config;
2371
  }
 
2372
  /**
2373
- * end of functions used to retrieve the old (pre 1.4) config
2374
- *=======================================================
2375
- */
 
2376
  /**
2377
- * This function returns the current config
2378
- * @return array
2379
- */
2380
  function get_postie_config() {
2381
- $config = get_option( 'postie-settings' );
2382
- if (file_exists(POSTIE_ROOT . '/postie_test_variables.php')) {
2383
- include(POSTIE_ROOT . '/postie_test_variables.php');
2384
- }
2385
- // These are computed
2386
- $config["time_offset"] = get_option('gmt_offset');
2387
- $config["postie_root"] = POSTIE_ROOT;
2388
- return $config;
2389
  }
 
2390
  /**
2391
- * Returns a list of config keys that should be arrays
2392
- *@return array
2393
- */
2394
  function get_arrayed_settings() {
2395
- return array(
2396
- ',' => array('audiotypes', 'video1types', 'video2types', 'default_post_tags'),
2397
- "\n" => array('smtp', 'authorized_addresses', 'supported_file_types',
2398
- 'banned_files_list', 'sig_pattern_list') );
2399
  }
 
2400
  /**
2401
- * Detects if they can do IMAP
2402
- * @return boolean
2403
- */
2404
  function HasIMAPSupport($display = true) {
2405
- $function_list = array("imap_open",
2406
- "imap_delete",
2407
- "imap_expunge",
2408
- "imap_body",
2409
- "imap_fetchheader");
2410
- return(HasFunctions($function_list,$display));
2411
  }
 
2412
  function HasIconvInstalled($display = true) {
2413
- $function_list = array("iconv");
2414
- return(HasFunctions($function_list,$display));
2415
  }
 
2416
  /**
2417
- * Handles verifing that a list of functions exists
2418
- * @return boolean
2419
- * @param array
2420
- */
2421
- function HasFunctions($function_list,$display = true) {
2422
- foreach ($function_list as $function) {
2423
- if (!function_exists($function)) {
2424
- if ($display) {
2425
- print("<p>Missing $function");
2426
- }
2427
- return(false);
 
2428
  }
2429
- }
2430
- return(true);
2431
  }
 
2432
  /**
2433
- * This function tests to see if postie is its own directory
2434
- */
2435
  function TestPostieDirectory() {
2436
- $dir_parts = explode(DIRECTORY_SEPARATOR,dirname(__FILE__));
2437
- $last_dir = array_pop($dir_parts);
2438
- if ($last_dir != "postie") {
2439
- return false;
2440
- }
2441
- return true;
2442
  }
 
2443
  /**
2444
- *This function looks for markdown which causes problems with postie
2445
- */
2446
  function TestForMarkdown() {
2447
- if (in_array("markdown.php",get_option("active_plugins"))) {
2448
  return(true);
2449
  }
2450
  return(false);
2451
-
2452
  }
 
2453
  /**
2454
- * validates the config form output, fills in any gaps by using the defaults,
2455
- * and ensures that arrayed items are stored as such
2456
- */
2457
- function postie_validate_settings( $in ) {
2458
- if ( defined ( 'POSTIE_DEBUG' ) ) var_dump( $in );
2459
- $out = array();
2460
-
2461
- // use the default as a template:
2462
- // if a field is present in the defaults, we want to store it; otherwise we discard it
2463
- $allowed_keys = get_postie_config_defaults();
2464
- foreach ( $allowed_keys as $key => $default )
2465
- $out[$key] = array_key_exists( $key, $in ) ? $in[$key] : $default;
2466
-
2467
- // some fields are always forced to lower case:
2468
- $lowercase = array( 'authorized_addresses', 'smtp', 'supported_file_types', 'video1types', 'video2types', 'audiotypes' );
2469
- foreach ($lowercase as $field) {
2470
- $out[$field] = ( is_array( $out[$field] ) ) ? array_map( strtolower, $out[$field] ) : strtolower( $out[$field] );
2471
- }
2472
- $arrays = get_arrayed_settings();
2473
-
2474
- foreach ( $arrays as $sep => $fields ) {
2475
- foreach ( $fields as $field ) {
2476
- if ( !is_array( $out[$field] ) )
2477
- $out[$field] = explode( $sep, trim( $out[$field] ) );
2478
- foreach ( $out[$field] as $key => $val ) {
2479
- $tst = trim($val);
2480
- if ( empty( $tst ) ) {
2481
- unset( $out[$field][$key] );
2482
- } else {
2483
- $out[$field][$key] = $tst;
2484
- }
2485
- }
2486
- }
2487
- }
 
2488
 
2489
- UpdatePostieConfig( $out );
2490
- return $out;
2491
  }
 
2492
  /**
2493
- * registers the settings and the admin optionspage
2494
- */
2495
  function postie_admin_settings() {
2496
- register_setting( 'postie-settings', 'postie-settings', 'postie_validate_settings' );
2497
  }
 
2498
  /**
2499
- * This function handles setting up the basic permissions
2500
- */
2501
- function UpdatePostiePermissions( $role_access ) {
2502
- global $wp_roles;
2503
- $admin = $wp_roles->get_role("administrator");
2504
- $admin->add_cap("config_postie");
2505
- $admin->add_cap("post_via_postie");
2506
- if (!is_array($role_access)) {
2507
- $role_access = array();
2508
- }
2509
- foreach($wp_roles->role_names as $roleId => $name) {
2510
- $role = &$wp_roles->get_role($roleId);
2511
- if ($roleId != "administrator") {
2512
- if ($role_access[$roleId]) {
2513
- $role->add_cap("post_via_postie");
2514
- } else {
2515
- $role->remove_cap("post_via_postie");
2516
- }
 
2517
  }
2518
- }
2519
- }
2520
- function DebugEmailOutput(&$email,&$mimeDecodedEmail) {
2521
- $file = fopen("test_emails/" . $mimeDecodedEmail->headers["message-id"].".txt","w");
2522
- fwrite($file, $email);
2523
- fclose($file);
2524
- $file = fopen("test_emails/" . $mimeDecodedEmail->headers["message-id"]."-mime.txt","w");
2525
- fwrite($file, print_r($mimeDecodedEmail,true));
2526
- fclose($file);
2527
- }
2528
- /**
2529
- * This function provides a hook to be able to write special parses for provider emails that are difficult to work with
2530
- * If you want to extend this functionality - write a new function and call it from here
2531
- */
2532
- function SpecialMessageParsing(&$content, &$attachments, $config){
2533
- extract($config);
2534
- if ( preg_match('/You have been sent a message from Vodafone mobile/',$content)) {
2535
- VodafoneHandler($content, $attachments); //Everything for this type of message is handled below
2536
- return;
2537
- }
2538
- if ( $message_start ) {
2539
- StartFilter($content,$message_start);
2540
- }
2541
- if ( $message_end ) {
2542
- EndFilter($content,$message_end);
2543
- }
2544
- if ( $drop_signature ) {
2545
- $content = remove_signature( $content, $sig_pattern_list );
2546
- }
2547
- if ($prefer_text_type == "html"
2548
- && count($attachments["cids"])) {
2549
- ReplaceImageCIDs($content,$attachments);
2550
- }
2551
- if (!$custom_image_field) {
2552
- ReplaceImagePlaceHolders($content,$attachments["html"], $config);
2553
- } else {
2554
- $customImages=array();
2555
- foreach ($attachments["html"] as $value) {
2556
- preg_match("/src=['\"]([^'\"]*)['\"]/", $value, $matches);
2557
- array_push($customImages,$matches[1]);
2558
- }
2559
-
2560
- return($customImages);
2561
- }
2562
- return(NULL);
2563
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2564
  /**
2565
- * Special Vodafone handler - their messages are mostly vendor trash - this strips them down.
2566
- */
2567
- function VodafoneHandler(&$content, &$attachments){
2568
- $index = strpos($content,"TEXT:");
2569
  if (strpos !== false) {
2570
- $alt_content = substr($content,$index,strlen($content));
2571
- if (preg_match("/<font face=\"verdana,helvetica,arial\" class=\"standard\" color=\"#999999\"><b>(.*)<\/b>/",$alt_content,$matches)) {
2572
  //The content is now just the text of the message
2573
  $content = $matches[1];
2574
  //Now to clean up the attachments
2575
- $vodafone_images = array("live.gif","smiley.gif","border_left_txt.gif","border_top.gif","border_bot.gif","border_right.gif","banner1.gif","i_text.gif","i_picture.gif",);
2576
- while(list($key,$value) = each($attachments['cids'])) {
2577
  if (!in_array($key, $vodafone_images)) {
2578
- $content .= "<br/>".$attachments['html'][$attachments['cids'][$key][1]] ;
2579
  }
2580
  }
2581
  }
2582
  }
2583
-
2584
  }
2585
 
2586
- define('WP_POST_REVISIONS', $revisions);
2587
- if (!ini_get('safe_mode')) {
2588
- ini_set('memory_limit', $original_mem_limit);
2589
- }
2590
  ?>
1
  <?php
2
+
3
+ function postie_disable_revisions($restore = false) {
4
+ global $_wp_post_type_features, $_postie_revisions;
5
+
6
+ if (!$restore) {
7
+ $_postie_revisions = false;
8
+ if (isset($_wp_post_type_features['post']) && isset($_wp_post_type_features['post']['revisions'])) {
9
+ $_postie_revisions = $_wp_post_type_features['post']['revisions'];
10
+ unset($_wp_post_type_features['post']['revisions']);
11
+ }
12
+ } else {
13
+ if ($_postie_revisions) {
14
+ $_wp_post_type_features['post']['revisions'] = $_postie_revisions;
15
+ }
16
+ }
17
+ }
18
+
19
+ function postie_increase_memory($restore = false) {
20
+ global $_postie_original_memory_limit, $_postie_original_max_execution_time;
21
+
22
+ if (!ini_get('safe_mode')) {
23
+ if (!$restore) {
24
+
25
+ $_postie_original_memory_limit = ini_get('memory_limit');
26
+ $_postie_original_max_execution_time = ini_get('max_execution_time');
27
+ ini_set('memory_limit', -1);
28
+ ini_set('max_execution_time', 300);
29
+ } else {
30
+ if (isset($_postie_original_memory_limit)) {
31
+ ini_set('memory_limit', $_postie_original_memory_limit);
32
+ }
33
+ if (isset($_postie_original_max_execution_time)) {
34
+ ini_set('max_execution_time', $_postie_original_max_execution_time);
35
+ }
36
+ }
37
+ }
38
  }
39
 
40
  //include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR."wp-admin" . DIRECTORY_SEPARATOR . "upgrade-functions.php");
41
  /*
42
+ $Id: postie-functions.php 625325 2012-11-14 19:29:41Z WayneAllen $
43
+ */
44
 
45
+ /* TODO
46
  * html purify
47
  * USE built-in php message decoding to improve speed
48
  * Add custom fields
49
  * support for flexible upload plugin
50
  * iso 8859-2 support
51
  * add private post function
52
+ http://forum.robfelty.com/topic/how-to-private-posts-from-postie?replies=2#post-1515
53
  * category per e-mail address
54
  */
55
 
57
 
58
  /* this function is necessary for wildcard matching on non-posix systems */
59
  if (!function_exists('fnmatch')) {
60
+
61
+ function fnmatch($pattern, $string) {
62
+ $pattern = strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' =>
63
+ '.', '\[' => '[', '\]' => ']'));
64
+ return @preg_match(
65
+ '/^' . strtr(addcslashes($pattern, '/\\.+^$(){}=!<>|'), array('*' => '.*', '?' => '.?')) . '$/i', $string
66
+ );
67
+ }
68
+
69
  }
70
 
71
  /**
72
+ * This is the main handler for all of the processing
73
+ */
74
+ function PostEmail($poster, $mimeDecodedEmail, $config) {
75
+ postie_disable_revisions();
76
+ postie_increase_memory();
77
+ extract($config);
78
+ $post_to_db = true;
79
+
80
+ $attachments = array(
81
+ "html" => array(), //holds the html for each image
82
+ "cids" => array(), //holds the cids for HTML email
83
+ "image_files" => array() //holds the files for each image
84
+ );
85
+ print("<p>Message Id is :" .
86
+ htmlentities($mimeDecodedEmail->headers["message-id"]) . "</p><br/>\n");
87
+ if (defined('POSTIE_DEBUG')) {
88
+ foreach ($mimeDecodedEmail->parts as $parts) {
89
+ print("<p>" . $parts->ctype_primary . " " . $parts->ctype_secondary) . "</p>\n";
90
+ }
91
+ echo "<p>Email is:</p>";
92
+ var_dump($mimeDecodedEmail);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
94
+ FilterTextParts($mimeDecodedEmail, $prefer_text_type);
95
+ $tmpPost = array('post_title' => 'tmptitle',
96
+ 'post_content' => 'tmpPost');
97
+ /* in order to do attachments correctly, we need to associate the
98
+ attachments with a post. So we add the post here, then update it
99
+ */
100
+ $post_id = wp_insert_post($tmpPost);
101
+ if (defined('POSTIE_DEBUG')) {
102
+ echo "the id is $post_id\n";
103
+ }
104
+ $content = GetContent($mimeDecodedEmail, $attachments, $post_id, $poster, $config);
105
+ if (defined('POSTIE_DEBUG')) {
106
+ echo "the content is $content\n";
107
+ }
108
+ $subject = GetSubject($mimeDecodedEmail, $content, $config);
109
+ if (defined('POSTIE_DEBUG')) {
110
+ echo "the subject is $subject, right after calling GetSubject\n";
111
+ }
112
+ $customImages = SpecialMessageParsing($content, $attachments, $config);
113
+ $post_excerpt = GetPostExcerpt($content, $filternewlines, $convertnewline);
114
+ $postAuthorDetails = getPostAuthorDetails($subject, $content, $mimeDecodedEmail);
115
+ $message_date = NULL;
116
+ if (array_key_exists("date", $mimeDecodedEmail->headers)
117
+ && !empty($mimeDecodedEmail->headers["date"])) {
118
+ $message_date = HandleMessageEncoding(
119
+ $mimeDecodedEmail->headers["content-transfer-encoding"], $mimeDecodedEmail->ctype_parameters["charset"], $mimeDecodedEmail->headers["date"], $message_encoding, $message_dequote);
120
+ //$message_date = $mimeDecodedEmail->headers['date'];
121
+ }
122
+ list($post_date, $post_date_gmt, $delay) = DeterminePostDate($content, $message_date, $time_offset);
123
+ ubb2HTML($content);
124
+
125
+ if ($converturls)
126
+ $content = clickableLink($content, $shortcode);
127
+
128
+ //$content = FixEmailQuotes($content);
129
+
130
+ $id = checkReply($subject);
131
+ $post_categories = GetPostCategories($subject, $default_post_category);
132
+ $post_tags = postie_get_tags($content, $default_post_tags);
133
+ $comment_status = AllowCommentsOnPost($content);
134
+
135
+ if ((empty($id) || is_null($id))) {
136
+ $id = $post_id;
137
+ $isReply = false;
138
+ if ($add_meta == 'yes') {
139
+ if ($wrap_pre == 'yes') {
140
+ $content = $postAuthorDetails['content'] . "<pre>\n" . $content . "</pre>\n";
141
+ $content = "<pre>\n" . $content . "</pre>\n";
142
+ } else {
143
+ $content = $postAuthorDetails['content'] . $content;
144
+ $content = $content;
145
+ }
146
+ } else {
147
+ if ($wrap_pre == 'yes') {
148
+ $content = "<pre>\n" . $content . "</pre>\n";
149
+ }
150
+ }
151
+ } else {
152
+ $isReply = true;
153
+ // strip out quoted content
154
+ $lines = explode("\n", $content);
155
+ //$lines=preg_split('/([\r\n]|<br \/>)/',$content);
156
+ $newContents = '';
157
+ foreach ($lines as $line) {
158
+ //$match=preg_match("/^>.*/i",$line);
159
+ //echo "line=$line, match=$match";
160
+ if (preg_match("/^>.*/i", $line) == 0 &&
161
+ preg_match("/^(from|subject|to|date):.*?/i", $line) == 0 &&
162
+ preg_match("/^-+.*?(from|subject|to|date).*?/i", $line) == 0 &&
163
+ preg_match("/^on.*?wrote:$/i", $line) == 0 &&
164
+ preg_match("/^-+\s*forwarded\s*message\s*-+/i", $line) == 0) {
165
+ $newContents.="$line\n";
166
+ }
167
+ }
168
+ $content = $newContents;
169
+ wp_delete_post($post_id);
170
  }
171
+ if ($filternewlines)
172
+ $content = FilterNewLines($content, $convertnewline);
173
+
174
+
175
+ if ($delay != 0 && $post_status == 'publish') {
176
+ $post_status = 'future';
177
+ } else {
178
+ $post_status = $post_status;
179
+ }
180
+ // DEBUG
181
+ $details = array(
182
+ 'post_author' => $poster,
183
+ 'comment_author' => $postAuthorDetails['author'],
184
+ 'comment_author_url' => $postAuthorDetails['comment_author_url'],
185
+ 'user_ID' => $postAuthorDetails['user_ID'],
186
+ 'email_author' => $postAuthorDetails['email'],
187
+ 'post_date' => $post_date,
188
+ // 'post_date_gmt' => $post_date_gmt,
189
+ // 'post_content' => apply_filters('content_save_pre',$content),
190
+ 'post_content' => $content,
191
+ 'post_title' => $subject,
192
+ // 'post_modified' => $post_date,
193
+ // 'post_modified_gmt' => $post_date_gmt,
194
+ 'ping_status' => get_option('default_ping_status'),
195
+ 'post_category' => $post_categories,
196
+ 'tags_input' => $post_tags,
197
+ 'comment_status' => $comment_status,
198
+ 'post_name' => sanitize_title($subject),
199
+ 'post_excerpt' => $post_excerpt,
200
+ 'ID' => $id,
201
+ 'customImages' => $customImages,
202
+ 'post_status' => $post_status
203
+ );
204
+ $details = apply_filters('postie_post', $details);
205
+ if (empty($details)) {
206
+ // It is possible that the filter has removed the post, in which case, it should not be posted.
207
+ // And if we created a placeholder post (because this was not a reply to an existing post),
208
+ // then it should be removed
209
+ if (!$is_reply) {
210
+ wp_delete_post($post_id);
211
+ }
212
+ } else {
213
+ DisplayEmailPost($details);
214
+ PostToDB($details, $isReply, $post_to_db, $custom_image_field);
215
+ if ($confirmation_email != '') {
216
+ if ($confirmation_email == 'sender') {
217
+ $recipients = array($postAuthorDetails['email']);
218
+ } elseif ($confirmation_email == 'admin') {
219
+ $recipients = array(get_option("admin_email"));
220
+ } elseif ($confirmation_email == 'both') {
221
+ $recipients = array($postAuthorDetails['email'],
222
+ get_option("admin_email"));
223
+ }
224
+ MailToRecipients($mimeDecodedEmail, false, $recipients, false, false);
225
+ }
 
 
 
 
226
  }
227
+ postie_disable_revisions(true);
228
+ postie_increase_memory(true);
229
  }
 
230
 
231
+ /** FUNCTIONS * */
232
+ function clickableLink($text, $shortcode = false) {
233
+ # this functions deserves credit to the fine folks at phpbb.com
234
+ # It turns urls into links, and video urls into embedded players
235
 
236
+ $text = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1:", $text);
 
 
237
 
238
+ // pad it with a space so we can match things at the start of the 1st line.
239
+ $ret = ' ' . $text;
240
+ if (strpos($ret, 'youtube') !== false) {
241
+ // try to embed youtube videos
242
+ $youtube = "#(^|[\n ]|>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9-]+).*?([ \n]|$|<)#is";
243
+ #$youtube="#(^|[\n ]|<p[^<]*>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9]+).*?([ \n]|$|</p>)#is";
244
+ if ($shortcode) {
245
+ $youtube_replace = "\\1[youtube \\3]\\4";
246
+ } else {
247
+ $youtube_replace = "\\1<embed width='425' height='344' allowfullscreen='true' allowscriptaccess='always' type='application/x-shockwave-flash' src=\"http://www.youtube.com/v/\\3&hl=en&fs=1\" />\\4";
248
+ }
249
+ $ret = preg_replace($youtube, $youtube_replace, $ret);
 
250
  }
 
 
251
 
252
+ if (strpos($ret, 'vimeo') !== false) {
253
+ // try to embed vimeo videos
254
  # : http://vimeo.com/6348141
255
+ $vimeo = "#(^|[\n ]|>)[\w]+?://(www\.)?vimeo\.com/([_a-zA-Z0-9-]+).*?([ \n]|$|<)#is";
256
+ #$youtube="#(^|[\n ]|<p[^<]*>)[\w]+?://(www\.)?youtube\.com/watch\?v=([_a-zA-Z0-9]+).*?([ \n]|$|</p>)#is";
257
+ if ($shortcode) {
258
+ $vimeo_replace = "\\1[vimeo \\3]\\4";
259
+ } else {
260
+ $vimeo_replace = "\\1<object width='400' height='300'><param name='allowfullscreen'
261
  value='true' /><param name='allowscriptaccess' value='always' /><param
262
  name='movie'
263
  value='http://vimeo.com/moogaloop.swf?clip_id=\\3&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1'
265
  src='http://vimeo.com/moogaloop.swf?clip_id=\\3&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1'
266
  type='application/x-shockwave-flash' allowfullscreen='true'
267
  allowscriptaccess='always' width='400' height='300'></embed></object>\\4";
268
+ //$vimeo_replace= "\\1<embed width='425' height='344' allowfullscreen='true' allowscriptaccess='always' type='application/x-shockwave-flash' src=\"http://www.youtube.com/v/\\3&hl=en&fs=1\" />\\4";
269
+ }
270
+ $ret = preg_replace($vimeo, $vimeo_replace, $ret);
271
+ }
272
+
273
+ // matches an "xxxx://yyyy" URL at the start of a line, or after a space.
274
+ // xxxx can only be alpha characters.
275
+ // yyyy is anything up to the first space, newline, comma, double quote or <
276
+ $ret = preg_replace("#(^|[\n ])<?([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)>?#is", "\\1<a href=\"\\2\" >\\2</a>", $ret);
277
+
278
+ // matches a "www|ftp.xxxx.yyyy[/zzzz]" kinda lazy URL thing
279
+ // Must contain at least 2 dots. xxxx contains either alphanum, or "-"
280
+ // zzzz is optional.. will contain everything up to the first space, newline,
281
+ // comma, double quote or <.
282
+ $ret = preg_replace("#(^|[\n ])<?((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)>?#is", "\\1<a href=\"http://\\2\" >\\2</a>", $ret);
283
+
284
+ // matches an email@domain type address at the start of a line, or after a space.
285
+ // Note: Only the followed chars are valid; alphanums, "-", "_" and or ".".
286
+ $ret = preg_replace(
287
+ "#(^|[\n ])([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", "\\1<a href=\"mailto:\\2@\\3\">\\2@\\3</a>", $ret);
288
+ // Remove our padding..
289
+ $ret = substr($ret, 1);
290
+ return $ret;
291
+ }
292
+
293
+ function getPostAuthorDetails(&$subject, &$content, &$mimeDecodedEmail) {
294
+ /* we check whether or not the e-mail is a forwards or a redirect. If it is
295
+ * a fwd, then we glean the author details from the body of the post.
296
+ * Otherwise we get them from the headers
297
+ */
298
+ global $wpdb;
299
+ // see if subject starts with Fwd:
300
+ if (preg_match("/(^Fwd:) (.*)/", $subject, $matches)) {
301
+ $subject = trim($matches[2]);
302
+ if (preg_match("/\nfrom:(.*?)\n/i", $content, $matches)) {
303
+ $theAuthor = GetNameFromEmail($matches[1]);
304
+ $mimeDecodedEmail->headers['from'] = $theAuthor;
305
+ }
306
+ if (preg_match("/\ndate:(.*?)\n/i", $content, $matches)) {
307
+ $theDate = $matches[1];
308
+ $mimeDecodedEmail->headers['date'] = $theDate;
309
+ }
 
 
 
 
 
 
 
 
 
 
 
 
310
  } else {
311
+ $theDate = $mimeDecodedEmail->headers['date'];
312
+ $theEmail = RemoveExtraCharactersInEmailAddress(trim(
313
+ $mimeDecodedEmail->headers["from"]));
314
+ $regAuthor = get_user_by('email', $theEmail);
315
+ if ($regAuthor) {
316
+ $theAuthor = $regAuthor->user_login;
317
+ $theUrl = $regAuthor->user_url;
318
+ $theID = $regAuthor->ID;
319
+ } else {
320
+ $theAuthor = GetNameFromEmail($mimeDecodedEmail->headers['from']);
321
+ $theUrl = '';
322
+ $theID = '';
323
+ }
324
+ }
325
+ // now get rid of forwarding info in the content
326
+ $lines = preg_split("/\r\n/", $content);
327
+ $newContents = '';
328
+ foreach ($lines as $line) {
329
+ if (preg_match("/^(from|subject|to|date):.*?/i", $line, $matches) == 0 &&
330
+ // preg_match("/^$/i",$line,$matches)==0 &&
331
+ preg_match("/^-+\s*forwarded\s*message\s*-+/i", $line, $matches) == 0) {
332
+ $newContents.=preg_replace("/\r/", "", $line) . "\n";
333
+ }
334
+ }
335
+ $content = $newContents;
336
+ $theDetails = array(
337
+ 'content' => "<div class='postmetadata alt'>On $theDate, $theAuthor" .
338
+ " posted:</div>",
339
+ 'emaildate' => $theDate,
340
+ 'author' => $theAuthor,
341
+ 'comment_author_url' => $theUrl,
342
+ 'user_ID' => $theID,
343
+ 'email' => $theEmail
344
+ );
345
+ return($theDetails);
346
  }
347
 
348
  function checkReply(&$subject) {
349
+ /* we check whether or not the e-mail is a reply to a previously
350
+ * published post. First we check whether it starts with Re:, and then
351
+ * we see if the remainder matches an already existing post. If so,
352
+ * then we add that post id to the details array, which will cause the
353
+ * existing post to be overwritten, instead of a new one being
354
+ * generated
355
+ */
356
+
357
+ global $wpdb;
358
+ // see if subject starts with Re:
359
+ if (preg_match("/(^Re:) (.*)/i", $subject, $matches)) {
360
+ $subject = trim($matches[2]);
361
+ // strip out category info into temporary variable
362
+ $tmpSubject = $subject;
363
+ if (preg_match('/(.+): (.*)/', $tmpSubject, $matches)) {
364
+ $tmpSubject = trim($matches[2]);
365
+ $matches[1] = array($matches[1]);
366
+ } else if (preg_match_all('/\[(.[^\[]*)\]/', $tmpSubject, $matches)) {
367
+ preg_match("/](.[^\[]*)$/", $tmpSubject, $tmpSubject_matches);
368
+ $tmpSubject = trim($tmpSubject_matches[1]);
369
+ } else if (preg_match_all('/-(.[^-]*)-/', $tmpSubject, $matches)) {
370
+ preg_match("/-(.[^-]*)$/", $tmpSubject, $tmpSubject_matches);
371
+ $tmpSubject = trim($tmpSubject_matches[1]);
372
+ }
373
+ $checkExistingPostQuery = "SELECT ID FROM $wpdb->posts WHERE
 
 
374
  '$tmpSubject' = post_title";
375
+ if ($id = $wpdb->get_var($wpdb->prepare($checkExistingPostQuery))) {
376
+ if (is_array($id)) {
377
+ $id = $id[count($id) - 1];
378
+ }
379
+ } else {
380
+ $id = NULL;
381
+ }
382
  }
383
+ return($id);
 
384
  }
385
 
386
  function postie_read_me() {
387
+ include(POSTIE_ROOT . DIRECTORY_SEPARATOR . "postie_read_me.php");
388
  }
389
+
390
  /**
391
+ * This sets up the configuration menu
392
+ */
393
  function PostieMenu() {
394
+ if (function_exists('add_options_page')) {
395
+ if (current_user_can('manage_options')) {
396
+ add_options_page("Postie", "Postie", 0, POSTIE_ROOT . "/postie.php", "ConfigurePostie");
397
+ }
398
  }
 
399
  }
400
+
401
  /**
402
+ * This handles actually showing the form
403
+ */
404
  function ConfigurePostie() {
405
+ include(POSTIE_ROOT . DIRECTORY_SEPARATOR . "config_form.php");
406
  }
407
 
408
  /**
409
+ * This function handles determining the protocol and fetching the mail
410
+ * @return array
411
+ */
412
+ function FetchMail($server = NULL, $port = NULL, $email = NULL, $password = NULL, $protocol = NULL, $offset = NULL, $test = NULL, $deleteMessages = true) {
413
+ $emails = array();
414
+ if (!$server || !$port || !$email) {
415
+ die("Missing Configuration For Mail Server\n");
416
+ }
417
+ if ($server == "pop.gmail.com") {
418
+ print("\nMAKE SURE POP IS TURNED ON IN SETTING AT Gmail\n");
419
+ }
420
+ switch (strtolower($protocol)) {
421
+ case 'smtp': //direct
422
+ $fd = fopen("php://stdin", "r");
423
+ $input = "";
424
+ while (!feof($fd)) {
425
+ $input .= fread($fd, 1024);
426
+ }
427
+ fclose($fd);
428
+ $emails[0] = $input;
429
+ break;
430
+ case 'imap':
431
+ case 'imap-ssl':
432
+ case 'pop3-ssl':
433
+ HasIMAPSupport(false);
434
+ if ($test) {
435
+ $emails = TestIMAPMessageFetch();
436
+ } else {
437
+ $emails = IMAPMessageFetch($server, $port, $email, $password, $protocol, $offset, $test, $deleteMessages);
438
+ }
439
+ break;
440
+ case 'pop3':
441
+ default:
442
+ if ($test) {
443
+ $emails = TestPOP3MessageFetch();
444
+ } else {
445
+ $emails = POP3MessageFetch($server, $port, $email, $password, $protocol, $offset, $test, $deleteMessages);
446
+ }
447
+ }
448
+ if (!$emails)
449
+ die("\n" . __('There does not seem to be any new mail.', 'postie') . "\n");
450
+ return($emails);
 
 
 
451
  }
 
 
 
 
 
 
 
 
 
 
 
 
452
 
453
+ /**
454
+ * Handles fetching messages from an imap server
455
+ */
456
+ function TestIMAPMessageFetch() {
457
+ print("**************RUNING IN TESTING MODE************\n");
458
+ $config = get_postie_config();
459
+ extract($config);
460
+ $email = $test_email_account;
461
+ $password = $test_email_password;
462
+ return(IMAPMessageFetch($mail_server, $mail_server_port, $email, $password, $input_protocol, $time_offset, $test_email));
463
  }
464
+
465
  /**
466
+ * Handles fetching messages from an imap server
467
+ */
468
+ function IMAPMessageFetch($server = NULL, $port = NULL, $email = NULL, $password = NULL, $protocol = NULL, $offset = NULL, $test = NULL, $deleteMessages = true) {
 
 
469
  require_once("postieIMAP.php");
470
 
471
  $mail_server = &PostieIMAP::Factory($protocol);
472
  print("\nConnecting to $server:$port ($protocol) \n");
473
+ if (!$mail_server->connect($server, $port, $email, $password)) {
474
  print("Mail Connection Time Out\n
475
  Common Reasons: \n
476
  Server Down \n
477
  Network Issue \n
478
  Port/Protocol MisMatch \n
479
  ");
480
+ die("The Server said:" . $mail_server->error() . "\n");
481
  }
482
  $msg_count = $mail_server->getNumberOfMessages();
483
  $emails = array();
484
+ // loop through messages
485
+ for ($i = 1; $i <= $msg_count; $i++) {
486
+ $emails[$i] = $mail_server->fetchEmail($i);
487
+ if ($deleteMessages) {
488
+ $mail_server->deleteMessage($i);
489
+ }
490
+ }
491
  if ($deleteMessages) {
492
+ $mail_server->expungeMessages();
493
+ }
494
+ //clean up
495
+ $mail_server->disconnect();
496
+ return $emails;
497
+ }
498
+
499
+ function TestPOP3MessageFetch() {
500
+ print("**************RUNING IN TESTING MODE************\n");
501
+ $config = get_postie_config();
502
+ extract($config);
503
+ $email = $test_email_account;
504
+ $password = $test_email_password;
505
+ return(POP3MessageFetch($mail_server, $mail_server_port, $email, $password, $input_protocol, $time_offset, $test_email));
 
 
 
 
 
506
  }
507
+
508
  /**
509
+ * Retrieves email via POP3
510
+ */
511
+ function POP3MessageFetch($server = NULL, $port = NULL, $email = NULL, $password = NULL, $protocol = NULL, $offset = NULL, $test = NULL, $deleteMessages = true) {
512
+ require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'class-pop3.php');
513
+ $pop3 = &new POP3();
 
 
514
  print("\nConnecting to $server:$port ($protocol)) \n");
515
  if (!$pop3->connect($server, $port)) {
516
+ if (strpos($pop3->ERROR, "POP3: premature NOOP OK, NOT an RFC 1939 Compliant server") === false) {
517
  print("Mail Connection Time Out\n
518
  Common Reasons: \n
519
  Server Down \n
524
  }
525
  }
526
 
527
+ //Check to see if there is any mail, if not die
528
+ $msg_count = $pop3->login($email, $password);
529
+ if ($msg_count === false) {
530
+ $pop3->quit();
531
+ // we should die if $msg_count is false, but the core wordpress pop3 needs
532
+ // to be fixed before we can do that
533
+ // die("there was a problem logging in. Please check username and password.");
534
  return(array());
535
+ }
536
 
537
+ // loop through messages
538
+ for ($i = 1; $i <= $msg_count; $i++) {
539
+ $emails[$i] = implode('', $pop3->get($i));
540
  if ($deleteMessages) {
541
+ if (!$pop3->delete($i)) {
542
+ echo 'Oops ' . $pop3->ERROR . '\n';
543
+ $pop3->reset();
544
+ exit;
545
+ } else {
546
+ echo "Mission complete, message $i deleted.\n";
547
+ }
548
+ } else {
 
549
  print("Not deleting messages!\n");
550
  }
551
+ }
552
+ //clean up
553
+ $pop3->quit();
554
+ return $emails;
555
  }
556
+
557
  /**
558
+ * This function handles putting the actual entry into the database
559
+ * @param array - categories to be posted to
560
+ * @param array - details of the post
561
+ */
562
+ function PostToDB($details, $isReply, $postToDb = true, $customImageField = false) {
563
+ if ($postToDb) {
564
+ //$_POST['publish'] = true; //Added to make subscribe2 work - it will only handle it if the global varilable _POST is set
565
+ if (!$isReply) {
566
+ $post_ID = wp_insert_post($details);
567
+ } else {
568
+ $comment = array(
569
+ 'comment_author' => $details['comment_author'],
570
+ 'comment_post_ID' => $details['ID'],
571
+ 'comment_author_email' => $details['email_author'],
572
+ 'comment_date' => $details['post_date'],
573
+ 'comment_date_gmt' => $details['post_date_gmt'],
574
+ 'comment_content' => $details['post_content'],
575
+ 'comment_author_url' => $details['comment_author_url'],
576
+ 'comment_author_IP' => '',
577
+ 'comment_approved' => 1,
578
+ 'comment_agent' => '',
579
+ 'comment_type' => '',
580
+ 'comment_parent' => 0,
581
+ 'user_id' => $details['user_ID']
582
+ );
583
+
584
+ $post_ID = wp_insert_comment($comment);
585
+ }
586
+ if ($customImageField) {
587
+ if (count($details['customImages']) > 1) {
588
+ $imageField = 1;
589
+ foreach ($details['customImages'] as $image) {
590
+ add_post_meta($post_ID, 'image' . $imageField, $image);
591
+ $imageField++;
592
+ }
593
+ } else {
594
+ add_post_meta($post_ID, 'image', $details['customImages'][0]);
595
+ }
596
+ }
597
  }
 
598
  }
599
 
600
  /**
601
+ * This function determines if the mime attachment is on the BANNED_FILE_LIST
602
+ * @param string
603
+ * @return boolean
604
+ */
605
  function BannedFileName($filename, $bannedFiles) {
606
+ if (empty($filename) || empty($bannedFiles))
607
+ return false;
608
+ foreach ($bannedFiles as $bannedFile) {
609
+ if (fnmatch($bannedFile, $filename)) {
610
+ print("<p>Ignoring $filename - it is on the banned files list.");
611
+ return(true);
612
+ }
613
  }
614
+ return(false);
 
615
  }
616
 
617
  //tear apart the meta part for useful information
618
+ function GetContent($part, &$attachments, $post_id, $poster, $config) {
619
+ extract($config);
620
+ global $charset, $encoding;
621
+ /*
622
+ if (!function_exists(imap_mime_header_decode))
623
+ echo "you need to install the php-imap extension for full functionality, including mime header decoding\n";
624
+ */
625
+ $meta_return = NULL;
626
+ echo "primary= " . $part->ctype_primary . ", secondary = " . $part->ctype_secondary . "\n";
627
+ DecodeBase64Part($part);
628
+ if (BannedFileName($part->ctype_parameters['name'], $banned_files_list))
629
+ return(NULL);
630
+ if ($part->ctype_primary == "application"
631
+ && $part->ctype_secondary == "octet-stream") {
632
+ if ($part->disposition == "attachment") {
633
+ $image_endings = array("jpg", "png", "gif", "jpeg", "pjpeg");
634
+ foreach ($image_endings as $type) {
635
+ if (eregi(".$type\$", $part->d_parameters["filename"])) {
636
+ $part->ctype_primary = "image";
637
+ $part->ctype_secondary = $type;
638
+ break;
639
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
  } else {
642
+ $mimeDecodedEmail = DecodeMIMEMail($part->body);
643
+ FilterTextParts($mimeDecodedEmail, $prefer_text_type);
644
+ foreach ($mimeDecodedEmail->parts as $section) {
645
+ $meta_return .= GetContent($section, $attachments, $post_id, $poster, $config);
646
+ }
647
+ }
648
+ }
649
+ if ($part->ctype_primary == "multipart"
650
+ && $part->ctype_secondary == "appledouble") {
651
+ $mimeDecodedEmail = DecodeMIMEMail("Content-Type: multipart/mixed; boundary=" . $part->ctype_parameters["boundary"] . "\n" . $part->body);
652
+ FilterTextParts($mimeDecodedEmail, $prefer_text_type);
653
+ FilterAppleFile($mimeDecodedEmail);
654
+ foreach ($mimeDecodedEmail->parts as $section) {
655
+ $meta_return .= GetContent($section, $attachments, $post_id, $poster, $config);
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  }
657
+ } else {
658
+ // fix filename (remove non-standard characters)
659
+ $filename = preg_replace("/[^\x9\xA\xD\x20-\x7F]/", "", $part->ctype_parameters['name']);
660
+ switch (strtolower($part->ctype_primary)) {
661
+ case 'multipart':
662
+ FilterTextParts($part, $prefer_text_type);
663
+ foreach ($part->parts as $section) {
664
+ $meta_return .= GetContent($section, $attachments, $post_id, $poster, $config);
665
+ }
666
+ break;
667
+ case 'text':
668
+ $tmpcharset = trim($part->ctype_parameters['charset']);
669
+ if ($tmpcharset != '')
670
+ $charset = $tmpcharset;
671
+ $tmpencoding = trim($part->headers['content-transfer-encoding']);
672
+ if ($tmpencoding != '')
673
+ $encoding = $tmpencoding;
674
+
675
+ $part->body = HandleMessageEncoding($part->headers["content-transfer-encoding"], $part->ctype_parameters["charset"], $part->body, $message_encoding, $message_dequote);
676
+
677
+ //go through each sub-section
678
+ if ($part->ctype_secondary == 'enriched') {
679
+ //convert enriched text to HTML
680
+ $meta_return .= etf2HTML($part->body) . "\n";
681
+ } elseif ($part->ctype_secondary == 'html') {
682
+ //strip excess HTML
683
+ //$meta_return .= HTML2HTML($part->body ) . "\n";
684
+ $meta_return .= $part->body . "\n";
685
+ } else {
686
+ //regular text, so just strip the pgp signature
687
+ if (ALLOW_HTML_IN_BODY) {
688
+ $meta_return .= $part->body . "\n";
689
+ } else {
690
+ $meta_return .= htmlentities($part->body) . "\n";
691
+ }
692
+ $meta_return = StripPGP($meta_return);
693
+ }
694
+ break;
695
+
696
+ case 'image':
697
+ $file_id = postie_media_handle_upload($part, $post_id, $poster);
698
+ $file = wp_get_attachment_url($file_id);
699
+
700
+ $cid = trim($part->headers["content-id"], "<>");
701
+ ; //cids are in <cid>
702
+ $the_post = get_post($file_id);
703
+ $attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary, $imagetemplate);
704
+ if ($cid) {
705
+ $attachments["cids"][$cid] = array($file,
706
+ count($attachments["html"]) - 1);
707
+ }
708
+ break;
709
+ case 'audio':
710
+ $file_id = postie_media_handle_upload($part, $post_id, $poster);
711
+ $file = wp_get_attachment_url($file_id);
712
+ $cid = trim($part->headers["content-id"], "<>");
713
+ ; //cids are in <cid>
714
+ if (in_array($part->ctype_secondary, $audiotypes)) {
715
+ $audioTemplate = $audiotemplate;
716
+ } else {
717
+ $icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size);
718
+ $audioTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
719
+ }
720
+ $attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary, $audioTemplate);
721
+ break;
722
+ case 'video':
723
+ $file_id = postie_media_handle_upload($part, $post_id, $poster);
724
+ $file = wp_get_attachment_url($file_id);
725
+ $cid = trim($part->headers["content-id"], "<>");
726
+ ; //cids are in <cid>
727
+ if (in_array(strtolower($part->ctype_secondary), $video1types)) {
728
+ $videoTemplate = $video1template;
729
+ } elseif (in_array(strtolower($part->ctype_secondary), $video2types)) {
730
+ $videoTemplate = $video2template;
731
+ } else {
732
+ $icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size);
733
+ $videoTemplate = '<a href="{FILELINK}">' . $icon . '{FILENAME}</a>';
734
+ }
735
+ $attachments["html"][$filename] = parseTemplate($file_id, $part->ctype_primary, $videoTemplate);
736
+ //echo "videoTemplate = $videoTemplate\n";
737
+ break;
738
+
739
+ default:
740
+ if (in_array(strtolower($part->ctype_primary), $supported_file_types)) {
741
+ //pgp signature - then forget it
742
+ if ($part->ctype_secondary == 'pgp-signature')
743
+ break;
744
+ $file_id = postie_media_handle_upload($part, $post_id, $poster);
745
+ $file = wp_get_attachment_url($file_id);
746
+ $cid = trim($part->headers["content-id"], "<>");
747
+ ; //cids are in <cid>
748
+ $icon = chooseAttachmentIcon($file, $part->ctype_primary, $part->ctype_secondary, $icon_set, $icon_size);
749
+ $attachments["html"][$filename] = "<a href='$file'>" .
750
+ $icon . $filename . '</a>' . "\n";
751
+ if ($cid) {
752
+ $attachments["cids"][$cid] = array($file,
753
+ count($attachments["html"]) - 1);
754
+ }
755
+ }
756
+ break;
757
+ }
758
+ }
759
+ return($meta_return);
760
  }
761
 
762
  function ubb2HTML(&$text) {
763
+ // Array of tags with opening and closing
764
+ $tagArray['img'] = array('open' => '<img src="', 'close' => '">');
765
+ $tagArray['b'] = array('open' => '<b>', 'close' => '</b>');
766
+ $tagArray['i'] = array('open' => '<i>', 'close' => '</i>');
767
+ $tagArray['u'] = array('open' => '<u>', 'close' => '</u>');
768
+ $tagArray['url'] = array('open' => '<a href="', 'close' => '">\\1</a>');
769
+ $tagArray['email'] = array('open' => '<a href="mailto:', 'close' => '">\\1</a>');
770
+ $tagArray['url=(.*)'] = array('open' => '<a href="', 'close' => '">\\2</a>');
771
+ $tagArray['email=(.*)'] = array('open' => '<a href="mailto:', 'close' => '">\\2</a>');
772
+ $tagArray['color=(.*)'] = array('open' => '<font color="', 'close' => '">\\2</font>');
773
+ $tagArray['size=(.*)'] = array('open' => '<font size="', 'close' => '">\\2</font>');
774
+ $tagArray['font=(.*)'] = array('open' => '<font face="', 'close' => '">\\2</font>');
775
+ // Array of tags with only one part
776
+ $sTagArray['br'] = array('tag' => '<br>');
777
+ $sTagArray['hr'] = array('tag' => '<hr>');
778
+
779
+ foreach ($tagArray as $tagName => $replace) {
780
+ $tagEnd = preg_replace('/\W/Ui', '', $tagName);
781
+ $text = preg_replace("|\[$tagName\](.*)\[/$tagEnd\]|Ui", "$replace[open]\\1$replace[close]", $text);
782
+ }
783
+ foreach ($sTagArray as $tagName => $replace) {
784
+ $text = preg_replace("|\[$tagName\]|Ui", "$replace[tag]", $text);
785
+ }
786
+ return $text;
787
  }
788
 
 
789
  // This function turns Enriched Text into something similar to HTML
790
  // Very basic at the moment, only supports some functionality and dumps the rest
791
  // FIXME: fix colours: <color><param>FFFF,C2FE,0374</param>some text </color>
792
+ function etf2HTML($content) {
793
+
794
+ $search = array(
795
+ '/<bold>/',
796
+ '/<\/bold>/',
797
+ '/<underline>/',
798
+ '/<\/underline>/',
799
+ '/<italic>/',
800
+ '/<\/italic>/',
801
+ '/<fontfamily><param>.*<\/param>/',
802
+ '/<\/fontfamily>/',
803
+ '/<x-tad-bigger>/',
804
+ '/<\/x-tad-bigger>/',
805
+ '/<bigger>/',
806
+ '</bigger>/',
807
+ '/<color>/',
808
+ '/<\/color>/',
809
+ '/<param>.+<\/param>/'
810
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
811
 
812
+ $replace = array(
813
+ '<b>',
814
+ '</b>',
815
+ '<u>',
816
+ '</u>',
817
+ '<i>',
818
+ '</i>',
819
+ '',
820
+ '',
821
+ '',
822
+ '',
823
+ '',
824
+ '',
825
+ '',
826
+ '',
827
+ ''
828
+ );
829
+ // strip extra line breaks
830
+ $content = preg_replace($search, $replace, $content);
831
+ return trim($content);
832
+ }
833
 
834
  // This function cleans up HTML in the e-mail
835
+ function HTML2HTML($content) {
836
+ $search = array(
837
+ '/<html [^<]*>/is',
838
+ '/<\/html>/i',
839
+ '/<\/?title>/i',
840
+ '/<body[^<]*>/i',
841
+ '/<\/body>/i',
842
+ '/<\/?head>/i',
843
+ '/<meta[^<]*>/i',
844
+ '/<style[^<]*>.*<\/style>/is',
845
+ '/<!--.*?-->/is',
846
+ '/<\/?o:[^<]*>/i',
847
+ '/<!DOCTYPE[^<]*>/',
848
+ //'/<img src=[\'"][^<]*>/'
849
  // '/<img src="cid:(.*)" .*>/'
850
+ );
851
 
852
+ $replace = array(
853
+ '',
854
+ '',
855
+ '',
856
+ '',
857
+ '',
858
+ '',
859
+ '',
860
+ '',
861
+ '',
862
+ '',
863
+ '',
864
+ ''
865
+ );
866
+ // strip extra line breaks
867
+ $content = preg_replace($search, $replace, trim($content));
868
+ return ($content);
869
  }
870
 
 
 
871
  /**
872
+ * Determines if the sender is a valid user.
873
+ * @return integer|NULL
874
+ */
875
+ function ValidatePoster(&$mimeDecodedEmail, $config) {
876
+ extract($config);
877
+ global $wpdb;
878
+ $poster = NULL;
879
+ $from = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["from"]));
880
+ $resentFrom = RemoveExtraCharactersInEmailAddress(trim($mimeDecodedEmail->headers["resent-from"]));
881
+ /*
882
+ if ( empty($from) ) {
883
  echo 'Invalid Sender - Emtpy! ';
884
  return;
885
+ }
886
+ */
887
+
888
+ //See if the email address is one of the special authorized ones
889
+ print("Confirming Access For $from \n");
890
+ $sql = 'SELECT id FROM ' . $wpdb->users . ' WHERE user_email=\'' . addslashes($from) . "' LIMIT 1;";
891
+ $user_ID = $wpdb->get_var($sql);
892
+ if (!empty($user_ID)) {
893
+ $user = new WP_User($user_ID);
894
+ if ($user->has_cap("post_via_postie")) {
895
+ $poster = $user_ID;
896
+ echo "posting as user $poster";
897
+ } else {
898
+ $poster = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE
899
  user_login = '$admin_username'");
900
+ }
901
+ } elseif ($turn_authorization_off ||
902
+ CheckEmailAddress($from, $authorized_addresses) ||
903
+ CheckEmailAddress($resentFrom, $authorized_addresses)) {
904
+ $poster = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE
905
  user_login = '$admin_username'");
 
 
 
 
 
 
 
 
 
 
 
 
906
  }
907
+ $validSMTP = checkSMTP($mimeDecodedEmail, $smtp);
908
+ if (!$poster || !$validSMTP) {
909
+ echo 'Invalid sender: ' . htmlentities($from) . "! Not adding email!\n";
910
+ if ($forward_rejected_mail) {
911
+ $admin_email = get_option("admin_email");
912
+ if (MailToRecipients($mimeDecodedEmail, $test_email, array($admin_email), $return_to_sender)) {
913
+ echo "A copy of the message has been forwarded to the administrator.\n";
914
+ } else {
915
+ echo "The message was unable to be forwarded to the adminstrator.\n";
916
+ }
917
+ }
918
+ return;
919
+ }
920
+ return $poster;
921
  }
922
 
923
  function post_as_admin($admin_username) {
924
+ print("$from is authorized to post as the administrator\n");
925
+ //$from = get_option("admin_email");
926
+ //$adminUser=$admin_username;
927
+ //echo "adminUser='$adminUser'";
928
+ return $poster;
929
  }
930
 
931
  function checkSMTP($mimeDecodedEmail, $smtpservers) {
932
+ if (empty($smtpservers))
933
+ return true;
934
+ foreach ((array) $mimeDecodedEmail->headers['received'] as $received) {
935
+ foreach ($smtpservers as $smtp) {
936
+ if (stristr($received, $smtp) !== false)
937
+ return true;
938
+ }
939
  }
940
+ return false;
 
941
  }
942
 
943
  /**
944
+ * Looks at the content for the start of the message and removes everything before that
945
+ * If the pattern is not found everything is returned
946
+ * @param string
947
+ * @param string
948
+ */
949
+ function StartFilter(&$content, $start) {
950
+ $pos = strpos($content, $start);
951
+ if ($pos === false) {
952
+ return($content);
953
+ }
954
+ $content = substr($content, $pos + strlen($start), strlen($content));
955
  }
956
 
957
  /**
958
+ * Looks at the content for the start of the signature and removes all text
959
+ * after that point
960
+ * @param string
961
+ * @param array - a list of patterns to determine if it is a sig block
962
+ */
963
+ function remove_signature($content, $filterList) {
964
+ if (empty($filterList))
965
+ return $content;
966
+ $arrcontent = explode("\n", $content);
967
+ $strcontent = '';
968
+ $pattern = '/^(' . implode('|', $filterList) . ')/';
969
+ for ($i = 0; $i <= count($arrcontent); $i++) {
970
+ $line = trim($arrcontent[$i]);
971
+ $nextline = $arrcontent[$i + 1];
972
+ if (preg_match($pattern, trim($line))) {
973
+ //if (!strpos(trim($line), $pattern)==0) {
974
+ //print("<p>Found in $line");
975
+ break;
976
+ }
977
+ $strcontent .= $line . "\n";
978
+ }
979
+ return $strcontent;
980
  }
981
+
982
  /**
983
+ * Looks at the content for the given tag and removes all text
984
+ * after that point
985
+ * @param string
986
+ * @param filter
987
+ */
988
+ function EndFilter(&$content, $end) {
989
+ $pos = strpos($content, $end);
990
+ if ($pos === false)
991
+ return $content;
992
+ return $content = substr($content, 0, $pos);
993
  }
994
 
995
  //filter content for new lines
996
+ function FilterNewLines($content, $convertNewLines = false) {
997
+ $search = array(
998
+ "/\r\n/",
999
+ "/\r/",
1000
+ "/\n\n/",
1001
+ "/\r\n\r\n/",
1002
+ "/\n/"
1003
+ );
1004
+ $replace = array(
1005
+ "\n",
1006
+ "\n",
1007
+ 'ACTUAL_NEW_LINE',
1008
+ 'ACTUAL_NEW_LINE',
1009
+ 'LINEBREAK'
1010
+ );
1011
+ // strip extra line breaks, and replace double line breaks with paragraph
1012
+ // tags
1013
+ $result = preg_replace($search, $replace, $content);
1014
+ //$newContent='<p>' . preg_replace('/ACTUAL_NEW_LINE/',"</p>\n<p>",$result);
1015
+
1016
+ $newContent = preg_replace('/(ACTUAL_NEW_LINE|LINEBREAK\s*LINEBREAK)/', "\n\n", $result);
1017
+ //$newContent=preg_replace('/<p>LINEBREAK$/', '', $newContent);
1018
+ if ($convertNewLines) {
1019
+ $newContent = preg_replace('/LINEBREAK/', "<br />\n", $newContent);
1020
+ if (defined('POSTIE_DEBUG')) {
1021
+ echo "converting newlines\n";
1022
+ }
1023
+ } else {
1024
+ $newContent = preg_replace('/LINEBREAK/', " ", $newContent);
1025
+ if (defined('POSTIE_DEBUG')) {
1026
+ echo "not converting newlines\n";
1027
+ }
1028
+ }
1029
+ return($newContent);
1030
+ }
1031
+
1032
+ function FixEmailQuotes($content) {
1033
+ # place e-mails quotes (indicated with >) in blockquote and pre tags
1034
+ $search = array(
1035
+ "/^>/"
1036
+ );
1037
+ $replace = array(
1038
+ '<br />&gt;'
1039
+ );
1040
+ // strip extra line breaks, and replace double line breaks with paragraph
1041
+ // tags
1042
+ $result = preg_replace($search, $replace, $content);
1043
+ //return('<p>' . preg_replace('/ACTUAL_NEW_LINE/',"<\/p>\n<p>",$result)
1044
+ //. '</p>');
1045
+ return($result);
1046
  }
1047
 
1048
  //strip pgp stuff
1049
+ function StripPGP($content) {
1050
+ $search = array(
1051
+ '/-----BEGIN PGP SIGNED MESSAGE-----/',
1052
+ '/Hash: SHA1/'
1053
+ );
1054
+ $replace = array(
1055
+ ' ',
1056
+ ''
1057
+ );
1058
+ // strip extra line breaks
1059
+ $return = preg_replace($search, $replace, $content);
1060
+ return $return;
1061
+ }
1062
+
1063
+ function ConvertToISO_8859_1($encoding, $charset, $body, $blogEncoding) {
1064
+ $charset = strtolower($charset);
1065
+ $encoding = strtolower($encoding);
1066
+ if (strtolower($blogEncoding == "iso-8859-1") && (strtolower($charset) != 'iso-8859-1')) {
1067
+ if ($encoding == 'base64' || $encoding == 'quoted-printable') {
1068
+ $body = utf8_decode($body);
1069
+ }
1070
+ }
1071
+ return($body);
1072
+ }
1073
+
1074
+ function HandleMessageEncoding($encoding, $charset, $body, $blogEncoding = 'utf-8', $dequote = true) {
1075
+ $charset = strtolower($charset);
1076
+ $encoding = strtolower($encoding);
1077
+ /*
1078
+ if ($encoding == '') {
1079
+ $encoding = '7bit';
1080
+ }
1081
+ */
1082
+ if ($dequote && strtolower($encoding) == 'quoted-printable') {
1083
+ //echo "handling quoted printable";
1084
+ $body = quoted_printable_decode($body);
1085
+ //echo "now body is:\n\n $body\n\n";
1086
+ }
1087
+ //HandleQuotedPrintable($encoding, $body, $dequote);
1088
+ if ($blogEncoding == 'iso-8859-1') {
1089
+ $text = ConvertToISO_8859_1($encoding, $charset, $body, $blogEncoding);
1090
+ } else {
1091
+ $text = ConvertToUTF_8($encoding, $charset, $body);
1092
+ }
1093
+ return($text);
1094
+ }
1095
+
1096
+ function ConvertToUTF_8($encoding, $charset, $body) {
1097
+ $charset = strtolower($charset);
1098
+ $encoding = strtolower($encoding);
1099
+
1100
+ switch ($charset) {
1101
+ case "iso-8859-1":
1102
+ $body = utf8_encode($body);
1103
+ break;
1104
+ case "iso-2022-jp":
1105
+ $body = iconv("ISO-2022-JP", "UTF-8//TRANSLIT", $body);
1106
+ break;
1107
+ case ($charset == "windows-1252" || $charset == "cp-1252" ||
1108
+ $charset == "cp 1252"):
1109
+ $body = cp1252_to_utf8($body);
1110
+ break;
1111
+ case ($charset == "windows-1256" || $charset == "cp-1256" ||
1112
+ $charset == "cp 1256"):
1113
+ $body = iconv("Windows-1256", "UTF-8//TRANSLIT", $body);
1114
+ break;
1115
+ case 'koi8-r':
1116
+ $body = iconv("koi8-r", "UTF-8//TRANSLIT", $body);
1117
+ break;
1118
+ case 'iso-8859-2':
1119
+ $body = iconv("iso-8859-2", "UTF-8//TRANSLIT", $body);
1120
+ break;
1121
+ case "big5":
1122
+ $body = iconv("BIG5", "UTF-8//TRANSLIT", $body);
1123
+ break;
1124
+ case "gb2312":
1125
+ $body = iconv("GB2312", "UTF-8//TRANSLIT", $body);
1126
+ break;
1127
+ case "iso-8859-15":
1128
+ $body = iconv("iso-8859-15", "UTF-8//TRANSLIT", $body);
1129
+ break;
1130
+ }
1131
+ return($body);
1132
  }
1133
+
1134
  /* this function will convert windows-1252 (also known as cp-1252 to utf-8 */
1135
+
1136
  function cp1252_to_utf8($str) {
1137
+ $cp1252_map = array(
1138
+ "\xc2\x80" => "\xe2\x82\xac",
1139
+ "\xc2\x82" => "\xe2\x80\x9a",
1140
+ "\xc2\x83" => "\xc6\x92",
1141
+ "\xc2\x84" => "\xe2\x80\x9e",
1142
+ "\xc2\x85" => "\xe2\x80\xa6",
1143
+ "\xc2\x86" => "\xe2\x80\xa0",
1144
+ "\xc2\x87" => "\xe2\x80\xa1",
1145
+ "\xc2\x88" => "\xcb\x86",
1146
+ "\xc2\x89" => "\xe2\x80\xb0",
1147
+ "\xc2\x8a" => "\xc5\xa0",
1148
+ "\xc2\x8b" => "\xe2\x80\xb9",
1149
+ "\xc2\x8c" => "\xc5\x92",
1150
+ "\xc2\x8e" => "\xc5\xbd",
1151
+ "\xc2\x91" => "\xe2\x80\x98",
1152
+ "\xc2\x92" => "\xe2\x80\x99",
1153
+ "\xc2\x93" => "\xe2\x80\x9c",
1154
+ "\xc2\x94" => "\xe2\x80\x9d",
1155
+ "\xc2\x95" => "\xe2\x80\xa2",
1156
+ "\xc2\x96" => "\xe2\x80\x93",
1157
+ "\xc2\x97" => "\xe2\x80\x94",
1158
+ "\xc2\x98" => "\xcb\x9c",
1159
+ "\xc2\x99" => "\xe2\x84\xa2",
1160
+ "\xc2\x9a" => "\xc5\xa1",
1161
+ "\xc2\x9b" => "\xe2\x80\xba",
1162
+ "\xc2\x9c" => "\xc5\x93",
1163
+ "\xc2\x9e" => "\xc5\xbe",
1164
+ "\xc2\x9f" => "\xc5\xb8"
1165
+ );
1166
+ return strtr(utf8_encode($str), $cp1252_map);
1167
  }
1168
 
1169
  /**
1170
+ * This function handles decoding base64 if needed
1171
+ */
1172
+ function DecodeBase64Part(&$part) {
1173
+ if (strtolower($part->headers['content-transfer-encoding']) == 'base64') {
1174
  $part->body = base64_decode($part->body);
1175
  }
1176
  }
1177
 
1178
+ function HandleQuotedPrintable($encoding, &$body, $dequote = true) {
1179
+ if ($dequote && strtolower($encoding) == 'quoted-printable') {
1180
+ echo "handling quoted printable";
1181
+ $body = quoted_printable_decode($body);
1182
  }
1183
  }
1184
 
 
1185
  /**
1186
+ * Checks for the comments tag
1187
+ * @return boolean
1188
+ */
1189
  function AllowCommentsOnPost(&$content) {
1190
  $comments_allowed = get_option('default_comment_status');
1191
+ if (eregi("comments:([0|1|2])", $content, $matches)) {
1192
+ $content = ereg_replace("comments:$matches[1]", "", $content);
1193
  if ($matches[1] == "1") {
1194
  $comments_allowed = "open";
1195
+ } else if ($matches[1] == "2") {
 
1196
  $comments_allowed = "registered_only";
1197
+ } else {
 
1198
  $comments_allowed = "closed";
1199
  }
1200
  }
1201
  return($comments_allowed);
1202
  }
1203
+
1204
  /**
1205
+ * Needed to be able to modify the content to remove the usage of the delay tag
1206
+ */
1207
+ function DeterminePostDate(&$content, $message_date = NULL, $offset = 0) {
1208
  $delay = 0;
1209
+ if (defined('POSTIE_DEBUG')) {
1210
+ echo "inside Determine Post Date, message_date = $message_date\n";
1211
  }
1212
+ if (eregi("delay:(-?[0-9dhm]+)", $content, $matches)
1213
+ && trim($matches[1])) {
1214
+ if (eregi("(-?[0-9]+)d", $matches[1], $dayMatches)) {
1215
  $days = $dayMatches[1];
1216
  }
1217
+ if (eregi("(-?[0-9]+)h", $matches[1], $hourMatches)) {
1218
  $hours = $hourMatches[1];
1219
  }
1220
+ if (eregi("(-?[0-9]+)m", $matches[1], $minuteMatches)) {
1221
  $minutes = $minuteMatches[1];
1222
  }
1223
  $delay = (($days * 24 + $hours) * 60 + $minutes) * 60;
1224
+ $content = ereg_replace("delay:$matches[1]", "", $content);
1225
  }
1226
+ if (!empty($message_date) && $delay == 0) {
1227
  $dateInSeconds = strtotime($message_date);
1228
+ } else {
 
1229
  $dateInSeconds = time() + $delay;
1230
  }
1231
+ $post_date = gmdate('Y-m-d H:i:s', $dateInSeconds + ($offset * 3600));
1232
+ $post_date_gmt = gmdate('Y-m-d H:i:s', $dateInSeconds);
1233
 
1234
+ /*
1235
+ echo "--------------------DELAY------------\n";
1236
+ echo "delay=$delay, dateInSeconds = $dateInSeconds\n";
1237
+ echo "post_date=$post_date\n";
1238
+ echo "--------------------DELAY------------\n";
1239
+ */
1240
+ return(array($post_date, $post_date_gmt, $delay));
1241
  }
1242
+
1243
  /**
1244
+ * This function takes the content of the message - looks for a subject at the begining surrounded by # and then removes that from the content
1245
+ */
1246
  function ParseInMessageSubject($content, $defaultTitle) {
1247
+ if (substr($content, 0, 1) != "#") {
1248
  //print("<p>Didn't start with # '".substr(ltrim($content),0,10)."'");
1249
+ return(array($defaultTitle, $content));
1250
  }
1251
+ $subjectEndIndex = strpos($content, "#", 1);
1252
  if (!$subjectEndIndex > 0) {
1253
+ return(array($defaultTitle, $content));
1254
  }
1255
+ $subject = substr($content, 1, $subjectEndIndex - 1);
1256
+ $content = substr($content, $subjectEndIndex + 1, strlen($content));
1257
+ return(array($subject, $content));
1258
  }
1259
+
1260
  /**
1261
+ * This method sorts thru the mime parts of the message. It is looking for files labeled - "applefile" - current
1262
+ * this part of the file attachment is not supported
1263
+ * @param object
1264
+ */
1265
  function FilterAppleFile(&$mimeDecodedEmail) {
1266
  $newParts = array();
1267
  $found = false;
1268
+ for ($i = 0; $i < count($mimeDecodedEmail->parts); $i++) {
1269
  if ($mimeDecodedEmail->parts[$i]->ctype_secondary == "applefile") {
1270
  $found = true;
1271
+ } else {
 
1272
  $newParts[] = &$mimeDecodedEmail->parts[$i];
1273
  }
1274
  }
1276
  $mimeDecodedEmail->parts = $newParts; //This is now the filtered list of just the preferred type.
1277
  }
1278
  }
1279
+
1280
  function postie_media_handle_upload($part, $post_id, $poster, $post_data = array()) {
1281
+ $overrides = array('test_form' => false);
1282
+ //$overrides = array('test_form'=>false, 'test_size'=>false,
1283
+ // 'test_type'=>false);
1284
+ $tmpFile = tempnam(getenv('TEMP'), 'postie');
1285
+ if (!is_writable($tmpFile)) {
1286
+ $uploadDir = wp_upload_dir();
1287
+ $tmpFile = tempnam($uploadDir['path'], 'postie');
1288
+ }
1289
+ $fp = fopen($tmpFile, 'w');
1290
+ if ($fp) {
1291
+ fwrite($fp, $part->body);
1292
+ fclose($fp);
 
 
 
 
 
 
1293
  } else {
1294
+ echo "could not write to temp file: '$tmpFile' ";
1295
+ }
1296
+ if ($part->ctype_parameters['name'] == '') {
1297
+ if ($part->d_parameters['filename'] != '') {
1298
+ $name = $part->d_parameters['filename'];
1299
+ } else {
1300
+ $name = 'postie-media.' . $part->ctype_secondary;
1301
+ }
1302
+ } else {
1303
+ $name = $part->ctype_parameters['name'];
1304
+ }
1305
+ $the_file = array('name' => $name,
1306
+ 'tmp_name' => $tmpFile,
1307
+ 'size' => filesize($tmpFile),
1308
+ 'error' => ''
1309
+ );
1310
+ if (stristr('.zip', $name)) {
1311
+ $parts = explode('.', $name);
1312
+ $ext = $parts[count($parts) - 1];
1313
+ $type = $part->primary . '/' . $part->secondary;
1314
+ $the_file['ext'] = $ext;
1315
+ $the_file['type'] = $type;
1316
+ $overrides['test_type'] = false;
1317
+ }
1318
+
1319
+ $time = current_time('mysql');
1320
+ if ($post = get_post($post_id)) {
1321
+ if (substr($post->post_date, 0, 4) > 0)
1322
+ $time = $post->post_date;
1323
+ }
1324
+
1325
+ $file = postie_handle_upload($the_file, $overrides, $time);
1326
+ //unlink($tmpFile);
1327
+
1328
+ if (isset($file['error']))
1329
+ return new WP_Error('upload_error', $file['error']);
1330
+
1331
+ $url = $file['url'];
1332
+ $type = $file['type'];
1333
+ $file = $file['file'];
1334
+ $title = preg_replace('/\.[^.]+$/', '', basename($file));
1335
+ $content = '';
1336
+
1337
+ // use image exif/iptc data for title and caption defaults if possible
1338
+ include_once(ABSPATH . '/wp-admin/includes/image.php');
1339
+ if ($image_meta = @wp_read_image_metadata($file)) {
1340
+ if (trim($image_meta['title']))
1341
+ $title = $image_meta['title'];
1342
+ if (trim($image_meta['caption']))
1343
+ $content = $image_meta['caption'];
1344
+ }
1345
+
1346
+ // Construct the attachment array
1347
+ $attachment = array_merge(array(
1348
+ 'post_mime_type' => $type,
1349
+ 'guid' => $url,
1350
+ 'post_parent' => $post_id,
1351
+ 'post_title' => $title,
1352
+ 'post_excerpt' => $content,
1353
+ 'post_content' => $content,
1354
+ 'post_author' => $poster
1355
+ ), $post_data);
1356
+
1357
+ // Save the data
1358
+ $id = wp_insert_attachment($attachment, $file, $post_id);
1359
+ if (!is_wp_error($id)) {
1360
+ wp_update_attachment_metadata($id, wp_generate_attachment_metadata($id, $file));
1361
+ }
1362
+
1363
+ return $id;
1364
+ }
1365
+
1366
+ function postie_handle_upload(&$file, $overrides = false, $time = null) {
1367
+ // The default error handler.
1368
+ if (!function_exists('wp_handle_upload_error')) {
1369
+
1370
+ function wp_handle_upload_error(&$file, $message) {
1371
+ return array('error' => $message);
1372
+ }
1373
+
1374
+ }
1375
+
1376
+ // You may define your own function and pass the name in $overrides['upload_error_handler']
1377
+ $upload_error_handler = 'wp_handle_upload_error';
1378
+
1379
+ // You may define your own function and pass the name in $overrides['unique_filename_callback']
1380
+ $unique_filename_callback = null;
1381
+
1382
+ // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
1383
+ $action = 'wp_handle_upload';
1384
+
1385
+ // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
1386
+ $upload_error_strings = array(false,
1387
+ __("The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>."),
1388
+ __("The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form."),
1389
+ __("The uploaded file was only partially uploaded."),
1390
+ __("No file was uploaded."),
1391
+ '',
1392
+ __("Missing a temporary folder."),
1393
+ __("Failed to write file to disk."));
1394
+
1395
+ // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
1396
+ $test_form = true;
1397
+ $test_size = true;
1398
+
1399
+ // If you override this, you must provide $ext and $type!!!!
1400
+ $test_type = true;
1401
+ $mimes = false;
1402
+
1403
+ // Install user overrides. Did we mention that this voids your warranty?
1404
+ if (is_array($overrides))
1405
+ extract($overrides, EXTR_OVERWRITE);
1406
+
1407
+ // A correct form post will pass this test.
1408
+ if ($test_form && (!isset($_POST['action']) || ($_POST['action'] != $action ) ))
1409
+ return $upload_error_handler($file, __('Invalid form submission.'));
1410
+
1411
+ // A successful upload will pass this test. It makes no sense to override this one.
1412
+ if ($file['error'] > 0)
1413
+ return $upload_error_handler($file, $upload_error_strings[$file['error']]);
1414
+
1415
+ // A non-empty file will pass this test.
1416
+ if ($test_size && !($file['size'] > 0 ))
1417
+ return $upload_error_handler($file, __('File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.'));
1418
+
1419
+ // A properly uploaded file will pass this test. There should be no reason to override this one.
1420
+ if (!file_exists($file['tmp_name']))
1421
+ return $upload_error_handler($file, __('Specified file failed upload test.'));
1422
+ // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
1423
+ if ($test_type) {
1424
+ $wp_filetype = wp_check_filetype($file['name'], $mimes);
1425
+
1426
+ extract($wp_filetype);
1427
+
1428
+ if ((!$type || !$ext ) && !current_user_can('unfiltered_upload'))
1429
+ return $upload_error_handler($file, __('File type does not meet security guidelines. Try another.'));
1430
+
1431
+ if (!$ext)
1432
+ $ext = ltrim(strrchr($file['name'], '.'), '.');
1433
+
1434
+ if (!$type)
1435
+ $type = $file['type'];
1436
+ }
1437
+
1438
+ // A writable uploads dir will pass this test. Again, there's no point overriding this one.
1439
+ if (!( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ))
1440
+ return $upload_error_handler($file, $uploads['error']);
1441
+
1442
+ // fix filename (remove non-standard characters)
1443
+ $file['name'] = preg_replace("/[^\x9\xA\xD\x20-\x7F]/", "", $file['name']);
1444
+ $filename = wp_unique_filename($uploads['path'], $file['name'], $unique_filename_callback);
1445
+
1446
+ // Move the file to the uploads dir
1447
+ $new_file = $uploads['path'] . "/$filename";
1448
+ if (false === @ rename($file['tmp_name'], $new_file)) {
1449
+ return $upload_error_handler($file, sprintf(__('The uploaded file could not be moved to %s.'), $uploads['path']));
1450
+ }
1451
+
1452
+ // Set correct file permissions
1453
+ $stat = stat(dirname($new_file));
1454
+ $perms = $stat['mode'] & 0000666;
1455
+ @ chmod($new_file, $perms);
1456
+
1457
+ // Compute the URL
1458
+ $url = $uploads['url'] . "/$filename";
1459
+
1460
+ $return = apply_filters('wp_handle_upload', array('file' => $new_file, 'url' => $url, 'type' => $type));
1461
+
1462
+ return $return;
1463
+ }
1464
+
1465
+ /**
1466
+ * Searches for the existance of a certain MIME TYPE in the tree of mime attachments
1467
+ * @param primary mime
1468
+ * @param secondary mime
1469
+ * @return boolean
1470
+ */
1471
+ function SearchForMIMEType($part, $primary, $secondary) {
1472
  if ($part->ctype_primary == $primary && $part->ctype_secondary == $secondary) {
1473
+ return true;
1474
  }
1475
  if ($part->ctype_primary == "multipart") {
1476
  for ($i = 0; $i < count($part->parts); $i++) {
1477
+ if (SearchForMIMEType($part->parts[$i], $primary, $secondary)) {
1478
  return true;
1479
  }
1480
  }
1481
  }
1482
  return false;
1483
  }
1484
+
1485
  /**
1486
+ * This method sorts thru the mime parts of the message. It is looking for a certain type of text attachment. If
1487
+ * that type is present it filters out all other text types. If it is not - then nothing is done
1488
+ * @param object
1489
+ */
1490
  function FilterTextParts(&$mimeDecodedEmail, $preferTextType) {
1491
+ $newParts = array();
1492
+ $found = false;
1493
+ for ($i = 0; $i < count($mimeDecodedEmail->parts); $i++) {
1494
+ if (in_array($mimeDecodedEmail->parts[$i]->ctype_primary, array("text", "multipart"))) {
1495
+ if (SearchForMIMEType($mimeDecodedEmail->parts[$i], "text", $preferTextType)) {
1496
+ $newParts[] = &$mimeDecodedEmail->parts[$i];
1497
+ $found = true;
1498
+ }
1499
+ } else {
1500
+ $newParts[] = &$mimeDecodedEmail->parts[$i];
1501
+ }
1502
+ }
1503
+ if ($found && $newParts) {
1504
+ //This is now the filtered list of just the preferred type.
1505
+ $mimeDecodedEmail->parts = $newParts;
1506
  }
 
 
 
 
 
1507
  }
1508
+
1509
  /**
1510
+ * This function can be used to send confirmation or rejection e-mails
1511
+ * It accepts an object containing the entire message
1512
+ */
1513
+ function MailToRecipients(&$mail_content, $testEmail = false, $recipients = array(), $returnToSender, $reject = true) {
1514
+ if ($testEmail) {
1515
+ return;
1516
+ }
1517
+ $user = get_userdata('1');
1518
+ $myname = $user->user_nicename;
1519
+ $myemailadd = get_option("admin_email");
1520
+ $blogname = get_option("blogname");
1521
+ $blogurl = get_option("siteurl");
1522
+ //array_push($recipients, $myemailadd);
1523
+ if (count($recipients) == 0) {
1524
+ return false;
1525
+ }
 
1526
 
1527
  $from = trim($mail_content->headers["from"]);
1528
  $subject = $mail_content->headers['subject'];
1529
+ if ($returnToSender) {
1530
+ array_push($recipients, $from);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1531
  }
1532
+
1533
+ $headers = "From: Wordpress <" . $myemailadd . ">\r\n";
1534
+ foreach ($recipients as $recipient) {
1535
+ $recipient = trim($recipient);
1536
+ if (!empty($recipient)) {
1537
+ $headers .= "Cc: " . $recipient . "\r\n";
1538
+ }
1539
+ }
1540
+ // Set email subject
1541
+ if ($reject) {
1542
+ $alert_subject = $blogname . ": Unauthorized Post Attempt from $from";
1543
+ if ($mail_content->ctype_parameters['boundary']) {
1544
+ $boundary = $mail_content->ctype_parameters["boundary"];
1545
+ } else {
1546
+ $boundary = uniqid("B_");
1547
+ }
1548
+ // Set sender details
1549
+ /*
1550
+ if (isset($mail_content->headers["mime-version"])) {
1551
  $headers .= "Mime-Version: ". $mail_content->headers["mime-version"] . "\r\n";
1552
+ }
1553
+ if (isset($mail_content->headers["content-type"])) {
1554
  $headers .= "Content-Type: ". $mail_content->headers["content-type"] . "\r\n";
1555
+ }
1556
+ */
1557
+
1558
+ $headers.="Content-Type:multipart/alternative; boundary=\"$boundary\"\r\n";
1559
+ // SDM 20041123
1560
+ // construct mail message
1561
+ $message = "An unauthorized message has been sent to $blogname.\n";
1562
+ $message .= "Sender: $from\n";
1563
+ $message .= "Subject: $subject\n";
1564
+ $message .= "\n\nIf you wish to allow posts from this address, please add " . $from . " to the registered users list and manually add the content of the e-mail found below.";
1565
+ $message .= "\n\nOtherwise, the e-mail has already been deleted from the server and you can ignore this message.";
1566
+ $message .= "\n\nIf you would like to prevent postie from forwarding mail
1567
  in the future, please change the FORWARD_REJECTED_MAIL setting in the Postie
1568
+ settings panel";
1569
+ $message .= "\n\nThe original content of the e-mail has been attached.\n\n";
1570
+ $mailtext = "--$boundary\r\n";
1571
+ $mailtext .= "Content-Type: text/plain;format=flowed;charset=\"iso-8859-1\";reply-type=original\n";
1572
+ $mailtext .= "Content-Transfer-Encoding: 7bit\n";
1573
+ $mailtext .= "\n";
1574
+ $mailtext .= "$message\n";
1575
+ if ($mail_content->parts) {
1576
+ $mailparts = $mail_content->parts;
1577
+ } else {
1578
+ $mailparts[] = $mail_content;
1579
+ }
1580
+ foreach ($mailparts as $part) {
1581
+ $mailtext .= "--$boundary\r\n";
1582
+ $mailtext .= "Content-Type: " . $part->headers["content-type"] . "\n";
1583
+ $mailtext .= "Content-Transfer-Encoding: " . $part->headers["content-transfer-encoding"] . "\n";
1584
+ if (isset($part->headers["content-disposition"])) {
1585
+ $mailtext .= "Content-Disposition: " . $part->headers["content-disposition"] . "\n";
1586
+ }
1587
+ $mailtext .= "\n";
1588
+ $mailtext .= $part->body;
1589
+ }
1590
  } else {
1591
+ $alert_subject = "Successfully posted to $blogname";
1592
+ $mailtext = "Your post '$subject' has been successfully published to " .
1593
+ "$blogname <$blogurl>.\n";
 
 
 
 
 
 
 
 
1594
  }
 
 
 
 
 
1595
 
 
 
 
1596
 
1597
+ // Send message
1598
+ mail($myemailadd, $alert_subject, $mailtext, $headers);
1599
+
1600
+ return true;
1601
  }
1602
+
1603
  /**
1604
+ * This function handles the basic mime decoding
1605
+ * @param string
1606
+ * @return array
1607
+ */
1608
+ function DecodeMIMEMail($email, $decodeHeaders = false) {
1609
  $params = array();
1610
  $params['include_bodies'] = true;
1611
  $params['decode_bodies'] = false;
1612
  $params['decode_headers'] = $decodeHeaders;
1613
  $params['input'] = $email;
1614
  //$decoded = imap_mime_header_decode($email);
1615
+ $decoded = Mail_mimeDecode::decode($params);
1616
+ if (empty($decoded->parts))
1617
+ $decoded->parts = array(); // have an empty array at minimum, so that it is safe for "foreach"
1618
  return $decoded;
1619
  }
1620
+
1621
  /**
1622
+ * This is used for debugging the mimeDecodedEmail of the mail
1623
+ */
1624
  function DisplayMIMEPartTypes($mimeDecodedEmail) {
1625
+ foreach ($mimeDecodedEmail->parts as $part) {
1626
+ print("<p>" . $part->ctype_primary . " / " . $part->ctype_secondary . "/ " . $part->headers['content-transfer-encoding'] . "\n");
1627
  }
1628
  }
1629
 
1630
  /**
1631
+ * This compares the current address to the list of authorized addresses
1632
+ * @param string - email address
1633
+ * @return boolean
1634
+ */
1635
  function CheckEmailAddress($address, $authorized) {
1636
+ $isAuthorized = in_array(strtolower($address), $authorized);
1637
+ return $isAuthorized;
1638
  }
1639
+
1640
  /**
1641
+ * This method works around a problemw with email address with extra <> in the email address
1642
+ * @param string
1643
+ * @return string
1644
+ */
1645
  function RemoveExtraCharactersInEmailAddress($address) {
1646
  $matches = array();
1647
+ if (preg_match('/^[^<>]+<([^<> ()]+)>$/', $address, $matches)) {
1648
  $address = $matches[1];
1649
+ } else if (preg_match('/<([^<> ()]+)>/', $address, $matches)) {
 
1650
  $address = $matches[1];
1651
  }
1652
 
1653
  return($address);
1654
  }
1655
 
1656
+ /**
1657
+ * This function gleans the name from the 'from:' header if available. If not
1658
+ * it just returns the username (everything before @)
1659
+ */
1660
  function GetNameFromEmail($address) {
1661
  $matches = array();
1662
+ if (preg_match('/^([^<>]+)<([^<> ()]+)>$/', $address, $matches)) {
1663
  $name = $matches[1];
1664
+ } else if (preg_match('/<([^<>@ ()]+)>/', $address, $matches)) {
 
1665
  $name = $matches[1];
1666
  }
1667
 
1668
  return($name);
1669
  }
1670
 
1671
+ /**
1672
+ * Choose an appropriate file icon based on the extension and mime type of
1673
+ * the attachment
1674
+ */
1675
+ function chooseAttachmentIcon($file, $primary, $secondary, $iconSet = 'silver', $size = '32') {
1676
+ if ($iconSet == 'none')
1677
+ return('');
1678
+ $fileName = basename($file);
1679
+ $parts = explode('.', $fileName);
1680
+ $ext = $parts[count($parts) - 1];
1681
+ $docExts = array('doc', 'docx');
1682
+ $docMimes = array('msword', 'vnd.ms-word',
1683
+ 'vnd.openxmlformats-officedocument.wordprocessingml.document');
1684
+ $pptExts = array('ppt', 'pptx');
1685
+ $pptMimes = array('mspowerpoint', 'vnd.ms-powerpoint',
1686
+ 'vnd.openxmlformats-officedocument.');
1687
+ $xlsExts = array('xls', 'xlsx');
1688
+ $xlsMimes = array('msexcel', 'vnd.ms-excel',
1689
+ 'vnd.openxmlformats-officedocument.spreadsheetml.sheet');
1690
+ $iWorkMimes = array('zip', 'octet-stream');
1691
+ $mpgExts = array('mpg', 'mpeg', 'mp2');
1692
+ $mpgMimes = array('mpg', 'mpeg', 'mp2');
1693
+ $mp3Exts = array('mp3');
1694
+ $mp3Mimes = array('mp3', 'mpeg3', 'mpeg');
1695
+ $mp4Exts = array('mp4', 'm4v');
1696
+ $mp4Mimes = array('mp4', 'mpeg4', 'octet-stream');
1697
+ $aacExts = array('m4a', 'aac');
1698
+ $aacMimes = array('m4a', 'aac', 'mp4');
1699
+ $aviExts = array('avi');
1700
+ $aviMimes = array('avi', 'x-msvideo');
1701
+ $movExts = array('mov');
1702
+ $movMimes = array('mov', 'quicktime');
1703
+ if ($ext == 'pdf' && $secondary == 'pdf') {
1704
+ $fileType = 'pdf';
1705
+ } else if ($ext == 'pages' && in_array($secondary, $iWorkMimes)) {
1706
+ $fileType = 'pages';
1707
+ } else if ($ext == 'numbers' && in_array($secondary, $iWorkMimes)) {
1708
+ $fileType = 'numbers';
1709
+ } else if ($ext == 'key' && in_array($secondary, $iWorkMimes)) {
1710
+ $fileType = 'key';
1711
+ } else if (in_array($ext, $docExts) && in_array($secondary, $docMimes)) {
1712
+ $fileType = 'doc';
1713
+ } else if (in_array($ext, $pptExts) && in_array($secondary, $pptMimes)) {
1714
+ $fileType = 'ppt';
1715
+ } else if (in_array($ext, $xlsExts) && in_array($secondary, $xlsMimes)) {
1716
+ $fileType = 'xls';
1717
+ } else if (in_array($ext, $mp4Exts) && in_array($secondary, $mp4Mimes)) {
1718
+ $fileType = 'mp4';
1719
+ } else if (in_array($ext, $movExts) && in_array($secondary, $movMimes)) {
1720
+ $fileType = 'mov';
1721
+ } else if (in_array($ext, $aviExts) && in_array($secondary, $aviMimes)) {
1722
+ $fileType = 'avi';
1723
+ } else if (in_array($ext, $mp3Exts) && in_array($secondary, $mp3Mimes)) {
1724
+ $fileType = 'mp3';
1725
+ } else if (in_array($ext, $mpgExts) && in_array($secondary, $mpgMimes)) {
1726
+ $fileType = 'mpg';
1727
+ } else if (in_array($ext, $aacExts) && in_array($secondary, $aacMimes)) {
1728
+ $fileType = 'aac';
1729
+ } else {
1730
+ $fileType = 'default';
1731
+ }
1732
+ $fileName = "/icons/$iconSet/$fileType-$size.png";
1733
+ if (!file_exists(POSTIE_ROOT . $fileName))
1734
+ $fileName = "/icons/$iconSet/default-$size.png";
1735
+ $iconHtml = "<img src='" . POSTIE_URL . $fileName . "' alt='$fileType icon' />";
1736
+ return($iconHtml);
1737
+ }
1738
+
1739
+ function parseTemplate($id, $type, $template, $size = 'medium') {
1740
+
1741
+ /* we check template for thumb, thumbnail, large, full and use that as
1742
+ size. If not found, we default to medium */
1743
+ if ($type == 'image') {
1744
+ $sizes = array('thumbnail', 'medium', 'large');
1745
+ $hwstrings = array();
1746
+ $widths = array();
1747
+ $heights = array();
1748
+ for ($i = 0; $i < count($sizes); $i++) {
1749
+ list( $img_src[$i], $widths[$i], $heights[$i] ) = image_downsize($id, $sizes[$i]);
1750
+ $hwstrings[$i] = image_hwstring($widths[$i], $heights[$i]);
1751
+ }
1752
+ }
1753
+ $attachment = get_post($id);
1754
+ $the_parent = get_post($attachment->post_parent);
1755
+ $uploadDir = wp_upload_dir();
1756
+ $fileName = basename($attachment->guid);
1757
+ $absFileName = $uploadDir['path'] . '/' . $fileName;
1758
+ $relFileName = str_replace(ABSPATH, '', $absFileName);
1759
+ $fileLink = wp_get_attachment_url($id);
1760
+ $pageLink = get_attachment_link($id);
1761
+
1762
+ $template = str_replace('{TITLE}', $attachment->post_title, $template);
1763
+ $template = str_replace('{ID}', $id, $template);
1764
+ $template = str_replace('{THUMBNAIL}', $img_src[0], $template);
1765
+ $template = str_replace('{THUMB}', $img_src[0], $template);
1766
+ $template = str_replace('{MEDIUM}', $img_src[1], $template);
1767
+ $template = str_replace('{LARGE}', $img_src[2], $template);
1768
+ $template = str_replace('{FULL}', $fileLink, $template);
1769
+ $template = str_replace('{FILELINK}', $fileLink, $template);
1770
+ $template = str_replace('{PAGELINK}', $pageLink, $template);
1771
+ $template = str_replace('{THUMBWIDTH}', $widths[0] . 'px', $template);
1772
+ $template = str_replace('{THUMBHEIGHT}', $heights[0] . 'px', $template);
1773
+ $template = str_replace('{MEDIUMWIDTH}', $widths[1] . 'px', $template);
1774
+ $template = str_replace('{MEDIUMHEIGHT}', $heights[1] . 'px', $template);
1775
+ $template = str_replace('{LARGEWIDTH}', $widths[2] . 'px', $template);
1776
+ $template = str_replace('{LARGEHEIGHT}', $heights[2] . 'px', $template);
1777
+ $template = str_replace('{FILENAME}', $fileName, $template);
1778
+ $template = str_replace('{IMAGE}', $fileLink, $template);
1779
+ $template = str_replace('{URL}', $fileLink, $template);
1780
+ $template = str_replace('{RELFILENAME}', $relFileName, $template);
1781
+ $template = str_replace('{POSTTITLE}', $the_parent->post_title, $template);
1782
+ if ($attachment->post_excerpt != '') {
1783
+ $template = str_replace('{CAPTION}', $attachment->post_excerpt, $template);
1784
+ } elseif (!preg_match("/$attachment->post_title/i", $fileName)) {
1785
+ $template = str_replace('{CAPTION}', $attachment->post_title, $template);
1786
+ } else {
1787
+ //$template=str_replace('{CAPTION}', '', $template);
1788
+ }
1789
+ return($template . '<br />');
1790
+ }
 
 
 
1791
 
1792
  /**
1793
+ * When sending in HTML email the html refers to the content-id(CID) of the image - this replaces
1794
+ * the cid place holder with the actual url of the image sent in
1795
+ * @param string - text of post
1796
+ * @param array - array of HTML for images for post
1797
+ */
1798
+ function ReplaceImageCIDs(&$content, &$attachments) {
1799
  $used = array();
1800
  foreach ($attachments["cids"] as $key => $info) {
1801
  $key = str_replace('/', '\/', $key);
1802
  $pattern = "/cid:$key/";
1803
+ if (preg_match($pattern, $content)) {
1804
+ $content = preg_replace($pattern, $info[0], $content);
1805
  $used[] = $info[1]; //Index of html to ignore
1806
  }
1807
  }
1808
  $html = array();
1809
  for ($i = 0; $i < count($attachments["html"]); $i++) {
1810
+ if (!in_array($i, $used)) {
1811
  $html[] = $attachments["html"][$i];
1812
  }
1813
  }
1814
  $attachments["html"] = $html;
 
1815
  }
1816
+
1817
  /**
1818
+ * This function handles replacing image place holder #img1# with the HTML for that image
1819
+ * @param string - text of post
1820
+ * @param array - array of HTML for images for post
1821
+ */
1822
+ function ReplaceImagePlaceHolders(&$content, $attachments, $config) {
1823
+ extract($config);
1824
+ ($start_image_count_at_zero ? $startIndex = 0 : $startIndex = 1);
1825
+ if (!empty($attachments) && $auto_gallery) {
1826
+ $value = '[gallery]';
1827
+ if ($images_append) {
1828
+ $content .= $value;
1829
+ } else {
1830
+ $content = "$value\n" . $content;
1831
+ }
1832
+ return;
1833
+ }
1834
+ $pictures = array();
1835
+ ksort($attachments);
1836
+ foreach ($attachments as $i => $value) {
1837
+ // looks for ' #img1# ' etc... and replaces with image
1838
+ $img_placeholder_temp = str_replace("%", intval($startIndex + $i), $image_placeholder);
1839
+ $eimg_placeholder_temp = str_replace("%", intval($startIndex + $i), "#eimg%#");
1840
+ $img_placeholder_temp = rtrim($img_placeholder_temp, '#');
1841
+ $eimg_placeholder_temp = rtrim($eimg_placeholder_temp, '#');
1842
+ if (stristr($content, $img_placeholder_temp) ||
1843
+ stristr($content, $eimg_placeholder_temp)) {
1844
+ // look for caption
1845
+ $caption = '';
1846
+ $content = preg_replace("/&#0?39;/", "'", $content);
1847
+ $content = preg_replace("/&(#0?34|quot);/", "\"", $content);
1848
+ if (preg_match("/$img_placeholder_temp caption=['\"]?(.*?)['\"]?#/", $content, $matches)) {
1849
+ $caption = $matches[1];
1850
+ $img_placeholder_temp = substr($matches[0], 0, -1);
1851
+ $eimg_placeholder_temp = substr($matches[0], 0, -1);
1852
+ }
1853
+ $value = str_replace('{CAPTION}', $caption, $value);
1854
+ $img_placeholder_temp.='#';
1855
+ $eimg_placeholder_temp.='#';
1856
+ $content = str_replace($img_placeholder_temp, $value, $content);
1857
+ $content = str_replace($eimg_placeholder_temp, $value, $content);
1858
+ //print(htmlspecialchars("value=$value\n",ENT_QUOTES));
1859
+ //print(htmlspecialchars("content=\n***\n$content\n***\n",ENT_QUOTES));
1860
+ } else {
1861
+ $value = str_replace('{CAPTION}', '', $value);
1862
+ /* if using the gallery shortcode, don't add pictures at all */
1863
+ if (!preg_match("/\[gallery[^\[]*\]/", $content, $matches)) {
1864
+ $pics .= $value;
1865
+ }
1866
+ }
1867
+ }
1868
  if ($images_append) {
1869
+ $content .= $pics;
1870
  } else {
1871
+ $content = $pics . $content;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1872
  }
 
 
 
 
 
 
1873
  }
1874
+
1875
  /**
1876
+ * This function handles finding and setting the correct subject
1877
+ * @return array - (subject,content)
1878
+ */
1879
+ function GetSubject(&$mimeDecodedEmail, &$content, $config) {
1880
+ extract($config);
1881
+ global $charset;
1882
+ //assign the default title/subject
1883
+ if ($mimeDecodedEmail->headers['subject'] == NULL) {
1884
+ if ($allow_subject_in_mail) {
1885
+ list($subject, $content) =
1886
+ ParseInMessageSubject($content, $default_title);
1887
+ } else {
1888
+ $subject = $default_title;
1889
+ }
1890
+ $mimeDecodedEmail->headers['subject'] = $subject;
 
 
 
 
 
 
 
1891
  } else {
1892
+ $subject = $mimeDecodedEmail->headers['subject'];
1893
+ if ($mimeDecodedEmail->headers["content-transfer-encoding"] != '') {
1894
+ $encoding = $mimeDecodedEmail->headers["content-transfer-encoding"];
1895
+ } else if ($mimeDecodedEmail->ctype_parameters["content-transfer-encoding"] != '') {
1896
+ $encoding = $mimeDecodedEmail->ctype_parameters["content-transfer-encoding"];
1897
+ } else {
1898
+ $encoding = '7bit';
1899
+ }
1900
+ if (function_exists(imap_mime_header_decode)) {
1901
+ $subject = '';
1902
+ //$elements=imap_mime_header_decode($mimeDecodedEmail->headers['subject']);
1903
+ //$text = "=?utf-8?b?w6XDpMO2?= unicode";
1904
+ $text = $mimeDecodedEmail->headers['subject'];
1905
+ //$text="test emails with ISO 8859-2 cahracters ąęśćółńżźĄĘŚÓŁŃŻŹ";
1906
+ //echo "text='$text'\n";
1907
+ $elements = imap_mime_header_decode($text);
1908
+ for ($i = 0; $i < count($elements); $i++) {
1909
+ $thischarset = $elements[$i]->charset;
1910
+ if ($thischarset == 'default')
1911
+ $thischarset = $charset;
1912
+ //echo "Charset: {$thischarset}\n";
1913
+ //echo "Text: ". utf8_encode($elements[$i]->text). "\n\n";
1914
+ $subject.=HandleMessageEncoding($encoding, $thischarset, $elements[$i]->text, $message_encoding, $message_dequote);
1915
+ //echo "subject=$subject\n";
1916
+ }
1917
+ //echo "now subject= $subject\n";
1918
+ //if ($element->charset!='') {
1919
+ //$charset = $element[0]->charset;
1920
+ //echo "charset='$charset'\n";
1921
+ // }
1922
+ }
1923
+ if (!$allow_html_in_subject) {
1924
+ $subject = htmlentities($subject);
1925
+ }
1926
+ }
1927
+ //This is for ISO-2022-JP - Can anyone confirm that this is still neeeded?
1928
+ // escape sequence is 'ESC $ B' == 1b 24 42 hex.
1929
+ if (strpos($subject, "\x1b\x24\x42") !== false) {
1930
+ // found iso-2022-jp escape sequence in subject... convert!
1931
+ $subject = iconv("ISO-2022-JP//TRANSLIT", "UTF-8", $subject);
1932
+ }
1933
+ return($subject);
1934
+ }
1935
+
1936
+ /**
1937
+ * this function determines tags for the post
1938
+ *
1939
+ */
1940
  function postie_get_tags(&$content, $defaultTags) {
1941
+ $post_tags = array();
1942
+ //try and determine tags
1943
+ if (preg_match('/tags: ?(.*)\n/i', $content, $matches)) {
1944
+ $content = str_replace($matches[0], "", $content);
1945
+ $post_tags = preg_split("/,\s*/", $matches[1]);
1946
+ }
1947
+ if (!count($post_tags) && !empty($defaultTags)) {
1948
+ $post_tags = $defaultTags;
1949
+ }
1950
+ return($post_tags);
1951
+ }
1952
+
1953
+ /**
1954
+ * this function determines excerpt for the post
1955
+ *
1956
+ */
1957
  function GetPostExcerpt(&$content, $filterNewLines, $convertNewLines) {
1958
+ global $wpdb;
1959
+ $post_excerpt = '';
1960
+ if (preg_match('/:excerptstart ?(.*):excerptend/s', $content, $matches)) {
1961
+ $content = str_replace($matches[0], "", $content);
1962
+ $post_excerpt = $matches[1];
1963
+ if ($filterNewLines)
1964
+ $post_excerpt = FilterNewLines($post_excerpt, $convertNewLines);
1965
+ }
1966
+ return($post_excerpt);
1967
  }
1968
+
1969
  /**
1970
+ * This function determines categories for the post
1971
+ * @return array
1972
+ */
1973
  function GetPostCategories(&$subject, $defaultCategory) {
1974
  global $wpdb;
1975
  $post_categories = array();
1976
  $matches = array();
1977
  //try and determine category
1978
+ if (preg_match('/(.+): (.*)/', $subject, $matches)) {
1979
  $subject = trim($matches[2]);
1980
  $matches[1] = array($matches[1]);
1981
+ } else if (preg_match_all('/\[(.[^\[]*)\]/', $subject, $matches)) {
1982
+ preg_match("/]([^\[]*)$/", $subject, $subject_matches);
 
1983
  $subject = trim($subject_matches[1]);
1984
+ } else if (preg_match_all('/-(.[^-]*)-/', $subject, $matches)) {
1985
+ preg_match("/-(.[^-]*)$/", $subject, $subject_matches);
 
1986
  $subject = trim($subject_matches[1]);
1987
  }
1988
  if (count($matches)) {
1989
+ foreach ($matches[1] as $match) {
1990
  $match = trim($match);
1991
  $category = NULL;
1992
+ print("Working on $match\n");
1993
 
1994
  $sql_name = 'SELECT term_id
1995
+ FROM ' . $wpdb->terms . '
1996
  WHERE name=\'' . addslashes($match) . '\'';
1997
  $sql_id = 'SELECT term_id
1998
+ FROM ' . $wpdb->terms . '
1999
  WHERE term_id=\'' . addslashes($match) . '\'';
2000
  $sql_sub_name = 'SELECT term_id
2001
+ FROM ' . $wpdb->terms . '
2002
  WHERE name LIKE \'' . addslashes($match) . '%\' limit 1';
2003
+
2004
+ if ($category = $wpdb->get_var($sql_name)) {
2005
  //then category is a named and found
2006
+ } elseif ($category = $wpdb->get_var($sql_id)) {
2007
  //then cateogry was an ID and found
2008
+ } elseif ($category = $wpdb->get_var($sql_sub_name)) {
2009
  //then cateogry is a start of a name and found
2010
+ }
2011
  if ($category) {
2012
  $post_categories[] = $category;
2013
  }
2014
  }
2015
  }
2016
  if (!count($post_categories)) {
2017
+ $post_categories[] = $defaultCategory;
2018
  }
2019
  return($post_categories);
2020
  }
2021
+
2022
  /**
2023
+ * This function just outputs a simple html report about what is being posted in
2024
+ */
2025
  function DisplayEmailPost($details) {
2026
+ if (defined('POSTIE_DEBUG')) {
2027
+ print_r($config);
2028
+ print_r($details);
2029
+ }
2030
+ $theFinalContent = $details['post_content'];
2031
+ // Report
2032
+ print '</pre><p><b>Post Author</b>: ' . $details["post_author"] . '<br />' . "\n";
2033
+ print '<b>Date</b>: ' . $details["post_date"] . '<br />' . "\n";
2034
+ foreach ($details["post_category"] as $category) {
2035
+ print '<b>Category</b>: ' . $category . '<br />' . "\n";
2036
+ }
2037
+ print '<b>Ping Status</b>: ' . $details["ping_status"] . '<br />' . "\n";
2038
+ print '<b>Comment Status</b>: ' . $details["comment_status"] . '<br />' . "\n";
2039
+ print '<b>Subject</b>: ' . $details["post_title"] . '<br />' . "\n";
2040
+ print '<b>Postname</b>: ' . $details["post_name"] . '<br />' . "\n";
2041
+ print '<b>Post Id</b>: ' . $details["ID"] . '<br />' . "\n";
2042
+ print '<b>Posted content:</b></p><hr />' .
2043
+ $details["post_content"] . '<hr /><pre>';
2044
+ //if (function_exists('memory_get_peak_usage'))
2045
  // echo "Memory used: ". memory_get_peak_usage(). "\n";
2046
  }
2047
+
2048
  /**
2049
+ * Takes a value and builds a simple simple yes/no select box
2050
+ * @param string
2051
+ * @param string
2052
+ * @param string
2053
+ * @param string
2054
+ */
2055
+ function BuildBooleanSelect($label, $id, $current_value, $recommendation = NULL) {
2056
+ $string = "<tr>
2057
+ <th scope=\"row\">" . __($label, 'postie') . ":</th>
2058
  <td><select name=\"$id\" id=\"$id\">
2059
+ <option value=\"1\">" . __("Yes", 'postie') . "</option>
2060
+ <option value=\"0\" " . (!$current_value ? "SELECTED" : NULL) .
2061
+ ">" . __("No", 'postie') . '</option>
2062
  </select>';
2063
+ if ($recommendation != NULL) {
2064
+ $string.='<span class="recommendation">' . __($recommendation, 'postie') . '</span>';
 
2065
  }
2066
  $string.="</td>\n</tr>";
2067
  return($string);
2068
  }
2069
+
2070
  /**
2071
+ * This takes an array and display a text box for editing
2072
+ * @param string
2073
+ * @param string
2074
+ * @param array
2075
+ * @param string
2076
+ */
2077
+ function BuildTextArea($label, $id, $current_value, $recommendation = NULL) {
2078
+ $string = "<tr> <th scope=\"row\">" . __($label, 'postie') . ":";
2079
+ if ($recommendation) {
2080
+ $string.="<br /><span class='recommendation'>" . __($recommendation, 'postie') . "</span>";
2081
+ }
2082
+ $string.="</th>";
2083
+
2084
+ $string .="<td><textarea cols=40 rows=3 name=\"$id\" id=\"$id\">";
2085
+ $current_value = preg_split("/[,\r\n]+/", trim($current_value));
2086
+ if (is_array($current_value)) {
2087
+ foreach ($current_value as $item) {
2088
+ $string .= "$item\n";
2089
+ }
2090
+ }
2091
+ $string .= "</textarea></td>
 
2092
  </tr>";
2093
+ return($string);
2094
  }
2095
+
2096
  /**
2097
+ * This function resets all the configuration options to the default
2098
+ */
2099
  function ResetPostieConfig() {
2100
+ $newconfig = get_postie_config_defaults();
2101
+ $config = get_option('postie-settings');
2102
+ $save_keys = array('mail_password', 'mail_server', 'mail_server_port', 'mail_userid', 'iinput_protocol');
2103
+ foreach ($save_keys as $key)
2104
+ $newconfig[$key] = $config[$key];
2105
+ update_option('postie-settings', $newconfig);
2106
+ UpdatePostieConfig($newconfig);
2107
+ return $newconfig;
2108
  }
2109
 
2110
  /**
2111
+ * This function used to handle updating the configuration.
2112
+ * @return boolean
2113
+ */
2114
  function UpdatePostieConfig($data) {
2115
+ UpdatePostiePermissions($data["role_access"]);
2116
+ // We also update the cron settings
2117
+ if ($data['interval'] != '') {
2118
+ postie_decron();
2119
+ if ($data['interval'] != 'manual') {
2120
+ postie_cron($interval = $data['interval']);
2121
+ }
2122
  }
2123
+ return(1);
 
2124
  }
2125
+
2126
  /**
2127
+ * return an array of the config defaults
2128
+ */
2129
  function get_postie_config_defaults() {
2130
+ include('templates/audio_templates.php');
2131
+ include('templates/image_templates.php');
2132
+ include('templates/video1_templates.php');
2133
+ include('templates/video2_templates.php');
2134
+ return array(
2135
+ 'add_meta' => 'no',
2136
+ 'admin_username' => 'admin',
2137
+ 'allow_html_in_body' => true,
2138
+ 'allow_html_in_subject' => true,
2139
+ 'allow_subject_in_mail' => true,
2140
+ 'audiotemplate' => $simple_link,
2141
+ 'audiotypes' => array('m4a', 'mp3', 'ogg', 'wav', 'mpeg'),
2142
+ 'authorized_addresses' => array(),
2143
+ 'banned_files_list' => array(),
2144
+ 'confirmation_email' => '',
2145
+ 'convertnewline' => false,
2146
+ 'converturls' => true,
2147
+ 'custom_image_field' => false,
2148
+ 'default_post_category' => NULL,
2149
+ 'default_post_tags' => array(),
2150
+ 'default_title' => "Live From The Field",
2151
+ 'delete_mail_after_processing' => true,
2152
+ 'drop_signature' => true,
2153
+ 'filternewlines' => true,
2154
+ 'forward_rejected_mail' => true,
2155
+ 'icon_set' => 'silver',
2156
+ 'icon_size' => 32,
2157
+ 'auto_gallery' => false,
2158
+ 'image_new_window' => false,
2159
+ 'image_placeholder' => "#img%#",
2160
+ 'images_append' => true,
2161
+ 'imagetemplate' => $wordpress_default,
2162
+ 'imagetemplates' => $imageTemplates,
2163
+ 'input_protocol' => "pop3",
2164
+ 'interval' => 'twiceperhour',
2165
+ 'mail_server' => NULL,
2166
+ 'mail_server_port' => 110,
2167
+ 'mail_userid' => NULL,
2168
+ 'mail_password' => NULL,
2169
+ 'message_start' => ":start",
2170
+ 'message_end' => ":end",
2171
+ 'message_encoding' => "UTF-8",
2172
+ 'message_dequote' => true,
2173
+ 'post_status' => 'publish',
2174
+ 'prefer_text_type' => "plain",
2175
+ 'return_to_sender' => false,
2176
+ 'role_access' => array(),
2177
+ 'selected_audiotemplate' => 'simple_link',
2178
+ 'selected_imagetemplate' => 'wordpress_default',
2179
+ 'selected_video1template' => 'simple_link',
2180
+ 'selected_video2template' => 'simple_link',
2181
+ 'shortcode' => false,
2182
+ 'sig_pattern_list' => array('--', '- --'),
2183
+ 'smtp' => array(),
2184
+ 'start_image_count_at_zero' => false,
2185
+ 'supported_file_types' => array('video', 'application'),
2186
+ 'turn_authorization_off' => false,
2187
+ 'time_offset' => get_option('gmt_offset'),
2188
+ 'video1template' => $simple_link,
2189
+ 'video1types' => array('mp4', 'mpeg4', '3gp', '3gpp', '3gpp2', '3gp2', 'mov', 'mpeg'),
2190
+ 'video2template' => $simple_link,
2191
+ 'video2types' => array('x-flv'),
2192
+ 'video1templates' => $video1Templates,
2193
+ 'video2templates' => $video2Templates,
2194
+ 'wrap_pre' => 'no'
2195
  );
2196
  }
2197
+
2198
  /**
2199
+ * =======================================================
2200
+ * the following functions are only used to retrieve the old (pre 1.4) config, to convert it
2201
+ * to the new format
2202
+ */
2203
  function GetListOfArrayConfig() {
2204
+ return(array('SUPPORTED_FILE_TYPES', 'AUTHORIZED_ADDRESSES',
2205
+ 'SIG_PATTERN_LIST', 'BANNED_FILES_LIST', 'VIDEO1TYPES',
2206
+ 'VIDEO2TYPES', 'AUDIOTYPES', 'SMTP'));
2207
  }
2208
+
2209
  /**
2210
+ * This function retrieves the old-format config (pre 1.4) from the database
2211
+ * @return array
2212
+ */
2213
  function ReadDBConfig() {
2214
+ $config = array();
2215
+ global $wpdb;
2216
+ $data = $wpdb->get_results("SELECT label,value FROM " . $GLOBALS["table_prefix"] . "postie_config;");
2217
+ if (is_array($data)) {
2218
+ foreach ($data as $row) {
2219
+ if (in_array($row->label, GetListOfArrayConfig())) {
2220
+ $config[$row->label] = unserialize($row->value);
2221
+ } else {
2222
+ $config[$row->label] = $row->value;
2223
+ }
2224
+ }
2225
  }
2226
+ return($config);
 
2227
  }
2228
+
2229
  /**
2230
+ * This function processes the old-format config (pre 1.4) for conversion to the 1.4 format
2231
+ * @return array
2232
+ * @access private
2233
+ */
2234
  function GetDBConfig() {
2235
  $config = ReadDBConfig();
2236
+ if (!isset($config["ADMIN_USERNAME"]))
2237
+ $config["ADMIN_USERNAME"] = 'admin';
2238
+ if (!isset($config["PREFER_TEXT_TYPE"]))
2239
+ $config["PREFER_TEXT_TYPE"] = "plain";
2240
+ if (!isset($config["DEFAULT_TITLE"]))
2241
+ $config["DEFAULT_TITLE"] = "Live From The Field";
2242
+ if (!isset($config["INPUT_PROTOCOL"]))
2243
+ $config["INPUT_PROTOCOL"] = "pop3";
2244
+ if (!isset($config["IMAGE_PLACEHOLDER"]))
2245
+ $config["IMAGE_PLACEHOLDER"] = "#img%#";
2246
+ if (!isset($config["IMAGES_APPEND"]))
2247
+ $config["IMAGES_APPEND"] = true;
2248
+ if (!isset($config["ALLOW_SUBJECT_IN_MAIL"]))
2249
+ $config["ALLOW_SUBJECT_IN_MAIL"] = true;
2250
  if (!isset($config["DROP_SIGNATURE"]))
2251
+ $config["DROP_SIGNATURE"] = true;
2252
+ if (!isset($config["MESSAGE_START"]))
2253
+ $config["MESSAGE_START"] = ":start";
2254
+ if (!isset($config["MESSAGE_END"]))
2255
+ $config["MESSAGE_END"] = ":end";
2256
+ if (!isset($config["FORWARD_REJECTED_MAIL"]))
2257
+ $config["FORWARD_REJECTED_MAIL"] = true;
2258
+ if (!isset($config["RETURN_TO_SENDER"]))
2259
+ $config["RETURN_TO_SENDER"] = false;
2260
+ if (!isset($config["CONFIRMATION_EMAIL"]))
2261
+ $config["CONFIRMATION_EMAIL"] = '';
2262
+ if (!isset($config["ALLOW_HTML_IN_SUBJECT"]))
2263
+ $config["ALLOW_HTML_IN_SUBJECT"] = true;
2264
+ if (!isset($config["ALLOW_HTML_IN_BODY"]))
2265
+ $config["ALLOW_HTML_IN_BODY"] = true;
2266
+ if (!isset($config["START_IMAGE_COUNT_AT_ZERO"]))
2267
+ $config["START_IMAGE_COUNT_AT_ZERO"] = false;
2268
+ if (!isset($config["MESSAGE_ENCODING"]))
2269
+ $config["MESSAGE_ENCODING"] = "UTF-8";
2270
+ if (!isset($config["MESSAGE_DEQUOTE"]))
2271
+ $config["MESSAGE_DEQUOTE"] = true;
2272
+ if (!isset($config["TURN_AUTHORIZATION_OFF"]))
2273
+ $config["TURN_AUTHORIZATION_OFF"] = false;
2274
+ if (!isset($config["CUSTOM_IMAGE_FIELD"]))
2275
+ $config["CUSTOM_IMAGE_FIELD"] = false;
2276
+ if (!isset($config["CONVERTNEWLINE"]))
2277
+ $config["CONVERTNEWLINE"] = false;
2278
+ if (!isset($config["SIG_PATTERN_LIST"]))
2279
+ $config["SIG_PATTERN_LIST"] = array('--', '- --');
2280
  if (!isset($config["BANNED_FILES_LIST"]))
2281
+ $config["BANNED_FILES_LIST"] = array();
2282
  if (!isset($config["SUPPORTED_FILE_TYPES"]))
2283
+ $config["SUPPORTED_FILE_TYPES"] = array("video", "application");
2284
+ if (!isset($config["AUTHORIZED_ADDRESSES"]))
2285
+ $config["AUTHORIZED_ADDRESSES"] = array();
2286
+ if (!isset($config["MAIL_SERVER"]))
2287
+ $config["MAIL_SERVER"] = NULL;
2288
+ if (!isset($config["MAIL_SERVER_PORT"]))
2289
+ $config["MAIL_SERVER_PORT"] = NULL;
2290
+ if (!isset($config["MAIL_USERID"]))
2291
+ $config["MAIL_USERID"] = NULL;
2292
+ if (!isset($config["MAIL_PASSWORD"]))
2293
+ $config["MAIL_PASSWORD"] = NULL;
2294
+ if (!isset($config["DEFAULT_POST_CATEGORY"]))
2295
+ $config["DEFAULT_POST_CATEGORY"] = NULL;
2296
+ if (!isset($config["DEFAULT_POST_TAGS"]))
2297
+ $config["DEFAULT_POST_TAGS"] = NULL;
2298
+ if (!isset($config["TIME_OFFSET"]))
2299
+ $config["TIME_OFFSET"] = get_option('gmt_offset');
2300
+ if (!isset($config["WRAP_PRE"]))
2301
+ $config["WRAP_PRE"] = 'no';
2302
+ if (!isset($config["CONVERTURLS"]))
2303
+ $config["CONVERTURLS"] = true;
2304
+ if (!isset($config["SHORTCODE"]))
2305
+ $config["SHORTCODE"] = false;
2306
+ if (!isset($config["ADD_META"]))
2307
+ $config["ADD_META"] = 'no';
2308
+ $config['ICON_SETS'] = array('silver', 'black', 'white', 'custom', 'none');
2309
+ if (!isset($config["ICON_SET"]))
2310
+ $config["ICON_SET"] = 'silver';
2311
+ $config['ICON_SIZES'] = array(32, 48, 64);
2312
+ if (!isset($config["ICON_SIZE"]))
2313
+ $config["ICON_SIZE"] = 32;
2314
+ if (!isset($config["AUDIOTEMPLATE"]))
2315
+ $config["AUDIOTEMPLATE"] = $simple_link;
2316
+ if (!isset($config["SELECTED_AUDIOTEMPLATE"]))
2317
+ $config['SELECTED_AUDIOTEMPLATE'] = 'simple_link';
2318
  include('templates/audio_templates.php');
2319
+ $config['AUDIOTEMPLATES'] = $audioTemplates;
2320
+ if (!isset($config["SELECTED_VIDEO1TEMPLATE"]))
2321
+ $config['SELECTED_VIDEO1TEMPLATE'] = 'simple_link';
2322
  include('templates/video1_templates.php');
2323
+ $config['VIDEO1TEMPLATES'] = $video1Templates;
2324
+ if (!isset($config["VIDEO1TEMPLATE"]))
2325
+ $config["VIDEO1TEMPLATE"] = $simple_link;
2326
+ if (!isset($config["VIDEO1TYPES"]))
2327
+ $config['VIDEO1TYPES'] = array('mp4', 'mpeg4', '3gp', '3gpp', '3gpp2',
2328
+ '3gp2', 'mov', 'mpeg');
2329
+ if (!isset($config["AUDIOTYPES"]))
2330
+ $config['AUDIOTYPES'] = array('m4a', 'mp3', 'ogg', 'wav', 'mpeg');
2331
+ if (!isset($config["SELECTED_VIDEO2TEMPLATE"]))
2332
+ $config['SELECTED_VIDEO2TEMPLATE'] = 'simple_link';
2333
  include('templates/video2_templates.php');
2334
+ $config['VIDEO2TEMPLATES'] = $video2Templates;
2335
+ if (!isset($config["VIDEO2TEMPLATE"]))
2336
+ $config["VIDEO2TEMPLATE"] = $simple_link;
2337
+ if (!isset($config["VIDEO2TYPES"]))
2338
+ $config['VIDEO2TYPES'] = array('x-flv');
2339
+ if (!isset($config["POST_STATUS"]))
2340
+ $config["POST_STATUS"] = 'publish';
2341
+ if (!isset($config["IMAGE_NEW_WINDOW"]))
2342
+ $config["IMAGE_NEW_WINDOW"] = false;
2343
+ if (!isset($config["FILTERNEWLINES"]))
2344
+ $config["FILTERNEWLINES"] = true;
2345
  include('templates/image_templates.php');
2346
+ $config['IMAGETEMPLATES'] = $imageTemplates;
2347
  if (!isset($config["SELECTED_IMAGETEMPLATE"]))
2348
+ $config['SELECTED_IMAGETEMPLATE'] = 'wordpress_default';
2349
+ if (!isset($config["IMAGETEMPLATE"]))
2350
+ $config["IMAGETEMPLATE"] = $wordpress_default;
2351
+ if (!isset($config["SMTP"]))
2352
+ $config["SMTP"] = array();
2353
  return($config);
2354
  }
2355
+
2356
  /**
2357
+ * This function returns the old-format config (pre 1.4)
2358
+ * @return array
2359
+ */
2360
  function GetConfig() {
2361
+ $config = GetDBConfig();
2362
+ //These should only be modified if you are testing
2363
+ $config["DELETE_MAIL_AFTER_PROCESSING"] = true;
2364
+ $config["POST_TO_DB"] = true;
2365
+ $config["TEST_EMAIL"] = false;
2366
+ $config["TEST_EMAIL_ACCOUNT"] = "blogtest";
2367
+ $config["TEST_EMAIL_PASSWORD"] = "yourpassword";
2368
+ if (file_exists(POSTIE_ROOT . '/postie_test_variables.php')) {
2369
+ include(POSTIE_ROOT . '/postie_test_variables.php');
2370
+ }
2371
+ //include(POSTIE_ROOT . "/../postie-test.php");
2372
+ // These are computed
2373
+ $config["TIME_OFFSET"] = get_option('gmt_offset');
2374
+ $config["POSTIE_ROOT"] = POSTIE_ROOT;
2375
+ for ($i = 0; $i < count($config["AUTHORIZED_ADDRESSES"]); $i++) {
2376
+ $config["AUTHORIZED_ADDRESSES"][$i] = strtolower($config["AUTHORIZED_ADDRESSES"][$i]);
2377
+ }
2378
+ return $config;
2379
  }
2380
+
2381
  /**
2382
+ * end of functions used to retrieve the old (pre 1.4) config
2383
+ * =======================================================
2384
+ */
2385
+
2386
  /**
2387
+ * This function returns the current config
2388
+ * @return array
2389
+ */
2390
  function get_postie_config() {
2391
+ $config = get_option('postie-settings');
2392
+ if (file_exists(POSTIE_ROOT . '/postie_test_variables.php')) {
2393
+ include(POSTIE_ROOT . '/postie_test_variables.php');
2394
+ }
2395
+ // These are computed
2396
+ $config["time_offset"] = get_option('gmt_offset');
2397
+ $config["postie_root"] = POSTIE_ROOT;
2398
+ return $config;
2399
  }
2400
+
2401
  /**
2402
+ * Returns a list of config keys that should be arrays
2403
+ * @return array
2404
+ */
2405
  function get_arrayed_settings() {
2406
+ return array(
2407
+ ',' => array('audiotypes', 'video1types', 'video2types', 'default_post_tags'),
2408
+ "\n" => array('smtp', 'authorized_addresses', 'supported_file_types',
2409
+ 'banned_files_list', 'sig_pattern_list'));
2410
  }
2411
+
2412
  /**
2413
+ * Detects if they can do IMAP
2414
+ * @return boolean
2415
+ */
2416
  function HasIMAPSupport($display = true) {
2417
+ $function_list = array("imap_open",
2418
+ "imap_delete",
2419
+ "imap_expunge",
2420
+ "imap_body",
2421
+ "imap_fetchheader");
2422
+ return(HasFunctions($function_list, $display));
2423
  }
2424
+
2425
  function HasIconvInstalled($display = true) {
2426
+ $function_list = array("iconv");
2427
+ return(HasFunctions($function_list, $display));
2428
  }
2429
+
2430
  /**
2431
+ * Handles verifing that a list of functions exists
2432
+ * @return boolean
2433
+ * @param array
2434
+ */
2435
+ function HasFunctions($function_list, $display = true) {
2436
+ foreach ($function_list as $function) {
2437
+ if (!function_exists($function)) {
2438
+ if ($display) {
2439
+ print("<p>Missing $function");
2440
+ }
2441
+ return(false);
2442
+ }
2443
  }
2444
+ return(true);
 
2445
  }
2446
+
2447
  /**
2448
+ * This function tests to see if postie is its own directory
2449
+ */
2450
  function TestPostieDirectory() {
2451
+ $dir_parts = explode(DIRECTORY_SEPARATOR, dirname(__FILE__));
2452
+ $last_dir = array_pop($dir_parts);
2453
+ if ($last_dir != "postie") {
2454
+ return false;
2455
+ }
2456
+ return true;
2457
  }
2458
+
2459
  /**
2460
+ * This function looks for markdown which causes problems with postie
2461
+ */
2462
  function TestForMarkdown() {
2463
+ if (in_array("markdown.php", get_option("active_plugins"))) {
2464
  return(true);
2465
  }
2466
  return(false);
 
2467
  }
2468
+
2469
  /**
2470
+ * validates the config form output, fills in any gaps by using the defaults,
2471
+ * and ensures that arrayed items are stored as such
2472
+ */
2473
+ function postie_validate_settings($in) {
2474
+ if (defined('POSTIE_DEBUG'))
2475
+ var_dump($in);
2476
+ $out = array();
2477
+
2478
+ // use the default as a template:
2479
+ // if a field is present in the defaults, we want to store it; otherwise we discard it
2480
+ $allowed_keys = get_postie_config_defaults();
2481
+ foreach ($allowed_keys as $key => $default)
2482
+ $out[$key] = array_key_exists($key, $in) ? $in[$key] : $default;
2483
+
2484
+ // some fields are always forced to lower case:
2485
+ $lowercase = array('authorized_addresses', 'smtp', 'supported_file_types', 'video1types', 'video2types', 'audiotypes');
2486
+ foreach ($lowercase as $field) {
2487
+ $out[$field] = ( is_array($out[$field]) ) ? array_map(strtolower, $out[$field]) : strtolower($out[$field]);
2488
+ }
2489
+ $arrays = get_arrayed_settings();
2490
+
2491
+ foreach ($arrays as $sep => $fields) {
2492
+ foreach ($fields as $field) {
2493
+ if (!is_array($out[$field]))
2494
+ $out[$field] = explode($sep, trim($out[$field]));
2495
+ foreach ($out[$field] as $key => $val) {
2496
+ $tst = trim($val);
2497
+ if (empty($tst)) {
2498
+ unset($out[$field][$key]);
2499
+ } else {
2500
+ $out[$field][$key] = $tst;
2501
+ }
2502
+ }
2503
+ }
2504
+ }
2505
 
2506
+ UpdatePostieConfig($out);
2507
+ return $out;
2508
  }
2509
+
2510
  /**
2511
+ * registers the settings and the admin optionspage
2512
+ */
2513
  function postie_admin_settings() {
2514
+ register_setting('postie-settings', 'postie-settings', 'postie_validate_settings');
2515
  }
2516
+
2517
  /**
2518
+ * This function handles setting up the basic permissions
2519
+ */
2520
+ function UpdatePostiePermissions($role_access) {
2521
+ global $wp_roles;
2522
+ $admin = $wp_roles->get_role("administrator");
2523
+ $admin->add_cap("config_postie");
2524
+ $admin->add_cap("post_via_postie");
2525
+ if (!is_array($role_access)) {
2526
+ $role_access = array();
2527
+ }
2528
+ foreach ($wp_roles->role_names as $roleId => $name) {
2529
+ $role = &$wp_roles->get_role($roleId);
2530
+ if ($roleId != "administrator") {
2531
+ if ($role_access[$roleId]) {
2532
+ $role->add_cap("post_via_postie");
2533
+ } else {
2534
+ $role->remove_cap("post_via_postie");
2535
+ }
2536
+ }
2537
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2538
  }
2539
+
2540
+ function DebugEmailOutput(&$email, &$mimeDecodedEmail) {
2541
+ $file = fopen("test_emails/" . $mimeDecodedEmail->headers["message-id"] . ".txt", "w");
2542
+ fwrite($file, $email);
2543
+ fclose($file);
2544
+ $file = fopen("test_emails/" . $mimeDecodedEmail->headers["message-id"] . "-mime.txt", "w");
2545
+ fwrite($file, print_r($mimeDecodedEmail, true));
2546
+ fclose($file);
2547
+ }
2548
+
2549
+ /**
2550
+ * This function provides a hook to be able to write special parses for provider emails that are difficult to work with
2551
+ * If you want to extend this functionality - write a new function and call it from here
2552
+ */
2553
+ function SpecialMessageParsing(&$content, &$attachments, $config) {
2554
+ extract($config);
2555
+ if (preg_match('/You have been sent a message from Vodafone mobile/', $content)) {
2556
+ VodafoneHandler($content, $attachments); //Everything for this type of message is handled below
2557
+ return;
2558
+ }
2559
+ if ($message_start) {
2560
+ StartFilter($content, $message_start);
2561
+ }
2562
+ if ($message_end) {
2563
+ EndFilter($content, $message_end);
2564
+ }
2565
+ if ($drop_signature) {
2566
+ $content = remove_signature($content, $sig_pattern_list);
2567
+ }
2568
+ if ($prefer_text_type == "html"
2569
+ && count($attachments["cids"])) {
2570
+ ReplaceImageCIDs($content, $attachments);
2571
+ }
2572
+ if (!$custom_image_field) {
2573
+ ReplaceImagePlaceHolders($content, $attachments["html"], $config);
2574
+ } else {
2575
+ $customImages = array();
2576
+ foreach ($attachments["html"] as $value) {
2577
+ preg_match("/src=['\"]([^'\"]*)['\"]/", $value, $matches);
2578
+ array_push($customImages, $matches[1]);
2579
+ }
2580
+
2581
+ return($customImages);
2582
+ }
2583
+ return(NULL);
2584
+ }
2585
+
2586
  /**
2587
+ * Special Vodafone handler - their messages are mostly vendor trash - this strips them down.
2588
+ */
2589
+ function VodafoneHandler(&$content, &$attachments) {
2590
+ $index = strpos($content, "TEXT:");
2591
  if (strpos !== false) {
2592
+ $alt_content = substr($content, $index, strlen($content));
2593
+ if (preg_match("/<font face=\"verdana,helvetica,arial\" class=\"standard\" color=\"#999999\"><b>(.*)<\/b>/", $alt_content, $matches)) {
2594
  //The content is now just the text of the message
2595
  $content = $matches[1];
2596
  //Now to clean up the attachments
2597
+ $vodafone_images = array("live.gif", "smiley.gif", "border_left_txt.gif", "border_top.gif", "border_bot.gif", "border_right.gif", "banner1.gif", "i_text.gif", "i_picture.gif",);
2598
+ while (list($key, $value) = each($attachments['cids'])) {
2599
  if (!in_array($key, $vodafone_images)) {
2600
+ $content .= "<br/>" . $attachments['html'][$attachments['cids'][$key][1]];
2601
  }
2602
  }
2603
  }
2604
  }
 
2605
  }
2606
 
 
 
 
 
2607
  ?>
postie.php CHANGED
@@ -1,66 +1,82 @@
1
  <?php
 
2
  /*
3
- Plugin Name: Postie
4
- Plugin URI: http://blog.robfelty.com/plugins/postie
5
- Description: Signifigantly upgrades the posting by mail features of Word Press (See <a href='options-general.php?page=postie/postie.php'>Settings and options</a>) to configure your e-mail settings. See the <a href='http://wordpress.org/extend/plugins/postie/other_notes'>Readme</a> for usage. Visit the <a href='http://forum.robfelty.com/forum/postie'>postie forum</a> for support.
6
- Version: 1.4.4
7
- Author: Robert Felty
8
- Author URI: http://blog.robfelty.com/
9
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  /*
12
- $Id: postie.php 584135 2012-08-11 04:02:39Z robfelty $
13
- * -= Requests Pending =-
14
- * German Umlats don't work
15
- * Problems under PHP5
16
- * Problem with some mail server
17
- * Multiple emails should tie to a single account
18
- * Each user should be able to have a default category
19
- * WP Switcher not compatible
20
- * Setup poll
21
- - web server
22
- - mail clients
23
- - plain/html
24
- - phone/computer
25
- - os of server
26
- - os of client
27
- - number of users posting
28
- * Test for calling from the command line
29
- * Support userid/domain as a valid username
30
- * WP-switcher not compatiable http://www.alexking.org/index.php?content=software/wordpress/content.php#wp_120
31
- * Test out a remote cron system
32
- * Add support for http://unknowngenius.com/wp-plugins/faq.html#one-click
33
- * www.cdavies.org/code/3gp-thumb.php.txt
34
- * www.cdavies.org/permalink/watchingbrowserembeddedgpvideosinlinux.php
35
- * Support private posts
36
- * Make it possible to post without a script at all
37
- */
38
 
39
  //Older Version History is in the HISTORY file
40
  //error_reporting(E_ALL & ~E_NOTICE);
41
  //ini_set("display_errors", 1);
42
 
43
- define("POSTIE_ROOT",dirname(__FILE__));
44
  define("POSTIE_URL", WP_PLUGIN_URL . '/' . basename(dirname(__FILE__)));
45
 
46
-
47
  function postie_loadjs_add_page() {
48
- $postiepage = add_options_page('Postie', 'Postie', 8, POSTIE_ROOT.'/postie.php', 'postie_loadjs_options_page');
49
- add_action( "admin_print_scripts-$postiepage", 'postie_loadjs_admin_head' );
50
  }
51
 
52
  function postie_loadjs_options_page() {
53
- require_once POSTIE_ROOT.'/config_form.php';
54
  }
55
 
56
  function postie_loadjs_admin_head() {
57
- $plugindir = get_settings('siteurl').'/wp-content/plugins/'.dirname(plugin_basename(__FILE__));
58
- wp_enqueue_script('loadjs', $plugindir . '/js/simpleTabs.jquery.js');
59
- echo '<link type="text/css" rel="stylesheet" href="' .get_bloginfo('wpurl') .'/wp-content/plugins/postie/css/style.css" />'."\n";
60
- echo '<link type="text/css" rel="stylesheet" href="' .get_bloginfo('wpurl') .'/wp-content/plugins/postie/css/simpleTabs.css" />'."\n";
61
  }
62
 
63
-
64
  if (isset($_GET["postie_read_me"])) {
65
  include_once(ABSPATH . "wp-admin/admin.php");
66
  $title = __("Edit Plugins");
@@ -71,162 +87,172 @@ if (isset($_GET["postie_read_me"])) {
71
  }
72
  //Add Menu Configuration
73
  if (is_admin()) {
74
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR ."postie-functions.php");
75
- //add_action("admin_menu","PostieMenu");
76
- add_action( 'admin_init', 'postie_admin_settings' );
77
- add_action('admin_menu', 'postie_loadjs_add_page');
78
- if(function_exists('load_plugin_textdomain')){
79
- $plugin_dir = WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__));
80
- function postie_load_domain() {
81
- load_plugin_textdomain( 'postie', $plugin_dir."/languages/",
82
- basename(dirname(__FILE__)). '/languages/');
 
 
83
  }
84
- add_action('init', 'postie_load_domain');
85
- }
86
- postie_warnings();
87
  }
88
 
89
  function activate_postie() {
90
- static $init = false;
91
- $options = get_option( 'postie-settings' );
92
-
93
- if ( $init ) return;
94
-
95
- if(!$options) {
96
- $options = array();
97
- }
98
- $default_options = get_postie_config_defaults();
99
- $old_config = array();
100
- $updated = false;
101
- $migration = false;
102
-
103
- /*
104
- global $wpdb;
105
- $GLOBALS["table_prefix"]. "postie_config";
106
- $result = $wpdb->get_results("SELECT label,value FROM $postietable ;");
107
- */
108
- $result = GetConfig();
109
- if (is_array($result)) {
110
- foreach ( $result as $key => $val ) {
111
- $old_config[strtolower( $key )] = $val;
112
- }
113
- }
114
-
115
- // overlay the options on top of each other:
116
- // the current value of $options takes priority over the $old_config, which takes priority over the $default_options
117
- $options = array_merge( $default_options, $old_config, $options );
118
- $options = postie_validate_settings( $options );
119
- update_option( 'postie-settings', $options );
120
- $init = true;
121
- // $wpdb->query("DROP TABLE IF EXISTS $postietable"); // safely updated options, so we can remove the old table
122
- return $options;
 
123
  }
 
124
  register_activation_hook(__FILE__, 'activate_postie');
125
 
126
  /**
127
- * set up actions to show relevant warnings,
128
- * if mail server is not set, or if IMAP extension is not available
129
- */
130
- function postie_warnings() {
131
-
132
- $config = get_option( 'postie-settings' );
133
-
134
- if ( (empty( $config['mail_server'] ) ||
135
- empty( $config['mail_server_port'] ) ||
136
- empty( $config['mail_userid'] ) ||
137
- empty( $config['mail_password'] )
138
- ) && !isset($_POST['submit'] ) ) {
139
- function postie_enter_info() {
140
- echo "
141
- <div id='postie-info-warning' class='updated fade'><p><strong>".
142
- __('Postie is almost ready.', 'postie')."</strong> "
143
- .sprintf(__('You must <a href="%1$s">enter your email settings</a> for it to work.','postie'), "options-general.php?page=postie/postie.php")."</p></div> ";
 
 
 
 
144
  }
145
- add_action('admin_notices', 'postie_enter_info');
146
- }
147
-
148
- if (!function_exists('imap_mime_header_decode') && $_GET['activate']==true) {
149
- function postie_imap_warning() {
150
- echo "<div id='postie-imap-warning' class='error'><p><strong>";
151
- echo __('Warning: the IMAP php extension is not installed.', 'postie');
152
- echo __('Postie may not function correctly without this extension (especially for non-English messages).', 'postie');
153
- echo "</strong> ";
154
- //echo __('Warning: the IMAP php extension is not installed. Postie may not function correctly without this extension (especially for non-English messages) .', 'postie')."</strong> ".
155
- echo sprintf(__('Please see the <a href="%1$s">FAQ </a> for more information.'), "options-general.php?page=postie/postie.php", 'postie')."</p></div> ";
 
 
156
  }
157
- add_action('admin_notices', 'postie_imap_warning');
158
- }
159
-
160
  }
161
 
162
  function disable_kses_content() {
163
- remove_filter('content_save_pre', 'wp_filter_post_kses');
164
  }
165
- add_action('init','disable_kses_content',20);
 
166
 
167
  function postie_whitelist($options) {
168
- $added = array( 'postie-settings' => array( 'postie-settings' ) );
169
- $options = add_option_whitelist( $added, $options );
170
- return $options;
171
  }
 
172
  add_filter('whitelist_options', 'postie_whitelist');
173
 
174
  function check_postie() {
175
- $host = get_option('siteurl');
176
- preg_match("/https?:\/\/(.[^\/]*)(.*)/",$host,$matches);
177
- $host = $matches[1];
178
- $url = "";
179
- if (isset($matches[2])) {
180
- $url .= $matches[2];
181
- }
182
- $url .= "/wp-content/plugins/postie/get_mail.php";
183
- $port = 80;
184
- $fp=fsockopen($host,$port,$errno,$errstr);
185
- if ($fp) {
186
- fputs($fp,"GET $url HTTP/1.0\r\n");
187
- fputs($fp,"User-Agent: Cronless-Postie\r\n");
188
- fputs($fp,"Host: $host\r\n");
189
- fputs($fp,"\r\n");
190
- $page = '';
191
- while(!feof($fp)) {
192
- $page.=fgets($fp,128);
193
  }
194
- fclose($fp);
195
- } else {
196
- echo "Cannot connect to server on port $port. Please check to make sure
 
 
 
 
 
 
 
 
 
 
 
 
197
  that this port is open on your webhost.
198
  Additional information:
199
  $errno: $errstr";
200
- }
201
  }
202
 
203
- function postie_cron($interval=false) {
204
- if (!$interval) {
205
- $config=get_option('postie-settings');
206
- $interval = $config['interval'];
207
- }
208
- if (!$interval || $interval=='')
209
- $interval='hourly';
210
- if ($interval=='manual') {
211
- wp_clear_scheduled_hook('check_postie_hook');
212
- } else {
213
- wp_schedule_event(time(),$interval,'check_postie_hook');
214
- }
215
  }
 
216
  function postie_decron() {
217
- wp_clear_scheduled_hook('check_postie_hook');
218
  }
219
 
220
  /* here we add some more options for how often to check for e-mail */
 
221
  function more_reccurences() {
222
- return array(
223
- 'weekly' => array('interval' => 604800, 'display' => 'Once Weekly'),
224
- 'twiceperhour' => array('interval' => 1800, 'display' => 'Twice per hour '),
225
- 'tenminutes' =>array('interval' => 600, 'display' => 'Every 10 minutes')
226
- );
227
  }
 
228
  add_filter('cron_schedules', 'more_reccurences');
229
- register_activation_hook(__FILE__,'postie_cron');
230
- register_deactivation_hook(__FILE__,'postie_decron');
231
  add_action('check_postie_hook', 'check_postie');
232
  ?>
1
  <?php
2
+
3
  /*
4
+ Plugin Name: Postie
5
+ Plugin URI: http://PostiePlugin.com/
6
+ Description: Signifigantly upgrades the posting by mail features of Word Press (See <a href='options-general.php?page=postie/postie.php'>Settings and options</a>) to configure your e-mail settings. See the <a href='http://wordpress.org/extend/plugins/postie/other_notes'>Readme</a> for usage. Visit the <a href='http://wordpress.org/support/plugin/postie'>postie forum</a> for support.
7
+ Version: 1.4.5
8
+ Author: Wayne Allen
9
+ Author URI: http://allens-home.com/
10
+ License: GPL2
11
+ */
12
+
13
+ /* Copyright (c) 2012 Wayne Allen (email : wayne@allens-home.com)
14
+
15
+ This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License, version 2, as
17
+ published by the Free Software Foundation.
18
+
19
+ This program is distributed in the hope that it will be useful,
20
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
+ GNU General Public License for more details.
23
+
24
+ You should have received a copy of the GNU General Public License
25
+ along with this program; if not, write to the Free Software
26
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
+ */
28
 
29
  /*
30
+ $Id: postie.php 625416 2012-11-14 22:18:55Z WayneAllen $
31
+ * -= Requests Pending =-
32
+ * German Umlats don't work
33
+ * Problems under PHP5
34
+ * Problem with some mail server
35
+ * Multiple emails should tie to a single account
36
+ * Each user should be able to have a default category
37
+ * WP Switcher not compatible
38
+ * Setup poll
39
+ - web server
40
+ - mail clients
41
+ - plain/html
42
+ - phone/computer
43
+ - os of server
44
+ - os of client
45
+ - number of users posting
46
+ * Test for calling from the command line
47
+ * Support userid/domain as a valid username
48
+ * WP-switcher not compatiable http://www.alexking.org/index.php?content=software/wordpress/content.php#wp_120
49
+ * Test out a remote cron system
50
+ * Add support for http://unknowngenius.com/wp-plugins/faq.html#one-click
51
+ * www.cdavies.org/code/3gp-thumb.php.txt
52
+ * www.cdavies.org/permalink/watchingbrowserembeddedgpvideosinlinux.php
53
+ * Support private posts
54
+ * Make it possible to post without a script at all
55
+ */
56
 
57
  //Older Version History is in the HISTORY file
58
  //error_reporting(E_ALL & ~E_NOTICE);
59
  //ini_set("display_errors", 1);
60
 
61
+ define("POSTIE_ROOT", dirname(__FILE__));
62
  define("POSTIE_URL", WP_PLUGIN_URL . '/' . basename(dirname(__FILE__)));
63
 
 
64
  function postie_loadjs_add_page() {
65
+ $postiepage = add_options_page('Postie', 'Postie', 8, POSTIE_ROOT . '/postie.php', 'postie_loadjs_options_page');
66
+ add_action("admin_print_scripts-$postiepage", 'postie_loadjs_admin_head');
67
  }
68
 
69
  function postie_loadjs_options_page() {
70
+ require_once POSTIE_ROOT . '/config_form.php';
71
  }
72
 
73
  function postie_loadjs_admin_head() {
74
+ $plugindir = get_settings('siteurl') . '/wp-content/plugins/' . dirname(plugin_basename(__FILE__));
75
+ wp_enqueue_script('loadjs', $plugindir . '/js/simpleTabs.jquery.js');
76
+ echo '<link type="text/css" rel="stylesheet" href="' . get_bloginfo('wpurl') . '/wp-content/plugins/postie/css/style.css" />' . "\n";
77
+ echo '<link type="text/css" rel="stylesheet" href="' . get_bloginfo('wpurl') . '/wp-content/plugins/postie/css/simpleTabs.css" />' . "\n";
78
  }
79
 
 
80
  if (isset($_GET["postie_read_me"])) {
81
  include_once(ABSPATH . "wp-admin/admin.php");
82
  $title = __("Edit Plugins");
87
  }
88
  //Add Menu Configuration
89
  if (is_admin()) {
90
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . "postie-functions.php");
91
+ //add_action("admin_menu","PostieMenu");
92
+ add_action('admin_init', 'postie_admin_settings');
93
+ add_action('admin_menu', 'postie_loadjs_add_page');
94
+ if (function_exists('load_plugin_textdomain')) {
95
+ function postie_load_domain() {
96
+ $plugin_dir = WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__));
97
+ load_plugin_textdomain('postie', $plugin_dir . "/languages/", basename(dirname(__FILE__)) . '/languages/');
98
+ }
99
+
100
+ add_action('init', 'postie_load_domain');
101
  }
102
+ postie_warnings();
 
 
103
  }
104
 
105
  function activate_postie() {
106
+ static $init = false;
107
+ $options = get_option('postie-settings');
108
+
109
+ if ($init)
110
+ return;
111
+
112
+ if (!$options) {
113
+ $options = array();
114
+ }
115
+ $default_options = get_postie_config_defaults();
116
+ $old_config = array();
117
+ $updated = false;
118
+ $migration = false;
119
+
120
+ /*
121
+ global $wpdb;
122
+ $GLOBALS["table_prefix"]. "postie_config";
123
+ $result = $wpdb->get_results("SELECT label,value FROM $postietable ;");
124
+ */
125
+ $result = GetConfig();
126
+ if (is_array($result)) {
127
+ foreach ($result as $key => $val) {
128
+ $old_config[strtolower($key)] = $val;
129
+ }
130
+ }
131
+
132
+ // overlay the options on top of each other:
133
+ // the current value of $options takes priority over the $old_config, which takes priority over the $default_options
134
+ $options = array_merge($default_options, $old_config, $options);
135
+ $options = postie_validate_settings($options);
136
+ update_option('postie-settings', $options);
137
+ $init = true;
138
+ // $wpdb->query("DROP TABLE IF EXISTS $postietable"); // safely updated options, so we can remove the old table
139
+ return $options;
140
  }
141
+
142
  register_activation_hook(__FILE__, 'activate_postie');
143
 
144
  /**
145
+ * set up actions to show relevant warnings,
146
+ * if mail server is not set, or if IMAP extension is not available
147
+ */
148
+ function postie_warnings() {
149
+
150
+ $config = get_option('postie-settings');
151
+
152
+ if ((empty($config['mail_server']) ||
153
+ empty($config['mail_server_port']) ||
154
+ empty($config['mail_userid']) ||
155
+ empty($config['mail_password'])
156
+ ) && !isset($_POST['submit'])) {
157
+
158
+ function postie_enter_info() {
159
+ echo "
160
+ <div id='postie-info-warning' class='updated fade'><p><strong>" .
161
+ __('Postie is almost ready.', 'postie') . "</strong> "
162
+ . sprintf(__('You must <a href="%1$s">enter your email settings</a> for it to work.', 'postie'), "options-general.php?page=postie/postie.php") . "</p></div> ";
163
+ }
164
+
165
+ add_action('admin_notices', 'postie_enter_info');
166
  }
167
+
168
+ if (!function_exists('imap_mime_header_decode') && $_GET['activate'] == true) {
169
+
170
+ function postie_imap_warning() {
171
+ echo "<div id='postie-imap-warning' class='error'><p><strong>";
172
+ echo __('Warning: the IMAP php extension is not installed.', 'postie');
173
+ echo __('Postie may not function correctly without this extension (especially for non-English messages).', 'postie');
174
+ echo "</strong> ";
175
+ //echo __('Warning: the IMAP php extension is not installed. Postie may not function correctly without this extension (especially for non-English messages) .', 'postie')."</strong> ".
176
+ echo sprintf(__('Please see the <a href="%1$s">FAQ </a> for more information.'), "options-general.php?page=postie/postie.php", 'postie') . "</p></div> ";
177
+ }
178
+
179
+ add_action('admin_notices', 'postie_imap_warning');
180
  }
 
 
 
181
  }
182
 
183
  function disable_kses_content() {
184
+ remove_filter('content_save_pre', 'wp_filter_post_kses');
185
  }
186
+
187
+ add_action('init', 'disable_kses_content', 20);
188
 
189
  function postie_whitelist($options) {
190
+ $added = array('postie-settings' => array('postie-settings'));
191
+ $options = add_option_whitelist($added, $options);
192
+ return $options;
193
  }
194
+
195
  add_filter('whitelist_options', 'postie_whitelist');
196
 
197
  function check_postie() {
198
+ $host = get_option('siteurl');
199
+ preg_match("/https?:\/\/(.[^\/]*)(.*)/", $host, $matches);
200
+ $host = $matches[1];
201
+ $url = "";
202
+ if (isset($matches[2])) {
203
+ $url .= $matches[2];
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
+ $url .= "/wp-content/plugins/postie/get_mail.php";
206
+ $port = 80;
207
+ $fp = fsockopen($host, $port, $errno, $errstr);
208
+ if ($fp) {
209
+ fputs($fp, "GET $url HTTP/1.0\r\n");
210
+ fputs($fp, "User-Agent: Cronless-Postie\r\n");
211
+ fputs($fp, "Host: $host\r\n");
212
+ fputs($fp, "\r\n");
213
+ $page = '';
214
+ while (!feof($fp)) {
215
+ $page.=fgets($fp, 128);
216
+ }
217
+ fclose($fp);
218
+ } else {
219
+ echo "Cannot connect to server on port $port. Please check to make sure
220
  that this port is open on your webhost.
221
  Additional information:
222
  $errno: $errstr";
223
+ }
224
  }
225
 
226
+ function postie_cron($interval = false) {
227
+ if (!$interval) {
228
+ $config = get_option('postie-settings');
229
+ $interval = $config['interval'];
230
+ }
231
+ if (!$interval || $interval == '')
232
+ $interval = 'hourly';
233
+ if ($interval == 'manual') {
234
+ wp_clear_scheduled_hook('check_postie_hook');
235
+ } else {
236
+ wp_schedule_event(time(), $interval, 'check_postie_hook');
237
+ }
238
  }
239
+
240
  function postie_decron() {
241
+ wp_clear_scheduled_hook('check_postie_hook');
242
  }
243
 
244
  /* here we add some more options for how often to check for e-mail */
245
+
246
  function more_reccurences() {
247
+ return array(
248
+ 'weekly' => array('interval' => 604800, 'display' => 'Once Weekly'),
249
+ 'twiceperhour' => array('interval' => 1800, 'display' => 'Twice per hour '),
250
+ 'tenminutes' => array('interval' => 600, 'display' => 'Every 10 minutes')
251
+ );
252
  }
253
+
254
  add_filter('cron_schedules', 'more_reccurences');
255
+ register_activation_hook(__FILE__, 'postie_cron');
256
+ register_deactivation_hook(__FILE__, 'postie_decron');
257
  add_action('check_postie_hook', 'check_postie');
258
  ?>
postie_test.php CHANGED
@@ -1,125 +1,112 @@
1
  <?php
2
  // try to connect to server with different protocols/ and userids
3
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR ."postie-functions.php");
4
- include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR. "wp-config.php");
5
  //require_once('admin.php');
6
  require_once("postie-functions.php");
 
7
  $config = get_postie_config();
8
  extract($config);
9
  $title = __("Postie Diagnosis");
10
  $parent_file = 'options-general.php?page=postie/postie.php';
11
  get_currentuserinfo();
12
- ?>
13
- <?php
14
- if (!current_user_can('manage_options')) {
15
  echo "<h2> Sorry only admin can run this file</h2>";
16
  exit();
17
- }
18
- ?>
19
 
20
- <?
21
- $images = array("Test.png",
22
- "Test.jpg",
23
- "Test.gif");
24
  ?>
25
  <div class="wrap">
26
  <h1>Postie Configuration Test</h1>
27
  <?php
28
- if (TestForMarkdown()) {
29
- print("<h1>Warning!</h1>
30
- <p>You currently have the Markdown plugin installed. It will cause problems if you send in HTML
31
- email. Please turn it off if you intend to send email using HTML</p>");
 
 
 
32
 
33
- }
 
 
 
 
34
  ?>
35
- <?php
36
-
37
- if (!TestPostieDirectory()) {
38
- print("<h1>Warning!</h1>
39
- <p>Postie expects to be in its own directory named postie.</p>");
40
- }
41
- else {
42
- print("<p>Postie is in ".dirname(__FILE__)."</p>");
43
- }
44
- ?>
45
 
46
  <br/>
47
- <h2>International support<h2>
48
- <p><i><?php _e('Only required for international character set support',
49
- 'postie') ?></i>
50
- <table>
51
- <tr>
52
- <th>iconv</th>
53
- <td> <?php if (HasIconvInstalled()) _e('yes', 'postie'); ?></td>
54
- </tr>
55
- <tr>
56
- <th>imap <small>(required for subjects)</small></th>
57
- <td> <?php if (function_exists('imap_mime_header_decode')) _e('yes', 'postie') ; ?></td>
58
- </tr>
59
  </table>
60
-
61
- </p>
62
  <br/>
63
- <h2>Clock Tests<h2>
 
64
  <p>This shows what time it would be if you posted right now</p>
65
  <?php
66
- $content ="";
67
- $data = DeterminePostDate($content);
68
-
69
  ?>
70
- <p><?php print("GMT:". $data[1]);?></p>
71
- <p><?php print("Current:". $data[0]);?></p>
 
72
  <h2>Mail Tests</h2>
73
  <p>These try to confirm that the email configuration is correct.</p>
74
 
75
  <table>
76
- <tr>
77
- <th>Test</th>
78
- <th>Result</th>
79
- </tr>
80
- <tr>
81
- <th>Connect to Mail Host</th>
82
- <td>
83
- <?php
84
- if (!$mail_server || !$mail_server_port || !$mail_userid) {
85
- print("NO - check server settings");
86
- }
87
- switch( strtolower($config["input_protocol"]) ) {
88
  case 'imap':
89
  case 'imap-ssl':
90
  case 'pop3-ssl':
91
  if (!HasIMAPSupport()) {
92
  print("Sorry - you do not have IMAP php module installed - it is required for this mail setting.");
93
- }
94
- else {
95
  require_once("postieIMAP.php");
96
  $mail_server = &PostieIMAP::Factory($config["input_protocol"]);
97
- if (!$mail_server->connect($config["mail_server"], $config["mail_server_port"],$config["mail_userid"],$config["mail_password"])) {
98
- print("Unable to connect. The server said - ".$mail_server->error());
99
  print("<br/>Try putting in your full email address as a userid and try again.");
100
- }
101
- else {
102
  print("Yes");
103
  }
104
  }
105
  break;
106
  case 'pop3':
107
- default:
108
- require_once(ABSPATH.WPINC.DIRECTORY_SEPARATOR.'class-pop3.php');
109
  $pop3 = &new POP3();
110
  if (!$pop3->connect($config["mail_server"], $config["mail_server_port"])) {
111
- print("Unable to connect. The server said - ".$pop3->ERROR);
112
- print("<br/>Try putting in your full email address as a userid and try again.");
113
- }
114
- else {
115
  print("Yes");
116
  }
117
  break;
118
-
119
  }
120
- ?>
121
  </td>
122
- </tr>
123
 
124
 
125
  </table>
1
  <?php
2
  // try to connect to server with different protocols/ and userids
3
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . "postie-functions.php");
4
+ include_once (dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . "wp-config.php");
5
  //require_once('admin.php');
6
  require_once("postie-functions.php");
7
+
8
  $config = get_postie_config();
9
  extract($config);
10
  $title = __("Postie Diagnosis");
11
  $parent_file = 'options-general.php?page=postie/postie.php';
12
  get_currentuserinfo();
13
+
14
+ if (!current_user_can('manage_options')) {
 
15
  echo "<h2> Sorry only admin can run this file</h2>";
16
  exit();
17
+ }
 
18
 
19
+ $images = array("Test.png", "Test.jpg", "Test.gif");
 
 
 
20
  ?>
21
  <div class="wrap">
22
  <h1>Postie Configuration Test</h1>
23
  <?php
24
+ if (TestForMarkdown()) {
25
+ ?>
26
+ <h1>Warning!</h1>
27
+ <p>You currently have the Markdown plugin installed. It will cause problems if you send in HTML
28
+ email. Please turn it off if you intend to send email using HTML</p>");
29
+ <?php
30
+ }
31
 
32
+ if (!TestPostieDirectory()) {
33
+ print("<h1>Warning!</h1><p>Postie expects to be in its own directory named postie.</p>");
34
+ } else {
35
+ print("<p>Postie is in " . dirname(__FILE__) . "</p>");
36
+ }
37
  ?>
 
 
 
 
 
 
 
 
 
 
38
 
39
  <br/>
40
+ <h2>International support</h2>
41
+ <p><i><?php _e('Only required for international character set support', 'postie') ?></i></p>
42
+ <table>
43
+ <tr>
44
+ <th>iconv</th>
45
+ <td> <?php if (HasIconvInstalled()) _e('yes', 'postie'); ?></td>
46
+ </tr>
47
+ <tr>
48
+ <th>imap <small>(required for subjects)</small></th>
49
+ <td> <?php if (function_exists('imap_mime_header_decode')) _e('yes', 'postie'); ?></td>
50
+ </tr>
 
51
  </table>
 
 
52
  <br/>
53
+
54
+ <h2>Clock Tests</h2>
55
  <p>This shows what time it would be if you posted right now</p>
56
  <?php
57
+ $content = "";
58
+ $data = DeterminePostDate($content);
 
59
  ?>
60
+ <p><?php print("GMT:" . $data[1]); ?></p>
61
+ <p><?php print("Current:" . $data[0]); ?></p>
62
+
63
  <h2>Mail Tests</h2>
64
  <p>These try to confirm that the email configuration is correct.</p>
65
 
66
  <table>
67
+ <tr>
68
+ <th>Test</th>
69
+ <th>Result</th>
70
+ </tr>
71
+ <tr>
72
+ <th>Connect to Mail Host</th>
73
+ <td>
74
+ <?php
75
+ if (!$mail_server || !$mail_server_port || !$mail_userid) {
76
+ print("NO - check server settings");
77
+ }
78
+ switch (strtolower($config["input_protocol"])) {
79
  case 'imap':
80
  case 'imap-ssl':
81
  case 'pop3-ssl':
82
  if (!HasIMAPSupport()) {
83
  print("Sorry - you do not have IMAP php module installed - it is required for this mail setting.");
84
+ } else {
 
85
  require_once("postieIMAP.php");
86
  $mail_server = &PostieIMAP::Factory($config["input_protocol"]);
87
+ if (!$mail_server->connect($config["mail_server"], $config["mail_server_port"], $config["mail_userid"], $config["mail_password"])) {
88
+ print("Unable to connect. The server said - " . $mail_server->error());
89
  print("<br/>Try putting in your full email address as a userid and try again.");
90
+ } else {
 
91
  print("Yes");
92
  }
93
  }
94
  break;
95
  case 'pop3':
96
+ default:
97
+ require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'class-pop3.php');
98
  $pop3 = &new POP3();
99
  if (!$pop3->connect($config["mail_server"], $config["mail_server_port"])) {
100
+ print("Unable to connect. The server said - " . $pop3->ERROR);
101
+ print("<br/>Try putting in your full email address as a userid and try again.");
102
+ } else {
 
103
  print("Yes");
104
  }
105
  break;
 
106
  }
107
+ ?>
108
  </td>
109
+ </tr>
110
 
111
 
112
  </table>
readme.html CHANGED
@@ -1,56 +1,2120 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
- <html>
4
- <head>
5
- <title>Validator Error!</title>
6
- </head>
7
- <style type="text/css">
8
- <!--
9
- body {
10
- font-family: Lucida Grande, Verdana, sans-serif;
11
- }
12
-
13
- code {
14
- font-size: 1.3em
15
- }
16
-
17
- div.success {
18
- background: #0f0;
19
- width: 50%;
20
- margin: 0 auto;
21
- padding: 1px 10px;
22
- border: 3px solid #0d0;
23
- }
24
-
25
- div.error {
26
- padding: 1px 10px;
27
- margin: 30px auto;
28
- }
29
-
30
- div.error p {
31
- font-weight: bold;
32
- }
33
-
34
- div.error ul {
35
- list-style: square;
36
- }
37
-
38
- div.fatal {
39
- background: #faa;
40
- border: 3px solid #d00;
41
- }
42
-
43
- div.warning {
44
- background: #f60;
45
- border: 3px solid #e40;
46
- }
47
-
48
- div.note {
49
- background: #5cf;
50
- border: 3px solid #3ad;
51
- }
52
-
53
- -->
54
- </style>
55
- <body>
56
- Invalid readme.txt URL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <p><em>The Postie plugin allows you to blog via e-mail, including many advanced
2
+ features not found in WordPress&#039;s default post by e-mail feature.</em></p>
3
+
4
+ <hr />
5
+
6
+ <p>
7
+ <strong>Contributors:</strong> WayneAllen<br />
8
+ <strong>Donate link:</strong> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&#038;hosted_button_id=HPK99BJ88V4C2">donate</a><br />
9
+ <strong>Tags:</strong> e-mail, email<br />
10
+ <strong>Requires at least:</strong> 2.8<br />
11
+ <strong>Tested up to:</strong> 3.4.2<br />
12
+ <strong>Stable tag:</strong> 1.4.5<br/>
13
+ <strong>License:</strong> GPLv2 or later (http://www.gnu.org/licenses/gpl-2.0.html) </p>
14
+
15
+ <hr />
16
+
17
+ <h3>Description</h3>
18
+ <p>Postie offers many advanced features for posting to your blog via e-mail,
19
+ including the ability to assign categories by name, included pictures and
20
+ videos, and automatically strip off signatures. It also has support for both
21
+ imap and pop3, with the option for ssl with both. For usage notes, see the
22
+ <a href="other_notes">other notes</a> page</p>
23
+
24
+ <h4>What's new?</h4>
25
+
26
+ <ul>
27
+ <li><p>1.4.5 (2012.11.14)</p>
28
+
29
+ <ul>
30
+ <li>Fixed bug in XSS attack vulnerability code. Thanks to R Reid <a href="http://blog.strictly-software.com/2012/03/fixing-postie-plugin-for-wordpress-to.html" rel="nofollow">http://blog.strictly-software.com/2012/03/fixing-postie-plugin-for-wordpress-to.html</a></li>
31
+ <li>Fixed bug where emails with multiple categories has the incorrect title</li>
32
+ <li>Fixed bugs where PHP setting were not being changed correctly - thanks to Peter Chester <a href="http://tri.be/author/peter/" rel="nofollow">http://tri.be/author/peter/</a></li>
33
+ <li>New maintainer</li>
34
+ </ul></li>
35
+ <li><p>1.4.4 (2012.08.10)</p>
36
+
37
+ <ul>
38
+ <li>Fixed possible XSS attack vulnerability </li>
39
+ </ul></li>
40
+ <li><p>1.4.3 (2011.12.12)</p>
41
+
42
+ <ul>
43
+ <li>Removed get_user_by function to make compatible with wp 3.3 - now requires
44
+ 2.8+</li>
45
+ </ul></li>
46
+ <li><p>1.4.2 (2011.01.29)</p>
47
+
48
+ <ul>
49
+ <li>Fixed mailto link bug (thanks to Jason McNeil) </li>
50
+ <li>Fixed bug with attachments with non-ascii characters in filename (thanks to
51
+ mtakada)</li>
52
+ <li>checking for socket errors when checking mail (thanks elysian)</li>
53
+ <li>fixed issue with multiple files not being inserted correctly</li>
54
+ <li>Added support for ISO 8859-15 (thanks paolog)</li>
55
+ <li>fixed sql injection problem (thanks Jose P. Espinal for pointing it out)</li>
56
+ </ul></li>
57
+ <li><p>1.4.1 (2010.06.18)</p>
58
+
59
+ <ul>
60
+ <li>Images appear in correct order when using images append = false</li>
61
+ <li>Images are sorted in order of filename before inserting into post</li>
62
+ <li>Fixed formatting problem with wordpress_default image template</li>
63
+ <li>Captions now correctly work with wordpress &gt;3.0 and &lt;3.0</li>
64
+ <li>Fixed auto_gallery feature</li>
65
+ <li>Default port is now 110</li>
66
+ <li>Added more configuration tests</li>
67
+ <li>Added background color to settings page to make input boxes more visible</li>
68
+ <li>Removed extra quote character in captions from #img# placeholders (thanks
69
+ SteelD for pointing out the error)</li>
70
+ <li>Added support for big5 and gb-1232 encodings (thanks Chow)</li>
71
+ <li>Fixed issue with configurations items stored as arrays, which caused
72
+ problems with validating authorized addresses</li>
73
+ <li>Fixed bug with replaceImageCIDs function</li>
74
+ <li>On hosts which allow it, we set max execution time to 300 seconds and
75
+ memory_limit to infinity to allow processing of large e-mails (especially
76
+ with large attachments)</li>
77
+ </ul></li>
78
+ </ul> <hr />
79
+ <h3>Installation</h3>
80
+ <ul>
81
+ <li>Either:
82
+
83
+ <ul>
84
+ <li>Put the postie.zip file in wp-content/plugins/ and unzip it</li>
85
+ </ul></li>
86
+ <li>Or:
87
+
88
+ <ul>
89
+ <li>Use the automatic installer (WP 2.7+)</li>
90
+ </ul></li>
91
+ <li>Login to WordPress as an administrator</li>
92
+ <li>Goto the Plugins tab in the WordPress Admin Site</li>
93
+ <li>Activate "Postie"</li>
94
+ <li>Goto to the "Settings" tab and click on the sub-tab "Postie" to configure it.</li>
95
+ <li>Make sure you enter the mailserver information correctly, including the type
96
+ of connection and the port number. Common port configurations:
97
+
98
+ <ul>
99
+ <li>pop3: 110 </li>
100
+ <li>pop3-ssl: 995</li>
101
+ <li>imap: 143</li>
102
+ <li>imap-ssl: 993</li>
103
+ </ul></li>
104
+ <li>(Postie ignores the settings under Settings-&gt;Writing-&gt;Writing-by-Email)</li>
105
+ </ul>
106
+
107
+ <h4>Automating checking e-mail</h4>
108
+
109
+ <p>By default, postie checks for new e-mail every 30 minutes. You can select from
110
+ a number of different checking intervals in the settings page, under the
111
+ mailserver tab.</p>
112
+
113
+ <p>If you would prefer to have more fine-grained control of how postie checks
114
+ for mail, you can also set up a crontab. This is for advanced users only.
115
+ If your site runs on a UNIX/linux server, and you have shell access, you can
116
+ enable mail checking using cron; if you don't know anything about cron, skip
117
+ to the cronless postie section.</p>
118
+
119
+ <p>Setup a cronjob to pull down the get&#095;mail.php
120
+ Examples:</p>
121
+
122
+ <p>*/5 * * * * /usr/bin/lynx --source <a href="http://blog.robfelty.com/wp-content/plugins/postie/get&#095;mail.php" rel="nofollow">http://blog.robfelty.com/wp-content/plugins/postie/get&#095;mail.php</a> &gt;/dev/null 2&gt;&amp;1</p>
123
+
124
+ <p>This fetches the mail every five minutes with lynx</p>
125
+
126
+ <p>*/10 * * * * /usr/bin/wget -O /dev/null <a href="http://blog.robfelty.com/wp-content/plugins/postie/get&#095;mail.php" rel="nofollow">http://blog.robfelty.com/wp-content/plugins/postie/get&#095;mail.php</a> &gt;/dev/null 2&gt;&amp;1</p>
127
+
128
+ <p>This fetches the mail every ten minutes with wget</p> <hr />
129
+ <h3>Frequently Asked Questions</h3>
130
+ <h4>Postie won't connect to my mailserver. Why Not?</h4>
131
+
132
+ <p>Make sure the port you are using is open. For example, bluehost seems to block
133
+ ports 993 and 995 (for pop3-ssl and imap-ssl) by default. I have heard that
134
+ you can request that they open them for you ( you might have to pay extra).</p>
135
+
136
+ <p>You can check for open ports with the following command on your server:
137
+ netstat -ln|grep -E ':::(993|995|143)'</p>
138
+
139
+ <p>If nothing shows up, then the ports are not open.</p>
140
+
141
+ <h4>How can I get postie to display inline images?</h4>
142
+
143
+ <p>Make sure that you send e-mail formatted as html (richtext), and set postie to
144
+ prefer html messages (in the message tab of the postie settings)</p>
145
+
146
+ <h4>Mail is not showing up right when I send html (rich formatted) e-mail!</h4>
147
+
148
+ <p>Make sure you set the preferred text type to html</p>
149
+
150
+ <h4>Do I need to any code to my theme for postie to work?</h4>
151
+
152
+ <p>No.</p>
153
+
154
+ <h4>I read somewhere to add an iframe to my footer. Should I do this?</h4>
155
+
156
+ <p>No. Do not add an iframe in your footer to get postie to check mail
157
+ periodically. To check e-mail periodically, either set-up a cron job, or use
158
+ cronless postie. See installation instructions</p>
159
+
160
+ <h4>My mail host requires SSL, but postie will not allow me to select pop3-ssl or imap-ssl</h4>
161
+
162
+ <p>You must have php-imap installed on your server for this to work. Ask your
163
+ hosting provider about this.</p>
164
+
165
+ <h4>Can I use postie to check a gmail account?</h4>
166
+
167
+ <p>Yes. You can use either pop3-ssl or imap-ssl with a gmail account. Before
168
+ attempting to use with postie, make sure that you enable pop or imap in your
169
+ gmail preferences.</p>
170
+
171
+ <ul>
172
+ <li>Pop3 settings:
173
+
174
+ <ul>
175
+ <li>protocol - pop3-ssl</li>
176
+ <li>server - pop.gmail.com</li>
177
+ <li>port - 995</li>
178
+ <li>userid - your username (e.g. if your e-mail address is <a href="mailto:foo@gmail.com">foo@gmail.com</a>,
179
+ this would be just foo)</li>
180
+ <li>password - your password </li>
181
+ </ul></li>
182
+ <li>IMAP settings:
183
+
184
+ <ul>
185
+ <li>protocol - imap-ssl</li>
186
+ <li>server - imap.gmail.com</li>
187
+ <li>port - 993</li>
188
+ <li>userid - your username (e.g. if your e-mail address is <a href="mailto:foo@gmail.com">foo@gmail.com</a>,
189
+ this would be just foo)</li>
190
+ <li>password - your password </li>
191
+ </ul></li>
192
+ </ul>
193
+
194
+ <h4>My posts show up as being posted by 'admin' instead of me. Why?</h4>
195
+
196
+ <p>If your admin account is linked to <a href="mailto:bar@gmail.com">bar@gmail.com</a>, and you send mail from
197
+ <a href="mailto:bar@gmail.com">bar@gmail.com</a>, it will show up as being posted by admin. If you have a
198
+ wordpress user named "John Doe", which is linked to <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a>, make
199
+ sure that you send e-mails from <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a>. It doesn't matter which
200
+ e-mail address postie is checking. That is, if you send mail from
201
+ <a href="mailto:johndoe@gmail.com">johndoe@gmail.com</a> to <a href="mailto:foo@gmail.com">foo@gmail.com</a>, it gets posted as "John Doe".</p>
202
+
203
+ <p>If you send an e-mail to your postie address from an e-mail address that is no
204
+ t linked to a wordpress user, it will get posted as admin.</p>
205
+
206
+ <h4>Images aren't showing up at all?</h4>
207
+
208
+ <p>There are a couple possible reasons for this. First, check to see if you can
209
+ add an image through wordpress's normal posting mechanism. If not, then there
210
+ is probably 1 or 2 problems:
211
+ 1. Your server does not have the php-gd library installed. Ask your hosting
212
+ provider about this.</p>
213
+
214
+ <ol>
215
+ <li>Your wp-content/uploads directory is not writable by the webserver. Make
216
+ sure that it is</li>
217
+ </ol>
218
+
219
+ <h4>Can I delete the wp-files directory needed by postie version &lt;1.3.0?</h4>
220
+
221
+ <p>If you have posts published already by older versions of postie, getting rid
222
+ of those directories will delete any files you might have had associated with
223
+ those old posts. If you don't have any such posts, then you can safely delete
224
+ them.</p>
225
+
226
+ <h4>How can I get rid of stupid stuff my e-mail provider adds to my messages?</h4>
227
+
228
+ <p>To strip off stuff that they add at the beginning of a message, start your
229
+ post with :start</p>
230
+
231
+ <p>To strip off stuff that they add at the end of a message, end your
232
+ post with :end</p>
233
+
234
+ <h4>How can I add custom attachment icons?</h4>
235
+
236
+ <p>Simply upload the icons you want to the postie/icons/custom directory. You
237
+ must name the icons according to the following scheme:
238
+ {filetype}-{size}.png</p>
239
+
240
+ <p>For example, for word documents, you could use:</p>
241
+
242
+ <pre><code>doc-32.png</code></pre>
243
+
244
+ <p>for a 32x32 pixel icon. (You can actually create any size icon you want, but
245
+ if you name it 32, then it will only be used if you select to use size 32
246
+ icons)</p>
247
+
248
+ <p>See the other directories in icons for more examples.</p>
249
+
250
+ <p>Currently the following filetypes are supported:</p>
251
+
252
+ <ul>
253
+ <li>doc - microsoft word (including docx)</li>
254
+ <li>ppt - microsoft powerpoint (including pptx)</li>
255
+ <li>xls - microsoft excel (including xlsx)</li>
256
+ <li>numbers - iWork numbres spreadsheet</li>
257
+ <li>pages - iWork pages document</li>
258
+ <li>key - iWork keynote presentation</li>
259
+ <li>pdf - portable document format</li>
260
+ <li>rtf - rich text format</li>
261
+ <li>txt - plain text document</li>
262
+ </ul>
263
+
264
+ <h4>Can I add special text to the body of the post when using postie?</h4>
265
+
266
+ <p>Yes. You can create your own function, and use the postie_post filter.
267
+ Two short examples are included in the filterPostie.php.sample file</p>
268
+
269
+ <h4>Can I add special text to the title of the post when using postie?</h4>
270
+
271
+ <p>Yes. You can create your own function, and use the postie_post filter.
272
+ Two short examples are included in the filterPostie.php.sample file</p>
273
+
274
+ <h4>Can I select tags or categories based on the content of the e-mail?</h4>
275
+
276
+ <p>Yes. You can create your own function, and use the postie_post filter.
277
+ See the filterPostie.php.sample file for examples.</p>
278
+
279
+ <h4>Is the IMAP extension required for postie?</h4>
280
+
281
+ <p>The IMAP extension is not required, but it is strongly recommended, especially
282
+ is you are using non-English text. There is more information on php.net about
283
+ installing the IMAP extension. If you have control over your server, it is
284
+ often not hard to install.</p>
285
+
286
+ <p>On Ubuntu, try
287
+ sudo apt-get install php5-imap</p>
288
+
289
+ <p>On Fedora, try
290
+ sudo yuminstall php-imap</p>
291
+
292
+ <p>The IMAP extension is known to be installed on the following popular webhosts:
293
+ * Dreamhost</p>
294
+
295
+ <h4>How can I embed youtube or vimeo videos?</h4>
296
+
297
+ <p>Simply put the url in the body of your e-mail. (Make sure that you have the
298
+ option to convert url into links turned on)</p> <hr />
299
+ <h3>Screenshots</h3>
300
+ <ol>
301
+ <li>Postie options (showing video and audio templates)</li>
302
+ </ol> <hr />
303
+ <h3>Changelog</h3>
304
+ <h4>1.4.5</h4>
305
+
306
+ <ul>
307
+ <li>TODO - fix corruption of rtf attachments</li>
308
+ <li>TODO - add port checking in tests</li>
309
+ <li>TODO - non-image uploads get ignored in content when using autogallery - see
310
+ replaceimageplaceholders</li>
311
+ </ul>
312
+
313
+ <h4>1.4.4 (2012.08.10)</h4>
314
+
315
+ <ul>
316
+ <li>Fixed possible XSS attack vulnerability </li>
317
+ </ul>
318
+
319
+ <h4>1.4.3</h4>
320
+
321
+ <ul>
322
+ <li>Removed get_user_by function to make compatible with wp 3.3 - now requires
323
+ 2.8+</li>
324
+ </ul>
325
+
326
+ <h4>1.4.2 (2011.01.29)</h4>
327
+
328
+ <ul>
329
+ <li>Fixed mailto link bug (thanks to Jason McNeil) </li>
330
+ <li>Fixed bug with attachments with non-ascii characters in filename (thanks to
331
+ mtakada)</li>
332
+ <li>checking for socket errors when checking mail (thanks elysian)</li>
333
+ <li>fixed issue with multiple files not being inserted correctly</li>
334
+ <li>Added support for ISO 8859-15 (thanks paolog)</li>
335
+ <li>fixed sql injection problem (thanks Jose P. Espinal for pointing it out)</li>
336
+ <li>Fixed namespace clashing for get_config function</li>
337
+ </ul>
338
+
339
+ <h4>1.4.1 (2010.06.18)</h4>
340
+
341
+ <ul>
342
+ <li>Images appear in correct order when using images append = false</li>
343
+ <li>Fixed formatting problem with wordpress_default image template</li>
344
+ <li>Captions now correctly work with wordpress &gt;3.0 and &lt;3.0</li>
345
+ <li>Fixed auto_gallery feature</li>
346
+ <li>Default port is now 110</li>
347
+ <li>Added more configuration tests</li>
348
+ <li>Added background color to settings page to make input boxes more visible</li>
349
+ <li>Removed extra quote character in captions from #img# placeholders (thanks
350
+ SteelD for pointing out the error)</li>
351
+ <li>Added support for big5 and gb-1232 encodings (thanks Chow)</li>
352
+ <li>Fixed issue with configurations items stored as arrays, which caused
353
+ problems with validating authorized addresses</li>
354
+ <li>Fixed bug with replaceImageCIDs function</li>
355
+ <li>On hosts which allow it, we set max execution time to 300 seconds and
356
+ memory_limit to infinity to allow processing of large e-mails (especially
357
+ with large attachments)</li>
358
+ <li>Images are sorted in order of filename before inserting into post
359
+ <h4>1.4 (2010.04.25)</h4> </li>
360
+ <li>Now using wordpress settings api (thanks for much help from Andrew S)</li>
361
+ <li>Cronless postie is now integrated with postie instead of a separate plugin</li>
362
+ <li>filterPostie.php moved to filterPostie.php.sample</li>
363
+ <li>Can use fetchmails.php to fetch mail from multiple mailboxes</li>
364
+ <li>Fixed problem with embedding youtube videos from html (richtext) e-mail</li>
365
+ <li>Added support for embedding vimeo vidoes</li>
366
+ <li>Fixed problem with selecting "none" as icon set for attachments (thanks
367
+ tonyvitali)</li>
368
+ <li>Fixed problems with cronless postie settings</li>
369
+ <li>Fixed bug with embedding youtube and vimeo videos whose ID contains a -
370
+ (thanks Jim Kehoe)</li>
371
+ <li>Post_author is now included with attachments</li>
372
+ <li>fixed confirmation_email settings so that now you can select between sender,
373
+ admin, both, or none (thanks to redsalmon for pointing out bug)</li>
374
+ <li>Added option to automatically insert galleries</li>
375
+ <li>Updated FAQ and readme</li>
376
+ </ul>
377
+
378
+ <h4>1.3.4 (2009.10.05)</h4>
379
+
380
+ <ul>
381
+ <li>Fixed problem with images not posting under cron</li>
382
+ <li>Fixed issue with disappearing password</li>
383
+ </ul>
384
+
385
+ <h4>1.3.3 (2009.09.11)</h4>
386
+
387
+ <ul>
388
+ <li>Fixed problem with double titles</li>
389
+ <li>Fixed error in wp-mu</li>
390
+ <li>Cronless postie now correctly updates when changing the setting in the
391
+ postie settings</li>
392
+ <li>Small fix in handling of names of attachments (thanks to Teejot)</li>
393
+ <li>Fixed delay option (thanks to redbrandonk)</li>
394
+ <li>Cronless option value is now correctly deleted when deactivating the
395
+ cronless postie plugin</li>
396
+ </ul>
397
+
398
+ <h4>1.3.2 (2009.08.27)</h4>
399
+
400
+ <ul>
401
+ <li>tags are now always an array, even if no default tags are set </li>
402
+ <li>Subject is showing up again if you do not have the IMAP extension
403
+ installed</li>
404
+ <li>More information on the IMAP extension and more user-friendly
405
+ installation</li>
406
+ <li>Fixed problems with smtp server settings in 1.3.1</li>
407
+ <li>Added russian translation (thanks to fatcow.com)</li>
408
+ </ul>
409
+
410
+ <h4>1.3.1 (2009.08.24)</h4>
411
+
412
+ <ul>
413
+ <li>Changed GetContent filter to postie_post</li>
414
+ <li>Added database upgrade hook on activation</li>
415
+ <li>Fixed bug where content would be empty if trying to remove signature,
416
+ and signature list was emtpy</li>
417
+ <li>Updated FAQ and readme</li>
418
+ </ul>
419
+
420
+ <h4>1.3.0 (2009.08.14)</h4>
421
+
422
+ <ul>
423
+ <li>Features
424
+
425
+ <ul>
426
+ <li>Added mpeg4 to default list of videotypes</li>
427
+ <li>Added support for KOI8-R character set (cyrillic)</li>
428
+ <li>Added support for iso-8859-2 character set (eastern european)</li>
429
+ <li>Added option to include custom icons for attachments</li>
430
+ <li>Added option to send confirmation message to sender</li>
431
+ <li>Enhanced e-mails for unauthorized users</li>
432
+ <li>Added option to send unauthorized e-mail back to sender</li>
433
+ <li>Added option to only allow e-mails from a specified list of smtp
434
+ servers</li>
435
+ <li>Added option to use shortcode for embedding videos (works with the
436
+ videos plugin <a href="http://www.daburna.de/download/videos-plugin.zip" rel="nofollow">http://www.daburna.de/download/videos-plugin.zip</a></li>
437
+ <li>Better handling of comment authors (thanks to Petter for suggestion)</li>
438
+ <li>Simplified message options (now includes an advanced options section)</li>
439
+ <li>Added filter ability for post content</li>
440
+ </ul></li>
441
+ <li>Bug fixes
442
+
443
+ <ul>
444
+ <li>No longer including wp-config.php</li>
445
+ <li>If tmpdir is not writable, try a different tmpdir</li>
446
+ <li>More subject encoding fixes</li>
447
+ <li>Updated image templates, which were causing problems for cron</li>
448
+ <li>Fixed in text captions</li>
449
+ <li>Fixed SQL problems when updating options</li>
450
+ <li>Fixed name clashes with other plugins</li>
451
+ <li>Fixed custom image field</li>
452
+ </ul></li>
453
+ </ul>
454
+
455
+ <h4>1.3.beta (2009.07.01)</h4>
456
+
457
+ <ul>
458
+ <li>Mores fixes for character issues in subject</li>
459
+ <li>Now handling Windows-1256 (arabic) character set</li>
460
+ <li>Fixed image uploading on windows servers</li>
461
+ <li>Fixed replying to message adds comment</li>
462
+ <li>Uploading pictures via MMS should now work</li>
463
+ <li>Fixed some issues with e-mails from outloook 12</li>
464
+ <li>Greatly reduced number of database queries</li>
465
+ <li>No longer requiring config_handler.php</li>
466
+ </ul>
467
+
468
+ <h4>1.3.alpha (2009.06.05)</h4>
469
+
470
+ <ul>
471
+ <li>Now using default wordpress image and upload handling, which means:
472
+
473
+ <ul>
474
+ <li>No more creating special directories for postie</li>
475
+ <li>No more confusion about imagemagick</li>
476
+ <li>Can now use the [gallery] feature of wordpress</li>
477
+ <li>Attachments are now connected to posts in the database</li>
478
+ <li>All image resizing uses wordpress's default settings (under media)</li>
479
+ </ul></li>
480
+ <li>Configuration, settings and documentation improvements
481
+
482
+ <ul>
483
+ <li>Completely redesigned settings page (mostly thanks to Rainman)</li>
484
+ <li>Reset configuration no longer deletes mailserver settings</li>
485
+ <li>Now including help files and faq directly in settings page</li>
486
+ </ul></li>
487
+ <li>More media features
488
+
489
+ <ul>
490
+ <li>Automatically turn links to youtube into an embedded player</li>
491
+ <li>Added option to embed audio files with custom templates</li>
492
+ <li>Video options are now template based</li>
493
+ <li>Image options are now solely template based, with several new default
494
+ templates</li>
495
+ </ul></li>
496
+ <li>Bug fixes
497
+
498
+ <ul>
499
+ <li>Uploading images from vodafone phones should now work</li>
500
+ <li>Correctly handling Windows-1252 encoding</li>
501
+ <li>Correctly handling non-ascii characters in subject line</li>
502
+ </ul></li>
503
+ </ul>
504
+
505
+ <h4>1.2.3 (2009.05.17)</h4>
506
+
507
+ <ul>
508
+ <li>Fixed headers already sent bug</li>
509
+ <li>Converted shortcode <code>&lt;?</code> to proper <code>&lt;?php</code> (thanks brack)</li>
510
+ <li>Deleting mails after processing again</li>
511
+ </ul>
512
+
513
+ <h4>1.2.2 (2009.05.15)</h4>
514
+
515
+ <ul>
516
+ <li>Show empty categories for default category in options</li>
517
+ <li>Image scaling fixed so that the smaller value of max image width and max
518
+ image height is used</li>
519
+ <li>Fixed some issues with parsing html e-mail</li>
520
+ <li>Got rid of stupid mime tag (thanks Jeroen)</li>
521
+ <li>No longer adding slashes before calling wp_insert_post</li>
522
+ <li>When using custom image field, each image has a unique key</li>
523
+ </ul>
524
+
525
+ <h4>1.2.1 (2009.05.07)</h4>
526
+
527
+ <ul>
528
+ <li>Got rid of stupid version checking</li>
529
+ <li>Improved cronless postie instructions and configuration</li>
530
+ <li>Internationalization is working now</li>
531
+ <li>Dutch localization (thanks to gvmelle> <a href="http://gvmelle.com" rel="nofollow">http://gvmelle.com</a></li>
532
+ <li>Fixed caption bug when using image magick</li>
533
+ <li>Added option to not filter new lines (when using markdown syntax)</li>
534
+ <li>Fixed autoplay option</li>
535
+ <li>Can now use wildcards in excluding filenames</li>
536
+ <li>Producing better quality thumbnails (thanks to robcarey)</li>
537
+ </ul>
538
+
539
+ <h4>1.2 (2009.04.22)</h4>
540
+
541
+ <ul>
542
+ <li>More video options:
543
+
544
+ <ul>
545
+ <li>Can embed 3gp, mp4, mov videos</li>
546
+ <li>Can specify video width, video height, player width, and player height
547
+ in the settings page</li>
548
+ <li>Can specify custom image template</li>
549
+ </ul></li>
550
+ <li>Image handling improvements:
551
+
552
+ <ul>
553
+ <li>Only downscale images, not up-scale (thanks Jarven)</li>
554
+ <li>More custom image template options</li>
555
+ <li>IPTC captions now also work when not resizing images</li>
556
+ <li>Added option to use custom field for images (for Datapusher)</li>
557
+ <li>Fixed some issues with image templates and line break handling</li>
558
+ <li>Custom image template now works even when not resizing images</li>
559
+ </ul></li>
560
+ <li>Documentation improvements:
561
+
562
+ <ul>
563
+ <li>Added links to settings, forum, and readme in plugin description</li>
564
+ <li>Updated readme (thanks to Venkatraman Dhamodaran)</li>
565
+ <li>Added better instructions on how to use cronless postie</li>
566
+ </ul></li>
567
+ <li>Text processing improvements:
568
+
569
+ <ul>
570
+ <li>Added option to automatically convert urls into links</li>
571
+ <li>Added feature to include a custom excerpt</li>
572
+ </ul></li>
573
+ <li>Miscellaneous improvements
574
+
575
+ <ul>
576
+ <li>Improved internationalization (thanks to Håvard Broberg
577
+ (nanablag@nanablag.com))</li>
578
+ </ul></li>
579
+ <li>Bug Fixes
580
+
581
+ <ul>
582
+ <li>Removed debugging info in get_mail.php (security issue) thanks to
583
+ <a href="http://svalgaard.net/jens/">Jens</a></li>
584
+ <li>No longer directly including pluggable.php (should
585
+ prevent conflicts with other plugins such as registerplus</li>
586
+ </ul></li>
587
+ </ul>
588
+
589
+ <h4>1.1.5 (2009.03.10)</h4>
590
+
591
+ <ul>
592
+ <li>Added option to have postie posts be pending review, published, or draft</li>
593
+ <li>Settings panel only shows up for administrators</li>
594
+ <li>Need not be user "admin" to modify settings or to post from non-registered
595
+ users</li>
596
+ <li>Can now set administrator name. Authorized e-mail addresses which don't
597
+ have a user get posted under this name</li>
598
+ <li>Will use IPTC captions if available</li>
599
+ <li>Added option to replace newline characters with <br /></li>
600
+ </ul>
601
+
602
+ <h4>1.1.4 (2009.03.06)</h4>
603
+
604
+ <ul>
605
+ <li>Added more image options (open in new window, custom image template)</li>
606
+ <li>can now add captions to images</li>
607
+ <li>Can now add tags (including default tag option)</li>
608
+ </ul>
609
+
610
+ <h4>1.1.3 (2009.02.20)</h4>
611
+
612
+ <ul>
613
+ <li>Fixed delayed posting</li>
614
+ <li>updated readme some</li>
615
+ </ul>
616
+
617
+ <h4>1.1.2 (2008.07.12)</h4>
618
+
619
+ <ul>
620
+ <li>now maintained by Robert Felty</li>
621
+ <li>allow negative delays</li>
622
+ <li>will glean author information from forwarded or redirected e*mails</li>
623
+ <li>replying to an e*mail adds a comment to a post</li>
624
+ <li>fixed category handling to work with taxonomy</li>
625
+ <li>fixed one syntax error</li>
626
+ <li>added option to wrap posts and comments in </li>
627
+ </ul>
628
+
629
+ <p>&lt;</p>
630
+
631
+ <p>pre%gt; tags</p>
632
+
633
+ <h4>1.1.1</h4>
634
+
635
+ <p>Below is all the of the version information. As far as I can tell there once was a guy named John Blade. He took some of the original wp-mail.php code
636
+ and started hacking away on it. He actually got pretty far. About the time I discovered WordPress and his little hack - called WP-Mail at the time - he
637
+ went on a vacation or something. There were some problems with the script, and it was missing some features I wanted. I hacked away at it and got it
638
+ into a place where it did what I wanted. I started posting about it since I figured other people might want the features.</p>
639
+
640
+ <p>John didn't release any more versions at least up til July 2005. So I started accepting submissions and feature requests from people to help make the
641
+ code better. In June/July 2005 I discovered a little plugin by Chris J Davis (<a href="http://www.chrisjdavis.org/cjd-notepad/" rel="nofollow">http://www.chrisjdavis.org/cjd-notepad/</a>) called notepad. I added a small
642
+ feature to it (basically a bookmarklet). In the process I started looking at his code and realized how much you could do with the plugin system
643
+ available in Word Press.</p>
644
+
645
+ <p>So I decided to make an offical fork. I put up an article on my blog asking for new names. I picked Postie. I then modified the code to be a proper
646
+ plugin. And the rest is history :)</p>
647
+
648
+ <ul>
649
+ <li>BUGFIX -problem with subject</li>
650
+ <li>BUGFIX -cronless postie typo</li>
651
+ </ul>
652
+
653
+ <h4>1.1</h4>
654
+
655
+ <ul>
656
+ <li>FEATURE: Updated and tested with WordPress 2.1</li>
657
+ <li>BUGFIX:Removed deprecated functions</li>
658
+ <li>FEATURE: Cronless Postie now uses the WordPress native Psuedo Cron.</li>
659
+ </ul>
660
+
661
+ <h4>1.0</h4>
662
+
663
+ <ul>
664
+ <li>BUGFIX: TestWPVersion broke with 2.1</li>
665
+ <li>FEATURE: end: now marks the end of a message (Dan Cunningham)</li>
666
+ <li>FEATURE: Better Readme (Michael Rasmussen)</li>
667
+ <li>FEATURE: Smart Sharpen Option -EXPERIMENTAL- (Jonas Rhodin)</li>
668
+ <li>BUGFIX: Issue with google imap fixed (Jim Hodgson)</li>
669
+ <li>BUGFIX: Fixed espacing issue in subjects (Paul Clip)</li>
670
+ <li>BUGFIX: Typo in Div fixed (phil)</li>
671
+ </ul>
672
+
673
+ <h4>0.9.9.3.2</h4>
674
+
675
+ <ul>
676
+ <li>BUGFIX: Typo</li>
677
+ </ul>
678
+
679
+ <h4>0.9.9.3.1</h4>
680
+
681
+ <ul>
682
+ <li>BUGFIX: Removed debugging code</li>
683
+ </ul>
684
+
685
+ <h4>0.9.9.3</h4>
686
+
687
+ <ul>
688
+ <li>BUGFIX: If your email address matches an existing user - then it will post as that user - even if you allow anyone to post.</li>
689
+ <li>BUGFIX: Replaced get_settings('home') with get_settings('siteurl')</li>
690
+ <li>BUGFIX: Better handling for Japanese charactersets - Thanks to <a href="http://www.souzouzone.jp/blog/archives/009531.html" rel="nofollow">http://www.souzouzone.jp/blog/archives/009531.html</a></li>
691
+ <li>BUGFIX: Better thumbnail window opening code - thanks to Gabi &amp; Duntello!</li>
692
+ <li>FEATURE: Added an option to set the MAX Height of an image - idea from Duntello</li>
693
+ <li>BUGFIX: Modified the FilterNewLines for better flowed text handling - You now HAVE TO PUT TWO NEW LINES to end a paragraph.</li>
694
+ <li>FEATURE: Added new CSS tags to support positioning images/attachments/3gp videos</li>
695
+ <li>BUGFIX: Tries to use the date in the message (Thanks Ravan) I tried this once before and it never worked - hopefully this time it will.</li>
696
+ <li>BUGFIX: Added a workaround to fix the problem with Subscribe2 - it will now notify on posts that are not set to show up in the future.</li>
697
+ </ul>
698
+
699
+ <h4>0.9.9.2</h4>
700
+
701
+ <ul>
702
+ <li>BUGFIX: Looks for the NOOP error and disgards it</li>
703
+ <li>FEATURE: Postie now detects the version of WordPress being used </li>
704
+ <li>FEATURE: Smarter Parsing of VodaPhone </li>
705
+ <li>FEATURE: Easy place to add new code to handle other brain-dead mail clients</li>
706
+ <li>BUGFIX: Handles insertion of single quotes properly</li>
707
+ <li>BUGFIX: Thumbnails should now link properly</li>
708
+ </ul>
709
+
710
+ <h4>0.9.9.1</h4>
711
+
712
+ <ul>
713
+ <li>BUGFIX: Needed a strtolower in places to catch all iso-8859 - thx to Gitte Wange for the catch</li>
714
+ <li>BUGFIX: Fixed issue with the category not being posted properly</li>
715
+ </ul>
716
+
717
+ <h4>0.9.9</h4>
718
+
719
+ <ul>
720
+ <li>UPDATE TO WP 2.0</li>
721
+ <li>BUGFIX: Config Page now works</li>
722
+ <li>FEATURES: Supports role based posting</li>
723
+ <li>BUGFIX: Posting updates the category counts.</li>
724
+ </ul>
725
+
726
+ <h4>0.9.8.6</h4>
727
+
728
+ <ul>
729
+ <li>BUGFIX: Fixed problems with config page &lt;%php became &lt;?php</li>
730
+ <li></li>
731
+ </ul>
732
+
733
+ <h4>0.9.8.5</h4>
734
+
735
+ <ul>
736
+ <li>BUGFIX: onClick changed to onclick</li>
737
+ <li>BUGFIX: strolower added to test for iso - thanks daniele</li>
738
+ <li>BUGFIX: Added a class to the 3gp video tags</li>
739
+ <li>FEATURE: Added the option to put the images before the article</li>
740
+ <li>BUGFIX: Added in selection for charsets - thanks Psykotik - this may cause problems for other encodings</li>
741
+ <li>FEATURE: Added option to turn of quoted printable decoding</li>
742
+ <li>FEATURE: :start tag - now postie looks for this tag before looking for you message - handy if your service provider prepends a message </li>
743
+ <li>FEATURE: Template for translation now included</li>
744
+ </ul>
745
+
746
+ <h4>0.9.8.4</h4>
747
+
748
+ <ul>
749
+ <li>BUGFIX: Fixed problem with config_form.php - select had "NULL" instead of ""</li>
750
+ <li>BUGFIX: 3g2 now supported</li>
751
+ <li>BUGFIX: More line break issues addressed</li>
752
+ <li>BUGFIX: QuickTime controls are now visible even if the movie is done playing</li>
753
+ <li>BUGFIX: Email addresses in the format <a href="mailto:&#x73;o&#109;&#x65;&#064;&#x64;&#111;&#x6d;&#097;&#x69;&#110;&#046;&#x63;&#111;&#x6d;">&#x73;o&#109;&#x65;&#064;&#x64;&#111;&#x6d;&#097;&#x69;&#110;&#046;&#x63;&#111;&#x6d;</a> (Full Name) supported</li>
754
+ <li>BUGFIX: Some images that were not being resized - are now</li>
755
+ <li>BUGFIX: HTML problems - if you posted plain text with HTML on it ignored all images</li>
756
+ <li>BUGFIX: The test system blew up on the thumbnails </li>
757
+ <li>BUGFIX: Selected HTML for preferred text is now shown in the config form properly</li>
758
+ <li>BUGFIX: Postie now complains if it is not in its own directory</li>
759
+ <li>BUGFIX: Postie doesn't include PEAR if it is already available</li>
760
+ <li>BUGFIX: In Test mode rejected emails are simply dropped</li>
761
+ <li>BUGFIX: Markdown messes up Postie - it will warn you if you turn it on.</li>
762
+ <li></li>
763
+ </ul>
764
+
765
+ <h4>0.9.8.3</h4>
766
+
767
+ <ul>
768
+ <li>BUGFIX: Fixed issue with the line feed replacement</li>
769
+ <li>BUGFIX: Added Banned File Config back in</li>
770
+ <li>FEATURE: Added in a link around 3gp video embedded via QT</li>
771
+ <li>BUGFIX: Email that has both Plain and HTML content will show the HTML content and not the plain if html is preferred</li>
772
+ </ul>
773
+
774
+ <h4>0.9.8.2</h4>
775
+
776
+ <ul>
777
+ <li>BUGFIX: Fixed an extra new line after attachin non-image files.</li>
778
+ <li>BUGFIX: The Test system now displays any missing gd functions</li>
779
+ <li>BUGFIX: The test system was only using ImageMagick</li>
780
+ </ul>
781
+
782
+ <h4>0.9.8.1</h4>
783
+
784
+ <ul>
785
+ <li>BUGFIX: The test images are now included in the zip </li>
786
+ </ul>
787
+
788
+ <h4>0.9.8</h4>
789
+
790
+ <ul>
791
+ <li>BUGFIX: New Lines detected and handled properly in cases where the mail client doesn't put a space before the new line (Miss Distance)</li>
792
+ <li>BUGFIX: 3gp mime type added (Paco Cotera)</li>
793
+ <li>BUGFIX: Authorized Email Addresses are not case-insensitive</li>
794
+ <li>FEATURE: The larger image now does a proper pop up </li>
795
+ <li>BUGFIX: Fixed Timeing Issue - turns out it wasn't reading the db at all</li>
796
+ <li>FEATURE: New Test Screen - to help track down problems</li>
797
+ </ul>
798
+
799
+ <h4>0.9.7</h4>
800
+
801
+ <ul>
802
+ <li>BUGFIX: removed all short tags</li>
803
+ <li>BUGFIX: There were spacing issues in the way I wrote the QT embed statements </li>
804
+ <li>FEATURE: Added calls to WP-Cron - should work with that properly now if you activate Cronless Postie</li>
805
+ <li>FEATURE: ImageMagick version works without any calls to GD</li>
806
+ <li>BUGFIX: Postie now correctly handles cases wjere tjere are multiple blogs in one db</li>
807
+ <li>BUGFIX: Turned off warnings when using without GD</li>
808
+ <li>FEATURE: add the rotate:X to your message to rotate all images</li>
809
+ <li>FEATURE: new filter_postie_thumbnail_with_full which makes it easy to show a thumbnail on the front page but full image on the single page - see FAQ</li>
810
+ </ul>
811
+
812
+ <h4>0.9.6</h4>
813
+
814
+ <ul>
815
+ <li>BUGFIX: handles email addresses that are no name and just <a href="mailto:&#101;&#109;&#x61;&#105;&#108;&#x40;&#101;&#109;&#x61;&#x69;&#108;&#x2e;&#x63;&#111;&#x6d;">&#101;&#109;&#x61;&#105;&#108;&#x40;&#101;&#109;&#x61;&#x69;&#108;&#x2e;&#x63;&#111;&#x6d;</a> (Steve Cooley Reported)</li>
816
+ <li>FEATURE: Basic support for embedding flash files</li>
817
+ <li>BUGFIX: Postie now handles creating the correct URL on non Unix platforms</li>
818
+ <li>BUGFIX: Fixed problem with file attachments not being put in the right place.</li>
819
+ <li>FEATURE: You can now choose to use imagemagick convert to handle making thumbnails</li>
820
+ <li>BUGFIX: Rewrote Cronless Postie to use direct sockets</li>
821
+ <li>BUGFIX: Time offset is now settable just for Postie - hopefully this will fix problems for cases where the normal time offset doesn't work properly.</li>
822
+ <li>FEATURE: First draft of frame for a 3GP video</li>
823
+ <li>FEATURE: Option to embed 3GP in QuickTime Controller.</li>
824
+ </ul>
825
+
826
+ <h4>0.9.5.2</h4>
827
+
828
+ <ul>
829
+ <li>BUGFIX: gmt varialble not being set correctly</li>
830
+ <li>BUGFIX: Changed the name of the Check Mail button to fix an issue with mod_security</li>
831
+ <li>BUGFIX: Fixed issue with Cronless-Postie</li>
832
+ <li>BUGFIX: There was an argument passed by reference incorrectly</li>
833
+ <li>FEATURE: Added in Cronless Postie Readme</li>
834
+ <li>FEATURE: Added in Postie Readme</li>
835
+ </ul>
836
+
837
+ <h4>0.9.5.1</h4>
838
+
839
+ <ul>
840
+ <li>BUGFIX: Confirmed POP3-SSL on debian-3.0</li>
841
+ <li>BUGFIX: Updated the plugin version</li>
842
+ <li>BUGFIX: Stopped displaying the email account</li>
843
+ <li></li>
844
+ </ul>
845
+
846
+ <h4>0.9.5</h4>
847
+
848
+ <ul>
849
+ <li>BUGFIX: Postie handles cases where you do not have GD</li>
850
+ <li>FEATURE: You can now set the access level for posting - so other people can use the gate way</li>
851
+ <li>BUGFIX: Fixed issue when admininstrator email is not tied to a user account.</li>
852
+ <li>FEATURE: Can now reset all Postie configurations back to defaults</li>
853
+ <li>BUGFIX: HTML Emails with embedded images are now handled properly.</li>
854
+ <li>BUGFIX: The time difference should work correctly now</li>
855
+ <li>BUGFIX: Postie's configs are completely seperate from Writing-By-Mail</li>
856
+ <li>FEATURE: Warning if you use Gmail to make sure you turn on POP support</li>
857
+ <li>BUGFIX: Manual Check Mail Button in interface</li>
858
+ <li>BUGFIX: fixed issue of compatability with cjd-notepad</li>
859
+ <li>BUGFIX: Windows Works Now</li>
860
+ </ul>
861
+
862
+ <h4>0.9.4</h4>
863
+
864
+ <ul>
865
+ <li>BUGFIX: Cronless Postie - fixed the include statement</li>
866
+ <li>BUGFIX: Authorized Addresses now supports a single address</li>
867
+ <li>FEATURE: All configuration in Postie done in a single screen</li>
868
+ <li>FEATURE: AUTHORIZATION can be completely overridden</li>
869
+ <li>BUGFIX: line 1159 - didn't handle cases where the table didn't exist already very well</li>
870
+ <li>FEATURE: Detects if you can do IMAP</li>
871
+ <li>FEATURE: Added IMAP Support</li>
872
+ <li>FEATURE: Added IMAP-SSL Support</li>
873
+ <li>FEATURE: Added POP3-SSL Support</li>
874
+ </ul>
875
+
876
+ <h4>0.9.3</h4>
877
+
878
+ <ul>
879
+ <li>Bug fixes for IIS</li>
880
+ </ul>
881
+
882
+ <h4>0.9.2</h4>
883
+
884
+ <ul>
885
+ <li>Moved to more of a DIRECTORY_SEPARATOR structure </li>
886
+ </ul>
887
+
888
+ <h4>0.9.1</h4>
889
+
890
+ <ul>
891
+ <li>Added a define to fix a problem with over including</li>
892
+ </ul>
893
+
894
+ <h4>0.9</h4>
895
+
896
+ <ul>
897
+ <li>Converted to an honest to god plugin</li>
898
+ <li>BUGFIX: If you put a single category:subject it now works</li>
899
+ <li>BUGFIX: ? Special characters may be supported? The test post now shows a lot of umlats and accents?</li>
900
+ <li>BUGFIX: The last ] in a subject with categories is now filtered out</li>
901
+ <li>FEATURE: -1- subject - will put the post in category 1</li>
902
+ </ul>
903
+
904
+ <h4>0.312.13</h4>
905
+
906
+ <ul>
907
+ <li>Code clean up - The main loop is finally readable by even non programmers</li>
908
+ <li>FEATURE - You can now post to multiple categories at one time by using the [#],[Category Name], [Cat] in the subject</li>
909
+ <li>FEATURE - You can now select a category by just including the begining characters [G] will select General </li>
910
+ <li>if you don't have any other categories that start with g</li>
911
+ <li>FEATURE - Jay Talbot - added a new feature so you can have multiple email addresses be allowed in</li>
912
+ <li>Make multi category posting more obvious</li>
913
+ <li>BUG FIX: Timezones of GMT+? should now work properly</li>
914
+ <li>BUG FIX: Able to handle mis-mime typed images as long as they are named with .jpg/.gif/.png</li>
915
+ </ul>
916
+
917
+ <h4>0.312.12</h4>
918
+
919
+ <ul>
920
+ <li>Code clean up - slowing shrinking the main to make it easiery to fix things</li>
921
+ <li>FEATURE: Be able to turn on/off allowing comments in an email</li>
922
+ <li>BUG FIX: AppleDouble now mostly supported </li>
923
+ <li>BUG FIX: MIME handling improved.</li>
924
+ <li>BUG FIX: Fix issue with timing delay</li>
925
+ </ul>
926
+
927
+ <h4>0.312.11</h4>
928
+
929
+ <ul>
930
+ <li>FEATURE: Patterns to define where a sig starts are user configurable</li>
931
+ <li>FEATURE: Add filter options for banned file names</li>
932
+ <li>BUG FIX: Made it possible to turn off posting to the db for testing purposes</li>
933
+ </ul>
934
+
935
+ <h4>0.312.10</h4>
936
+
937
+ <ul>
938
+ <li>FEATURE: Added in code to diplay the mime type of the file being linked to</li>
939
+ <li>BUG FIX: It now tests for the existance of the directories and makes sure</li>
940
+ <li>that the web server can write to them</li>
941
+ </ul>
942
+
943
+ <h4>0.312.9</h4>
944
+
945
+ <ul>
946
+ <li>FEATURE:Should handle jpg as well as jpeg as the file type</li>
947
+ <li>BUG FIX: Now correctly handles the subject in the message</li>
948
+ <li>BUG FIX: Should handle Text preferences correctly </li>
949
+ </ul>
950
+
951
+ <h4>0.312.8</h4>
952
+
953
+ <ul>
954
+ <li>Some general code tidying. </li>
955
+ <li>FEATURE: Can now have email from invalid email addresses automatically forwared</li>
956
+ <li>to the admin's email account. This forward includes all attachments. </li>
957
+ <li>Props to David Luden for getting this started.</li>
958
+ <li>Minor change: The system will continue if it runs into a message that doesn't have </li>
959
+ <li>any content - it will also continue to process if it gets an email from </li>
960
+ <li>someone not in the system. In the past this could result in deleted mail</li>
961
+ <li>if your cron job didn't run often enough.</li>
962
+ </ul>
963
+
964
+ <h4>0.312.7</h4>
965
+
966
+ <ul>
967
+ <li>Confirm the handling of 3gp video for cell phones o</li>
968
+ <li>Added in new directive SUPPORTED_FILE_TYPES -if the mime type is listed here then the system will try to make a link to it without making a thumb nail.</li>
969
+ </ul>
970
+
971
+ <h4>0.312.6</h4>
972
+
973
+ <ul>
974
+ <li>Bug Fix: Ok the last bug I fixed - actually caused another bug - man I should set up some unit tests. Now it handles mail from the nokia mail client correctly.</li>
975
+ </ul>
976
+
977
+ <h4>0.312.5</h4>
978
+
979
+ <ul>
980
+ <li>Bug Fix : The system was accepting all test/* types. Now you can set a preference (defaults to text/plain)</li>
981
+ <li>to use as the main text for the post.</li>
982
+ </ul>
983
+
984
+ <h4>0.312.4</h4>
985
+
986
+ <ul>
987
+ <li>Added in sanitize_title call suggested by Jemima</li>
988
+ <li>Added in ability to provide a subject in an mms - by using #Subject#</li>
989
+ <li>Fixed an issue with the time stamp system so it now automatically uses the gmt_offset from WordPress</li>
990
+ <li>Fixed issue with the delay:1d1h tag that prevented it from being removed from the body.</li>
991
+ <li>Fixed issue with the delay tag that caused problems if it was the last thing before an image.</li>
992
+ </ul>
993
+
994
+ <h4>0.312.3-HEY (2005-05)</h4>
995
+
996
+ <ul>
997
+ <li>&gt; Some changes and Bugfixes by Adrian Heydecker</li>
998
+ <li>&gt; Not (yet) in main development branch.</li>
999
+ <li>Fixed bug: JPEG-thumbnails had a bigger filesize than full images caused by bad hardcoded compression value.</li>
1000
+ <li>Fixed bug: If images and signatures were present but no placeholder tags, the images were deleted together with the signature.</li>
1001
+ <li>Fixed bug: Generates valid postnames for users of mod_rewrite. Permalinks to posts should now work even when whitespaces are present in the subject line.</li>
1002
+ <li>Added support for Quoted Printable encoded mail.</li>
1003
+ <li>Added ability to encode Wordpress-posts in charset ISO-8859-1 instead of UTF-8.</li>
1004
+ <li>Added ability to choose JPEG-compression value for thumbnails.</li>
1005
+ <li>Added ability to add class="" and style="" to images.</li>
1006
+ <li>Added ability to use a different mailadress (eg. mobile) without setting up a new Wordpress-account.</li>
1007
+ </ul>
1008
+
1009
+ <h4>0.312.2</h4>
1010
+
1011
+ <ul>
1012
+ <li>BUGFIX: It now removes the delay tag from the message</li>
1013
+ </ul>
1014
+
1015
+ <h4>0.312.1</h4>
1016
+
1017
+ <ul>
1018
+ <li>Added modification for placeholder support for images (David Luden)</li>
1019
+ <li>Added in support to automatically scale down big images (Dirk Elmendorf)</li>
1020
+ <li>Fixed bug with multiple emails all getting the contents of the first image tag (Dirk Elmendorf)</li>
1021
+ <li>Added option to allow HTML in the body and subject of the email (Dirk Elmendorf)</li>
1022
+ <li>Switch config options to defines to reduce the number of global variables (Dirk Elmendorf)</li>
1023
+ <li>Added tests to make sure there is a trailing slash on the DIR definitions (Dirk Elmendorf)</li>
1024
+ <li>Add tests to see if they have gd installed (Dirk Elmendorf)</li>
1025
+ <li>Seperate the scaling out to a function for easier usage (Dirk Elmendorf)</li>
1026
+ <li>Add delay feature for future posting. (Dirk Elmendorf)</li>
1027
+ <li><p>Added in ability to use strtotime if it is available (Dirk ELmendorf)</p></li>
1028
+ <li><p>Todo</p></li>
1029
+ <li>Have option to have the email that is rejected forwarded on to another address.</li>
1030
+ <li>Fix bug that id still diplays the delay tag in the body </li>
1031
+ </ul>
1032
+
1033
+ <h4>0.312 - 2005-03</h4>
1034
+
1035
+ <ul>
1036
+ <li>CHANGE FOR DEFAULT E-mail Categories, instead of [General] Subject you can now use General: Subject in the subject line. Less typing, and there must be a space after the colon. </li>
1037
+ <li>Fixed bugs with no default posting for categories and user </li>
1038
+ </ul>
1039
+
1040
+ <h4>0.311 - 2005-01</h4>
1041
+
1042
+ <ul>
1043
+ <li>eep, major bug for pop3 server. Next time I test my code more before I released, fixed so that pop3 now works.`</li>
1044
+ </ul>
1045
+
1046
+ <h4>0.31 - 2004-12 &amp; 2005-01</h4>
1047
+
1048
+ <ul>
1049
+ <li>(Has it been this long, best get back into the swing of things... did most of this coding on my holiday as I didn't have a machine to play WoW on :)</li>
1050
+ <li>moved the deletion of pop3 emails into a check so that e-mails aren't deleted without proper checking.</li>
1051
+ <li>added HTML 'decoding' (basic support for Thunderbird &amp; Outlook) </li>
1052
+ <li>updated the Category search so that it matches words as well as numbers (i.e. [General] Subjectname will work instead of just [1] Subjectname)</li>
1053
+ <li>Changed time function from time to strtotime (as per Senior Pez's suggestion), but found out that strtotime isn't in default php distro so removed...</li>
1054
+ </ul>
1055
+
1056
+ <h4>0.3 - 2004-09</h4>
1057
+
1058
+ <ul>
1059
+ <li>Added UBB decoding support</li>
1060
+ <li>Added default title (when there is no subject assigned)</li>
1061
+ <li>Started doing a little code cleanup, been reading Advanced PHP Book :)</li>
1062
+ <li></li>
1063
+ </ul>
1064
+
1065
+ <h4>0.2 - 2004-08</h4>
1066
+
1067
+ <ul>
1068
+ <li>Stopped using pear body decoding in favour of own decoding (may be slower but more modifiable) because of enriched text decoding</li>
1069
+ <li>Added base64_decode checking (may help mobile phone users)</li>
1070
+ <li>Fixed Subject line for non-english users (htmlentities instead of just trim)</li>
1071
+ <li>Fixed error in some pop hanging -&gt; more graceful exit on event on no emails in inbox ($pop3-&gt;quit)</li>
1072
+ <li>Added work around for email addresses with exta &lt;&gt; in field (ie: <a href="mailto:&#098;&#108;&#097;d&#x65;&#x40;&#x6c;&#x61;&#x6e;&#115;&#109;&#097;&#115;&#104;.&#x63;&#x6f;&#x6d;">&#098;&#108;&#097;d&#x65;&#x40;&#x6c;&#x61;&#x6e;&#115;&#109;&#097;&#115;&#104;.&#x63;&#x6f;&#x6d;</a> instead of <a href="mailto:blade@lasmash.com">blade@lasmash.com</a></li>
1073
+ <li>Added some ===basic=== enriched text support</li>
1074
+ <li>Updated readme file for easier install</li>
1075
+ <li>Easy modify of globals (such as PHOTOSDIR and FILESDIR)</li>
1076
+ <li>Cleaned up some pear stuff in install</li>
1077
+ <li></li>
1078
+ </ul>
1079
+
1080
+ <h4>0.1 - 2004-06</h4>
1081
+
1082
+ <ul>
1083
+ <li>First release</li>
1084
+ </ul> <hr />
1085
+
1086
+ <h3>Upgrade Notice</h3>
1087
+ <dl>
1088
+ <dt>1.4.4</dt>
1089
+ <dd>Fixed possible XSS attack vulnerability</dd>
1090
+ </dl>
1091
+
1092
+ <h3 id='Usage'>Usage</h3>
1093
+ <ul>
1094
+ <li>If you put in :start - the message processing won't start until it sees that string</li>
1095
+ <li>If you put in :end - the message processing will stop once it sees that string</li>
1096
+ <li>Posts can be delayed by adding a line with delayXdXhXm where X is a number.
1097
+
1098
+ <ul>
1099
+ <li>delay:1d - 1 day</li>
1100
+ <li>delay:1h - 1 hour</li>
1101
+ <li>delay:1m - 1 minute</li>
1102
+ <li>delay:1d2h4m - 1 day 2 hours 4m</li>
1103
+ </ul></li>
1104
+ <li>By putting comments:X in your message you can control if comments are allowed
1105
+
1106
+ <ul>
1107
+ <li>comments:0 - means closed</li>
1108
+ <li>comments:1 - means open</li>
1109
+ <li>comments:2 - means registered only</li>
1110
+ </ul></li>
1111
+ <li>Replying to an e-mail gets posted as a comment.
1112
+
1113
+ <ul>
1114
+ <li>For example, you e-mailed a post with the subject line "foo".
1115
+ If you then send an e-mail with the subject line "Re: foo", it will
1116
+ get posted as a comment to the "foo" post. This works by the subject
1117
+ line, so if you have two posts with titles "foo", then the comment
1118
+ will get placed in the more recent post.</li>
1119
+ </ul></li>
1120
+ <li>Custom excerpt
1121
+
1122
+ <ul>
1123
+ <li>You can include a custom excerpt of an e-mail by putting it between
1124
+ :excerptstart and :excerptend</li>
1125
+ <li>You can include images in the excerpt by using the shortcode #eimg1#,
1126
+ #eimg2# etc.</li>
1127
+ </ul></li>
1128
+ </ul>
1129
+
1130
+ <h4>Category and tag handling</h4>
1131
+
1132
+ <ul>
1133
+ <li>If you put a category name in the subject with a : it will be used
1134
+ as the category for the post</li>
1135
+ <li>If you put a category id number in the subject with a : it will
1136
+ be used as the category for the post</li>
1137
+ <li><p>If you put the first part of a category name it will be posted in
1138
+ the first category that the system finds that matches - so if you put</p>
1139
+
1140
+ <p>Subject: Gen: New News</p>
1141
+
1142
+ <p>The system will post that in General.</p></li>
1143
+ <li><p>All of the above also applies if you put the category in brackets []</p></li>
1144
+ <li><p>Using [] or you can post to multiple categories at once</p>
1145
+
1146
+ <p>Subject: [1] [Mo] [Br] My Subject</p>
1147
+
1148
+ <p>On my blog it would post to General (Id 1), Moblog, and Brewing all at one time</p></li>
1149
+ <li><p>Using - or you can post to multiple categories at once</p>
1150
+
1151
+ <p>Subject: -1- -Mo- -Br- My Subject</p>
1152
+
1153
+ <p>On my blog it would post to General (Id 1), Moblog, and Brewing all at one time</p></li>
1154
+ <li>You can add tags by adding a line in the body of the message like so:
1155
+ tags: foo, bar</li>
1156
+ <li>You can also set a default tag to be applied if no tags are included.</li>
1157
+ </ul>
1158
+
1159
+ <h4>Image Handling</h4>
1160
+
1161
+ <ul>
1162
+ <li>Allows you to attach images to your email and automatically post
1163
+ them to your blog</li>
1164
+ <li>You can publish images in the text of your message by using #img1#
1165
+ #img2# - each one will be replaced with the HTML for the image
1166
+ you attached</li>
1167
+ <li><p>Captions - you can also add a caption like so:</p>
1168
+
1169
+ <ul>
1170
+ <li>#img1 caption='foo'#</li>
1171
+ <li>#img2 caption='bar'#</li>
1172
+ </ul>
1173
+
1174
+ <p>Or, if you use IPTC captions, this caption will be used (adding a caption
1175
+ in many photo editing programs (for example Picasa), will add an IPTC caption)</p></li>
1176
+ <li><p>Image templates
1177
+ Postie now uses the default wordpress image template, but you can specify a
1178
+ different one if you wish.</p>
1179
+
1180
+ <p>You can also specify a custom image template. I use the following custom
1181
+ template:</p></li>
1182
+ </ul>
1183
+
1184
+ <a href='{IMAGE}'></a>{CAPTION}
1185
+
1186
+ <pre><code>* {THUMBNAIL} gets replaced with the url to the thumbnail image
1187
+ * {MEDIUM} gets replaced with the url to the medium-sized image
1188
+ * {LARGE} gets replaced with the url to the large-sized image
1189
+ * {FULL} gets replaced with the url to the full-sized image
1190
+ * {FILENAME} gets replaced with the absolute path to the full-size image
1191
+ * {RELFILENAME} gets replaced with the relative path to the full-size image
1192
+ * {CAPTION} gets replaced with the caption you specified (if any)
1193
+ * {WIDTH} gets replaced with width of the photo
1194
+ * {HEIGHT} gets replaced with the height of the photo
1195
+ </code></pre>
1196
+
1197
+ <h4>Interoperability</h4>
1198
+
1199
+ <ul>
1200
+ <li>If your mail client doesn't support setting the subject (nokia) you
1201
+ can do so by putting #your title here# at the begining of your message</li>
1202
+ <li>POP3,POP3-SSL,IMAP,IMAP-SSL now supported - last three require
1203
+ php-imap support</li>
1204
+ <li>The program understands enough about mime to not duplicate post
1205
+ if you send an HTML and plain text message</li>
1206
+ <li>Automatically confirms that you are installed correctly</li>
1207
+ </ul>
1208
+ <hr />
1209
+
1210
+ <h2 id='re-edit'>Re-Edit your Readme File</h2>
1211
+
1212
+ <form method="post" action="">
1213
+ <input type="hidden" name="text" value="1" />
1214
+ <textarea rows="20" cols="100" name="readme_contents">=== Postie ===
1215
+ Contributors: robfelty, WayneAllen
1216
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=HPK99BJ88V4C2
1217
+ Author URI: http://allens-home.com/
1218
+ Plugin URI: http://PostiePlugin.com/
1219
+ Tags: e-mail, email
1220
+ Requires at least: 2.8
1221
+ Tested up to: 3.4.1
1222
+ Stable tag: 1.4.5
1223
+ License: GPLv2 or later
1224
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
1225
+
1226
+ The Postie plugin allows you to blog via e-mail, including many advanced
1227
+ features not found in WordPress&#039;s default post by e-mail feature.
1228
+
1229
+ == Description ==
1230
+ Postie offers many advanced features for posting to your blog via e-mail,
1231
+ including the ability to assign categories by name, included pictures and
1232
+ videos, and automatically strip off signatures. It also has support for both
1233
+ imap and pop3, with the option for ssl with both. For usage notes, see the
1234
+ [other notes](other_notes) page
1235
+
1236
+ = What&#039;s new? =
1237
+
1238
+ * 1.4.5 (upcoming)
1239
+ * Fixed bug in XSS attack vulnerability code. Thanks to R Reid http://blog.strictly-software.com/2012/03/fixing-postie-plugin-for-wordpress-to.html
1240
+ * Fixed bug where emails with multiple categories has the incorrect title
1241
+ * Fixed bugs where PHP setting were not being changed correctly - thanks to Peter Chester http://tri.be/author/peter/
1242
+ * New maintainer
1243
+
1244
+ * 1.4.4 (2012.08.10)
1245
+ * Fixed possible XSS attack vulnerability
1246
+
1247
+ * 1.4.3 (2011.12.12)
1248
+ * Removed get_user_by function to make compatible with wp 3.3 - now requires
1249
+ 2.8+
1250
+
1251
+ * 1.4.2 (2011.01.29)
1252
+ * Fixed mailto link bug (thanks to Jason McNeil)
1253
+ * Fixed bug with attachments with non-ascii characters in filename (thanks to
1254
+ mtakada)
1255
+ * checking for socket errors when checking mail (thanks elysian)
1256
+ * fixed issue with multiple files not being inserted correctly
1257
+ * Added support for ISO 8859-15 (thanks paolog)
1258
+ * fixed sql injection problem (thanks Jose P. Espinal for pointing it out)
1259
+
1260
+ * 1.4.1 (2010.06.18)
1261
+ * Images appear in correct order when using images append = false
1262
+ * Images are sorted in order of filename before inserting into post
1263
+ * Fixed formatting problem with wordpress_default image template
1264
+ * Captions now correctly work with wordpress &gt;3.0 and &lt;3.0
1265
+ * Fixed auto_gallery feature
1266
+ * Default port is now 110
1267
+ * Added more configuration tests
1268
+ * Added background color to settings page to make input boxes more visible
1269
+ * Removed extra quote character in captions from #img# placeholders (thanks
1270
+ SteelD for pointing out the error)
1271
+ * Added support for big5 and gb-1232 encodings (thanks Chow)
1272
+ * Fixed issue with configurations items stored as arrays, which caused
1273
+ problems with validating authorized addresses
1274
+ * Fixed bug with replaceImageCIDs function
1275
+ * On hosts which allow it, we set max execution time to 300 seconds and
1276
+ memory_limit to infinity to allow processing of large e-mails (especially
1277
+ with large attachments)
1278
+
1279
+ == Installation ==
1280
+ * Either:
1281
+ * Put the postie.zip file in wp-content/plugins/ and unzip it
1282
+ * Or:
1283
+ * Use the automatic installer (WP 2.7+)
1284
+ * Login to WordPress as an administrator
1285
+ * Goto the Plugins tab in the WordPress Admin Site
1286
+ * Activate &quot;Postie&quot;
1287
+ * Goto to the &quot;Settings&quot; tab and click on the sub-tab &quot;Postie&quot; to configure it.
1288
+ * Make sure you enter the mailserver information correctly, including the type
1289
+ of connection and the port number. Common port configurations:
1290
+ * pop3: 110
1291
+ * pop3-ssl: 995
1292
+ * imap: 143
1293
+ * imap-ssl: 993
1294
+ * (Postie ignores the settings under Settings-&gt;Writing-&gt;Writing-by-Email)
1295
+
1296
+ = Automating checking e-mail =
1297
+
1298
+ By default, postie checks for new e-mail every 30 minutes. You can select from
1299
+ a number of different checking intervals in the settings page, under the
1300
+ mailserver tab.
1301
+
1302
+ If you would prefer to have more fine-grained control of how postie checks
1303
+ for mail, you can also set up a crontab. This is for advanced users only.
1304
+ If your site runs on a UNIX/linux server, and you have shell access, you can
1305
+ enable mail checking using cron; if you don&#039;t know anything about cron, skip
1306
+ to the cronless postie section.
1307
+
1308
+ Setup a cronjob to pull down the get\_mail.php
1309
+ Examples:
1310
+
1311
+ */5 * * * * /usr/bin/lynx --source http://blog.robfelty.com/wp-content/plugins/postie/get\_mail.php &gt;/dev/null 2&gt;&amp;1
1312
+
1313
+ This fetches the mail every five minutes with lynx
1314
+
1315
+ */10 * * * * /usr/bin/wget -O /dev/null http://blog.robfelty.com/wp-content/plugins/postie/get\_mail.php &gt;/dev/null 2&gt;&amp;1
1316
+
1317
+ This fetches the mail every ten minutes with wget
1318
+
1319
+ == Usage ==
1320
+ * If you put in :start - the message processing won&#039;t start until it sees that string
1321
+ * If you put in :end - the message processing will stop once it sees that string
1322
+ * Posts can be delayed by adding a line with delayXdXhXm where X is a number.
1323
+ * delay:1d - 1 day
1324
+ * delay:1h - 1 hour
1325
+ * delay:1m - 1 minute
1326
+ * delay:1d2h4m - 1 day 2 hours 4m
1327
+ * By putting comments:X in your message you can control if comments are allowed
1328
+ * comments:0 - means closed
1329
+ * comments:1 - means open
1330
+ * comments:2 - means registered only
1331
+ * Replying to an e-mail gets posted as a comment.
1332
+ * For example, you e-mailed a post with the subject line &quot;foo&quot;.
1333
+ If you then send an e-mail with the subject line &quot;Re: foo&quot;, it will
1334
+ get posted as a comment to the &quot;foo&quot; post. This works by the subject
1335
+ line, so if you have two posts with titles &quot;foo&quot;, then the comment
1336
+ will get placed in the more recent post.
1337
+ * Custom excerpt
1338
+ * You can include a custom excerpt of an e-mail by putting it between
1339
+ :excerptstart and :excerptend
1340
+ * You can include images in the excerpt by using the shortcode #eimg1#,
1341
+ #eimg2# etc.
1342
+
1343
+ = Category and tag handling =
1344
+ * If you put a category name in the subject with a : it will be used
1345
+ as the category for the post
1346
+ * If you put a category id number in the subject with a : it will
1347
+ be used as the category for the post
1348
+ * If you put the first part of a category name it will be posted in
1349
+ the first category that the system finds that matches - so if you put
1350
+
1351
+ Subject: Gen: New News
1352
+
1353
+ The system will post that in General.
1354
+
1355
+ * All of the above also applies if you put the category in brackets []
1356
+ * Using [] or you can post to multiple categories at once
1357
+
1358
+ Subject: [1] [Mo] [Br] My Subject
1359
+
1360
+ On my blog it would post to General (Id 1), Moblog, and Brewing all at one time
1361
+
1362
+ * Using - or you can post to multiple categories at once
1363
+
1364
+ Subject: -1- -Mo- -Br- My Subject
1365
+
1366
+ On my blog it would post to General (Id 1), Moblog, and Brewing all at one time
1367
+ * You can add tags by adding a line in the body of the message like so:
1368
+ tags: foo, bar
1369
+ * You can also set a default tag to be applied if no tags are included.
1370
+
1371
+ = Image Handling =
1372
+ * Allows you to attach images to your email and automatically post
1373
+ them to your blog
1374
+ * You can publish images in the text of your message by using #img1#
1375
+ #img2# - each one will be replaced with the HTML for the image
1376
+ you attached
1377
+ * Captions - you can also add a caption like so:
1378
+
1379
+ * #img1 caption=&#039;foo&#039;#
1380
+ * #img2 caption=&#039;bar&#039;#
1381
+
1382
+ Or, if you use IPTC captions, this caption will be used (adding a caption
1383
+ in many photo editing programs (for example Picasa), will add an IPTC caption)
1384
+
1385
+ * Image templates
1386
+ Postie now uses the default wordpress image template, but you can specify a
1387
+ different one if you wish.
1388
+
1389
+ You can also specify a custom image template. I use the following custom
1390
+ template:
1391
+
1392
+ &lt;div class=&#039;imageframe alignleft&#039;&gt;&lt;a href=&#039;{IMAGE}&#039;&gt;&lt;img src=&quot;{THUMBNAIL}&quot;
1393
+ alt=&quot;{CAPTION}&quot; title=&quot;{CAPTION}&quot;
1394
+ class=&quot;attachment&quot; /&gt;&lt;/a&gt;&lt;div
1395
+ class=&#039;imagecaption&#039;&gt;{CAPTION}&lt;/div&gt;&lt;/div&gt;
1396
+
1397
+ * {THUMBNAIL} gets replaced with the url to the thumbnail image
1398
+ * {MEDIUM} gets replaced with the url to the medium-sized image
1399
+ * {LARGE} gets replaced with the url to the large-sized image
1400
+ * {FULL} gets replaced with the url to the full-sized image
1401
+ * {FILENAME} gets replaced with the absolute path to the full-size image
1402
+ * {RELFILENAME} gets replaced with the relative path to the full-size image
1403
+ * {CAPTION} gets replaced with the caption you specified (if any)
1404
+ * {WIDTH} gets replaced with width of the photo
1405
+ * {HEIGHT} gets replaced with the height of the photo
1406
+
1407
+ = Interoperability =
1408
+ * If your mail client doesn&#039;t support setting the subject (nokia) you
1409
+ can do so by putting #your title here# at the begining of your message
1410
+ * POP3,POP3-SSL,IMAP,IMAP-SSL now supported - last three require
1411
+ php-imap support
1412
+ * The program understands enough about mime to not duplicate post
1413
+ if you send an HTML and plain text message
1414
+ * Automatically confirms that you are installed correctly
1415
+
1416
+ == Screenshots ==
1417
+
1418
+ 1. Postie options (showing video and audio templates)
1419
+
1420
+ == Frequently Asked Questions ==
1421
+
1422
+ = Postie won&#039;t connect to my mailserver. Why Not? =
1423
+
1424
+ Make sure the port you are using is open. For example, bluehost seems to block
1425
+ ports 993 and 995 (for pop3-ssl and imap-ssl) by default. I have heard that
1426
+ you can request that they open them for you ( you might have to pay extra).
1427
+
1428
+ You can check for open ports with the following command on your server:
1429
+ netstat -ln|grep -E &#039;:::(993|995|143)&#039;
1430
+
1431
+ If nothing shows up, then the ports are not open.
1432
+
1433
+ = How can I get postie to display inline images? =
1434
+
1435
+ Make sure that you send e-mail formatted as html (richtext), and set postie to
1436
+ prefer html messages (in the message tab of the postie settings)
1437
+
1438
+ = Mail is not showing up right when I send html (rich formatted) e-mail! =
1439
+
1440
+ Make sure you set the preferred text type to html
1441
+
1442
+ = Do I need to any code to my theme for postie to work? =
1443
+
1444
+ No.
1445
+
1446
+ = I read somewhere to add an iframe to my footer. Should I do this? =
1447
+
1448
+ No. Do not add an iframe in your footer to get postie to check mail
1449
+ periodically. To check e-mail periodically, either set-up a cron job, or use
1450
+ cronless postie. See installation instructions
1451
+
1452
+ = My mail host requires SSL, but postie will not allow me to select pop3-ssl or imap-ssl =
1453
+
1454
+ You must have php-imap installed on your server for this to work. Ask your
1455
+ hosting provider about this.
1456
+
1457
+ = Can I use postie to check a gmail account? =
1458
+
1459
+ Yes. You can use either pop3-ssl or imap-ssl with a gmail account. Before
1460
+ attempting to use with postie, make sure that you enable pop or imap in your
1461
+ gmail preferences.
1462
+
1463
+ * Pop3 settings:
1464
+ * protocol - pop3-ssl
1465
+ * server - pop.gmail.com
1466
+ * port - 995
1467
+ * userid - your username (e.g. if your e-mail address is foo@gmail.com,
1468
+ this would be just foo)
1469
+ * password - your password
1470
+ * IMAP settings:
1471
+ * protocol - imap-ssl
1472
+ * server - imap.gmail.com
1473
+ * port - 993
1474
+ * userid - your username (e.g. if your e-mail address is foo@gmail.com,
1475
+ this would be just foo)
1476
+ * password - your password
1477
+
1478
+ = My posts show up as being posted by &#039;admin&#039; instead of me. Why? =
1479
+
1480
+ If your admin account is linked to bar@gmail.com, and you send mail from
1481
+ bar@gmail.com, it will show up as being posted by admin. If you have a
1482
+ wordpress user named &quot;John Doe&quot;, which is linked to johndoe@gmail.com, make
1483
+ sure that you send e-mails from johndoe@gmail.com. It doesn&#039;t matter which
1484
+ e-mail address postie is checking. That is, if you send mail from
1485
+ johndoe@gmail.com to foo@gmail.com, it gets posted as &quot;John Doe&quot;.
1486
+
1487
+ If you send an e-mail to your postie address from an e-mail address that is no
1488
+ t linked to a wordpress user, it will get posted as admin.
1489
+
1490
+ = Images aren&#039;t showing up at all? =
1491
+
1492
+ There are a couple possible reasons for this. First, check to see if you can
1493
+ add an image through wordpress&#039;s normal posting mechanism. If not, then there
1494
+ is probably 1 or 2 problems:
1495
+ 1. Your server does not have the php-gd library installed. Ask your hosting
1496
+ provider about this.
1497
+
1498
+ 2. Your wp-content/uploads directory is not writable by the webserver. Make
1499
+ sure that it is
1500
+
1501
+ = Can I delete the wp-files directory needed by postie version &lt;1.3.0? =
1502
+
1503
+ If you have posts published already by older versions of postie, getting rid
1504
+ of those directories will delete any files you might have had associated with
1505
+ those old posts. If you don&#039;t have any such posts, then you can safely delete
1506
+ them.
1507
+
1508
+ = How can I get rid of stupid stuff my e-mail provider adds to my messages? =
1509
+
1510
+ To strip off stuff that they add at the beginning of a message, start your
1511
+ post with :start
1512
+
1513
+ To strip off stuff that they add at the end of a message, end your
1514
+ post with :end
1515
+
1516
+ = How can I add custom attachment icons? =
1517
+
1518
+ Simply upload the icons you want to the postie/icons/custom directory. You
1519
+ must name the icons according to the following scheme:
1520
+ {filetype}-{size}.png
1521
+
1522
+ For example, for word documents, you could use:
1523
+
1524
+ `doc-32.png`
1525
+
1526
+ for a 32x32 pixel icon. (You can actually create any size icon you want, but
1527
+ if you name it 32, then it will only be used if you select to use size 32
1528
+ icons)
1529
+
1530
+ See the other directories in icons for more examples.
1531
+
1532
+ Currently the following filetypes are supported:
1533
+
1534
+ * doc - microsoft word (including docx)
1535
+ * ppt - microsoft powerpoint (including pptx)
1536
+ * xls - microsoft excel (including xlsx)
1537
+ * numbers - iWork numbres spreadsheet
1538
+ * pages - iWork pages document
1539
+ * key - iWork keynote presentation
1540
+ * pdf - portable document format
1541
+ * rtf - rich text format
1542
+ * txt - plain text document
1543
+
1544
+ = Can I add special text to the body of the post when using postie? =
1545
+
1546
+ Yes. You can create your own function, and use the postie_post filter.
1547
+ Two short examples are included in the filterPostie.php.sample file
1548
+
1549
+ = Can I add special text to the title of the post when using postie? =
1550
+
1551
+ Yes. You can create your own function, and use the postie_post filter.
1552
+ Two short examples are included in the filterPostie.php.sample file
1553
+
1554
+ = Can I select tags or categories based on the content of the e-mail? =
1555
+
1556
+ Yes. You can create your own function, and use the postie_post filter.
1557
+ See the filterPostie.php.sample file for examples.
1558
+
1559
+ = Is the IMAP extension required for postie? =
1560
+
1561
+ The IMAP extension is not required, but it is strongly recommended, especially
1562
+ is you are using non-English text. There is more information on php.net about
1563
+ installing the IMAP extension. If you have control over your server, it is
1564
+ often not hard to install.
1565
+
1566
+ On Ubuntu, try
1567
+ sudo apt-get install php5-imap
1568
+
1569
+ On Fedora, try
1570
+ sudo yuminstall php-imap
1571
+
1572
+ The IMAP extension is known to be installed on the following popular webhosts:
1573
+ * Dreamhost
1574
+
1575
+ = How can I embed youtube or vimeo videos? =
1576
+
1577
+ Simply put the url in the body of your e-mail. (Make sure that you have the
1578
+ option to convert url into links turned on)
1579
+
1580
+ == CHANGELOG ==
1581
+
1582
+ = 1.4.5 =
1583
+ * TODO - fix corruption of rtf attachments
1584
+ * TODO - add port checking in tests
1585
+ * TODO - non-image uploads get ignored in content when using autogallery - see
1586
+ replaceimageplaceholders
1587
+
1588
+ = 1.4.4 (2012.08.10) =
1589
+ * Fixed possible XSS attack vulnerability
1590
+
1591
+ = 1.4.3 =
1592
+ * Removed get_user_by function to make compatible with wp 3.3 - now requires
1593
+ 2.8+
1594
+
1595
+ = 1.4.2 (2011.01.29) =
1596
+ * Fixed mailto link bug (thanks to Jason McNeil)
1597
+ * Fixed bug with attachments with non-ascii characters in filename (thanks to
1598
+ mtakada)
1599
+ * checking for socket errors when checking mail (thanks elysian)
1600
+ * fixed issue with multiple files not being inserted correctly
1601
+ * Added support for ISO 8859-15 (thanks paolog)
1602
+ * fixed sql injection problem (thanks Jose P. Espinal for pointing it out)
1603
+ * Fixed namespace clashing for get_config function
1604
+
1605
+ = 1.4.1 (2010.06.18) =
1606
+ * Images appear in correct order when using images append = false
1607
+ * Fixed formatting problem with wordpress_default image template
1608
+ * Captions now correctly work with wordpress &gt;3.0 and &lt;3.0
1609
+ * Fixed auto_gallery feature
1610
+ * Default port is now 110
1611
+ * Added more configuration tests
1612
+ * Added background color to settings page to make input boxes more visible
1613
+ * Removed extra quote character in captions from #img# placeholders (thanks
1614
+ SteelD for pointing out the error)
1615
+ * Added support for big5 and gb-1232 encodings (thanks Chow)
1616
+ * Fixed issue with configurations items stored as arrays, which caused
1617
+ problems with validating authorized addresses
1618
+ * Fixed bug with replaceImageCIDs function
1619
+ * On hosts which allow it, we set max execution time to 300 seconds and
1620
+ memory_limit to infinity to allow processing of large e-mails (especially
1621
+ with large attachments)
1622
+ * Images are sorted in order of filename before inserting into post
1623
+
1624
+ = 1.4 (2010.04.25) =
1625
+ * Now using wordpress settings api (thanks for much help from Andrew S)
1626
+ * Cronless postie is now integrated with postie instead of a separate plugin
1627
+ * filterPostie.php moved to filterPostie.php.sample
1628
+ * Can use fetchmails.php to fetch mail from multiple mailboxes
1629
+ * Fixed problem with embedding youtube videos from html (richtext) e-mail
1630
+ * Added support for embedding vimeo vidoes
1631
+ * Fixed problem with selecting &quot;none&quot; as icon set for attachments (thanks
1632
+ tonyvitali)
1633
+ * Fixed problems with cronless postie settings
1634
+ * Fixed bug with embedding youtube and vimeo videos whose ID contains a -
1635
+ (thanks Jim Kehoe)
1636
+ * Post_author is now included with attachments
1637
+ * fixed confirmation_email settings so that now you can select between sender,
1638
+ admin, both, or none (thanks to redsalmon for pointing out bug)
1639
+ * Added option to automatically insert galleries
1640
+ * Updated FAQ and readme
1641
+
1642
+ = 1.3.4 (2009.10.05) =
1643
+ * Fixed problem with images not posting under cron
1644
+ * Fixed issue with disappearing password
1645
+
1646
+ = 1.3.3 (2009.09.11) =
1647
+ * Fixed problem with double titles
1648
+ * Fixed error in wp-mu
1649
+ * Cronless postie now correctly updates when changing the setting in the
1650
+ postie settings
1651
+ * Small fix in handling of names of attachments (thanks to Teejot)
1652
+ * Fixed delay option (thanks to redbrandonk)
1653
+ * Cronless option value is now correctly deleted when deactivating the
1654
+ cronless postie plugin
1655
+
1656
+ = 1.3.2 (2009.08.27) =
1657
+ * tags are now always an array, even if no default tags are set
1658
+ * Subject is showing up again if you do not have the IMAP extension
1659
+ installed
1660
+ * More information on the IMAP extension and more user-friendly
1661
+ installation
1662
+ * Fixed problems with smtp server settings in 1.3.1
1663
+ * Added russian translation (thanks to fatcow.com)
1664
+
1665
+ = 1.3.1 (2009.08.24) =
1666
+ * Changed GetContent filter to postie_post
1667
+ * Added database upgrade hook on activation
1668
+ * Fixed bug where content would be empty if trying to remove signature,
1669
+ and signature list was emtpy
1670
+ * Updated FAQ and readme
1671
+
1672
+ = 1.3.0 (2009.08.14) =
1673
+ * Features
1674
+ * Added mpeg4 to default list of videotypes
1675
+ * Added support for KOI8-R character set (cyrillic)
1676
+ * Added support for iso-8859-2 character set (eastern european)
1677
+ * Added option to include custom icons for attachments
1678
+ * Added option to send confirmation message to sender
1679
+ * Enhanced e-mails for unauthorized users
1680
+ * Added option to send unauthorized e-mail back to sender
1681
+ * Added option to only allow e-mails from a specified list of smtp
1682
+ servers
1683
+ * Added option to use shortcode for embedding videos (works with the
1684
+ videos plugin http://www.daburna.de/download/videos-plugin.zip
1685
+ * Better handling of comment authors (thanks to Petter for suggestion)
1686
+ * Simplified message options (now includes an advanced options section)
1687
+ * Added filter ability for post content
1688
+ * Bug fixes
1689
+ * No longer including wp-config.php
1690
+ * If tmpdir is not writable, try a different tmpdir
1691
+ * More subject encoding fixes
1692
+ * Updated image templates, which were causing problems for cron
1693
+ * Fixed in text captions
1694
+ * Fixed SQL problems when updating options
1695
+ * Fixed name clashes with other plugins
1696
+ * Fixed custom image field
1697
+
1698
+ = 1.3.beta (2009.07.01) =
1699
+ * Mores fixes for character issues in subject
1700
+ * Now handling Windows-1256 (arabic) character set
1701
+ * Fixed image uploading on windows servers
1702
+ * Fixed replying to message adds comment
1703
+ * Uploading pictures via MMS should now work
1704
+ * Fixed some issues with e-mails from outloook 12
1705
+ * Greatly reduced number of database queries
1706
+ * No longer requiring config_handler.php
1707
+
1708
+ = 1.3.alpha (2009.06.05) =
1709
+ * Now using default wordpress image and upload handling, which means:
1710
+ * No more creating special directories for postie
1711
+ * No more confusion about imagemagick
1712
+ * Can now use the [gallery] feature of wordpress
1713
+ * Attachments are now connected to posts in the database
1714
+ * All image resizing uses wordpress&#039;s default settings (under media)
1715
+ * Configuration, settings and documentation improvements
1716
+ * Completely redesigned settings page (mostly thanks to Rainman)
1717
+ * Reset configuration no longer deletes mailserver settings
1718
+ * Now including help files and faq directly in settings page
1719
+ * More media features
1720
+ * Automatically turn links to youtube into an embedded player
1721
+ * Added option to embed audio files with custom templates
1722
+ * Video options are now template based
1723
+ * Image options are now solely template based, with several new default
1724
+ templates
1725
+ * Bug fixes
1726
+ * Uploading images from vodafone phones should now work
1727
+ * Correctly handling Windows-1252 encoding
1728
+ * Correctly handling non-ascii characters in subject line
1729
+
1730
+ = 1.2.3 (2009.05.17) =
1731
+ * Fixed headers already sent bug
1732
+ * Converted shortcode `&lt;?` to proper `&lt;?php` (thanks brack)
1733
+ * Deleting mails after processing again
1734
+
1735
+ = 1.2.2 (2009.05.15) =
1736
+ * Show empty categories for default category in options
1737
+ * Image scaling fixed so that the smaller value of max image width and max
1738
+ image height is used
1739
+ * Fixed some issues with parsing html e-mail
1740
+ * Got rid of stupid mime tag (thanks Jeroen)
1741
+ * No longer adding slashes before calling wp_insert_post
1742
+ * When using custom image field, each image has a unique key
1743
+
1744
+
1745
+ = 1.2.1 (2009.05.07) =
1746
+ * Got rid of stupid version checking
1747
+ * Improved cronless postie instructions and configuration
1748
+ * Internationalization is working now
1749
+ * Dutch localization (thanks to gvmelle http://gvmelle.com)
1750
+ * Fixed caption bug when using image magick
1751
+ * Added option to not filter new lines (when using markdown syntax)
1752
+ * Fixed autoplay option
1753
+ * Can now use wildcards in excluding filenames
1754
+ * Producing better quality thumbnails (thanks to robcarey)
1755
+
1756
+ = 1.2 (2009.04.22) =
1757
+ * More video options:
1758
+ * Can embed 3gp, mp4, mov videos
1759
+ * Can specify video width, video height, player width, and player height
1760
+ in the settings page
1761
+ * Can specify custom image template
1762
+ * Image handling improvements:
1763
+ * Only downscale images, not up-scale (thanks Jarven)
1764
+ * More custom image template options
1765
+ * IPTC captions now also work when not resizing images
1766
+ * Added option to use custom field for images (for Datapusher)
1767
+ * Fixed some issues with image templates and line break handling
1768
+ * Custom image template now works even when not resizing images
1769
+ * Documentation improvements:
1770
+ * Added links to settings, forum, and readme in plugin description
1771
+ * Updated readme (thanks to Venkatraman Dhamodaran)
1772
+ * Added better instructions on how to use cronless postie
1773
+ * Text processing improvements:
1774
+ * Added option to automatically convert urls into links
1775
+ * Added feature to include a custom excerpt
1776
+ * Miscellaneous improvements
1777
+ * Improved internationalization (thanks to Håvard Broberg
1778
+ (nanablag@nanablag.com))
1779
+ * Bug Fixes
1780
+ * Removed debugging info in get_mail.php (security issue) thanks to
1781
+ [Jens]( http://svalgaard.net/jens/)
1782
+ * No longer directly including pluggable.php (should
1783
+ prevent conflicts with other plugins such as registerplus
1784
+
1785
+
1786
+ = 1.1.5 (2009.03.10) =
1787
+ * Added option to have postie posts be pending review, published, or draft
1788
+ * Settings panel only shows up for administrators
1789
+ * Need not be user &quot;admin&quot; to modify settings or to post from non-registered
1790
+ users
1791
+ * Can now set administrator name. Authorized e-mail addresses which don&#039;t
1792
+ have a user get posted under this name
1793
+ * Will use IPTC captions if available
1794
+ * Added option to replace newline characters with &lt;br /&gt;
1795
+
1796
+ = 1.1.4 (2009.03.06) =
1797
+ * Added more image options (open in new window, custom image template)
1798
+ * can now add captions to images
1799
+ * Can now add tags (including default tag option)
1800
+
1801
+ = 1.1.3 (2009.02.20) =
1802
+ * Fixed delayed posting
1803
+ * updated readme some
1804
+
1805
+ = 1.1.2 (2008.07.12) =
1806
+ * now maintained by Robert Felty
1807
+ * allow negative delays
1808
+ * will glean author information from forwarded or redirected e*mails
1809
+ * replying to an e*mail adds a comment to a post
1810
+ * fixed category handling to work with taxonomy
1811
+ * fixed one syntax error
1812
+ * added option to wrap posts and comments in &lt;pre%gt; tags
1813
+
1814
+
1815
+ = 1.1.1 =
1816
+
1817
+ Below is all the of the version information. As far as I can tell there once was a guy named John Blade. He took some of the original wp-mail.php code
1818
+ and started hacking away on it. He actually got pretty far. About the time I discovered WordPress and his little hack - called WP-Mail at the time - he
1819
+ went on a vacation or something. There were some problems with the script, and it was missing some features I wanted. I hacked away at it and got it
1820
+ into a place where it did what I wanted. I started posting about it since I figured other people might want the features.
1821
+
1822
+ John didn&#039;t release any more versions at least up til July 2005. So I started accepting submissions and feature requests from people to help make the
1823
+ code better. In June/July 2005 I discovered a little plugin by Chris J Davis (http://www.chrisjdavis.org/cjd-notepad/) called notepad. I added a small
1824
+ feature to it (basically a bookmarklet). In the process I started looking at his code and realized how much you could do with the plugin system
1825
+ available in Word Press.
1826
+
1827
+ So I decided to make an offical fork. I put up an article on my blog asking for new names. I picked Postie. I then modified the code to be a proper
1828
+ plugin. And the rest is history :)
1829
+
1830
+ * BUGFIX -problem with subject
1831
+ * BUGFIX -cronless postie typo
1832
+
1833
+ = 1.1 =
1834
+ * FEATURE: Updated and tested with WordPress 2.1
1835
+ * BUGFIX:Removed deprecated functions
1836
+ * FEATURE: Cronless Postie now uses the WordPress native Psuedo Cron.
1837
+
1838
+ = 1.0 =
1839
+ * BUGFIX: TestWPVersion broke with 2.1
1840
+ * FEATURE: end: now marks the end of a message (Dan Cunningham)
1841
+ * FEATURE: Better Readme (Michael Rasmussen)
1842
+ * FEATURE: Smart Sharpen Option -EXPERIMENTAL- (Jonas Rhodin)
1843
+ * BUGFIX: Issue with google imap fixed (Jim Hodgson)
1844
+ * BUGFIX: Fixed espacing issue in subjects (Paul Clip)
1845
+ * BUGFIX: Typo in Div fixed (phil)
1846
+
1847
+ = 0.9.9.3.2 =
1848
+ * BUGFIX: Typo
1849
+ = 0.9.9.3.1 =
1850
+ * BUGFIX: Removed debugging code
1851
+
1852
+ = 0.9.9.3 =
1853
+ * BUGFIX: If your email address matches an existing user - then it will post as that user - even if you allow anyone to post.
1854
+ * BUGFIX: Replaced get_settings(&#039;home&#039;) with get_settings(&#039;siteurl&#039;)
1855
+ * BUGFIX: Better handling for Japanese charactersets - Thanks to http://www.souzouzone.jp/blog/archives/009531.html
1856
+ * BUGFIX: Better thumbnail window opening code - thanks to Gabi &amp; Duntello!
1857
+ * FEATURE: Added an option to set the MAX Height of an image - idea from Duntello
1858
+ * BUGFIX: Modified the FilterNewLines for better flowed text handling - You now HAVE TO PUT TWO NEW LINES to end a paragraph.
1859
+ * FEATURE: Added new CSS tags to support positioning images/attachments/3gp videos
1860
+ * BUGFIX: Tries to use the date in the message (Thanks Ravan) I tried this once before and it never worked - hopefully this time it will.
1861
+ * BUGFIX: Added a workaround to fix the problem with Subscribe2 - it will now notify on posts that are not set to show up in the future.
1862
+
1863
+
1864
+
1865
+ = 0.9.9.2 =
1866
+ * BUGFIX: Looks for the NOOP error and disgards it
1867
+ * FEATURE: Postie now detects the version of WordPress being used
1868
+ * FEATURE: Smarter Parsing of VodaPhone
1869
+ * FEATURE: Easy place to add new code to handle other brain-dead mail clients
1870
+ * BUGFIX: Handles insertion of single quotes properly
1871
+ * BUGFIX: Thumbnails should now link properly
1872
+
1873
+ = 0.9.9.1 =
1874
+ * BUGFIX: Needed a strtolower in places to catch all iso-8859 - thx to Gitte Wange for the catch
1875
+ * BUGFIX: Fixed issue with the category not being posted properly
1876
+
1877
+ = 0.9.9 =
1878
+ * UPDATE TO WP 2.0
1879
+ * BUGFIX: Config Page now works
1880
+ * FEATURES: Supports role based posting
1881
+ * BUGFIX: Posting updates the category counts.
1882
+
1883
+ = 0.9.8.6 =
1884
+ * BUGFIX: Fixed problems with config page &lt;%php became &lt;?php
1885
+ *
1886
+ = 0.9.8.5 =
1887
+ * BUGFIX: onClick changed to onclick
1888
+ * BUGFIX: strolower added to test for iso - thanks daniele
1889
+ * BUGFIX: Added a class to the 3gp video tags
1890
+ * FEATURE: Added the option to put the images before the article
1891
+ * BUGFIX: Added in selection for charsets - thanks Psykotik - this may cause problems for other encodings
1892
+ * FEATURE: Added option to turn of quoted printable decoding
1893
+ * FEATURE: :start tag - now postie looks for this tag before looking for you message - handy if your service provider prepends a message
1894
+ * FEATURE: Template for translation now included
1895
+ = 0.9.8.4 =
1896
+ * BUGFIX: Fixed problem with config_form.php - select had &quot;NULL&quot; instead of &quot;&quot;
1897
+ * BUGFIX: 3g2 now supported
1898
+ * BUGFIX: More line break issues addressed
1899
+ * BUGFIX: QuickTime controls are now visible even if the movie is done playing
1900
+ * BUGFIX: Email addresses in the format &lt;some@domain.com&gt; (Full Name) supported
1901
+ * BUGFIX: Some images that were not being resized - are now
1902
+ * BUGFIX: HTML problems - if you posted plain text with HTML on it ignored all images
1903
+ * BUGFIX: The test system blew up on the thumbnails
1904
+ * BUGFIX: Selected HTML for preferred text is now shown in the config form properly
1905
+ * BUGFIX: Postie now complains if it is not in its own directory
1906
+ * BUGFIX: Postie doesn&#039;t include PEAR if it is already available
1907
+ * BUGFIX: In Test mode rejected emails are simply dropped
1908
+ * BUGFIX: Markdown messes up Postie - it will warn you if you turn it on.
1909
+ *
1910
+ = 0.9.8.3 =
1911
+ * BUGFIX: Fixed issue with the line feed replacement
1912
+ * BUGFIX: Added Banned File Config back in
1913
+ * FEATURE: Added in a link around 3gp video embedded via QT
1914
+ * BUGFIX: Email that has both Plain and HTML content will show the HTML content and not the plain if html is preferred
1915
+
1916
+ = 0.9.8.2 =
1917
+ * BUGFIX: Fixed an extra new line after attachin non-image files.
1918
+ * BUGFIX: The Test system now displays any missing gd functions
1919
+ * BUGFIX: The test system was only using ImageMagick
1920
+
1921
+ = 0.9.8.1 =
1922
+ * BUGFIX: The test images are now included in the zip
1923
+
1924
+ = 0.9.8 =
1925
+ * BUGFIX: New Lines detected and handled properly in cases where the mail client doesn&#039;t put a space before the new line (Miss Distance)
1926
+ * BUGFIX: 3gp mime type added (Paco Cotera)
1927
+ * BUGFIX: Authorized Email Addresses are not case-insensitive
1928
+ * FEATURE: The larger image now does a proper pop up
1929
+ * BUGFIX: Fixed Timeing Issue - turns out it wasn&#039;t reading the db at all
1930
+ * FEATURE: New Test Screen - to help track down problems
1931
+
1932
+ = 0.9.7 =
1933
+ * BUGFIX: removed all short tags
1934
+ * BUGFIX: There were spacing issues in the way I wrote the QT embed statements
1935
+ * FEATURE: Added calls to WP-Cron - should work with that properly now if you activate Cronless Postie
1936
+ * FEATURE: ImageMagick version works without any calls to GD
1937
+ * BUGFIX: Postie now correctly handles cases wjere tjere are multiple blogs in one db
1938
+ * BUGFIX: Turned off warnings when using without GD
1939
+ * FEATURE: add the rotate:X to your message to rotate all images
1940
+ * FEATURE: new filter_postie_thumbnail_with_full which makes it easy to show a thumbnail on the front page but full image on the single page - see FAQ
1941
+
1942
+ = 0.9.6 =
1943
+ * BUGFIX: handles email addresses that are no name and just &lt;email@email.com&gt; (Steve Cooley Reported)
1944
+ * FEATURE: Basic support for embedding flash files
1945
+ * BUGFIX: Postie now handles creating the correct URL on non Unix platforms
1946
+ * BUGFIX: Fixed problem with file attachments not being put in the right place.
1947
+ * FEATURE: You can now choose to use imagemagick convert to handle making thumbnails
1948
+ * BUGFIX: Rewrote Cronless Postie to use direct sockets
1949
+ * BUGFIX: Time offset is now settable just for Postie - hopefully this will fix problems for cases where the normal time offset doesn&#039;t work properly.
1950
+ * FEATURE: First draft of frame for a 3GP video
1951
+ * FEATURE: Option to embed 3GP in QuickTime Controller.
1952
+
1953
+ = 0.9.5.2 =
1954
+ * BUGFIX: gmt varialble not being set correctly
1955
+ * BUGFIX: Changed the name of the Check Mail button to fix an issue with mod_security
1956
+ * BUGFIX: Fixed issue with Cronless-Postie
1957
+ * BUGFIX: There was an argument passed by reference incorrectly
1958
+ * FEATURE: Added in Cronless Postie Readme
1959
+ * FEATURE: Added in Postie Readme
1960
+
1961
+ = 0.9.5.1 =
1962
+ * BUGFIX: Confirmed POP3-SSL on debian-3.0
1963
+ * BUGFIX: Updated the plugin version
1964
+ * BUGFIX: Stopped displaying the email account
1965
+ *
1966
+ = 0.9.5 =
1967
+ * BUGFIX: Postie handles cases where you do not have GD
1968
+ * FEATURE: You can now set the access level for posting - so other people can use the gate way
1969
+ * BUGFIX: Fixed issue when admininstrator email is not tied to a user account.
1970
+ * FEATURE: Can now reset all Postie configurations back to defaults
1971
+ * BUGFIX: HTML Emails with embedded images are now handled properly.
1972
+ * BUGFIX: The time difference should work correctly now
1973
+ * BUGFIX: Postie&#039;s configs are completely seperate from Writing-By-Mail
1974
+ * FEATURE: Warning if you use Gmail to make sure you turn on POP support
1975
+ * BUGFIX: Manual Check Mail Button in interface
1976
+ * BUGFIX: fixed issue of compatability with cjd-notepad
1977
+ * BUGFIX: Windows Works Now
1978
+
1979
+
1980
+ = 0.9.4 =
1981
+ * BUGFIX: Cronless Postie - fixed the include statement
1982
+ * BUGFIX: Authorized Addresses now supports a single address
1983
+ * FEATURE: All configuration in Postie done in a single screen
1984
+ * FEATURE: AUTHORIZATION can be completely overridden
1985
+ * BUGFIX: line 1159 - didn&#039;t handle cases where the table didn&#039;t exist already very well
1986
+ * FEATURE: Detects if you can do IMAP
1987
+ * FEATURE: Added IMAP Support
1988
+ * FEATURE: Added IMAP-SSL Support
1989
+ * FEATURE: Added POP3-SSL Support
1990
+
1991
+ = 0.9.3 =
1992
+ * Bug fixes for IIS
1993
+ = 0.9.2 =
1994
+ * Moved to more of a DIRECTORY_SEPARATOR structure
1995
+ = 0.9.1 =
1996
+ * Added a define to fix a problem with over including
1997
+ = 0.9 =
1998
+ * Converted to an honest to god plugin
1999
+ * BUGFIX: If you put a single category:subject it now works
2000
+ * BUGFIX: ? Special characters may be supported? The test post now shows a lot of umlats and accents?
2001
+ * BUGFIX: The last ] in a subject with categories is now filtered out
2002
+ * FEATURE: -1- subject - will put the post in category 1
2003
+ = 0.312.13 =
2004
+ * Code clean up - The main loop is finally readable by even non programmers
2005
+ * FEATURE - You can now post to multiple categories at one time by using the [#],[Category Name], [Cat] in the subject
2006
+ * FEATURE - You can now select a category by just including the begining characters [G] will select General
2007
+ * if you don&#039;t have any other categories that start with g
2008
+ * FEATURE - Jay Talbot - added a new feature so you can have multiple email addresses be allowed in
2009
+ * Make multi category posting more obvious
2010
+ * BUG FIX: Timezones of GMT+? should now work properly
2011
+ * BUG FIX: Able to handle mis-mime typed images as long as they are named with .jpg/.gif/.png
2012
+
2013
+ = 0.312.12 =
2014
+ * Code clean up - slowing shrinking the main to make it easiery to fix things
2015
+ * FEATURE: Be able to turn on/off allowing comments in an email
2016
+ * BUG FIX: AppleDouble now mostly supported
2017
+ * BUG FIX: MIME handling improved.
2018
+ * BUG FIX: Fix issue with timing delay
2019
+ = 0.312.11 =
2020
+ * FEATURE: Patterns to define where a sig starts are user configurable
2021
+ * FEATURE: Add filter options for banned file names
2022
+ * BUG FIX: Made it possible to turn off posting to the db for testing purposes
2023
+ = 0.312.10 =
2024
+ * FEATURE: Added in code to diplay the mime type of the file being linked to
2025
+ * BUG FIX: It now tests for the existance of the directories and makes sure
2026
+ * that the web server can write to them
2027
+ = 0.312.9 =
2028
+ * FEATURE:Should handle jpg as well as jpeg as the file type
2029
+ * BUG FIX: Now correctly handles the subject in the message
2030
+ * BUG FIX: Should handle Text preferences correctly
2031
+ = 0.312.8 =
2032
+ * Some general code tidying.
2033
+ * FEATURE: Can now have email from invalid email addresses automatically forwared
2034
+ * to the admin&#039;s email account. This forward includes all attachments.
2035
+ * Props to David Luden for getting this started.
2036
+ * Minor change: The system will continue if it runs into a message that doesn&#039;t have
2037
+ * any content - it will also continue to process if it gets an email from
2038
+ * someone not in the system. In the past this could result in deleted mail
2039
+ * if your cron job didn&#039;t run often enough.
2040
+ = 0.312.7 =
2041
+ * Confirm the handling of 3gp video for cell phones o
2042
+ * Added in new directive SUPPORTED_FILE_TYPES -if the mime type is listed here then the system will try to make a link to it without making a thumb nail.
2043
+ = 0.312.6 =
2044
+ * Bug Fix: Ok the last bug I fixed - actually caused another bug - man I should set up some unit tests. Now it handles mail from the nokia mail client correctly.
2045
+ = 0.312.5 =
2046
+ * Bug Fix : The system was accepting all test/* types. Now you can set a preference (defaults to text/plain)
2047
+ * to use as the main text for the post.
2048
+ = 0.312.4 =
2049
+ * Added in sanitize_title call suggested by Jemima
2050
+ * Added in ability to provide a subject in an mms - by using #Subject#
2051
+ * Fixed an issue with the time stamp system so it now automatically uses the gmt_offset from WordPress
2052
+ * Fixed issue with the delay:1d1h tag that prevented it from being removed from the body.
2053
+ * Fixed issue with the delay tag that caused problems if it was the last thing before an image.
2054
+
2055
+ = 0.312.3-HEY (2005-05) =
2056
+ * &gt; Some changes and Bugfixes by Adrian Heydecker
2057
+ * &gt; Not (yet) in main development branch.
2058
+ * Fixed bug: JPEG-thumbnails had a bigger filesize than full images caused by bad hardcoded compression value.
2059
+ * Fixed bug: If images and signatures were present but no placeholder tags, the images were deleted together with the signature.
2060
+ * Fixed bug: Generates valid postnames for users of mod_rewrite. Permalinks to posts should now work even when whitespaces are present in the subject line.
2061
+ * Added support for Quoted Printable encoded mail.
2062
+ * Added ability to encode Wordpress-posts in charset ISO-8859-1 instead of UTF-8.
2063
+ * Added ability to choose JPEG-compression value for thumbnails.
2064
+ * Added ability to add class=&quot;&quot; and style=&quot;&quot; to images.
2065
+ * Added ability to use a different mailadress (eg. mobile) without setting up a new Wordpress-account.
2066
+
2067
+ = 0.312.2 =
2068
+ * BUGFIX: It now removes the delay tag from the message
2069
+ = 0.312.1 =
2070
+ * Added modification for placeholder support for images (David Luden)
2071
+ * Added in support to automatically scale down big images (Dirk Elmendorf)
2072
+ * Fixed bug with multiple emails all getting the contents of the first image tag (Dirk Elmendorf)
2073
+ * Added option to allow HTML in the body and subject of the email (Dirk Elmendorf)
2074
+ * Switch config options to defines to reduce the number of global variables (Dirk Elmendorf)
2075
+ * Added tests to make sure there is a trailing slash on the DIR definitions (Dirk Elmendorf)
2076
+ * Add tests to see if they have gd installed (Dirk Elmendorf)
2077
+ * Seperate the scaling out to a function for easier usage (Dirk Elmendorf)
2078
+ * Add delay feature for future posting. (Dirk Elmendorf)
2079
+ * Added in ability to use strtotime if it is available (Dirk ELmendorf)
2080
+
2081
+ * Todo
2082
+ * Have option to have the email that is rejected forwarded on to another address.
2083
+ * Fix bug that id still diplays the delay tag in the body
2084
+ = 0.312 - 2005-03 =
2085
+ * CHANGE FOR DEFAULT E-mail Categories, instead of [General] Subject you can now use General: Subject in the subject line. Less typing, and there must be a space after the colon.
2086
+ * Fixed bugs with no default posting for categories and user
2087
+ = 0.311 - 2005-01 =
2088
+ * eep, major bug for pop3 server. Next time I test my code more before I released, fixed so that pop3 now works.`
2089
+ = 0.31 - 2004-12 &amp; 2005-01 =
2090
+ * (Has it been this long, best get back into the swing of things... did most of this coding on my holiday as I didn&#039;t have a machine to play WoW on :)
2091
+ * moved the deletion of pop3 emails into a check so that e-mails aren&#039;t deleted without proper checking.
2092
+ * added HTML &#039;decoding&#039; (basic support for Thunderbird &amp; Outlook)
2093
+ * updated the Category search so that it matches words as well as numbers (i.e. [General] Subjectname will work instead of just [1] Subjectname)
2094
+ * Changed time function from time to strtotime (as per Senior Pez&#039;s suggestion), but found out that strtotime isn&#039;t in default php distro so removed...
2095
+
2096
+ = 0.3 - 2004-09 =
2097
+ * Added UBB decoding support
2098
+ * Added default title (when there is no subject assigned)
2099
+ * Started doing a little code cleanup, been reading Advanced PHP Book :)
2100
+ *
2101
+ = 0.2 - 2004-08 =
2102
+ * Stopped using pear body decoding in favour of own decoding (may be slower but more modifiable) because of enriched text decoding
2103
+ * Added base64_decode checking (may help mobile phone users)
2104
+ * Fixed Subject line for non-english users (htmlentities instead of just trim)
2105
+ * Fixed error in some pop hanging -&gt; more graceful exit on event on no emails in inbox ($pop3-&gt;quit)
2106
+ * Added work around for email addresses with exta &lt;&gt; in field (ie: &lt;blade@lansmash.com&gt; instead of blade@lasmash.com
2107
+ * Added some ===basic=== enriched text support
2108
+ * Updated readme file for easier install
2109
+ * Easy modify of globals (such as PHOTOSDIR and FILESDIR)
2110
+ * Cleaned up some pear stuff in install
2111
+ *
2112
+ = 0.1 - 2004-06 =
2113
+ * First release
2114
+
2115
+ == Upgrade Notice ==
2116
+
2117
+ = 1.4.4 =
2118
+ Fixed possible XSS attack vulnerability</textarea>
2119
+ <p><input type="submit" value="Validate!" /></p>
2120
+ </form>
readme.txt CHANGED
@@ -1,14 +1,17 @@
1
  === Postie ===
2
- Contributors: robfelty,
3
- Donate link: http://blog.robfelty.com/plugins/postie
4
- Plugin URI: http://blog.robfelty.com/plugins/postie
 
5
  Tags: e-mail, email
6
  Requires at least: 2.8
7
- Tested up to: 3.4.1
8
- Stable tag: 1.4.4
 
 
9
 
10
  The Postie plugin allows you to blog via e-mail, including many advanced
11
- features not found in wordpress's default post by e-mail feature.
12
 
13
  == Description ==
14
  Postie offers many advanced features for posting to your blog via e-mail,
@@ -19,6 +22,12 @@ imap and pop3, with the option for ssl with both. For usage notes, see the
19
 
20
  = What's new? =
21
 
 
 
 
 
 
 
22
  * 1.4.4 (2012.08.10)
23
  * Fixed possible XSS attack vulnerability
24
 
@@ -167,10 +176,10 @@ different one if you wish.
167
  You can also specify a custom image template. I use the following custom
168
  template:
169
 
170
- &lt;div class='imageframe alignleft'&gt;&lt;a href='{IMAGE}'&gt;&lt;img src="{THUMBNAIL}"
171
  alt="{CAPTION}" title="{CAPTION}"
172
- class="attachment" /&gt;&lt;/a&gt;&lt;div
173
- class='imagecaption'&gt;{CAPTION}&lt;/div&gt;&lt;/div&gt;
174
 
175
  * {THUMBNAIL} gets replaced with the url to the thumbnail image
176
  * {MEDIUM} gets replaced with the url to the medium-sized image
@@ -524,7 +533,7 @@ option to convert url into links turned on)
524
  * Got rid of stupid version checking
525
  * Improved cronless postie instructions and configuration
526
  * Internationalization is working now
527
- * Dutch localization (thanks to gvmelle http://gvmelle.com)
528
  * Fixed caption bug when using image magick
529
  * Added option to not filter new lines (when using markdown syntax)
530
  * Fixed autoplay option
@@ -569,7 +578,7 @@ option to convert url into links turned on)
569
  * Can now set administrator name. Authorized e-mail addresses which don't
570
  have a user get posted under this name
571
  * Will use IPTC captions if available
572
- * Added option to replace newline characters with &lt;br /&gt;
573
 
574
  = 1.1.4 (2009.03.06) =
575
  * Added more image options (open in new window, custom image template)
@@ -587,16 +596,24 @@ option to convert url into links turned on)
587
  * replying to an e*mail adds a comment to a post
588
  * fixed category handling to work with taxonomy
589
  * fixed one syntax error
590
- * added option to wrap posts and comments in &lt;pre%gt; tags
591
 
592
 
593
  = 1.1.1 =
594
 
595
- Below is all the of the version information. As far as I can tell there once was a guy named John Blade. He took some of the orignal wp-mail.php code and started hacking away on it. He actually got pretty far. About the time I discovered WordPress and his little hack - called WP-Mail at the time - he went on a vacation or something. There were some problems with the script, and it was missing some features I wanted. I hacked away at it and got it into a place where it did what I wanted. I started posting about it since I figured other people might want the features.
 
 
 
 
 
 
 
 
596
 
597
- John didn't release any more versions at least up til July 2005. So I started accepting submissions and feature requests from people to help make the code better. In June/July 2005 I discovered a little plugin by Chris J Davis (http://www.chrisjdavis.org/cjd-notepad/) called notepad. I added a small feature to it (basically a bookmarklet). In the process I started looking at his code and realized how much you could do with the plugin system available in Word Press.
 
598
 
599
- So I decided to make an offical fork. I put up an article on my blog asking for new names. I picked Postie. I then modified the code to be a proper plugin. And the rest is history :)
600
  * BUGFIX -problem with subject
601
  * BUGFIX -cronless postie typo
602
 
@@ -651,7 +668,7 @@ So I decided to make an offical fork. I put up an article on my blog asking for
651
  * BUGFIX: Posting updates the category counts.
652
 
653
  = 0.9.8.6 =
654
- * BUGFIX: Fixed problems with config page &lt;%php became &lt;?php
655
  *
656
  = 0.9.8.5 =
657
  * BUGFIX: onClick changed to onclick
@@ -881,3 +898,8 @@ So I decided to make an offical fork. I put up an article on my blog asking for
881
  *
882
  = 0.1 - 2004-06 =
883
  * First release
 
 
 
 
 
1
  === Postie ===
2
+ Contributors: WayneAllen
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HPK99BJ88V4C2
4
+ Author URI: http://allens-home.com/
5
+ Plugin URI: http://PostiePlugin.com/
6
  Tags: e-mail, email
7
  Requires at least: 2.8
8
+ Tested up to: 3.4.2
9
+ Stable tag: 1.4.5
10
+ License: GPLv2 or later
11
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
13
  The Postie plugin allows you to blog via e-mail, including many advanced
14
+ features not found in WordPress's default post by e-mail feature.
15
 
16
  == Description ==
17
  Postie offers many advanced features for posting to your blog via e-mail,
22
 
23
  = What's new? =
24
 
25
+ * 1.4.5 (2012.11.14)
26
+ * Fixed bug in XSS attack vulnerability code. Thanks to R Reid http://blog.strictly-software.com/2012/03/fixing-postie-plugin-for-wordpress-to.html
27
+ * Fixed bug where emails with multiple categories has the incorrect title
28
+ * Fixed bugs where PHP setting were not being changed correctly - thanks to Peter Chester http://tri.be/author/peter/
29
+ * New maintainer
30
+
31
  * 1.4.4 (2012.08.10)
32
  * Fixed possible XSS attack vulnerability
33
 
176
  You can also specify a custom image template. I use the following custom
177
  template:
178
 
179
+ <div class='imageframe alignleft'><a href='{IMAGE}'><img src="{THUMBNAIL}"
180
  alt="{CAPTION}" title="{CAPTION}"
181
+ class="attachment" /></a><div
182
+ class='imagecaption'>{CAPTION}</div></div>
183
 
184
  * {THUMBNAIL} gets replaced with the url to the thumbnail image
185
  * {MEDIUM} gets replaced with the url to the medium-sized image
533
  * Got rid of stupid version checking
534
  * Improved cronless postie instructions and configuration
535
  * Internationalization is working now
536
+ * Dutch localization (thanks to gvmelle http://gvmelle.com )
537
  * Fixed caption bug when using image magick
538
  * Added option to not filter new lines (when using markdown syntax)
539
  * Fixed autoplay option
578
  * Can now set administrator name. Authorized e-mail addresses which don't
579
  have a user get posted under this name
580
  * Will use IPTC captions if available
581
+ * Added option to replace newline characters with <br />
582
 
583
  = 1.1.4 (2009.03.06) =
584
  * Added more image options (open in new window, custom image template)
596
  * replying to an e*mail adds a comment to a post
597
  * fixed category handling to work with taxonomy
598
  * fixed one syntax error
599
+ * added option to wrap posts and comments in <pre%gt; tags
600
 
601
 
602
  = 1.1.1 =
603
 
604
+ Below is all the of the version information. As far as I can tell there once was a guy named John Blade. He took some of the original wp-mail.php code
605
+ and started hacking away on it. He actually got pretty far. About the time I discovered WordPress and his little hack - called WP-Mail at the time - he
606
+ went on a vacation or something. There were some problems with the script, and it was missing some features I wanted. I hacked away at it and got it
607
+ into a place where it did what I wanted. I started posting about it since I figured other people might want the features.
608
+
609
+ John didn't release any more versions at least up til July 2005. So I started accepting submissions and feature requests from people to help make the
610
+ code better. In June/July 2005 I discovered a little plugin by Chris J Davis (http://www.chrisjdavis.org/cjd-notepad/) called notepad. I added a small
611
+ feature to it (basically a bookmarklet). In the process I started looking at his code and realized how much you could do with the plugin system
612
+ available in Word Press.
613
 
614
+ So I decided to make an offical fork. I put up an article on my blog asking for new names. I picked Postie. I then modified the code to be a proper
615
+ plugin. And the rest is history :)
616
 
 
617
  * BUGFIX -problem with subject
618
  * BUGFIX -cronless postie typo
619
 
668
  * BUGFIX: Posting updates the category counts.
669
 
670
  = 0.9.8.6 =
671
+ * BUGFIX: Fixed problems with config page <%php became <?php
672
  *
673
  = 0.9.8.5 =
674
  * BUGFIX: onClick changed to onclick
898
  *
899
  = 0.1 - 2004-06 =
900
  * First release
901
+
902
+ == Upgrade Notice ==
903
+
904
+ = 1.4.4 =
905
+ Fixed possible XSS attack vulnerability
templates/image_templates.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  $simple_link = '<a href="{FILELINK}">{FILENAME}</a>';
3
  $robert_felty = '<div style="margin-right:10px;background:black;color:white;padding:2px; width:{MEDIUMWIDTH};float:left"><a href="{IMAGE}"><img src="{MEDIUM}" alt="{CAPTION}" title="{CAPTION}" class="attachment" /></a><div style="padding:.2em;text-align:left">{CAPTION}</div></div>';
4
  $no_wrappers = '<a href="{IMAGE}"><img src="{THUMBNAIL}" alt="{CAPTION}" title="{CAPTION}" class="attachment" /></a>';
@@ -6,7 +7,6 @@ $thumbnail_left = '<div style="float:left;margin-right:10px;"><a href="{IMAGE}">
6
  $thumbnail_right = '<div style="float:right;margin-left:10px;"><a href="{IMAGE}"><img src="{THUMBNAIL}" alt="{CAPTION}" title="{CAPTION}" class="attachment" /></a></div>';
7
  $wordpress_default = '<div id="attachment_{ID}" class="wp-caption alignleft" style="width: {MEDIUMWIDTH};"><a rel="attachment wp-att-{ID}" href="{PAGELINK}"><img class="size-medium wp-image-{ID}" title="{TITLE}" alt="{CAPTION}" src="{MEDIUM}" /> </a><p class="wp-caption-text">{CAPTION}</p></div>';
8
  $postie_legacy = '<div class="postie-image-div"><a href="{IMAGE}"><img src="{THUMBNAIL}" alt="{FILENAME}" title="{FILENAME}" style="border:none" class="postie-image" /></a></div>';
9
- $custom=$config['IMAGETEMPLATE'];
10
- $imageTemplates=compact('simple_link','no_wrappers',
11
- 'wordpress_default','thumbnail_left','thumbnail_right','robert_felty','postie_legacy','custom');
12
  ?>
1
  <?php
2
+
3
  $simple_link = '<a href="{FILELINK}">{FILENAME}</a>';
4
  $robert_felty = '<div style="margin-right:10px;background:black;color:white;padding:2px; width:{MEDIUMWIDTH};float:left"><a href="{IMAGE}"><img src="{MEDIUM}" alt="{CAPTION}" title="{CAPTION}" class="attachment" /></a><div style="padding:.2em;text-align:left">{CAPTION}</div></div>';
5
  $no_wrappers = '<a href="{IMAGE}"><img src="{THUMBNAIL}" alt="{CAPTION}" title="{CAPTION}" class="attachment" /></a>';
7
  $thumbnail_right = '<div style="float:right;margin-left:10px;"><a href="{IMAGE}"><img src="{THUMBNAIL}" alt="{CAPTION}" title="{CAPTION}" class="attachment" /></a></div>';
8
  $wordpress_default = '<div id="attachment_{ID}" class="wp-caption alignleft" style="width: {MEDIUMWIDTH};"><a rel="attachment wp-att-{ID}" href="{PAGELINK}"><img class="size-medium wp-image-{ID}" title="{TITLE}" alt="{CAPTION}" src="{MEDIUM}" /> </a><p class="wp-caption-text">{CAPTION}</p></div>';
9
  $postie_legacy = '<div class="postie-image-div"><a href="{IMAGE}"><img src="{THUMBNAIL}" alt="{FILENAME}" title="{FILENAME}" style="border:none" class="postie-image" /></a></div>';
10
+ $custom = $config['IMAGETEMPLATE'];
11
+ $imageTemplates = compact('simple_link', 'no_wrappers', 'wordpress_default', 'thumbnail_left', 'thumbnail_right', 'robert_felty', 'postie_legacy', 'custom');
 
12
  ?>
updateVersion.cmd ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ rem this script updates the version number in all relevant files in the directory
2
+ if [ $# -ne 1 ]
3
+ echo updating revision but not versionNum
4
+ GOTO REVISION
5
+ else
6
+ VER=$1
7
+ for file in *.{php,js,txt,css}; do
8
+ perl -pe "s/(version|stable tag): [0-9a-zA-Z\.]+( |$)/\$1: $VER/gi" < $file > ${file}TEMP
9
+ done
10
+ for file in *TEMP; do
11
+ mv -f $file `echo $file|perl -pe 's/TEMP//'`
12
+ done
13
+ fi
14
+
15
+ :REVISION
16
+ # update Revision file
17
+ svn up
18
+ svn info | grep -E '(Date|Revision)' > Revision
19
+ # convert readme.txt to readme.html using wordpress's online converter
20
+ wget --post-data='url=1&readme_url=robfelty.com/wptesting/wp-content/plugins/postie/readme.txt' http://wordpress.org/extend/plugins/about/validator/ -O - |./stripParts.pl > readme.html
21
+ #svn commit
util/wp-i18n/add-textdomain.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Console application, which adds textdomain argument
4
+ * to all i18n function calls
5
+ *
6
+ * @author
7
+ * @version $Id: add-textdomain.php 15618 2011-01-15 15:23:34Z nbachiyski $
8
+ * @package wordpress-i18n
9
+ */
10
+ error_reporting(E_ALL);
11
+
12
+ require_once dirname( __FILE__ ) . '/makepot.php';
13
+
14
+ class AddTextdomain {
15
+
16
+ var $modified_contents = '';
17
+ var $funcs;
18
+
19
+ function AddTextdomain() {
20
+ $makepot = new MakePOT;
21
+ $this->funcs = array_keys( $makepot->rules );
22
+ }
23
+
24
+ function usage() {
25
+ $usage = "Usage: php add-textdomain.php [-i] <domain> <file>\n\nAdds the string <domain> as a last argument to all i18n function calls in <file>\nand prints the modified php file on standard output.\n\nOptions:\n -i Modifies the PHP file in place, instead of printing it to standard output.\n";
26
+ fwrite(STDERR, $usage);
27
+ exit(1);
28
+ }
29
+
30
+ function process_token($token_text, $inplace) {
31
+ if ($inplace)
32
+ $this->modified_contents .= $token_text;
33
+ else
34
+ echo $token_text;
35
+ }
36
+
37
+
38
+ function process_file($domain, $source_filename, $inplace) {
39
+
40
+ $this->modified_contents = '';
41
+ $domain = addslashes($domain);
42
+
43
+ $source = file_get_contents($source_filename);
44
+ $tokens = token_get_all($source);
45
+
46
+ $in_func = false;
47
+ $args_started = false;
48
+ $parens_balance = 0;
49
+ $found_domain = false;
50
+
51
+ foreach($tokens as $token) {
52
+ $string_success = false;
53
+ if (is_array($token)) {
54
+ list($id, $text) = $token;
55
+ if (T_STRING == $id && in_array($text, $this->funcs)) {
56
+ $in_func = true;
57
+ $parens_balance = 0;
58
+ $args_started = false;
59
+ $found_domain = false;
60
+ } elseif (T_CONSTANT_ENCAPSED_STRING == $id && ("'$domain'" == $text || "\"$domain\"" == $text)) {
61
+ if ($in_func && $args_started) {
62
+ $found_domain = true;
63
+ }
64
+ }
65
+ $token = $text;
66
+ } elseif ('(' == $token){
67
+ $args_started = true;
68
+ ++$parens_balance;
69
+ } elseif (')' == $token) {
70
+ --$parens_balance;
71
+ if ($in_func && 0 == $parens_balance) {
72
+ $token = $found_domain? ')' : ", '$domain')";
73
+ $in_func = false;
74
+ $args_started = false;
75
+ $found_domain = false;
76
+ }
77
+ }
78
+ $this->process_token($token, $inplace);
79
+ }
80
+
81
+ if ($inplace) {
82
+ $f = fopen($source_filename, 'w');
83
+ fwrite($f, $this->modified_contents);
84
+ fclose($f);
85
+ }
86
+ }
87
+ }
88
+
89
+
90
+ // run the CLI only if the file
91
+ // wasn't included
92
+ $included_files = get_included_files();
93
+ if ($included_files[0] == __FILE__) {
94
+ $adddomain = new AddTextdomain;
95
+
96
+ if (!isset($argv[1]) || !isset($argv[2])) {
97
+ $adddomain->usage();
98
+ }
99
+
100
+ $inplace = false;
101
+ if ('-i' == $argv[1]) {
102
+ $inplace = true;
103
+ if (!isset($argv[3])) $adddomain->usage();
104
+ array_shift($argv);
105
+ }
106
+
107
+ $adddomain->process_file($argv[1], $argv[2], $inplace);
108
+ }
109
+
110
+ ?>
util/wp-i18n/cron-svn-pots.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname( __FILE__ ) . '/makepot.php';
3
+
4
+ function silent_system( $command ) {
5
+ global $at_least_one_error;
6
+ ob_start();
7
+ system( "$command 2>&1", $exit_code );
8
+ $output = ob_get_contents();
9
+ ob_end_clean();
10
+ if ( $exit_code != 0 ) {
11
+ echo "ERROR:\t$command\nCODE:\t$exit_code\nOUTPUT:\n";
12
+ echo $output."\n";
13
+ } else {
14
+ echo "OK:\t$command\n";
15
+ }
16
+ return $exit_code;
17
+ }
18
+
19
+
20
+ $options = getopt( 'c:p:m:n:sa:b:u:w:df' );
21
+ if ( empty( $options ) ) {
22
+ ?>
23
+ -s No branch/version directories, it's all flat
24
+ -c Application svn checkout
25
+ -p POT svn checkout
26
+ -m MakePOT project
27
+ -n POT filename
28
+ -a Relative path of application inside version dir in -c
29
+ -b Relative patch of POT dir inside version dir in -p
30
+ -u SVN username (optional)
31
+ -w SVN password (optional)
32
+ -d Dry-run
33
+ -f Fast - do not update checkouts
34
+ <?php
35
+ die;
36
+ }
37
+
38
+ $application_svn_checkout = realpath( $options['c'] );
39
+ $pot_svn_checkout = realpath( $options['p'] );
40
+ $makepot_project = str_replace( '-', '_', $options['m'] );
41
+ $pot_name = $options['n'];
42
+ $no_branch_dirs = isset( $options['s'] );
43
+ $relative_application_path = isset( $options['a'] )? '/'.$options['a'] : '';
44
+ $relative_pot_path = isset( $options['b'] )? '/'.$options['b'] : '';
45
+ $dry_run = isset( $options['d'] );
46
+
47
+ $makepot = new MakePOT;
48
+ $svn_args = array('--non-interactive');
49
+ if ( isset( $options['u'] ) && isset( $options['w'] ) ) {
50
+ $svn_args[] = '--username='.$options['u'];
51
+ $svn_args[] = '--password='.$options['w'];
52
+ $svn_args[] = '--no-auth-cache';
53
+ }
54
+ $svn_args_str = implode( ' ', array_map( 'escapeshellarg', $svn_args ) );
55
+ $svn = 'svn '.$svn_args_str;
56
+
57
+
58
+ $versions = array();
59
+
60
+ chdir( $application_svn_checkout );
61
+ if ( ! isset( $options['f'] ) ) {
62
+ $exit = silent_system( "$svn cleanup" );
63
+ if ( 0 != $exit ) die();
64
+ $exit = silent_system( "$svn up" );
65
+ if ( 0 != $exit ) die();
66
+ }
67
+ if ( is_dir( 'trunk' ) ) $versions[] = 'trunk';
68
+ $branches = glob( 'branches/*' );
69
+ if ( false !== $branches ) $versions = array_merge( $versions, $branches );
70
+ $tags = glob( 'tags/*' );
71
+ if ( false !== $tags ) $versions = array_merge( $versions, $tags );
72
+
73
+ if ( $no_branch_dirs ) {
74
+ $versions = array( '.' );
75
+ }
76
+
77
+ chdir( $pot_svn_checkout );
78
+ if ( $application_svn_checkout != $pot_svn_checkout && ! isset( $options['f'] ) ) {
79
+ $exit = silent_system( "$svn cleanup" );
80
+ if ( 0 != $exit ) die();
81
+ $exit = silent_system( "$svn up" );
82
+ if ( 0 != $exit ) die();
83
+ }
84
+ $real_application_svn_checkout = realpath( $application_svn_checkout );
85
+ foreach( $versions as $version ) {
86
+ $application_path = "$real_application_svn_checkout/$version{$relative_application_path}";
87
+ if ( !is_dir( $application_path ) ) continue;
88
+ $pot = "$version{$relative_pot_path}/$pot_name";
89
+ $exists = is_file( $pot );
90
+ // do not update old tag pots
91
+ if ( 'tags/' == substr( $version, 0, 5 ) && $exists ) continue;
92
+ if ( !is_dir( $version ) ) {
93
+ $exit = silent_system( "$svn mkdir $version" );
94
+ if ( 0 != $exit ) continue;
95
+ }
96
+ if ( !is_dir(dirname("$pot_svn_checkout/$pot")) ) continue;
97
+ if ( !call_user_func( array( &$makepot, $makepot_project ), $application_path, "$pot_svn_checkout/$pot" ) ) continue;
98
+ if ( !file_exists( "$pot_svn_checkout/$pot" ) ) continue;
99
+ if ( !$exists ) {
100
+ $exit = silent_system( "$svn add $pot" );
101
+ if ( 0 != $exit ) continue;
102
+ }
103
+ // do not commit if the difference is only in the header, but always commit a new file
104
+ $real_differences = `svn diff $pot | wc -l` > 16;
105
+ $target = $exists ? $pot : $version;
106
+ if ( !$exists || $real_differences ) {
107
+ preg_match( '/Revision:\s+(\d+)/', `svn info $application_path`, $matches );
108
+ $logmsg = isset( $matches[1] ) && intval( $matches[1] )? "POT, generated from r".intval( $matches[1] ) : 'Automatic POT update';
109
+ $command = "$svn ci $target --non-interactive --message='$logmsg'";
110
+ if ( !$dry_run )
111
+ silent_system( $command );
112
+ else
113
+ echo "CMD:\t$command\n";
114
+ } else {
115
+ silent_system( "$svn revert $target" );
116
+ }
117
+ }
util/wp-i18n/extract/ExtractTest.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/extract.php';
4
+
5
+ class ExtractTest extends PHPUnit_Framework_TestCase {
6
+
7
+ function setUp() {
8
+ $this->extractor = new StringExtractor;
9
+ $this->extractor->rules = array(
10
+ '__' => array('string'),
11
+ );
12
+ }
13
+
14
+ function test_with_just_a_string() {
15
+ $expected = new Translation_Entry( array( 'singular' => 'baba', 'references' => array('baba.php:1') ) );
16
+ $result = $this->extractor->extract_entries('<?php __("baba"); ?>', 'baba.php' );
17
+ $this->assertEquals( $expected, $result->entries['baba'] );
18
+ }
19
+
20
+ function test_entry_from_call_simple() {
21
+ $entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba') ), 'baba.php' );
22
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba' ) ) );
23
+ }
24
+
25
+ function test_entry_from_call_nonexisting_function() {
26
+ $entry = $this->extractor->entry_from_call( array( 'name' => 'f', 'args' => array('baba') ), 'baba.php' );
27
+ $this->assertEquals( $entry, null );
28
+ }
29
+
30
+ function test_entry_from_call_too_few_args() {
31
+ $entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array() ), 'baba.php' );
32
+ $this->assertEquals( $entry, null );
33
+ }
34
+
35
+ function test_entry_from_call_non_expected_null_arg() {
36
+ $this->extractor->rules = array( '_nx' => array( 'singular', 'plural', 'context' ) );
37
+ $entry = $this->extractor->entry_from_call( array( 'name' => '_nx', 'args' => array('%s baba', null, 'noun') ), 'baba.php' );
38
+ $this->assertEquals( $entry, null );
39
+ }
40
+
41
+ function test_entry_from_call_more_args_should_be_ok() {
42
+ $this->extractor->rules = array( '__' => array('string') );
43
+ $entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba', 5, 'pijo', null) ), 'baba.php' );
44
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba' ) ) );
45
+ }
46
+
47
+
48
+ function test_entry_from_call_context() {
49
+ $this->extractor->rules = array( '_x' => array( 'string', 'context' ) );
50
+ $entry = $this->extractor->entry_from_call( array( 'name' => '_x', 'args' => array('baba', 'noun') ), 'baba.php' );
51
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba', 'context' => 'noun' ) ) );
52
+ }
53
+
54
+ function test_entry_from_call_plural() {
55
+ $this->extractor->rules = array( '_n' => array( 'singular', 'plural' ) );
56
+ $entry = $this->extractor->entry_from_call( array( 'name' => '_n', 'args' => array('%s baba', '%s babas') ), 'baba.php' );
57
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => '%s baba', 'plural' => '%s babas' ) ) );
58
+ }
59
+
60
+ function test_entry_from_call_plural_and_context() {
61
+ $this->extractor->rules = array( '_nx' => array( 'singular', 'plural', 'context' ) );
62
+ $entry = $this->extractor->entry_from_call( array( 'name' => '_nx', 'args' => array('%s baba', '%s babas', 'noun') ), 'baba.php' );
63
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => '%s baba', 'plural' => '%s babas', 'context' => 'noun' ) ) );
64
+ }
65
+
66
+ function test_entry_from_call_extracted_comment() {
67
+ $entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba'), 'comment' => 'translators: give me back my pants!' ), 'baba.php' );
68
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba', 'extracted_comments' => "translators: give me back my pants!\n" ) ) );
69
+ }
70
+
71
+ function test_entry_from_call_line_number() {
72
+ $entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba'), 'line' => 10 ), 'baba.php' );
73
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba', 'references' => array('baba.php:10') ) ) );
74
+ }
75
+
76
+ function test_entry_from_call_zero() {
77
+ $entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('0') ), 'baba.php' );
78
+ $this->assertEquals( $entry, new Translation_Entry( array( 'singular' => '0' ) ) );
79
+ }
80
+
81
+ function test_entry_from_call_multiple() {
82
+ $this->extractor->rules = array( 'c' => array( 'string', 'singular', 'plural' ) );
83
+ $entries = $this->extractor->entry_from_call( array( 'name' => 'c', 'args' => array('baba', 'dyado', 'dyados') ), 'baba.php' );
84
+ $this->assertEquals( array(
85
+ new Translation_Entry( array( 'singular' => 'baba' ) ), new Translation_Entry( array( 'singular' => 'dyado', 'plural' => 'dyados' ) ) ), $entries );
86
+ }
87
+
88
+ function test_entry_from_call_multiple_first_plural_then_two_strings() {
89
+ $this->extractor->rules = array( 'c' => array( 'singular', 'plural', null, 'string', 'string' ) );
90
+ $entries = $this->extractor->entry_from_call( array( 'name' => 'c', 'args' => array('dyado', 'dyados', 'baba', 'foo', 'bar') ), 'baba.php' );
91
+ $this->assertEquals( array(
92
+ new Translation_Entry( array( 'singular' => 'dyado', 'plural' => 'dyados' ) ),
93
+ new Translation_Entry( array( 'singular' => 'foo' ) ),
94
+ new Translation_Entry( array( 'singular' => 'bar' ) ) ), $entries );
95
+ }
96
+
97
+ function test_find_function_calls_one_arg_literal() {
98
+ $this->assertEquals( array( array( 'name' => '__', 'args' => array( 'baba' ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('__'), '<?php __("baba"); ?>' ) );
99
+ }
100
+
101
+ function test_find_function_calls_one_arg_zero() {
102
+ $this->assertEquals( array( array( 'name' => '__', 'args' => array( '0' ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('__'), '<?php __("0"); ?>' ) );
103
+ }
104
+
105
+ function test_find_function_calls_one_arg_non_literal() {
106
+ $this->assertEquals( array( array( 'name' => '__', 'args' => array( null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('__'), '<?php __("baba" . "dudu"); ?>' ) );
107
+ }
108
+
109
+ function test_find_function_calls_shouldnt_be_mistaken_by_a_class() {
110
+ $this->assertEquals( array(), $this->extractor->find_function_calls( array('__'), '<?php class __ { }; ("dyado");' ) );
111
+ }
112
+
113
+ function test_find_function_calls_2_args_bad_literal() {
114
+ $this->assertEquals( array( array( 'name' => 'f', 'args' => array( null, "baba" ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f(5, "baba" ); ' ) );
115
+ }
116
+
117
+ function test_find_function_calls_2_args_bad_literal_bad() {
118
+ $this->assertEquals( array( array( 'name' => 'f', 'args' => array( null, "baba", null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f(5, "baba", 5 ); ' ) );
119
+ }
120
+
121
+ function test_find_function_calls_1_arg_bad_concat() {
122
+ $this->assertEquals( array( array( 'name' => 'f', 'args' => array( null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( "baba" . "baba" ); ' ) );
123
+ }
124
+
125
+ function test_find_function_calls_1_arg_bad_function_call() {
126
+ $this->assertEquals( array( array( 'name' => 'f', 'args' => array( null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( g( "baba" ) ); ' ) );
127
+ }
128
+
129
+ function test_find_function_calls_2_arg_literal_bad() {
130
+ $this->assertEquals( array( array( 'name' => 'f', 'args' => array( "baba", null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( "baba", null ); ' ) );
131
+ }
132
+
133
+ function test_find_function_calls_2_arg_bad_with_parens_literal() {
134
+ $this->assertEquals( array( array( 'name' => 'f', 'args' => array( null, "baba" ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( g( "dyado", "chicho", "lelya "), "baba" ); ' ) );
135
+ }
136
+
137
+ function test_find_function_calls_with_comment() {
138
+ $this->assertEquals(
139
+ array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'translators: let your ears fly!' ) ),
140
+ $this->extractor->find_function_calls( array('f'), '<?php /* translators: let your ears fly! */ f( "baba" ); ' ) );
141
+ }
142
+
143
+ function test_find_function_calls_with_not_immediate_comment() {
144
+ $this->assertEquals(
145
+ array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'translators: let your ears fly!' ) ),
146
+ $this->extractor->find_function_calls( array('f'), '<?php /* translators: let your ears fly! */ $foo = g ( f( "baba" ) ); ' ) );
147
+ }
148
+
149
+ function test_find_function_calls_with_not_immediate_comment_include_only_latest() {
150
+ $this->assertEquals(
151
+ array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'translators: let your ears fly!' ) ),
152
+ $this->extractor->find_function_calls( array('f'), '<?php /* translators: boo */ /* translators: let your ears fly! */ /* baba */ $foo = g ( f( "baba" ) ); ' ) );
153
+ }
154
+ }
util/wp-i18n/extract/TODO ADDED
@@ -0,0 +1 @@
 
1
+ * php-format
util/wp-i18n/extract/extract.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname( __FILE__ ) . '/../pomo/entry.php';
3
+ require_once dirname( __FILE__ ) . '/../pomo/translations.php';
4
+
5
+ class StringExtractor {
6
+
7
+ var $rules = array();
8
+ var $comment_prefix = 'translators:';
9
+
10
+ function __construct( $rules = array() ) {
11
+ $this->rules = $rules;
12
+ }
13
+
14
+ function extract_from_directory( $dir, $excludes = array(), $includes = array(), $prefix = '' ) {
15
+ $old_cwd = getcwd();
16
+ chdir( $dir );
17
+ $translations = new Translations;
18
+ $file_names = (array) scandir( '.' );
19
+ foreach ( $file_names as $file_name ) {
20
+ if ( '.' == $file_name || '..' == $file_name ) continue;
21
+ if ( preg_match( '/\.php$/', $file_name ) && $this->does_file_name_match( $prefix . $file_name, $excludes, $includes ) ) {
22
+ $translations->merge_originals_with( $this->extract_from_file( $file_name, $prefix ) );
23
+ }
24
+ if ( is_dir( $file_name ) ) {
25
+ $translations->merge_originals_with( $this->extract_from_directory( $file_name, $excludes, $includes, $prefix . $file_name . '/' ) );
26
+ }
27
+ }
28
+ chdir( $old_cwd );
29
+ return $translations;
30
+ }
31
+
32
+ function extract_from_file( $file_name, $prefix ) {
33
+ $code = file_get_contents( $file_name );
34
+ return $this->extract_entries( $code, $prefix . $file_name );
35
+ }
36
+
37
+ function does_file_name_match( $path, $excludes, $includes ) {
38
+ if ( $includes ) {
39
+ $matched_any_include = false;
40
+ foreach( $includes as $include ) {
41
+ if ( preg_match( '|^'.$include.'$|', $path ) ) {
42
+ $matched_any_include = true;
43
+ break;
44
+ }
45
+ }
46
+ if ( !$matched_any_include ) return false;
47
+ }
48
+ if ( $excludes ) {
49
+ foreach( $excludes as $exclude ) {
50
+ if ( preg_match( '|^'.$exclude.'$|', $path ) ) {
51
+ return false;
52
+ }
53
+ }
54
+ }
55
+ return true;
56
+ }
57
+
58
+ function entry_from_call( $call, $file_name ) {
59
+ $rule = isset( $this->rules[$call['name']] )? $this->rules[$call['name']] : null;
60
+ if ( !$rule ) return null;
61
+ $entry = new Translation_Entry;
62
+ $multiple = array();
63
+ $complete = false;
64
+ for( $i = 0; $i < count( $rule ); ++$i ) {
65
+ if ( $rule[$i] && ( !isset( $call['args'][$i] ) || !is_string( $call['args'][$i] ) || '' == $call['args'][$i] ) ) return false;
66
+ switch( $rule[$i] ) {
67
+ case 'string':
68
+ if ( $complete ) {
69
+ $multiple[] = $entry;
70
+ $entry = new Translation_Entry;
71
+ $complete = false;
72
+ }
73
+ $entry->singular = $call['args'][$i];
74
+ $complete = true;
75
+ break;
76
+ case 'singular':
77
+ if ( $complete ) {
78
+ $multiple[] = $entry;
79
+ $entry = new Translation_Entry;
80
+ $complete = false;
81
+ }
82
+ $entry->singular = $call['args'][$i];
83
+ $entry->is_plural = true;
84
+ break;
85
+ case 'plural':
86
+ $entry->plural = $call['args'][$i];
87
+ $entry->is_plural = true;
88
+ $complete = true;
89
+ break;
90
+ case 'context':
91
+ $entry->context = $call['args'][$i];
92
+ foreach( $multiple as &$single_entry ) {
93
+ $single_entry->context = $entry->context;
94
+ }
95
+ break;
96
+ }
97
+ }
98
+ if ( isset( $call['line'] ) && $call['line'] ) {
99
+ $references = array( $file_name . ':' . $call['line'] );
100
+ $entry->references = $references;
101
+ foreach( $multiple as &$single_entry ) {
102
+ $single_entry->references = $references;
103
+ }
104
+ }
105
+ if ( isset( $call['comment'] ) && $call['comment'] ) {
106
+ $comments = rtrim( $call['comment'] ) . "\n";
107
+ $entry->extracted_comments = $comments;
108
+ foreach( $multiple as &$single_entry ) {
109
+ $single_entry->extracted_comments = $comments;
110
+ }
111
+ }
112
+ if ( $multiple && $entry ) {
113
+ $multiple[] = $entry;
114
+ return $multiple;
115
+ }
116
+
117
+ return $entry;
118
+ }
119
+
120
+ function extract_entries( $code, $file_name ) {
121
+ $translations = new Translations;
122
+ $function_calls = $this->find_function_calls( array_keys( $this->rules ), $code );
123
+ foreach( $function_calls as $call ) {
124
+ $entry = $this->entry_from_call( $call, $file_name );
125
+ if ( is_array( $entry ) )
126
+ foreach( $entry as $single_entry )
127
+ $translations->add_entry_or_merge( $single_entry );
128
+ elseif ( $entry)
129
+ $translations->add_entry_or_merge( $entry );
130
+ }
131
+ return $translations;
132
+ }
133
+
134
+ /**
135
+ * Finds all function calls in $code and returns an array with an associative array for each function:
136
+ * - name - name of the function
137
+ * - args - array for the function arguments. Each string literal is represented by itself, other arguments are represented by null.
138
+ * - line - line number
139
+ */
140
+ function find_function_calls( $function_names, $code ) {
141
+ $tokens = token_get_all( $code );
142
+ $function_calls = array();
143
+ $latest_comment = false;
144
+ $in_func = false;
145
+ foreach( $tokens as $token ) {
146
+ $id = $text = null;
147
+ if ( is_array( $token ) ) list( $id, $text, $line ) = $token;
148
+ if ( T_WHITESPACE == $id ) continue;
149
+ if ( T_STRING == $id && in_array( $text, $function_names ) && !$in_func ) {
150
+ $in_func = true;
151
+ $paren_level = -1;
152
+ $args = array();
153
+ $func_name = $text;
154
+ $func_line = $line;
155
+ $func_comment = $latest_comment? $latest_comment : '';
156
+
157
+ $just_got_into_func = true;
158
+ $latest_comment = false;
159
+ continue;
160
+ }
161
+ if ( T_COMMENT == $id ) {
162
+ $text = trim( preg_replace( '%^/\*|//%', '', preg_replace( '%\*/$%', '', $text ) ) );
163
+ if ( 0 === strpos( $text, $this->comment_prefix ) ) {
164
+ $latest_comment = $text;
165
+ }
166
+ }
167
+ if ( !$in_func ) continue;
168
+ if ( '(' == $token ) {
169
+ $paren_level++;
170
+ if ( 0 == $paren_level ) { // start of first argument
171
+ $just_got_into_func = false;
172
+ $current_argument = null;
173
+ $current_argument_is_just_literal = true;
174
+ }
175
+ continue;
176
+ }
177
+ if ( $just_got_into_func ) {
178
+ // there wasn't a opening paren just after the function name -- this means it is not a function
179
+ $in_func = false;
180
+ $just_got_into_func = false;
181
+ }
182
+ if ( ')' == $token ) {
183
+ if ( 0 == $paren_level ) {
184
+ $in_func = false;
185
+ $args[] = $current_argument;
186
+ $call = array( 'name' => $func_name, 'args' => $args, 'line' => $func_line );
187
+ if ( $func_comment ) $call['comment'] = $func_comment;
188
+ $function_calls[] = $call;
189
+ }
190
+ $paren_level--;
191
+ continue;
192
+ }
193
+ if ( ',' == $token && 0 == $paren_level ) {
194
+ $args[] = $current_argument;
195
+ $current_argument = null;
196
+ $current_argument_is_just_literal = true;
197
+ continue;
198
+ }
199
+ if ( T_CONSTANT_ENCAPSED_STRING == $id && $current_argument_is_just_literal ) {
200
+ // we can use eval safely, because we are sure $text is just a string literal
201
+ eval('$current_argument = '.$text.';' );
202
+ continue;
203
+ }
204
+ $current_argument_is_just_literal = false;
205
+ $current_argument = null;
206
+ }
207
+ return $function_calls;
208
+ }
209
+ }
util/wp-i18n/importers-i18n.php ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ini_set( 'display_errors', 1 );
3
+ class ImportersI18n {
4
+ var $importers_slugs = array('wpcat2tag', 'wordpress', 'utw', 'textpattern', 'stp', 'rss', 'opml', 'movabletype', 'livejournal', 'greymatter', 'dotclear', 'blogware', 'blogger');
5
+ var $username = 'nbachiyski';
6
+ var $plugins_dir = '/www/wp-content-trunk/plugins';
7
+ var $glotpress_source_dir = '/Users/nb/glotpress';
8
+ var $glotpress_api_url = 'http://x/gp/api/projects/importers/%importer%/dev';
9
+ var $glotpress_url = 'http://x/gp/projects/importers/%importer%/dev';
10
+ var $minimum_percentage = 80;
11
+
12
+ function __construct() {
13
+ $this->importers = array_map( create_function( '$x', 'return $x."-importer";' ), $this->importers_slugs);
14
+ }
15
+
16
+ function s( $importer, $text ) {
17
+ return str_replace( array( '%importer%', '%trunk%' ), array( $importer, "$importer/trunk" ), $text );
18
+ }
19
+
20
+ function call_on_all( $command ) {
21
+ foreach( $this->importers as $importer ) {
22
+ system( $this->s( $importer, $command ) );
23
+ }
24
+ }
25
+
26
+ function ls() {
27
+ $this->call_on_all( "ls %trunk%" );
28
+ }
29
+
30
+ function command( $command ) {
31
+ $this->call_on_all( $command );
32
+ }
33
+
34
+
35
+ function checkout() {
36
+ $this->call_on_all( "svn checkout --username=$this->username http://plugins.svn.wordpress.org/%importer%" );
37
+ }
38
+
39
+ function update() {
40
+ $this->call_on_all( "svn up %importer%" );
41
+ }
42
+
43
+ function rename_main_file() {
44
+ $this->call_on_all( "svn mv %importer%/trunk/*.php %importer%/trunk/%importer%.php" );
45
+ }
46
+
47
+ function link( $target ) {
48
+ $this->call_on_all( "ln -s `pwd`/%importer%/trunk $target/%importer%" );
49
+ }
50
+
51
+ function add_load_plugin_textdomain_call() {
52
+ foreach( $this->importers as $importer ) {
53
+ $importer_underscore = str_replace( '-', '_', $importer );
54
+ $main_file_name = "$importer/trunk/$importer.php";
55
+ $main_file = file_get_contents( $main_file_name );
56
+ $main_file .= "
57
+ function {$importer_underscore}_init() {
58
+ load_plugin_textdomain( '$importer', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
59
+ }
60
+ add_action( 'init', '{$importer_underscore}_init' );
61
+ ";
62
+ file_put_contents( $main_file_name, $main_file );
63
+ }
64
+ }
65
+
66
+ function make_languages_dir() {
67
+ $this->call_on_all( "svn mkdir %importer%/trunk/languages" );
68
+ }
69
+
70
+ function generate_pot() {
71
+ foreach( $this->importers as $importer ) {
72
+ $old_cwd = getcwd();
73
+ chdir( "$importer/trunk/languages" );
74
+ system( "php ".dirname(__FILE__)."/makepot.php wp-plugin .." );
75
+ chdir( $old_cwd );
76
+ }
77
+ }
78
+
79
+
80
+ function diff() {
81
+ $this->call_on_all( "svn diff %trunk%" );
82
+ }
83
+
84
+ function st() {
85
+ $this->call_on_all( "svn st %trunk%" );
86
+ }
87
+
88
+ function svn_add_missing() {
89
+ $this->call_on_all( "svn add %trunk%/*" );
90
+ $this->call_on_all( "svn add %trunk%/languages/*" );
91
+ }
92
+
93
+ function lint() {
94
+ $this->call_on_all( "php -l %importer% %trunk%/%importer%.php" );
95
+ }
96
+
97
+
98
+ function add_textdomain() {
99
+ $this->call_on_all( "php ".dirname(__FILE__)."/add-textdomain.php -i %importer% %trunk%/%importer%.php" );
100
+ }
101
+
102
+ function sync() {
103
+ $this->call_on_all( "cp -R %trunk% $this->plugins_dir/%importer%" );
104
+ }
105
+
106
+ function commit($message) {
107
+ $this->call_on_all( "svn ci %trunk% -m ".escapeshellarg($message) );
108
+ }
109
+
110
+ function update_translations() {
111
+ require_once $this->glotpress_source_dir . '/locales/locales.php';
112
+ foreach( $this->importers as $importer ) {
113
+ $project_details_json = file_get_contents( $this->s( $importer, $this->glotpress_api_url ) );
114
+ $project_details = json_decode( $project_details_json );
115
+ if ( !is_object( $project_details ) ) {
116
+ echo "Couldn't get project JSON from GlotPress for $importer.\n";
117
+ continue;
118
+ }
119
+ foreach( $project_details->translation_sets as $set ) {
120
+ $locale = GP_Locales::by_slug( $set->locale );
121
+ if ( !$locale->wp_locale ) {
122
+ echo "Locale '$set->locale' doesn't have WordPress equivalent.\n";
123
+ continue;
124
+ }
125
+ $po_file = file_get_contents( $this->s( $importer, $this->glotpress_url ) . "/$locale->slug/$set->slug/export-translations" );
126
+ if ( !$po_file ) {
127
+ echo "Couldn't download translation for '$importer' in '$set->locale'.\n";
128
+ continue;
129
+ }
130
+ $po_path = $this->s( $importer, "%trunk%/languages/$locale->wp_locale.po" );
131
+ $mo_path = str_replace( '.po', '.mo', $po_path );
132
+ file_put_contents( $po_path, $po_file );
133
+ $msgfmt_output = `msgfmt --statistics $po_path -o $mo_path 2>&1`;
134
+ preg_match( '/(\d+) translated messages(?:\.|, (\d+) untranslated messages)/', $msgfmt_output, $matches );
135
+ if ( isset( $matches[2] ) ) {
136
+ $translated_percentage = $matches[1] / ( $matches[1] + $matches[2] ) * 100;
137
+ if ( $translated_percentage < $this->minimum_percentage ) {
138
+ unlink( $po_path );
139
+ unlink( $mo_path );
140
+ echo "Translation of '$importer' in '$locale->slug' has only $translated_percentage% translated, $this->minimum_percentage% are required.\n";
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ function create_glotpress_projects( $parent_project_path ) {
148
+ require_once $this->glotpress_source_dir . '/gp-load.php';
149
+ require_once dirname(__FILE__) . '/makepot.php';
150
+ $makepot = new MakePOT;
151
+ $parent_project = GP::$project->by_path( $parent_project_path );
152
+ if ( !$parent_project ) {
153
+ echo "Couldn't find project with path $parent_project_path.\n";
154
+ return;
155
+ }
156
+ foreach( $this->importers as $importer ) {
157
+ $source = $makepot->get_first_lines( $this->s( $importer, '%trunk%/%importer%.php' ), $makepot->max_header_lines);
158
+ if ( !GP::$project->by_path( "$parent_project_path/$importer") ) {
159
+ $importer_project = GP::$project->create_and_select(array(
160
+ 'name' => $makepot->get_addon_header('Plugin Name', $source),
161
+ 'slug' => $importer,
162
+ 'description' => $makepot->get_addon_header('Description', $source),
163
+ 'parent_project_id' => $parent_project->id,
164
+ ));
165
+ } else {
166
+ echo "Project $parent_project_path/$importer already exists.\n";
167
+ }
168
+ if ( !GP::$project->by_path( "$parent_project_path/$importer/dev") ) {
169
+ $trunk_project = GP::$project->create_and_select(array(
170
+ 'name' => 'Development (trunk)',
171
+ 'slug' => 'dev',
172
+ 'description' => 'Development version of ' . $makepot->get_addon_header('Plugin Name', $source),
173
+ 'parent_project_id' => $importer_project->id,
174
+ 'source_url_template' => $this->s($importer, "http://plugins.trac.wordpress.org/browser/%importer%/trunk/%file%#L%line%"),
175
+ ));
176
+ } else {
177
+ echo "Project $parent_project_path/$importer/dev already exists.\n";
178
+ }
179
+ }
180
+ }
181
+
182
+ function import_glotpress_originals( $parent_project_path ) {
183
+ foreach( $this->importers as $importer ) {
184
+ system( $this->s( $importer, "php $this->glotpress_source_dir/scripts/import-originals.php -p $parent_project_path/%importer%/dev -f %trunk%/languages/%importer%.pot" ) );
185
+ }
186
+ }
187
+
188
+ function line_of_text( $line ) {
189
+ foreach( $this->importers as $importer ) {
190
+ echo $this->s( $importer, $line ) . "\n";
191
+ }
192
+ }
193
+ }
194
+ $importers_i18n = new ImportersI18n;
195
+ call_user_func_array( array( &$importers_i18n, $argv[1] ), array_slice( $argv, 2 ) );
util/wp-i18n/makepot.php ADDED
@@ -0,0 +1,561 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname( __FILE__ ) . '/not-gettexted.php';
3
+ require_once dirname( __FILE__ ) . '/pot-ext-meta.php';
4
+ require_once dirname( __FILE__ ) . '/extract/extract.php';
5
+
6
+ if ( !defined( 'STDERR' ) ) {
7
+ define( 'STDERR', fopen( 'php://stderr', 'w' ) );
8
+ }
9
+
10
+ class MakePOT {
11
+ var $max_header_lines = 30;
12
+
13
+ var $projects = array(
14
+ 'generic',
15
+ 'wp-frontend',
16
+ 'wp-admin',
17
+ 'wp-network-admin',
18
+ 'wp-core',
19
+ 'wp-ms',
20
+ 'wp-tz',
21
+ 'wp-plugin',
22
+ 'wp-theme',
23
+ 'bb',
24
+ 'mu',
25
+ 'bp',
26
+ 'rosetta',
27
+ 'wporg-bb-forums',
28
+ );
29
+
30
+ var $rules = array(
31
+ '_' => array('string'),
32
+ '__' => array('string'),
33
+ '_e' => array('string'),
34
+ '_c' => array('string'),
35
+ '_n' => array('singular', 'plural'),
36
+ '_n_noop' => array('singular', 'plural'),
37
+ '_nc' => array('singular', 'plural'),
38
+ '__ngettext' => array('singular', 'plural'),
39
+ '__ngettext_noop' => array('singular', 'plural'),
40
+ '_x' => array('string', 'context'),
41
+ '_ex' => array('string', 'context'),
42
+ '_nx' => array('singular', 'plural', null, 'context'),
43
+ '_nx_noop' => array('singular', 'plural', 'context'),
44
+ '_n_js' => array('singular', 'plural'),
45
+ '_nx_js' => array('singular', 'plural', 'context'),
46
+ 'esc_attr__' => array('string'),
47
+ 'esc_html__' => array('string'),
48
+ 'esc_attr_e' => array('string'),
49
+ 'esc_html_e' => array('string'),
50
+ 'esc_attr_x' => array('string', 'context'),
51
+ 'esc_html_x' => array('string', 'context'),
52
+ 'comments_number_link' => array('string', 'singular', 'plural'),
53
+ );
54
+
55
+ var $ms_files = array( 'ms-.*', '.*/ms-.*', '.*/my-.*', 'wp-activate\.php', 'wp-signup\.php', 'wp-admin/network\.php', 'wp-admin/includes/ms\.php', 'wp-admin/network/.*\.php', 'wp-admin/includes/class-wp-ms.*' );
56
+
57
+ var $temp_files = array();
58
+
59
+ var $meta = array(
60
+ 'default' => array(
61
+ 'from-code' => 'utf-8',
62
+ 'msgid-bugs-address' => 'http://wppolyglots.wordpress.com',
63
+ 'language' => 'php',
64
+ 'add-comments' => 'translators',
65
+ 'comments' => "Copyright (C) {year} {package-name}\nThis file is distributed under the same license as the {package-name} package.",
66
+ ),
67
+ 'generic' => array(),
68
+ 'wp-frontend' => array(
69
+ 'description' => 'Translation of frontend strings in WordPress {version}',
70
+ 'copyright-holder' => 'WordPress',
71
+ 'package-name' => 'WordPress',
72
+ 'package-version' => '{version}',
73
+ ),
74
+ 'wp-admin' => array(
75
+ 'description' => 'Translation of site admin strings in WordPress {version}',
76
+ 'copyright-holder' => 'WordPress',
77
+ 'package-name' => 'WordPress',
78
+ 'package-version' => '{version}',
79
+ ),
80
+ 'wp-network-admin' => array(
81
+ 'description' => 'Translation of network admin strings in WordPress {version}',
82
+ 'copyright-holder' => 'WordPress',
83
+ 'package-name' => 'WordPress',
84
+ 'package-version' => '{version}',
85
+ ),
86
+ 'wp-core' => array(
87
+ 'description' => 'Translation of WordPress {version}',
88
+ 'copyright-holder' => 'WordPress',
89
+ 'package-name' => 'WordPress',
90
+ 'package-version' => '{version}',
91
+ ),
92
+ 'wp-ms' => array(
93
+ 'description' => 'Translation of multisite strings in WordPress {version}',
94
+ 'copyright-holder' => 'WordPress',
95
+ 'package-name' => 'WordPress',
96
+ 'package-version' => '{version}',
97
+ ),
98
+ 'wp-tz' => array(
99
+ 'description' => 'Translation of timezone strings in WordPress {version}',
100
+ 'copyright-holder' => 'WordPress',
101
+ 'package-name' => 'WordPress',
102
+ 'package-version' => '{version}',
103
+ ),
104
+ 'bb' => array(
105
+ 'description' => 'Translation of bbPress',
106
+ 'copyright-holder' => 'bbPress',
107
+ 'package-name' => 'bbPress',
108
+ ),
109
+ 'wp-plugin' => array(
110
+ 'description' => 'Translation of the WordPress plugin {name} {version} by {author}',
111
+ 'msgid-bugs-address' => 'http://wordpress.org/tag/{slug}',
112
+ 'copyright-holder' => '{author}',
113
+ 'package-name' => '{name}',
114
+ 'package-version' => '{version}',
115
+ ),
116
+ 'wp-theme' => array(
117
+ 'description' => 'Translation of the WordPress theme {name} {version} by {author}',
118
+ 'msgid-bugs-address' => 'http://wordpress.org/tags/{slug}',
119
+ 'copyright-holder' => '{author}',
120
+ 'package-name' => '{name}',
121
+ 'package-version' => '{version}',
122
+ 'comments' => 'Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.',
123
+ ),
124
+ 'bp' => array(
125
+ 'description' => 'Translation of BuddyPress',
126
+ 'copyright-holder' => 'BuddyPress',
127
+ 'package-name' => 'BuddyPress',
128
+ ),
129
+ 'wporg-bb-forums' => array(
130
+ 'description' => 'WordPress.org International Forums',
131
+ 'copyright-holder' => 'WordPress',
132
+ 'package-name' => 'WordPress.org International Forums',
133
+ ),
134
+ 'rosetta' => array(
135
+ 'description' => 'Rosetta (.wordpress.org locale sites)',
136
+ 'copyright-holder' => 'WordPress',
137
+ 'package-name' => 'Rosetta',
138
+ ),
139
+ );
140
+
141
+ function __construct($deprecated = true) {
142
+ $this->extractor = new StringExtractor( $this->rules );
143
+ }
144
+
145
+ function __destruct() {
146
+ foreach ( $this->temp_files as $temp_file )
147
+ unlink( $temp_file );
148
+ }
149
+
150
+ function tempnam( $file ) {
151
+ $tempnam = tempnam( sys_get_temp_dir(), $file );
152
+ $this->temp_files[] = $tempnam;
153
+ return $tempnam;
154
+ }
155
+
156
+ function realpath_missing($path) {
157
+ return realpath(dirname($path)).DIRECTORY_SEPARATOR.basename($path);
158
+ }
159
+
160
+ function xgettext($project, $dir, $output_file, $placeholders = array(), $excludes = array(), $includes = array()) {
161
+ $meta = array_merge( $this->meta['default'], $this->meta[$project] );
162
+ $placeholders = array_merge( $meta, $placeholders );
163
+ $meta['output'] = $this->realpath_missing( $output_file );
164
+ $placeholders['year'] = date( 'Y' );
165
+ $placeholder_keys = array_map( create_function( '$x', 'return "{".$x."}";' ), array_keys( $placeholders ) );
166
+ $placeholder_values = array_values( $placeholders );
167
+ foreach($meta as $key => $value) {
168
+ $meta[$key] = str_replace($placeholder_keys, $placeholder_values, $value);
169
+ }
170
+
171
+ $originals = $this->extractor->extract_from_directory( $dir, $excludes, $includes );
172
+ $pot = new PO;
173
+ $pot->entries = $originals->entries;
174
+
175
+ $pot->set_header( 'Project-Id-Version', $meta['package-name'].' '.$meta['package-version'] );
176
+ $pot->set_header( 'Report-Msgid-Bugs-To', $meta['msgid-bugs-address'] );
177
+ $pot->set_header( 'POT-Creation-Date', gmdate( 'Y-m-d H:i:s+00:00' ) );
178
+ $pot->set_header( 'MIME-Version', '1.0' );
179
+ $pot->set_header( 'Content-Type', 'text/plain; charset=UTF-8' );
180
+ $pot->set_header( 'Content-Transfer-Encoding', '8bit' );
181
+ $pot->set_header( 'PO-Revision-Date', date( 'Y') . '-MO-DA HO:MI+ZONE' );
182
+ $pot->set_header( 'Last-Translator', 'FULL NAME <EMAIL@ADDRESS>' );
183
+ $pot->set_header( 'Language-Team', 'LANGUAGE <LL@li.org>' );
184
+ $pot->set_comment_before_headers( $meta['comments'] );
185
+ $pot->export_to_file( $output_file );
186
+ return true;
187
+ }
188
+
189
+ function wp_generic($dir, $args) {
190
+ $defaults = array(
191
+ 'project' => 'wp-core',
192
+ 'output' => null,
193
+ 'default_output' => 'wordpress.pot',
194
+ 'includes' => array(),
195
+ 'excludes' => array_merge(
196
+ array('wp-admin/includes/continents-cities\.php', 'wp-content/themes/twenty.*', ),
197
+ $this->ms_files
198
+ ),
199
+ 'extract_not_gettexted' => false,
200
+ 'not_gettexted_files_filter' => false,
201
+ );
202
+ $args = array_merge( $defaults, $args );
203
+ extract( $args );
204
+ $placeholders = array();
205
+ if ( $wp_version = $this->wp_version( $dir ) )
206
+ $placeholders['version'] = $wp_version;
207
+ else
208
+ return false;
209
+ $output = is_null( $output )? $default_output : $output;
210
+ $res = $this->xgettext( $project, $dir, $output, $placeholders, $excludes, $includes );
211
+ if ( !$res ) return false;
212
+
213
+ if ( $extract_not_gettexted ) {
214
+ $old_dir = getcwd();
215
+ $output = realpath( $output );
216
+ chdir( $dir );
217
+ $php_files = NotGettexted::list_php_files('.');
218
+ $php_files = array_filter( $php_files, $not_gettexted_files_filter );
219
+ $not_gettexted = new NotGettexted;
220
+ $res = $not_gettexted->command_extract( $output, $php_files );
221
+ chdir( $old_dir );
222
+ /* Adding non-gettexted strings can repeat some phrases */
223
+ $output_shell = escapeshellarg( $output );
224
+ system( "msguniq --use-first $output_shell -o $output_shell" );
225
+ }
226
+ return $res;
227
+ }
228
+
229
+ function wp_core($dir, $output) {
230
+ if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
231
+
232
+ return $this->wp_generic( $dir, array(
233
+ 'project' => 'wp-core', 'output' => $output,
234
+ 'extract_not_gettexted' => true,
235
+ 'not_gettexted_files_filter' => array( &$this, 'is_not_ms_file' ),
236
+ ) );
237
+ }
238
+
239
+ function wp_frontend($dir, $output) {
240
+ if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
241
+
242
+ return $this->wp_generic( $dir, array(
243
+ 'project' => 'wp-frontend', 'output' => $output,
244
+ 'includes' => array(), 'excludes' => array( 'wp-admin/.*', 'wp-content/themes/.*' ),
245
+ 'default_output' => 'wordpress.pot',
246
+ ) );
247
+ }
248
+
249
+ function wp_admin($dir, $output) {
250
+ if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
251
+
252
+ $frontend_pot = $this->tempnam( 'frontend.pot' );
253
+ if ( false === $frontend_pot ) return false;
254
+
255
+ $frontend_result = $this->wp_frontend( $dir, $frontend_pot );
256
+ if ( ! $frontend_result )
257
+ return false;
258
+
259
+ $result = $this->wp_generic( $dir, array(
260
+ 'project' => 'wp-admin', 'output' => $output,
261
+ 'includes' => array( 'wp-admin/.*' ), 'excludes' => array( 'wp-admin/includes/continents-cities\.php', 'wp-admin/network/.*', 'wp-admin/network.php' ),
262
+ 'default_output' => 'wordpress-admin.pot',
263
+ ) );
264
+
265
+ if ( ! $result )
266
+ return false;
267
+
268
+ $potextmeta = new PotExtMeta;
269
+ $result = $potextmeta->append( "$dir/wp-content/plugins/akismet/akismet.php", $output );
270
+ if ( ! $result )
271
+ return false;
272
+ $result = $potextmeta->append( "$dir/wp-content/plugins/hello.php", $output );
273
+ if ( ! $result )
274
+ return false;
275
+ /* Adding non-gettexted strings can repeat some phrases */
276
+ $output_shell = escapeshellarg($output);
277
+ system("msguniq $output_shell -o $output_shell");
278
+
279
+ $common_pot = $this->tempnam( 'common.pot' );
280
+ if ( ! $common_pot )
281
+ return false;
282
+ $admin_pot = realpath( is_null( $output ) ? 'wordpress-admin.pot' : $output );
283
+ system( "msgcat --more-than=1 --use-first $frontend_pot $admin_pot > $common_pot" );
284
+ system( "msgcat -u --use-first $admin_pot $common_pot -o $admin_pot" );
285
+ return true;
286
+ }
287
+
288
+ function wp_network_admin($dir, $output) {
289
+ if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
290
+
291
+ $frontend_pot = $this->tempnam( 'frontend.pot' );
292
+ if ( false === $frontend_pot ) return false;
293
+
294
+ $frontend_result = $this->wp_frontend( $dir, $frontend_pot );
295
+ if ( ! $frontend_result )
296
+ return false;
297
+
298
+ $admin_pot = $this->tempnam( 'admin.pot' );
299
+ if ( false === $admin_pot ) return false;
300
+
301
+ $admin_result = $this->wp_admin( $dir, $admin_pot );
302
+ if ( ! $admin_result )
303
+ return false;
304
+
305
+ $result = $this->wp_generic( $dir, array(
306
+ 'project' => 'wp-network-admin', 'output' => $output,
307
+ 'includes' => array( 'wp-admin/network/.*', 'wp-admin/network.php' ), 'excludes' => array(),
308
+ 'default_output' => 'wordpress-admin-network.pot',
309
+ ) );
310
+
311
+ if ( ! $result ) {
312
+ return false;
313
+ }
314
+
315
+ $common_pot = $this->tempnam( 'common.pot' );
316
+ if ( ! $common_pot )
317
+ return false;
318
+
319
+ $net_admin_pot = realpath( is_null( $output ) ? 'wordpress-network-admin.pot' : $output );
320
+ system( "msgcat --more-than=1 --use-first $frontend_pot $admin_pot $net_admin_pot > $common_pot" );
321
+ system( "msgcat -u --use-first $net_admin_pot $common_pot -o $net_admin_pot" );
322
+ return true;
323
+ }
324
+
325
+ function wp_ms($dir, $output) {
326
+ if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
327
+ if ( !is_file("$dir/wp-admin/ms-users.php") ) return false;
328
+ $core_pot = $this->tempnam( 'wordpress.pot' );
329
+ if ( false === $core_pot ) return false;
330
+ $core_result = $this->wp_core( $dir, $core_pot );
331
+ if ( ! $core_result )
332
+ return false;
333
+ $ms_result = $this->wp_generic( $dir, array(
334
+ 'project' => 'wp-ms', 'output' => $output,
335
+ 'includes' => $this->ms_files, 'excludes' => array(),
336
+ 'default_output' => 'wordpress-ms.pot',
337
+ 'extract_not_gettexted' => true,
338
+ 'not_gettexted_files_filter' => array( &$this, 'is_ms_file' ),
339
+ ) );
340
+ if ( !$ms_result ) {
341
+ return false;
342
+ }
343
+ $common_pot = $this->tempnam( 'common.pot' );
344
+ if ( ! $common_pot )
345
+ return false;
346
+ $ms_pot = realpath( is_null( $output )? 'wordpress-ms.pot' : $output );
347
+ system( "msgcat --more-than=1 --use-first $core_pot $ms_pot > $common_pot" );
348
+ system( "msgcat -u --use-first $ms_pot $common_pot -o $ms_pot" );
349
+ return true;
350
+ }
351
+
352
+ function wp_tz($dir, $output) {
353
+ $continents_path = 'wp-admin/includes/continents-cities.php';
354
+ if ( !file_exists( "$dir/$continents_path" ) ) return false;
355
+ return $this->wp_generic( $dir, array(
356
+ 'project' => 'wp-tz', 'output' => $output,
357
+ 'includes' => array($continents_path), 'excludes' => array(),
358
+ 'default_output' => 'wordpress-continents-cities.pot',
359
+ ) );
360
+ }
361
+
362
+ function wp_version($dir) {
363
+ $version_php = $dir.'/wp-includes/version.php';
364
+ if ( !is_readable( $version_php ) ) return false;
365
+ return preg_match( '/\$wp_version\s*=\s*\'(.*?)\';/', file_get_contents( $version_php ), $matches )? $matches[1] : false;
366
+ }
367
+
368
+
369
+ function mu($dir, $output) {
370
+ $placeholders = array();
371
+ if (preg_match('/\$wpmu_version\s*=\s*\'(.*?)\';/', file_get_contents($dir.'/wp-includes/version.php'), $matches)) {
372
+ $placeholders['version'] = $matches[1];
373
+ }
374
+ $output = is_null($output)? 'wordpress.pot' : $output;
375
+ return $this->xgettext('wp', $dir, $output, $placeholders);
376
+ }
377
+
378
+
379
+ function bb($dir, $output) {
380
+ $placeholders = array();
381
+ $output = is_null($output)? 'bbpress.pot' : $output;
382
+ return $this->xgettext('bb', $dir, $output, $placeholders);
383
+
384
+ }
385
+
386
+ function get_first_lines($filename, $lines = 30) {
387
+ $extf = fopen($filename, 'r');
388
+ if (!$extf) return false;
389
+ $first_lines = '';
390
+ foreach(range(1, $lines) as $x) {
391
+ $line = fgets($extf);
392
+ if (feof($extf)) break;
393
+ if (false === $line) {
394
+ return false;
395
+ }
396
+ $first_lines .= $line;
397
+ }
398
+ return $first_lines;
399
+ }
400
+
401
+
402
+ function get_addon_header($header, &$source) {
403
+ if (preg_match('|'.$header.':(.*)$|mi', $source, $matches))
404
+ return trim($matches[1]);
405
+ else
406
+ return false;
407
+ }
408
+
409
+ function generic($dir, $output) {
410
+ $output = is_null($output)? "generic.pot" : $output;
411
+ return $this->xgettext('generic', $dir, $output, array());
412
+ }
413
+
414
+ function guess_plugin_slug($dir) {
415
+ if ('trunk' == basename($dir)) {
416
+ $slug = basename(dirname($dir));
417
+ } elseif (in_array(basename(dirname($dir)), array('branches', 'tags'))) {
418
+ $slug = basename(dirname(dirname($dir)));
419
+ } else {
420
+ $slug = basename($dir);
421
+ }
422
+ return $slug;
423
+ }
424
+
425
+ function wp_plugin($dir, $output, $slug = null) {
426
+ $placeholders = array();
427
+ // guess plugin slug
428
+ if (is_null($slug)) {
429
+ $slug = $this->guess_plugin_slug($dir);
430
+ }
431
+ $main_file = $dir.'/'.$slug.'.php';
432
+ $source = $this->get_first_lines($main_file, $this->max_header_lines);
433
+
434
+ $placeholders['version'] = $this->get_addon_header('Version', $source);
435
+ $placeholders['author'] = $this->get_addon_header('Author', $source);
436
+ $placeholders['name'] = $this->get_addon_header('Plugin Name', $source);
437
+ $placeholders['slug'] = $slug;
438
+
439
+ $output = is_null($output)? "$slug.pot" : $output;
440
+ $res = $this->xgettext('wp-plugin', $dir, $output, $placeholders);
441
+ if (!$res) return false;
442
+ $potextmeta = new PotExtMeta;
443
+ $res = $potextmeta->append($main_file, $output);
444
+ /* Adding non-gettexted strings can repeat some phrases */
445
+ $output_shell = escapeshellarg($output);
446
+ system("msguniq $output_shell -o $output_shell");
447
+ return $res;
448
+ }
449
+
450
+ function wp_theme($dir, $output, $slug = null) {
451
+ $placeholders = array();
452
+ // guess plugin slug
453
+ if (is_null($slug)) {
454
+ $slug = $this->guess_plugin_slug($dir);
455
+ }
456
+ $main_file = $dir.'/style.css';
457
+ $source = $this->get_first_lines($main_file, $this->max_header_lines);
458
+
459
+ $placeholders['version'] = $this->get_addon_header('Version', $source);
460
+ $placeholders['author'] = $this->get_addon_header('Author', $source);
461
+ $placeholders['name'] = $this->get_addon_header('Theme Name', $source);
462
+ $placeholders['slug'] = $slug;
463
+
464
+ $license = $this->get_addon_header( 'License', $source );
465
+ if ( $license )
466
+ $this->meta['wp-theme']['comments'] = "Copyright (C) {year} {author}\nThis file is distributed under the {$license}.";
467
+ else
468
+ $this->meta['wp-theme']['comments'] = "Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.";
469
+
470
+ $output = is_null($output)? "$slug.pot" : $output;
471
+ $res = $this->xgettext('wp-theme', $dir, $output, $placeholders);
472
+ if (! $res )
473
+ return false;
474
+ $potextmeta = new PotExtMeta;
475
+ $res = $potextmeta->append( $main_file, $output, array( 'Theme Name', 'Theme URI', 'Description', 'Author', 'Author URI' ) );
476
+ if ( ! $res )
477
+ return false;
478
+ // If we're dealing with a pre-3.4 default theme, don't extract page templates before 3.4.
479
+ $extract_templates = ! in_array( $slug, array( 'twentyten', 'twentyeleven', 'default', 'classic' ) );
480
+ if ( ! $extract_templates ) {
481
+ $wp_dir = dirname( dirname( dirname( $dir ) ) );
482
+ $extract_templates = file_exists( "$wp_dir/wp-admin/user/about.php" ) || ! file_exists( "$wp_dir/wp-load.php" );
483
+ }
484
+ if ( $extract_templates ) {
485
+ $res = $potextmeta->append( $dir, $output, array( 'Template Name' ) );
486
+ if ( ! $res )
487
+ return false;
488
+ $files = scandir( $dir );
489
+ foreach ( $files as $file ) {
490
+ if ( '.' == $file[0] || 'CVS' == $file )
491
+ continue;
492
+ if ( is_dir( $dir . '/' . $file ) ) {
493
+ $res = $potextmeta->append( $dir . '/' . $file, $output, array( 'Template Name' ) );
494
+ if ( ! $res )
495
+ return false;
496
+ }
497
+ }
498
+ }
499
+ /* Adding non-gettexted strings can repeat some phrases */
500
+ $output_shell = escapeshellarg($output);
501
+ system("msguniq $output_shell -o $output_shell");
502
+ return $res;
503
+ }
504
+
505
+ function bp($dir, $output) {
506
+ $output = is_null($output)? "buddypress.pot" : $output;
507
+ return $this->xgettext('bp', $dir, $output, array(), array('bp-forums/bbpress/.*'));
508
+ }
509
+
510
+ function wporg_bb_forums( $dir, $output ) {
511
+ $output = is_null( $output ) ? 'wporg.pot' : $output;
512
+ return $this->xgettext( 'wporg-bb-forums', $dir, $output, array(), array(
513
+ 'bb-plugins/elfakismet/.*',
514
+ 'bb-plugins/support-forum/.*',
515
+ ) );
516
+ }
517
+
518
+ function rosetta( $dir, $output ) {
519
+ $output = is_null( $output )? 'rosetta.pot' : $output;
520
+ return $this->xgettext( 'rosetta', $dir, $output, array(), array(), array(
521
+ 'mu-plugins/rosetta.*\.php',
522
+ 'mu-plugins/rosetta/[^/]+\.php',
523
+ 'mu-plugins/rosetta/tmpl/.*\.php',
524
+ 'themes/rosetta/.*\.php',
525
+ ) );
526
+ }
527
+
528
+ function is_ms_file( $file_name ) {
529
+ $is_ms_file = false;
530
+ $prefix = substr( $file_name, 0, 2 ) === './'? '\./' : '';
531
+ foreach( $this->ms_files as $ms_file )
532
+ if ( preg_match( '|^'.$prefix.$ms_file.'$|', $file_name ) ) {
533
+ $is_ms_file = true;
534
+ break;
535
+ }
536
+ return $is_ms_file;
537
+ }
538
+
539
+ function is_not_ms_file( $file_name ) {
540
+ return !$this->is_ms_file( $file_name );
541
+ }
542
+ }
543
+
544
+ // run the CLI only if the file
545
+ // wasn't included
546
+ $included_files = get_included_files();
547
+ if ($included_files[0] == __FILE__) {
548
+ $makepot = new MakePOT;
549
+ if ((3 == count($argv) || 4 == count($argv)) && in_array($method = str_replace('-', '_', $argv[1]), get_class_methods($makepot))) {
550
+ $res = call_user_func(array(&$makepot, $method), realpath($argv[2]), isset($argv[3])? $argv[3] : null);
551
+ if (false === $res) {
552
+ fwrite(STDERR, "Couldn't generate POT file!\n");
553
+ }
554
+ } else {
555
+ $usage = "Usage: php makepot.php PROJECT DIRECTORY [OUTPUT]\n\n";
556
+ $usage .= "Generate POT file from the files in DIRECTORY [OUTPUT]\n";
557
+ $usage .= "Available projects: ".implode(', ', $makepot->projects)."\n";
558
+ fwrite(STDERR, $usage);
559
+ exit(1);
560
+ }
561
+ }
util/wp-i18n/not-gettexted.php ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Console application, which extracts or replaces strings for
4
+ * translation, which cannot be gettexted
5
+ *
6
+ * @version $Id: not-gettexted.php 19275 2012-02-10 17:47:42Z nacin $
7
+ * @package wordpress-i18n
8
+ * @subpackage tools
9
+ */
10
+ // see: http://php.net/tokenizer
11
+ if (!defined('T_ML_COMMENT'))
12
+ define('T_ML_COMMENT', T_COMMENT);
13
+ else
14
+ define('T_DOC_COMMENT', T_ML_COMMENT);
15
+
16
+ require_once dirname( __FILE__ ) . '/pomo/po.php';
17
+ require_once dirname( __FILE__ ) . '/pomo/mo.php';
18
+
19
+ class NotGettexted {
20
+ var $enable_logging = false;
21
+
22
+ var $STAGE_OUTSIDE = 0;
23
+ var $STAGE_START_COMMENT = 1;
24
+ var $STAGE_WHITESPACE_BEFORE = 2;
25
+ var $STAGE_STRING = 3;
26
+ var $STAGE_WHITESPACE_AFTER = 4;
27
+ var $STAGE_END_COMMENT = 4;
28
+
29
+ var $commands = array('extract' => 'command_extract', 'replace' => 'command_replace' );
30
+
31
+
32
+ function logmsg() {
33
+ $args = func_get_args();
34
+ if ($this->enable_logging) error_log(implode(' ', $args));
35
+ }
36
+
37
+ function stderr($msg, $nl=true) {
38
+ fwrite(STDERR, $msg.($nl? "\n" : ""));
39
+ }
40
+
41
+ function cli_die($msg) {
42
+ $this->stderr($msg);
43
+ exit(1);
44
+ }
45
+
46
+ function unchanged_token($token, $s='') {
47
+ return is_array($token)? $token[1] : $token;
48
+ }
49
+
50
+ function ignore_token($token, $s='') {
51
+ return '';
52
+ }
53
+
54
+ function list_php_files($dir) {
55
+ $files = array();
56
+ $items = scandir( $dir );
57
+ foreach ( (array) $items as $item ) {
58
+ $full_item = $dir . '/' . $item;
59
+ if ('.' == $item || '..' == $item)
60
+ continue;
61
+ if ('.php' == substr($item, -4))
62
+ $files[] = $full_item;
63
+ if (is_dir($full_item))
64
+ $files += array_merge($files, NotGettexted::list_php_files($full_item, $files));
65
+ }
66
+ return $files;
67
+ }
68
+
69
+
70
+ function make_string_aggregator($global_array_name, $filename) {
71
+ $a = $global_array_name;
72
+ return create_function('$string, $comment_id, $line_number', 'global $'.$a.'; $'.$a.'[] = array($string, $comment_id, '.var_export($filename, true).', $line_number);');
73
+ }
74
+
75
+ function make_mo_replacer($global_mo_name) {
76
+ $m = $global_mo_name;
77
+ return create_function('$token, $string', 'global $'.$m.'; return var_export($'.$m.'->translate($string), true);');
78
+ }
79
+
80
+ function walk_tokens(&$tokens, $string_action, $other_action, $register_action=null) {
81
+
82
+ $current_comment_id = '';
83
+ $current_string = '';
84
+ $current_string_line = 0;
85
+
86
+ $result = '';
87
+ $line = 1;
88
+
89
+ foreach($tokens as $token) {
90
+ if (is_array($token)) {
91
+ list($id, $text) = $token;
92
+ $line += substr_count($text, "\n");
93
+ if ((T_ML_COMMENT == $id || T_COMMENT == $id) && preg_match('|/\*\s*(/?WP_I18N_[a-z_]+)\s*\*/|i', $text, $matches)) {
94
+ if ($this->STAGE_OUTSIDE == $stage) {
95
+ $stage = $this->STAGE_START_COMMENT;
96
+ $current_comment_id = $matches[1];
97
+ $this->logmsg('start comment', $current_comment_id);
98
+ $result .= call_user_func($other_action, $token);
99
+ continue;
100
+ }
101
+ if ($this->STAGE_START_COMMENT <= $stage && $stage <= $this->STAGE_WHITESPACE_AFTER && '/'.$current_comment_id == $matches[1]) {
102
+ $stage = $this->STAGE_END_COMMENT;
103
+ $this->logmsg('end comment', $current_comment_id);
104
+ $result .= call_user_func($other_action, $token);
105
+ if (!is_null($register_action)) call_user_func($register_action, $current_string, $current_comment_id, $current_string_line);
106
+ continue;
107
+ }
108
+ } else if (T_CONSTANT_ENCAPSED_STRING == $id) {
109
+ if ($this->STAGE_START_COMMENT <= $stage && $stage < $this->STAGE_WHITESPACE_AFTER) {
110
+ eval('$current_string='.$text.';');
111
+ $this->logmsg('string', $current_string);
112
+ $current_string_line = $line;
113
+ $result .= call_user_func($string_action, $token, $current_string);
114
+ continue;
115
+ }
116
+ } else if (T_WHITESPACE == $id) {
117
+ if ($this->STAGE_START_COMMENT <= $stage && $stage < $this->STAGE_STRING) {
118
+ $stage = $this->STAGE_WHITESPACE_BEFORE;
119
+ $this->logmsg('whitespace before');
120
+ $result .= call_user_func($other_action, $token);
121
+ continue;
122
+ }
123
+ if ($this->STAGE_STRING < $stage && $stage < $this->STAGE_END_COMMENT) {
124
+ $stage = $this->STAGE_WHITESPACE_AFTER;
125
+ $this->logmsg('whitespace after');
126
+ $result .= call_user_func($other_action, $token);
127
+ continue;
128
+ }
129
+ }
130
+ }
131
+ $result .= call_user_func($other_action, $token);
132
+ $stage = $this->STAGE_OUTSIDE;
133
+ $current_comment_id = '';
134
+ $current_string = '';
135
+ $current_string_line = 0;
136
+ }
137
+ return $result;
138
+ }
139
+
140
+
141
+ function command_extract() {
142
+ $args = func_get_args();
143
+ $pot_filename = $args[0];
144
+ if (isset($args[1]) && is_array($args[1]))
145
+ $filenames = $args[1];
146
+ else
147
+ $filenames = array_slice($args, 1);
148
+
149
+ $global_name = '__entries_'.mt_rand(1, 1000);
150
+ $GLOBALS[$global_name] = array();
151
+
152
+ foreach($filenames as $filename) {
153
+ $tokens = token_get_all(file_get_contents($filename));
154
+ $aggregator = $this->make_string_aggregator($global_name, $filename);
155
+ $this->walk_tokens($tokens, array(&$this, 'ignore_token'), array(&$this, 'ignore_token'), $aggregator);
156
+ }
157
+
158
+ $potf = '-' == $pot_filename? STDOUT : @fopen($pot_filename, 'a');
159
+ if (false === $potf) {
160
+ $this->cli_die("Couldn't open pot file: $pot_filename");
161
+ }
162
+
163
+ foreach($GLOBALS[$global_name] as $item) {
164
+ @list($string, $comment_id, $filename, $line_number) = $item;
165
+ $filename = isset($filename)? preg_replace('|^\./|', '', $filename) : '';
166
+ $ref_line_number = isset($line_number)? ":$line_number" : '';
167
+ $args = array(
168
+ 'singular' => $string,
169
+ 'extracted_comments' => "Not gettexted string $comment_id",
170
+ 'references' => array("$filename$ref_line_number"),
171
+ );
172
+ $entry = new Translation_Entry($args);
173
+ fwrite($potf, "\n".PO::export_entry($entry)."\n");
174
+ }
175
+ if ('-' != $pot_filename) fclose($potf);
176
+ return true;
177
+ }
178
+
179
+ function command_replace() {
180
+ $args = func_get_args();
181
+ $mo_filename = $args[0];
182
+ if (isset($args[1]) && is_array($args[1]))
183
+ $filenames = $args[1];
184
+ else
185
+ $filenames = array_slice($args, 1);
186
+
187
+ $global_name = '__mo_'.mt_rand(1, 1000);
188
+ $GLOBALS[$global_name] = new MO();
189
+ $replacer = $this->make_mo_replacer($global_name);
190
+
191
+ $res = $GLOBALS[$global_name]->import_from_file($mo_filename);
192
+ if (false === $res) {
193
+ $this->cli_die("Couldn't read MO file '$mo_filename'!");
194
+ }
195
+ foreach($filenames as $filename) {
196
+ $source = file_get_contents($filename);
197
+ if ( strlen($source) > 150000 ) continue;
198
+ $tokens = token_get_all($source);
199
+ $new_file = $this->walk_tokens($tokens, $replacer, array(&$this, 'unchanged_token'));
200
+ $f = fopen($filename, 'w');
201
+ fwrite($f, $new_file);
202
+ fclose($f);
203
+ }
204
+ return true;
205
+ }
206
+
207
+ function usage() {
208
+ $this->stderr('php i18n-comments.php COMMAND OUTPUTFILE INPUTFILES');
209
+ $this->stderr('Extracts and replaces strings, which cannot be gettexted');
210
+ $this->stderr('Commands:');
211
+ $this->stderr(' extract POTFILE PHPFILES appends the strings to POTFILE');
212
+ $this->stderr(' replace MOFILE PHPFILES replaces strings in PHPFILES with translations from MOFILE');
213
+ }
214
+
215
+ function cli() {
216
+ global $argv, $commands;
217
+ if (count($argv) < 4 || !in_array($argv[1], array_keys($this->commands))) {
218
+ $this->usage();
219
+ exit(1);
220
+ }
221
+ call_user_func_array(array(&$this, $this->commands[$argv[1]]), array_slice($argv, 2));
222
+ }
223
+ }
224
+
225
+ // run the CLI only if the file
226
+ // wasn't included
227
+ $included_files = get_included_files();
228
+ if ($included_files[0] == __FILE__) {
229
+ error_reporting(E_ALL);
230
+ $not_gettexted = new NotGettexted;
231
+ $not_gettexted->cli();
232
+ }
233
+
234
+ ?>
util/wp-i18n/pomo/entry.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains Translation_Entry class
4
+ *
5
+ * @version $Id: entry.php 718 2012-10-31 00:32:02Z nbachiyski $
6
+ * @package pomo
7
+ * @subpackage entry
8
+ */
9
+
10
+ if ( !class_exists( 'Translation_Entry' ) ):
11
+ /**
12
+ * Translation_Entry class encapsulates a translatable string
13
+ */
14
+ class Translation_Entry {
15
+
16
+ /**
17
+ * Whether the entry contains a string and its plural form, default is false
18
+ *
19
+ * @var boolean
20
+ */
21
+ var $is_plural = false;
22
+
23
+ var $context = null;
24
+ var $singular = null;
25
+ var $plural = null;
26
+ var $translations = array();
27
+ var $translator_comments = '';
28
+ var $extracted_comments = '';
29
+ var $references = array();
30
+ var $flags = array();
31
+
32
+ /**
33
+ * @param array $args associative array, support following keys:
34
+ * - singular (string) -- the string to translate, if omitted and empty entry will be created
35
+ * - plural (string) -- the plural form of the string, setting this will set {@link $is_plural} to true
36
+ * - translations (array) -- translations of the string and possibly -- its plural forms
37
+ * - context (string) -- a string differentiating two equal strings used in different contexts
38
+ * - translator_comments (string) -- comments left by translators
39
+ * - extracted_comments (string) -- comments left by developers
40
+ * - references (array) -- places in the code this strings is used, in relative_to_root_path/file.php:linenum form
41
+ * - flags (array) -- flags like php-format
42
+ */
43
+ function Translation_Entry($args=array()) {
44
+ // if no singular -- empty object
45
+ if (!isset($args['singular'])) {
46
+ return;
47
+ }
48
+ // get member variable values from args hash
49
+ foreach ($args as $varname => $value) {
50
+ $this->$varname = $value;
51
+ }
52
+ if (isset($args['plural'])) $this->is_plural = true;
53
+ if (!is_array($this->translations)) $this->translations = array();
54
+ if (!is_array($this->references)) $this->references = array();
55
+ if (!is_array($this->flags)) $this->flags = array();
56
+ }
57
+
58
+ /**
59
+ * Generates a unique key for this entry
60
+ *
61
+ * @return string|bool the key or false if the entry is empty
62
+ */
63
+ function key() {
64
+ if (is_null($this->singular)) return false;
65
+ // prepend context and EOT, like in MO files
66
+ return is_null($this->context)? $this->singular : $this->context.chr(4).$this->singular;
67
+ }
68
+
69
+ function merge_with(&$other) {
70
+ $this->flags = array_unique( array_merge( $this->flags, $other->flags ) );
71
+ $this->references = array_unique( array_merge( $this->references, $other->references ) );
72
+ if ( $this->extracted_comments != $other->extracted_comments ) {
73
+ $this->extracted_comments .= $other->extracted_comments;
74
+ }
75
+
76
+ }
77
+ }
78
+ endif;
util/wp-i18n/pomo/mo.php ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class for working with MO files
4
+ *
5
+ * @version $Id: mo.php 718 2012-10-31 00:32:02Z nbachiyski $
6
+ * @package pomo
7
+ * @subpackage mo
8
+ */
9
+
10
+ require_once dirname(__FILE__) . '/translations.php';
11
+ require_once dirname(__FILE__) . '/streams.php';
12
+
13
+ if ( !class_exists( 'MO' ) ):
14
+ class MO extends Gettext_Translations {
15
+
16
+ var $_nplurals = 2;
17
+
18
+ /**
19
+ * Fills up with the entries from MO file $filename
20
+ *
21
+ * @param string $filename MO file to load
22
+ */
23
+ function import_from_file($filename) {
24
+ $reader = new POMO_FileReader($filename);
25
+ if (!$reader->is_resource())
26
+ return false;
27
+ return $this->import_from_reader($reader);
28
+ }
29
+
30
+ function export_to_file($filename) {
31
+ $fh = fopen($filename, 'wb');
32
+ if ( !$fh ) return false;
33
+ $res = $this->export_to_file_handle( $fh );
34
+ fclose($fh);
35
+ return $res;
36
+ }
37
+
38
+ function export() {
39
+ $tmp_fh = fopen("php://temp", 'r+');
40
+ if ( !$tmp_fh ) return false;
41
+ $this->export_to_file_handle( $tmp_fh );
42
+ rewind( $tmp_fh );
43
+ return stream_get_contents( $tmp_fh );
44
+ }
45
+
46
+ function is_entry_good_for_export( $entry ) {
47
+ if ( empty( $entry->translations ) ) {
48
+ return false;
49
+ }
50
+
51
+ if ( !array_filter( $entry->translations ) ) {
52
+ return false;
53
+ }
54
+
55
+ return true;
56
+ }
57
+
58
+ function export_to_file_handle($fh) {
59
+ $entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) );
60
+ ksort($entries);
61
+ $magic = 0x950412de;
62
+ $revision = 0;
63
+ $total = count($entries) + 1; // all the headers are one entry
64
+ $originals_lenghts_addr = 28;
65
+ $translations_lenghts_addr = $originals_lenghts_addr + 8 * $total;
66
+ $size_of_hash = 0;
67
+ $hash_addr = $translations_lenghts_addr + 8 * $total;
68
+ $current_addr = $hash_addr;
69
+ fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr,
70
+ $translations_lenghts_addr, $size_of_hash, $hash_addr));
71
+ fseek($fh, $originals_lenghts_addr);
72
+
73
+ // headers' msgid is an empty string
74
+ fwrite($fh, pack('VV', 0, $current_addr));
75
+ $current_addr++;
76
+ $originals_table = chr(0);
77
+
78
+ foreach($entries as $entry) {
79
+ $originals_table .= $this->export_original($entry) . chr(0);
80
+ $length = strlen($this->export_original($entry));
81
+ fwrite($fh, pack('VV', $length, $current_addr));
82
+ $current_addr += $length + 1; // account for the NULL byte after
83
+ }
84
+
85
+ $exported_headers = $this->export_headers();
86
+ fwrite($fh, pack('VV', strlen($exported_headers), $current_addr));
87
+ $current_addr += strlen($exported_headers) + 1;
88
+ $translations_table = $exported_headers . chr(0);
89
+
90
+ foreach($entries as $entry) {
91
+ $translations_table .= $this->export_translations($entry) . chr(0);
92
+ $length = strlen($this->export_translations($entry));
93
+ fwrite($fh, pack('VV', $length, $current_addr));
94
+ $current_addr += $length + 1;
95
+ }
96
+
97
+ fwrite($fh, $originals_table);
98
+ fwrite($fh, $translations_table);
99
+ return true;
100
+ }
101
+
102
+ function export_original($entry) {
103
+ //TODO: warnings for control characters
104
+ $exported = $entry->singular;
105
+ if ($entry->is_plural) $exported .= chr(0).$entry->plural;
106
+ if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported;
107
+ return $exported;
108
+ }
109
+
110
+ function export_translations($entry) {
111
+ //TODO: warnings for control characters
112
+ return implode(chr(0), $entry->translations);
113
+ }
114
+
115
+ function export_headers() {
116
+ $exported = '';
117
+ foreach($this->headers as $header => $value) {
118
+ $exported.= "$header: $value\n";
119
+ }
120
+ return $exported;
121
+ }
122
+
123
+ function get_byteorder($magic) {
124
+ // The magic is 0x950412de
125
+
126
+ // bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
127
+ $magic_little = (int) - 1794895138;
128
+ $magic_little_64 = (int) 2500072158;
129
+ // 0xde120495
130
+ $magic_big = ((int) - 569244523) & 0xFFFFFFFF;
131
+ if ($magic_little == $magic || $magic_little_64 == $magic) {
132
+ return 'little';
133
+ } else if ($magic_big == $magic) {
134
+ return 'big';
135
+ } else {
136
+ return false;
137
+ }
138
+ }
139
+
140
+ function import_from_reader($reader) {
141
+ $endian_string = MO::get_byteorder($reader->readint32());
142
+ if (false === $endian_string) {
143
+ return false;
144
+ }
145
+ $reader->setEndian($endian_string);
146
+
147
+ $endian = ('big' == $endian_string)? 'N' : 'V';
148
+
149
+ $header = $reader->read(24);
150
+ if ($reader->strlen($header) != 24)
151
+ return false;
152
+
153
+ // parse header
154
+ $header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header);
155
+ if (!is_array($header))
156
+ return false;
157
+
158
+ extract( $header );
159
+
160
+ // support revision 0 of MO format specs, only
161
+ if ($revision != 0)
162
+ return false;
163
+
164
+ // seek to data blocks
165
+ $reader->seekto($originals_lenghts_addr);
166
+
167
+ // read originals' indices
168
+ $originals_lengths_length = $translations_lenghts_addr - $originals_lenghts_addr;
169
+ if ( $originals_lengths_length != $total * 8 )
170
+ return false;
171
+
172
+ $originals = $reader->read($originals_lengths_length);
173
+ if ( $reader->strlen( $originals ) != $originals_lengths_length )
174
+ return false;
175
+
176
+ // read translations' indices
177
+ $translations_lenghts_length = $hash_addr - $translations_lenghts_addr;
178
+ if ( $translations_lenghts_length != $total * 8 )
179
+ return false;
180
+
181
+ $translations = $reader->read($translations_lenghts_length);
182
+ if ( $reader->strlen( $translations ) != $translations_lenghts_length )
183
+ return false;
184
+
185
+ // transform raw data into set of indices
186
+ $originals = $reader->str_split( $originals, 8 );
187
+ $translations = $reader->str_split( $translations, 8 );
188
+
189
+ // skip hash table
190
+ $strings_addr = $hash_addr + $hash_length * 4;
191
+
192
+ $reader->seekto($strings_addr);
193
+
194
+ $strings = $reader->read_all();
195
+ $reader->close();
196
+
197
+ for ( $i = 0; $i < $total; $i++ ) {
198
+ $o = unpack( "{$endian}length/{$endian}pos", $originals[$i] );
199
+ $t = unpack( "{$endian}length/{$endian}pos", $translations[$i] );
200
+ if ( !$o || !$t ) return false;
201
+
202
+ // adjust offset due to reading strings to separate space before
203
+ $o['pos'] -= $strings_addr;
204
+ $t['pos'] -= $strings_addr;
205
+
206
+ $original = $reader->substr( $strings, $o['pos'], $o['length'] );
207
+ $translation = $reader->substr( $strings, $t['pos'], $t['length'] );
208
+
209
+ if ('' === $original) {
210
+ $this->set_headers($this->make_headers($translation));
211
+ } else {
212
+ $entry = &$this->make_entry($original, $translation);
213
+ $this->entries[$entry->key()] = &$entry;
214
+ }
215
+ }
216
+ return true;
217
+ }
218
+
219
+ /**
220
+ * Build a Translation_Entry from original string and translation strings,
221
+ * found in a MO file
222
+ *
223
+ * @static
224
+ * @param string $original original string to translate from MO file. Might contain
225
+ * 0x04 as context separator or 0x00 as singular/plural separator
226
+ * @param string $translation translation string from MO file. Might contain
227
+ * 0x00 as a plural translations separator
228
+ */
229
+ function &make_entry($original, $translation) {
230
+ $entry = new Translation_Entry();
231
+ // look for context
232
+ $parts = explode(chr(4), $original);
233
+ if (isset($parts[1])) {
234
+ $original = $parts[1];
235
+ $entry->context = $parts[0];
236
+ }
237
+ // look for plural original
238
+ $parts = explode(chr(0), $original);
239
+ $entry->singular = $parts[0];
240
+ if (isset($parts[1])) {
241
+ $entry->is_plural = true;
242
+ $entry->plural = $parts[1];
243
+ }
244
+ // plural translations are also separated by \0
245
+ $entry->translations = explode(chr(0), $translation);
246
+ return $entry;
247
+ }
248
+
249
+ function select_plural_form($count) {
250
+ return $this->gettext_select_plural_form($count);
251
+ }
252
+
253
+ function get_plural_forms_count() {
254
+ return $this->_nplurals;
255
+ }
256
+ }
257
+ endif;
util/wp-i18n/pomo/po.php ADDED
@@ -0,0 +1,384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class for working with PO files
4
+ *
5
+ * @version $Id: po.php 718 2012-10-31 00:32:02Z nbachiyski $
6
+ * @package pomo
7
+ * @subpackage po
8
+ */
9
+
10
+ require_once dirname(__FILE__) . '/translations.php';
11
+
12
+ define('PO_MAX_LINE_LEN', 79);
13
+
14
+ ini_set('auto_detect_line_endings', 1);
15
+
16
+ /**
17
+ * Routines for working with PO files
18
+ */
19
+ if ( !class_exists( 'PO' ) ):
20
+ class PO extends Gettext_Translations {
21
+
22
+ var $comments_before_headers = '';
23
+
24
+ /**
25
+ * Exports headers to a PO entry
26
+ *
27
+ * @return string msgid/msgstr PO entry for this PO file headers, doesn't contain newline at the end
28
+ */
29
+ function export_headers() {
30
+ $header_string = '';
31
+ foreach($this->headers as $header => $value) {
32
+ $header_string.= "$header: $value\n";
33
+ }
34
+ $poified = PO::poify($header_string);
35
+ if ($this->comments_before_headers)
36
+ $before_headers = $this->prepend_each_line(rtrim($this->comments_before_headers)."\n", '# ');
37
+ else
38
+ $before_headers = '';
39
+ return rtrim("{$before_headers}msgid \"\"\nmsgstr $poified");
40
+ }
41
+
42
+ /**
43
+ * Exports all entries to PO format
44
+ *
45
+ * @return string sequence of mgsgid/msgstr PO strings, doesn't containt newline at the end
46
+ */
47
+ function export_entries() {
48
+ //TODO sorting
49
+ return implode("\n\n", array_map(array('PO', 'export_entry'), $this->entries));
50
+ }
51
+
52
+ /**
53
+ * Exports the whole PO file as a string
54
+ *
55
+ * @param bool $include_headers whether to include the headers in the export
56
+ * @return string ready for inclusion in PO file string for headers and all the enrtries
57
+ */
58
+ function export($include_headers = true) {
59
+ $res = '';
60
+ if ($include_headers) {
61
+ $res .= $this->export_headers();
62
+ $res .= "\n\n";
63
+ }
64
+ $res .= $this->export_entries();
65
+ return $res;
66
+ }
67
+
68
+ /**
69
+ * Same as {@link export}, but writes the result to a file
70
+ *
71
+ * @param string $filename where to write the PO string
72
+ * @param bool $include_headers whether to include tje headers in the export
73
+ * @return bool true on success, false on error
74
+ */
75
+ function export_to_file($filename, $include_headers = true) {
76
+ $fh = fopen($filename, 'w');
77
+ if (false === $fh) return false;
78
+ $export = $this->export($include_headers);
79
+ $res = fwrite($fh, $export);
80
+ if (false === $res) return false;
81
+ return fclose($fh);
82
+ }
83
+
84
+ /**
85
+ * Text to include as a comment before the start of the PO contents
86
+ *
87
+ * Doesn't need to include # in the beginning of lines, these are added automatically
88
+ */
89
+ function set_comment_before_headers( $text ) {
90
+ $this->comments_before_headers = $text;
91
+ }
92
+
93
+ /**
94
+ * Formats a string in PO-style
95
+ *
96
+ * @static
97
+ * @param string $string the string to format
98
+ * @return string the poified string
99
+ */
100
+ function poify($string) {
101
+ $quote = '"';
102
+ $slash = '\\';
103
+ $newline = "\n";
104
+
105
+ $replaces = array(
106
+ "$slash" => "$slash$slash",
107
+ "$quote" => "$slash$quote",
108
+ "\t" => '\t',
109
+ );
110
+
111
+ $string = str_replace(array_keys($replaces), array_values($replaces), $string);
112
+
113
+ $po = $quote.implode("${slash}n$quote$newline$quote", explode($newline, $string)).$quote;
114
+ // add empty string on first line for readbility
115
+ if (false !== strpos($string, $newline) &&
116
+ (substr_count($string, $newline) > 1 || !($newline === substr($string, -strlen($newline))))) {
117
+ $po = "$quote$quote$newline$po";
118
+ }
119
+ // remove empty strings
120
+ $po = str_replace("$newline$quote$quote", '', $po);
121
+ return $po;
122
+ }
123
+
124
+ /**
125
+ * Gives back the original string from a PO-formatted string
126
+ *
127
+ * @static
128
+ * @param string $string PO-formatted string
129
+ * @return string enascaped string
130
+ */
131
+ function unpoify($string) {
132
+ $escapes = array('t' => "\t", 'n' => "\n", '\\' => '\\');
133
+ $lines = array_map('trim', explode("\n", $string));
134
+ $lines = array_map(array('PO', 'trim_quotes'), $lines);
135
+ $unpoified = '';
136
+ $previous_is_backslash = false;
137
+ foreach($lines as $line) {
138
+ preg_match_all('/./u', $line, $chars);
139
+ $chars = $chars[0];
140
+ foreach($chars as $char) {
141
+ if (!$previous_is_backslash) {
142
+ if ('\\' == $char)
143
+ $previous_is_backslash = true;
144
+ else
145
+ $unpoified .= $char;
146
+ } else {
147
+ $previous_is_backslash = false;
148
+ $unpoified .= isset($escapes[$char])? $escapes[$char] : $char;
149
+ }
150
+ }
151
+ }
152
+ return $unpoified;
153
+ }
154
+
155
+ /**
156
+ * Inserts $with in the beginning of every new line of $string and
157
+ * returns the modified string
158
+ *
159
+ * @static
160
+ * @param string $string prepend lines in this string
161
+ * @param string $with prepend lines with this string
162
+ */
163
+ function prepend_each_line($string, $with) {
164
+ $php_with = var_export($with, true);
165
+ $lines = explode("\n", $string);
166
+ // do not prepend the string on the last empty line, artefact by explode
167
+ if ("\n" == substr($string, -1)) unset($lines[count($lines) - 1]);
168
+ $res = implode("\n", array_map(create_function('$x', "return $php_with.\$x;"), $lines));
169
+ // give back the empty line, we ignored above
170
+ if ("\n" == substr($string, -1)) $res .= "\n";
171
+ return $res;
172
+ }
173
+
174
+ /**
175
+ * Prepare a text as a comment -- wraps the lines and prepends #
176
+ * and a special character to each line
177
+ *
178
+ * @access private
179
+ * @param string $text the comment text
180
+ * @param string $char character to denote a special PO comment,
181
+ * like :, default is a space
182
+ */
183
+ function comment_block($text, $char=' ') {
184
+ $text = wordwrap($text, PO_MAX_LINE_LEN - 3);
185
+ return PO::prepend_each_line($text, "#$char ");
186
+ }
187
+
188
+ /**
189
+ * Builds a string from the entry for inclusion in PO file
190
+ *
191
+ * @static
192
+ * @param object &$entry the entry to convert to po string
193
+ * @return string|bool PO-style formatted string for the entry or
194
+ * false if the entry is empty
195
+ */
196
+ function export_entry(&$entry) {
197
+ if (is_null($entry->singular)) return false;
198
+ $po = array();
199
+ if (!empty($entry->translator_comments)) $po[] = PO::comment_block($entry->translator_comments);
200
+ if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.');
201
+ if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':');
202
+ if (!empty($entry->flags)) $po[] = PO::comment_block(implode(", ", $entry->flags), ',');
203
+ if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context);
204
+ $po[] = 'msgid '.PO::poify($entry->singular);
205
+ if (!$entry->is_plural) {
206
+ $translation = empty($entry->translations)? '' : $entry->translations[0];
207
+ $po[] = 'msgstr '.PO::poify($translation);
208
+ } else {
209
+ $po[] = 'msgid_plural '.PO::poify($entry->plural);
210
+ $translations = empty($entry->translations)? array('', '') : $entry->translations;
211
+ foreach($translations as $i => $translation) {
212
+ $po[] = "msgstr[$i] ".PO::poify($translation);
213
+ }
214
+ }
215
+ return implode("\n", $po);
216
+ }
217
+
218
+ function import_from_file($filename) {
219
+ $f = fopen($filename, 'r');
220
+ if (!$f) return false;
221
+ $lineno = 0;
222
+ while (true) {
223
+ $res = $this->read_entry($f, $lineno);
224
+ if (!$res) break;
225
+ if ($res['entry']->singular == '') {
226
+ $this->set_headers($this->make_headers($res['entry']->translations[0]));
227
+ } else {
228
+ $this->add_entry($res['entry']);
229
+ }
230
+ }
231
+ PO::read_line($f, 'clear');
232
+ if ( false === $res ) {
233
+ return false;
234
+ }
235
+ if ( ! $this->headers && ! $this->entries ) {
236
+ return false;
237
+ }
238
+ return true;
239
+ }
240
+
241
+ function read_entry($f, $lineno = 0) {
242
+ $entry = new Translation_Entry();
243
+ // where were we in the last step
244
+ // can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural
245
+ $context = '';
246
+ $msgstr_index = 0;
247
+ $is_final = create_function('$context', 'return $context == "msgstr" || $context == "msgstr_plural";');
248
+ while (true) {
249
+ $lineno++;
250
+ $line = PO::read_line($f);
251
+ if (!$line) {
252
+ if (feof($f)) {
253
+ if ($is_final($context))
254
+ break;
255
+ elseif (!$context) // we haven't read a line and eof came
256
+ return null;
257
+ else
258
+ return false;
259
+ } else {
260
+ return false;
261
+ }
262
+ }
263
+ if ($line == "\n") continue;
264
+ $line = trim($line);
265
+ if (preg_match('/^#/', $line, $m)) {
266
+ // the comment is the start of a new entry
267
+ if ($is_final($context)) {
268
+ PO::read_line($f, 'put-back');
269
+ $lineno--;
270
+ break;
271
+ }
272
+ // comments have to be at the beginning
273
+ if ($context && $context != 'comment') {
274
+ return false;
275
+ }
276
+ // add comment
277
+ $this->add_comment_to_entry($entry, $line);;
278
+ } elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
279
+ if ($is_final($context)) {
280
+ PO::read_line($f, 'put-back');
281
+ $lineno--;
282
+ break;
283
+ }
284
+ if ($context && $context != 'comment') {
285
+ return false;
286
+ }
287
+ $context = 'msgctxt';
288
+ $entry->context .= PO::unpoify($m[1]);
289
+ } elseif (preg_match('/^msgid\s+(".*")/', $line, $m)) {
290
+ if ($is_final($context)) {
291
+ PO::read_line($f, 'put-back');
292
+ $lineno--;
293
+ break;
294
+ }
295
+ if ($context && $context != 'msgctxt' && $context != 'comment') {
296
+ return false;
297
+ }
298
+ $context = 'msgid';
299
+ $entry->singular .= PO::unpoify($m[1]);
300
+ } elseif (preg_match('/^msgid_plural\s+(".*")/', $line, $m)) {
301
+ if ($context != 'msgid') {
302
+ return false;
303
+ }
304
+ $context = 'msgid_plural';
305
+ $entry->is_plural = true;
306
+ $entry->plural .= PO::unpoify($m[1]);
307
+ } elseif (preg_match('/^msgstr\s+(".*")/', $line, $m)) {
308
+ if ($context != 'msgid') {
309
+ return false;
310
+ }
311
+ $context = 'msgstr';
312
+ $entry->translations = array(PO::unpoify($m[1]));
313
+ } elseif (preg_match('/^msgstr\[(\d+)\]\s+(".*")/', $line, $m)) {
314
+ if ($context != 'msgid_plural' && $context != 'msgstr_plural') {
315
+ return false;
316
+ }
317
+ $context = 'msgstr_plural';
318
+ $msgstr_index = $m[1];
319
+ $entry->translations[$m[1]] = PO::unpoify($m[2]);
320
+ } elseif (preg_match('/^".*"$/', $line)) {
321
+ $unpoified = PO::unpoify($line);
322
+ switch ($context) {
323
+ case 'msgid':
324
+ $entry->singular .= $unpoified; break;
325
+ case 'msgctxt':
326
+ $entry->context .= $unpoified; break;
327
+ case 'msgid_plural':
328
+ $entry->plural .= $unpoified; break;
329
+ case 'msgstr':
330
+ $entry->translations[0] .= $unpoified; break;
331
+ case 'msgstr_plural':
332
+ $entry->translations[$msgstr_index] .= $unpoified; break;
333
+ default:
334
+ return false;
335
+ }
336
+ } else {
337
+ return false;
338
+ }
339
+ }
340
+ if (array() == array_filter($entry->translations, create_function('$t', 'return $t || "0" === $t;'))) {
341
+ $entry->translations = array();
342
+ }
343
+ return array('entry' => $entry, 'lineno' => $lineno);
344
+ }
345
+
346
+ function read_line($f, $action = 'read') {
347
+ static $last_line = '';
348
+ static $use_last_line = false;
349
+ if ('clear' == $action) {
350
+ $last_line = '';
351
+ return true;
352
+ }
353
+ if ('put-back' == $action) {
354
+ $use_last_line = true;
355
+ return true;
356
+ }
357
+ $line = $use_last_line? $last_line : fgets($f);
358
+ $line = gp_endswith( $line, "\r\n" )? rtrim( $line, "\r\n" ) . "\n" : $line;
359
+ $last_line = $line;
360
+ $use_last_line = false;
361
+ return $line;
362
+ }
363
+
364
+ function add_comment_to_entry(&$entry, $po_comment_line) {
365
+ $first_two = substr($po_comment_line, 0, 2);
366
+ $comment = trim(substr($po_comment_line, 2));
367
+ if ('#:' == $first_two) {
368
+ $entry->references = array_merge($entry->references, preg_split('/\s+/', $comment));
369
+ } elseif ('#.' == $first_two) {
370
+ $entry->extracted_comments = trim($entry->extracted_comments . "\n" . $comment);
371
+ } elseif ('#,' == $first_two) {
372
+ $entry->flags = array_merge($entry->flags, preg_split('/,\s*/', $comment));
373
+ } else {
374
+ $entry->translator_comments = trim($entry->translator_comments . "\n" . $comment);
375
+ }
376
+ }
377
+
378
+ function trim_quotes($s) {
379
+ if ( substr($s, 0, 1) == '"') $s = substr($s, 1);
380
+ if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1);
381
+ return $s;
382
+ }
383
+ }
384
+ endif;
util/wp-i18n/pomo/sample/app.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once '../translations.php';
4
+ require_once '../mo.php';
5
+
6
+
7
+ function __($text, $domain = 'default') {
8
+ $translations = &get_translations($domain);
9
+ return $translations->translate($text);
10
+ }
11
+
12
+ function _e($text, $domain = 'default') {
13
+ $translations = &get_translations($domain);
14
+ echo $translations->translate($text);
15
+ }
16
+
17
+ function __n($singular, $plural, $count, $domain = 'default') {
18
+ $translations = &get_translations($domain);
19
+ return $translations->translate_plural($singular, $plural, $count);
20
+ }
21
+
22
+ function &load_translations($mo_filename) {
23
+ if (is_readable($mo_filename)) {
24
+ $translations = new MO();
25
+ $translations->import_from_file($mo_filename);
26
+ } else {
27
+ $translations = new Translations();
28
+ }
29
+ return $translations;
30
+ }
31
+
32
+ // get the locale from somewhere: subomain, config, GET var, etc.
33
+ // it can be safely empty
34
+ $locale = 'bg';
35
+ $translations = array();
36
+ $empty_translations = & new Translations();
37
+
38
+ function load_textdomain($domain, $mofile) {
39
+ global $translations;
40
+ $translations[$domain] = &load_translations($mofile);
41
+ }
42
+
43
+ function &get_translations($domain) {
44
+ global $translations, $empty_translations;
45
+ return isset($translations[$domain])? $translations[$domain] : $empty_translations;
46
+ }
47
+
48
+ // load the translations
49
+ load_textdomain('default', "languages/$locale.mo");
50
+ load_textdomain('side', "languages/$locale-side.mo");
51
+
52
+ //here comes the real app
53
+ $user = 'apok';
54
+ $messages = rand(0, 2);
55
+
56
+ printf(__('Welcome %s!')."\n", $user);
57
+
58
+ printf(__n('You have one new message.', 'You have %s new messages.', $messages)."\n", $messages);
59
+
60
+ echo __("A string with low priority!", 'side')."\n";
61
+
62
+ _e("Bye\n");
63
+ ?>
util/wp-i18n/pomo/sample/languages/app-side.pot ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SOME DESCRIPTIVE TITLE.
2
+ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
+ # This file is distributed under the same license as the PACKAGE package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PACKAGE VERSION\n"
10
+ "Report-Msgid-Bugs-To: wp-polyglots@lists.automattic.com\n"
11
+ "POT-Creation-Date: 2008-06-06 23:10+0300\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=CHARSET\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
+
20
+ msgid "A string with low priority!"
21
+ msgstr ""
util/wp-i18n/pomo/sample/languages/app.pot ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SOME DESCRIPTIVE TITLE.
2
+ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
+ # This file is distributed under the same license as the PACKAGE package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PACKAGE VERSION\n"
10
+ "Report-Msgid-Bugs-To: wp-polyglots@lists.automattic.com\n"
11
+ "POT-Creation-Date: 2008-06-06 23:10+0300\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=CHARSET\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
+
20
+ #: app.php:46
21
+ #, php-format
22
+ msgid "Welcome %s!"
23
+ msgstr ""
24
+
25
+ #: app.php:48
26
+ #, php-format
27
+ msgid "You have one new message."
28
+ msgid_plural "You have %s new messages."
29
+ msgstr[0] ""
30
+ msgstr[1] ""
31
+
32
+ #: app.php:50
33
+ msgid "Bye\n"
34
+ msgstr ""
util/wp-i18n/pomo/sample/languages/bg-side.mo ADDED
Binary file
util/wp-i18n/pomo/sample/languages/bg-side.po ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bulgarian translations for PACKAGE package.
2
+ # Copyright (C) 2008 THE PACKAGE'S COPYRIGHT HOLDER
3
+ # This file is distributed under the same license as the PACKAGE package.
4
+ # Nikolay Bachiyski <nb@nikolay.bg>, 2008.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: PACKAGE VERSION\n"
9
+ "Report-Msgid-Bugs-To: wp-polyglots@lists.automattic.com\n"
10
+ "POT-Creation-Date: 2008-06-06 23:10+0300\n"
11
+ "PO-Revision-Date: 2008-06-06 22:54+0300\n"
12
+ "Last-Translator: Nikolay Bachiyski <nb@nikolay.bg>\n"
13
+ "Language-Team: Bulgarian\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=UTF-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+
18
+ msgid "A string with low priority!"
19
+ msgstr "Смотан низ!"
util/wp-i18n/pomo/sample/languages/bg.mo ADDED
Binary file
util/wp-i18n/pomo/sample/languages/bg.po ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bulgarian translations for PACKAGE package.
2
+ # Copyright (C) 2008 THE PACKAGE'S COPYRIGHT HOLDER
3
+ # This file is distributed under the same license as the PACKAGE package.
4
+ # Nikolay Bachiyski <nb@nikolay.bg>, 2008.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: PACKAGE VERSION\n"
9
+ "Report-Msgid-Bugs-To: wp-polyglots@lists.automattic.com\n"
10
+ "POT-Creation-Date: 2008-06-06 23:10+0300\n"
11
+ "PO-Revision-Date: 2008-06-06 22:54+0300\n"
12
+ "Last-Translator: Nikolay Bachiyski <nb@nikolay.bg>\n"
13
+ "Language-Team: Bulgarian\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=UTF-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+
18
+ #: app.php:46
19
+ #, php-format
20
+ msgid "Welcome %s!"
21
+ msgstr "Добре дошъл, %s!"
22
+
23
+ #: app.php:48
24
+ #, php-format
25
+ msgid "You have one new message."
26
+ msgid_plural "You have %s new messages."
27
+ msgstr[0] "Имате едно ново съобщение."
28
+ msgstr[1] "Имате %s нови съобщения."
29
+
30
+ #: app.php:50
31
+ msgid "Bye\n"
32
+ msgstr "Чао\n"
util/wp-i18n/pomo/streams.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Classes, which help reading streams of data from files.
4
+ * Based on the classes from Danilo Segan <danilo@kvota.net>
5
+ *
6
+ * @version $Id: streams.php 718 2012-10-31 00:32:02Z nbachiyski $
7
+ * @package pomo
8
+ * @subpackage streams
9
+ */
10
+
11
+ if ( !class_exists( 'POMO_Reader' ) ):
12
+ class POMO_Reader {
13
+
14
+ var $endian = 'little';
15
+ var $_post = '';
16
+
17
+ function POMO_Reader() {
18
+ $this->is_overloaded = ((ini_get("mbstring.func_overload") & 2) != 0) && function_exists('mb_substr');
19
+ $this->_pos = 0;
20
+ }
21
+
22
+ /**
23
+ * Sets the endianness of the file.
24
+ *
25
+ * @param $endian string 'big' or 'little'
26
+ */
27
+ function setEndian($endian) {
28
+ $this->endian = $endian;
29
+ }
30
+
31
+ /**
32
+ * Reads a 32bit Integer from the Stream
33
+ *
34
+ * @return mixed The integer, corresponding to the next 32 bits from
35
+ * the stream of false if there are not enough bytes or on error
36
+ */
37
+ function readint32() {
38
+ $bytes = $this->read(4);
39
+ if (4 != $this->strlen($bytes))
40
+ return false;
41
+ $endian_letter = ('big' == $this->endian)? 'N' : 'V';
42
+ $int = unpack($endian_letter, $bytes);
43
+ return array_shift($int);
44
+ }
45
+
46
+ /**
47
+ * Reads an array of 32-bit Integers from the Stream
48
+ *
49
+ * @param integer count How many elements should be read
50
+ * @return mixed Array of integers or false if there isn't
51
+ * enough data or on error
52
+ */
53
+ function readint32array($count) {
54
+ $bytes = $this->read(4 * $count);
55
+ if (4*$count != $this->strlen($bytes))
56
+ return false;
57
+ $endian_letter = ('big' == $this->endian)? 'N' : 'V';
58
+ return unpack($endian_letter.$count, $bytes);
59
+ }
60
+
61
+
62
+ function substr($string, $start, $length) {
63
+ if ($this->is_overloaded) {
64
+ return mb_substr($string, $start, $length, 'ascii');
65
+ } else {
66
+ return substr($string, $start, $length);
67
+ }
68
+ }
69
+
70
+ function strlen($string) {
71
+ if ($this->is_overloaded) {
72
+ return mb_strlen($string, 'ascii');
73
+ } else {
74
+ return strlen($string);
75
+ }
76
+ }
77
+
78
+ function str_split($string, $chunk_size) {
79
+ if (!function_exists('str_split')) {
80
+ $length = $this->strlen($string);
81
+ $out = array();
82
+ for ($i = 0; $i < $length; $i += $chunk_size)
83
+ $out[] = $this->substr($string, $i, $chunk_size);
84
+ return $out;
85
+ } else {
86
+ return str_split( $string, $chunk_size );
87
+ }
88
+ }
89
+
90
+
91
+ function pos() {
92
+ return $this->_pos;
93
+ }
94
+
95
+ function is_resource() {
96
+ return true;
97
+ }
98
+
99
+ function close() {
100
+ return true;
101
+ }
102
+ }
103
+ endif;
104
+
105
+ if ( !class_exists( 'POMO_FileReader' ) ):
106
+ class POMO_FileReader extends POMO_Reader {
107
+ function POMO_FileReader($filename) {
108
+ parent::POMO_Reader();
109
+ $this->_f = fopen($filename, 'rb');
110
+ }
111
+
112
+ function read($bytes) {
113
+ return fread($this->_f, $bytes);
114
+ }
115
+
116
+ function seekto($pos) {
117
+ if ( -1 == fseek($this->_f, $pos, SEEK_SET)) {
118
+ return false;
119
+ }
120
+ $this->_pos = $pos;
121
+ return true;
122
+ }
123
+
124
+ function is_resource() {
125
+ return is_resource($this->_f);
126
+ }
127
+
128
+ function feof() {
129
+ return feof($this->_f);
130
+ }
131
+
132
+ function close() {
133
+ return fclose($this->_f);
134
+ }
135
+
136
+ function read_all() {
137
+ $all = '';
138
+ while ( !$this->feof() )
139
+ $all .= $this->read(4096);
140
+ return $all;
141
+ }
142
+ }
143
+ endif;
144
+
145
+ if ( !class_exists( 'POMO_StringReader' ) ):
146
+ /**
147
+ * Provides file-like methods for manipulating a string instead
148
+ * of a physical file.
149
+ */
150
+ class POMO_StringReader extends POMO_Reader {
151
+
152
+ var $_str = '';
153
+
154
+ function POMO_StringReader($str = '') {
155
+ parent::POMO_Reader();
156
+ $this->_str = $str;
157
+ $this->_pos = 0;
158
+ }
159
+
160
+
161
+ function read($bytes) {
162
+ $data = $this->substr($this->_str, $this->_pos, $bytes);
163
+ $this->_pos += $bytes;
164
+ if ($this->strlen($this->_str) < $this->_pos) $this->_pos = $this->strlen($this->_str);
165
+ return $data;
166
+ }
167
+
168
+ function seekto($pos) {
169
+ $this->_pos = $pos;
170
+ if ($this->strlen($this->_str) < $this->_pos) $this->_pos = $this->strlen($this->_str);
171
+ return $this->_pos;
172
+ }
173
+
174
+ function length() {
175
+ return $this->strlen($this->_str);
176
+ }
177
+
178
+ function read_all() {
179
+ return $this->substr($this->_str, $this->_pos, $this->strlen($this->_str));
180
+ }
181
+
182
+ }
183
+ endif;
184
+
185
+ if ( !class_exists( 'POMO_CachedFileReader' ) ):
186
+ /**
187
+ * Reads the contents of the file in the beginning.
188
+ */
189
+ class POMO_CachedFileReader extends POMO_StringReader {
190
+ function POMO_CachedFileReader($filename) {
191
+ parent::POMO_StringReader();
192
+ $this->_str = file_get_contents($filename);
193
+ if (false === $this->_str)
194
+ return false;
195
+ $this->_pos = 0;
196
+ }
197
+ }
198
+ endif;
199
+
200
+ if ( !class_exists( 'POMO_CachedIntFileReader' ) ):
201
+ /**
202
+ * Reads the contents of the file in the beginning.
203
+ */
204
+ class POMO_CachedIntFileReader extends POMO_CachedFileReader {
205
+ function POMO_CachedIntFileReader($filename) {
206
+ parent::POMO_CachedFileReader($filename);
207
+ }
208
+ }
209
+ endif;
util/wp-i18n/pomo/translations.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class for a set of entries for translation and their associated headers
4
+ *
5
+ * @version $Id: translations.php 718 2012-10-31 00:32:02Z nbachiyski $
6
+ * @package pomo
7
+ * @subpackage translations
8
+ */
9
+
10
+ require_once dirname(__FILE__) . '/entry.php';
11
+
12
+ if ( !class_exists( 'Translations' ) ):
13
+ class Translations {
14
+ var $entries = array();
15
+ var $headers = array();
16
+
17
+ /**
18
+ * Add entry to the PO structure
19
+ *
20
+ * @param object &$entry
21
+ * @return bool true on success, false if the entry doesn't have a key
22
+ */
23
+ function add_entry($entry) {
24
+ if (is_array($entry)) {
25
+ $entry = new Translation_Entry($entry);
26
+ }
27
+ $key = $entry->key();
28
+ if (false === $key) return false;
29
+ $this->entries[$key] = &$entry;
30
+ return true;
31
+ }
32
+
33
+ function add_entry_or_merge($entry) {
34
+ if (is_array($entry)) {
35
+ $entry = new Translation_Entry($entry);
36
+ }
37
+ $key = $entry->key();
38
+ if (false === $key) return false;
39
+ if (isset($this->entries[$key]))
40
+ $this->entries[$key]->merge_with($entry);
41
+ else
42
+ $this->entries[$key] = &$entry;
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Sets $header PO header to $value
48
+ *
49
+ * If the header already exists, it will be overwritten
50
+ *
51
+ * TODO: this should be out of this class, it is gettext specific
52
+ *
53
+ * @param string $header header name, without trailing :
54
+ * @param string $value header value, without trailing \n
55
+ */
56
+ function set_header($header, $value) {
57
+ $this->headers[$header] = $value;
58
+ }
59
+
60
+ function set_headers(&$headers) {
61
+ foreach($headers as $header => $value) {
62
+ $this->set_header($header, $value);
63
+ }
64
+ }
65
+
66
+ function get_header($header) {
67
+ return isset($this->headers[$header])? $this->headers[$header] : false;
68
+ }
69
+
70
+ function translate_entry(&$entry) {
71
+ $key = $entry->key();
72
+ return isset($this->entries[$key])? $this->entries[$key] : false;
73
+ }
74
+
75
+ function translate($singular, $context=null) {
76
+ $entry = new Translation_Entry(array('singular' => $singular, 'context' => $context));
77
+ $translated = $this->translate_entry($entry);
78
+ return ($translated && !empty($translated->translations))? $translated->translations[0] : $singular;
79
+ }
80
+
81
+ /**
82
+ * Given the number of items, returns the 0-based index of the plural form to use
83
+ *
84
+ * Here, in the base Translations class, the commong logic for English is implmented:
85
+ * 0 if there is one element, 1 otherwise
86
+ *
87
+ * This function should be overrided by the sub-classes. For example MO/PO can derive the logic
88
+ * from their headers.
89
+ *
90
+ * @param integer $count number of items
91
+ */
92
+ function select_plural_form($count) {
93
+ return 1 == $count? 0 : 1;
94
+ }
95
+
96
+ function get_plural_forms_count() {
97
+ return 2;
98
+ }
99
+
100
+ function translate_plural($singular, $plural, $count, $context = null) {
101
+ $entry = new Translation_Entry(array('singular' => $singular, 'plural' => $plural, 'context' => $context));
102
+ $translated = $this->translate_entry($entry);
103
+ $index = $this->select_plural_form($count);
104
+ $total_plural_forms = $this->get_plural_forms_count();
105
+ if ($translated && 0 <= $index && $index < $total_plural_forms &&
106
+ is_array($translated->translations) &&
107
+ isset($translated->translations[$index]))
108
+ return $translated->translations[$index];
109
+ else
110
+ return 1 == $count? $singular : $plural;
111
+ }
112
+
113
+ /**
114
+ * Merge $other in the current object.
115
+ *
116
+ * @param Object &$other Another Translation object, whose translations will be merged in this one
117
+ * @return void
118
+ **/
119
+ function merge_with(&$other) {
120
+ foreach( $other->entries as $entry ) {
121
+ $this->entries[$entry->key()] = $entry;
122
+ }
123
+ }
124
+
125
+ function merge_originals_with(&$other) {
126
+ foreach( $other->entries as $entry ) {
127
+ if ( !isset( $this->entries[$entry->key()] ) )
128
+ $this->entries[$entry->key()] = $entry;
129
+ else
130
+ $this->entries[$entry->key()]->merge_with($entry);
131
+ }
132
+ }
133
+ }
134
+
135
+ class Gettext_Translations extends Translations {
136
+ /**
137
+ * The gettext implmentation of select_plural_form.
138
+ *
139
+ * It lives in this class, because there are more than one descendand, which will use it and
140
+ * they can't share it effectively.
141
+ *
142
+ */
143
+ function gettext_select_plural_form($count) {
144
+ if (!isset($this->_gettext_select_plural_form) || is_null($this->_gettext_select_plural_form)) {
145
+ list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
146
+ $this->_nplurals = $nplurals;
147
+ $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
148
+ }
149
+ return call_user_func($this->_gettext_select_plural_form, $count);
150
+ }
151
+
152
+ function nplurals_and_expression_from_header($header) {
153
+ if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) {
154
+ $nplurals = (int)$matches[1];
155
+ $expression = trim($this->parenthesize_plural_exression($matches[2]));
156
+ return array($nplurals, $expression);
157
+ } else {
158
+ return array(2, 'n != 1');
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Makes a function, which will return the right translation index, according to the
164
+ * plural forms header
165
+ */
166
+ function make_plural_form_function($nplurals, $expression) {
167
+ $expression = str_replace('n', '$n', $expression);
168
+ $func_body = "
169
+ \$index = (int)($expression);
170
+ return (\$index < $nplurals)? \$index : $nplurals - 1;";
171
+ return create_function('$n', $func_body);
172
+ }
173
+
174
+ /**
175
+ * Adds parantheses to the inner parts of ternary operators in
176
+ * plural expressions, because PHP evaluates ternary oerators from left to right
177
+ *
178
+ * @param string $expression the expression without parentheses
179
+ * @return string the expression with parentheses added
180
+ */
181
+ function parenthesize_plural_exression($expression) {
182
+ $expression .= ';';
183
+ $res = '';
184
+ $depth = 0;
185
+ for ($i = 0; $i < strlen($expression); ++$i) {
186
+ $char = $expression[$i];
187
+ switch ($char) {
188
+ case '?':
189
+ $res .= ' ? (';
190
+ $depth++;
191
+ break;
192
+ case ':':
193
+ $res .= ') : (';
194
+ break;
195
+ case ';':
196
+ $res .= str_repeat(')', $depth) . ';';
197
+ $depth= 0;
198
+ break;
199
+ default:
200
+ $res .= $char;
201
+ }
202
+ }
203
+ return rtrim($res, ';');
204
+ }
205
+
206
+ function make_headers($translation) {
207
+ $headers = array();
208
+ // sometimes \ns are used instead of real new lines
209
+ $translation = str_replace('\n', "\n", $translation);
210
+ $lines = explode("\n", $translation);
211
+ foreach($lines as $line) {
212
+ $parts = explode(':', $line, 2);
213
+ if (!isset($parts[1])) continue;
214
+ $headers[trim($parts[0])] = trim($parts[1]);
215
+ }
216
+ return $headers;
217
+ }
218
+
219
+ function set_header($header, $value) {
220
+ parent::set_header($header, $value);
221
+ if ('Plural-Forms' == $header) {
222
+ list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
223
+ $this->_nplurals = $nplurals;
224
+ $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
225
+ }
226
+ }
227
+ }
228
+ endif;
229
+
230
+ if ( !class_exists( 'NOOP_Translations' ) ):
231
+ /**
232
+ * Provides the same interface as Translations, but doesn't do anything
233
+ */
234
+ class NOOP_Translations {
235
+ var $entries = array();
236
+ var $headers = array();
237
+
238
+ function add_entry($entry) {
239
+ return true;
240
+ }
241
+
242
+ function set_header($header, $value) {
243
+ }
244
+
245
+ function set_headers(&$headers) {
246
+ }
247
+
248
+ function get_header($header) {
249
+ return false;
250
+ }
251
+
252
+ function translate_entry(&$entry) {
253
+ return false;
254
+ }
255
+
256
+ function translate($singular, $context=null) {
257
+ return $singular;
258
+ }
259
+
260
+ function select_plural_form($count) {
261
+ return 1 == $count? 0 : 1;
262
+ }
263
+
264
+ function get_plural_forms_count() {
265
+ return 2;
266
+ }
267
+
268
+ function translate_plural($singular, $plural, $count, $context = null) {
269
+ return 1 == $count? $singular : $plural;
270
+ }
271
+
272
+ function merge_with(&$other) {
273
+ }
274
+ }
275
+ endif;
util/wp-i18n/pot-ext-meta.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Console application, which adds metadata strings from
4
+ * a WordPress extension to a POT file
5
+ *
6
+ * @version $Id: pot-ext-meta.php 19937 2012-05-21 21:40:14Z nacin $
7
+ * @package wordpress-i18n
8
+ * @subpackage tools
9
+ */
10
+
11
+ require_once dirname( __FILE__ ) . '/pomo/po.php';
12
+ require_once dirname( __FILE__ ) . '/makepot.php';
13
+
14
+ class PotExtMeta {
15
+
16
+ var $headers = array(
17
+ 'Plugin Name',
18
+ 'Theme Name',
19
+ 'Plugin URI',
20
+ 'Theme URI',
21
+ 'Description',
22
+ 'Author',
23
+ 'Author URI',
24
+ 'Tags',
25
+ );
26
+
27
+
28
+ function usage() {
29
+ fwrite(STDERR, "Usage: php pot-ext-meta.php EXT POT\n");
30
+ fwrite(STDERR, "Adds metadata from a WordPress theme or plugin file EXT to POT file\n");
31
+ exit(1);
32
+ }
33
+
34
+ function load_from_file($ext_filename) {
35
+ $source = MakePOT::get_first_lines($ext_filename);
36
+ $pot = '';
37
+ foreach($this->headers as $header) {
38
+ $string = MakePOT::get_addon_header($header, $source);
39
+ if (!$string) continue;
40
+ $args = array(
41
+ 'singular' => $string,
42
+ 'extracted_comments' => $header.' of the plugin/theme',
43
+ );
44
+ $entry = new Translation_Entry($args);
45
+ $pot .= "\n".PO::export_entry($entry)."\n";
46
+ }
47
+ return $pot;
48
+ }
49
+
50
+ function append( $ext_filename, $pot_filename, $headers = null ) {
51
+ if ( $headers )
52
+ $this->headers = (array) $headers;
53
+ if ( is_dir( $ext_filename ) ) {
54
+ $pot = implode('', array_map(array(&$this, 'load_from_file'), glob("$ext_filename/*.php")));
55
+ } else {
56
+ $pot = $this->load_from_file($ext_filename);
57
+ }
58
+ $potf = '-' == $pot_filename? STDOUT : fopen($pot_filename, 'a');
59
+ if (!$potf) return false;
60
+ fwrite($potf, $pot);
61
+ if ('-' != $pot_filename) fclose($potf);
62
+ return true;
63
+ }
64
+ }
65
+
66
+ $included_files = get_included_files();
67
+ if ($included_files[0] == __FILE__) {
68
+ ini_set('display_errors', 1);
69
+ $potextmeta = new PotExtMeta;
70
+ if (!isset($argv[1])) {
71
+ $potextmeta->usage();
72
+ }
73
+ $potextmeta->append( $argv[1], isset( $argv[2] ) ? $argv[2] : '-', isset( $argv[3] ) ? $argv[3] : null );
74
+ }
75
+
76
+ ?>
util/wp-i18n/setup_locale ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ # setup_locale - Creates the directory structure for a new locale in the
3
+ # wordpress-i18n repository for a new locale.
4
+
5
+ # First argument is the locale. Ex: es_ES
6
+ locale=$1
7
+
8
+ if [ -z "$locale" ]
9
+ then
10
+ echo "A locale must be specified."
11
+ echo Usage is: $0 locale [repository]
12
+ exit
13
+ fi
14
+
15
+ # Second argument is the base directory of your working copy
16
+ # of wordpress-i18n.
17
+ base=$2
18
+
19
+ if [ -z "$base" ]
20
+ then
21
+ base=.
22
+ fi
23
+
24
+ if [ ! -d "$base" ]
25
+ then
26
+ echo "Directory $base does not exist."
27
+ echo Usage is: $0 locale [repository]
28
+ exit
29
+ fi
30
+
31
+ cd $base
32
+
33
+ svn mkdir $locale
34
+ svn mkdir $locale/trunk
35
+ svn mkdir $locale/branches
36
+ svn mkdir $locale/tags
37
+
38
+ svn mkdir $locale/trunk/dist
39
+
40
+ svn commit $locale -m "$locale" --force-log
util/wp-i18n/t/data/not-gettexted-0-result.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (! isset($wp_did_header)):
4
+ if ( !file_exists( dirname(__FILE__) . '/wp-config.php') ) {
5
+ if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false) $path = '';
6
+ else $path = 'wp-admin/';
7
+
8
+ require_once( dirname(__FILE__) . '/wp-includes/classes.php');
9
+ require_once( dirname(__FILE__) . '/wp-includes/functions.php');
10
+ require_once( dirname(__FILE__) . '/wp-includes/plugin.php');
11
+ wp_die( sprintf(/*WP_I18N_CONFIG*/'Translation: There doesn\'t seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href=\'http://codex.wordpress.org/Editing_wp-config.php\'>We got it</a>. You can create a <code>wp-config.php</code> file through a web interface, but this doesn\'t work for all server setups. The safest way is to manually create the file.</p><p><a href=\'%s\' class=\'button\'>Create a Configuration File</a>' /*/WP_I18N_CONFIG*/, $path.'setup-config.php'), /*WP_I18N_ERROR*/ 'Translation: WordPress &rsaquo; Error' /*/WP_I18N_ERROR*/);
12
+ }
13
+
14
+ $wp_did_header = true;
15
+
16
+ require_once( dirname(__FILE__) . '/wp-config.php');
17
+
18
+ wp();
19
+
20
+ require_once(ABSPATH . WPINC . '/template-loader.php');
21
+
22
+ endif;
23
+
24
+ ?>
util/wp-i18n/t/data/not-gettexted-0-work.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (! isset($wp_did_header)):
4
+ if ( !file_exists( dirname(__FILE__) . '/wp-config.php') ) {
5
+ if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false) $path = '';
6
+ else $path = 'wp-admin/';
7
+
8
+ require_once( dirname(__FILE__) . '/wp-includes/classes.php');
9
+ require_once( dirname(__FILE__) . '/wp-includes/functions.php');
10
+ require_once( dirname(__FILE__) . '/wp-includes/plugin.php');
11
+ wp_die( sprintf(/*WP_I18N_CONFIG*/'Translation: There doesn\'t seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href=\'http://codex.wordpress.org/Editing_wp-config.php\'>We got it</a>. You can create a <code>wp-config.php</code> file through a web interface, but this doesn\'t work for all server setups. The safest way is to manually create the file.</p><p><a href=\'%s\' class=\'button\'>Create a Configuration File</a>' /*/WP_I18N_CONFIG*/, $path.'setup-config.php'), /*WP_I18N_ERROR*/ 'Translation: WordPress &rsaquo; Error' /*/WP_I18N_ERROR*/);
12
+ }
13
+
14
+ $wp_did_header = true;
15
+
16
+ require_once( dirname(__FILE__) . '/wp-config.php');
17
+
18
+ wp();
19
+
20
+ require_once(ABSPATH . WPINC . '/template-loader.php');
21
+
22
+ endif;
23
+
24
+ ?>
util/wp-i18n/t/data/not-gettexted-0.mo ADDED
Binary file
util/wp-i18n/t/data/not-gettexted-0.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (! isset($wp_did_header)):
4
+ if ( !file_exists( dirname(__FILE__) . '/wp-config.php') ) {
5
+ if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false) $path = '';
6
+ else $path = 'wp-admin/';
7
+
8
+ require_once( dirname(__FILE__) . '/wp-includes/classes.php');
9
+ require_once( dirname(__FILE__) . '/wp-includes/functions.php');
10
+ require_once( dirname(__FILE__) . '/wp-includes/plugin.php');
11
+ wp_die( sprintf(/*WP_I18N_CONFIG*/" There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://codex.wordpress.org/Editing_wp-config.php'>We got it</a>. You can create a <code>wp-config.php</code> file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file.</p><p><a href='%s' class='button'>Create a Configuration File</a>" /*/WP_I18N_CONFIG*/, $path.'setup-config.php'), /*WP_I18N_ERROR*/ "WordPress &rsaquo; Error" /*/WP_I18N_ERROR*/);
12
+ }
13
+
14
+ $wp_did_header = true;
15
+
16
+ require_once( dirname(__FILE__) . '/wp-config.php');
17
+
18
+ wp();
19
+
20
+ require_once(ABSPATH . WPINC . '/template-loader.php');
21
+
22
+ endif;
23
+
24
+ ?>
util/wp-i18n/t/data/not-gettexted-0.po ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: \n"
4
+ "POT-Creation-Date: \n"
5
+ "PO-Revision-Date: 2008-04-22 19:23+0200\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=iso-8859-1\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+
12
+ #. Not gettexted string WP_I18N_CONFIG
13
+ #: not-gettext-0.php:11
14
+ msgid " There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://codex.wordpress.org/Editing_wp-config.php'>We got it</a>. You can create a <code>wp-config.php</code> file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file.</p><p><a href='%s' class='button'>Create a Configuration File</a>"
15
+ msgstr "Translation: There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://codex.wordpress.org/Editing_wp-config.php'>We got it</a>. You can create a <code>wp-config.php</code> file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file.</p><p><a href='%s' class='button'>Create a Configuration File</a>"
16
+
17
+ #. Not gettexted string WP_I18N_ERROR
18
+ #: not-gettext-0.php:11
19
+ msgid "WordPress &rsaquo; Error"
20
+ msgstr "Translation: WordPress &rsaquo; Error"
21
+
util/wp-i18n/t/run.sh ADDED
@@ -0,0 +1,2 @@
 
 
1
+ #!/bin/sh
2
+ phpunit Test_Not_Gettexted test_not-gettexted.php
util/wp-i18n/t/test_not-gettexted.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Tests for not-gettexted.php
4
+ *
5
+ * @version $Id: test_not-gettexted.php 19937 2012-05-21 21:40:14Z nacin $
6
+ * @package wordpress-i18n
7
+ * @subpackage tools
8
+ */
9
+ error_reporting( E_ALL );
10
+ require_once 'PHPUnit/Framework.php';
11
+ require_once dirname( __FILE__ ) '/../not-gettexted.php';
12
+
13
+ class Test_Not_Gettexted extends PHPUnit_Framework_TestCase {
14
+
15
+ function __construct() {
16
+ $this->ng = new NotGettexted;
17
+ }
18
+
19
+ function test_make_string_aggregator() {
20
+ global $baba;
21
+ $f = $this->ng->make_string_aggregator( 'baba', 'baba.php' );
22
+ call_user_func( $f, 'x', 'y', 'z' );
23
+ call_user_func( $f, 'a', 'b', 'c' );
24
+ $this->assertEquals( array( array( 'x', 'y', 'baba.php', 'z'), array( 'a', 'b', 'baba.php', 'c' ) ), $baba );
25
+ }
26
+
27
+ function test_walk() {
28
+ $code = '
29
+ <?php
30
+ $s = 8;
31
+ echo /* WP_I18N_GUGU*/ "yes" /* /WP_I18N_UGU */;
32
+ if ($x == "18181") { wp_die(sprintf(/*WP_I18N_DIE*/\'We died %d times!\'/*WP_I18N_DIE*/)); }
33
+ ?>';
34
+ $tokens = token_get_all($code);
35
+ $this->assertEquals( '', $this->ng->walk_tokens( $tokens, array(&$this->ng, 'ignore_token'), array(&$this->ng, 'ignore_token') ) );
36
+ $this->assertEquals( '"yes"\'We died %d times!\'', $this->ng->walk_tokens( $tokens, array(&$this->ng, 'unchanged_token'), array(&$this->ng, 'ignore_token') ) );
37
+ $this->assertEquals( $code, $this->ng->walk_tokens( $tokens, array(&$this->ng, 'unchanged_token'), array(&$this->ng, 'unchanged_token') ) );
38
+ $this->assertEquals( $code, $this->ng->walk_tokens( $tokens, array(&$this->ng, 'unchanged_token'), array(&$this->ng, 'unchanged_token') ) );
39
+ }
40
+
41
+ function test_replace() {
42
+ # copy to a new file, so that we don't corrupt the old one
43
+ copy( 'data/not-gettexted-0.php', 'data/not-gettexted-0-work.php' );
44
+ $this->ng->command_replace( 'data/not-gettexted-0.mo', 'data/not-gettexted-0-work.php' );
45
+ $this->assertEquals( file_get_contents( 'data/not-gettexted-0-result.php' ), file_get_contents( 'data/not-gettexted-0-work.php' ) );
46
+ unlink( 'data/not-gettexted-0-work.php' );
47
+ }
48
+ }