Completed
Branch BETA-4.9-messages-queue-fixed (cf2209)
by
unknown
32:34 queued 17:09
created

EED_Batch   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 273
Duplicated Lines 4.4 %

Coupling/Cohesion

Components 2
Dependencies 5
Metric Value
wmc 32
lcom 2
cbo 5
dl 12
loc 273
rs 9.6

16 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 3 1
A _return_json() 0 19 4
A job_step_response() 0 3 1
A run() 0 3 1
A set_hooks() 0 8 2
A set_hooks_admin() 0 10 1
B enqueue_scripts() 0 18 6
A enqueue_scripts_styles_batch_create() 0 9 1
A enqueue_scripts_styles_batch_file_create() 0 14 1
A _enqueue_batch_job_scripts_and_styles_and_start_job() 0 17 1
A override_template() 0 6 3
A register_admin_pages() 0 10 1
A show_admin_page() 0 6 1
A batch_continue() 6 6 1
A batch_cleanup() 6 6 1
B batch_request_type() 0 16 6

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 *
5
 * Class EED_Batch
6
 *
7
 * Module for running batch jobs, which uses the library files in event-espresso-core/core/libraries/batch.
8
 * So will respond on the frontend at "{site_url}?espresso_batch&batch={file|job}", 
9
 * or in the admin at "{site_url}/wp-admin?page=espresso_batch&batch={file|job}" (use whichever will make your user happier,
10
 * note that the admin one requires the user to be able to access the admin, and the frontend one is disabled until specifically enabled via a filter).
11
 * 
12
 * 
13
 *
14
 * @package         Event Espresso
15
 * @subpackage    
16
 * @author				Mike Nelson
17
 * @since		 	   4.8.30.rc.007
18
 *
19
 */
20
if( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
21
	exit( 'No direct script access allowed' );
22
}
23
24
define( 'BATCH_URL', plugin_dir_url( __FILE__ ) );
25
26
class EED_Batch extends EED_Module{
27
	
28
	/**
29
	 * Possibly value for $_REQUEST[ 'batch' ]. Indicates to run a job that
30
	 * processes data only
31
	 */
32
	const batch_job = 'job';
33
	/**
34
	 * Possibly value for $_REQUEST[ 'batch' ]. Indicates to run a job that
35
	 * produces a file for download
36
	 */
37
	const batch_file_job = 'file';
38
	/**
39
	 * Possibly value for $_REQUEST[ 'batch' ]. Indicates this request is NOT
40
	 * for a batch job. It's the same as not providing the $_REQUEST[ 'batch' ] 
41
	 * at all
42
	 */
43
	const batch_not_job = 'none';
44
	
45
	/**
46
	 *
47
	 * @var string 'file', or 'job', or false to indicate its not a batch request at all
48
	 */
49
	protected $_batch_request_type = null;
50
	
51
	/**
52
	 * Because we want to use the response in both the localized JS and in the body
53
	 * we need to make this response available between method calls
54
	 * @var \EventEspressoBatchRequest\Helpers\JobStepResponse
55
	 */
56
	protected $_job_step_response = null;
57
	
58
	/**
59
	 * Gets the batch instance
60
	 * @return EED_Batch
61
	 */
62
	public static function instance() {
63
		return self::get_instance();
64
	}
65
	
66
	/**
67
	 * Sets hooks to enable batch jobs on the frontend. Disabled by default
68
	 * because it's an attack vector and there are currently no implementations
69
	 */
70
	public static function set_hooks() {
71
		//because this is a possibel attack vector, let's have this disabled until 
72
		//we at least have a real use for it on the frontend
73
		if( apply_filters( 'FHEE__EED_Batch__set_hooks__enable_frontend_batch', false ) ) {
74
			add_action( 'wp_enqueue_scripts', array( self::instance(), 'enqueue_scripts' ) );
75
			add_filter( 'template_include', array( self::instance(), 'override_template' ), 99 );
76
		}
77
	}
78
	
79
	/**
80
	 * Initializes some hooks for the admin in order to run batch jobs
81
	 */
82
	public static function set_hooks_admin() {
83
		add_action( 'admin_menu', array( self::instance(), 'register_admin_pages' ) );
84
		add_action( 'admin_enqueue_scripts', array( self::instance(), 'enqueue_scripts' ) );
85
		
86
		//ajax
87
		add_action('wp_ajax_espresso_batch_continue',array(self::instance(),'batch_continue'));
88
		add_action('wp_ajax_espresso_batch_cleanup',array(self::instance(),'batch_cleanup'));
89
		add_action('wp_ajax_nopriv_espresso_batch_continue',array(self::instance(),'batch_continue'));
90
		add_action('wp_ajax_nopriv_espresso_batch_cleanup',array(self::instance(),'batch_cleanup'));
91
	}
92
	
93
	/**
94
	 * Enqueues batch scripts on the frontend or admin, and creates a job
95
	 */
96
	public function enqueue_scripts() { 
97
		if( isset( $_REQUEST[ 'espresso_batch' ] ) 
98
			|| 
99
			( 
100
				isset( $_REQUEST[ 'page' ] )
101
				&& $_REQUEST[ 'page' ] == 'espresso_batch'
102
			) 
103
		) { 
104
			switch( $this->batch_request_type() ) {
105
				case self::batch_job:
106
					$this->enqueue_scripts_styles_batch_create();
107
					break;
108
				case self::batch_file_job:
109
					$this->enqueue_scripts_styles_batch_file_create();
110
					break;
111
			}
112
		}
113
	}
114
	
115
	/**
116
	 * Create a batch job, enqueues a script to run it, and localizes some data for it
117
	 */
118
	public function enqueue_scripts_styles_batch_create() {	
119
		$job_response = $this->_enqueue_batch_job_scripts_and_styles_and_start_job();
120
		wp_enqueue_script( 'batch_runner_init', BATCH_URL . '/assets/batch_runner_init.js', array( 'batch_runner' ), EVENT_ESPRESSO_VERSION, true );
121
		wp_localize_script( 'batch_runner_init', 'ee_job_response', $job_response->to_array() );
122
		wp_localize_script( 'batch_runner_init', 'ee_job_i18n', 
123
			array(
124
				'return_url' => $_REQUEST['return_url' ],
125
			));
126
	}
127
	
128
	/**
129
	 * Creates a batch job which will download a file, enqueues a script to run the job, and localizes some data for it
130
	 */
131
	public function enqueue_scripts_styles_batch_file_create() {
132
		//creates a job based on the request variable
133
		$job_response = $this->_enqueue_batch_job_scripts_and_styles_and_start_job();
134
		wp_enqueue_script( 'batch_file_runner_init', BATCH_URL . '/assets/batch_file_runner_init.js', array( 'batch_runner' ), EVENT_ESPRESSO_VERSION, true );
135
		wp_localize_script( 'batch_file_runner_init', 'ee_job_response', $job_response->to_array() );
136
		wp_localize_script( 'batch_file_runner_init', 'ee_job_i18n', 
137
				array(
138
					'download_and_redirecting' => sprintf( 
139
							__('File Generation complete. Downloading, and %1$sredirecting%2$s...', 'event_espresso'),
140
							'<a href="' . $_REQUEST['return_url' ] .'">',
141
							'</a>' ),
142
					'return_url' => $_REQUEST['return_url' ],
143
				));
144
	}
145
	
146
	/**
147
	 * Enqueues scripts and styles common to any batch job, and creates 
148
	 * a job from the request data, and stores the response in the
149
	 * $this->_job_step_response property
150
	 * @return \EventEspressoBatchRequest\Helpers\JobStepResponse
151
	 */
152
	protected function _enqueue_batch_job_scripts_and_styles_and_start_job() {
153
		wp_register_script( 'progress_bar', EE_PLUGIN_DIR_URL . 'core/libraries/batch/Assets/progress_bar.js', array( 'jquery' ) );
154
		wp_enqueue_style( 'progress_bar', EE_PLUGIN_DIR_URL . 'core/libraries/batch/Assets/progress_bar.css', array(), EVENT_ESPRESSO_VERSION );
155
		wp_enqueue_script( 'batch_runner', EE_PLUGIN_DIR_URL . 'core/libraries/batch/Assets/batch_runner.js', array( 'progress_bar' ));
156
		//just copy the bits of EE admin's eei18n that we need in the JS
157
		wp_localize_script( 'batch_runner', 'eei18n', array( 'ajax_url' => WP_AJAX_URL, 'is_admin' => (bool)is_admin() ) );
158
		$job_handler_classname = stripslashes( $_GET[ 'job_handler' ] );
159
		$request_data = array_diff_key( 
160
				$_REQUEST, 
161
				array_flip( array( 'action',  'page', 'ee', 'batch' ) ) );
162
		$batch_runner = new EventEspressoBatchRequest\BatchRequestProcessor();
163
		//eg 'EventEspressoBatchRequest\JobHandlers\RegistrationsReport'
164
		$job_response = $batch_runner->create_job( $job_handler_classname, $request_data );
165
		//remember the response for later. We need it to display the page body
166
		$this->_job_step_response = $job_response;
167
		return $job_response;
168
	}
169
	
170
	/**
171
	 * If we are doing a frontend batch job, this makes it so WP shows our template's HTML
172
	 * @param string $template
173
	 * @return string
174
	 */
175
	public function override_template( $template ) {
176
		if( isset( $_REQUEST[ 'espresso_batch' ] ) && isset( $_REQUEST[ 'batch' ] ) ) {
177
			return EE_MODULES . 'batch' . DS . 'templates' . DS . 'batch_frontend_wrapper.template.html';
178
		}
179
		return $template;
180
	}
181
	
182
	/**
183
	 * Adds an admin page which doesn't appear in the admin menu
184
	 */
185
	public function register_admin_pages() {
186
		add_submenu_page( 
187
			'', //parent slug. we don't want this to actually appear in the menu
188
			__( 'Batch Job', 'event_espresso' ), //page title
189
			'n/a', //menu title
190
			'read', //we want this page to actually be accessible to anyone,  
191
			'espresso_batch', //menu slug
192
			array( self::instance(), 'show_admin_page' )
193
		);
194
	}
195
	
196
	/**
197
	 * Renders the admin page, after most of the work was already done during enqueuing scripts
198
	 * of creating the job and localizing some data
199
	 */
200
	public function show_admin_page() { 
201
		echo EEH_Template::locate_template( 
202
			EE_MODULES . 'batch' . DS . 'templates' . DS . 'batch_wrapper.template.html', 
203
			array( 'batch_request_type' => $this->batch_request_type() )
204
		);
205
	}
206
	
207
	/**
208
	 * Receives ajax calls for continuing a job
209
	 */
210 View Code Duplication
	public function batch_continue() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
211
		$job_id = sanitize_text_field( $_REQUEST[ 'job_id' ] );
212
		$batch_runner = new EventEspressoBatchRequest\BatchRequestProcessor();
213
		$response_obj = $batch_runner->continue_job( $job_id);
214
		$this->_return_json( $response_obj->to_array() );
215
	}
216
	
217
	/**
218
	 * Receives the ajax call to cleanup a job
219
	 * @return type
220
	 */
221 View Code Duplication
	public function batch_cleanup() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
222
		$job_id = sanitize_text_field( $_REQUEST[ 'job_id' ] );
223
		$batch_runner = new EventEspressoBatchRequest\BatchRequestProcessor();
224
		$response_obj = $batch_runner->cleanup_job( $job_id );
225
		$this->_return_json( $response_obj->to_array() );
226
	}
227
	
228
	
229
	/**
230
	 * Returns a json response
231
	 *
232
	 * @param array $data The data we want to send echo via in the JSON response's "data" element
233
	 *
234
	 * The returned json object is created from an array in the following format:
235
	 * array(
236
	 * 	'notices' => '', // - contains any EE_Error formatted notices
237
	 * 	'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js. We're also going to include the template args with every package (so js can pick out any specific template args that might be included in here)
238
	 *	'isEEajax' => true,//indicates this is a response from EE
239
	 * )
240
	 */
241
	protected function _return_json( $data ) {
242
		$json = array(
243
			'notices' => EE_Error::get_notices(),
244
			'data' => $data,
245
			'isEEajax' => TRUE //special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
246
			);
247
248
249
		// make sure there are no php errors or headers_sent.  Then we can set correct json header.
250
		if ( NULL === error_get_last() || ! headers_sent() ) {
251
			header('Content-Type: application/json; charset=UTF-8');
252
		}	
253
		if( function_exists( 'wp_json_encode' ) ) {
254
			echo wp_json_encode( $json );
255
		} else {
256
			echo json_encode( $json );
257
		}
258
		exit();
259
	}
260
	
261
	/**
262
	 * Gets the job step response which was done during the enqueuing of scripts
263
	 * @return \EventEspressoBatchRequest\Helpers\JobStepResponse
264
	 */
265
	public function job_step_response() {
266
		return $this->_job_step_response;
267
	}
268
	/**
269
	 * Gets the batch request type indicated in the $_REQUEST
270
	 * @return string: EED_Batch::batch_job, EED_Batch::batch_file_job, EED_Batch::batch_not_job
0 ignored issues
show
Documentation introduced by
The doc-type string: could not be parsed: Unknown type name "string:" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
271
	 */
272
	public function batch_request_type() {
273
		if( $this->_batch_request_type === null ) {
274
			if( isset( $_GET[ 'batch' ] ) ) {
275
				if( $_GET[ 'batch' ] == self::batch_job ) {
276
					$this->_batch_request_type = self::batch_job;
277
				} elseif( $_GET[ 'batch' ] == self::batch_file_job ) {
278
					$this->_batch_request_type = self::batch_file_job;
279
				}
280
			}
281
			//if we didn't find that it was a batch request, indicate it wasn't
282
			if( $this->_batch_request_type === null ) {
283
				$this->_batch_request_type = self::batch_not_job;
284
			}
285
		}
286
		return $this->_batch_request_type;
287
	}
288
	
289
	/**
290
	 * Unnecessary
291
	 * @param type $WP
292
	 */
293
	public function run( $WP ) {
294
		
295
	}
296
297
//put your code here
298
}
299