• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ideasonpurpose / wp-theme-init / #83

22 May 2026 06:21PM UTC coverage: 98.638% (-0.7%) from 99.377%
#83

push

php-coveralls

joemaller
2.20.0

652 of 661 relevant lines covered (98.64%)

2.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.18
/src/ThemeInit.php
1
<?php
2
namespace IdeasOnPurpose;
3

4
class ThemeInit
5
{
6
    /**
7
     * Placeholders for mocking
8
     */
9
    public $ABSPATH;
10
    public $WP_DEBUG = false;
11

12
    public function __construct($options = [])
13
    {
14
        $this->ABSPATH = defined('ABSPATH') ? ABSPATH : getcwd(); // WordPress always defines this
2✔
15
        $this->WP_DEBUG = defined('WP_DEBUG') && WP_DEBUG;
2✔
16

17
        $defaults = [
2✔
18
            'showIncludes' => true,
2✔
19
            'enableComments' => false,
2✔
20
            'jQueryMigrate' => true,
2✔
21
            'enforceMFA' => true, // Disable to enforce MFA per-user
2✔
22
        ];
2✔
23
        $options = array_merge($defaults, $options);
2✔
24

25
        /**
26
         * Global core defaults (revisions, auto-updates, head cleanup)
27
         */
28
        new ThemeInit\Core();
2✔
29

30
        /**
31
         * Admin core defaults (menu, footer, block editor)
32
         */
33
        new ThemeInit\Admin\Core();
2✔
34

35
        /**
36
         * Sets JPEG_QUALITY
37
         * Add Imagick\HQ scaling
38
         * Compress all newly added images
39
         */
40
        new ThemeInit\Media();
2✔
41

42
        /**
43
         * Add Post State Labels to WP Admin
44
         *  - Includes "404 Page" label
45
         */
46
        new ThemeInit\Admin\PostStates();
2✔
47

48
        /**
49
         * Add the Template Audit column and wp-admin page
50
         */
51
        new ThemeInit\Admin\TemplateAudit();
2✔
52

53
        /**
54
         * Attempts to set the DISALLOW_FILE_EDIT constant to true (disabling the Theme File Editor)
55
         * or displays a notice when the values is explicitly set to false.
56
         */
57
        new ThemeInit\Admin\DisallowFileEdit();
2✔
58

59
        /**
60
         * Log time of last_login for all users
61
         */
62
        new ThemeInit\Admin\LastLogin();
2✔
63

64
        /**
65
         * Clear stale wordpress_logged_in cookies
66
         */
67
        new ThemeInit\Admin\LoginCookieCleaner();
2✔
68

69
        /**
70
         * Add Metabox Reset buttons to Admin User Profiles
71
         */
72
        new ThemeInit\Admin\ResetMetaboxes();
2✔
73

74
        /**
75
         * Clean up the wp-admin dashboard
76
         */
77
        new ThemeInit\Admin\CleanDashboard();
2✔
78

79
        /**
80
         * Common plugin tweaks
81
         */
82
        new ThemeInit\Plugins\ACF();
2✔
83
        new ThemeInit\Plugins\EnableMediaReplace();
2✔
84
        new ThemeInit\Plugins\SEOFramework();
2✔
85
        new ThemeInit\Plugins\TwoFactor(!!$options['enforceMFA']);
2✔
86

87
        if ($options['showIncludes'] !== false) {
2✔
88
            new ThemeInit\Debug\ShowIncludes();
2✔
89
        }
90

91
        if ($options['enableComments'] === false) {
2✔
92
            new ThemeInit\Extras\GlobalCommentsDisable();
2✔
93
        }
94

95
        /**
96
         * TODO: EXPERIMENTAL
97
         * Provide a switch to remove jquery-migrate
98
         */
99
        if ($options['jQueryMigrate'] === false) {
2✔
100
            new ThemeInit\Extras\RemoveJQueryMigrate();
1✔
101
        }
102
        new ThemeInit\Extras\Shortcodes();
2✔
103

104
        // TODO: Is this too permissive? Reason not to disable unless WP_ENV == 'development'?
105
        if (class_exists('Kint')) {
2✔
106
            /** @disregard P1014 "undefined property '$enabled_mode'" **/
107
            \Kint::$enabled_mode = false;
×
108
            if ($this->WP_DEBUG) {
×
109
                /** @disregard P1014 "undefined property '$enabled_mode'" **/
110
                \Kint::$enabled_mode = true;
×
111
            }
112
        }
113
        // @codeCoverageIgnoreEnd
114

115
        /**
116
         * Load IOP common i18n text domain 'iopwp'
117
         *
118
         * TODO: Namespace collision?
119
         */
120
        // new WP\I18n();
121
    }
122

123
    /**
124
     * Should be called as late as possible, either shutdown or something right before shutdown
125
     * need to check that it's not breaking JSON or other API-ish responses by appending
126
     * a blob of arbitrary text to the content.
127
     *
128
     * @codeCoverageIgnore
129
     *
130
     */
131
    public function totalExecutionTime()
132
    {
133
        /**
134
                      * Need to be sure we don't dump this into a JSON response or other structured data request
135
                      *
136
                      * TODO: Check code from wp-includes/admin-bar.php for skipping AJAX, JSON, etc.
137
                      *       https://github.com/WordPress/WordPress/blob/42d52ce08099f9fae82a1977da0237b32c863e94/wp-includes/admin-bar.php#L1179-L1181
138
                      *
139
                      *      if ( defined( 'XMLRPC_REQUEST' ) || defined( 'DOING_AJAX' ) || defined( 'IFRAME_REQUEST' ) || wp_is_json_request() ) {
140
                      *
141
                      */
142
        // if (wp_doing_ajax()) {
143
        //     return;
144
        // }
145
        // error_log('SHUTDOWN');
146
        // error_log(print_r($_SERVER, true));
147

148
        // $time = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
149
        // $msg = sprintf('Total processing time: %0.4f seconds', $time);
150
        // echo "\n<!--\n\n$msg\n -->";
151
        // printf('<script>console.log("%%c⏱", "font-weight: bold;", "%s");</script>', $msg);
152
    }
153

154
    /**
155
     * Webpack/Browsersync reload on post save
156
     * Currently attempts to reload if WP_DEBUG is true
157
     * More info:
158
     * https://www.browsersync.io/docs/http-protocol
159
     * https://blogs.oracle.com/fatbloke/networking-in-virtualbox#NAT
160
     * https://superuser.com/a/310745/193584
161
     *
162
     * TODO: This was disabled from init() on 2019-11-06 for a few reasons:
163
     *       1. Since _everything_ is going through the devserver proxy,
164
     *          saving a post in admin will trigger a reload of the page
165
     *          being authored. This breaks the default workflow and causes
166
     *          pops up a number of "Reload site?" alerts.
167
     *
168
     *       2. Trying to reach the 10.0.2.2 Vagrant external IP from Docker
169
     *          was causing a blocking DNS stall for 10 seconds per request.
170
     *          This made the backend nearly unusable.
171
     *
172
     * @codeCoverageIgnore
173
     */
174
    private function browsersyncReload()
175
    {
176
        if (defined('WP_DEBUG') && WP_DEBUG) {
177
            add_action('save_post', function () {
178
                $args = ['blocking' => false, 'sslverify' => false];
179
                // Sloppy, but there's no assurance we're actually serving over ssl
180
                // This hits both possible endpoints and ignores replies, one of these should work
181
                wp_remote_get('http://10.0.2.2:3000/__browser_sync__?method=reload', $args);
182
                wp_remote_get('https://10.0.2.2:3000/__browser_sync__?method=reload', $args);
183

184
                /**
185
                 * /webpack/reload is specific to ideasonpurpose/docker-build
186
                 */
187
                wp_remote_get('http://host.docker.internal:8080/webpack/reload', $args);
188
            });
189
        }
190
    }
191
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc