Skip to content

Commit fa41290

Browse files
authored
Merge pull request #969 from cloudinary/feature/clean-up-errored-assets
Clean up errored assets
2 parents 4dd37fb + 9c38fbc commit fa41290

File tree

11 files changed

+193
-26
lines changed

11 files changed

+193
-26
lines changed

css/cloudinary.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/cloudinary.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/class-connect.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ public function history( $days = 1 ) {
447447
$plan = ! empty( $this->usage['plan'] ) ? $this->usage['plan'] : $this->credentials['cloud_name'];
448448
for ( $i = 1; $i <= $days; $i ++ ) {
449449
$date = date_i18n( 'd-m-Y', strtotime( '- ' . $i . ' days' ) );
450-
if ( ! isset( $history[ $plan ][ $date ] ) ) {
450+
if ( ! isset( $history[ $plan ][ $date ] ) || is_wp_error( $history[ $plan ][ $date ] ) ) {
451451
$history[ $plan ][ $date ] = $this->api->usage( $date );
452452
uksort(
453453
$history[ $plan ],

php/class-dashboard.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,41 @@ public function register_settings( $pages ) {
149149
'data-text' => 'error_count_hr',
150150
'class' => array(
151151
'cld-stat-text',
152-
'cld-ui-error',
152+
'cld-link-button',
153+
'cld-link-button-secondary',
154+
'cld-toggle',
155+
'hidden',
153156
),
157+
'title' => __( 'View errored assets', 'cloudinary' ),
158+
),
159+
),
160+
array(
161+
'type' => 'tag',
162+
'element' => 'br',
163+
),
164+
array(
165+
'type' => 'tag',
166+
'element' => 'a',
167+
'content' => '&nbsp;',
168+
'attributes' => array(
169+
'href' => add_query_arg(
170+
array(
171+
'page' => 'cloudinary',
172+
'action' => 'clean_up',
173+
'nonce' => wp_create_nonce( 'clean_up' ),
174+
),
175+
admin_url( 'admin.php' )
176+
),
177+
'data-text' => 'error_clean_up',
178+
'class' => array(
179+
'cld-stat-text',
180+
'cld-link-button',
181+
'cld-link-button-secondary',
182+
'cld-link-button-secondary-error',
183+
'cld-toggle',
184+
'hidden',
185+
),
186+
'title' => __( 'Retry sync assets with errors', 'cloudinary' ),
154187
),
155188
),
156189
),
@@ -334,5 +367,4 @@ public function register_settings( $pages ) {
334367

335368
return $pages;
336369
}
337-
338370
}

php/class-sync.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,45 @@ public function get_signature_syncable_type( $signature, $attachment_id ) {
10791079
return $signature;
10801080
}
10811081

1082+
/**
1083+
* Cleanup errored syncs.
1084+
*/
1085+
public function maybe_cleanup_errored() {
1086+
if ( 'cloudinary' !== Utils::get_sanitized_text( 'page' ) ) {
1087+
return;
1088+
}
1089+
1090+
if ( 'cleaned_up' === Utils::get_sanitized_text( 'action' ) ) {
1091+
$this->plugin->get_component( 'admin' )->add_admin_notice( 'error_notice', __( 'Sync errors cleaned up', 'cloudinary' ), 'success' );
1092+
}
1093+
1094+
if ( 'clean_up' !== Utils::get_sanitized_text( 'action' ) ) {
1095+
return;
1096+
}
1097+
1098+
if ( ! wp_verify_nonce( Utils::get_sanitized_text( 'nonce' ), 'clean_up' ) ) {
1099+
return;
1100+
}
1101+
1102+
if ( ! current_user_can( 'manage_options' ) ) {
1103+
return;
1104+
}
1105+
1106+
delete_post_meta_by_key( self::META_KEYS['sync_error'] );
1107+
1108+
wp_redirect(
1109+
add_query_arg(
1110+
array(
1111+
'page' => 'cloudinary',
1112+
'action' => 'cleaned_up',
1113+
),
1114+
admin_url( 'admin.php' )
1115+
)
1116+
);
1117+
1118+
exit;
1119+
}
1120+
10821121
/**
10831122
* Checks if auto sync feature is enabled.
10841123
*
@@ -1175,6 +1214,8 @@ public function setup() {
11751214
add_filter( 'cloudinary_setting_get_value', array( $this, 'filter_get_cloudinary_folder' ), 10, 2 );
11761215
add_filter( 'cloudinary_get_signature', array( $this, 'get_signature_syncable_type' ), 10, 2 );
11771216

1217+
add_action( 'admin_init', array( $this, 'maybe_cleanup_errored' ), 10, 2 );
1218+
11781219
add_action( 'rest_api_init', array( $this, 'rest_api_is_synced_field' ) );
11791220
}
11801221
}

php/sync/class-sync-queue.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public function setup( $sync ) {
114114
* @return {int}
115115
*/
116116
$queue_threads_count = apply_filters( 'cloudinary_queue_threads', 2 );
117-
for ( $i = 0; $i < $queue_threads_count; $i ++ ) {
117+
for ( $i = 0; $i < $queue_threads_count; ++$i ) {
118118
$this->queue_threads[] = 'queue_sync_thread_' . $i;
119119
}
120120

@@ -128,7 +128,7 @@ public function setup( $sync ) {
128128
* @return {int}
129129
*/
130130
$autosync_thread_count = apply_filters( 'cloudinary_autosync_threads', 2 );
131-
for ( $i = 0; $i < $autosync_thread_count; $i ++ ) {
131+
for ( $i = 0; $i < $autosync_thread_count; ++$i ) {
132132
$this->autosync_threads[] = 'auto_sync_thread_' . $i;
133133
}
134134
$this->threads = array_merge( $this->queue_threads, $this->autosync_threads );
@@ -411,7 +411,8 @@ public function get_total_synced_media() {
411411
// Error size: No mockups on what to display here.
412412
'error_count' => $errors_count,
413413
// translators: placeholders are the number of errors.
414-
'error_count_hr' => 0 === $errors_count ? '' : sprintf( _n( '%s error with assets.', '%s errors with assets', $errors_count, 'cloudinary' ), number_format_i18n( $errors_count ) ),
414+
'error_count_hr' => 0 === $errors_count ? '' : sprintf( _n( '%s error with assets', '%s errors with assets', $errors_count, 'cloudinary' ), number_format_i18n( $errors_count ) ),
415+
'error_clean_up' => 0 === $errors_count ? '' : __( 'Retry errored unsynced items', 'cloudinary' ),
415416

416417
// Number of assets.
417418
'total_assets' => $total_assets, // This is a count of the assets in _cloudinary_relationships.
@@ -502,7 +503,7 @@ public function build_queue() {
502503
do {
503504
$ids = array_merge( $ids, $query->get_posts() );
504505
$args = $query->query_vars;
505-
$args['paged'] ++;
506+
++$args['paged'];
506507
$query = new \WP_Query( $args );
507508
} while ( $query->have_posts() );
508509

php/sync/class-upload-sync.php

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
namespace Cloudinary\Sync;
99

10-
use Cloudinary\Delivery;
1110
use Cloudinary\Sync;
1211
use Cloudinary\Utils;
1312

@@ -91,7 +90,8 @@ private function register_hooks() {
9190
'bulk_actions-upload',
9291
function ( $actions ) {
9392
$cloudinary_actions = array(
94-
'cloudinary-push' => __( 'Sync with Cloudinary', 'cloudinary' ),
93+
'cloudinary-push' => __( 'Sync with Cloudinary', 'cloudinary' ),
94+
'cloudinary-clean-up' => __( 'Fix Cloudinary Sync Errors', 'cloudinary' ),
9595
);
9696

9797
return array_merge( $cloudinary_actions, $actions );
@@ -136,18 +136,35 @@ public function add_inline_action( $actions, $post ) {
136136
esc_attr__( 'Sync and deliver from Cloudinary', 'cloudinary' ),
137137
esc_html__( 'Sync and deliver from Cloudinary', 'cloudinary' )
138138
);
139-
} else {
140-
if ( file_exists( get_attached_file( $post->ID ) ) ) {
141-
$actions['cloudinary-push'] = sprintf(
142-
'<a href="%s" aria-label="%s">%s</a>',
143-
$action_url,
144-
esc_attr__( 'Re-sync to Cloudinary', 'cloudinary' ),
145-
esc_html__( 'Re-sync to Cloudinary', 'cloudinary' )
146-
);
147-
}
139+
} else if ( file_exists( get_attached_file( $post->ID ) ) ) {
140+
$actions['cloudinary-push'] = sprintf(
141+
'<a href="%s" aria-label="%s">%s</a>',
142+
$action_url,
143+
esc_attr__( 'Re-sync to Cloudinary', 'cloudinary' ),
144+
esc_html__( 'Re-sync to Cloudinary', 'cloudinary' )
145+
);
148146
}
149147
}
150148

149+
if (
150+
$this->sync->is_syncable( $post->ID )
151+
&& ! empty( get_post_meta( $post->ID, Sync::META_KEYS['sync_error'], true ) )
152+
) {
153+
$actions['cloudinary-clean-up'] = sprintf(
154+
'<a href="%s" aria-label="%s">%s</a>',
155+
add_query_arg(
156+
array(
157+
'action' => 'cloudinary-clean-up',
158+
'media[]' => $post->ID,
159+
'_wpnonce' => wp_create_nonce( 'bulk-media' ),
160+
),
161+
admin_url( 'upload.php' )
162+
),
163+
esc_attr__( 'Fix Cloudinary Sync Error', 'cloudinary' ),
164+
esc_html__( 'Fix Cloudinary Sync Error', 'cloudinary' )
165+
);
166+
}
167+
151168
return $actions;
152169
}
153170

@@ -188,6 +205,15 @@ public function handle_bulk_actions( $location, $action, $post_ids ) {
188205
}
189206
}
190207
break;
208+
209+
case 'cloudinary-clean-up':
210+
foreach ( $post_ids as $post_id ) {
211+
if ( ! $this->sync->is_syncable( $post_id ) ) {
212+
continue;
213+
}
214+
delete_post_meta( $post_id, Sync::META_KEYS['sync_error'] );
215+
}
216+
break;
191217
}
192218

193219
return $location;

php/traits/trait-cli.php

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,23 @@ trait CLI_Trait {
7272

7373
/**
7474
* Is debug mode on.
75-
* Either verbose or export flags.git
75+
* Either verbose or export flags.
7676
*
7777
* @since 3.0.3
7878
*
7979
* @var bool
8080
*/
8181
protected $is_debug_enabled = false;
8282

83+
/**
84+
* Clean up flag.
85+
*
86+
* @since 3.2.0
87+
*
88+
* @var bool
89+
*/
90+
protected $clean_up = false;
91+
8392
/**
8493
* CLI Cloudinary Setup.
8594
*
@@ -114,6 +123,16 @@ protected function do_intro() {
114123
*
115124
* wp cloudinary sync
116125
*
126+
* ## OPTIONS
127+
* [--verbose]
128+
* : Whether to show extra information on unsynced and errored attachments.
129+
*
130+
* [--export]
131+
* : Whether to export CSV files with unsynced and errored attachments.
132+
*
133+
* [--clean-up]
134+
* : Whether to clean up all the error flags.
135+
*
117136
* @when after_wp_load
118137
* @since 2.5.1
119138
*
@@ -133,6 +152,7 @@ public function sync( $args, $assoc_args ) {
133152
$this->is_verbose = ! empty( $assoc_args['verbose'] );
134153
$this->is_export = ! empty( $assoc_args['export'] );
135154
$this->is_debug_enabled = empty( $args ) && ( $this->is_verbose || $this->is_export );
155+
$this->clean_up = ! empty( $assoc_args['clean-up'] );
136156

137157
// Initial Query.
138158
$query_args = $this->base_query_args;
@@ -152,7 +172,6 @@ public function sync( $args, $assoc_args ) {
152172
\WP_CLI::log( \WP_CLI::colorize( '%gAll assets synced.%n' ) );
153173
delete_option( '_cld_cli_analyzed' );
154174
}
155-
156175
}
157176

158177
/**
@@ -165,6 +184,9 @@ public function sync( $args, $assoc_args ) {
165184
* [--export]
166185
* : Whether to export CSV files with unsynced and errored attachments.
167186
*
187+
* [--clean-up]
188+
* : Whether to clean up all the error flags.
189+
*
168190
* ## EXAMPLES
169191
*
170192
* wp cloudinary analyze
@@ -179,11 +201,14 @@ public function sync( $args, $assoc_args ) {
179201
*/
180202
public function analyze( $args = null, $assoc_args = null ) {
181203

204+
static $did_cleanup = false;
205+
182206
// Warmup flags if called as command.
183207
if ( ! is_null( $args ) && ! is_null( $assoc_args ) ) {
184208
$this->is_verbose = ! empty( $assoc_args['verbose'] );
185209
$this->is_export = ! empty( $assoc_args['export'] );
186210
$this->is_debug_enabled = empty( $args ) && ( $this->is_verbose || $this->is_export );
211+
$this->clean_up = ! empty( $assoc_args['clean-up'] );
187212
}
188213

189214
// Initial query.
@@ -196,6 +221,14 @@ public function analyze( $args = null, $assoc_args = null ) {
196221

197222
// Do process.
198223
$this->do_process( $query, 'analyze' );
224+
225+
// Clean up all the error flags.
226+
if ( $this->clean_up && ! $did_cleanup ) {
227+
$did_cleanup = true;
228+
229+
\WP_CLI::log( \WP_CLI::colorize( '%gCleaning up the error flags.%n' ) );
230+
delete_post_meta_by_key( Sync::META_KEYS['sync_error'] );
231+
}
199232
}
200233

201234
/**
@@ -239,7 +272,7 @@ protected function do_process( &$query, $process, $paginate = true ) {
239272
// Paginate.
240273
$query_args = $query->query_vars;
241274
if ( true === $paginate ) {
242-
$query_args['paged'] ++;
275+
++$query_args['paged'];
243276
}
244277
$query = new \WP_Query( $query_args );
245278
} while ( $query->have_posts() );
@@ -261,7 +294,7 @@ protected function process_sync( $posts, $total ) {
261294
$done = 0;
262295
}
263296
foreach ( $posts as $index => $asset ) {
264-
$done ++; // Set $done early to not show 0 of x.
297+
++$done; // Set $done early to not show 0 of x.
265298
$file = get_attached_file( $asset );
266299
$filename = self::pad_name( wp_basename( $file ), 20, ' ', '*' );
267300
$bar->tick( 1, 'Syncing (' . ( $done ) . ' of ' . $total . ') : ' . $filename );
@@ -312,7 +345,7 @@ protected function process_analyze( $posts, $total ) {
312345
$errored_attachments = array();
313346

314347
foreach ( $posts as $asset ) {
315-
$done ++;
348+
++$done;
316349
$key = '_cld_unsupported';
317350
if (
318351
$this->plugin->get_component( 'media' )->is_uploadable_media( $asset )
@@ -345,7 +378,7 @@ protected function process_analyze( $posts, $total ) {
345378
}
346379
}
347380
}
348-
$info[ $key ] ++;
381+
++$info[ $key ];
349382
$bar->tick( 1, $done . ' of ' . $total . ' |' );
350383
}
351384
// Done message.

src/css/components/ui/_links.scss

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,27 @@
1616
color: #fff;
1717
text-decoration: none;
1818
}
19+
20+
&.hidden {
21+
display: none;
22+
}
23+
24+
&-secondary {
25+
background-color: $color-cld-grey-blue;
26+
color: $color-cld-dark-description;
27+
border: 1px solid $color-cld-blue;
28+
29+
&:hover, &:focus {
30+
background-color: $color-cld-blue;
31+
}
32+
33+
&-error {
34+
border-color: $color-red;
35+
36+
&:hover, &:focus {
37+
background-color: $color-red;
38+
}
39+
}
40+
}
1941
}
2042
}

0 commit comments

Comments
 (0)