|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Wordlift\Videoobject; |
|
4
|
|
|
|
|
5
|
|
View Code Duplication |
class Videoobject_Background_Process extends \Wordlift_Plugin_WP_Background_Process { |
|
|
|
|
|
|
6
|
|
|
|
|
7
|
|
|
const WL_CMKG_ANALYSIS_BACKGROUND_PROCESS = '_wl_cmkg_analysis_background_process'; |
|
8
|
|
|
|
|
9
|
|
|
|
|
10
|
|
|
protected $action = 'wl_cmkg_analysis_background__analysis'; |
|
11
|
|
|
|
|
12
|
|
|
/** |
|
13
|
|
|
* @var Analysis_Background_Service |
|
14
|
|
|
*/ |
|
15
|
|
|
private $analysis_background_service; |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* @var \Wordlift_Log_Service |
|
19
|
|
|
*/ |
|
20
|
|
|
private $log; |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* Analysis_Background_Process constructor. |
|
24
|
|
|
* |
|
25
|
|
|
* @param $analysis_background_service Analysis_Background_Service A {@link Analysis_Background_Service} instance providing the supporting functions to this background process. |
|
26
|
|
|
*/ |
|
27
|
|
|
public function __construct( $analysis_background_service ) { |
|
28
|
|
|
parent::__construct(); |
|
29
|
|
|
|
|
30
|
|
|
$this->log = \Wordlift_Log_Service::get_logger( get_class() ); |
|
31
|
|
|
|
|
32
|
|
|
$this->analysis_background_service = $analysis_background_service; |
|
33
|
|
|
|
|
34
|
|
|
|
|
35
|
|
|
} |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* This function is called: |
|
39
|
|
|
* - To start a new Synchronization, by passing a {@link Sync_Start_Message} instance. |
|
40
|
|
|
* - To synchronize a post, by passing a numeric ID. |
|
41
|
|
|
* |
|
42
|
|
|
* This function returns the parameter for the next call or NULL if there are no more posts to process. |
|
43
|
|
|
* |
|
44
|
|
|
* @param int[] $term_ids An array of term IDs. |
|
45
|
|
|
* |
|
46
|
|
|
* @return int[]|false The next term IDs or false if there are no more. |
|
47
|
|
|
*/ |
|
48
|
|
|
protected function task( $term_ids ) { |
|
49
|
|
|
|
|
50
|
|
|
// Check if we must cancel. |
|
51
|
|
|
if ( $this->must_cancel() ) { |
|
52
|
|
|
$this->cancel(); |
|
53
|
|
|
|
|
54
|
|
|
return false; |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
if ( $term_ids && is_array($term_ids) ) { |
|
|
|
|
|
|
58
|
|
|
$this->log->debug( sprintf( "Synchronizing terms %s...", implode( ', ', $term_ids ) ) ); |
|
59
|
|
|
} |
|
60
|
|
|
// Sync the item. |
|
61
|
|
|
return $this->sync_items( $term_ids ); |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* Start the background processing. |
|
66
|
|
|
* |
|
67
|
|
|
* @return bool True if the process has been started, otherwise false. |
|
68
|
|
|
*/ |
|
69
|
|
|
public function start() { |
|
70
|
|
|
$this->log->debug( "Trying to start analysis bg service..." ); |
|
71
|
|
|
// Create a new Sync_Model state of `started`. |
|
72
|
|
|
if ( ! $this->is_started( self::get_state() ) ) { |
|
73
|
|
|
$this->log->debug( "Starting..." ); |
|
74
|
|
|
|
|
75
|
|
|
$sync_state = new Sync_State( time(), 0, $this->analysis_background_service->count(), time(), 'started' ); |
|
76
|
|
|
update_option( self::WL_CMKG_ANALYSIS_BACKGROUND_PROCESS, $sync_state, false ); |
|
77
|
|
|
|
|
78
|
|
|
$next = $this->analysis_background_service->next(); |
|
79
|
|
|
|
|
80
|
|
|
$this->push_to_queue( $next ); |
|
81
|
|
|
$this->save()->dispatch(); |
|
82
|
|
|
|
|
83
|
|
|
if ( $next && is_array($next) ) { |
|
84
|
|
|
$this->log->debug( sprintf( 'Started with term IDs %s.', implode( ', ', $next ) ) ); |
|
85
|
|
|
} |
|
86
|
|
|
return true; |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
return false; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Set the transient to cancel the process. The next time the process runs, it'll check whether this transient is |
|
94
|
|
|
* set and will stop processing. |
|
95
|
|
|
*/ |
|
96
|
|
|
public function request_cancel() { |
|
97
|
|
|
|
|
98
|
|
|
set_transient( "{$this->action}__cancel", true ); |
|
99
|
|
|
|
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* Get the sync state. |
|
104
|
|
|
* |
|
105
|
|
|
* @return Sync_State The {@link Sync_State}. |
|
106
|
|
|
*/ |
|
107
|
|
|
public static function get_state() { |
|
108
|
|
|
|
|
109
|
|
|
try { |
|
110
|
|
|
return get_option( self::WL_CMKG_ANALYSIS_BACKGROUND_PROCESS, Sync_State::unknown() ); |
|
111
|
|
|
} catch ( \Exception $e ) { |
|
112
|
|
|
return Sync_State::unknown(); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
/** |
|
118
|
|
|
* Check whether the provided state is `started` or not. |
|
119
|
|
|
* |
|
120
|
|
|
* @param Sync_State $state The {@link Sync_State}. |
|
121
|
|
|
* |
|
122
|
|
|
* @return bool True if the state is started. |
|
123
|
|
|
*/ |
|
124
|
|
|
private function is_started( $state ) { |
|
125
|
|
|
return $state instanceof Sync_State && 'started' === $state->state && 30 > ( time() - $state->last_update ); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
/** |
|
129
|
|
|
* Check whether the process must cancel or not. |
|
130
|
|
|
* |
|
131
|
|
|
* @return bool Whether to cancel or not the process. |
|
132
|
|
|
*/ |
|
133
|
|
|
private function must_cancel() { |
|
134
|
|
|
|
|
135
|
|
|
return get_transient( "{$this->action}__cancel" ); |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* Cancels the current process. |
|
140
|
|
|
*/ |
|
141
|
|
|
public function cancel() { |
|
142
|
|
|
|
|
143
|
|
|
$this->log->debug( "Cancelling synchronization..." ); |
|
144
|
|
|
|
|
145
|
|
|
// Cleanup the process data. |
|
146
|
|
|
$this->cancel_process(); |
|
147
|
|
|
|
|
148
|
|
|
// Set the state to cancelled. |
|
149
|
|
|
$state = self::get_state(); |
|
150
|
|
|
$state->set_state( 'cancelled' ); |
|
151
|
|
|
update_option( self::WL_CMKG_ANALYSIS_BACKGROUND_PROCESS, $state, false ); |
|
152
|
|
|
|
|
153
|
|
|
// Finally delete the transient. |
|
154
|
|
|
delete_transient( "{$this->action}__cancel" ); |
|
155
|
|
|
|
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* Push the post with the provided ID to the remote platform. |
|
160
|
|
|
* |
|
161
|
|
|
* @param int[] $term_ids The term IDs. |
|
162
|
|
|
* |
|
163
|
|
|
* @return int[]|false The next term ID to process or false if processing is complete. |
|
164
|
|
|
*/ |
|
165
|
|
|
private function sync_items( $term_ids ) { |
|
166
|
|
|
|
|
167
|
|
|
|
|
168
|
|
|
$this->log->debug( "sync_items called with term ids : " . join( ",", $term_ids ) ); |
|
169
|
|
|
|
|
170
|
|
|
if (! $term_ids ) { |
|
|
|
|
|
|
171
|
|
|
$this->cancel_process(); |
|
172
|
|
|
return false; |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
if ( ! is_array( $term_ids ) ) { |
|
176
|
|
|
$this->log->error( '$term_ids must be an array, received: ' . var_export( $term_ids, true ) ); |
|
177
|
|
|
|
|
178
|
|
|
return false; |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
// Sync this item. |
|
182
|
|
|
if ( $this->analysis_background_service->perform_analysis_for_terms( $term_ids ) ) { |
|
183
|
|
|
|
|
184
|
|
|
$next = $this->analysis_background_service->next(); |
|
185
|
|
|
$next_state = isset( $next ) ? 'started' : 'ended'; |
|
186
|
|
|
|
|
187
|
|
|
/** |
|
188
|
|
|
* Update the synchronization meta data, by increasing the current index. |
|
189
|
|
|
* |
|
190
|
|
|
* @var Sync_State $sync The {@link Sync_State}. |
|
191
|
|
|
*/ |
|
192
|
|
|
$state = self::get_state() |
|
193
|
|
|
->increment_index( $this->analysis_background_service->get_batch_size() ) |
|
194
|
|
|
->set_state( $next_state ); |
|
195
|
|
|
update_option( self::WL_CMKG_ANALYSIS_BACKGROUND_PROCESS . '', $state, false ); |
|
196
|
|
|
|
|
197
|
|
|
|
|
198
|
|
|
// Return the next IDs or false if there aren't. |
|
199
|
|
|
return isset( $next ) ? $next : false; |
|
200
|
|
|
} else { |
|
201
|
|
|
// Retry. |
|
202
|
|
|
// @@todo: put a limit to the number of retries. |
|
203
|
|
|
|
|
204
|
|
|
$this->log->error( sprintf( "Sync failed for terms %s.", implode( ', ', $term_ids ) ) ); |
|
205
|
|
|
|
|
206
|
|
|
return $term_ids; |
|
|
|
|
|
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
} |
|
210
|
|
|
|
|
211
|
|
|
} |
|
212
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.