partials
2 months ago
contact-us-basic.php
1 year ago
contact-us-pro.php
3 months ago
contact-us.php
1 year ago
darkmode-toggle-button.php
4 months ago
faq.php
3 months ago
footer.php
1 week ago
general-error-modal.php
1 year ago
header.php
3 months ago
main-navigation.php
1 year ago
newsfeed.php
3 months ago
newsfeed.php
161 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Newsfeed view template |
| 5 | * |
| 6 | * Renders the newsfeed section in the WP Staging admin sidebar. |
| 7 | * Data is fetched from remote JSON files and rendered using this template. |
| 8 | * Collapsible state is managed via localStorage in JavaScript. |
| 9 | */ |
| 10 | |
| 11 | use WPStaging\Core\WPStaging; |
| 12 | use WPStaging\Framework\Newsfeed\NewsfeedProvider; |
| 13 | |
| 14 | $provider = WPStaging::make(NewsfeedProvider::class); |
| 15 | $data = $provider->getNewsfeedData(); |
| 16 | |
| 17 | if (empty($data)) { |
| 18 | return; |
| 19 | } |
| 20 | |
| 21 | $proFeatureCount = $provider->countProFeatures($data); |
| 22 | |
| 23 | /** |
| 24 | * Render tip text with embedded link |
| 25 | * |
| 26 | * @param array $tip Tip data with text, link, and link_text |
| 27 | * @return string Rendered HTML |
| 28 | */ |
| 29 | $renderTipText = function (array $tip): string { |
| 30 | if (empty($tip['link']) || empty($tip['link_text'])) { |
| 31 | return esc_html($tip['text'] ?? ''); |
| 32 | } |
| 33 | |
| 34 | $link = '<a href="' . esc_url($tip['link']) . '" target="_blank">' . esc_html($tip['link_text']) . '</a>'; |
| 35 | $text = $tip['text'] ?? ''; |
| 36 | |
| 37 | // Replace {link} placeholder with actual link |
| 38 | if (strpos($text, '{link}') !== false) { |
| 39 | $parts = explode('{link}', $text); |
| 40 | return esc_html($parts[0]) . $link . esc_html($parts[1] ?? ''); |
| 41 | } |
| 42 | |
| 43 | // If no placeholder, append link at end |
| 44 | return esc_html($text) . ' ' . $link; |
| 45 | }; |
| 46 | ?> |
| 47 | |
| 48 | <div class="wpstg-newsfeed-container wpstg-u-block" id="wpstg-newsfeed-container"> |
| 49 | <!-- Unified Header (Always Visible, Clickable) --> |
| 50 | <div class="wpstg-newsfeed-collapsed-header" data-version="<?php echo esc_attr($data['version']); ?>" role="button" aria-expanded="true"> |
| 51 | <div class="wpstg-newsfeed-collapsed-left"> |
| 52 | <span class="wpstg-newsfeed-version">v.<?php echo esc_html($data['version']); ?></span> |
| 53 | <span class="wpstg-newsfeed-date"><?php |
| 54 | $timestamp = !empty($data['date']) ? strtotime($data['date']) : false; |
| 55 | echo esc_html($timestamp !== false ? date_i18n('M j, Y', $timestamp) : __('Unknown date', 'wp-staging')); |
| 56 | ?></span> |
| 57 | <span class="wpstg-newsfeed-new-badge" style="display: none;"><?php esc_html_e('NEW', 'wp-staging'); ?></span> |
| 58 | <?php if (!empty($data['intro']['description'])) : ?> |
| 59 | <span class="wpstg-newsfeed-intro-brief"> |
| 60 | <?php echo esc_html($data['intro']['description']); ?> |
| 61 | </span> |
| 62 | <?php endif; ?> |
| 63 | <?php if ($proFeatureCount > 0) : ?> |
| 64 | <span class="wpstg-newsfeed-pro-teaser">✨ <?php |
| 65 | // translators: %d is the number of Pro features |
| 66 | printf(esc_html(_n('%d new Pro feature', '%d new Pro features', $proFeatureCount, 'wp-staging')), absint($proFeatureCount)); |
| 67 | ?></span> |
| 68 | <?php endif; ?> |
| 69 | </div> |
| 70 | <div class="wpstg-newsfeed-collapsed-right"> |
| 71 | <span class="wpstg-newsfeed-toggle-link"> |
| 72 | <span class="wpstg-toggle-text"><?php esc_html_e('View Details', 'wp-staging'); ?></span> |
| 73 | <span class="wpstg-toggle-icon">‹</span> |
| 74 | </span> |
| 75 | </div> |
| 76 | </div> |
| 77 | |
| 78 | <!-- Collapsible Content --> |
| 79 | <div class="wpstg-newsfeed-content" style="display: none;"> |
| 80 | <?php if (!empty($data['highlights'])) : ?> |
| 81 | <div class="wpstg-newsfeed-section wpstg-newsfeed-highlights"> |
| 82 | <h3 class="wpstg-newsfeed-section-title"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#3498db" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="wpstg-newsfeed-icon"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg> <?php esc_html_e('New & Improved', 'wp-staging'); ?></h3> |
| 83 | <ul class="wpstg-newsfeed-list"> |
| 84 | <?php foreach ($data['highlights'] as $item) : ?> |
| 85 | <li class="wpstg-newsfeed-item"> |
| 86 | <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="wpstg-newsfeed-check-icon"><path d="M20 6 9 17l-5-5"></path></svg> |
| 87 | <span class="wpstg-newsfeed-item-text"> |
| 88 | <?php if (!empty($item['pro_only'])) : ?> |
| 89 | <span class="wpstg-newsfeed-badge-pro">PRO</span> |
| 90 | <?php endif; ?> |
| 91 | <strong><?php echo esc_html(rtrim($item['title'] ?? '', '.')); ?></strong><?php |
| 92 | if (!empty($item['description'])) : |
| 93 | ?>: <?php echo esc_html($item['description']); |
| 94 | endif; |
| 95 | ?> |
| 96 | </span> |
| 97 | </li> |
| 98 | <?php endforeach; ?> |
| 99 | </ul> |
| 100 | </div> |
| 101 | <?php endif; ?> |
| 102 | |
| 103 | <?php if (!empty($data['fixes'])) : ?> |
| 104 | <div class="wpstg-newsfeed-section wpstg-newsfeed-fixes"> |
| 105 | <h3 class="wpstg-newsfeed-section-title"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#e74c3c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="wpstg-newsfeed-icon"><path d="m8 2 1.88 1.88"></path><path d="M14.12 3.88 16 2"></path><path d="M9 7.13v-1a3.003 3.003 0 1 1 6 0v1"></path><path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6"></path><path d="M12 20v-9"></path><path d="M6.53 9C4.6 8.8 3 7.1 3 5"></path><path d="M6 13H2"></path><path d="M3 21c0-2.1 1.7-3.9 3.8-4"></path><path d="M20.97 5c0 2.1-1.6 3.8-3.5 4"></path><path d="M22 13h-4"></path><path d="M17.2 17c2.1.1 3.8 1.9 3.8 4"></path></svg> <?php esc_html_e('Bug Fixes', 'wp-staging'); ?></h3> |
| 106 | <ul class="wpstg-newsfeed-grid"> |
| 107 | <?php foreach ($data['fixes'] as $fix) : ?> |
| 108 | <li> |
| 109 | <?php if (!empty($fix['pro_only'])) : ?> |
| 110 | <span class="wpstg-newsfeed-badge-pro">PRO</span> |
| 111 | <?php endif; ?> |
| 112 | <?php echo esc_html($fix['description'] ?? ''); ?> |
| 113 | </li> |
| 114 | <?php endforeach; ?> |
| 115 | </ul> |
| 116 | </div> |
| 117 | <?php endif; ?> |
| 118 | |
| 119 | <?php if (WPStaging::isBasic()) : ?> |
| 120 | <!-- Upgrade Banner (Free Version Only) --> |
| 121 | <div class="wpstg-newsfeed-upgrade-banner"> |
| 122 | <span class="wpstg-upgrade-banner-text"> |
| 123 | <?php if ($proFeatureCount > 0) : ?> |
| 124 | ✨ <?php |
| 125 | // translators: %d is the number of Pro features |
| 126 | printf(esc_html__('Unlock %d Pro features', 'wp-staging'), absint($proFeatureCount)); |
| 127 | ?> |
| 128 | <?php else : ?> |
| 129 | ✨ <?php esc_html_e('Unlock all Pro features', 'wp-staging'); ?> |
| 130 | <?php endif; ?> |
| 131 | </span> |
| 132 | <a href="https://wp-staging.com/#pricing" target="_blank" rel="noopener" class="wpstg-upgrade-banner-btn"> |
| 133 | <?php esc_html_e('Upgrade to Pro', 'wp-staging'); ?> |
| 134 | </a> |
| 135 | </div> |
| 136 | <?php endif; ?> |
| 137 | </div> |
| 138 | |
| 139 | <!-- Footer (Always Visible) --> |
| 140 | <div class="wpstg-newsfeed-footer"> |
| 141 | <?php if (!empty($data['tips'])) : ?> |
| 142 | <div class="wpstg-newsfeed-tips"> |
| 143 | <?php foreach ($data['tips'] as $tip) : ?> |
| 144 | <div class="wpstg-newsfeed-tip-item"> |
| 145 | <strong><?php echo esc_html(($tip['icon'] ?? '') . ' ' . ($tip['label'] ?? '')); ?>:</strong> |
| 146 | <?php |
| 147 | // phpcs:ignore WPStagingCS.Security.EscapeOutput.OutputNotEscaped -- Output is escaped in $renderTipText |
| 148 | echo $renderTipText($tip); |
| 149 | ?> |
| 150 | </div> |
| 151 | <?php endforeach; ?> |
| 152 | </div> |
| 153 | <?php endif; ?> |
| 154 | <div class="wpstg-newsfeed-history-link"> |
| 155 | <a href="<?php echo esc_url($data['changelog_url'] ?? 'https://wp-staging.com/wp-staging-pro-changelog/'); ?>" target="_blank"> |
| 156 | <?php esc_html_e('View changelog', 'wp-staging'); ?> → |
| 157 | </a> |
| 158 | </div> |
| 159 | </div> |
| 160 | </div> |
| 161 |