Completed
Branch BUG-10636-remove-unnecessary-b... (dfa227)
by
unknown
35:02 queued 23:26
created

Registry::getData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\services\assets;
4
5
use EE_Currency_Config;
6
use EE_Registry;
7
use EE_Template_Config;
8
use EEH_Qtip_Loader;
9
use InvalidArgumentException;
10
11
defined('EVENT_ESPRESSO_VERSION') || exit;
12
13
14
15
/**
16
 * Used for registering assets used in EE.
17
 *
18
 * @package    EventEspresso
19
 * @subpackage services\assets
20
 * @author     Darren Ethier
21
 * @since      4.9.24.rc.004
22
 */
23
class Registry
24
{
25
26
    /**
27
     * @var EE_Template_Config $template_config
28
     */
29
    protected $template_config;
30
31
    /**
32
     * @var EE_Currency_Config $currency_config
33
     */
34
    protected $currency_config;
35
36
    /**
37
     * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
38
     *
39
     * @var array
40
     */
41
    protected $jsdata = array();
42
43
44
    /**
45
     * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
46
     * page source.
47
     * @var array
48
     */
49
    protected $script_handles_with_data = array();
50
51
52
53
    /**
54
     * Registry constructor.
55
     * Hooking into WP actions for script registry.
56
     *
57
     * @param EE_Template_Config $template_config
58
     * @param EE_Currency_Config $currency_config
59
     */
60
    public function __construct(EE_Template_Config $template_config, EE_Currency_Config $currency_config)
61
    {
62
        $this->template_config = $template_config;
63
        $this->currency_config = $currency_config;
64
        add_action('wp_enqueue_scripts', array($this, 'scripts'), 1);
65
        add_action('admin_enqueue_scripts', array($this, 'scripts'), 1);
66
        add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 2);
67
        add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 2);
68
        add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
69
        add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
70
    }
71
72
73
74
    /**
75
     * Callback for the WP script actions.
76
     * Used to register globally accessible core scripts.
77
     * Also used to add the eejs.data object to the source for any js having eejs-core as a dependency.
78
     */
79
    public function scripts()
80
    {
81
        global $wp_version;
82
        wp_register_script(
83
            'eejs-core',
84
            EE_PLUGIN_DIR_URL . 'core/services/assets/core_assets/eejs-core.js',
85
            array(),
86
            EVENT_ESPRESSO_VERSION,
87
            true
88
        );
89
        //only run this if WordPress 4.4.0 > is in use.
90
        if (version_compare($wp_version, '4.4.0', '>')) {
91
            //js.api
92
            wp_register_script(
93
                'eejs-api',
94
                EE_LIBRARIES_URL . 'rest_api/assets/js/eejs-api.min.js',
95
                array('underscore', 'eejs-core'),
96
                EVENT_ESPRESSO_VERSION,
97
                true
98
            );
99
            $this->jsdata['eejs_api_nonce'] = wp_create_nonce('wp_rest');
100
            $this->jsdata['paths'] = array('rest_route' => rest_url('ee/v4.8.36/'));
101
        }
102
        if (! is_admin()) {
103
            $this->loadCoreCss();
104
        }
105
        $this->loadCoreJs();
106
        $this->loadJqueryValidate();
107
        $this->loadAccountingJs();
108
        $this->loadQtipJs();
109
    }
110
111
112
113
    /**
114
     * Call back for the script print in frontend and backend.
115
     * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
116
     *
117
     * @since 4.9.31.rc.015
118
     */
119
    public function enqueueData()
120
    {
121
        $this->removeAlreadyRegisteredDataForScriptHandles();
122
        wp_localize_script('eejs-core', 'eejs', array('data' => $this->jsdata));
123
        wp_localize_script('espresso_core', 'eei18n', EE_Registry::$i18n_js_strings);
124
        $this->localizeAccountingJs();
125
        $this->addRegisteredScriptHandlesWithData('eejs-core');
126
        $this->addRegisteredScriptHandlesWithData('espresso_core');
127
    }
128
129
130
131
    /**
132
     * Used to add data to eejs.data object.
133
     * Note:  Overriding existing data is not allowed.
134
     * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
135
     * If the data you add is something like this:
136
     *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
137
     * It will be exposed in the page source as:
138
     *  eejs.data.my_plugin_data.foo == gar
139
     *
140
     * @param string       $key   Key used to access your data
141
     * @param string|array $value Value to attach to key
142
     * @throws InvalidArgumentException
143
     */
144
    public function addData($key, $value)
145
    {
146
        if ($this->verifyDataNotExisting($key)) {
147
            $this->jsdata[$key] = $value;
148
        }
149
    }
150
151
152
153
    /**
154
     * Similar to addData except this allows for users to push values to an existing key where the values on key are
155
     * elements in an array.
156
     * When you use this method, the value you include will be appended to the end of an array on $key.
157
     * So if the $key was 'test' and you added a value of 'my_data' then it would be represented in the javascript
158
     * object like this, eejs.data.test = [ my_data,
159
     * ]
160
     * If there has already been a scalar value attached to the data object given key, then
161
     * this will throw an exception.
162
     *
163
     * @param string       $key   Key to attach data to.
164
     * @param string|array $value Value being registered.
165
     * @throws InvalidArgumentException
166
     */
167
    public function pushData($key, $value)
168
    {
169 View Code Duplication
        if (isset($this->jsdata[$key])
170
            && ! is_array($this->jsdata[$key])
171
        ) {
172
            throw new invalidArgumentException(
173
                sprintf(
174
                    __(
175
                        'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
176
                         push values to this data element when it is an array.',
177
                        'event_espresso'
178
                    ),
179
                    $key,
180
                    __METHOD__
181
                )
182
            );
183
        }
184
        $this->jsdata[$key][] = $value;
185
    }
186
187
188
189
    /**
190
     * Used to set content used by javascript for a template.
191
     * Note: Overrides of existing registered templates are not allowed.
192
     *
193
     * @param string $template_reference
194
     * @param string $template_content
195
     * @throws InvalidArgumentException
196
     */
197
    public function addTemplate($template_reference, $template_content)
198
    {
199
        if (! isset($this->jsdata['templates'])) {
200
            $this->jsdata['templates'] = array();
201
        }
202
        //no overrides allowed.
203
        if (isset($this->jsdata['templates'][$template_reference])) {
204
            throw new invalidArgumentException(
205
                sprintf(
206
                    __(
207
                        'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
208
                        'event_espresso'
209
                    ),
210
                    $template_reference
211
                )
212
            );
213
        }
214
        $this->jsdata['templates'][$template_reference] = $template_content;
215
    }
216
217
218
219
    /**
220
     * Retrieve the template content already registered for the given reference.
221
     *
222
     * @param string $template_reference
223
     * @return string
224
     */
225
    public function getTemplate($template_reference)
226
    {
227
        return isset($this->jsdata['templates'], $this->jsdata['templates'][$template_reference])
228
            ? $this->jsdata['templates'][$template_reference]
229
            : '';
230
    }
231
232
233
234
    /**
235
     * Retrieve registered data.
236
     *
237
     * @param string $key Name of key to attach data to.
238
     * @return mixed                If there is no for the given key, then false is returned.
239
     */
240
    public function getData($key)
241
    {
242
        return isset($this->jsdata[$key])
243
            ? $this->jsdata[$key]
244
            : false;
245
    }
246
247
248
249
    /**
250
     * Verifies whether the given data exists already on the jsdata array.
251
     * Overriding data is not allowed.
252
     *
253
     * @param string $key Index for data.
254
     * @return bool        If valid then return true.
255
     * @throws InvalidArgumentException if data already exists.
256
     */
257
    protected function verifyDataNotExisting($key)
258
    {
259
        if (isset($this->jsdata[$key])) {
260 View Code Duplication
            if (is_array($this->jsdata[$key])) {
261
                throw new InvalidArgumentException(
262
                    sprintf(
263
                        __(
264
                            'The value for %1$s already exists in the Registry::eejs object.
265
                            Overrides are not allowed. Since the value of this data is an array, you may want to use the
266
                            %2$s method to push your value to the array.',
267
                            'event_espresso'
268
                        ),
269
                        $key,
270
                        'pushData()'
271
                    )
272
                );
273
            }
274
            throw new InvalidArgumentException(
275
                sprintf(
276
                    __(
277
                        'The value for %1$s already exists in the Registry::eejs object. Overrides are not
278
                        allowed.  Consider attaching your value to a different key',
279
                        'event_espresso'
280
                    ),
281
                    $key
282
                )
283
            );
284
        }
285
        return true;
286
    }
287
288
289
290
    /**
291
     * registers core default stylesheets
292
     */
293
    private function loadCoreCss()
294
    {
295
        if ($this->template_config->enable_default_style) {
296
            $default_stylesheet_path = is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
297
                ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
298
                : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css';
299
            wp_register_style(
300
                'espresso_default',
301
                $default_stylesheet_path,
302
                array('dashicons'),
303
                EVENT_ESPRESSO_VERSION
304
            );
305
            //Load custom style sheet if available
306
            if ($this->template_config->custom_style_sheet !== null) {
307
                wp_register_style(
308
                    'espresso_custom_css',
309
                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
310
                    array('espresso_default'),
311
                    EVENT_ESPRESSO_VERSION
312
                );
313
            }
314
        }
315
    }
316
317
318
319
    /**
320
     * registers core default javascript
321
     */
322
    private function loadCoreJs()
323
    {
324
        // load core js
325
        wp_register_script(
326
            'espresso_core',
327
            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
328
            array('jquery'),
329
            EVENT_ESPRESSO_VERSION,
330
            true
331
        );
332
    }
333
334
335
336
    /**
337
     * registers jQuery Validate for form validation
338
     */
339
    private function loadJqueryValidate()
340
    {
341
        // register jQuery Validate and additional methods
342
        wp_register_script(
343
            'jquery-validate',
344
            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
345
            array('jquery'),
346
            '1.15.0',
347
            true
348
        );
349
        wp_register_script(
350
            'jquery-validate-extra-methods',
351
            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
352
            array('jquery', 'jquery-validate'),
353
            '1.15.0',
354
            true
355
        );
356
    }
357
358
359
360
    /**
361
     * registers accounting.js for performing client-side calculations
362
     */
363
    private function loadAccountingJs()
364
    {
365
        //accounting.js library
366
        // @link http://josscrowcroft.github.io/accounting.js/
367
        wp_register_script(
368
            'ee-accounting-core',
369
            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
370
            array('underscore'),
371
            '0.3.2',
372
            true
373
        );
374
        wp_register_script(
375
            'ee-accounting',
376
            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
377
            array('ee-accounting-core'),
378
            EVENT_ESPRESSO_VERSION,
379
            true
380
        );
381
    }
382
383
384
385
    /**
386
     * registers accounting.js for performing client-side calculations
387
     */
388
    private function localizeAccountingJs()
389
    {
390
        wp_localize_script(
391
            'ee-accounting',
392
            'EE_ACCOUNTING_CFG',
393
            array(
394
                'currency' => array(
395
                    'symbol'    => $this->currency_config->sign,
396
                    'format'    => array(
397
                        'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
398
                        'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
399
                        'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
400
                    ),
401
                    'decimal'   => $this->currency_config->dec_mrk,
402
                    'thousand'  => $this->currency_config->thsnds,
403
                    'precision' => $this->currency_config->dec_plc,
404
                ),
405
                'number'   => array(
406
                    'precision' => $this->currency_config->dec_plc,
407
                    'thousand'  => $this->currency_config->thsnds,
408
                    'decimal'   => $this->currency_config->dec_mrk,
409
                ),
410
            )
411
        );
412
        $this->addRegisteredScriptHandlesWithData('ee-accounting');
413
    }
414
415
416
417
    /**
418
     * registers assets for cleaning your ears
419
     */
420
    private function loadQtipJs()
421
    {
422
        // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
423
        // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
424
        if (apply_filters('FHEE_load_qtip', false)) {
425
            EEH_Qtip_Loader::instance()->register_and_enqueue();
426
        }
427
    }
428
429
430
    /**
431
     * This is used to set registered script handles that have data.
432
     * @param string $script_handle
433
     */
434
    private function addRegisteredScriptHandlesWithData($script_handle)
435
    {
436
        $this->script_handles_with_data[$script_handle] = $script_handle;
437
    }
438
439
440
    /**
441
     * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the
442
     * Dependency stored in WP_Scripts if its set.
443
     */
444
    private function removeAlreadyRegisteredDataForScriptHandles()
445
    {
446
        if (empty($this->script_handles_with_data)) {
447
            return;
448
        }
449
        foreach ($this->script_handles_with_data as $script_handle) {
450
            $this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
451
        }
452
    }
453
454
455
    /**
456
     * Removes any data dependency registered in WP_Scripts if its set.
457
     * @param string $script_handle
458
     */
459
    private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
460
    {
461
        if (isset($this->script_handles_with_data[$script_handle])) {
462
            global $wp_scripts;
463
            if ($wp_scripts->get_data($script_handle, 'data')) {
464
                unset($wp_scripts->registered[$script_handle]->extra['data']);
465
                unset($this->script_handles_with_data[$script_handle]);
466
            }
467
        }
468
    }
469
470
471
}
472