Attachments - Version 3.1.3

Version Description

  • Fixed a potential issue with the WYSIWYG field not working on CPT without editor support
  • Field assets are less aggressive and only fire when necessary
  • Reorganized the migration process a bit in prep for Attachments Pro support
Download this release

Release Info

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

Code changes from version 3.1.2 to 3.1.3

README.md CHANGED
@@ -250,6 +250,11 @@ Attachments uses WordPress' built in Media library for uploads and storage.
250
 
251
  <dl>
252
 
 
 
 
 
 
253
  <dt>3.1.2</dt>
254
  <dd>Fixed a regression that prevented successful migration of legacy Attachments data</dd>
255
 
250
 
251
  <dl>
252
 
253
+ <dt>3.1.3</dt>
254
+ <dd>Fixed a potential issue with the WYSIWYG field not working on CPT without editor support</dd>
255
+ <dd>Field assets are less aggressive and only fire when necessary</dd>
256
+ <dd>Reorganized the migration process a bit in prep for Attachments Pro support</dd>
257
+
258
  <dt>3.1.2</dt>
259
  <dd>Fixed a regression that prevented successful migration of legacy Attachments data</dd>
260
 
classes/class.attachments.migrate.php ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if( !defined( 'ABSPATH' ) ) exit;
5
+
6
+ /**
7
+ * Migration class for legacy Attachments data
8
+ *
9
+ * @since 3.1.3
10
+ */
11
+ class AttachmentsMigrate extends Attachments
12
+ {
13
+
14
+ function __construct()
15
+ {
16
+ parent::__construct();
17
+ }
18
+
19
+ /**
20
+ * Migrate Attachments 1.x records to 3.0's format
21
+ *
22
+ * @since 3.0
23
+ */
24
+ function migrate( $instance = null, $title = null, $caption = null )
25
+ {
26
+ // sanitize
27
+ if( is_null( $instance ) || empty( $instance ) || is_null( $title ) || is_null( $caption ) )
28
+ return false;
29
+
30
+ $instance = str_replace( '-', '_', sanitize_title( $instance ) );
31
+ $title = empty( $title ) ? false : str_replace( '-', '_', sanitize_title( $title ) );
32
+ $caption = empty( $caption ) ? false : str_replace( '-', '_', sanitize_title( $caption ) );
33
+
34
+ // we need our deprecated functions
35
+ include_once( ATTACHMENTS_DIR . '/deprecated/get-attachments.php' );
36
+
37
+ $legacy_attachments_settings = get_option( 'attachments_settings' );
38
+
39
+ if( $legacy_attachments_settings && is_array( $legacy_attachments_settings['post_types'] ) && count( $legacy_attachments_settings['post_types'] ) )
40
+ {
41
+ // we have legacy settings, so we're going to use the post types
42
+ // that Attachments is currently utilizing
43
+
44
+ // the keys are the actual CPT names, so we need those
45
+ foreach( $legacy_attachments_settings['post_types'] as $post_type => $value )
46
+ if( $value )
47
+ $post_types[] = $post_type;
48
+
49
+ // set up our WP_Query args to grab anything with legacy data
50
+ $args = array(
51
+ 'post_type' => isset( $post_types ) ? $post_types : array(),
52
+ 'post_status' => 'any',
53
+ 'posts_per_page' => -1,
54
+ 'meta_key' => '_attachments',
55
+ );
56
+
57
+ $query = new WP_Query( $args );
58
+ }
59
+
60
+ $count = 0;
61
+
62
+ // loop through each post
63
+ if( $query ) { while( $query->have_posts() )
64
+ {
65
+ // set up postdata
66
+ $query->the_post();
67
+
68
+ // let's first decode our Attachments data
69
+ $existing_attachments = get_post_meta( $query->post->ID, '_attachments', false );
70
+
71
+ $post_attachments = array();
72
+
73
+ // check to make sure we've got data
74
+ if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
75
+ {
76
+ // loop through each existing attachment
77
+ foreach( $existing_attachments as $attachment )
78
+ {
79
+ // decode and unserialize the data
80
+ $data = unserialize( base64_decode( $attachment ) );
81
+
82
+ array_push( $post_attachments, array(
83
+ 'id' => stripslashes( $data['id'] ),
84
+ 'title' => stripslashes( $data['title'] ),
85
+ 'caption' => stripslashes( $data['caption'] ),
86
+ 'order' => stripslashes( $data['order'] )
87
+ ));
88
+ }
89
+
90
+ // sort attachments
91
+ if( count( $post_attachments ) > 1 )
92
+ {
93
+ usort( $post_attachments, 'attachments_cmp' );
94
+ }
95
+ }
96
+
97
+ // we have our Attachments entries
98
+
99
+ // let's check to see if we're migrating after population has taken place
100
+ $existing_attachments = get_post_meta( $query->post->ID, 'attachments', false );
101
+
102
+ if( !isset( $existing_attachments[0] ) )
103
+ $existing_attachments[0] = '';
104
+
105
+ $existing_attachments = json_decode( $existing_attachments[0] );
106
+
107
+ if( !is_object( $existing_attachments ) )
108
+ $existing_attachments = new stdClass();
109
+
110
+ // we'll loop through the legacy Attachments and save them in the new format
111
+ foreach( $post_attachments as $legacy_attachment )
112
+ {
113
+ // convert to the new format
114
+ $converted_attachment = array( 'id' => $legacy_attachment['id'] );
115
+
116
+ // fields are technically optional so we'll add those separately
117
+ // we're also going to encode them in the same way the main class does
118
+ if( $title )
119
+ $converted_attachment['fields'][$title] = htmlentities( stripslashes( $legacy_attachment['title'] ), ENT_QUOTES, 'UTF-8' );
120
+
121
+ if( $caption )
122
+ $converted_attachment['fields'][$caption] = htmlentities( stripslashes( $legacy_attachment['caption'] ), ENT_QUOTES, 'UTF-8' );
123
+
124
+ // check to see if the existing Attachments have our target instance
125
+ if( !isset( $existing_attachments->$instance ) )
126
+ {
127
+ // the instance doesn't exist so we need to create it
128
+ $existing_attachments->$instance = array();
129
+ }
130
+
131
+ // we need to convert our array to an object
132
+ $converted_attachment['fields'] = (object) $converted_attachment['fields'];
133
+ $converted_attachment = (object) $converted_attachment;
134
+
135
+ // append this legacy attachment to the existing instance
136
+ array_push( $existing_attachments->$instance, $converted_attachment );
137
+ }
138
+
139
+ // we're done! let's save everything in our new format
140
+ $existing_attachments = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $existing_attachments, JSON_UNESCAPED_UNICODE ) : json_encode( $existing_attachments );
141
+
142
+ // save it to the database
143
+ update_post_meta( $query->post->ID, 'attachments', $existing_attachments );
144
+
145
+ // increment our counter
146
+ $count++;
147
+ } }
148
+
149
+ return $count;
150
+ }
151
+
152
+
153
+
154
+ /**
155
+ * Step 1 of the migration process. Allows the user to define the target instance and field names.
156
+ *
157
+ * @since 3.2
158
+ */
159
+ function prepare_migration()
160
+ {
161
+ if( !wp_verify_nonce( $_GET['nonce'], 'attachments-migrate-1') ) wp_die( __( 'Invalid request', 'attachments' ) );
162
+ ?>
163
+ <h3><?php _e( 'Migration Step 1', 'attachments' ); ?></h3>
164
+ <p><?php _e( "In order to migrate Attachments 1.x data, you need to set which instance and fields in version 3.0+ you'd like to use:", 'attachments' ); ?></p>
165
+ <form action="options-general.php" method="get">
166
+ <input type="hidden" name="page" value="attachments" />
167
+ <input type="hidden" name="migrate" value="2" />
168
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'attachments-migrate-2' ); ?>" />
169
+ <table class="form-table">
170
+ <tbody>
171
+ <tr valign="top">
172
+ <th scope="row">
173
+ <label for="attachments-instance"><?php _e( 'Attachments 3.x Instance', 'attachments' ); ?></label>
174
+ </th>
175
+ <td>
176
+ <input name="attachments-instance" id="attachments-instance" value="attachments" class="regular-text" />
177
+ <p class="description"><?php _e( 'The instance name you would like to use in the migration. Required.', 'attachments' ); ?></p>
178
+ </td>
179
+ </tr>
180
+ <tr valign="top">
181
+ <th scope="row">
182
+ <label for="attachments-title"><?php _e( 'Attachments 3.x Title', 'attachments' ); ?></label>
183
+ </th>
184
+ <td>
185
+ <input name="attachments-title" id="attachments-title" value="title" class="regular-text" />
186
+ <p class="description"><?php _e( 'The <code>Title</code> field data will be migrated to this field name in Attachments 3.x. Leave empty to disregard.', 'attachments' ); ?></p>
187
+ </td>
188
+ </tr>
189
+ <tr valign="top">
190
+ <th scope="row">
191
+ <label for="attachments-caption"><?php _e( 'Attachments 3.x Caption', 'attachments' ); ?></label>
192
+ </th>
193
+ <td>
194
+ <input name="attachments-caption" id="attachments-caption" value="caption" class="regular-text" />
195
+ <p class="description"><?php _e( 'The <code>Caption</code> field data will be migrated to this field name in Attachments 3.x. Leave empty to disregard.', 'attachments' ); ?></p>
196
+ </td>
197
+ </tr>
198
+ </tbody>
199
+ </table>
200
+ <p class="submit">
201
+ <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e( 'Start Migration', 'attachments' ); ?>" />
202
+ </p>
203
+ </form>
204
+ <?php
205
+ }
206
+
207
+
208
+
209
+ /**
210
+ * Step 2 of the migration process. Validates migration requests and fires the migration method.
211
+ *
212
+ * @since 3.2
213
+ */
214
+ function init_migration()
215
+ {
216
+ if( !wp_verify_nonce( $_GET['nonce'], 'attachments-migrate-2') )
217
+ wp_die( __( 'Invalid request', 'attachments' ) );
218
+
219
+ $total = $this->migrate( $_GET['attachments-instance'], $_GET['attachments-title'], $_GET['attachments-caption'] );
220
+
221
+ if( false == get_option( 'attachments_migrated' ) ) :
222
+ ?>
223
+ <h3><?php _e( 'Migration Complete!', 'attachments' ); ?></h3>
224
+ <p><?php _e( 'The migration has completed.', 'attachments' ); ?> <strong><?php _e( 'Migrated', 'attachments'); ?>: <?php echo $total; ?></strong>.</p>
225
+ <?php else : ?>
226
+ <h3><?php _e( 'Migration has already Run!', 'attachments' ); ?></h3>
227
+ <p><?php _e( 'The migration has already been run. The migration process has not been repeated.', 'attachments' ); ?></p>
228
+ <?php endif;
229
+
230
+ // make sure the database knows the migration has run
231
+ add_option( 'attachments_migrated', true, '', 'no' );
232
+ }
233
+
234
+ }
classes/class.attachments.php CHANGED
@@ -32,6 +32,8 @@ if ( !class_exists( 'Attachments' ) ) :
32
  private $fields; // stores all registered field types
33
  private $attachments; // stores all of the Attachments for the given instance
34
 
 
 
35
  private $image_sizes = array( 'full' ); // store all registered image sizes
36
  private $default_instance = true; // use the default instance?
37
  private $attachments_ref = -1; // flags where a get() loop last did it's thing
@@ -56,7 +58,8 @@ if ( !class_exists( 'Attachments' ) ) :
56
  global $_wp_additional_image_sizes;
57
 
58
  // establish our environment variables
59
- $this->version = '3.1.2';
 
60
  $this->url = ATTACHMENTS_URL;
61
  $this->dir = ATTACHMENTS_DIR;
62
 
@@ -64,47 +67,35 @@ if ( !class_exists( 'Attachments' ) ) :
64
  include_once( ATTACHMENTS_DIR . 'upgrade.php' );
65
  include_once( ATTACHMENTS_DIR . '/classes/class.field.php' );
66
 
 
 
 
67
  // deal with our legacy issues if the user hasn't dismissed or migrated already
68
- if( false == get_option( 'attachments_migrated' ) && false == get_option( 'attachments_ignore_migration' ) )
69
- {
70
- // TODO: this will not retrieve posts that have exclude_from_search = true
71
- // TODO: make this reusable elsewhere
72
- $legacy = new WP_Query( 'post_type=any&post_status=any&posts_per_page=1&meta_key=_attachments' );
73
- $this->legacy = empty( $legacy->found_posts ) ? false : true;
74
- }
75
- else
76
- {
77
- $this->legacy = false;
78
- }
79
 
80
  // set our image sizes
81
  $this->image_sizes = array_merge( $this->image_sizes, get_intermediate_image_sizes() );
82
 
83
- // include our fields
84
- $this->fields = $this->get_field_types();
85
-
86
  // hook into WP
87
- add_action( 'admin_enqueue_scripts', array( $this, 'assets' ), 999, 1 );
88
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_pointer' ), 999 );
89
 
90
  // register our user-defined instances
91
- add_action( 'init', array( $this, 'do_actions_filters' ) );
92
 
93
  // determine which instances apply to the current post type
94
- add_action( 'init', array( $this, 'set_instances_for_current_post_type' ) );
95
-
96
- add_action( 'add_meta_boxes', array( $this, 'meta_box_init' ) );
97
-
98
- add_action( 'admin_footer', array( $this, 'admin_footer' ) );
99
 
100
- add_action( 'save_post', array( $this, 'save' ) );
101
-
102
- add_action( 'admin_menu', array( $this, 'admin_page' ) );
 
103
 
104
  // with version 3 we'll be giving at least one admin notice
105
- add_action( 'admin_notices', array( $this, 'admin_notice' ) );
106
 
107
- add_action( 'admin_print_footer_scripts', array( $this, 'field_assets' ) );
 
108
 
109
  // set our attachments if necessary
110
  if( !is_null( $instance ) )
@@ -113,6 +104,59 @@ if ( !class_exists( 'Attachments' ) ) :
113
 
114
 
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  /**
117
  * Returns whether or not the current object has any Attachments
118
  *
@@ -496,7 +540,7 @@ if ( !class_exists( 'Attachments' ) ) :
496
 
497
  // only thumbnails have sizes which is what we're on the hunt for
498
  if(attachments_isset(attachment.attributes.sizes)){
499
- if(attachments_isset(attachment.attributes.sizes.thumbnail)){
500
  if(attachments_isset(attachment.attributes.sizes.thumbnail.url)){
501
  // use the thumbnail
502
  attachment.attributes.attachment_thumb = attachment.attributes.sizes.thumbnail.url;
@@ -936,19 +980,26 @@ if ( !class_exists( 'Attachments' ) ) :
936
 
937
 
938
 
 
 
 
 
 
939
  function field_assets()
940
  {
 
 
 
 
 
 
941
  // all metaboxes have been put in place, we can now determine which field assets need to be included
942
 
943
  // first we'll get a list of the field types on screen
944
  $fieldtypes = array();
945
  foreach( $this->instances_for_post_type as $instance )
946
- {
947
  foreach( $this->instances[$instance]['fields'] as $field )
948
- {
949
  $fieldtypes[] = $field['type'];
950
- }
951
- }
952
 
953
  // we only want to dump out assets once for each field type
954
  $fieldtypes = array_unique( $fieldtypes );
@@ -963,6 +1014,40 @@ if ( !class_exists( 'Attachments' ) ) :
963
 
964
 
965
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
966
  /**
967
  * Outputs all necessary Backbone templates
968
  * Each Backbone template includes each field present in an instance
@@ -1287,4 +1372,4 @@ if ( !class_exists( 'Attachments' ) ) :
1287
 
1288
  endif; // class_exists check
1289
 
1290
- new Attachments();
32
  private $fields; // stores all registered field types
33
  private $attachments; // stores all of the Attachments for the given instance
34
 
35
+ private $legacy = false; // whether or not there is legacy Attachments data
36
+ private $legacy_pro = false; // whether or not there is legacy Attachment Pro data
37
  private $image_sizes = array( 'full' ); // store all registered image sizes
38
  private $default_instance = true; // use the default instance?
39
  private $attachments_ref = -1; // flags where a get() loop last did it's thing
58
  global $_wp_additional_image_sizes;
59
 
60
  // establish our environment variables
61
+
62
+ $this->version = '3.1.3';
63
  $this->url = ATTACHMENTS_URL;
64
  $this->dir = ATTACHMENTS_DIR;
65
 
67
  include_once( ATTACHMENTS_DIR . 'upgrade.php' );
68
  include_once( ATTACHMENTS_DIR . '/classes/class.field.php' );
69
 
70
+ // include our fields
71
+ $this->fields = $this->get_field_types();
72
+
73
  // deal with our legacy issues if the user hasn't dismissed or migrated already
74
+ $this->check_for_legacy_data();
 
 
 
 
 
 
 
 
 
 
75
 
76
  // set our image sizes
77
  $this->image_sizes = array_merge( $this->image_sizes, get_intermediate_image_sizes() );
78
 
 
 
 
79
  // hook into WP
80
+ add_action( 'admin_enqueue_scripts', array( $this, 'assets' ), 999, 1 );
81
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_pointer' ), 999 );
82
 
83
  // register our user-defined instances
84
+ add_action( 'init', array( $this, 'do_actions_filters' ) );
85
 
86
  // determine which instances apply to the current post type
87
+ add_action( 'init', array( $this, 'set_instances_for_current_post_type' ) );
 
 
 
 
88
 
89
+ add_action( 'add_meta_boxes', array( $this, 'meta_box_init' ) );
90
+ add_action( 'admin_footer', array( $this, 'admin_footer' ) );
91
+ add_action( 'save_post', array( $this, 'save' ) );
92
+ add_action( 'admin_menu', array( $this, 'admin_page' ) );
93
 
94
  // with version 3 we'll be giving at least one admin notice
95
+ add_action( 'admin_notices', array( $this, 'admin_notice' ) );
96
 
97
+ add_action( 'admin_head', array( $this, 'field_inits' ) );
98
+ add_action( 'admin_print_footer_scripts', array( $this, 'field_assets' ) );
99
 
100
  // set our attachments if necessary
101
  if( !is_null( $instance ) )
104
 
105
 
106
 
107
+ /**
108
+ * Stores whether or not this environment has active legacy Attachments/Pro data
109
+ *
110
+ * @since 3.1.3
111
+ */
112
+ function check_for_legacy_data()
113
+ {
114
+ // deal with our legacy issues if the user hasn't dismissed or migrated already
115
+ if( false == get_option( 'attachments_migrated' ) && false == get_option( 'attachments_ignore_migration' ) )
116
+ {
117
+ $legacy_attachments_settings = get_option( 'attachments_settings' );
118
+
119
+ if( $legacy_attachments_settings && is_array( $legacy_attachments_settings['post_types'] ) && count( $legacy_attachments_settings['post_types'] ) )
120
+ {
121
+ // we have legacy settings, so we're going to use the post types
122
+ // that Attachments is currently utilizing
123
+
124
+ // the keys are the actual CPT names, so we need those
125
+ foreach( $legacy_attachments_settings['post_types'] as $post_type => $value )
126
+ if( $value )
127
+ $post_types[] = $post_type;
128
+
129
+ // set up our WP_Query args to grab anything with legacy data
130
+ $args = array(
131
+ 'post_type' => isset( $post_types ) ? $post_types : array(),
132
+ 'post_status' => 'any',
133
+ 'posts_per_page' => 1,
134
+ 'meta_key' => '_attachments',
135
+ );
136
+
137
+ $legacy = new WP_Query( $args );
138
+ $this->legacy = empty( $legacy->found_posts ) ? false : true;
139
+ }
140
+ }
141
+
142
+ // deal with our legacy Pro issues if the user hasn't dismissed or migrated already
143
+ if( false == get_option( 'attachments_pro_migrated' ) && false == get_option( 'attachments_pro_ignore_migration' ) )
144
+ {
145
+ // set up our WP_Query args to grab anything (really anything) with legacy data
146
+ $args = array(
147
+ 'post_type' => get_post_types(),
148
+ 'post_status' => 'any',
149
+ 'posts_per_page' => 1,
150
+ 'meta_key' => '_attachments_pro',
151
+ );
152
+
153
+ $legacy_pro = new WP_Query( $args );
154
+ $this->legacy_pro = empty( $legacy_pro->found_posts ) ? false : true;
155
+ }
156
+ }
157
+
158
+
159
+
160
  /**
161
  * Returns whether or not the current object has any Attachments
162
  *
540
 
541
  // only thumbnails have sizes which is what we're on the hunt for
542
  if(attachments_isset(attachment.attributes.sizes)){
543
+ if(attachments_isset(attachment.attributes.sizes.thumbnail)){
544
  if(attachments_isset(attachment.attributes.sizes.thumbnail.url)){
545
  // use the thumbnail
546
  attachment.attributes.attachment_thumb = attachment.attributes.sizes.thumbnail.url;
980
 
981
 
982
 
983
+ /**
984
+ * Callback to fire the assets() function for reach registered field
985
+ *
986
+ * @since 3.1
987
+ */
988
  function field_assets()
989
  {
990
+ global $post;
991
+
992
+ // we only want to enqueue if we're on an edit screen and it's applicable
993
+ if( empty( $this->instances_for_post_type ) || empty( $post ) )
994
+ return;
995
+
996
  // all metaboxes have been put in place, we can now determine which field assets need to be included
997
 
998
  // first we'll get a list of the field types on screen
999
  $fieldtypes = array();
1000
  foreach( $this->instances_for_post_type as $instance )
 
1001
  foreach( $this->instances[$instance]['fields'] as $field )
 
1002
  $fieldtypes[] = $field['type'];
 
 
1003
 
1004
  // we only want to dump out assets once for each field type
1005
  $fieldtypes = array_unique( $fieldtypes );
1014
 
1015
 
1016
 
1017
+ /**
1018
+ * Callback to fire the init() function for reach registered field
1019
+ *
1020
+ * @since 3.1
1021
+ */
1022
+ function field_inits()
1023
+ {
1024
+ global $post;
1025
+
1026
+ // we only want to enqueue if we're on an edit screen and it's applicable
1027
+ if( empty( $this->instances_for_post_type ) || empty( $post ) )
1028
+ return;
1029
+
1030
+ // all metaboxes have been put in place, we can now determine which field assets need to be included
1031
+
1032
+ // first we'll get a list of the field types on screen
1033
+ $fieldtypes = array();
1034
+ foreach( $this->instances_for_post_type as $instance )
1035
+ foreach( $this->instances[$instance]['fields'] as $field )
1036
+ $fieldtypes[] = $field['type'];
1037
+
1038
+ // we only want to dump out assets once for each field type
1039
+ $fieldtypes = array_unique( $fieldtypes );
1040
+
1041
+ // loop through and dump out all the assets
1042
+ foreach( $fieldtypes as $fieldtype )
1043
+ {
1044
+ $field = new $this->fields[$fieldtype];
1045
+ $field->init();
1046
+ }
1047
+ }
1048
+
1049
+
1050
+
1051
  /**
1052
  * Outputs all necessary Backbone templates
1053
  * Each Backbone template includes each field present in an instance
1372
 
1373
  endif; // class_exists check
1374
 
1375
+ new Attachments();
classes/class.field.php CHANGED
@@ -15,6 +15,7 @@ if ( !class_exists( 'Attachments_Field' ) ) :
15
  public function html( $field );
16
  public function format_value_for_input( $value, $field = null );
17
  public function assets();
 
18
  }
19
 
20
  class Attachments_Field implements Attachments_Field_Template
@@ -80,6 +81,11 @@ if ( !class_exists( 'Attachments_Field' ) ) :
80
  return;
81
  }
82
 
 
 
 
 
 
83
  }
84
 
85
  endif; // class_exists check
15
  public function html( $field );
16
  public function format_value_for_input( $value, $field = null );
17
  public function assets();
18
+ public function init();
19
  }
20
 
21
  class Attachments_Field implements Attachments_Field_Template
81
  return;
82
  }
83
 
84
+ public function init()
85
+ {
86
+ return;
87
+ }
88
+
89
  }
90
 
91
  endif; // class_exists check
classes/fields/class.field.text.php CHANGED
@@ -32,4 +32,9 @@ class Attachments_Field_Text extends Attachments_Field implements Attachments_Fi
32
  return;
33
  }
34
 
 
 
 
 
 
35
  }
32
  return;
33
  }
34
 
35
+ function init()
36
+ {
37
+ return;
38
+ }
39
+
40
  }
classes/fields/class.field.textarea.php CHANGED
@@ -32,4 +32,9 @@ class Attachments_Field_Textarea extends Attachments_Field implements Attachment
32
  return;
33
  }
34
 
 
 
 
 
 
35
  }
32
  return;
33
  }
34
 
35
+ function init()
36
+ {
37
+ return;
38
+ }
39
+
40
  }
classes/fields/class.field.wysiwyg.php CHANGED
@@ -14,7 +14,19 @@ class Attachments_Field_WYSIWYG extends Attachments_Field implements Attachments
14
  {
15
  parent::__construct( $name, $label, $value );
16
 
17
- add_filter( 'wp_default_editor', array( $this, 'wp_default_editor' ) );
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
  function html( $field )
@@ -57,6 +69,7 @@ class Attachments_Field_WYSIWYG extends Attachments_Field implements Attachments
57
  var input_id = $(this).attr('id');
58
 
59
  // create wysiwyg
 
60
  tinyMCE.settings.theme_advanced_buttons2 += ',code';
61
  tinyMCE.settings.wpautop = false;
62
  tinyMCE.execCommand('mceAddControl', false, input_id);
14
  {
15
  parent::__construct( $name, $label, $value );
16
 
17
+ add_filter( 'wp_default_editor', array( $this, 'wp_default_editor' ) );
18
+ }
19
+
20
+ function init()
21
+ {
22
+ global $post;
23
+
24
+ // ensure we've got TinyMCE to work with
25
+ $has_editor = post_type_supports( $post->post_type, 'editor' );
26
+ add_post_type_support( $post->post_type, 'editor' );
27
+
28
+ if( !$has_editor )
29
+ echo '<style type="text/css">#poststuff .postarea { display:none; }</style>';
30
  }
31
 
32
  function html( $field )
69
  var input_id = $(this).attr('id');
70
 
71
  // create wysiwyg
72
+
73
  tinyMCE.settings.theme_advanced_buttons2 += ',code';
74
  tinyMCE.settings.wpautop = false;
75
  tinyMCE.execCommand('mceAddControl', false, input_id);
index.php CHANGED
@@ -6,7 +6,7 @@
6
  * Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
7
  * Author: Jonathan Christopher
8
  * Author URI: http://mondaybynoon.com/
9
- * Version: 3.1.2
10
  * Text Domain: attachments
11
  * Domain Path: /languages/
12
  * License: GPLv2 or later
6
  * Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
7
  * Author: Jonathan Christopher
8
  * Author URI: http://mondaybynoon.com/
9
+ * Version: 3.1.3
10
  * Text Domain: attachments
11
  * Domain Path: /languages/
12
  * License: GPLv2 or later
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.5
7
- Stable tag: 3.1.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -95,6 +95,11 @@ Attachments uses WordPress' built in Media library for uploads and storage.
95
 
96
  == Changelog ==
97
 
 
 
 
 
 
98
  = 3.1.2 =
99
  * Fixed a regression that prevented successful migration of legacy Attachments data
100
 
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.5
7
+ Stable tag: 3.1.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
95
 
96
  == Changelog ==
97
 
98
+ = 3.1.3 =
99
+ * Fixed a potential issue with the WYSIWYG field not working on CPT without editor support
100
+ * Field assets are less aggressive and only fire when necessary
101
+ * Reorganized the migration process a bit in prep for Attachments Pro support
102
+
103
  = 3.1.2 =
104
  * Fixed a regression that prevented successful migration of legacy Attachments data
105
 
views/options.php CHANGED
@@ -1,127 +1,15 @@
1
  <?php
2
 
3
- // Exit if accessed directly
4
- if( !defined( 'ABSPATH' ) ) exit;
5
-
6
- /**
7
- * Migrate Attachments 1.x records to 3.0's format
8
- *
9
- * @since 3.0
10
- */
11
- function attachments_migrate( $instance = null, $title = null, $caption = null )
12
- {
13
- // sanitize
14
- if( is_null( $instance ) || empty( $instance ) || is_null( $title ) || is_null( $caption ) )
15
- return false;
16
-
17
- $instance = str_replace( '-', '_', sanitize_title( $instance ) );
18
- $title = empty( $title ) ? false : str_replace( '-', '_', sanitize_title( $title ) );
19
- $caption = empty( $caption ) ? false : str_replace( '-', '_', sanitize_title( $caption ) );
20
-
21
- // we need our deprecated functions
22
- include_once( ATTACHMENTS_DIR . '/deprecated/get-attachments.php' );
23
-
24
- // grab all of the posts we need to migrate
25
- // TODO: this will not retrieve posts that have exclude_from_search = true
26
- // TODO: make this reusable elsewhere
27
- $query = new WP_Query( 'post_type=any&post_status=any&posts_per_page=-1&meta_key=_attachments' );
28
-
29
- $count = 0;
30
-
31
- // loop through each post
32
- while( $query->have_posts() )
33
- {
34
- // set up postdata
35
- $query->the_post();
36
-
37
- // let's first decode our Attachments data
38
- $existing_attachments = get_post_meta( $query->post->ID, '_attachments', false );
39
-
40
- $post_attachments = array();
41
-
42
- // check to make sure we've got data
43
- if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
44
- {
45
- // loop through each existing attachment
46
- foreach( $existing_attachments as $attachment )
47
- {
48
- // decode and unserialize the data
49
- $data = unserialize( base64_decode( $attachment ) );
50
-
51
- array_push( $post_attachments, array(
52
- 'id' => stripslashes( $data['id'] ),
53
- 'title' => stripslashes( $data['title'] ),
54
- 'caption' => stripslashes( $data['caption'] ),
55
- 'order' => stripslashes( $data['order'] )
56
- ));
57
- }
58
-
59
- // sort attachments
60
- if( count( $post_attachments ) > 1 )
61
- {
62
- usort( $post_attachments, 'attachments_cmp' );
63
- }
64
- }
65
-
66
- // we have our Attachments entries
67
-
68
- // let's check to see if we're migrating after population has taken place
69
- $existing_attachments = get_post_meta( $query->post->ID, 'attachments', false );
70
-
71
- if( !isset( $existing_attachments[0] ) )
72
- $existing_attachments[0] = '';
73
-
74
- $existing_attachments = json_decode( $existing_attachments[0] );
75
-
76
- if( !is_object( $existing_attachments ) )
77
- $existing_attachments = new stdClass();
78
-
79
- // we'll loop through the legacy Attachments and save them in the new format
80
- foreach( $post_attachments as $legacy_attachment )
81
- {
82
- // convert to the new format
83
- $converted_attachment = array( 'id' => $legacy_attachment['id'] );
84
-
85
- // fields are technically optional so we'll add those separately
86
- // we're also going to encode them in the same way the main class does
87
- if( $title )
88
- $converted_attachment['fields'][$title] = htmlentities( stripslashes( $legacy_attachment['title'] ), ENT_QUOTES, 'UTF-8' );
89
-
90
- if( $caption )
91
- $converted_attachment['fields'][$caption] = htmlentities( stripslashes( $legacy_attachment['caption'] ), ENT_QUOTES, 'UTF-8' );
92
-
93
- // check to see if the existing Attachments have our target instance
94
- if( !isset( $existing_attachments->$instance ) )
95
- {
96
- // the instance doesn't exist so we need to create it
97
- $existing_attachments->$instance = array();
98
- }
99
-
100
- // we need to convert our array to an object
101
- $converted_attachment['fields'] = (object) $converted_attachment['fields'];
102
- $converted_attachment = (object) $converted_attachment;
103
-
104
- // append this legacy attachment to the existing instance
105
- array_push( $existing_attachments->$instance, $converted_attachment );
106
- }
107
-
108
- // we're done! let's save everything in our new format
109
- $existing_attachments = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $existing_attachments, JSON_UNESCAPED_UNICODE ) : json_encode( $existing_attachments );
110
-
111
- // save it to the database
112
- update_post_meta( $query->post->ID, 'attachments', $existing_attachments );
113
-
114
- // increment our counter
115
- $count++;
116
- }
117
-
118
- return $count;
119
- }
120
 
121
  if( isset( $_GET['dismiss'] ) )
122
  {
123
- if( !wp_verify_nonce( $_GET['nonce'], 'attachments-dismiss') ) wp_die( __( 'Invalid request', 'attachments' ) );
 
124
 
 
125
  add_option( 'attachments_ignore_migration', true, '', 'no' );
126
  }
127
  ?>
@@ -173,93 +61,31 @@
173
  <?php endif; ?>
174
 
175
  <?php
176
-
177
- // check for any legacy Attachments
178
- // TODO: this will not retrieve posts that have exclude_from_search = true
179
- // TODO: make this reusable elsewhere
180
- $legacy = new WP_Query( 'post_type=any&post_status=any&posts_per_page=1&meta_key=_attachments' );
181
-
182
  // check to see if we're migrating
183
  if( isset( $_GET['migrate'] ) )
184
  {
185
  switch( intval( $_GET['migrate'] ) )
186
  {
187
  case 1:
188
- if( !wp_verify_nonce( $_GET['nonce'], 'attachments-migrate-1') ) wp_die( __( 'Invalid request', 'attachments' ) );
189
- ?>
190
- <h3><?php _e( 'Migration Step 1', 'attachments' ); ?></h3>
191
- <p><?php _e( "In order to migrate Attachments 1.x data, you need to set which instance and fields in version 3.0+ you'd like to use:", 'attachments' ); ?></p>
192
- <form action="options-general.php" method="get">
193
- <input type="hidden" name="page" value="attachments" />
194
- <input type="hidden" name="migrate" value="2" />
195
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'attachments-migrate-2' ); ?>" />
196
- <table class="form-table">
197
- <tbody>
198
- <tr valign="top">
199
- <th scope="row">
200
- <label for="attachments-instance"><?php _e( 'Attachments 3.x Instance', 'attachments' ); ?></label>
201
- </th>
202
- <td>
203
- <input name="attachments-instance" id="attachments-instance" value="attachments" class="regular-text" />
204
- <p class="description"><?php _e( 'The instance name you would like to use in the migration. Required.', 'attachments' ); ?></p>
205
- </td>
206
- </tr>
207
- <tr valign="top">
208
- <th scope="row">
209
- <label for="attachments-title"><?php _e( 'Attachments 3.x Title', 'attachments' ); ?></label>
210
- </th>
211
- <td>
212
- <input name="attachments-title" id="attachments-title" value="title" class="regular-text" />
213
- <p class="description"><?php _e( 'The <code>Title</code> field data will be migrated to this field name in Attachments 3.x. Leave empty to disregard.', 'attachments' ); ?></p>
214
- </td>
215
- </tr>
216
- <tr valign="top">
217
- <th scope="row">
218
- <label for="attachments-caption"><?php _e( 'Attachments 3.x Caption', 'attachments' ); ?></label>
219
- </th>
220
- <td>
221
- <input name="attachments-caption" id="attachments-caption" value="caption" class="regular-text" />
222
- <p class="description"><?php _e( 'The <code>Caption</code> field data will be migrated to this field name in Attachments 3.x. Leave empty to disregard.', 'attachments' ); ?></p>
223
- </td>
224
- </tr>
225
- </tbody>
226
- </table>
227
- <p class="submit">
228
- <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e( 'Start Migration', 'attachments' ); ?>" />
229
- </p>
230
- </form>
231
- <?php
232
  break;
233
 
234
  case 2:
235
- if( !wp_verify_nonce( $_GET['nonce'], 'attachments-migrate-2') ) wp_die( __( 'Invalid request', 'attachments' ) );
236
-
237
- $total = attachments_migrate( $_GET['attachments-instance'], $_GET['attachments-title'], $_GET['attachments-caption'] );
238
-
239
- if( false == get_option( 'attachments_migrated' ) ) :
240
- ?>
241
- <h3><?php _e( 'Migration Complete!', 'attachments' ); ?></h3>
242
- <p><?php _e( 'The migration has completed.', 'attachments' ); ?> <strong><?php _e( 'Migrated', 'attachments'); ?>: <?php echo $total; ?></strong>.</p>
243
- <?php else : ?>
244
- <h3><?php _e( 'Migration Already Run!', 'attachments' ); ?></h3>
245
- <p><?php _e( 'The migration has already been run. The migration process has not been repeated.', 'attachments' ); ?></p>
246
- <?php endif;
247
-
248
- // make sure the database knows the migration has run
249
- add_option( 'attachments_migrated', true, '', 'no' );
250
-
251
  break;
252
  }
253
  }
254
  else
255
  { ?>
256
- <?php if( false == get_option( 'attachments_migrated' ) && $legacy->found_posts ) : ?>
257
- <h2><?php _e( 'Migrate legacy Attachments', 'attachments' ); ?></h2>
 
258
  <p><?php _e( 'Attachments has found records from version 1.x. Would you like to migrate them to version 3?', 'attachments' ); ?></p>
259
- <p><a href="?page=attachments&amp;migrate=1&amp;nonce=<?php echo wp_create_nonce( 'attachments-migrate-1' ); ?>" class="button-primary button"><?php _e( 'Migrate legacy Attachments', 'attachments' ); ?></a></p>
260
  <?php elseif( true == get_option( 'attachments_migrated' ) ) : ?>
261
- <p><?php _e( 'You have already migrated your legacy Attachments.', 'attachments' ); ?></p>
262
  <?php endif; ?>
 
263
  <h2><?php _e( 'Revert to version 1.x', 'attachments' ); ?></h2>
264
  <p><?php _e( 'If you would like to forcefully revert to the 1.x version branch of Attachments, add the following to your', 'attachments' ); ?> <code>wp-config.php</code>:</p>
265
  <p><code>define( 'ATTACHMENTS_LEGACY', true );</code></p>
1
  <?php
2
 
3
+ // instantiate our migration class
4
+ include_once( ATTACHMENTS_DIR . '/classes/class.attachments.migrate.php' );
5
+ $migrator = new AttachmentsMigrate();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  if( isset( $_GET['dismiss'] ) )
8
  {
9
+ if( !wp_verify_nonce( $_GET['nonce'], 'attachments-dismiss') )
10
+ wp_die( __( 'Invalid request', 'attachments' ) );
11
 
12
+ // set our flag that the user wants to ignore the migration message
13
  add_option( 'attachments_ignore_migration', true, '', 'no' );
14
  }
15
  ?>
61
  <?php endif; ?>
62
 
63
  <?php
 
 
 
 
 
 
64
  // check to see if we're migrating
65
  if( isset( $_GET['migrate'] ) )
66
  {
67
  switch( intval( $_GET['migrate'] ) )
68
  {
69
  case 1:
70
+ $migrator->prepare_migration();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  break;
72
 
73
  case 2:
74
+ $migrator->init_migration();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  break;
76
  }
77
  }
78
  else
79
  { ?>
80
+
81
+ <?php if( false == get_option( 'attachments_migrated' ) && $migrator->legacy ) : ?>
82
+ <h2><?php _e( 'Migrate legacy Attachments data', 'attachments' ); ?></h2>
83
  <p><?php _e( 'Attachments has found records from version 1.x. Would you like to migrate them to version 3?', 'attachments' ); ?></p>
84
+ <p><a href="?page=attachments&amp;migrate=1&amp;nonce=<?php echo wp_create_nonce( 'attachments-migrate-1' ); ?>" class="button-primary button"><?php _e( 'Migrate legacy data', 'attachments' ); ?></a></p>
85
  <?php elseif( true == get_option( 'attachments_migrated' ) ) : ?>
86
+ <p><?php _e( 'You have already migrated your legacy Attachments data.', 'attachments' ); ?></p>
87
  <?php endif; ?>
88
+
89
  <h2><?php _e( 'Revert to version 1.x', 'attachments' ); ?></h2>
90
  <p><?php _e( 'If you would like to forcefully revert to the 1.x version branch of Attachments, add the following to your', 'attachments' ); ?> <code>wp-config.php</code>:</p>
91
  <p><code>define( 'ATTACHMENTS_LEGACY', true );</code></p>