PluginProbe
Extendify / 3.1.0
Extendify v3.1.0
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / bootstrap.php

bootstrap.php in Extendify 3.1.0, at bootstrap.php

241 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Bootstrap the application
5 */
6
7 defined('ABSPATH') || die('No direct access.');
8
9 use Extendify\AdminPageRouter;
10 use Extendify\Assist\Admin as AssistAdmin;
11 use Extendify\Agent\Admin as AgentAdmin;
12 use Extendify\Config;
13 use Extendify\Draft\Admin as DraftAdmin;
14 use Extendify\HelpCenter\Admin as HelpCenterAdmin;
15 use Extendify\Insights;
16 use Extendify\Launch\Admin as LaunchAdmin;
17 use Extendify\AutoLaunch\Admin as AutoLaunchAdmin;
18 use Extendify\Library\Admin as LibraryAdmin;
19 use Extendify\Library\Frontend as LibraryFrontend;
20 use Extendify\Agent\Frontend as AgentFrontend;
21 use Extendify\QuickEdit\Frontend as QuickEditFrontend;
22 use Extendify\PageCreator\Admin as PageCreatorAdmin;
23 use Extendify\PartnerData;
24 use Extendify\Toolbar\Admin as ToolbarAdmin;
25 use Extendify\Toolbar\Frontend as ToolbarFrontend;
26 use Extendify\Recommendations\Admin as RecommendationsAdmin;
27 use Extendify\PluginNotifications\Admin as PluginNotificationsAdmin;
28 use Extendify\Shared\Admin as SharedAdmin;
29 use Extendify\Shared\DataProvider\ResourceData;
30 use Extendify\Shared\Services\Import\ImagesImporter;
31 use Extendify\Shared\Services\PluginRedirectDisabler;
32 use Extendify\Shared\Services\VersionMigrator;
33
34 if (!defined('EXTENDIFY_REQUIRED_CAPABILITY')) {
35 define('EXTENDIFY_REQUIRED_CAPABILITY', 'manage_options');
36 }
37
38 if (!defined('EXTENDIFY_PATH')) {
39 define('EXTENDIFY_PATH', \plugin_dir_path(__FILE__));
40 }
41
42 if (!defined('EXTENDIFY_URL')) {
43 define('EXTENDIFY_URL', \plugin_dir_url(__FILE__));
44 }
45
46 if (is_readable(EXTENDIFY_PATH . 'vendor/autoload.php')) {
47 require EXTENDIFY_PATH . 'vendor/autoload.php';
48 }
49
50 if (!defined('EXTENDIFY_IS_THEME_EXTENDABLE')) {
51 define('EXTENDIFY_IS_THEME_EXTENDABLE', get_option('stylesheet') === 'extendable');
52 }
53
54 (static function () {
55 // This file should have no dependencies and always load.
56 new LibraryFrontend();
57 // This file hooks into an external task and should always load.
58 new Insights();
59 // This class set up the image import check scheduler.
60 new ImagesImporter();
61
62 // Run various database updates depending on the plugin version.
63 new VersionMigrator();
64
65 // This class will fetch and cache partner data to be used
66 // throughout every class below. If opt in.
67 new PartnerData();
68
69 // Assign A/B test variants now that partner data is loaded.
70 Insights::setup((array) PartnerData::setting('activeTests'));
71
72 // Set up scheduled cache (if opt-in and active).
73 if (!PartnerData::setting('deactivated')) {
74 ResourceData::scheduleCache();
75 }
76
77 if (!current_user_can(EXTENDIFY_REQUIRED_CAPABILITY)) {
78 return;
79 }
80
81 // The config class will collect information about the
82 // partner and plugin, so it's easier to access.
83 new Config();
84 if (!defined('EXTENDIFY_DEVMODE')) {
85 define('EXTENDIFY_DEVMODE', Config::$environment === 'DEVELOPMENT');
86 }
87
88 // This is a global "loader" class that loads in any assets that are shared everywhere.
89 new SharedAdmin();
90 // This class will handle loading library assets.
91 new LibraryAdmin();
92 if (PartnerData::setting('hidePluginNotifications')) {
93 new PluginNotificationsAdmin();
94 }
95
96 // Only load these if the partner ID is set. These are all opt-in features.
97 if (!Config::$partnerId && !constant('EXTENDIFY_DEVMODE')) {
98 return;
99 }
100
101 if (PartnerData::setting('deactivated')) {
102 return;
103 }
104
105 // This class handles the admin pages required for the plugin.
106 new AdminPageRouter();
107 new PluginRedirectDisabler();
108
109 // This class will handle loading page creator assets.
110 if (PartnerData::setting('showAIPageCreation') || constant('EXTENDIFY_DEVMODE')) {
111 new PageCreatorAdmin();
112 }
113
114 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
115 $page = sanitize_text_field(wp_unslash($_GET['page'] ?? ''));
116
117 if ($page === 'extendify-launch') {
118 new LaunchAdmin();
119 return;
120 }
121
122 if ($page === 'extendify-auto-launch') {
123 new AutoLaunchAdmin();
124 return;
125 }
126
127 // The remaining classes handle loading assets for each individual products.
128 // They are essentially asset loading classes.
129 if ($page === 'extendify-assist') {
130 new AssistAdmin();
131 }
132
133 $extendifyShowAgent = constant('EXTENDIFY_IS_THEME_EXTENDABLE')
134 && Config::$launchCompleted
135 && (PartnerData::setting('showAIAgents') || Config::preview('ai-agent'));
136
137 // True when the AI Agent is actually loaded this request — the gate
138 // above, or dev mode (so it can be exercised locally). Quick Edit and
139 // the simple toolbar both build on the Agent, so they share this
140 // decision rather than gating themselves independently.
141 $extendifyLoadAgent = $extendifyShowAgent || constant('EXTENDIFY_DEVMODE');
142
143 if (!$extendifyShowAgent) {
144 new HelpCenterAdmin();
145 }
146
147 if (PartnerData::setting('showProductRecommendations') || constant('EXTENDIFY_DEVMODE')) {
148 new RecommendationsAdmin();
149 }
150
151 if (PartnerData::setting('showDraft') || constant('EXTENDIFY_DEVMODE')) {
152 new DraftAdmin();
153 }
154
155 if ($extendifyLoadAgent) {
156 new AgentAdmin();
157 new AgentFrontend();
158 }
159
160 if ($extendifyLoadAgent) {
161 new QuickEditFrontend();
162 }
163
164 // Simple Extendify toolbar — replaces the WordPress core admin
165 // bar on the front end with a minimal AI Agent / Quick Edit /
166 // Edit / WP Admin bar. The user-profile "Toolbar Style" setting
167 // controls per-user override; the default is Launch-aware
168 // ('simple' post-Launch, 'full' pre-Launch). Gated on the Agent
169 // too: the toolbar's "AI Agent" button drives the Agent's mounted
170 // admin-bar button, so without the Agent it would present a dead
171 // button — never ship the toolbar unless the Agent is there.
172 if ($extendifyLoadAgent && (PartnerData::setting('showSimpleToolbar') || Config::preview('simple-toolbar'))) {
173 new ToolbarAdmin();
174 new ToolbarFrontend();
175 }
176 })();
177
178 (static function () {
179 if (!current_user_can(EXTENDIFY_REQUIRED_CAPABILITY)) {
180 return;
181 }
182
183 // This loads in all the REST API routes used by the plugin.
184 require EXTENDIFY_PATH . 'routes/api.php';
185 })();
186
187 // This file is used to update the plugin and removed before w.org release.
188 if (is_readable(EXTENDIFY_PATH . '/updater.php')) {
189 require EXTENDIFY_PATH . 'updater.php';
190 }
191
192 add_action('init', function () {
193 load_plugin_textdomain('extendify-local', false, dirname(plugin_basename(__FILE__)) . '/languages/php');
194 });
195
196 // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
197 add_filter('load_script_translation_file', function ($file, $handle, $domain) {
198 if ($domain !== 'extendify-local') {
199 return $file;
200 }
201
202 return extendifyResolveFallbackLocaleFile($file);
203 }, 10, 3);
204
205 add_filter('load_textdomain_mofile', function ($mofile, $domain) {
206 if ($domain !== 'extendify-local') {
207 return $mofile;
208 }
209
210 return extendifyResolveFallbackLocaleFile($mofile);
211 }, 10, 2);
212
213 /**
214 * Resolves a fallback translation file path if the requested locale is unsupported.
215 *
216 * This function checks if the current file path includes an unsupported locale
217 * and replaces it with a supported fallback (e.g. es_AR → es_ES),
218 * as long as the fallback file exists on disk.
219 *
220 * @param string $filepath The original .mo or .json translation file path.
221 * @return string The fallback file path if it exists, or the original one.
222 */
223
224 function extendifyResolveFallbackLocaleFile($filepath)
225 {
226 if (str_contains($filepath, '-es_') && !file_exists($filepath)) {
227 $fallbackFile = preg_replace('/-es_[A-Z]{2}/', '-es_ES', $filepath);
228 if ($fallbackFile && file_exists($fallbackFile)) {
229 return $fallbackFile;
230 }
231 }
232
233 return $filepath;
234 }
235
236 // To cover legacy conflicts.
237 // phpcs:ignore
238 class ExtendifySdk
239 {
240 }
241