← All changes
|
includes/class-metasync-compatibility-checker.php
+196
-51
2.6.10
→
2.7.2
View file →
| @@ -38,8 +38,36 @@ | ||
| 38 | 38 | |
| 39 | 39 | <div class="dashboard-card"> |
| 40 | 40 | <?php $this->render_compatibility_sections(); ?> |
| 41 | 41 | </div> |
| 42 | + | |
| 43 | + <?php | |
| 44 | + # Plugin-compatibility toggles. Registered under the | |
| 45 | + # <page_slug>_compatibility settings page only while the relevant | |
| 46 | + # plugin is active, so the card self-hides when neither plugin is | |
| 47 | + # present. Saves through options.php with a hidden active_tab so | |
| 48 | + # the General-tab sanitizer blocks stay inert. | |
| 49 | + $has_compat_fields = defined('WP_ROCKET_VERSION') | |
| 50 | + || class_exists('WP_Rocket') | |
| 51 | + || class_exists('SiteGround_Optimizer\Parser\Parser') | |
| 52 | + || defined('SiteGround_Optimizer\VERSION') | |
| 53 | + || class_exists('bookingpress_spam_protection'); | |
| 54 | + if ($has_compat_fields) : | |
| 55 | + settings_errors(); | |
| 56 | + ?> | |
| 57 | + <div class="dashboard-card" style="margin-top: 20px;"> | |
| 58 | + <h2 style="margin: 0 0 4px 0;">Plugin Compatibility Settings</h2> | |
| 59 | + <p style="color: var(--dashboard-text-secondary); margin: 0 0 20px 0;">Control how <?php echo esc_html(Metasync::get_effective_plugin_name()); ?> interacts with detected plugins. Each setting appears only while its plugin is active.</p> | |
| 60 | + <form method="post" action="options.php"> | |
| 61 | + <input type="hidden" name="active_tab" value="compatibility" /> | |
| 62 | + <?php | |
| 63 | + settings_fields(Metasync_Admin::option_group); | |
| 64 | + do_settings_sections(Metasync_Admin::$page_slug . '_compatibility'); | |
| 65 | + submit_button(); | |
| 66 | + ?> | |
| 67 | + </form> | |
| 68 | + </div> | |
| 69 | + <?php endif; ?> | |
| 42 | 70 | |
| 43 | 71 | <!-- Section: Host Blocking Test --> |
| 44 | 72 | <div id="ms-comp-host-test" class="dashboard-card" style="margin-top: 20px;"> |
| 45 | 73 | <details open> |
| @@ -58,8 +86,9 @@ | ||
| 58 | 86 | <button type="button" id="test-both-requests" class="button button-primary"> |
| 59 | 87 | <span class="dashicons dashicons-controls-repeat"></span> Test Both Requests |
| 60 | 88 | </button> |
| 61 | 89 | </div> |
| 90 | + <?php $this->render_last_automatic_check(); ?> | |
| 62 | 91 | </div> |
| 63 | 92 | <div id="host-test-results" style="display: none; margin-top:16px;"> |
| 64 | 93 | <h3 style="color: var(--dashboard-text-primary); margin-bottom: 10px;">Test Results</h3> |
| 65 | 94 | <div id="test-results-content"></div> |
| @@ -133,9 +162,9 @@ | ||
| 133 | 162 | $.ajax({ |
| 134 | 163 | url: ajaxUrl, |
| 135 | 164 | type: 'POST', |
| 136 | 165 | dataType: 'json', |
| 137 | - data: { action: action, nonce: '<?php echo wp_create_nonce("metasync_nonce"); ?>' }, | |
| 166 | + data: { action: action, nonce: '<?php echo esc_attr(wp_create_nonce("metasync_nonce")); ?>' }, | |
| 138 | 167 | timeout: 35000, |
| 139 | 168 | success: function(response, textStatus, xhr) { |
| 140 | 169 | try { |
| 141 | 170 | if (response && response.success && response.data) { |
| @@ -193,29 +222,33 @@ | ||
| 193 | 222 | function displayResults(results) { |
| 194 | 223 | var html = ''; |
| 195 | 224 | |
| 196 | 225 | results.forEach(function(result) { |
| 197 | - var statusClass = result.status === 'success' ? 'success' : 'error'; | |
| 198 | - var statusIcon = result.status === 'success' ? '✅' : '❌'; | |
| 199 | - var blockedStatus = result.blocked ? 'BLOCKED' : 'ALLOWED'; | |
| 200 | - var blockedClass = result.blocked ? 'blocked' : 'allowed'; | |
| 226 | + // Three states, not two: a request can also be | |
| 227 | + // inconclusive when the checker service itself is | |
| 228 | + // unavailable — that must never read as "blocked". | |
| 229 | + var inconclusive = !!result.checker_unreachable; | |
| 230 | + var statusClass = result.status === 'success' ? 'success' : (inconclusive ? 'warning' : 'error'); | |
| 231 | + var statusIcon = result.status === 'success' ? '✅' : (inconclusive ? '⚠️' : '❌'); | |
| 232 | + var blockedStatus = inconclusive ? 'INCONCLUSIVE' : (result.blocked ? 'BLOCKED' : 'ALLOWED'); | |
| 233 | + var blockedClass = inconclusive ? 'inconclusive' : (result.blocked ? 'blocked' : 'allowed'); | |
| 201 | 234 | |
| 202 | 235 | html += '<div class="test-result-item ' + statusClass + '">'; |
| 203 | 236 | html += '<div class="test-result-header">'; |
| 204 | - html += '<h4>' + statusIcon + ' ' + result.method + ' Request - ' + blockedStatus + '</h4>'; | |
| 237 | + html += '<h4>' + statusIcon + ' ' + escapeHtml(result.method) + ' Request - ' + blockedStatus + '</h4>'; | |
| 205 | 238 | html += '<span class="test-status ' + blockedClass + '">' + blockedStatus + '</span>'; |
| 206 | 239 | html += '</div>'; |
| 207 | 240 | |
| 208 | 241 | html += '<div class="test-result-details">'; |
| 209 | - html += '<p><strong>Response Time:</strong> ' + result.response_time + '</p>'; | |
| 210 | - html += '<p><strong>Status:</strong> ' + result.status + '</p>'; | |
| 242 | + html += '<p><strong>Response Time:</strong> ' + escapeHtml(result.response_time) + '</p>'; | |
| 243 | + html += '<p><strong>Status:</strong> ' + escapeHtml(result.status) + '</p>'; | |
| 211 | 244 | |
| 212 | 245 | if (result.status_code) { |
| 213 | - html += '<p><strong>HTTP Status Code:</strong> <span class="status-code">' + result.status_code + '</span></p>'; | |
| 246 | + html += '<p><strong>HTTP Status Code:</strong> <span class="status-code">' + escapeHtml(result.status_code) + '</span></p>'; | |
| 214 | 247 | } |
| 215 | 248 | |
| 216 | 249 | if (result.error) { |
| 217 | - html += '<p><strong>Error:</strong> <span class="error-message">' + result.error + '</span></p>'; | |
| 250 | + html += '<p><strong>Error:</strong> <span class="error-message">' + escapeHtml(result.error) + '</span></p>'; | |
| 218 | 251 | } |
| 219 | 252 | |
| 220 | 253 | if (result.body) { |
| 221 | 254 | html += '<p><strong>Response Body:</strong></p>'; |
| @@ -225,9 +258,9 @@ | ||
| 225 | 258 | if (result.headers && Object.keys(result.headers).length > 0) { |
| 226 | 259 | html += '<p><strong>Response Headers:</strong></p>'; |
| 227 | 260 | html += '<pre class="response-headers">'; |
| 228 | 261 | Object.keys(result.headers).forEach(function(key) { |
| 229 | - html += key + ': ' + result.headers[key] + '\n'; | |
| 262 | + html += escapeHtml(key) + ': ' + escapeHtml(result.headers[key]) + '\n'; | |
| 230 | 263 | }); |
| 231 | 264 | html += '</pre>'; |
| 232 | 265 | } |
| 233 | 266 | |
| @@ -240,9 +273,9 @@ | ||
| 240 | 273 | html += '<p><strong>Parsed Response:</strong></p>'; |
| 241 | 274 | html += '<pre class="parsed-response">' + escapeHtml(JSON.stringify(result.parsed_response, null, 2)) + '</pre>'; |
| 242 | 275 | } |
| 243 | 276 | |
| 244 | - html += '<p><strong>Details:</strong> ' + result.details + '</p>'; | |
| 277 | + html += '<p><strong>Details:</strong> ' + escapeHtml(result.details) + '</p>'; | |
| 245 | 278 | html += '</div>'; |
| 246 | 279 | html += '</div>'; |
| 247 | 280 | }); |
| 248 | 281 | |
| @@ -257,9 +290,9 @@ | ||
| 257 | 290 | '>': '>', |
| 258 | 291 | '"': '"', |
| 259 | 292 | "'": ''' |
| 260 | 293 | }; |
| 261 | - return text.replace(/[&<>"']/g, function(m) { return map[m]; }); | |
| 294 | + return String(text).replace(/[&<>"']/g, function(m) { return map[m]; }); | |
| 262 | 295 | } |
| 263 | 296 | |
| 264 | 297 | setTimeout(function() { |
| 265 | 298 | var btnBoth = $('#test-both-requests'); |
| @@ -289,9 +322,13 @@ | ||
| 289 | 322 | |
| 290 | 323 | .test-result-item.error { |
| 291 | 324 | border-left: 4px solid #dc3545; |
| 292 | 325 | } |
| 293 | - | |
| 326 | + | |
| 327 | + .test-result-item.warning { | |
| 328 | + border-left: 4px solid #dba617; | |
| 329 | + } | |
| 330 | + | |
| 294 | 331 | .test-result-header { |
| 295 | 332 | background: var(--dashboard-bg); |
| 296 | 333 | padding: 15px 20px; |
| 297 | 334 | border-bottom: 1px solid #dee2e6; |
| @@ -322,9 +359,14 @@ | ||
| 322 | 359 | .test-status.blocked { |
| 323 | 360 | background: rgba(248,113,113,0.15); |
| 324 | 361 | color: #f87171; |
| 325 | 362 | } |
| 326 | - | |
| 363 | + | |
| 364 | + .test-status.inconclusive { | |
| 365 | + background: rgba(219,166,23,0.15); | |
| 366 | + color: #dba617; | |
| 367 | + } | |
| 368 | + | |
| 327 | 369 | .test-result-details { |
| 328 | 370 | padding: 20px; |
| 329 | 371 | } |
| 330 | 372 | |
| @@ -493,8 +535,10 @@ | ||
| 493 | 535 | color: #646970 !important; |
| 494 | 536 | opacity: 0.7; |
| 495 | 537 | } |
| 496 | 538 | |
| 539 | + /* Equal width so badges of different lengths (Exact, Contains, | |
| 540 | + etc.) render at the same size for a visually balanced column. */ | |
| 497 | 541 | .otto-pattern-type-badge { |
| 498 | 542 | display: inline-block; |
| 499 | 543 | padding: 3px 8px; |
| 500 | 544 | border-radius: 3px; |
| @@ -501,13 +545,19 @@ | ||
| 501 | 545 | font-size: 11px; |
| 502 | 546 | font-weight: 600; |
| 503 | 547 | text-transform: uppercase; |
| 504 | 548 | letter-spacing: 0.5px; |
| 549 | + min-width: 90px; | |
| 550 | + text-align: center; | |
| 551 | + box-sizing: border-box; | |
| 505 | 552 | } |
| 506 | 553 | |
| 554 | + /* Badge text is 11px uppercase, i.e. normal-size text: the darker | |
| 555 | + foreground steps keep every pair at or above the 4.5:1 AA bar | |
| 556 | + on its own pastel background. */ | |
| 507 | 557 | .otto-pattern-exact { |
| 508 | 558 | background: #e3f2fd; |
| 509 | - color: #1976d2; | |
| 559 | + color: #0d47a1; | |
| 510 | 560 | } |
| 511 | 561 | |
| 512 | 562 | .otto-pattern-contain { |
| 513 | 563 | background: #f3e5f5; |
| @@ -515,14 +565,14 @@ | ||
| 515 | 565 | } |
| 516 | 566 | |
| 517 | 567 | .otto-pattern-start { |
| 518 | 568 | background: #e8f5e9; |
| 519 | - color: #388e3c; | |
| 569 | + color: #1b5e20; | |
| 520 | 570 | } |
| 521 | 571 | |
| 522 | 572 | .otto-pattern-end { |
| 523 | - background: var(--dashboard-card-bg)3e0; | |
| 524 | - color: #f57c00; | |
| 573 | + background: #fff3e0; | |
| 574 | + color: #8f4400; | |
| 525 | 575 | } |
| 526 | 576 | |
| 527 | 577 | .otto-pattern-regex { |
| 528 | 578 | background: #fce4ec; |
| @@ -554,12 +604,35 @@ | ||
| 554 | 604 | } |
| 555 | 605 | |
| 556 | 606 | #otto-excluded-urls-table-container .wp-list-table td { |
| 557 | 607 | background: var(--dashboard-card-bg) !important; |
| 558 | - color: #2c3338 !important; | |
| 608 | + color: var(--dashboard-text-primary) !important; | |
| 559 | 609 | border-bottom: 1px solid #c3c4c7; |
| 560 | 610 | } |
| 561 | 611 | |
| 612 | + /* Placeholder text (empty description, no recheck date) still has to | |
| 613 | + clear AA against the card background in both themes. */ | |
| 614 | + #otto-excluded-urls-table-container .otto-muted { | |
| 615 | + color: var(--dashboard-text-secondary) !important; | |
| 616 | + } | |
| 617 | + | |
| 618 | + /* Loading / empty-state text shown in place of the table. */ | |
| 619 | + #otto-excluded-urls-table-container .otto-table-message { | |
| 620 | + text-align: center; | |
| 621 | + padding: 40px; | |
| 622 | + color: var(--dashboard-text-secondary); | |
| 623 | + } | |
| 624 | + | |
| 625 | + /* Error text replaces the table on a failed load. No single red | |
| 626 | + clears AA on both card backgrounds, so each theme gets its own. */ | |
| 627 | + #otto-excluded-urls-table-container .otto-error-message { | |
| 628 | + color: #f87171 !important; | |
| 629 | + } | |
| 630 | + | |
| 631 | + [data-theme="light"] #otto-excluded-urls-table-container .otto-error-message { | |
| 632 | + color: #b02a37 !important; | |
| 633 | + } | |
| 634 | + | |
| 562 | 635 | #otto-excluded-urls-table-container .wp-list-table tbody tr { |
| 563 | 636 | background: var(--dashboard-card-bg); |
| 564 | 637 | } |
| 565 | 638 | |
| @@ -576,11 +649,15 @@ | ||
| 576 | 649 | border: 1px solid #dcdcde; |
| 577 | 650 | } |
| 578 | 651 | |
| 579 | 652 | #otto-excluded-urls-table-container .otto-delete-url, |
| 580 | - #otto-excluded-urls-table-container .otto-recheck-url { | |
| 653 | + #otto-excluded-urls-table-container .otto-recheck-url, | |
| 654 | + #otto-excluded-urls-table-container .otto-recheck-disabled { | |
| 581 | 655 | padding: 4px 10px; |
| 582 | 656 | font-size: 12px; |
| 657 | + box-sizing: border-box; | |
| 658 | + height: 26px; | |
| 659 | + line-height: 1; | |
| 583 | 660 | } |
| 584 | 661 | |
| 585 | 662 | #otto-excluded-urls-table-container .otto-delete-url { |
| 586 | 663 | background: #dc3545 !important; |
| @@ -629,8 +706,62 @@ | ||
| 629 | 706 | <?php |
| 630 | 707 | $admin->render_layout_close(); |
| 631 | 708 | } |
| 632 | 709 | |
| 710 | + /** | |
| 711 | + * Show the result of the last automatic host blocking check. | |
| 712 | + * | |
| 713 | + * Reads the stored result only — it never triggers a probe, so opening this page | |
| 714 | + * costs nothing extra. The automatic check runs ~10 minutes after activation and | |
| 715 | + * weekly after that; the button above re-runs the same probe on demand. | |
| 716 | + */ | |
| 717 | + private function render_last_automatic_check(): void | |
| 718 | + { | |
| 719 | + if (!class_exists('Metasync_Host_Blocking_Check')) { | |
| 720 | + return; | |
| 721 | + } | |
| 722 | + | |
| 723 | + $checker = Metasync_Host_Blocking_Check::get_instance(); | |
| 724 | + $result = $checker->get_last_result(); | |
| 725 | + | |
| 726 | + echo '<p style="margin: 16px 0 0 0; font-size: 12px; color: var(--dashboard-text-secondary);">'; | |
| 727 | + | |
| 728 | + if ($result === null) { | |
| 729 | + if (!$checker->site_is_publicly_reachable()) { | |
| 730 | + echo esc_html__('Automatic checks are skipped on local and private-network sites, because our services cannot call this site back. Use the button above to test manually.', 'metasync'); | |
| 731 | + } else { | |
| 732 | + echo esc_html__('The automatic check has not run yet. It runs about 10 minutes after activation, then weekly.', 'metasync'); | |
| 733 | + } | |
| 734 | + echo '</p>'; | |
| 735 | + return; | |
| 736 | + } | |
| 737 | + | |
| 738 | + $blocked = []; | |
| 739 | + if ($result['get_blocked']) { | |
| 740 | + $blocked[] = 'GET'; | |
| 741 | + } | |
| 742 | + if ($result['post_blocked']) { | |
| 743 | + $blocked[] = 'POST'; | |
| 744 | + } | |
| 745 | + | |
| 746 | + if (empty($blocked)) { | |
| 747 | + printf( | |
| 748 | + /* translators: %s: date/time of the last automatic check */ | |
| 749 | + esc_html__('Last automatic check: %s — no blocking detected.', 'metasync'), | |
| 750 | + esc_html($result['checked_at']) | |
| 751 | + ); | |
| 752 | + } else { | |
| 753 | + printf( | |
| 754 | + /* translators: 1: date/time of the last automatic check, 2: blocked HTTP methods */ | |
| 755 | + esc_html__('Last automatic check: %1$s — %2$s requests were blocked. Re-run the test above after changing any firewall or security settings.', 'metasync'), | |
| 756 | + esc_html($result['checked_at']), | |
| 757 | + esc_html(implode(' and ', $blocked)) | |
| 758 | + ); | |
| 759 | + } | |
| 760 | + | |
| 761 | + echo '</p>'; | |
| 762 | + } | |
| 763 | + | |
| 633 | 764 | public function render_compatibility_sections() |
| 634 | 765 | { |
| 635 | 766 | ?> |
| 636 | 767 | <div class="metasync-settings-accordion"> |
| @@ -864,8 +995,9 @@ | ||
| 864 | 995 | ], |
| 865 | 996 | 'bricks' => [ |
| 866 | 997 | 'name' => 'Bricks Builder', |
| 867 | 998 | 'plugin_files' => [ 'bricks/bricks.php' ], |
| 999 | + 'theme_name' => 'Bricks', | |
| 868 | 1000 | 'supported' => true, |
| 869 | 1001 | 'version' => '1.11', |
| 870 | 1002 | ], |
| 871 | 1003 | ]; |
| @@ -873,10 +1005,12 @@ | ||
| 873 | 1005 | $result = []; |
| 874 | 1006 | |
| 875 | 1007 | foreach ($builders as $key => $builder) { |
| 876 | 1008 | $is_core = isset($builder['is_core']) && $builder['is_core']; |
| 877 | - $theme_name = isset($builder['theme_name']) ? $builder['theme_name'] : null; | |
| 878 | - $plugin_status = $this->get_plugin_status($builder['plugin_files'], $is_core, $theme_name); | |
| 1009 | + // The array key is the theme directory slug; pass it (not the display name) | |
| 1010 | + // so wp_get_theme() can resolve the theme on case-sensitive filesystems. | |
| 1011 | + $theme_slug = isset($builder['theme_name']) ? $key : null; | |
| 1012 | + $plugin_status = $this->get_plugin_status($builder['plugin_files'], $is_core, $theme_slug); | |
| 879 | 1013 | |
| 880 | 1014 | if ($builder['supported']) { |
| 881 | 1015 | $status = 'supported'; |
| 882 | 1016 | $status_text = 'Supported'; |
| @@ -1002,9 +1136,11 @@ | ||
| 1002 | 1136 | ]; |
| 1003 | 1137 | |
| 1004 | 1138 | $result = []; |
| 1005 | 1139 | foreach ( $themes as $key => $theme ) { |
| 1006 | - $status = $this->get_plugin_status( $theme['plugin_files'], false, $theme['theme_name'] ); | |
| 1140 | + // The array key is the theme directory slug; pass it (not the display name) | |
| 1141 | + // so wp_get_theme() can resolve the theme on case-sensitive filesystems. | |
| 1142 | + $status = $this->get_plugin_status( $theme['plugin_files'], false, $key ); | |
| 1007 | 1143 | $result[] = [ |
| 1008 | 1144 | 'name' => $theme['name'], |
| 1009 | 1145 | 'version' => $theme['version'], |
| 1010 | 1146 | 'status' => 'supported', |
| @@ -1177,12 +1313,14 @@ | ||
| 1177 | 1313 | * Get detailed plugin status (installed and/or active). |
| 1178 | 1314 | * |
| 1179 | 1315 | * @param array $plugin_files Array of plugin file paths to check |
| 1180 | 1316 | * @param bool $is_core Whether this is a WordPress core feature |
| 1181 | - * @param string $theme_name Optional theme name to check | |
| 1317 | + * @param string $theme_slug Optional theme directory slug to check (e.g. 'hello-elementor', | |
| 1318 | + * 'astra'). Must be the directory slug, not the display name, | |
| 1319 | + * because wp_get_theme() resolves themes by directory slug. | |
| 1182 | 1320 | * @return array ['is_installed' => bool, 'is_active' => bool, 'active_version' => string|null] |
| 1183 | 1321 | */ |
| 1184 | - public function get_plugin_status($plugin_files, $is_core = false, $theme_name = null) | |
| 1322 | + public function get_plugin_status($plugin_files, $is_core = false, $theme_slug = null) | |
| 1185 | 1323 | { |
| 1186 | 1324 | if ($is_core) { |
| 1187 | 1325 | return [ |
| 1188 | 1326 | 'is_installed' => true, |
| @@ -1190,14 +1328,16 @@ | ||
| 1190 | 1328 | 'active_version' => 'core' |
| 1191 | 1329 | ]; |
| 1192 | 1330 | } |
| 1193 | 1331 | |
| 1194 | - if ($theme_name) { | |
| 1332 | + if ($theme_slug) { | |
| 1195 | 1333 | $current_theme = wp_get_theme(); |
| 1196 | - $is_theme_active = (strtolower($current_theme->get('Name')) === strtolower($theme_name) || | |
| 1197 | - strtolower($current_theme->get_stylesheet()) === strtolower($theme_name)); | |
| 1334 | + $is_theme_active = (strtolower($current_theme->get('Name')) === strtolower($theme_slug) || | |
| 1335 | + strtolower($current_theme->get_stylesheet()) === strtolower($theme_slug)); | |
| 1198 | 1336 | |
| 1199 | - $theme_exists = wp_get_theme($theme_name)->exists(); | |
| 1337 | + // An active theme is by definition installed. Fall back to a directory | |
| 1338 | + // lookup for themes that are installed but not currently active. | |
| 1339 | + $theme_exists = $is_theme_active || wp_get_theme($theme_slug)->exists(); | |
| 1200 | 1340 | |
| 1201 | 1341 | if ($theme_exists) { |
| 1202 | 1342 | return [ |
| 1203 | 1343 | 'is_installed' => true, |
| @@ -1246,39 +1386,44 @@ | ||
| 1246 | 1386 | } |
| 1247 | 1387 | |
| 1248 | 1388 | public function get_plugin_logo($plugin_key, $type) |
| 1249 | 1389 | { |
| 1390 | + // Compatibility icons are bundled locally; loading images from external | |
| 1391 | + // servers (wp.org, vendor sites, CDNs) counts as offloaded content and | |
| 1392 | + // is disallowed for wordpress.org releases. | |
| 1393 | + $assets = plugins_url('assets/images/compat/', dirname(__DIR__) . '/metasync.php'); | |
| 1394 | + | |
| 1250 | 1395 | $logos = [ |
| 1251 | 1396 | 'page_builder' => [ |
| 1252 | - 'elementor' => 'https://ps.w.org/elementor/assets/icon-256x256.gif', | |
| 1253 | - 'gutenberg' => 'https://i0.wp.com/wordpress.org/files/2023/02/wmark.png', | |
| 1254 | - 'divi' => 'https://www.elegantthemes.com/images/logo.svg', | |
| 1255 | - 'oxygen' => 'https://oxygenbuilder.com/wp-content/uploads/2021/09/oxygen-logo-icon.png', | |
| 1256 | - 'bricks' => 'https://bricksbuilder.io/wp-content/uploads/2021/05/bricks-icon.svg', | |
| 1397 | + 'elementor' => $assets . 'elementor.svg', | |
| 1398 | + 'gutenberg' => $assets . 'gutenberg.svg', | |
| 1399 | + 'divi' => $assets . 'divi.svg', | |
| 1400 | + 'oxygen' => $assets . 'oxygen.svg', | |
| 1401 | + 'bricks' => $assets . 'bricks.svg', | |
| 1257 | 1402 | ], |
| 1258 | 1403 | 'theme' => [ |
| 1259 | - 'astra' => 'https://ps.w.org/astra/assets/icon-128x128.png', | |
| 1260 | - 'generatepress' => 'https://ps.w.org/generatepress/assets/icon-128x128.png', | |
| 1261 | - 'oceanwp' => 'https://ps.w.org/ocean-extra/assets/icon-128x128.png', | |
| 1262 | - 'hello-elementor' => 'https://ps.w.org/hello-elementor/assets/icon-128x128.png', | |
| 1263 | - 'kadence' => 'https://ps.w.org/kadence-blocks/assets/icon-128x128.png', | |
| 1404 | + 'astra' => $assets . 'astra.svg', | |
| 1405 | + 'generatepress' => $assets . 'generatepress.svg', | |
| 1406 | + 'oceanwp' => $assets . 'oceanwp.svg', | |
| 1407 | + 'hello-elementor' => $assets . 'hello-elementor.svg', | |
| 1408 | + 'kadence' => $assets . 'kadence.svg', | |
| 1264 | 1409 | ], |
| 1265 | 1410 | 'seo' => [ |
| 1266 | - 'yoast' => 'https://ps.w.org/wordpress-seo/assets/icon-128x128.gif', | |
| 1267 | - 'rankmath' => 'https://ps.w.org/seo-by-rank-math/assets/icon-128x128.png', | |
| 1268 | - 'aioseo' => 'https://ps.w.org/all-in-one-seo-pack/assets/icon-128x128.png', | |
| 1411 | + 'yoast' => $assets . 'yoast.svg', | |
| 1412 | + 'rankmath' => $assets . 'rankmath.svg', | |
| 1413 | + 'aioseo' => $assets . 'aioseo.svg', | |
| 1269 | 1414 | ], |
| 1270 | 1415 | 'cache' => [ |
| 1271 | - 'wp-rocket' => 'https://ps.w.org/rocket-lazy-load/assets/icon-128x128.png', | |
| 1272 | - 'litespeed-cache' => 'https://ps.w.org/litespeed-cache/assets/icon-128x128.png', | |
| 1273 | - 'w3-total-cache' => 'https://ps.w.org/w3-total-cache/assets/icon-128x128.png', | |
| 1274 | - 'sg-cachepress' => 'https://ps.w.org/sg-cachepress/assets/icon-128x128.png', | |
| 1275 | - 'hummingbird-performance' => 'https://ps.w.org/hummingbird-performance/assets/icon-128x128.png', | |
| 1276 | - 'autoptimize' => 'https://ps.w.org/autoptimize/assets/icon-128x128.png', | |
| 1416 | + 'wp-rocket' => $assets . 'wp-rocket.svg', | |
| 1417 | + 'litespeed-cache' => $assets . 'litespeed-cache.svg', | |
| 1418 | + 'w3-total-cache' => $assets . 'w3-total-cache.svg', | |
| 1419 | + 'sg-cachepress' => $assets . 'sg-cachepress.svg', | |
| 1420 | + 'hummingbird-performance' => $assets . 'hummingbird-performance.svg', | |
| 1421 | + 'autoptimize' => $assets . 'autoptimize.svg', | |
| 1277 | 1422 | ], |
| 1278 | 1423 | 'cdn' => [ |
| 1279 | - 'cloudflare' => 'https://ps.w.org/cloudflare/assets/icon-128x128.png', | |
| 1280 | - 'fastly' => 'https://ps.w.org/purgely/assets/icon-128x128.png', | |
| 1424 | + 'cloudflare' => $assets . 'cloudflare.svg', | |
| 1425 | + 'fastly' => $assets . 'fastly.svg', | |
| 1281 | 1426 | ], |
| 1282 | 1427 | ]; |
| 1283 | 1428 | |
| 1284 | 1429 | return isset($logos[$type][$plugin_key]) ? $logos[$type][$plugin_key] : ''; |