PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.2
4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Newsfeed / NewsfeedRequester.php
wp-staging / Framework / Newsfeed Last commit date
NewsfeedProvider.php 5 months ago NewsfeedRequester.php 5 months ago NewsfeedValidator.php 4 months ago
NewsfeedRequester.php
124 lines
1 <?php
2
3 namespace WPStaging\Framework\Newsfeed;
4
5 use function WPStaging\functions\debug_log;
6
7 /**
8 * Fetches newsfeed JSON data from remote endpoints and caches it in the database.
9 *
10 * The remote source URLs must provide valid JSON content with the newsfeed data structure.
11 * Data is cached for 24 hours using WordPress transients.
12 */
13 class NewsfeedRequester
14 {
15 /**
16 * The transient expiration time in seconds.
17 * @var int
18 */
19 const TRANSIENT_EXPIRATION_TIME = 86400; // 24 hours
20
21 /** @var string */
22 private $url;
23
24 /** @var string */
25 private $transientIdentifier;
26
27 /**
28 * When debug mode is on, it will always fetch the data from the remote server.
29 * @var bool
30 */
31 private $isDebug = false;
32
33 /** @var NewsfeedValidator */
34 private $validator;
35
36 public function __construct(string $transientIdentifier = '', string $url = '')
37 {
38 if (empty($transientIdentifier)) {
39 throw new \InvalidArgumentException('Transient identifier cannot be empty.');
40 }
41
42 if (empty($url)) {
43 throw new \InvalidArgumentException('URL cannot be empty.');
44 }
45
46 $this->validator = new NewsfeedValidator();
47
48 $this->url = $url;
49
50 $this->transientIdentifier = 'wpstg_news_block_' . md5($transientIdentifier);
51 }
52
53 /**
54 * Fetch and return newsfeed data as an array
55 *
56 * @return array|null Parsed JSON data or null on failure
57 */
58 public function returnData()
59 {
60 $cached = get_transient($this->transientIdentifier);
61
62 if ($cached !== false && !$this->isDebug) {
63 return $cached;
64 }
65
66 $data = $this->getRemoteData();
67 if ($data === null || !$this->validator->validate($data)) {
68 return null;
69 }
70
71 if (!$this->isDebug) {
72 set_transient($this->transientIdentifier, $data, self::TRANSIENT_EXPIRATION_TIME);
73 }
74
75 return $data;
76 }
77
78 /**
79 * @param bool $isDebug
80 * @return void
81 */
82 public function setIsDebug(bool $isDebug)
83 {
84 $this->isDebug = $isDebug;
85 }
86
87 /**
88 * Fetch and parse JSON from remote URL
89 *
90 * @return array|null Parsed JSON data or null on failure
91 */
92 private function getRemoteData()
93 {
94 if (!filter_var($this->url, FILTER_VALIDATE_URL)) {
95 debug_log(sprintf('Invalid URL for retrieving the news from %s', $this->url));
96 return null;
97 }
98
99 $response = wp_remote_get($this->url, ['timeout' => 5, 'sslverify' => true]);
100
101 if (is_wp_error($response)) {
102 debug_log(sprintf('Cannot retrieve news data from URL %s. Error: %s', $this->url, $response->get_error_message()));
103 return null;
104 }
105
106 $statusCode = wp_remote_retrieve_response_code($response);
107
108 if ($statusCode !== 200) {
109 debug_log(sprintf('Cannot get remote news data from url %s Response: %s', $this->url, $statusCode));
110 return null;
111 }
112
113 $body = wp_remote_retrieve_body($response);
114 $data = json_decode(trim($body), true);
115
116 if (json_last_error() !== JSON_ERROR_NONE) {
117 debug_log(sprintf('Newsfeed JSON parse error from %s: %s', $this->url, json_last_error_msg()));
118 return null;
119 }
120
121 return $data;
122 }
123 }
124