Code Duplication    Length = 207-207 lines in 2 locations

src/wordlift/videoobject/class-videoobject-background-process.php 1 location

@@ 5-211 (lines=207) @@
2
3
namespace Wordlift\Videoobject;
4
5
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

src/wordlift/vocabulary/class-analysis-background-process.php 1 location

@@ 5-211 (lines=207) @@
2
3
namespace Wordlift\Vocabulary;
4
5
class Analysis_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