Completed
Branch BUG-8957-add-countries (301f85)
by
unknown
32:21 queued 18:11
created

PostShortcodeTracking   C

Complexity

Total Complexity 61

Size/Duplication

Total Lines 451
Duplicated Lines 1.55 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 7
loc 451
rs 6.018
c 0
b 0
f 0
wmc 61
lcom 1
cbo 4

11 Methods

Rating   Name   Duplication   Size   Complexity  
B unset_posts_page_shortcode_for_post() 0 26 5
B set_hooks_admin() 0 33 1
C parse_post_content_on_save() 0 75 13
A set_post_shortcodes_for_posts_page() 0 11 3
A set_post_shortcode_for_posts_page() 0 21 4
C unset_post_shortcodes_on_delete() 0 36 8
C update_post_shortcodes() 0 57 11
A reset_page_for_posts_on_initial_set() 0 4 1
A reset_page_for_posts_on_change() 7 10 3
A reset_page_for_posts_on_delete() 0 6 2
D get_post_ids_for_shortcode() 0 37 10

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PostShortcodeTracking often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PostShortcodeTracking, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace EventEspresso\core\admin;
3
4
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
5
    exit( 'No direct script access allowed' );
6
}
7
8
9
10
/**
11
 * Class PostShortcodeTracking
12
 * Description
13
 *
14
 * @package       Event Espresso
15
 * @subpackage    core
16
 * @author        Brent Christensen
17
 * @since         $VID:$
18
 */
19
class PostShortcodeTracking
20
{
21
22
    /**
23
     * set_hooks_admin
24
     *
25
     * @access    public
26
     */
27
    public static function set_hooks_admin()
28
    {
29
        add_action(
30
            'save_post',
31
            array( 'EventEspresso\core\admin\PostShortcodeTracking', 'parse_post_content_on_save' ),
32
            100,
33
            2
34
        );
35
        add_action(
36
            'delete_post',
37
            array( 'EventEspresso\core\admin\PostShortcodeTracking', 'unset_post_shortcodes_on_delete' ),
38
            100,
39
            1
40
        );
41
        add_action(
42
            'add_option_page_for_posts',
43
            array( 'EventEspresso\core\admin\PostShortcodeTracking', 'reset_page_for_posts_on_initial_set' ),
44
            100,
45
            2
46
        );
47
        add_action(
48
            'update_option',
49
            array( 'EventEspresso\core\admin\PostShortcodeTracking', 'reset_page_for_posts_on_change' ),
50
            100,
51
            3
52
        );
53
        add_action(
54
            'delete_option',
55
            array( 'EventEspresso\core\admin\PostShortcodeTracking', 'reset_page_for_posts_on_delete' ),
56
            100,
57
            1
58
        );
59
    }
60
61
62
63
    /**
64
     *    parse_post_content_on_save
65
     *    any time a post is saved, we need to check for any EE shortcodes that may be embedded in the content,
66
     *    and then track what posts those shortcodes are on, so that we can initialize shortcodes well before
67
     *    the_content() runs. this allows us to do things like enqueue scripts for shortcodes ONLY on the pages the
68
     *    shortcodes are actually used on
69
     *
70
     * @access    public
71
     * @param int      $post_ID
72
     * @param \WP_Post $post
73
     * @return    void
74
     */
75
    public static function parse_post_content_on_save( $post_ID, $post )
76
    {
77
        // if the post is trashed, then let's remove our post shortcode tracking
78
        if ( $post instanceof \WP_Post && $post->post_status === 'trash' ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
79
            PostShortcodeTracking::unset_post_shortcodes_on_delete( $post_ID );
80
            return;
81
        }
82
        // default post types
83
        $post_types = array( 'post' => 0, 'page' => 1 );
84
        // add CPTs
85
        $CPTs = \EE_Register_CPTs::get_CPTs();
86
        $post_types = array_merge( $post_types, $CPTs );
87
        // for default or CPT posts...
88
        if ( isset( $post_types[ $post->post_type ] ) ) {
89
            // post on frontpage ?
90
            $page_for_posts = \EE_Config::get_page_for_posts();
91
            if ( $post->post_name === $page_for_posts ) {
92
                PostShortcodeTracking::set_post_shortcodes_for_posts_page( $page_for_posts );
93
                return;
94
            }
95
            // array of shortcodes indexed by post name
96
            \EE_Registry::CFG()->core->post_shortcodes = isset( \EE_Registry::CFG()->core->post_shortcodes )
97
                ? \EE_Registry::CFG()->core->post_shortcodes
98
                : array();
99
            // whether to proceed with update
100
            $update_post_shortcodes = false;
101
            // empty both arrays
102
            \EE_Registry::CFG()->core->post_shortcodes[ $post->post_name ] = array();
103
            // check that posts page is already being tracked
104
            if ( ! isset( \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ] ) ) {
105
                // if not, then ensure that it is properly added
106
                \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ] = array();
107
            }
108
            // loop thru shortcodes
109
            foreach ( \EE_Registry::instance()->shortcodes as $EES_Shortcode => $shortcode_dir ) {
110
                // convert to UPPERCASE to get actual shortcode
111
                $EES_Shortcode = strtoupper( $EES_Shortcode );
112
                // is the shortcode in the post_content ?
113
                if ( strpos( $post->post_content, $EES_Shortcode ) !== false ) {
114
                    // map shortcode to post names and post IDs
115
                    \EE_Registry::CFG()->core->post_shortcodes[ $post->post_name ][ $EES_Shortcode ] = $post_ID;
116
                    // and add this shortcode to the tracking for the blog page
117
                    PostShortcodeTracking::set_post_shortcode_for_posts_page( $page_for_posts, $EES_Shortcode,
118
                        $post_ID );
119
                    $update_post_shortcodes = true;
120
                } else {
121
                    // shortcode is not present in post content, so check if we were tracking it previously
122
                    // stop tracking if shortcode is not used in this specific post
123
                    if ( isset( \EE_Registry::CFG()->core->post_shortcodes[ $post->post_name ][ $EES_Shortcode ] ) ) {
124
                        unset( \EE_Registry::CFG()->core->post_shortcodes[ $post->post_name ][ $EES_Shortcode ] );
125
                        $update_post_shortcodes = true;
126
                    }
127
                    // make sure that something is set for the shortcode posts (even though we may remove this)
128
                    $shortcode_posts = isset(
129
                        \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ]
130
                    )
131
                        ? \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ]
132
                        : array();
133
                    // and stop tracking for this shortcode on the blog page if it is not used
134
                    $update_post_shortcodes = PostShortcodeTracking::unset_posts_page_shortcode_for_post(
135
                        $post_ID,
136
                        $EES_Shortcode,
137
                        $shortcode_posts,
138
                        $page_for_posts,
139
                        $update_post_shortcodes
140
                    )
141
                        ? true
142
                        : $update_post_shortcodes;
143
                }
144
            }
145
            if ( $update_post_shortcodes ) {
146
                PostShortcodeTracking::update_post_shortcodes( $page_for_posts );
147
            }
148
        }
149
    }
150
151
152
153
    /**
154
     * set_post_shortcodes_for_posts_page (plz note: shortcodes is plural)
155
     * called when updating the WordPress Posts Page,
156
     * and adds shortcode tracking for the Posts Page, for all shortcodes currently tracked on individual posts
157
     *
158
     * @access protected
159
     * @param  string $page_for_posts
160
     * @return void
161
     */
162
    protected static function set_post_shortcodes_for_posts_page( $page_for_posts )
163
    {
164
        \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ] = array();
165
        // loop thru shortcodes
166
        foreach ( \EE_Registry::CFG()->core->post_shortcodes as $post_name => $post_shortcodes ) {
167
            foreach ( $post_shortcodes as $EES_Shortcode => $post_ID ) {
168
                PostShortcodeTracking::set_post_shortcode_for_posts_page( $page_for_posts, $EES_Shortcode, $post_ID );
169
            }
170
        }
171
        PostShortcodeTracking::update_post_shortcodes( $page_for_posts );
172
    }
173
174
175
176
    /**
177
     * set_post_shortcode_for_posts_page (plz note: shortcode is singular)
178
     * adds Posts Page shortcode tracking for the supplied shortcode for an individual post
179
     *
180
     * @access protected
181
     * @param  string $page_for_posts
182
     * @param         $EES_Shortcode
183
     * @param         $post_ID
184
     */
185
    protected static function set_post_shortcode_for_posts_page( $page_for_posts, $EES_Shortcode, $post_ID )
186
    {
187
        // critical page shortcodes that we do NOT want added to the Posts page (blog)
188
        $critical_shortcodes = \EE_Registry::CFG()->core->get_critical_pages_shortcodes_array();
189
        // if the shortcode is NOT one of the critical page shortcodes like ESPRESSO_TXN_PAGE
190
        if ( in_array( $EES_Shortcode, $critical_shortcodes ) ) {
191
            return;
192
        }
193
        // add shortcode to "Posts page" tracking
194
        if ( isset( \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ] ) ) {
195
            // make sure tracking is in form of an array
196
            if ( ! is_array( \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ] ) ) {
197
                \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ] = array(
198
                    \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ] => true,
199
                );
200
            }
201
            \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ] += array( $post_ID => true );
202
        } else {
203
            \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $EES_Shortcode ] = array( $post_ID => true );
204
        }
205
    }
206
207
208
209
    /**
210
     * unset_post_shortcodes_on_delete
211
     *
212
     * @access protected
213
     * @param  int $ID
214
     * @return void
215
     */
216
    public static function unset_post_shortcodes_on_delete( $ID )
217
    {
218
        $update_post_shortcodes = false;
219
        // post on frontpage ?
220
        $page_for_posts = \EE_Config::get_page_for_posts();
221
        // looking for any references to this post
222
        foreach ( \EE_Registry::CFG()->core->post_shortcodes as $post_name => $post_shortcodes ) {
223
            // is this the "Posts Page" (blog) ?
224
            if ( $post_name === $page_for_posts ) {
225
                // loop thru shortcodes registered for the posts page
226
                foreach ( $post_shortcodes as $shortcode_class => $shortcode_posts ) {
227
                    $update_post_shortcodes = PostShortcodeTracking::unset_posts_page_shortcode_for_post(
228
                        $ID,
229
                        $shortcode_class,
230
                        $shortcode_posts,
231
                        $page_for_posts,
232
                        $update_post_shortcodes
233
                    )
234
                        ? true
235
                        : $update_post_shortcodes;
236
                }
237
            } else {
238
                // loop thru shortcodes registered for each page
239
                foreach ( $post_shortcodes as $shortcode_class => $post_ID ) {
240
                    // if this is page is being deleted, then don't track any post shortcodes for it
241
                    if ( $post_ID === $ID ) {
242
                        unset( \EE_Registry::CFG()->core->post_shortcodes[ $post_name ] );
243
                        $update_post_shortcodes = true;
244
                    }
245
                }
246
            }
247
        }
248
        if ( $update_post_shortcodes ) {
249
            PostShortcodeTracking::update_post_shortcodes( $page_for_posts );
250
        }
251
    }
252
253
254
255
    /**
256
     * unset_post_shortcodes_on_delete
257
     *
258
     * @access protected
259
     * @param  int $ID
260
     * @param      $shortcode_class
261
     * @param      $shortcode_posts
262
     * @param      $page_for_posts
263
     * @param bool $update_post_shortcodes
264
     * @return bool
265
     */
266
    protected static function unset_posts_page_shortcode_for_post(
267
        $ID,
268
        $shortcode_class,
269
        $shortcode_posts,
270
        $page_for_posts,
271
        $update_post_shortcodes = false
272
    ) {
273
        // make sure that an array of post IDs is being tracked for each  shortcode
274
        if ( ! is_array( $shortcode_posts ) ) {
275
            \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $shortcode_class ] = array(
276
                $shortcode_posts => true,
277
            );
278
            $update_post_shortcodes = true;
279
        }
280
        // now if the ID of the post being deleted is in the $shortcode_posts array
281
        if ( is_array( $shortcode_posts ) && isset( $shortcode_posts[ $ID ] ) ) {
282
            unset( \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $shortcode_class ][ $ID ] );
283
            $update_post_shortcodes = true;
284
        }
285
        // if nothing is registered for that shortcode anymore, then delete the shortcode altogether
286
        if ( empty( \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $shortcode_class ] ) ) {
287
            unset( \EE_Registry::CFG()->core->post_shortcodes[ $page_for_posts ][ $shortcode_class ] );
288
            $update_post_shortcodes = true;
289
        }
290
        return $update_post_shortcodes;
291
    }
292
293
294
295
    /**
296
     *    update_post_shortcodes
297
     *
298
     * @access    public
299
     * @param $page_for_posts
300
     * @return    void
301
     */
302
    public static function update_post_shortcodes( $page_for_posts = '' )
303
    {
304
        // make sure page_for_posts is set
305
        $page_for_posts = ! empty( $page_for_posts )
306
            ? $page_for_posts
307
            : \EE_Config::get_page_for_posts();
308
        // allow others to mess stuff up :D
309
        do_action(
310
            'AHEE__\EventEspresso\core\admin\PostShortcodeTracking__update_post_shortcodes',
311
            \EE_Config::instance()->core->post_shortcodes,
312
            $page_for_posts
313
        );
314
        // keep old hookpoint for now, will deprecate later
315
        do_action(
316
            'AHEE__EE_Config__update_post_shortcodes',
317
            \EE_Config::instance()->core->post_shortcodes,
318
            $page_for_posts
319
        );
320
        // verify that post_shortcodes is set
321
        \EE_Config::instance()->core->post_shortcodes = isset( \EE_Config::instance()->core->post_shortcodes )
322
                                                        && is_array( \EE_Config::instance()->core->post_shortcodes )
323
            ? \EE_Config::instance()->core->post_shortcodes
324
            : array();
325
        // cycle thru post_shortcodes
326
        foreach ( \EE_Config::instance()->core->post_shortcodes as $post_name => $shortcodes ) {
327
            // are there any shortcodes to track ?
328
            if ( ! empty( $shortcodes ) ) {
329
                // skip the posts page, because we want all shortcodes registered for it
330
                if ( $post_name === $page_for_posts ) {
331
                    continue;
332
                }
333
                // loop thru list of tracked shortcodes
334
                foreach ( $shortcodes as $shortcode => $post_id ) {
335
                    // make sure post still exists
336
                    $post = get_post( $post_id );
337
                    // check that the post name matches what we have saved
338
                    if ( $post && $post->post_name === $post_name ) {
339
                        // if so, then break before hitting the unset below
340
                        continue;
341
                    }
342
                    // we don't like missing posts around here >:(
343
                    unset( \EE_Config::instance()->core->post_shortcodes[ $post_name ] );
344
                }
345
            } else {
346
                // you got no shortcodes to keep track of !
347
                unset( \EE_Config::instance()->core->post_shortcodes[ $post_name ] );
348
            }
349
        }
350
        // critical page shortcodes that we do NOT want added to the Posts page (blog)
351
        $critical_shortcodes = \EE_Config::instance()->core->get_critical_pages_shortcodes_array();
352
        $critical_shortcodes = array_flip( $critical_shortcodes );
353
        foreach ( $critical_shortcodes as $critical_shortcode ) {
354
            unset( \EE_Config::instance()->core->post_shortcodes[ $page_for_posts ][ $critical_shortcode ] );
355
        }
356
        //only show errors
357
        \EE_Config::instance()->update_espresso_config();
358
    }
359
360
361
362
    /**
363
     * reset_page_for_posts_on_initial_set
364
     * if an admin is on the WP Reading Settings page and sets the option for "Posts page",
365
     * when it had previously been unset,
366
     * then we need to attribute any actively used shortcodes to the new blog page
367
     *
368
     * @access public
369
     * @param  string $option
370
     * @param  string $value
371
     * @return void
372
     */
373
    public static function reset_page_for_posts_on_initial_set( $option, $value )
374
    {
375
        PostShortcodeTracking::reset_page_for_posts_on_change( $option, '', $value );
376
    }
377
378
379
380
    /**
381
     *    reset_page_for_posts_on_change
382
     *    if an admin is on the WP Reading Settings page and changes the option for "Posts page",
383
     * then we need to attribute any actively used shortcodes for the previous blog page to the new blog page
384
     *
385
     * @access public
386
     * @param  string $option
387
     * @param  string $old_value
388
     * @param  string $value
389
     * @return void
390
     */
391
    public static function reset_page_for_posts_on_change( $option, $old_value = '', $value = '' )
392
    {
393 View Code Duplication
        if ( $option === 'page_for_posts' ) {
394
            global $wpdb;
395
            $table = $wpdb->posts;
396
            $SQL = "SELECT post_name from $table WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
397
            $new_page_for_posts = $value ? $wpdb->get_var( $wpdb->prepare( $SQL, $value ) ) : 'posts';
398
            PostShortcodeTracking::set_post_shortcodes_for_posts_page( $new_page_for_posts );
399
        }
400
    }
401
402
403
404
    /**
405
     * reset_page_for_posts_on_delete
406
     * if an admin deletes a page designated as the WP "Posts page",
407
     * then we need to attribute any actively used shortcodes for that blog page to a generic 'posts' page
408
     *
409
     * @access public
410
     * @param  string $option
411
     * @return void
412
     */
413
    public static function reset_page_for_posts_on_delete( $option )
414
    {
415
        if ( $option === 'page_for_posts' ) {
416
            PostShortcodeTracking::set_post_shortcodes_for_posts_page( 'posts' );
417
        }
418
    }
419
420
421
422
    /**
423
     * @param array|string $shortcodes
424
     * @param bool         $index_results if passing more than one shortcode for the $shortcodes parameter above,
425
     *                                    then setting this to true, will return as associative array indexed by
426
     *                                    the shortcodes. If false, then the returned array will be unindexed
427
     * @return array
428
     */
429
    public static function get_post_ids_for_shortcode( $shortcodes, $index_results = true )
430
    {
431
        $post_ids = array();
432
        if ( is_array( $shortcodes ) ) {
433
            foreach ( $shortcodes as $shortcode ) {
434
                $new_post_ids = PostShortcodeTracking::get_post_ids_for_shortcode(
435
                    $shortcode,
436
                    $index_results
437
                );
438
                foreach ( $new_post_ids as $new_post_id ) {
439
                    if ( $index_results ) {
440
                        $post_ids[ $shortcode ][ $new_post_id ] = $new_post_id;
441
                    } else {
442
                        $post_ids[ $new_post_id ] = $new_post_id;
443
                    }
444
                }
445
            }
446
        } else {
447
            $shortcode = strtoupper( $shortcodes );
448
            $shortcode = strpos( $shortcode, 'ESPRESSO_' ) !== 0 ? "ESPRESSO_{$shortcode}" : $shortcode;
449
            $page_for_posts = \EE_Config::get_page_for_posts();
450
            // looking for any references to this post
451
            foreach ( \EE_Registry::CFG()->core->post_shortcodes as $post_name => $post_shortcodes ) {
452
                // if this is the "Posts Page" (blog), then skip it
453
                if ( $post_name === $page_for_posts ) {
454
                    continue;
455
                }
456
                // loop thru shortcodes registered for each page, and grab post id for matches
457
                foreach ( (array) $post_shortcodes as $post_shortcode => $post_ID ) {
458
                    if ( $post_shortcode === $shortcode ) {
459
                        $post_ids[ $post_ID ] = $post_ID;
460
                    }
461
                }
462
            }
463
        }
464
        return $post_ids;
465
    }
466
467
468
469
}
470
// End of file PostShortcodeTracking.php
471
// Location: /PostShortcodeTracking.php