Completed
Branch BUG-10911-php-7.2 (ef442d)
by
unknown
104:08 queued 92:42
created

retrieveStoredNotices()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 59
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 39
c 1
b 0
f 0
nc 6
nop 0
dl 0
loc 59
rs 8.7117

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace EventEspresso\core\services\notifications;
4
5
use DomainException;
6
use EE_Error;
7
use EE_Request;
8
use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
9
use EventEspresso\core\domain\services\capabilities\CapabilitiesChecker;
10
use EventEspresso\core\exceptions\InsufficientPermissionsException;
11
use EventEspresso\core\exceptions\InvalidClassException;
12
use EventEspresso\core\exceptions\InvalidDataTypeException;
13
use EventEspresso\core\exceptions\InvalidEntityException;
14
use EventEspresso\core\exceptions\InvalidInterfaceException;
15
use EventEspresso\core\services\collections\Collection;
16
use Exception;
17
18
defined('EVENT_ESPRESSO_VERSION') || exit;
19
20
21
22
/**
23
 * Class PersistentAdminNoticeManager
24
 * class for managing the loading, display, and storage of PersistentAdminNotice objects
25
 *
26
 * @package Event Espresso
27
 * @author  Brent Christensen
28
 * @since   4.9.27
29
 */
30
class PersistentAdminNoticeManager
31
{
32
33
    const WP_OPTION_KEY = 'ee_pers_admin_notices';
34
35
    /**
36
     * @var Collection|PersistentAdminNotice[] $notice_collection
37
     */
38
    private $notice_collection;
39
40
    /**
41
     * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the
42
     * persistent admin notice was displayed, and ultimately dismissed from.
43
     *
44
     * @type string $return_url
45
     */
46
    private $return_url;
47
48
    /**
49
     * @type CapabilitiesChecker $capabilities_checker
50
     */
51
    private $capabilities_checker;
52
53
    /**
54
     * @type EE_Request $request
55
     */
56
    private $request;
57
58
59
60
    /**
61
     * CapChecker constructor
62
     *
63
     * @param string              $return_url  where to  redirect to after dismissing notices
64
     * @param CapabilitiesChecker $capabilities_checker
65
     * @param EE_Request          $request
66
     * @throws InvalidDataTypeException
67
     */
68
    public function __construct($return_url = '', CapabilitiesChecker $capabilities_checker, EE_Request $request)
69
    {
70
        $this->setReturnUrl($return_url);
71
        $this->capabilities_checker = $capabilities_checker;
72
        $this->request              = $request;
73
        // setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10,
74
        // and we want to retrieve and generate any nag notices at the last possible moment
75
        add_action('admin_notices', array($this, 'displayNotices'), 9);
76
        add_action('network_admin_notices', array($this, 'displayNotices'), 9);
77
        add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice'));
78
        add_action('shutdown', array($this, 'registerAndSaveNotices'), 998);
79
    }
80
81
82
83
    /**
84
     * @param string $return_url
85
     * @throws InvalidDataTypeException
86
     */
87
    private function setReturnUrl($return_url)
88
    {
89
        if (! is_string($return_url)) {
90
            throw new InvalidDataTypeException('$return_url', $return_url, 'string');
91
        }
92
        $this->return_url = $return_url;
93
    }
94
95
96
97
    /**
98
     * @return Collection
99
     * @throws InvalidEntityException
100
     * @throws InvalidInterfaceException
101
     * @throws InvalidDataTypeException
102
     * @throws DomainException
103
     */
104
    protected function getPersistentAdminNoticeCollection()
105
    {
106
        if (! $this->notice_collection instanceof Collection) {
107
            $this->notice_collection = new Collection(
108
                'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
109
            );
110
            $this->retrieveStoredNotices();
111
            $this->registerNotices();
112
        }
113
        return $this->notice_collection;
114
    }
115
116
117
118
    /**
119
     * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db
120
     *
121
     * @return void
122
     * @throws InvalidEntityException
123
     * @throws DomainException
124
     * @throws InvalidDataTypeException
125
     */
126
    protected function retrieveStoredNotices()
127
    {
128
        $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
129
        // \EEH_Debug_Tools::printr($persistent_admin_notices, '$persistent_admin_notices', __FILE__, __LINE__);
130
        if (! empty($persistent_admin_notices)) {
131
            foreach ($persistent_admin_notices as $name => $details) {
132
                if (is_array($details)) {
133
                    if (
134
                        ! isset(
135
                            $details['message'],
136
                            $details['capability'],
137
                            $details['cap_context'],
138
                            $details['dismissed']
139
                        )
140
                    ) {
141
                        throw new DomainException(
142
                            sprintf(
143
                                esc_html__(
144
                                    'The "%1$s" PersistentAdminNotice could not be retrieved from the database.',
145
                                    'event_espresso'
146
                                ),
147
                                $name
148
                            )
149
                        );
150
                    }
151
                    // new format for nag notices
152
                    $this->notice_collection->add(
153
                        new PersistentAdminNotice(
154
                            $name,
155
                            $details['message'],
156
                            false,
157
                            $details['capability'],
158
                            $details['cap_context'],
159
                            $details['dismissed']
160
                        ),
161
                        $name
162
                    );
163
                } else {
164
                    try {
165
                        // old nag notices, that we want to convert to the new format
166
                        $this->notice_collection->add(
167
                            new PersistentAdminNotice(
168
                                $name,
169
                                (string)$details,
170
                                false,
171
                                '',
172
                                '',
173
                                empty($details)
174
                            ),
175
                            $name
176
                        );
177
                    } catch (Exception $e) {
178
                        EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
179
                    }
180
                }
181
                // each notice will self register when the action hook in registerNotices is triggered
182
            }
183
        }
184
    }
185
186
187
188
    /**
189
     * exposes the Persistent Admin Notice Collection via an action
190
     * so that PersistentAdminNotice objects can be added and/or removed
191
     * without compromising the actual collection like a filter would
192
     */
193
    protected function registerNotices()
194
    {
195
        do_action(
196
            'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices',
197
            $this->notice_collection
198
        );
199
    }
200
201
202
203
    /**
204
     * @throws DomainException
205
     * @throws InvalidClassException
206
     * @throws InvalidDataTypeException
207
     * @throws InvalidInterfaceException
208
     * @throws InvalidEntityException
209
     */
210
    public function displayNotices()
211
    {
212
        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
213
        if ($this->notice_collection->hasObjects()) {
214
            $enqueue_assets = false;
215
            // and display notices
216
            foreach ($this->notice_collection as $persistent_admin_notice) {
217
                /** @var PersistentAdminNotice $persistent_admin_notice */
218
                // don't display notices that have already been dismissed
219
                if ($persistent_admin_notice->getDismissed()) {
220
                    continue;
221
                }
222
                try {
223
                    $this->capabilities_checker->processCapCheck(
224
                        $persistent_admin_notice->getCapCheck()
225
                    );
226
                } catch (InsufficientPermissionsException $e) {
227
                    // user does not have required cap, so skip to next notice
228
                    // and just eat the exception - nom nom nom nom
229
                    continue;
230
                }
231
                if ($persistent_admin_notice->getMessage() === '') {
232
                    continue;
233
                }
234
                $this->displayPersistentAdminNotice($persistent_admin_notice);
235
                $enqueue_assets = true;
236
            }
237
            if ($enqueue_assets) {
238
                $this->enqueueAssets();
239
            }
240
        }
241
    }
242
243
244
245
    /**
246
     * does what it's named
247
     *
248
     * @return void
249
     */
250
    public function enqueueAssets()
251
    {
252
        wp_register_script(
253
            'espresso_core',
254
            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
255
            array('jquery'),
256
            EVENT_ESPRESSO_VERSION,
257
            true
258
        );
259
        wp_register_script(
260
            'ee_error_js',
261
            EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
262
            array('espresso_core'),
263
            EVENT_ESPRESSO_VERSION,
264
            true
265
        );
266
        wp_localize_script(
267
            'ee_error_js',
268
            'ee_dismiss',
269
            array(
270
                'return_url'    => urlencode($this->return_url),
271
                'ajax_url'      => WP_AJAX_URL,
272
                'unknown_error' => esc_html__(
273
                    'An unknown error has occurred on the server while attempting to dismiss this notice.',
274
                    'event_espresso'
275
                ),
276
            )
277
        );
278
        wp_enqueue_script('ee_error_js');
279
    }
280
281
282
283
    /**
284
     * displayPersistentAdminNoticeHtml
285
     *
286
     * @param  PersistentAdminNotice $persistent_admin_notice
287
     */
288
    protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice)
289
    {
290
        // used in template
291
        $persistent_admin_notice_name    = $persistent_admin_notice->getName();
292
        $persistent_admin_notice_message = $persistent_admin_notice->getMessage();
293
        require EE_TEMPLATES . DS . 'notifications' . DS . 'persistent_admin_notice.template.php';
294
    }
295
296
297
298
    /**
299
     * dismissNotice
300
     *
301
     * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
302
     * @param bool   $purge    if true, then delete it from the db
303
     * @param bool   $return   forget all of this AJAX or redirect nonsense, and just return
304
     * @return void
305
     * @throws InvalidEntityException
306
     * @throws InvalidInterfaceException
307
     * @throws InvalidDataTypeException
308
     * @throws DomainException
309
     */
310
    public function dismissNotice($pan_name = '', $purge = false, $return = false)
311
    {
312
        $pan_name                = $this->request->get('ee_nag_notice', $pan_name);
313
        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
314
        if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
315
            /** @var PersistentAdminNotice $persistent_admin_notice */
316
            $persistent_admin_notice = $this->notice_collection->get($pan_name);
317
            $persistent_admin_notice->setDismissed(true);
318
            $persistent_admin_notice->setPurge($purge);
319
            $this->saveNotices();
320
        }
321
        if ($return) {
322
            return;
323
        }
324
        if ($this->request->ajax) {
325
            // grab any notices and concatenate into string
326
            echo wp_json_encode(
327
                array(
328
                    'errors' => implode('<br />', EE_Error::get_notices(false)),
329
                )
330
            );
331
            exit();
332
        }
333
        // save errors to a transient to be displayed on next request (after redirect)
334
        EE_Error::get_notices(false, true);
335
        wp_safe_redirect(
336
            urldecode(
337
                $this->request->get('return_url', '')
338
            )
339
        );
340
    }
341
342
343
344
    /**
345
     * saveNotices
346
     *
347
     * @throws DomainException
348
     * @throws InvalidDataTypeException
349
     * @throws InvalidInterfaceException
350
     * @throws InvalidEntityException
351
     */
352
    public function saveNotices()
353
    {
354
        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
355
        if ($this->notice_collection->hasObjects()) {
356
            $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
357
            //maybe initialize persistent_admin_notices
358
            if (empty($persistent_admin_notices)) {
359
                add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no');
360
            }
361
            foreach ($this->notice_collection as $persistent_admin_notice) {
362
                // are we deleting this notice ?
363
                if ($persistent_admin_notice->getPurge()) {
364
                    unset($persistent_admin_notices[$persistent_admin_notice->getName()]);
365
                } else {
366
                    /** @var PersistentAdminNotice $persistent_admin_notice */
367
                    $persistent_admin_notices[$persistent_admin_notice->getName()] = array(
368
                        'message'     => $persistent_admin_notice->getMessage(),
369
                        'capability'  => $persistent_admin_notice->getCapability(),
370
                        'cap_context' => $persistent_admin_notice->getCapContext(),
371
                        'dismissed'   => $persistent_admin_notice->getDismissed(),
372
                    );
373
                }
374
            }
375
            update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices);
376
        }
377
    }
378
379
380
381
    /**
382
     * @throws DomainException
383
     * @throws InvalidDataTypeException
384
     * @throws InvalidEntityException
385
     * @throws InvalidInterfaceException
386
     */
387
    public function registerAndSaveNotices()
388
    {
389
        $this->getPersistentAdminNoticeCollection();
390
        $this->registerNotices();
391
        $this->saveNotices();
392
    }
393
394
395
}
396
// End of file PersistentAdminNoticeManager.php
397
// Location: EventEspresso\core\services\notifications/PersistentAdminNoticeManager.php
398