PluginProbe
Ultimate Store Kit / 3.0.9
Ultimate Store Kit v3.0.9
3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 92 releases
ultimate-store-kit / includes / Admin / Feeds.php

Feeds.php in Ultimate Store Kit 3.0.9, at includes/Admin/Feeds.php

243 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimateStoreKit\Admin;
4
5 use UltimateStoreKit\Base\Singleton;
6
7 if (! defined('ABSPATH')) {
8 exit;
9 }
10
11 /**
12 * Class Feeds
13 */
14 class Feeds {
15 use Singleton;
16 private $settings;
17
18 /**
19 * Static variable to track if the feed has been displayed
20 */
21 private static $feed_displayed = false;
22
23 /**
24 * Feeds constructor.
25 */
26 public function __construct($settings = null) {
27 $this->settings = $settings ?: [
28 'feed_title' => 'BdThemes News & Updates',
29 'transient_key' => 'bdthemes_product_feeds',
30 'feed_link' => 'https://bdthemes.com/feed',
31 'remote_feed_link' => 'https://dashboard.bdthemes.io/wp-json/bdthemes/v1/product-feed/?product_category=element-pack',
32 'text_domain' => 'ultimate-store-kit',
33 'footer_links' => [
34 [
35 'url' => 'https://bdthemes.com/blog/',
36 'title' => 'Blog',
37 ],
38 [
39 'url' => 'https://bdthemes.com/knowledge-base/',
40 'title' => 'Docs',
41 ],
42 [
43 'url' => 'https://store.bdthemes.com/',
44 'title' => 'Get Pro',
45 ],
46 [
47 'url' => 'https://feedback.elementpack.pro/announcements/',
48 'title' => 'Changelog',
49 ],
50 ],
51 ];
52 add_action('wp_dashboard_setup', [$this, 'register_rss_feeds']);
53 }
54
55 /**
56 * Register RSS Feeds for Element Pack
57 */
58 public function register_rss_feeds() {
59 if (self::$feed_displayed) {
60 /**
61 * If the feed has already been displayed, do not add it again
62 */
63 return;
64 }
65
66 wp_add_dashboard_widget(
67 'bdt-dashboard-overview',
68 esc_html($this->settings['feed_title']),
69 [$this, 'display_rss_feeds_content'],
70 null,
71 null,
72 'column4',
73 'core'
74 );
75
76 /**
77 * Mark the feed as displayed
78 */
79 self::$feed_displayed = true;
80 }
81
82 /**
83 * Display RSS Feeds Content
84 */
85 public function display_rss_feeds_content() {
86 $feeds = $this->get_remote_feeds_data();
87 if (is_array($feeds)) {
88 foreach ($feeds as $feed) {
89 ?>
90 <div class="activity-block">
91 <a href="<?php echo esc_url($feed->demo_link); ?>" target="_blank" style="margin-bottom:10px; display: inline-block;">
92 <img src="<?php echo esc_url($feed->image); ?>" style="width:100%;min-height:240px;">
93 </a>
94 <p>
95 <?php echo wp_kses_post(wp_trim_words(wp_strip_all_tags($feed->content), 50)); ?>
96 <a href="<?php echo esc_url($feed->demo_link); ?>" target="_blank">
97 <?php esc_html_e('Learn more...', $this->settings['text_domain']); ?>
98 </a>
99 </p>
100 </div>
101 <?php
102 }
103 }
104 echo wp_kses_post($this->get_rss_posts_data());
105 }
106
107 /**
108 * Get Remote Feeds Data
109 *
110 * @return array|mixed
111 */
112 private function get_remote_feeds_data() {
113 $transient_key = $this->settings['transient_key'];
114 $cached_data = get_transient($transient_key);
115
116 if (! empty($cached_data)) {
117 return json_decode($cached_data);
118 }
119
120 $response = wp_remote_get(
121 $this->settings['remote_feed_link'],
122 array(
123 'timeout' => 30,
124 'headers' => array(
125 'Accept' => 'application/json',
126 ),
127 )
128 );
129
130 if (is_wp_error($response)) {
131 return [];
132 }
133
134 $response_body = wp_remote_retrieve_body($response);
135 set_transient($transient_key, $response_body, 6 * HOUR_IN_SECONDS);
136
137 return json_decode($response_body);
138 }
139
140 /**
141 * Get RSS Posts Data
142 *
143 * @return string
144 */
145 private function get_rss_posts_data() {
146 $transient_key = $this->settings['transient_key'] . '_rss';
147 $cached_data = get_transient($transient_key);
148
149 if (! empty($cached_data)) {
150 /**
151 * Decode as associative array
152 */
153 $rss_items = json_decode($cached_data, true);
154 } else {
155 include_once ABSPATH . WPINC . '/feed.php';
156
157 $rss = fetch_feed($this->settings['feed_link']);
158
159 if (is_wp_error($rss)) {
160 return '<li>' . esc_html__('Items Not Found', $this->settings['text_domain']) . '.</li>';
161 }
162
163 $maxitems = $rss->get_item_quantity(5);
164 $rss_items = $rss->get_items(0, $maxitems);
165
166 /**
167 * Convert RSS items to a simpler array to avoid serialization issues
168 */
169 $simplified_rss_items = array_map(function ($item) {
170 return [
171 'title' => $item->get_title(),
172 'link' => $item->get_permalink(),
173 'date' => $item->get_date('U'),
174 'content' => $item->get_content(),
175 ];
176 }, $rss_items);
177
178 set_transient($transient_key, json_encode($simplified_rss_items), 6 * HOUR_IN_SECONDS);
179 $rss_items = $simplified_rss_items;
180 }
181
182 ob_start();
183 ?>
184 <div class="bdt-widget">
185 <ul>
186 <?php if (empty($rss_items)) : ?>
187 <li><?php esc_html_e('Items Not Found', $this->settings['text_domain']); ?>.</li>
188 <?php else : ?>
189 <?php foreach ($rss_items as $item) : ?>
190 <li>
191 <a target="_blank" href="<?php echo esc_url($item['link']); ?>"
192 title="<?php echo esc_html($item['date']); ?>">
193 <?php if ($this->is_feed_item_new($item['date'])) : ?>
194 <span class="bdt-feed-badge bdt-feed-badge--new"><?php esc_html_e('New', $this->settings['text_domain']); ?></span>
195 <?php endif; ?>
196 <?php echo esc_html($item['title']); ?>
197 </a>
198 <span class="bdt-date" style="display: block; margin: 0;">
199 <?php echo esc_html(human_time_diff($item['date'], current_time('timestamp')) . ' ' . __('ago', $this->settings['text_domain'])); ?>
200 </span>
201 <div class="bdt-summary">
202 <?php echo esc_html(wp_html_excerpt($item['content'], 120) . ' [...]'); ?>
203 </div>
204 </li>
205 <?php endforeach; ?>
206 <?php endif; ?>
207 </ul>
208 </div>
209 <p class="community-events-footer" style="margin: 12px -12px 6px -12px; padding: 12px 12px 0px;">
210 <?php
211 foreach ($this->settings['footer_links'] as $link) {
212 printf(
213 '<a href="%s" target="_blank">%s <span class="screen-reader-text"> (opens in a new tab)</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
214 esc_url($link['url']),
215 esc_html($link['title'])
216 );
217
218 if (next($this->settings['footer_links'])) {
219 echo ' | ';
220 }
221 }
222 ?>
223 </p>
224 <?php
225 return ob_get_clean();
226 }
227
228 /**
229 * Check if a feed item is "new" (published within the last 7 days).
230 *
231 * @param int|string $date Unix timestamp.
232 * @return bool
233 */
234 private function is_feed_item_new($date) {
235 $timestamp = is_numeric($date) ? (int) $date : strtotime($date);
236 if (! $timestamp) {
237 return false;
238 }
239 $cutoff = time() - (7 * DAY_IN_SECONDS);
240 return $timestamp >= $cutoff;
241 }
242 }
243