Skip to content

Commit 52ebcd9

Browse files
committed
Refactor media offload functionality and enhance REST API integration
- Replaced `get_image_count` with `move_images` in the media offload process for better clarity. - Updated the rollback process to use `move_images` instead of `get_image_count`. - Introduced a new REST API endpoint for moving images, allowing for offloading and rollback actions. - Enhanced the admin interface by adding scripts and styles for the media management screen. - Improved action handling for image processing, ensuring better performance and user experience.
1 parent a3c513f commit 52ebcd9

File tree

4 files changed

+176
-157
lines changed

4 files changed

+176
-157
lines changed

assets/js/media.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
jQuery(document).ready(function($) {
2+
jQuery('.move-image-optml').click(function() {
3+
//ge the id and send a jquery rest request to the server
4+
var id = jQuery(this).data('id');
5+
var action = jQuery(this).data('action');
6+
moveImage(id, action, jQuery(this));
7+
});
8+
});
9+
10+
function moveImage(id, action, element, is_retry = false) {
11+
//add a loading indicator
12+
element.parent().find('.spinner').addClass('is-active');
13+
element.parent().addClass('is-loading');
14+
jQuery.ajax({
15+
url: optimoleMediaListing.rest_url,
16+
type: 'POST',
17+
headers: {
18+
'X-WP-Nonce': optimoleMediaListing.nonce
19+
},
20+
data: {
21+
action: action,
22+
status: is_retry ? 'check' : 'start',
23+
id: id
24+
},
25+
success: function(response) {
26+
if(response.code === 'moved') {
27+
element.parent().find('.spinner').removeClass('is-active');
28+
element.parent().removeClass('is-loading');
29+
element.parent().find('.move-image-optml').toggleClass('hidden');
30+
31+
}else if(response.code === 'error'){
32+
element.parent().find('.spinner').removeClass('is-active');
33+
element.parent().removeClass('is-loading');
34+
element.parent().text(response.data);
35+
}else{
36+
setTimeout(function() {
37+
moveImage(id, action, element, true);
38+
}, 1000);
39+
}
40+
}
41+
});
42+
}

inc/admin.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ public function daily_sync() {
11411141
$this->settings->update( 'rollback_status', 'enabled' );
11421142
// We start the rollback process.
11431143
Optml_Logger::instance()->add_log( 'rollback_images', 'Account deactivated, starting rollback.' );
1144-
Optml_Media_Offload::get_image_count( 'rollback_images', false );
1144+
Optml_Media_Offload::move_images( 'rollback_images', false );
11451145
$this->settings->update( 'offload_media', 'disabled' );
11461146
}
11471147
remove_filter( 'optml_dont_trigger_settings_updated', '__return_true' );
@@ -1282,7 +1282,33 @@ public function enqueue() {
12821282
if ( ! isset( $current_screen->id ) ) {
12831283
return;
12841284
}
1285+
if ( $current_screen->id === 'upload' ) {
1286+
wp_enqueue_script( OPTML_NAMESPACE . '-media-admin', OPTML_URL . 'assets/js/media.js', [], OPTML_VERSION );
1287+
wp_localize_script(
1288+
OPTML_NAMESPACE . '-media-admin',
1289+
'optimoleMediaListing',
1290+
[
1291+
'rest_url' => rest_url( OPTML_NAMESPACE . '/v1/move_image' ),
1292+
'nonce' => wp_create_nonce( 'wp_rest' ),
1293+
]
1294+
);
12851295

1296+
wp_register_style( 'optml_media_admin_style', false );
1297+
wp_add_inline_style(
1298+
'optml_media_admin_style',
1299+
'
1300+
.is-loading {
1301+
pointer-events: none;
1302+
opacity: 0.5;
1303+
display: inline-block;
1304+
}
1305+
.spinner {
1306+
margin-top: 0px;
1307+
}
1308+
'
1309+
);
1310+
wp_enqueue_style( 'optml_media_admin_style' );
1311+
}
12861312
if ( $current_screen->id !== 'toplevel_page_optimole' ) {
12871313
return;
12881314
}

inc/media_offload.php

Lines changed: 55 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,13 @@ public static function instance() {
173173

174174
add_action( 'optml_start_processing_images', [ self::$instance, 'start_processing_images' ], 10, 5 );
175175
add_action(
176-
'optml_start_processing_images_by_id',
176+
'optml_move_images_by_id',
177177
[
178178
self::$instance,
179-
'start_processing_images_by_id',
179+
'move_single_image',
180180
],
181181
10,
182-
4
182+
2
183183
);
184184
add_action( 'init', [ self::$instance, 'maybe_reschedule' ] );
185185
if ( self::$is_legacy_install === null ) {
@@ -212,7 +212,7 @@ public function maybe_reschedule() {
212212
return;
213213
}
214214
self::$instance->logger->add_log( $transfer_type, 'Cron missed, attempt to reschedule.' );
215-
self::get_image_count( $transfer_type, false );
215+
self::move_images( $transfer_type, false );
216216
}
217217

218218
/**
@@ -758,39 +758,17 @@ public function add_inline_media_action( $actions, $post ) {
758758
if ( wp_check_filetype( $file, Optml_Config::$all_extensions )['ext'] === false || ! current_user_can( 'delete_post', $post->ID ) ) {
759759
return $actions;
760760
}
761-
if ( ! self::is_uploaded_image( $file ) ) {
762-
$upload_action_url = add_query_arg(
763-
[
764-
'page' => 'optimole',
765-
'optimole_action' => 'offload_images',
766-
'0' => $post->ID,
767-
],
768-
'admin.php'
769-
);
770-
771-
$actions['offload_images'] = sprintf(
772-
'<a href="%s" aria-label="%s">%s</a>',
773-
$upload_action_url,
774-
esc_attr__( 'Offload to Optimole', 'optimole-wp' ),
775-
esc_html__( 'Offload to Optimole', 'optimole-wp' )
776-
);
777-
}
778-
if ( self::is_uploaded_image( $file ) ) {
779-
$rollback_action_url = add_query_arg(
780-
[
781-
'page' => 'optimole',
782-
'optimole_action' => 'rollback_images',
783-
'0' => $post->ID,
784-
],
785-
'admin.php'
786-
);
787-
$actions['rollback_images'] = sprintf(
788-
'<a href="%s" aria-label="%s">%s</a>',
789-
$rollback_action_url,
790-
esc_attr__( 'Restore image to media library', 'optimole-wp' ),
791-
esc_html__( 'Restore image to media library', 'optimole-wp' )
792-
);
793-
}
761+
$actions['optml_actions'] = sprintf(
762+
'<span class="spinner"></span><a class="move-image-optml %s" data-action="offload_image" href="#" aria-label="%s" data-id="%s">%s</a><a class="move-image-optml %s" data-action="rollback_image" href="#" aria-label="%s" data-id="%s">%s</a>',
763+
self::is_uploaded_image( $file ) ? 'hidden' : '',
764+
esc_attr__( 'Offload to Optimole', 'optimole-wp' ),
765+
$post->ID,
766+
esc_html__( 'Offload to Optimole', 'optimole-wp' ),
767+
self::is_uploaded_image( $file ) ? '' : 'hidden',
768+
esc_attr__( 'Restore image to media library', 'optimole-wp' ),
769+
$post->ID,
770+
esc_html__( 'Restore image to media library', 'optimole-wp' )
771+
);
794772

795773
return $actions;
796774
}
@@ -1868,21 +1846,16 @@ public static function get_process_meta() {
18681846
*
18691847
* @param string $action The actions for which to get the number of images.
18701848
* @param bool $refresh Whether to refresh the cron or not.
1871-
* @param array $images The images to process.
18721849
*
18731850
* @return array Image count and Cron status.
18741851
*/
1875-
public static function get_image_count( $action, $refresh, $images = [] ) {
1852+
public static function move_images( $action, $refresh ) {
18761853
$option = 'offload_images' === $action ? 'offloading_status' : 'rollback_status';
18771854
$count = 0;
18781855
$step = 0;
18791856
$batch = apply_filters( 'optimole_offload_batch', 20 ); // Reduce this to smaller if we have memory issues during testing.
18801857

1881-
if ( empty( $images ) ) {
1882-
$count = Optml_Media_Offload::number_of_images_and_pages( $action );
1883-
} else {
1884-
$count = Optml_Media_Offload::number_of_images_by_ids( $action, $images );
1885-
}
1858+
$count = Optml_Media_Offload::number_of_images_and_pages( $action );
18861859

18871860
$possible_batch = ceil( $count / 10 );
18881861

@@ -1901,15 +1874,12 @@ public static function get_image_count( $action, $refresh, $images = [] ) {
19011874
$in_progress = false;
19021875
}
19031876
$type = 'offload_images' === $action ? 'offload' : 'rollback';
1904-
// We save the status if this ia multi step transfer.
1905-
if ( empty( $images ) ) {
1906-
self::$instance->settings->update( 'transfer_status', $action );
1907-
}
1877+
self::$instance->settings->update( 'transfer_status', $action );
19081878
if ( false === $refresh ) {
19091879
// We check also the alternative action to avoid doing both in the same time and disable the running one.
19101880
$in_progress_b = self::$instance->settings->get( 'rollback_images' === $action ? 'offloading_status' : 'rollback_status' ) !== 'disabled';
19111881
// We do this only if there is a mass action in progress, not individual ones.
1912-
if ( $in_progress_b && empty( $images ) ) {
1882+
if ( $in_progress_b ) {
19131883
// We stop the oposite action from going any further.
19141884
self::$instance->settings->update( 'rollback_images' === $action ? 'offloading_status' : 'rollback_status', 'disabled' );
19151885
}
@@ -1927,32 +1897,18 @@ public static function get_image_count( $action, $refresh, $images = [] ) {
19271897
'action' => $type,
19281898
];
19291899
}
1930-
1931-
if ( empty( $images ) ) {
1932-
$total = ceil( $count / $batch );
1933-
self::schedule_action(
1934-
time(),
1935-
'optml_start_processing_images',
1936-
[
1937-
$action,
1938-
$batch,
1939-
1,
1940-
$total,
1941-
$step,
1942-
]
1943-
);
1944-
} else {
1945-
self::schedule_action(
1946-
time(),
1947-
'optml_start_processing_images_by_id',
1948-
[
1949-
$action,
1950-
$batch,
1951-
1,
1952-
$images,
1953-
]
1954-
);
1955-
}
1900+
$total = ceil( $count / $batch );
1901+
self::schedule_action(
1902+
time(),
1903+
'optml_start_processing_images',
1904+
[
1905+
$action,
1906+
$batch,
1907+
1,
1908+
$total,
1909+
$step,
1910+
]
1911+
);
19561912
}
19571913

19581914
$response = [
@@ -2016,100 +1972,50 @@ public static function is_scheduled( $hook ) {
20161972
* Start Processing Images by IDs
20171973
*
20181974
* @param string $action The action for which to get the number of images.
2019-
* @param int $batch The batch of images to process.
2020-
* @param int $page The page of images to process.
2021-
* @param array $image_ids The images to process.
1975+
* @param int $id The images to process.
20221976
*
1977+
* @throws Exception If there is an error.
20231978
* @return void
20241979
*/
2025-
public function start_processing_images_by_id( $action, $batch, $page, $image_ids = [] ) {
2026-
$option = 'offload_images' === $action ? 'offloading_status' : 'rollback_status';
2027-
$type = 'offload_images' === $action ? Optml_Logger::LOG_TYPE_OFFLOAD : Optml_Logger::LOG_TYPE_ROLLBACK;
2028-
2029-
if ( self::$instance->settings->get( $option ) === 'disabled' ) {
2030-
return;
2031-
}
2032-
1980+
public function move_single_image( $action, $id ) {
20331981
set_time_limit( 0 );
20341982

20351983
// Only use the legacy offloaded attachments to query the pages that need to be updated.
20361984
// We can be confident that these IDs are already marked as offloaded.
2037-
$legacy_offloaded = array_filter(
2038-
$image_ids,
2039-
function ( $id ) {
2040-
return ! $this->is_new_offloaded_attachment( $id );
2041-
}
2042-
);
2043-
2044-
// On the new mechanism, we don't update posts anymore when offloading.
2045-
$page_in = $action === 'offload_images' ? [] : Optml_Media_Offload::get_posts_by_image_ids( $action, $legacy_offloaded, $batch, $page );
2046-
2047-
if ( empty( $image_ids ) && empty( $page_in ) && empty( $legacy_offloaded ) ) {
2048-
$meta = self::get_process_meta();
2049-
self::$instance->logger->add_log( $type, 'Process finished with ' . $meta['count'] . ' items in ' . $meta['time_passed'] . ' minutes.' );
2050-
2051-
self::$instance->settings->update( $option, 'disabled' );
2052-
2053-
return;
2054-
}
2055-
2056-
try {
2057-
// This will be 0 in the case of offloading now.
2058-
if ( $action === 'rollback_images' && 0 !== count( $page_in ) ) {
2059-
$to_update = Optml_Media_Offload::instance()->update_content( $page, $action, $batch, $page_in );
2060-
1985+
$legacy_offloaded = ! $this->is_new_offloaded_attachment( $id );
1986+
$page_in = [];
1987+
if ( $legacy_offloaded ) {
1988+
$page_in = $action === 'offload_images' ? [] : Optml_Media_Offload::get_posts_by_image_ids( $action, [ $id ] );
1989+
}
1990+
// This will be 0 in the case of offloading now.
1991+
if ( $action === 'rollback_images' && 0 !== count( $page_in ) ) {
1992+
$page = 0;
1993+
do {
1994+
$to_update = Optml_Media_Offload::instance()->update_content( $page, $action, 100, $page_in );
20611995
if ( isset( $to_update['page'] ) ) {
20621996
if ( isset( $to_update['imagesToUpdate'] ) && count( $to_update['imagesToUpdate'] ) ) {
20631997
foreach ( $to_update['imagesToUpdate'] as $post_id => $images ) {
2064-
if ( ! empty( $image_ids ) ) {
2065-
$images = array_intersect( $images, $image_ids );
2066-
}
2067-
1998+
$images = array_intersect( $images, [ $id ] );
20681999
if ( empty( $images ) ) {
20692000
continue;
20702001
}
2071-
20722002
Optml_Media_Offload::instance()->rollback_and_update_images( $images );
20732003
Optml_Media_Offload::instance()->update_page( $post_id );
20742004
}
20752005
}
20762006
}
2077-
20782007
$page = $page + 1;
2079-
} else {
2080-
// From $image_ids get the number as per $batch and save it in $page_in and update $images with the remaining images.
2081-
$images = array_slice( $image_ids, 0, $batch );
2082-
$image_ids = array_slice( $image_ids, $batch );
2083-
$action === 'rollback_images' ?
2084-
Optml_Media_Offload::instance()->rollback_images( $batch, $images ) :
2085-
Optml_Media_Offload::instance()->upload_images( $batch, $images );
2086-
}
2008+
} while ( ! empty( $to_update['imagesToUpdate'] ) );
20872009

2088-
self::schedule_action(
2089-
time(),
2090-
'optml_start_processing_images_by_id',
2091-
[
2092-
$action,
2093-
$batch,
2094-
$page,
2095-
$image_ids,
2096-
]
2097-
);
2098-
} catch ( Exception $e ) {
2099-
// Reschedule the cron to run again after a delay. Sometimes memory limit is exhausted.
2100-
$delay_in_seconds = 10;
2101-
self::$instance->logger->add_log( $type, $e->getMessage() );
2102-
2103-
self::schedule_action(
2104-
time() + $delay_in_seconds,
2105-
'optml_start_processing_images_by_id',
2106-
[
2107-
$action,
2108-
$batch,
2109-
$page,
2110-
$image_ids,
2111-
]
2112-
);
2010+
} else {
2011+
$action === 'rollback_images' ?
2012+
Optml_Media_Offload::instance()->rollback_images( 1, [ $id ] ) :
2013+
Optml_Media_Offload::instance()->upload_images( 1, [ $id ] );
2014+
}
2015+
if ( empty( $page_in ) && $legacy_offloaded === false ) {
2016+
$meta = self::get_process_meta();
2017+
self::$instance->logger->add_log( $action, 'Process finished with ' . $meta['count'] . ' items in ' . $meta['time_passed'] . ' minutes.' );
2018+
return;
21132019
}
21142020
}
21152021

0 commit comments

Comments
 (0)