Skip to content

Commit b34eead

Browse files
committed
refactor the CLI sync and analyze
1 parent 5290905 commit b34eead

File tree

1 file changed

+177
-81
lines changed

1 file changed

+177
-81
lines changed

php/class-cli.php

Lines changed: 177 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -7,142 +7,238 @@
77

88
namespace Cloudinary;
99

10+
use Cloudinary\Plugin;
11+
1012
/**
1113
* CLI class.
14+
*
15+
* @since 2.5.1
1216
*/
1317
class CLI {
1418

1519
/**
1620
* Holds the plugin instance.
1721
*
18-
* @since 0.1
22+
* @since 2.5.1
1923
*
2024
* @var Plugin Instance of the global plugin.
2125
*/
2226
public $plugin;
2327

28+
/**
29+
* Holds the base query args.
30+
*
31+
* @since 2.5.1
32+
*
33+
* @var array
34+
*/
35+
protected $base_query_args = array(
36+
'post_type' => 'attachment',
37+
'post_status' => 'inherit',
38+
'fields' => 'ids',
39+
'posts_per_page' => 100,
40+
'update_post_term_cache' => false,
41+
'update_post_meta_cache' => false,
42+
'paged' => 1,
43+
);
44+
2445
/**
2546
* CLI constructor.
2647
*
27-
* @param \Cloudinary\Plugin $plugin The plugin instance.
48+
* @since 2.5.1
49+
*
50+
* @param Plugin $plugin The plugin instance.
2851
*/
2952
public function __construct( $plugin ) {
53+
\WP_CLI::log( '' );
54+
\WP_CLI::log( '╔═╗┬ ┌─┐┬ ┬┌┬┐┬┌┐┌┌─┐┬─┐┬ ┬ ╔═╗╦ ╦' );
55+
\WP_CLI::log( '║ │ │ ││ │ ││││││├─┤├┬┘└┬┘ ║ ║ ║' );
56+
\WP_CLI::log( '╚═╝┴─┘└─┘└─┘─┴┘┴┘└┘┴ ┴┴└─ ┴ ╚═╝╩═╝╩' );
3057
$this->plugin = $plugin;
31-
3258
}
3359

3460
/**
3561
* Syncs assets with Cloudinary.
36-
*
37-
* ## OPTIONS
38-
* [--assets=<assets>]
39-
* : Optional list of assets, comma separated.
40-
*
4162
* ## EXAMPLES
4263
*
4364
* wp cloudinary sync
4465
*
45-
* @when after_wp_load
66+
* @when after_wp_load
67+
* @since 2.5.1
4668
*
4769
* @param array $args Ignored.
48-
* @param array $assoc_args Passed parameters.
70+
* @param array $assoc_args Ignored.
71+
*
72+
* @return void
4973
*/
5074
public function sync( $args, $assoc_args ) {
5175

52-
\WP_CLI::log( '' );
53-
\WP_CLI::log( '╔═╗┬ ┌─┐┬ ┬┌┬┐┬┌┐┌┌─┐┬─┐┬ ┬ ╔═╗╦ ╦' );
54-
\WP_CLI::log( '║ │ │ ││ │ ││││││├─┤├┬┘└┬┘ ║ ║ ║' );
55-
\WP_CLI::log( '╚═╝┴─┘└─┘└─┘─┴┘┴┘└┘┴ ┴┴└─ ┴ ╚═╝╩═╝╩' );
76+
// Check if analyzed first.
77+
if ( empty( get_option( '_cld_cli_analyzed' ) ) ) {
78+
$this->analyze();
79+
}
80+
81+
// Initial Query.
82+
$query_args = $this->base_query_args;
83+
// phpcs:ignore WordPress.DB.SlowDBQuery
84+
$query_args['meta_query'] = array(
85+
'AND',
86+
array(
87+
'key' => '_cld_unsynced',
88+
'compare' => 'EXISTS',
89+
),
90+
);
5691

57-
$assets = null;
58-
if ( ! empty( $assoc_args['assets'] ) ) {
59-
$assets = explode( ',', $assoc_args['assets'] );
60-
$assets = array_map( 'trim', $assets );
92+
// Get assets that need to be synced.
93+
$query = new \WP_Query( $query_args );
94+
$this->do_process( $query, 'sync' );
95+
if ( ! $query->have_posts() ) {
96+
\WP_CLI::log( \WP_CLI::colorize( '%gAll assets synced.%n' ) );
6197
}
62-
$assets = $this->get_all_unsynced( $assets );
6398

64-
if ( empty( $assets ) ) {
99+
}
100+
101+
/**
102+
* Analyze assets with Cloudinary.
103+
* ## EXAMPLES
104+
*
105+
* wp cloudinary analyze
106+
*
107+
* @when after_wp_load
108+
* @since 2.5.1
109+
*
110+
* @return void
111+
*/
112+
public function analyze() {
113+
114+
// Initial query.
115+
$query_args = $this->base_query_args;
116+
$query = new \WP_Query( $query_args );
117+
118+
// Kill all _cld_ related meta.
119+
delete_post_meta_by_key( '_cld_unsynced' );
120+
delete_option( '_cld_cli_analyzed' );
121+
122+
// Do process.
123+
$this->do_process( $query, 'analyze' );
124+
}
125+
126+
/**
127+
* Do a process on the query.
128+
*
129+
* @since 2.5.1
130+
*
131+
* @param \WP_Query $query The initial query object.
132+
* @param string $process The process to do.
133+
*/
134+
protected function do_process( &$query, $process ) {
135+
// Bail early.
136+
if ( ! method_exists( $this, "process_{$process}" ) ) {
137+
\WP_CLI::log( \WP_CLI::colorize( "%Invalid Process: {$process}.%n" ) );
138+
65139
return;
66140
}
67-
$total = count( $assets );
68-
\WP_CLI::log( '' );
69-
\WP_CLI::log( \WP_CLI::colorize( '%gStarting Sync:%n' ) );
70-
$bar = \WP_CLI\Utils\make_progress_bar( 'Syncing ' . $total . ' assets', $total, 10 );
71-
foreach ( $assets as $index => $asset ) {
141+
if ( method_exists( $this, $process ) ) {
142+
// Setup process.
143+
$total = $query->found_posts;
144+
$process = "process_{$process}";
145+
do {
146+
$posts = $query->get_posts();
147+
$this->{$process}( $posts, $total );
148+
149+
// Free up memory.
150+
if ( method_exists( $this, 'stop_the_insanity' ) ) {
151+
$this->stop_the_insanity();
152+
}
153+
154+
// Paginate.
155+
$query_args = $query->query_vars;
156+
$query_args['paged'] ++;
157+
$query = new \WP_Query( $query_args );
158+
} while ( $query->have_posts() );
159+
}
160+
\WP_CLI::line( '' );
161+
}
162+
163+
/**
164+
* Sync Assets.
165+
*
166+
* @param array $posts Array of Post IDs to process.
167+
* @param int $total Count of total posts to process.
168+
*/
169+
protected function process_sync( $posts, $total ) {
170+
static $bar, $done;
171+
if ( ! $bar && ! empty( $posts ) ) {
172+
\WP_CLI::log( \WP_CLI::colorize( '%gSyncing assets%n' ) );
173+
$bar = \WP_CLI\Utils\make_progress_bar( 'Syncing ' . $total . ' assets', $total, 10 );
174+
$done = 0;
175+
}
176+
foreach ( $posts as $index => $asset ) {
177+
$done ++; // Set $done early to not show 0 of x.
72178
$file = get_attached_file( $asset );
73-
$bar->tick( 0, 'Syncing: ' . basename( $file ) . ' (' . ( $index + 1 ) . ' of ' . $total . ')' );
74-
$this->plugin->get_component( 'sync' )->managers['push']->process_assets( $asset, $bar );
179+
$bar->tick( 0, 'Syncing: ' . basename( $file ) . ' (' . ( $done ) . ' of ' . $total . ')' );
180+
if ( ! $this->plugin->get_component( 'sync' )->is_synced( $asset ) ) {
181+
$this->plugin->get_component( 'sync' )->managers['push']->process_assets( $asset, $bar );
182+
}
183+
delete_post_meta( $asset, '_cld_unsynced', true );
75184
$bar->tick();
76185
}
77-
$bar->tick( 0, 'Sync Completed.' );
78-
$bar->finish();
79-
$this->get_all_unsynced();
80-
\WP_CLI::success( 'Assets all synced' );
186+
// Done message - reanalyze.
187+
if ( $done === $total ) {
188+
$bar->tick( 0, 'Sync Completed.' );
189+
$bar->finish();
190+
$bar = null;
191+
\WP_CLI::line( '' );
192+
$this->analyze();
193+
delete_option( '_cld_cli_analyzed' );
194+
}
81195
}
82196

83197
/**
84-
* Allocate unsynced items to the queue threads.
198+
* Analyze and mark assets that need to be synced.
85199
*
86-
* @param array|bool $include Include already found items.
200+
* @since 2.5.1
87201
*
88-
* @return array
202+
* @param array $posts Array of Post IDs to process.
203+
* @param int $total Count of total posts to process.
89204
*/
90-
private function get_all_unsynced( $include = false ) {
91-
92-
$params = array(
93-
'post_type' => 'attachment',
94-
'post_status' => 'inherit',
95-
'fields' => 'ids',
96-
'posts_per_page' => - 1,
97-
);
205+
protected function process_analyze( $posts, $total ) {
206+
static $bar, $done, $info;
98207

99-
if ( ! empty( $include ) ) {
100-
$params['post__in'] = $include;
208+
if ( ! $bar ) {
209+
\WP_CLI::log( \WP_CLI::colorize( '%gAnalyzing ' . $total . ' assets:%n' ) );
210+
$bar = \WP_CLI\Utils\make_progress_bar( '', $total, 10 );
211+
$done = 0;
212+
$info = array(
213+
'_cld_unsupported' => 0,
214+
'_cld_synced' => 0,
215+
'_cld_unsynced' => 0,
216+
);
101217
}
102-
$ids = array();
103-
104-
$query = new \WP_Query( $params );
105-
$posts = $query->get_posts();
106-
\WP_CLI::log( '' );
107-
\WP_CLI::log( \WP_CLI::colorize( '%yAnalysing assets:%n' ) );
108-
$bar = \WP_CLI\Utils\make_progress_bar( '', $query->found_posts, 10 );
109-
$info = array(
110-
'_cld_unsupported' => 0,
111-
'_cld_synced' => 0,
112-
'_cld_unsynced' => 0,
113-
);
114-
foreach ( $posts as $index => $post ) {
115-
delete_post_meta( $post, '_cld_unsupported', true );
116-
delete_post_meta( $post, '_cld_synced', true );
117-
delete_post_meta( $post, '_cld_unsynced', true );
218+
foreach ( $posts as $index => $asset ) {
219+
$done ++;
118220
$key = '_cld_unsupported';
119-
if ( $this->plugin->get_component( 'media' )->is_media( $post ) ) {
221+
if ( $this->plugin->get_component( 'media' )->is_media( $asset ) ) {
120222
// Add a key.
121223
$key = '_cld_synced';
122-
if ( ! $this->plugin->get_component( 'sync' )->is_synced( $post ) ) {
123-
$key = '_cld_unsynced';
124-
$ids[] = $post;
224+
if ( ! $this->plugin->get_component( 'sync' )->is_synced( $asset ) ) {
225+
$key = '_cld_unsynced';
226+
add_post_meta( $asset, $key, true, true );
125227
}
126228
}
127229
$info[ $key ] ++;
128-
add_post_meta( $post, $key, true, true );
129-
$bar->tick( 1, $index . ' of ' . $query->found_posts . ' |' );
230+
$bar->tick( 1, $done . ' of ' . $total . ' |' );
130231
}
131-
$bar->tick( 0, ' ' );
132-
$bar->finish();
133-
134-
\WP_CLI::success( $query->found_posts . ' analysed.' );
135-
\WP_CLI::log( '' );
136-
\WP_CLI::log( \WP_CLI::colorize( '%gSynced%n :' ) . ' ' . $info['_cld_synced'] );
137-
\WP_CLI::log( \WP_CLI::colorize( '%yUn-synced%n :' ) . ' ' . $info['_cld_unsynced'] );
138-
\WP_CLI::log( \WP_CLI::colorize( '%rUnsupported%n :' ) . ' ' . $info['_cld_unsupported'] );
139-
\WP_CLI::log( '' );
140-
if ( ! empty( $info['_cld_unsynced'] ) ) {
141-
\WP_CLI::confirm( 'Sync ' . count( $ids ) . ' assets?' );
142-
} else {
143-
return;
232+
// Done message.
233+
if ( $done === $total ) {
234+
$bar->tick( 0, $total . ' Analyzed |' );
235+
$bar->finish();
236+
$bar = null;
237+
\WP_CLI::log( '' );
238+
\WP_CLI::log( \WP_CLI::colorize( '%gSynced%n :' ) . ' ' . $info['_cld_synced'] );
239+
\WP_CLI::log( \WP_CLI::colorize( '%yUn-synced%n :' ) . ' ' . $info['_cld_unsynced'] );
240+
\WP_CLI::log( \WP_CLI::colorize( '%rUnsupported%n :' ) . ' ' . $info['_cld_unsupported'] );
241+
update_option( '_cld_cli_analyzed', true, false );
144242
}
145-
146-
return $ids;
147243
}
148244
}

0 commit comments

Comments
 (0)