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 / Util / ConflictResolver.php
mailpoet / lib / Util Last commit date
DataInconsistency 2 weeks ago License 2 months ago Notices 2 months ago pQuery 2 months ago APIPermissionHelper.php 1 year ago CdnAssetUrl.php 3 years ago ConflictResolver.php 1 month ago Cookies.php 2 months ago DBCollationChecker.php 2 months ago DOM.php 2 years ago DateConverter.php 3 years ago FreeDomains.php 3 years ago Headers.php 1 year ago Helpers.php 1 month ago Installation.php 1 year ago LegacyDatabase.php 1 year ago Request.php 2 months ago SecondLevelDomainNames.php 3 years ago Security.php 2 months ago ThirdPartyOutput.php 1 month ago Url.php 2 months ago index.php 3 years ago
ConflictResolver.php
234 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Util;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\WP\Functions as WPFunctions;
9
10 class ConflictResolver {
11 /** @var array{styles: string[], scripts: string[]} */
12 public $permittedAssetsLocations = [
13 'styles' => [
14 'mailpoet',
15 // WP default
16 '^/wp-admin',
17 '^/wp-includes',
18 // CDN
19 'googleapis.com/ajax/libs',
20 '\bwp\.com\b',
21 // third-party
22 'jetpack',
23 'query-monitor',
24 'wpt-tx-updater-network',
25 // WP.com
26 '^/_static',
27 'mu-host-plugins/debug-bar/css',
28 'woocommerce-payments/',
29 'automatewoo/',
30 'full-site-editing',
31 'wpcomsh',
32 // Gutenberg
33 'gutenberg/',
34 ],
35 'scripts' => [
36 'mailpoet',
37 // WP default
38 '^/wp-admin',
39 '^/wp-includes',
40 // CDN
41 'googleapis.com/ajax/libs',
42 '\bwp\.com\b',
43 // third-party
44 'query-monitor',
45 'wpt-tx-updater-network',
46 'polylang',
47 // WP.com
48 'full-site-editing',
49 'wpcomsh',
50 ],
51 ];
52
53 /** @var string[] */
54 public $permittedScriptHandles = [
55 'wp-commands',
56 'wp-core-commands',
57 ];
58
59 public function init() {
60 WPFunctions::get()->addAction(
61 'mailpoet_conflict_resolver_router_url_query_parameters',
62 [
63 $this,
64 'resolveRouterUrlQueryParametersConflict',
65 ]
66 );
67 WPFunctions::get()->addAction(
68 'mailpoet_conflict_resolver_styles',
69 [
70 $this,
71 'resolveStylesConflict',
72 ]
73 );
74 WPFunctions::get()->addAction(
75 'mailpoet_conflict_resolver_scripts',
76 [
77 $this,
78 'resolveScriptsConflict',
79 ]
80 );
81 WPFunctions::get()->addAction(
82 'mailpoet_conflict_resolver_scripts',
83 [
84 $this,
85 'resolveEditorConflict',
86 ]
87 );
88 WPFunctions::get()->addAction(
89 'mailpoet_conflict_resolver_scripts',
90 [
91 $this,
92 'resolveTinyMceConflict',
93 ]
94 );
95 }
96
97 public function resolveRouterUrlQueryParametersConflict() {
98 // prevents other plugins from overtaking URL query parameters 'action=' and 'endpoint='
99 unset($_GET['endpoint'], $_GET['action']);
100 }
101
102 public function resolveStylesConflict() {
103 $_this = $this;
104 $filteredStyles = WPFunctions::get()->applyFilters('mailpoet_conflict_resolver_whitelist_style', $_this->permittedAssetsLocations['styles']);
105 if (is_array($filteredStyles)) {
106 // Reject empty/whitespace-only entries: an empty branch in the imploded
107 // regex would match every URL at position zero and disable the resolver.
108 $_this->permittedAssetsLocations['styles'] = array_values(array_filter($filteredStyles, static function ($pattern): bool {
109 return is_string($pattern) && trim($pattern) !== '';
110 }));
111 }
112 // unload all styles except from the list of allowed
113 $dequeueStyles = function() use($_this) {
114 global $wp_styles; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
115 if (!isset($wp_styles->registered)) return; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
116 if (empty($wp_styles->queue)) return; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
117 foreach ($wp_styles->queue as $wpStyle) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
118 if (empty($wp_styles->registered[$wpStyle])) continue; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
119 $registeredStyle = $wp_styles->registered[$wpStyle]; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
120 if (!is_string($registeredStyle->src)) {
121 continue;
122 }
123 if (!preg_match('!' . implode('|', $_this->permittedAssetsLocations['styles']) . '!i', $registeredStyle->src)) {
124 WPFunctions::get()->wpDequeueStyle($wpStyle);
125 }
126 }
127 };
128
129 // execute last in the following hooks
130 $executeLast = PHP_INT_MAX;
131 WPFunctions::get()->addAction('admin_enqueue_scripts', $dequeueStyles, $executeLast); // used also for styles
132 WPFunctions::get()->addAction('admin_footer', $dequeueStyles, $executeLast);
133
134 // execute first in hooks for printing (after printing is too late)
135 $executeFirst = defined('PHP_INT_MIN') ? constant('PHP_INT_MIN') : ~PHP_INT_MAX;
136 WPFunctions::get()->addAction('admin_print_styles', $dequeueStyles, $executeFirst);
137 WPFunctions::get()->addAction('admin_print_footer_scripts', $dequeueStyles, $executeFirst);
138 }
139
140 public function resolveScriptsConflict() {
141 $_this = $this;
142 $filteredScripts = WPFunctions::get()->applyFilters('mailpoet_conflict_resolver_whitelist_script', $_this->permittedAssetsLocations['scripts']);
143 if (is_array($filteredScripts)) {
144 // Reject empty/whitespace-only entries: an empty branch in the imploded
145 // regex would match every URL at position zero and disable the resolver.
146 $_this->permittedAssetsLocations['scripts'] = array_values(array_filter($filteredScripts, static function ($pattern): bool {
147 return is_string($pattern) && trim($pattern) !== '';
148 }));
149 }
150 // unload all scripts except from the list of allowed
151 $dequeueScripts = function() use($_this) {
152 global $wp_scripts; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
153 foreach ($wp_scripts->queue as $wpScript) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
154 if (in_array($wpScript, $_this->permittedScriptHandles, true)) {
155 continue;
156 }
157 if (empty($wp_scripts->registered[$wpScript])) continue; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
158 $registeredScript = $wp_scripts->registered[$wpScript]; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
159 if (!is_string($registeredScript->src)) {
160 continue;
161 }
162 if (!preg_match('!' . implode('|', $_this->permittedAssetsLocations['scripts']) . '!i', $registeredScript->src)) {
163 WPFunctions::get()->wpDequeueScript($wpScript);
164 }
165 }
166 };
167
168 // execute last in the following hooks
169 $executeLast = PHP_INT_MAX;
170 WPFunctions::get()->addAction('admin_enqueue_scripts', $dequeueScripts, $executeLast);
171 WPFunctions::get()->addAction('admin_footer', $dequeueScripts, $executeLast);
172
173 // execute first in hooks for printing (after printing is too late)
174 $executeFirst = defined('PHP_INT_MIN') ? constant('PHP_INT_MIN') : ~PHP_INT_MAX;
175 WPFunctions::get()->addAction('admin_print_scripts', $dequeueScripts, $executeFirst);
176 WPFunctions::get()->addAction('admin_print_footer_scripts', $dequeueScripts, $executeFirst);
177 }
178
179 public function resolveEditorConflict() {
180
181 // mark editor as already enqueued to prevent loading its assets
182 // when wp_enqueue_editor() used by some other plugin
183 global $wp_actions; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
184 $wp_actions['wp_enqueue_editor'] = 1; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
185
186 // prevent editor loading when used wp_editor() used by some other plugin
187 WPFunctions::get()->addFilter('wp_editor_settings', function () {
188 ob_start();
189 return [
190 'tinymce' => false,
191 'quicktags' => false,
192 ];
193 });
194
195 WPFunctions::get()->addFilter('the_editor', function () {
196 return '';
197 });
198
199 WPFunctions::get()->addFilter('the_editor_content', function () {
200 ob_end_clean();
201 return '';
202 });
203 }
204
205 public function resolveTinyMceConflict() {
206 // WordPress TinyMCE scripts may not get enqueued as scripts when some plugins use wp_editor()
207 // or wp_enqueue_editor(). Instead, they are printed inside the footer script print actions.
208 // To unload TinyMCE we need to remove those actions.
209 $tinyMceFooterScriptHooks = [
210 '_WP_Editors::enqueue_scripts',
211 '_WP_Editors::editor_js',
212 '_WP_Editors::force_uncompressed_tinymce',
213 '_WP_Editors::print_default_editor_scripts',
214 ];
215
216 $disableWpTinymce = function() use ($tinyMceFooterScriptHooks) {
217 global $wp_filter; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
218 $actionName = 'admin_print_footer_scripts';
219 if (!isset($wp_filter[$actionName])) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
220 return;
221 }
222 foreach ($wp_filter[$actionName]->callbacks as $priority => $callbacks) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
223 foreach ($tinyMceFooterScriptHooks as $hook) {
224 if (isset($callbacks[$hook])) {
225 WPFunctions::get()->removeAction($actionName, $callbacks[$hook]['function'], $priority);
226 }
227 }
228 }
229 };
230
231 WPFunctions::get()->addAction('admin_footer', $disableWpTinymce, PHP_INT_MAX);
232 }
233 }
234