Completed
Branch Gutenberg/event-attendees-bloc... (e27df5)
by
unknown
42:51 queued 28:10
created

EED_Batch::enqueue_scripts()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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