Completed
Branch BUG-9140-has-billing-form-igno... (f963e1)
by
unknown
257:50 queued 242:55
created

BatchRequestProcessor::create_job()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 29
Code Lines 21

Duplication

Lines 17
Ratio 58.62 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 17
loc 29
rs 8.5806
c 1
b 0
f 0
cc 4
eloc 21
nc 8
nop 2
1
<?php
2
 /**
3
 *
4
 * Class BatchRequetProcessor
5
  * 
6
 * Responsible for receiving a request to start a job and assign it a job Id.
7
 * Then when subsequent requests come in to continue that job, dispatches
8
 * the request to the appropriate JobHandler, which processes a step of the batch,
9
 * and then returns the job's new status.
10
 * This class is used by controller code, and the controller code is sent HTTP
11
 * requests from the batch_runner.js library
12
 *
13
 * @package         Event Espresso
14
 * @subpackage    batch
15
 * @author				Mike Nelson
16
 * @since		 	   4.8.26
17
 *
18
 */
19
namespace EventEspressoBatchRequest;
20
21
use EventEspressoBatchRequest\JobHandlerBaseClasses\JobHandlerInterface;
22
use EventEspressoBatchRequest\Helpers\BatchRequestException;
23
use EventEspressoBatchRequest\Helpers\JobParameters;
24
use EventEspressoBatchRequest\Helpers\JobStepResponse;
25
26
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
27
	exit( 'No direct script access allowed' );
28
}
29
30
31
32
class BatchRequestProcessor {
33
34
	/**
35
	 * Current job's ID (if assigned)
36
	 * @var string|null
37
	 */
38
	protected $_job_id;
39
40
	/**
41
	 * Current job's parameters
42
	 * @var JobParameters|null
43
	 */
44
	protected $_job_parameters;
45
46
	/**
47
	 * Creates a job for the specified batch handler class (which should be autoloaded)
48
	 * and the specified request data
49
	 * @param string $batch_job_handler_class of an auto-loaded class implementing JobHandlerInterface
50
	 * @param array $request_data to be used by the batch job handler
51
	 * @return JobStepResponse
52
	 */
53
	public function create_job( $batch_job_handler_class, $request_data ) {
54
		try {
55
			$this->_job_id = wp_generate_password( 15, false );
56
			$obj = $this->instantiate_batch_job_handler_from_classname( $batch_job_handler_class );
57
			$this->_job_parameters = new JobParameters( $this->_job_id, $batch_job_handler_class, $request_data );
58
			$response = $obj->create_job( $this->_job_parameters );
59 View Code Duplication
			if( ! $response instanceof JobStepResponse ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
60
				throw new BatchRequestException(
61
					sprintf(
62
						__( 'The class implementing JobHandlerInterface did not return a JobStepResponse when create_job was called with %1$s. It needs to return one or throw an Exception', 'event_espresso' ),
63
						wp_json_encode( $request_data )
64
					)
65
				);
66
			}
67
			$success = $this->_job_parameters->save( true );
68 View Code Duplication
			if( ! $success ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
69
				throw new BatchRequestException(
70
					sprintf(
71
						__('Could not save job %1$s to the Wordpress Options table. These were the arguments used: %2$s', 'event_espresso'),
72
						$this->_job_id,
73
						wp_json_encode( $request_data )
74
					)
75
				);
76
			}
77
		} catch( \Exception $e ) {
78
			$response = $this->_get_error_response( $e, 'create_job' );
79
		}
80
		return $response;
81
	}
82
83
84
85
	/**
86
	 * Retrieves the job's arguments
87
	 * @param string $job_id
88
	 * @param int $batch_size
89
	 * @return JobStepResponse
90
	 */
91
	public function continue_job( $job_id, $batch_size = 50 ) {
92
		try {
93
			$this->_job_id = $job_id;
94
			$batch_size = defined( 'EE_BATCHRUNNER_BATCH_SIZE' ) ? EE_BATCHRUNNER_BATCH_SIZE : $batch_size;
95
			//get the corresponding WordPress option for the job
96
			$this->_job_parameters = JobParameters::load( $this->_job_id );
97
			$handler_obj = $this->instantiate_batch_job_handler_from_classname( $this->_job_parameters->classname() );
98
			//continue it
99
			$response = $handler_obj->continue_job( $this->_job_parameters, $batch_size );
100 View Code Duplication
			if( ! $response instanceof JobStepResponse ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
101
				throw new BatchRequestException(
102
					sprintf(
103
						__( 'The class implementing JobHandlerInterface did not return a JobStepResponse when continue_job was called with job %1$s. It needs to return one or throw an Exception', 'event_espresso' ),
104
						$this->_job_id
105
					)
106
				);
107
			}
108
			$this->_job_parameters->save();
109
		} catch( \Exception $e ) {
110
			$response = $this->_get_error_response( $e, 'continue_job' );
111
		}
112
		return $response;
113
	}
114
115
116
117
	/**
118
	 * Instantiates an object of type $classname, which implements
119
	 * JobHandlerInterface
120
	 *
121
	 * @param string $classname
122
	 * @return JobHandlerInterface
123
	 * @throws BatchRequestException
124
	 */
125
	public function instantiate_batch_job_handler_from_classname( $classname ) {
126
		if( ! class_exists( $classname ) ) {
127
			throw new BatchRequestException(
128
				sprintf(
129
					__('The class %1$s does not exist, and so could not be used for running a job. It should implement JobHandlerInterface.', 'event_espresso'),
130
					$classname
131
				)
132
			);
133
		}
134
		$obj = new $classname;
135
		if( ! $obj instanceof JobHandlerInterface ) {
136
			throw new BatchRequestException(
137
				sprintf(
138
					__('The class %1$s does not implement JobHandlerInterface and so could not be used for running a job', 'event_espresso'),
139
					$classname
140
				)
141
			);
142
		}
143
		return $obj;
144
	}
145
146
147
148
	/**
149
	 * Forces a job to be cleaned up
150
	 *
151
	 * @param string $job_id
152
	 * @return JobStepResponse
153
	 * @throws BatchRequestException
154
	 */
155
	public function cleanup_job( $job_id ) {
156
		try{
157
			$this->_job_id = $job_id;
158
			$job_parameters = JobParameters::load( $this->_job_id );
159
			$handler_obj = $this->instantiate_batch_job_handler_from_classname( $job_parameters->classname() );
160
			//continue it
161
			$response = $handler_obj->cleanup_job( $job_parameters );
162 View Code Duplication
			if( ! $response instanceof JobStepResponse ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
163
				throw new BatchRequestException(
164
					sprintf(
165
						__( 'The class implementing JobHandlerInterface did not return a JobStepResponse when cleanup_job was called with job %1$s. It needs to return one or throw an Exception', 'event_espresso' ),
166
						$this->_job_id
167
					)
168
				);
169
			}
170
			$job_parameters->set_status( JobParameters::status_cleaned_up );
171
			$job_parameters->delete();
172
			return $response;
173
		} catch( \Exception $e ) {
174
			$response = $this->_get_error_response( $e, 'cleanup_job' );
175
		}
176
		return $response;
177
	}
178
179
180
181
	/**
182
	 * Creates a valid JobStepResponse object from an exception and method name.
183
	 * @param \Exception $exception
184
	 * @param string $method_name
185
	 * @return JobStepResponse
186
	 */
187
	protected function _get_error_response( \Exception $exception, $method_name ) {
188
		if( ! $this->_job_parameters instanceof JobParameters ) {
189
			$this->_job_parameters = new JobParameters( $this->_job_id, __( '__Unknown__', 'event_espresso' ), array() );
190
		}
191
		$this->_job_parameters->set_status( JobParameters::status_error );
192
		return new JobStepResponse(
193
			$this->_job_parameters,
194
			sprintf(
195
				__('An exception of type %1$s occurred while running %2$s. Its message was %3$s and had trace %4$s', 'event_espresso'),
196
				get_class( $exception ),
197
				'BatchRunner::' . $method_name . '()',
198
				$exception->getMessage(),
199
				$exception->getTraceAsString()
200
			)
201
		);
202
	}
203
204
205
}
206
207