PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / AdminPages / AssetsController.php
mailpoet / lib / AdminPages Last commit date
Pages 1 week ago AssetsController.php 2 weeks ago PageRenderer.php 2 months ago index.php 3 years ago
AssetsController.php
302 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\AdminPages;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Config\Env;
9 use MailPoet\Config\Renderer;
10 use MailPoet\WP\Functions as WPFunctions;
11
12 class AssetsController {
13 /** @var Renderer */
14 private $renderer;
15
16 /** @var WPFunctions */
17 private $wp;
18
19 /** @var bool */
20 private $skipAdminPagesDependencies = false;
21
22 public function __construct(
23 Renderer $renderer,
24 WPFunctions $wp
25 ) {
26 $this->renderer = $renderer;
27 $this->wp = $wp;
28 }
29
30 public function setupAdminPagesDependencies(): void {
31 if ($this->skipAdminPagesDependencies) {
32 return;
33 }
34 $this->registerAdminDeps();
35 $this->wp->wpEnqueueScript('mailpoet_admin');
36 }
37
38 public function setupHomepageDependencies(): void {
39 $this->wp->wpEnqueueStyle('mailpoet_homepage', $this->getCssUrl('mailpoet-homepage.css'));
40 }
41
42 public function setupNewsletterEditorDependencies(): void {
43 $this->enqueueJsEntrypoint('newsletter_editor', ['underscore']);
44 $this->wp->wpEnqueueStyle('mailpoet_newsletter_editor', $this->getCssUrl('mailpoet-editor.css'));
45 }
46
47 public function setupFormEditorDependencies(): void {
48 $this->skipAdminPagesDependencies = true;
49 $this->setupFormEditorLocalizationDependency();
50 $dependencies = ['mailpoet_mailpoet', 'underscore'];
51 if ($this->wp->wpEnqueueCodeEditor(['type' => 'text/css']) !== false) {
52 $dependencies[] = 'code-editor';
53 }
54 $this->enqueueJsEntrypoint('form_editor', $dependencies, false);
55 }
56
57 public function setupSettingsDependencies(): void {
58 $this->enqueueJsEntrypoint('settings');
59 }
60
61 public function setupTagsDependencies(): void {
62 $this->enqueueJsEntrypoint('tags');
63 $this->setupDataViewsDependencies();
64 $this->wp->wpEnqueueStyle('mailpoet_tags', $this->getCssUrl('mailpoet-tags.css'));
65 }
66
67 public function setupCustomFieldsDependencies(): void {
68 $this->enqueueJsEntrypoint('custom_fields');
69 $this->setupDataViewsDependencies();
70 $this->wp->wpEnqueueStyle('mailpoet_custom_fields', $this->getCssUrl('mailpoet-custom-fields.css'));
71 }
72
73 /**
74 * Enqueue the WordPress component + DataViews styles required by listings
75 * that render `@wordpress/dataviews`. Listings already shipped via the
76 * shared admin JS bundle (e.g. Forms) only need the styles enqueued; their
77 * JS lives in `webpack-admin-index`.
78 *
79 * `wp-components` is registered by WordPress core. `wp-dataviews` is
80 * package-shipped, so we bundle its build-style into `mailpoet-dataviews.css`.
81 */
82 public function setupDataViewsDependencies(): void {
83 $this->wp->wpEnqueueStyle('wp-components');
84 $this->wp->wpEnqueueStyle('mailpoet_dataviews', $this->getCssUrl('mailpoet-dataviews.css'));
85 }
86
87 public function setupDynamicSegmentsDependencies(): void {
88 $this->wp->wpEnqueueStyle('mailpoet_templates', $this->getCssUrl('mailpoet-templates.css'));
89 $this->wp->wpEnqueueStyle('mailpoet_dynamic_segments', $this->getCssUrl('mailpoet-dynamic-segments.css'));
90 }
91
92 public function setupAutomationListingDependencies(): void {
93 $this->enqueueJsEntrypoint('automation');
94 $this->setupDataViewsDependencies();
95 $this->wp->wpEnqueueStyle('mailpoet_automation', $this->getCssUrl('mailpoet-automation.css'));
96 }
97
98 public function setupAutomationTemplatesDependencies(): void {
99 $this->enqueueJsEntrypoint('automation_templates');
100 $this->wp->wpEnqueueStyle('mailpoet_automation_templates', $this->getCssUrl('mailpoet-automation-templates.css'));
101 }
102
103 public function setupAutomationEditorDependencies(): void {
104 $this->enqueueJsEntrypoint('automation_editor', ['wp-date']);
105 $this->wp->wpEnqueueStyle('mailpoet_automation_editor', $this->getCssUrl('mailpoet-automation-editor.css'));
106 }
107
108 public function setupAutomationAnalyticsDependencies(): void {
109 $this->enqueueJsEntrypoint('automation_analytics');
110 $this->wp->wpEnqueueStyle('mailpoet_automation_analytics', $this->getCssUrl('mailpoet-automation-analytics.css'));
111 }
112
113 public function setupAutomationPreviewEmbedDependencies(): void {
114 $this->enqueueJsEntrypoint('automation_preview_embed');
115 $this->wp->wpEnqueueStyle('mailpoet_automation_templates', $this->getCssUrl('mailpoet-automation-templates.css'));
116 }
117
118 public function setupAutomationFlowEmbedDependencies(): void {
119 $this->enqueueJsEntrypoint('automation_flow_embed');
120 $this->wp->wpEnqueueStyle('mailpoet_automation_analytics', $this->getCssUrl('mailpoet-automation-analytics.css'));
121 }
122
123 private function enqueueJsEntrypoint(string $asset, array $dependencies = [], bool $withAdminDeps = true): void {
124 if ($withAdminDeps) {
125 $this->registerAdminDeps();
126 }
127
128 $assetData = $this->getScriptAssetData($asset);
129 $dependencies = array_values(array_unique(array_merge(
130 $dependencies,
131 $assetData['dependencies'],
132 $withAdminDeps ? ['mailpoet_admin'] : []
133 )));
134
135 $name = "mailpoet_$asset";
136 $this->wp->wpEnqueueScript(
137 $name,
138 Env::$assetsUrl . '/dist/js/' . $this->renderer->getJsAsset("$asset.js"),
139 $dependencies,
140 $assetData['version'],
141 true
142 );
143 $this->wp->wpSetScriptTranslations($name, 'mailpoet');
144
145 // Ensure Lodash doesn't override Underscore from WordPress on "window._" global.
146 // Checking for "_.at" detects Lodash (the function doesn't exist in Underscore).
147 $noConflict = 'if (window._ && window._.at && window._.noConflict) window._.noConflict();';
148 if ($withAdminDeps) {
149 $this->wp->wpAddInlineScript('mailpoet_admin_commons', $noConflict);
150 $this->wp->wpAddInlineScript('mailpoet_mailpoet', $noConflict);
151 $this->wp->wpAddInlineScript('mailpoet_admin_vendor', $noConflict);
152 $this->wp->wpAddInlineScript('mailpoet_admin', $noConflict);
153 }
154 $this->wp->wpAddInlineScript($name, $noConflict);
155 }
156
157 /**
158 * @return array{dependencies: string[], version: string}
159 */
160 private function getScriptAssetData(string $asset): array {
161 $assetPaths = [
162 'form_editor' => Env::$assetsPath . '/dist/js/form_editor.asset.json',
163 ];
164 $fallback = [
165 'dependencies' => [],
166 'version' => Env::$version,
167 ];
168 $assetPath = $assetPaths[$asset] ?? null;
169 if ($assetPath === null) {
170 return $fallback;
171 }
172
173 if (!file_exists($assetPath)) {
174 $this->logScriptAssetDataIssue(sprintf('Missing script asset metadata for "%s" at "%s".', $asset, $assetPath));
175 return $fallback;
176 }
177
178 $assetData = json_decode((string)file_get_contents($assetPath), true);
179 if (!is_array($assetData)) {
180 $this->logScriptAssetDataIssue(sprintf('Invalid script asset metadata for "%s" at "%s".', $asset, $assetPath));
181 return $fallback;
182 }
183
184 $dependencies = is_array($assetData['dependencies'] ?? null) ? $assetData['dependencies'] : [];
185 $version = is_string($assetData['version'] ?? null) ? $assetData['version'] : $fallback['version'];
186
187 return [
188 'dependencies' => array_values(array_filter($dependencies, 'is_string')),
189 'version' => $version,
190 ];
191 }
192
193 private function logScriptAssetDataIssue(string $message): void {
194 if (defined('WP_DEBUG') && WP_DEBUG && function_exists('error_log')) {
195 // phpcs:disable QITStandard.PHP.DebugCode.DebugFunctionFound
196 error_log('[MailPoet] ' . $message); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
197 // phpcs:enable QITStandard.PHP.DebugCode.DebugFunctionFound
198 }
199 }
200
201 private function registerAdminDeps(): void {
202 // runtime
203 $this->registerFooterScript('mailpoet_runtime', $this->getScriptUrl('runtime.js'));
204
205 // vendor
206 $this->registerFooterScript('mailpoet_vendor', $this->getScriptUrl('vendor.js'));
207
208 // commons
209 $this->registerFooterScript('mailpoet_admin_commons', $this->getScriptUrl('commons.js'));
210 $this->wp->wpSetScriptTranslations('mailpoet_admin_commons', 'mailpoet');
211
212 // mailpoet
213 $this->registerFooterScript('mailpoet_mailpoet', $this->getScriptUrl('mailpoet.js'));
214 $this->wp->wpSetScriptTranslations('mailpoet_mailpoet', 'mailpoet');
215
216 // admin_vendor
217 $this->registerFooterScript(
218 'mailpoet_admin_vendor',
219 $this->getScriptUrl('admin_vendor.js'),
220 [
221 'wp-i18n',
222 'mailpoet_runtime',
223 'mailpoet_vendor',
224 'mailpoet_admin_commons',
225 'mailpoet_mailpoet',
226 ]
227 );
228
229 // append Parsley validation string translations
230 $this->wp->wpAddInlineScript('mailpoet_admin_vendor', $this->renderer->render('parsley-translations.html'));
231
232 // enqueue "mailpoet_admin_vendor" so the hook fires after it, but before "mailpoet_admin"
233 $this->wp->wpEnqueueScript('mailpoet_admin_vendor');
234 if ($this->wp->didAction('mailpoet_scripts_admin_before') === 0) {
235 $this->wp->doAction('mailpoet_scripts_admin_before');
236 }
237
238 // admin
239 $this->registerFooterScript(
240 'mailpoet_admin',
241 $this->getScriptUrl('admin.js'),
242 ['mailpoet_admin_vendor', 'wp-preferences-persistence']
243 );
244 $this->wp->wpLocalizeScript('mailpoet_admin', 'mailpoet_preferences_data', [
245 'currentUserId' => $this->wp->getCurrentUserId(),
246 'preloadedData' => $this->getPersistedPreferences(),
247 ]);
248 $this->wp->wpSetScriptTranslations('mailpoet_admin', 'mailpoet');
249 }
250
251 private function setupFormEditorLocalizationDependency(): void {
252 $this->wp->wpRegisterScript('mailpoet_mailpoet', false, [], Env::$version, true);
253 $this->wp->wpAddInlineScript(
254 'mailpoet_mailpoet',
255 <<<'JAVASCRIPT'
256 window.mailpoet_i18n = window.mailpoet_i18n || {};
257 window.MailPoet = window.MailPoet || {};
258 window.MailPoet.I18n = window.MailPoet.I18n || {
259 add: function(key, value) {
260 window.mailpoet_i18n[key] = value;
261 },
262 t: function(key) {
263 return window.mailpoet_i18n[key] || 'TRANSLATION "%1$s" NOT FOUND'.replace('%1$s', key);
264 },
265 all: function() {
266 return window.mailpoet_i18n;
267 }
268 };
269 JAVASCRIPT,
270 'before'
271 );
272 $this->wp->wpEnqueueScript('mailpoet_mailpoet');
273 }
274
275 private function getPersistedPreferences(): \stdClass {
276 $currentUserId = $this->wp->getCurrentUserId();
277 if (!$currentUserId) {
278 return new \stdClass();
279 }
280
281 $preferences = $this->wp->getUserMeta(
282 $currentUserId,
283 $this->wp->getBlogPrefix() . 'persisted_preferences',
284 true
285 );
286
287 return is_array($preferences) ? (object)$preferences : new \stdClass();
288 }
289
290 private function getScriptUrl(string $name): string {
291 return Env::$assetsUrl . '/dist/js/' . $this->renderer->getJsAsset($name);
292 }
293
294 private function getCssUrl(string $name): string {
295 return Env::$assetsUrl . '/dist/css/' . $this->renderer->getCssAsset($name);
296 }
297
298 private function registerFooterScript(string $handle, string $src, array $deps = []): void {
299 $this->wp->wpRegisterScript($handle, $src, $deps, Env::$version, true);
300 }
301 }
302