Attachments - Version 1.5.2

Version Description

  • Added Swedish translation, courtesy of Sebastian Johansson
  • 'Attach' button is now localized
  • Fixed a couple of other miscellaneous localization issues
  • Added Italian translation, courtesy of Andrea Bersi
  • Fixed a number of PHP notices/warnings in more strict environments
Download this release

Release Info

Developer jchristopher
Plugin Icon wp plugin Attachments
Version 1.5.2
Comparing to
See all releases

Code changes from version 1.5.1.2 to 1.5.2

attachments-it_IT.mo ADDED
Binary file
attachments-it_IT.po ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Attachments\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2010-03-21 14:50-0500\n"
6
+ "PO-Revision-Date: 2011-01-24 19:08+0100\n"
7
+ "Last-Translator: Andrea Bersi\n"
8
+ "Language-Team: Jonathan Christopher <jonathandchr@gmail.com>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Poedit-KeywordsList: _e;__\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "X-Poedit-Language: Portuguese\n"
15
+ "X-Poedit-Country: BRAZIL\n"
16
+ "X-Poedit-SourceCharset: utf-8\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: attachments.php:97
20
+ msgid "Users can only see their own attachments"
21
+ msgstr "Utenti vedono slolo i loro allegati"
22
+
23
+ #: attachments.php:102
24
+ msgid "Save"
25
+ msgstr "Salva"
26
+
27
+ #: attachments.php:137
28
+ msgid "Browse Existing"
29
+ msgstr "Sfoglia esistenti"
30
+
31
+ #: attachments.php:138
32
+ #: media.php:26
33
+ msgid "Add to Media Library"
34
+ msgstr "Aggiungi ai media"
35
+
36
+ #: attachments.php:160
37
+ msgid "Delete"
38
+ msgstr "Cancella"
39
+
40
+ #: attachments.php:164
41
+ msgid "Title"
42
+ msgstr "Titolo"
43
+
44
+ #: attachments.php:168
45
+ msgid "Caption"
46
+ msgstr "Descrizione"
47
+
48
+ #: attachments.php:205
49
+ #: attachments.php:208
50
+ msgid "Attachments"
51
+ msgstr "Allegati"
52
+
53
+ #: media.php:26
54
+ msgid "Available attachments are listed from your"
55
+ msgstr "Elenco allegati disponibili dal tuo"
56
+
57
+ #: media.php:26
58
+ msgid "Media Library"
59
+ msgstr "Libreria Media"
60
+
61
+ #: media.php:26
62
+ msgid "If you need to upload a new attachment, please close this dialog and use the available"
63
+ msgstr "Se vuoi caricare un altro allegato, chiudi questa finestra e usa quella disponibile"
64
+
65
+ #: media.php:26
66
+ msgid "button"
67
+ msgstr "bottone"
68
+
69
+ #: media.php:27
70
+ msgid "Select/deselect an attachment by clicking its thumbnail. When you're done managing your attachments, click "
71
+ msgstr "Seleziona/deseleziona un allegato cliccando la sua miniatura.Quando terminato, fai click"
72
+
73
+ #: media.php:27
74
+ #: media.php:29
75
+ #: media.php:160
76
+ msgid "Apply"
77
+ msgstr "Applica"
78
+
79
+ #: media.php:39
80
+ msgid "Images"
81
+ msgstr "Immagini"
82
+
83
+ #: media.php:67
84
+ msgid "Videos"
85
+ msgstr "Video"
86
+
87
+ #: media.php:99
88
+ msgid "Documents"
89
+ msgstr "Documenti"
90
+
91
+ #: media.php:131
92
+ msgid "Audio"
93
+ msgstr "Audio"
94
+
attachments-sv_SE.mo ADDED
Binary file
attachments-sv_SE.po ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Attachments sv_SE version\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2011-02-03 20:40-0100\n"
6
+ "PO-Revision-Date: 2011-02-03 21:11+0100\n"
7
+ "Last-Translator: Sebastian Johansson <johansson.seb@gmail.com>\n"
8
+ "Language-Team: Sebastian Johansson <johansson.seb@gmail.com>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
13
+ "X-Poedit-Language: Swedish\n"
14
+ "X-Poedit-Country: SWEDEN\n"
15
+ "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
17
+ "X-Poedit-Basepath: .\n"
18
+ "X-Poedit-Bookmarks: \n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+ "X-Textdomain-Support: yes"
21
+
22
+ #: attachments.options.php:35
23
+ #@ attachments
24
+ msgid "Save"
25
+ msgstr "Spara"
26
+
27
+ #: attachments.php:156
28
+ #@ attachments
29
+ msgid "Delete"
30
+ msgstr "Ta bort"
31
+
32
+ #: attachments.php:160
33
+ #@ attachments
34
+ msgid "Title"
35
+ msgstr "Titel"
36
+
37
+ #: attachments.php:164
38
+ #@ attachments
39
+ msgid "Caption"
40
+ msgstr "Beskrivning"
41
+
42
+ #: attachments.php:201
43
+ #: attachments.php:204
44
+ #: attachments.php:220
45
+ #@ attachments
46
+ msgid "Attachments"
47
+ msgstr "Bilagor"
48
+
49
+ #: attachments.options.php:21
50
+ #@ attachments
51
+ msgid "Custom Post Type Settings"
52
+ msgstr "Inställningar för Custom Post Types"
53
+
54
+ #: attachments.options.php:22
55
+ #@ attachments
56
+ msgid "Include Attachments in the following Custom Post Types:"
57
+ msgstr "Använd Attachments i följande Custom Post Types:"
58
+
59
+ #: attachments.options.php:40
60
+ #@ attachments
61
+ msgid "Attachments can be integrated with your Custom Post Types. Unfortunately, there are none to work with at this time."
62
+ msgstr "Attachments kan integreras med dina Custom Post Types. Tyvärr är inga Custom Post Types registrerade."
63
+
64
+ #: attachments.php:132
65
+ #: attachments.php:440
66
+ #@ attachments
67
+ msgid "Attach"
68
+ msgstr "Bifoga"
69
+
attachments.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /*
3
- Plugin Name: Attachments
4
- Plugin URI: http://mondaybynoon.com/wordpress-attachments/
5
  Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
6
- Version: 1.5.1.2
7
- Author: Jonathan Christopher
8
- Author URI: http://mondaybynoon.com/
9
  */
10
 
11
  /* Copyright 2009 Jonathan Christopher (email : jonathandchr@gmail.com)
@@ -23,7 +23,7 @@ Author URI: http://mondaybynoon.com/
23
  You should have received a copy of the GNU General Public License
24
  along with this program; if not, write to the Free Software
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
- */
27
 
28
 
29
  // ===========
@@ -39,11 +39,11 @@ global $wpdb;
39
  // =========
40
  if( WP_ADMIN )
41
  {
42
- add_action( 'admin_menu', 'attachments_init' );
43
- add_action( 'admin_head', 'attachments_init_js' );
44
- add_action( 'save_post', 'attachments_save' );
45
- add_action( 'admin_menu', 'attachments_menu' );
46
- add_action( 'admin_init', 'fix_async_upload_image' );
47
  }
48
 
49
 
@@ -53,394 +53,422 @@ if( WP_ADMIN )
53
  // =============
54
 
55
  /**
56
- * Compares two array values with the same key "order"
57
- *
58
- * @param string $a First value
59
- * @param string $b Second value
60
- * @return int
61
- * @author Jonathan Christopher
62
- */
63
  function attachments_cmp($a, $b)
64
  {
65
- $a = intval( $a['order'] );
66
- $b = intval( $b['order'] );
67
-
68
- if( $a < $b )
69
- {
70
- return -1;
71
- }
72
- else if( $a > $b )
73
- {
74
- return 1;
75
- }
76
- else
77
- {
78
- return 0;
79
- }
80
  }
81
 
82
 
83
 
84
 
85
  /**
86
- * Creates the markup for the WordPress admin options page
87
- *
88
- * @return void
89
- * @author Jonathan Christopher
90
- */
91
  function attachments_options()
92
  {
93
- include 'attachments.options.php';
94
  }
95
 
96
 
97
 
98
 
99
  /**
100
- * Creates the entry for Attachments Options under Settings in the WordPress Admin
101
- *
102
- * @return void
103
- * @author Jonathan Christopher
104
- */
105
  function attachments_menu()
106
  {
107
- add_options_page('Settings', 'Attachments', 8, __FILE__, 'attachments_options');
108
  }
109
 
110
 
111
 
112
 
113
  /**
114
- * Inserts HTML for meta box, including all existing attachments
115
- *
116
- * @return void
117
- * @author Jonathan Christopher
118
- */
119
  function attachments_add()
120
  {?>
121
-
122
- <div id="attachments-inner">
123
-
124
- <?php
125
- $media_upload_iframe_src = "media-upload.php?type=image&TB_iframe=1";
126
- $image_upload_iframe_src = apply_filters( 'image_upload_iframe_src', "$media_upload_iframe_src" );
127
- ?>
128
-
129
- <ul id="attachments-actions">
130
- <li>
131
- <a id="attachments-thickbox" href="<?php echo $image_upload_iframe_src; ?>&attachments_thickbox=1" title="Attachments" class="button button-highlighted">
132
- Attach
133
- </a>
134
- </li>
135
- </ul>
136
-
137
- <div id="attachments-list">
138
- <input type="hidden" name="attachments_nonce" id="attachments_nonce" value="<?php echo wp_create_nonce( plugin_basename(__FILE__) ); ?>" />
139
- <ul>
140
- <?php
141
- if( !empty($_GET['post']) )
142
- {
143
- // get all attachments
144
- $existing_attachments = attachments_get_attachments( intval( $_GET['post'] ) );
145
-
146
- if( is_array($existing_attachments) && !empty($existing_attachments) )
147
- {
148
- $attachment_index = 0;
149
- foreach ($existing_attachments as $attachment) : $attachment_index++; ?>
150
- <li class="attachments-file">
151
- <h2>
152
- <a href="#" class="attachment-handle">
153
- <span class="attachment-handle-icon"><img src="<?php echo WP_PLUGIN_URL; ?>/attachments/images/handle.gif" alt="Drag" /></span>
154
- </a>
155
- <span class="attachment-name"><?php echo $attachment['name']; ?></span>
156
- <span class="attachment-delete"><a href="#"><?php _e("Delete", "attachments")?></a></span>
157
- </h2>
158
- <div class="attachments-fields">
159
- <div class="textfield" id="field_attachment_title_<?php echo $attachment_index ; ?>">
160
- <label for="attachment_title_<?php echo $attachment_index; ?>"><?php _e("Title", "attachments")?></label>
161
- <input type="text" id="attachment_title_<?php echo $attachment_index; ?>" name="attachment_title_<?php echo $attachment_index; ?>" value="<?php echo $attachment['title']; ?>" size="20" />
162
- </div>
163
- <div class="textfield" id="field_attachment_caption_<?php echo $attachment_index; ?>">
164
- <label for="attachment_caption_<?php echo $attachment_index; ?>"><?php _e("Caption", "attachments")?></label>
165
- <input type="text" id="attachment_caption_<?php echo $attachment_index; ?>" name="attachment_caption_<?php echo $attachment_index; ?>" value="<?php echo $attachment['caption']; ?>" size="20" />
166
- </div>
167
- </div>
168
- <div class="attachments-data">
169
- <input type="hidden" name="attachment_id_<?php echo $attachment_index; ?>" id="attachment_id_<?php echo $attachment_index; ?>" value="<?php echo $attachment['id']; ?>" />
170
- <input type="hidden" class="attachment_order" name="attachment_order_<?php echo $attachment_index; ?>" id="attachment_order_<?php echo $attachment_index; ?>" value="<?php echo $attachment['order']; ?>" />
171
- </div>
172
- <div class="attachment-thumbnail">
173
- <span class="attachments-thumbnail">
174
- <?php echo wp_get_attachment_image( $attachment['id'], array(80, 60), 1 ); ?>
175
- </span>
176
- </div>
177
- </li>
178
- <?php endforeach;
179
- }
180
- }
181
- ?>
182
- </ul>
183
- </div>
184
-
185
- </div>
186
-
187
  <?php }
188
 
189
 
190
 
191
  /**
192
- * Creates meta box on all Posts and Pages
193
- *
194
- * @return void
195
- * @author Jonathan Christopher
196
- */
197
 
198
  function attachments_meta_box()
199
  {
200
- // for posts
201
- add_meta_box( 'attachments_list', __( 'Attachments', 'attachments_textdomain' ), 'attachments_add', 'post', 'normal' );
202
-
203
- // for pages
204
- add_meta_box( 'attachments_list', __( 'Attachments', 'attachments_textdomain' ), 'attachments_add', 'page', 'normal' );
205
-
206
- // for custom post types
207
- if( function_exists( 'get_post_types' ) )
208
- {
209
- $args = array(
210
- 'public' => true,
211
- '_builtin' => false
212
- );
213
- $output = 'objects';
214
- $operator = 'and';
215
- $post_types = get_post_types( $args, $output, $operator );
216
- foreach($post_types as $post_type)
217
- {
218
- if (get_option('attachments_cpt_' . $post_type->name)=='true')
219
- {
220
- add_meta_box( 'attachments_list', __( 'Attachments', 'attachments_textdomain' ), 'attachments_add', $post_type->name, 'normal' );
221
- }
222
- }
223
- }
224
  }
225
 
226
 
227
 
228
  /**
229
- * Echos JavaScript that sets some required global variables
230
- *
231
- * @return void
232
- * @author Jonathan Christopher
233
- */
234
  function attachments_init_js()
235
  {
236
- global $pagenow;
237
-
238
- echo '<script type="text/javascript" charset="utf-8">';
239
- echo ' var attachments_base = "' . WP_PLUGIN_URL . '/attachments"; ';
240
- echo ' var attachments_media = ""; ';
241
- if ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow )
242
- {
243
- echo ' var attachments_upload = true; ';
244
- }
245
- else
246
- {
247
- echo ' var attachments_upload = false; ';
248
- }
249
- if( ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow ) && is_attachments_context() )
250
- {
251
- echo ' var attachments_is_attachments_context = true; ';
252
- }
253
- else
254
- {
255
- echo ' var attachments_is_attachments_context = false; ';
256
- }
257
- echo '</script>';
258
  }
259
 
260
 
261
 
262
  /**
263
- * Fired when Post or Page is saved. Serializes all attachment data and saves to post_meta
264
- *
265
- * @param int $post_id The ID of the current post
266
- * @return void
267
- * @author Jonathan Christopher
268
- * @author JR Tashjian
269
- */
270
  function attachments_save($post_id)
271
  {
272
- // verify this came from the our screen and with proper authorization,
273
- // because save_post can be triggered at other times
274
- if ( !wp_verify_nonce( $_POST['attachments_nonce'], plugin_basename(__FILE__) )) {
275
- return $post_id;
276
- }
277
-
278
- // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
279
- // to do anything
280
- if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
281
- return $post_id;
282
-
283
- // Check permissions
284
- if ( 'page' == $_POST['post_type'] ) {
285
- if ( !current_user_can( 'edit_page', $post_id ) )
286
- return $post_id;
287
- } else {
288
- if ( !current_user_can( 'edit_post', $post_id ) )
289
- return $post_id;
290
- }
291
-
292
- // OK, we're authenticated: we need to find and save the data
293
-
294
- // delete all current attachments meta
295
- // moved outside conditional, else we can never delete all attachments
296
- delete_post_meta($post_id, '_attachments');
297
-
298
- // Since we're allowing Attachments to be sortable, we can't simply increment a counter
299
- // we need to keep track of the IDs we're given
300
- $attachment_ids = array();
301
-
302
- // We'll build our array of attachments
303
- foreach($_POST as $key => $data) {
304
-
305
- // Arbitrarily using the id
306
- if( substr($key, 0, 14) == 'attachment_id_' )
307
- {
308
- array_push( $attachment_ids, substr( $key, 14, strlen( $key ) ) );
309
- }
310
-
311
- }
312
-
313
- // If we have attachments, there's work to do
314
- if( !empty( $attachment_ids ) )
315
- {
316
-
317
- foreach ( $attachment_ids as $i )
318
- {
319
- if( !empty( $_POST['attachment_id_' . $i] ) )
320
- {
321
- $attachment_details = array(
322
- 'id' => $_POST['attachment_id_' . $i],
323
- 'title' => str_replace( '"', '&quot;', $_POST['attachment_title_' . $i] ),
324
- 'caption' => str_replace( '"', '&quot;', $_POST['attachment_caption_' . $i] ),
325
- 'order' => $_POST['attachment_order_' . $i]
326
- );
327
-
328
- // serialize data and encode
329
- $attachment_serialized = base64_encode( serialize( $attachment_details ) );
330
-
331
- // add individual attachment
332
- add_post_meta( $post_id, '_attachments', $attachment_serialized );
333
- }
334
- }
335
-
336
- }
337
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  }
339
 
340
 
341
 
342
  /**
343
- * Retrieves all Attachments for provided Post or Page
344
- *
345
- * @param int $post_id (optional) ID of target Post or Page, otherwise pulls from global $post
346
- * @return array $post_attachments
347
- * @author Jonathan Christopher
348
- * @author JR Tashjian
349
- */
350
  function attachments_get_attachments( $post_id=null )
351
  {
352
- global $post;
353
-
354
- if( $post_id==null )
355
- {
356
- $post_id = $post->ID;
357
- }
358
-
359
- // get all attachments
360
- $existing_attachments = get_post_meta( $post_id, '_attachments', false );
361
-
362
- if( !empty( $existing_attachments ) )
363
- {
364
- $legacy_existing_attachments = unserialize( $existing_attachments[0] );
365
- }
366
-
367
- // Check for legacy attachments
368
- if( is_array( $legacy_existing_attachments ) )
369
- {
370
- $tmp_legacy_attachments = array();
371
-
372
- // Legacy attachments (single serialized record)
373
- foreach ( $legacy_existing_attachments as $legacy_attachment )
374
- {
375
- array_push( $tmp_legacy_attachments, base64_encode( serialize( $legacy_attachment ) ) );
376
- }
377
-
378
- $existing_attachments = $tmp_legacy_attachments;
379
- }
380
-
381
- // We can now proceed as normal, all legacy data should now be upgraded
382
- if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
383
- {
384
- $post_attachments = array();
385
-
386
- foreach ($existing_attachments as $attachment)
387
- {
388
- // decode and unserialize the data
389
- $data = unserialize( base64_decode( $attachment ) );
390
-
391
- array_push( $post_attachments, array(
392
- 'id' => stripslashes( $data['id'] ),
393
- 'name' => stripslashes( get_the_title( $data['id'] ) ),
394
- 'mime' => stripslashes( get_post_mime_type( $data['id'] ) ),
395
- 'title' => stripslashes( $data['title'] ),
396
- 'caption' => stripslashes( $data['caption'] ),
397
- 'location' => stripslashes( wp_get_attachment_url( $data['id'] ) ),
398
- 'order' => stripslashes( $data['order'] )
399
- ));
400
- }
401
-
402
- // sort attachments
403
- if( count( $post_attachments ) > 1 )
404
- {
405
- usort( $post_attachments, "attachments_cmp" );
406
- }
407
- }
408
-
409
- return $post_attachments;
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  }
411
 
412
 
413
  if( !function_exists( 'fix_async_upload_image' ) )
414
  {
415
- function fix_async_upload_image() {
416
- if( isset( $_REQUEST['attachment_id'] ) )
417
- {
418
- $GLOBALS['post'] = get_post( $_REQUEST['attachment_id'] );
419
- }
420
- }
421
  }
422
 
423
  function is_attachments_context()
424
  {
425
- global $pagenow;
426
-
427
- // if post_id is set, it's the editor upload...
428
- if ( ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow ) && empty( $_REQUEST['post_id'] ) )
429
- {
430
- return true;
431
- }
432
- return false;
433
  }
434
 
435
  function hijack_thickbox_text($translated_text, $source_text, $domain)
436
  {
437
- if ( is_attachments_context() )
438
- {
439
- if ('Insert into Post' == $source_text) {
440
- return __('Attach', 'attachments' );
441
- }
442
- }
443
- return $translated_text;
444
  }
445
 
446
 
@@ -448,38 +476,38 @@ function hijack_thickbox_text($translated_text, $source_text, $domain)
448
 
449
 
450
  /**
451
- * This is the main initialization function, it will invoke the necessary meta_box
452
- *
453
- * @return void
454
- * @author Jonathan Christopher
455
- */
456
 
457
  function attachments_init()
458
  {
459
- global $pagenow;
460
-
461
- wp_enqueue_script( 'jquery-ui-core' );
462
- wp_enqueue_style( 'thickbox' );
463
-
464
- if ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow )
465
- {
466
- add_filter( 'gettext', 'hijack_thickbox_text', 1, 3 );
467
- }
468
-
469
- wp_enqueue_style( 'attachments', WP_PLUGIN_URL . '/attachments/css/attachments.css' );
470
- wp_enqueue_script( 'attachments', WP_PLUGIN_URL . '/attachments/js/attachments.js', array( 'thickbox' ), false, false );
471
-
472
- if( function_exists( 'load_plugin_textdomain' ) )
473
- {
474
- if( !defined('WP_PLUGIN_DIR') )
475
- {
476
- load_plugin_textdomain( 'attachments', str_replace( ABSPATH, '', dirname( __FILE__ ) ) );
477
- }
478
- else
479
- {
480
- load_plugin_textdomain( 'attachments', false, dirname( plugin_basename( __FILE__ ) ) );
481
- }
482
- }
483
-
484
- attachments_meta_box();
485
  }
1
  <?php
2
  /*
3
+ Plugin Name: Attachments
4
+ Plugin URI: http://mondaybynoon.com/wordpress-attachments/
5
  Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
6
+ Version: 1.5.2
7
+ Author: Jonathan Christopher
8
+ Author URI: http://mondaybynoon.com/
9
  */
10
 
11
  /* Copyright 2009 Jonathan Christopher (email : jonathandchr@gmail.com)
23
  You should have received a copy of the GNU General Public License
24
  along with this program; if not, write to the Free Software
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
+ */
27
 
28
 
29
  // ===========
39
  // =========
40
  if( WP_ADMIN )
41
  {
42
+ add_action( 'admin_menu', 'attachments_init' );
43
+ add_action( 'admin_head', 'attachments_init_js' );
44
+ add_action( 'save_post', 'attachments_save' );
45
+ add_action( 'admin_menu', 'attachments_menu' );
46
+ add_action( 'admin_init', 'fix_async_upload_image' );
47
  }
48
 
49
 
53
  // =============
54
 
55
  /**
56
+ * Compares two array values with the same key "order"
57
+ *
58
+ * @param string $a First value
59
+ * @param string $b Second value
60
+ * @return int
61
+ * @author Jonathan Christopher
62
+ */
63
  function attachments_cmp($a, $b)
64
  {
65
+ $a = intval( $a['order'] );
66
+ $b = intval( $b['order'] );
67
+
68
+ if( $a < $b )
69
+ {
70
+ return -1;
71
+ }
72
+ else if( $a > $b )
73
+ {
74
+ return 1;
75
+ }
76
+ else
77
+ {
78
+ return 0;
79
+ }
80
  }
81
 
82
 
83
 
84
 
85
  /**
86
+ * Creates the markup for the WordPress admin options page
87
+ *
88
+ * @return void
89
+ * @author Jonathan Christopher
90
+ */
91
  function attachments_options()
92
  {
93
+ include 'attachments.options.php';
94
  }
95
 
96
 
97
 
98
 
99
  /**
100
+ * Creates the entry for Attachments Options under Settings in the WordPress Admin
101
+ *
102
+ * @return void
103
+ * @author Jonathan Christopher
104
+ */
105
  function attachments_menu()
106
  {
107
+ add_options_page('Settings', 'Attachments', 8, __FILE__, 'attachments_options');
108
  }
109
 
110
 
111
 
112
 
113
  /**
114
+ * Inserts HTML for meta box, including all existing attachments
115
+ *
116
+ * @return void
117
+ * @author Jonathan Christopher
118
+ */
119
  function attachments_add()
120
  {?>
121
+
122
+ <div id="attachments-inner">
123
+
124
+ <?php
125
+ $media_upload_iframe_src = "media-upload.php?type=image&TB_iframe=1";
126
+ $image_upload_iframe_src = apply_filters( 'image_upload_iframe_src', "$media_upload_iframe_src" );
127
+ ?>
128
+
129
+ <ul id="attachments-actions">
130
+ <li>
131
+ <a id="attachments-thickbox" href="<?php echo $image_upload_iframe_src; ?>&attachments_thickbox=1" title="Attachments" class="button button-highlighted">
132
+ <?php _e( 'Attach', 'attachments' ) ?>
133
+ </a>
134
+ </li>
135
+ </ul>
136
+
137
+ <div id="attachments-list">
138
+ <input type="hidden" name="attachments_nonce" id="attachments_nonce" value="<?php echo wp_create_nonce( plugin_basename(__FILE__) ); ?>" />
139
+ <ul>
140
+ <?php
141
+ if( !empty($_GET['post']) )
142
+ {
143
+ // get all attachments
144
+ $existing_attachments = attachments_get_attachments( intval( $_GET['post'] ) );
145
+
146
+ if( is_array($existing_attachments) && !empty($existing_attachments) )
147
+ {
148
+ $attachment_index = 0;
149
+ foreach ($existing_attachments as $attachment) : $attachment_index++; ?>
150
+ <li class="attachments-file">
151
+ <h2>
152
+ <a href="#" class="attachment-handle">
153
+ <span class="attachment-handle-icon"><img src="<?php echo WP_PLUGIN_URL; ?>/attachments/images/handle.gif" alt="Drag" /></span>
154
+ </a>
155
+ <span class="attachment-name"><?php echo $attachment['name']; ?></span>
156
+ <span class="attachment-delete"><a href="#"><?php _e("Delete", "attachments")?></a></span>
157
+ </h2>
158
+ <div class="attachments-fields">
159
+ <div class="textfield" id="field_attachment_title_<?php echo $attachment_index ; ?>">
160
+ <label for="attachment_title_<?php echo $attachment_index; ?>"><?php _e("Title", "attachments")?></label>
161
+ <input type="text" id="attachment_title_<?php echo $attachment_index; ?>" name="attachment_title_<?php echo $attachment_index; ?>" value="<?php echo $attachment['title']; ?>" size="20" />
162
+ </div>
163
+ <div class="textfield" id="field_attachment_caption_<?php echo $attachment_index; ?>">
164
+ <label for="attachment_caption_<?php echo $attachment_index; ?>"><?php _e("Caption", "attachments")?></label>
165
+ <input type="text" id="attachment_caption_<?php echo $attachment_index; ?>" name="attachment_caption_<?php echo $attachment_index; ?>" value="<?php echo $attachment['caption']; ?>" size="20" />
166
+ </div>
167
+ </div>
168
+ <div class="attachments-data">
169
+ <input type="hidden" name="attachment_id_<?php echo $attachment_index; ?>" id="attachment_id_<?php echo $attachment_index; ?>" value="<?php echo $attachment['id']; ?>" />
170
+ <input type="hidden" class="attachment_order" name="attachment_order_<?php echo $attachment_index; ?>" id="attachment_order_<?php echo $attachment_index; ?>" value="<?php echo $attachment['order']; ?>" />
171
+ </div>
172
+ <div class="attachment-thumbnail">
173
+ <span class="attachments-thumbnail">
174
+ <?php echo wp_get_attachment_image( $attachment['id'], array(80, 60), 1 ); ?>
175
+ </span>
176
+ </div>
177
+ </li>
178
+ <?php endforeach;
179
+ }
180
+ }
181
+ ?>
182
+ </ul>
183
+ </div>
184
+
185
+ </div>
186
+
187
  <?php }
188
 
189
 
190
 
191
  /**
192
+ * Creates meta box on all Posts and Pages
193
+ *
194
+ * @return void
195
+ * @author Jonathan Christopher
196
+ */
197
 
198
  function attachments_meta_box()
199
  {
200
+ // for posts
201
+ add_meta_box( 'attachments_list', __( 'Attachments', 'attachments' ), 'attachments_add', 'post', 'normal' );
202
+
203
+ // for pages
204
+ add_meta_box( 'attachments_list', __( 'Attachments', 'attachments' ), 'attachments_add', 'page', 'normal' );
205
+
206
+ // for custom post types
207
+ if( function_exists( 'get_post_types' ) )
208
+ {
209
+ $args = array(
210
+ 'public' => true,
211
+ '_builtin' => false
212
+ );
213
+ $output = 'objects';
214
+ $operator = 'and';
215
+ $post_types = get_post_types( $args, $output, $operator );
216
+ foreach($post_types as $post_type)
217
+ {
218
+ if (get_option('attachments_cpt_' . $post_type->name)=='true')
219
+ {
220
+ add_meta_box( 'attachments_list', __( 'Attachments', 'attachments' ), 'attachments_add', $post_type->name, 'normal' );
221
+ }
222
+ }
223
+ }
224
  }
225
 
226
 
227
 
228
  /**
229
+ * Echos JavaScript that sets some required global variables
230
+ *
231
+ * @return void
232
+ * @author Jonathan Christopher
233
+ */
234
  function attachments_init_js()
235
  {
236
+ global $pagenow;
237
+
238
+ echo '<script type="text/javascript" charset="utf-8">';
239
+ echo ' var attachments_base = "' . WP_PLUGIN_URL . '/attachments"; ';
240
+ echo ' var attachments_media = ""; ';
241
+ if ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow )
242
+ {
243
+ echo ' var attachments_upload = true; ';
244
+ }
245
+ else
246
+ {
247
+ echo ' var attachments_upload = false; ';
248
+ }
249
+ if( ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow ) && is_attachments_context() )
250
+ {
251
+ echo ' var attachments_is_attachments_context = true; ';
252
+ }
253
+ else
254
+ {
255
+ echo ' var attachments_is_attachments_context = false; ';
256
+ }
257
+ echo '</script>';
258
  }
259
 
260
 
261
 
262
  /**
263
+ * Fired when Post or Page is saved. Serializes all attachment data and saves to post_meta
264
+ *
265
+ * @param int $post_id The ID of the current post
266
+ * @return void
267
+ * @author Jonathan Christopher
268
+ * @author JR Tashjian
269
+ */
270
  function attachments_save($post_id)
271
  {
272
+ // verify this came from the our screen and with proper authorization,
273
+ // because save_post can be triggered at other times
274
+ if( !isset( $_POST['attachments_nonce'] ) )
275
+ {
276
+ return $post_id;
277
+ }
278
+
279
+ if( !wp_verify_nonce( $_POST['attachments_nonce'], plugin_basename(__FILE__) ) )
280
+ {
281
+ return $post_id;
282
+ }
283
+
284
+ // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
285
+ // to do anything
286
+ if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
287
+ {
288
+ return $post_id;
289
+ }
290
+
291
+ // Check permissions
292
+ if( 'page' == $_POST['post_type'] )
293
+ {
294
+ if( !current_user_can( 'edit_page', $post_id ) )
295
+ {
296
+ return $post_id;
297
+ }
298
+ }
299
+ else
300
+ {
301
+ if( !current_user_can( 'edit_post', $post_id ) )
302
+ {
303
+ return $post_id;
304
+ }
305
+ }
306
+
307
+ // OK, we're authenticated: we need to find and save the data
308
+
309
+ // delete all current attachments meta
310
+ // moved outside conditional, else we can never delete all attachments
311
+ delete_post_meta( $post_id, '_attachments' );
312
+
313
+ // Since we're allowing Attachments to be sortable, we can't simply increment a counter
314
+ // we need to keep track of the IDs we're given
315
+ $attachment_ids = array();
316
+
317
+ // We'll build our array of attachments
318
+ foreach( $_POST as $key => $data )
319
+ {
320
+ // Arbitrarily using the id
321
+ if( substr($key, 0, 14) == 'attachment_id_' )
322
+ {
323
+ array_push( $attachment_ids, substr( $key, 14, strlen( $key ) ) );
324
+ }
325
+
326
+ }
327
+
328
+ // If we have attachments, there's work to do
329
+ if( !empty( $attachment_ids ) )
330
+ {
331
+
332
+ foreach ( $attachment_ids as $i )
333
+ {
334
+ if( !empty( $_POST['attachment_id_' . $i] ) )
335
+ {
336
+ $attachment_details = array(
337
+ 'id' => $_POST['attachment_id_' . $i],
338
+ 'title' => str_replace( '"', '&quot;', $_POST['attachment_title_' . $i] ),
339
+ 'caption' => str_replace( '"', '&quot;', $_POST['attachment_caption_' . $i] ),
340
+ 'order' => $_POST['attachment_order_' . $i]
341
+ );
342
+
343
+ // serialize data and encode
344
+ $attachment_serialized = base64_encode( serialize( $attachment_details ) );
345
+
346
+ // add individual attachment
347
+ add_post_meta( $post_id, '_attachments', $attachment_serialized );
348
+ }
349
+ }
350
+
351
+ }
352
+
353
  }
354
 
355
 
356
 
357
  /**
358
+ * Retrieves all Attachments for provided Post or Page
359
+ *
360
+ * @param int $post_id (optional) ID of target Post or Page, otherwise pulls from global $post
361
+ * @return array $post_attachments
362
+ * @author Jonathan Christopher
363
+ * @author JR Tashjian
364
+ */
365
  function attachments_get_attachments( $post_id=null )
366
  {
367
+ global $post;
368
+
369
+ if( $post_id==null )
370
+ {
371
+ $post_id = $post->ID;
372
+ }
373
+
374
+ // get all attachments
375
+ $existing_attachments = get_post_meta( $post_id, '_attachments', false );
376
+
377
+ if( !empty( $existing_attachments ) )
378
+ {
379
+ try
380
+ {
381
+ $legacy_existing_attachments = unserialize( $existing_attachments[0] );
382
+ }
383
+ catch( Exception $e )
384
+ {
385
+ // unserialization failed
386
+ }
387
+ }
388
+
389
+ // Check for legacy attachments
390
+ if( isset( $legacy_existing_attachments ) )
391
+ {
392
+ if( is_array( $legacy_existing_attachments ) )
393
+ {
394
+ $tmp_legacy_attachments = array();
395
+
396
+ // Legacy attachments (single serialized record)
397
+ foreach ( $legacy_existing_attachments as $legacy_attachment )
398
+ {
399
+ array_push( $tmp_legacy_attachments, base64_encode( serialize( $legacy_attachment ) ) );
400
+ }
401
+
402
+ $existing_attachments = $tmp_legacy_attachments;
403
+ }
404
+ }
405
+
406
+
407
+ // We can now proceed as normal, all legacy data should now be upgraded
408
+
409
+ $post_attachments = array();
410
+
411
+ if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
412
+ {
413
+
414
+ foreach ($existing_attachments as $attachment)
415
+ {
416
+ // decode and unserialize the data
417
+ $data = unserialize( base64_decode( $attachment ) );
418
+
419
+ array_push( $post_attachments, array(
420
+ 'id' => stripslashes( $data['id'] ),
421
+ 'name' => stripslashes( get_the_title( $data['id'] ) ),
422
+ 'mime' => stripslashes( get_post_mime_type( $data['id'] ) ),
423
+ 'title' => stripslashes( $data['title'] ),
424
+ 'caption' => stripslashes( $data['caption'] ),
425
+ 'location' => stripslashes( wp_get_attachment_url( $data['id'] ) ),
426
+ 'order' => stripslashes( $data['order'] )
427
+ ));
428
+ }
429
+
430
+ // sort attachments
431
+ if( count( $post_attachments ) > 1 )
432
+ {
433
+ usort( $post_attachments, "attachments_cmp" );
434
+ }
435
+ }
436
+
437
+ return $post_attachments;
438
  }
439
 
440
 
441
  if( !function_exists( 'fix_async_upload_image' ) )
442
  {
443
+ function fix_async_upload_image() {
444
+ if( isset( $_REQUEST['attachment_id'] ) )
445
+ {
446
+ $GLOBALS['post'] = get_post( $_REQUEST['attachment_id'] );
447
+ }
448
+ }
449
  }
450
 
451
  function is_attachments_context()
452
  {
453
+ global $pagenow;
454
+
455
+ // if post_id is set, it's the editor upload...
456
+ if ( ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow ) && empty( $_REQUEST['post_id'] ) )
457
+ {
458
+ return true;
459
+ }
460
+ return false;
461
  }
462
 
463
  function hijack_thickbox_text($translated_text, $source_text, $domain)
464
  {
465
+ if ( is_attachments_context() )
466
+ {
467
+ if ('Insert into Post' == $source_text) {
468
+ return __('Attach', 'attachments' );
469
+ }
470
+ }
471
+ return $translated_text;
472
  }
473
 
474
 
476
 
477
 
478
  /**
479
+ * This is the main initialization function, it will invoke the necessary meta_box
480
+ *
481
+ * @return void
482
+ * @author Jonathan Christopher
483
+ */
484
 
485
  function attachments_init()
486
  {
487
+ global $pagenow;
488
+
489
+ wp_enqueue_script( 'jquery-ui-core' );
490
+ wp_enqueue_style( 'thickbox' );
491
+
492
+ if ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow )
493
+ {
494
+ add_filter( 'gettext', 'hijack_thickbox_text', 1, 3 );
495
+ }
496
+
497
+ wp_enqueue_style( 'attachments', WP_PLUGIN_URL . '/attachments/css/attachments.css' );
498
+ wp_enqueue_script( 'attachments', WP_PLUGIN_URL . '/attachments/js/attachments.js', array( 'thickbox' ), false, false );
499
+
500
+ if( function_exists( 'load_plugin_textdomain' ) )
501
+ {
502
+ if( !defined('WP_PLUGIN_DIR') )
503
+ {
504
+ load_plugin_textdomain( 'attachments', str_replace( ABSPATH, '', dirname( __FILE__ ) ) );
505
+ }
506
+ else
507
+ {
508
+ load_plugin_textdomain( 'attachments', false, dirname( plugin_basename( __FILE__ ) ) );
509
+ }
510
+ }
511
+
512
+ attachments_meta_box();
513
  }
js/attachments.js CHANGED
@@ -22,10 +22,10 @@ function str_replace (search, replace, subject, count) {
22
  // * returns 2: 'hemmo, mars'
23
 
24
  var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
25
- f = [].concat(search),
26
- r = [].concat(replace),
27
- s = subject,
28
- ra = r instanceof Array, sa = s instanceof Array;
29
  s = [].concat(s);
30
  if (count) {
31
  this.window[count] = 0;
@@ -41,128 +41,128 @@ function str_replace (search, replace, subject, count) {
41
  s[i] = (temp).split(f[j]).join(repl);
42
  if (count && s[i] !== temp) {
43
  this.window[count] += (temp.length-s[i].length)/f[j].length;}
 
44
  }
 
45
  }
46
- return sa ? s : s[0];
47
- }
48
-
49
-
50
-
51
-
52
- function init_attachments_sortable() {
53
- if(jQuery('div#attachments-list ul:data(sortable)').length==0&&jQuery('div#attachments-list ul li').length>0){
54
- jQuery('div#attachments-list ul').sortable({
55
- containment: 'parent',
56
- stop: function(e, ui) {
57
- jQuery('#attachments-list ul li').each(function(i, id) {
58
- jQuery(this).find('input.attachment_order').val(i+1);
59
- });
60
- }
61
- });
62
- }
63
- }
64
-
65
-
66
-
67
-
68
- function attachments_handle_attach(title,caption,id,thumb){
69
-
70
- attachment_index = jQuery('li.attachments-file', top.document).length;
71
- new_attachments = '';
72
-
73
- attachment_name = title;
74
- attachment_caption = caption;
75
- attachment_id = id;
76
- attachment_thumb = thumb;
77
-
78
- attachment_index++;
79
- new_attachments += '<li class="attachments-file">';
80
- new_attachments += '<h2><a href="#" class="attachment-handle"><span class="attachment-handle-icon"><img src="' + attachments_base + '/images/handle.gif" alt="Drag" /></span></a><span class="attachment-name">' + attachment_name + '</span><span class="attachment-delete"><a href="#">Delete</a></span></h2>';
81
- new_attachments += '<div class="attachments-fields">';
82
- new_attachments += '<div class="textfield" id="field_attachment_title_' + attachment_index + '"><label for="attachment_title_' + attachment_index + '">Title</label><input type="text" id="attachment_title_' + attachment_index + '" name="attachment_title_' + attachment_index + '" value="' + attachment_name + '" size="20" /></div>';
83
- new_attachments += '<div class="textfield" id="field_attachment_caption_' + attachment_index + '"><label for="attachment_caption_' + attachment_index + '">Caption</label><input type="text" id="attachment_caption_' + attachment_index + '" name="attachment_caption_' + attachment_index + '" value="' + attachment_caption + '" size="20" /></div>';
84
- new_attachments += '</div>';
85
- new_attachments += '<div class="attachments-data">';
86
- new_attachments += '<input type="hidden" name="attachment_id_' + attachment_index + '" id="attachment_id_' + attachment_index + '" value="' + attachment_id + '" />';
87
- new_attachments += '<input type="hidden" class="attachment_order" name="attachment_order_' + attachment_index + '" id="attachment_order_' + attachment_index + '" value="' + attachment_index + '" />';
88
- new_attachments += '</div>';
89
- new_attachments += '<div class="attachment-thumbnail"><span class="attachments-thumbnail">';
90
-
91
-
92
- new_attachments += '<img src="' + attachment_thumb + '" alt="Thumbnail" />';
93
- new_attachments += '</span></div>';
94
- new_attachments += '</li>';
95
-
96
- jQuery('div#attachments-list ul', top.document).append(new_attachments);
97
-
98
- if(jQuery('#attachments-list li', top.document).length > 0) {
99
-
100
- // We've got some attachments
101
- jQuery('#attachments-list', top.document).show();
102
-
103
- }
104
- }
105
-
106
-
107
- jQuery(document).ready(function() {
108
-
109
- if(attachments_is_attachments_context)
110
- {
111
- jQuery('body').addClass('attachments-media-upload');
112
-
113
- // we need to hijack the Attach button
114
- jQuery('td.savesend input').live('click',function(e){
115
- theparent = jQuery(this).parent().parent().parent();
116
- thetitle = theparent.find('tr.post_title td.field input').val();
117
- thecaption = theparent.find('tr.post_excerpt td.field input').val();
118
- theid = str_replace( 'imgedit-response-', '', theparent.find('td.imgedit-response').attr('id') );
119
- thethumb = theparent.parent().parent().find('img.pinkynail').attr('src');
120
- attachments_handle_attach(thetitle,thecaption,theid,thethumb);
121
- jQuery(this).after('<span class="attachments-attached-note"> Attached</span>').parent().find('span.attachments-attached-note').delay(1000).fadeOut();
122
- return false;
123
- });
124
- }
125
-
126
- // we're going to handle the Thickbox
127
- jQuery("body").click(function(event) {
128
- if (jQuery(event.target).is('a#attachments-thickbox')) {
129
- tb_show("Attach a file", event.target.href, false);
130
- return false;
131
- }
132
- });
133
-
134
- // Modify thickbox link to fit window. Adapted from wp-admin\js\media-upload.dev.js.
135
- jQuery('a#attachments-thickbox').each( function() {
136
- var href = jQuery(this).attr('href'), width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 < width ) ? 720 : width;
137
- if ( ! href ) return;
138
- href = href.replace(/&width=[0-9]+/g, '');
139
- href = href.replace(/&height=[0-9]+/g, '');
140
- jQuery(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 ) );
141
- });
142
-
143
- // If there are no attachments, let's hide this thing...
144
- if(jQuery('div#attachments-list li').length == 0) {
145
- jQuery('#attachments-list').hide();
146
- }
147
-
148
- // Hook our delete links
149
- jQuery('span.attachment-delete a').live('click', function() {
150
- attachment_parent = jQuery(this).parent().parent().parent();
151
- attachment_parent.slideUp(function() {
152
- attachment_parent.remove();
153
- jQuery('#attachments-list ul li').each(function(i, id) {
154
- jQuery(this).find('input.attachment_order').val(i+1);
155
- });
156
- if(jQuery('div#attachments-list li').length == 0) {
157
- jQuery('#attachments-list').slideUp(function() {
158
- jQuery('#attachments-list').hide();
159
- });
160
- }
161
- });
162
- return false;
163
- });
164
-
165
- // we also need to get a bit hacky with sortable...
166
- setInterval('init_attachments_sortable()',500);
167
-
168
- });
22
  // * returns 2: 'hemmo, mars'
23
 
24
  var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
25
+ f = [].concat(search),
26
+ r = [].concat(replace),
27
+ s = subject,
28
+ ra = r instanceof Array, sa = s instanceof Array;
29
  s = [].concat(s);
30
  if (count) {
31
  this.window[count] = 0;
41
  s[i] = (temp).split(f[j]).join(repl);
42
  if (count && s[i] !== temp) {
43
  this.window[count] += (temp.length-s[i].length)/f[j].length;}
44
+ }
45
  }
46
+ return sa ? s : s[0];
47
  }
48
+
49
+
50
+
51
+
52
+ function init_attachments_sortable() {
53
+ if(jQuery('div#attachments-list ul:data(sortable)').length==0&&jQuery('div#attachments-list ul li').length>0){
54
+ jQuery('div#attachments-list ul').sortable({
55
+ containment: 'parent',
56
+ stop: function(e, ui) {
57
+ jQuery('#attachments-list ul li').each(function(i, id) {
58
+ jQuery(this).find('input.attachment_order').val(i+1);
59
+ });
60
+ }
61
+ });
62
+ }
63
+ }
64
+
65
+
66
+
67
+
68
+ function attachments_handle_attach(title,caption,id,thumb){
69
+
70
+ attachment_index = jQuery('li.attachments-file', top.document).length;
71
+ new_attachments = '';
72
+
73
+ attachment_name = title;
74
+ attachment_caption = caption;
75
+ attachment_id = id;
76
+ attachment_thumb = thumb;
77
+
78
+ attachment_index++;
79
+ new_attachments += '<li class="attachments-file">';
80
+ new_attachments += '<h2><a href="#" class="attachment-handle"><span class="attachment-handle-icon"><img src="' + attachments_base + '/images/handle.gif" alt="Drag" /></span></a><span class="attachment-name">' + attachment_name + '</span><span class="attachment-delete"><a href="#">Delete</a></span></h2>';
81
+ new_attachments += '<div class="attachments-fields">';
82
+ new_attachments += '<div class="textfield" id="field_attachment_title_' + attachment_index + '"><label for="attachment_title_' + attachment_index + '">Title</label><input type="text" id="attachment_title_' + attachment_index + '" name="attachment_title_' + attachment_index + '" value="' + attachment_name + '" size="20" /></div>';
83
+ new_attachments += '<div class="textfield" id="field_attachment_caption_' + attachment_index + '"><label for="attachment_caption_' + attachment_index + '">Caption</label><input type="text" id="attachment_caption_' + attachment_index + '" name="attachment_caption_' + attachment_index + '" value="' + attachment_caption + '" size="20" /></div>';
84
+ new_attachments += '</div>';
85
+ new_attachments += '<div class="attachments-data">';
86
+ new_attachments += '<input type="hidden" name="attachment_id_' + attachment_index + '" id="attachment_id_' + attachment_index + '" value="' + attachment_id + '" />';
87
+ new_attachments += '<input type="hidden" class="attachment_order" name="attachment_order_' + attachment_index + '" id="attachment_order_' + attachment_index + '" value="' + attachment_index + '" />';
88
+ new_attachments += '</div>';
89
+ new_attachments += '<div class="attachment-thumbnail"><span class="attachments-thumbnail">';
90
+
91
+
92
+ new_attachments += '<img src="' + attachment_thumb + '" alt="Thumbnail" />';
93
+ new_attachments += '</span></div>';
94
+ new_attachments += '</li>';
95
+
96
+ jQuery('div#attachments-list ul', top.document).append(new_attachments);
97
+
98
+ if(jQuery('#attachments-list li', top.document).length > 0) {
99
+
100
+ // We've got some attachments
101
+ jQuery('#attachments-list', top.document).show();
102
+
103
+ }
104
+ }
105
+
106
+
107
+ jQuery(document).ready(function() {
108
+
109
+ if(attachments_is_attachments_context)
110
+ {
111
+ jQuery('body').addClass('attachments-media-upload');
112
+
113
+ // we need to hijack the Attach button
114
+ jQuery('td.savesend input').live('click',function(e){
115
+ theparent = jQuery(this).parent().parent().parent();
116
+ thetitle = theparent.find('tr.post_title td.field input').val();
117
+ thecaption = theparent.find('tr.post_excerpt td.field input').val();
118
+ theid = str_replace( 'imgedit-response-', '', theparent.find('td.imgedit-response').attr('id') );
119
+ thethumb = theparent.parent().parent().find('img.pinkynail').attr('src');
120
+ attachments_handle_attach(thetitle,thecaption,theid,thethumb);
121
+ jQuery(this).after('<span class="attachments-attached-note"> Attached</span>').parent().find('span.attachments-attached-note').delay(1000).fadeOut();
122
+ return false;
123
+ });
124
+ }
125
+
126
+ // we're going to handle the Thickbox
127
+ jQuery("body").click(function(event) {
128
+ if (jQuery(event.target).is('a#attachments-thickbox')) {
129
+ tb_show("Attach a file", event.target.href, false);
130
+ return false;
131
+ }
132
+ });
133
+
134
+ // Modify thickbox link to fit window. Adapted from wp-admin\js\media-upload.dev.js.
135
+ jQuery('a#attachments-thickbox').each( function() {
136
+ var href = jQuery(this).attr('href'), width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 < width ) ? 720 : width;
137
+ if ( ! href ) return;
138
+ href = href.replace(/&width=[0-9]+/g, '');
139
+ href = href.replace(/&height=[0-9]+/g, '');
140
+ jQuery(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 ) );
141
+ });
142
+
143
+ // If there are no attachments, let's hide this thing...
144
+ if(jQuery('div#attachments-list li').length == 0) {
145
+ jQuery('#attachments-list').hide();
146
+ }
147
+
148
+ // Hook our delete links
149
+ jQuery('span.attachment-delete a').live('click', function() {
150
+ attachment_parent = jQuery(this).parent().parent().parent();
151
+ attachment_parent.slideUp(function() {
152
+ attachment_parent.remove();
153
+ jQuery('#attachments-list ul li').each(function(i, id) {
154
+ jQuery(this).find('input.attachment_order').val(i+1);
155
+ });
156
+ if(jQuery('div#attachments-list li').length == 0) {
157
+ jQuery('#attachments-list').slideUp(function() {
158
+ jQuery('#attachments-list').hide();
159
+ });
160
+ }
161
+ });
162
+ return false;
163
+ });
164
+
165
+ // we also need to get a bit hacky with sortable...
166
+ setInterval('init_attachments_sortable()',500);
167
+
168
+ });
 
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://mondaybynoon.com/donate/
4
  Tags: post, page, posts, pages, images, PDF, doc, Word, image, jpg, jpeg, picture, pictures, photos, attachment
5
  Requires at least: 3.0
6
  Tested up to: 3.1
7
- Stable tag: 1.5.1.2
8
 
9
  Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
10
 
@@ -12,7 +12,7 @@ Attachments allows you to simply append any number of items from your WordPress
12
 
13
  Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
14
 
15
- There is a **screencast available** on the [plugin home page](http://mondaybynoon.com/wordpress-attachments/)
16
 
17
  == Installation ==
18
 
@@ -33,7 +33,7 @@ Attachments uses WordPress' built in Media library for uploads and storage.
33
 
34
  = I lost my Attachments after upgrading! =
35
 
36
- ***Do not update any Post/Page with Attachments***, the data has not been lost. Please [contact me](http://mondaybynoon.com/contact/) to begin a bugfix
37
 
38
  == Screenshots ==
39
 
@@ -44,6 +44,13 @@ Attachments uses WordPress' built in Media library for uploads and storage.
44
 
45
  == Changelog ==
46
 
 
 
 
 
 
 
 
47
  = 1.5.1.2 =
48
  * Fixed bug with handling legacy Attachments data store
49
  * Updated localization hook for options screen
@@ -118,9 +125,12 @@ As always, be sure to back up your database and files before upgrading.
118
  = 1.0.7 =
119
  Attachments are now stored in such a way that removes an in-place limitation on string lengths for both titles and captions.
120
 
121
- == Screencast ==
 
 
122
 
123
- There is a **screencast available** on the [plugin home page](http://mondaybynoon.com/wordpress-attachments/)
 
124
 
125
  == Usage ==
126
 
@@ -139,19 +149,19 @@ Firing `attachments_get_attachments()` returns an array consisting of all availa
139
  Here is a basic implementation:
140
 
141
  `<?php
142
- $attachments = attachments_get_attachments();
143
- $total_attachments = count($attachments);
144
- if( $total_attachments > 0 )
145
  {
146
- echo '<ul>';
147
- for ($i=0; $i < $total_attachments; $i++)
148
- {
149
- echo '<li>' . $attachments[$i]['title'] . '</li>';
150
- echo '<li>' . $attachments[$i]['caption'] . '</li>';
151
- echo '<li>' . $attachments[$i]['id'] . '</li>';
152
- echo '<li>' . $attachments[$i]['location'] . '</li>';
153
- echo '<li>' . $attachments[$i]['mime'] . '</li>';
154
- }
155
- echo '</ul>';
156
- }
157
- ?>`
 
 
4
  Tags: post, page, posts, pages, images, PDF, doc, Word, image, jpg, jpeg, picture, pictures, photos, attachment
5
  Requires at least: 3.0
6
  Tested up to: 3.1
7
+ Stable tag: 1.5.2
8
 
9
  Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
10
 
12
 
13
  Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
14
 
15
+ There is an [outdated] **screencast available** on the [plugin home page](http://mondaybynoon.com/wordpress-attachments/) that will be upgraded soon.
16
 
17
  == Installation ==
18
 
33
 
34
  = I lost my Attachments after upgrading! =
35
 
36
+ ***DO NOT update any Post/Page/CPT with Attachments***, the data has not been lost. Please [contact me](http://mondaybynoon.com/contact/) to begin a bugfix
37
 
38
  == Screenshots ==
39
 
44
 
45
  == Changelog ==
46
 
47
+ = 1.5.2 =
48
+ * Added Swedish translation, courtesy of Sebastian Johansson
49
+ * 'Attach' button is now localized
50
+ * Fixed a couple of other miscellaneous localization issues
51
+ * Added Italian translation, courtesy of Andrea Bersi
52
+ * Fixed a number of PHP notices/warnings in more strict environments
53
+
54
  = 1.5.1.2 =
55
  * Fixed bug with handling legacy Attachments data store
56
  * Updated localization hook for options screen
125
  = 1.0.7 =
126
  Attachments are now stored in such a way that removes an in-place limitation on string lengths for both titles and captions.
127
 
128
+ == Roadmap ==
129
+
130
+ Planned feature additions include:
131
 
132
+ * Physically attaching Attachments to Posts/Pages/Custom Post Types on a WordPress level
133
+ * Modifying UI to provide ability to better bulk-add Attachments
134
 
135
  == Usage ==
136
 
149
  Here is a basic implementation:
150
 
151
  `<?php
152
+ if( function_exists( 'attachments_get_attachments' ) )
 
 
153
  {
154
+ $attachments = attachments_get_attachments();
155
+ $total_attachments = count( $attachments );
156
+ if( $total_attachments ) : ?>
157
+ <ul>
158
+ <?php for( $i=0; $i<$total_attachments; $i++ ) : ?>
159
+ <li><?php echo $attachments[$i]['title']; ?></li>
160
+ <li><?php echo $attachments[$i]['caption']; ?></li>
161
+ <li><?php echo $attachments[$i]['id']; ?></li>
162
+ <li><?php echo $attachments[$i]['location']; ?></li>
163
+ <li><?php echo $attachments[$i]['mime']; ?></li>
164
+ <?php endfor; ?>
165
+ </ul>
166
+ <?php endif; ?>
167
+ <?php } ?>`