PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 7.3.3
Admin and Site Enhancements (ASE) v7.3.3
9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / classes / class-media-replacement.php
admin-site-enhancements / classes Last commit date
class-activation.php 2 years ago class-admin-columns-manager.php 2 years ago class-admin-menu-organizer.php 2 years ago class-auto-publish-posts-with-missed-schedule.php 2 years ago class-avif-upload.php 2 years ago class-change-login-url.php 2 years ago class-cleanup-admin-bar.php 2 years ago class-code-snippets-manager.php 2 years ago class-common-methods.php 2 years ago class-content-duplication.php 2 years ago class-content-order.php 2 years ago class-custom-admin-footer-text.php 2 years ago class-custom-body-class.php 2 years ago class-custom-content-types.php 2 years ago class-custom-css.php 2 years ago class-custom-nav-menu-items-in-new-tab.php 2 years ago class-deactivation.php 2 years ago class-disable-comments.php 2 years ago class-disable-dashboard-widgets.php 2 years ago class-disable-feeds.php 2 years ago class-disable-gutenberg.php 2 years ago class-disable-rest-api.php 2 years ago class-disable-smaller-components.php 2 years ago class-disable-updates.php 2 years ago class-disable-xml-rpc.php 2 years ago class-display-system-summary.php 2 years ago class-email-address-obfuscator.php 2 years ago class-email-delivery.php 2 years ago class-enhance-list-tables.php 2 years ago class-external-permalinks.php 2 years ago class-heartbeat-control.php 2 years ago class-hide-admin-bar.php 2 years ago class-hide-admin-notices.php 2 years ago class-image-sizes-panel.php 2 years ago class-image-upload-control.php 2 years ago class-insert-head-body-footer-code.php 2 years ago class-last-login-column.php 2 years ago class-limit-login-attempts.php 2 years ago class-login-id-type.php 2 years ago class-login-logout-menu.php 2 years ago class-maintenance-mode.php 2 years ago class-manage-ads-appads-txt.php 2 years ago class-manage-robots-txt.php 2 years ago class-media-replacement.php 2 years ago class-multiple-user-roles.php 2 years ago class-obfuscate-author-slugs.php 2 years ago class-open-external-links-in-new-tab.php 2 years ago class-password-protection.php 2 years ago class-redirect-after-login.php 2 years ago class-redirect-after-logout.php 2 years ago class-redirect-fourofour.php 2 years ago class-revisions-control.php 2 years ago class-search-engines-visibility.php 2 years ago class-settings-fields-render.php 2 years ago class-settings-sanitization.php 2 years ago class-settings-sections-fields.php 2 years ago class-show-custom-taxonomy-filters.php 2 years ago class-site-identity-on-login-page.php 2 years ago class-svg-upload.php 2 years ago class-various-admin-ui-enhancements.php 2 years ago class-view-admin-as-role.php 2 years ago class-wider-admin-menu.php 2 years ago
class-media-replacement.php
335 lines
1 <?php
2
3 namespace ASENHA\Classes;
4
5 /**
6 * Class for Media Replacement module
7 *
8 * @since 6.9.5
9 */
10 class Media_Replacement {
11
12 /**
13 * Modify the 'Edit' link to be 'Edit or Replace'
14 *
15 */
16 public function modify_media_list_table_edit_link( $actions, $post ) {
17
18 $new_actions = array();
19
20 foreach( $actions as $key => $value ) {
21
22 if ( $key == 'edit' ) {
23
24 $new_actions['edit'] = '<a href="' . get_edit_post_link( $post ) . '" aria-label="Edit or Replace">Edit or Replace</a>';
25
26 } else {
27
28 $new_actions[$key] = $value;
29
30 }
31
32 }
33
34 return $new_actions;
35
36 }
37
38 /**
39 * Add media replacement button in the edit screen of media/attachment
40 *
41 * @since 1.1.0
42 */
43 public function add_media_replacement_button( $fields, $post ) {
44 global $post, $pagenow, $typenow;
45
46 // Do not do this on post creation and editing screen
47 // May cause media frame layout / display issues
48 if ( 'attachment' == $typenow ||
49 ( 'attachment' != $typenow && 'post-new.php' != $pagenow && 'post.php' != $pagenow )
50 ) {
51 $image_mime_type = '';
52 if ( is_object( $post ) ) {
53 if ( property_exists( $post, 'post_mime_type' ) ) {
54 $image_mime_type = $post->post_mime_type;
55 }
56 }
57
58 // Enqueues all scripts, styles, settings, and templates necessary to use all media JS APIs.
59 // Reference: https://codex.wordpress.org/Javascript_Reference/wp.media
60 wp_enqueue_media();
61
62 // Add new field to attachment fields for the media replace functionality
63 $fields['asenha-media-replace'] = array();
64 $fields['asenha-media-replace']['label'] = '';
65 $fields['asenha-media-replace']['input'] = 'html';
66 $fields['asenha-media-replace']['html'] = '
67 <div id="media-replace-div" class="postbox">
68 <div class="postbox-header">
69 <h2 class="hndle ui-sortable-handle">' . __( 'Replace Media', 'admin-site-enhancements' ) . '</h2>
70 </div>
71 <div class="inside">
72 <button type="button" id="asenha-media-replace" class="button-secondary button-large asenha-media-replace-button" data-old-image-mime-type="' . $image_mime_type . '" onclick="replaceMedia(\'' . $image_mime_type . '\');">' . __( 'Select New Media File', 'admin-site-enhancements' ) . '</button>
73 <input type="hidden" id="new-attachment-id" name="new-attachment-id" />
74 <div class="asenha-media-replace-notes"><p>' . __( 'The current file will be replaced with the uploaded / selected file (of the same type) while retaining the current ID, publish date and file name. Thus, no existing links will break.', 'admin-site-enhancements' ) . '</p></div>
75 </div>
76 </div>
77 ';
78 }
79
80 return $fields;
81
82 }
83
84 public function attachment_for_js( $image_url, $attachment_id ) {
85 // vi( $image_url );
86 // vi( $attachment_id );
87 }
88
89 /**
90 * Replace existing media with the newly updated file
91 *
92 * @link https://plugins.trac.wordpress.org/browser/replace-image/tags/1.1.7/hm-replace-image.php#L55
93 * @since 1.1.0
94 */
95 public function replace_media( $old_attachment_id ) {
96
97 $old_post_meta = get_post( $old_attachment_id, ARRAY_A );
98 $old_post_mime = $old_post_meta['post_mime_type']; // e.g. 'image/jpeg'
99
100 // Get the new attachment/media ID, meta and mime type
101 if ( isset( $_POST['new-attachment-id'] ) && ! empty( $_POST['new-attachment-id'] ) ) {
102 $new_attachment_id = intval( sanitize_text_field( $_POST['new-attachment-id'] ) );
103 $new_post_meta = get_post( $new_attachment_id, ARRAY_A );
104 $new_post_mime = $new_post_meta['post_mime_type']; // e.g. 'image/jpeg'
105 }
106
107 // Check if the media file ID selected via the media frame and passed on to the #new-attachment-id hidden field
108 // Ensure the mime type matches too
109 if ( ( ! empty( $new_attachment_id ) ) && is_numeric( $new_attachment_id ) && ( $old_post_mime == $new_post_mime ) ) {
110
111 $new_attachment_meta = wp_get_attachment_metadata( $new_attachment_id );
112
113 // If original file is larger than 2560 pixel
114 // https://make.wordpress.org/core/2019/10/09/introducing-handling-of-big-images-in-wordpress-5-3/
115 if ( array_key_exists( 'original_image', $new_attachment_meta ) ) {
116
117 // Get the original media file path
118 $new_media_file_path = wp_get_original_image_path( $new_attachment_id );
119
120 } else {
121
122 // Get the path to newly uploaded media file. An image file name may end with '-scaled'.
123 $new_attachment_file = get_post_meta( $new_attachment_id, '_wp_attached_file', true );
124 $upload_dir = wp_upload_dir();
125 $new_media_file_path = $upload_dir['basedir'] . '/' . $new_attachment_file;
126
127 }
128
129 // Check if the new media file exist / was successfully uploaded
130 if ( ! is_file( $new_media_file_path ) ) {
131 return false;
132 }
133
134 // Delete existing/old media files. Post and post meta entries for it are still there in the database.
135 $this->delete_media_files( $old_attachment_id );
136
137 // If original file is larger than 2560 pixel
138 // https://make.wordpress.org/core/2019/10/09/introducing-handling-of-big-images-in-wordpress-5-3/
139 if ( array_key_exists( 'original_image', $new_attachment_meta ) ) {
140
141 // Get the original media file path
142 $old_media_file_path = wp_get_original_image_path( $old_attachment_id );
143
144 } else {
145
146 // Get the path to the old/existing media file that will be replaced and deleted. An image file name may end with '-scaled'.
147 $old_attachment_file = get_post_meta( $old_attachment_id, '_wp_attached_file', true );
148 $old_media_file_path = $upload_dir['basedir'] . '/' . $old_attachment_file;
149
150 }
151
152 // Check if the directory path to the old media file is still intact
153 if ( ! file_exists( dirname( $old_media_file_path ) ) ) {
154
155 // Recreate the directory path
156 mkdir( dirname( $old_media_file_path ), 0755, true );
157
158 }
159
160 // Copy the new media file into the old media file's path
161 copy( $new_media_file_path, $old_media_file_path );
162
163 // Regenerate attachment meta data and image sub-sizes from the new media file that was just copied to the old path
164 $old_media_post_meta_updated = wp_generate_attachment_metadata( $old_attachment_id, $old_media_file_path );
165
166 // Update new media file's meta data with the ones from the old media. i.e. new media file will carry over the post ID and post meta of the old media file. i.e. only the files are replaced for the old media's ID and post meta in the database.
167 wp_update_attachment_metadata( $old_attachment_id, $old_media_post_meta_updated );
168
169 // Delete the newly uploaded media file and it's sub-sizes, and also delete post and post meta entries for it in the database.
170 wp_delete_attachment( $new_attachment_id, true );
171
172 // Add old attachment ID to recently replaced media option. This will be used for cache busting to ensure the new replacement images are immediately loaded in the browser / wp-admin
173 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
174 $recently_replaced_media = isset( $options_extra['recently_replaced_media'] ) ? $options_extra['recently_replaced_media'] : array();
175 $max_media_number_to_cache_bust = 5;
176 if ( count( $recently_replaced_media ) >= $max_media_number_to_cache_bust ) {
177 // Remove first/oldest attachment ID
178 array_shift( $recently_replaced_media );
179 }
180 $recently_replaced_media[] = $old_attachment_id;
181 $recently_replaced_media = array_unique( $recently_replaced_media );
182 $options_extra['recently_replaced_media'] = $recently_replaced_media;
183 update_option( ASENHA_SLUG_U . '_extra', $options_extra, true );
184
185 }
186
187 }
188
189 /**
190 * Delete the existing/old media files when performing media replacement
191 *
192 * @link https://plugins.trac.wordpress.org/browser/replace-image/tags/1.1.7/hm-replace-image.php#L80
193 * @since 1.1.0
194 */
195 public function delete_media_files( $post_id ) {
196
197 $attachment_meta = wp_get_attachment_metadata( $post_id );
198
199 // Will get '-scaled' version if it exists, e.g. /path/to/uploads/year/month/file-name.jpg
200 $attachment_file_path = get_attached_file( $post_id );
201
202 // e.g. file-name.jpg
203 $attachment_file_basename = basename( $attachment_file_path );
204
205 // Delete intermediate images if there are any
206
207 if ( isset( $attachment_meta['sizes'] ) && is_array( $attachment_meta['sizes'] ) ) {
208
209 foreach( $attachment_meta['sizes'] as $size => $size_info) {
210
211 // /path/to/uploads/year/month/file-name.jpg --> /path/to/uploads/year/month/file-name-1024x768.jpg
212 $intermediate_file_path = str_replace( $attachment_file_basename, $size_info['file'], $attachment_file_path );
213 wp_delete_file( $intermediate_file_path );
214
215 }
216
217 }
218
219 // Delete the attachment file, which maybe the '-scaled' version
220 wp_delete_file( $attachment_file_path );
221
222 // If original file is larger than 2560 pixel
223 // https://make.wordpress.org/core/2019/10/09/introducing-handling-of-big-images-in-wordpress-5-3/
224 $attachment_original_file_path = wp_get_original_image_path( $post_id );
225
226 // Maybe delete the original file if it's an image file, and the original file path exists / was found
227 if ( $attachment_original_file_path ) {
228 wp_delete_file( $attachment_original_file_path );
229 }
230
231 }
232
233 /**
234 * Customize the attachment updated message
235 *
236 * @link https://github.com/WordPress/wordpress-develop/blob/6.0.2/src/wp-admin/edit-form-advanced.php#L180
237 * @since 1.1.0
238 */
239 public function attachment_updated_custom_message( $messages ) {
240
241 $new_messages = array();
242
243 foreach( $messages as $post_type => $messages_array ) {
244
245 if ( $post_type == 'attachment' ) {
246
247 // Message ID for successful edit/update of an attachment is 4. e.g. /wp-admin/post.php?post=a&action=edit&classic-editor&message=4 Customize it here.
248 $messages_array[4] = 'Media file updated. You may need to <a href="https://fabricdigital.co.nz/blog/how-to-hard-refresh-your-browser-and-clear-cache" target="_blank">hard refresh</a> your browser to see the updated media preview image below.';
249
250 }
251
252 $new_messages[$post_type] = $messages_array;
253
254 }
255
256 return $new_messages;
257
258 }
259
260 /**
261 * Append cache busting parameter to the end of image srcset
262 *
263 * @since 5.7.0
264 */
265 public function append_cache_busting_param_to_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
266 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
267 $recently_replaced_media = isset( $options_extra['recently_replaced_media'] ) ? $options_extra['recently_replaced_media'] : array();
268
269 if ( in_array( $attachment_id, $recently_replaced_media ) ) {
270 foreach ( $sources as $size => $source ) {
271 $source['url'] .= ( false === strpos($source['url'], '?' ) ? '?' : '&' ) . 't=' . time();
272 $sources[$size] = $source;
273 }
274 }
275 return $sources;
276 }
277
278 /**
279 * Append cache busting parameter to the end of image src
280 *
281 * @since 5.7.0
282 */
283 public function append_cache_busting_param_to_attachment_image_src( $image, $attachment_id ) {
284 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
285 $recently_replaced_media = isset( $options_extra['recently_replaced_media'] ) ? $options_extra['recently_replaced_media'] : array();
286
287 if ( ! empty( $image[0] ) && in_array( $attachment_id, $recently_replaced_media ) ) {
288 $image[0] .= ( false === strpos($image[0], '?') ? '?' : '&' ) . 't=' . time();
289 }
290
291 return $image;
292 }
293
294 /**
295 * Append cache busting parameter to image src for js
296 *
297 * @since 5.7.0
298 */
299 public function append_cache_busting_param_to_attachment_for_js( $response, $attachment ) {
300 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
301 $recently_replaced_media = isset( $options_extra['recently_replaced_media'] ) ? $options_extra['recently_replaced_media'] : array();
302
303 if ( in_array( $attachment->ID, $recently_replaced_media ) ) {
304 if ( false !== strpos( $response['url'], '?' ) ) {
305 $response['url'] .= ( false === strpos( $response['url'], '?' ) ? '?' : '&' ) . 't=' . time();
306 }
307 if ( isset( $response['sizes'] ) ) {
308 foreach ( $response['sizes'] as $size_name => $size ) {
309 $response['sizes'][$size_name]['url'] .= ( false === strpos( $size['url'], '?' ) ? '?' : '&' ) . 't=' . time();
310 }
311 }
312 }
313
314 return $response;
315 }
316
317 /**
318 * Append cache busting parameter to attachment URL
319 *
320 * @since 6.8.2
321 */
322 public function append_cache_busting_param_to_attachment_url( $url, $attachment_id ) {
323 $options_extra = get_option( ASENHA_SLUG_U . '_extra', array() );
324 $recently_replaced_media = isset( $options_extra['recently_replaced_media'] ) ? $options_extra['recently_replaced_media'] : array();
325
326 if ( in_array( $attachment_id, $recently_replaced_media ) ) {
327 // if ( false !== strpos( $url, '?' ) ) {
328 $url .= ( false === strpos( $url, '?' ) ? '?' : '&' ) . 't=' . time();
329 // }
330 }
331
332 return $url;
333 }
334
335 }