PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.3
Elementor Website Builder – more than just a page builder v4.3.3
4.3.3 4.3.2 4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 All 456 releases
elementor / vendor / elementor / wp-notifications-package / src / V120 / Notifications.php

Notifications.php in Elementor Website Builder – more than just a page builder 4.3.3, at vendor/elementor/wp-notifications-package/src/V120/Notifications.php

253 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\WPNotificationsPackage\V120;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 class Notifications {
9
10 const PACKAGE_VERSION = '1.2.0';
11
12 private string $app_name;
13
14 private string $app_version;
15
16 private string $short_app_name;
17
18 private string $transient_key;
19
20 private array $app_data = [];
21
22 private string $api_endpoint = 'https://my.elementor.com/api/v1/notifications';
23
24 public function __construct( array $config ) {
25 $this->app_name = sanitize_title( $config['app_name'] );
26 $this->app_version = $config['app_version'];
27 $this->short_app_name = $config['short_app_name'] ?? 'plugin';
28
29 $this->app_data = $config['app_data'] ?? [];
30
31 $this->transient_key = "_{$this->app_name}_notifications";
32
33 add_action( 'admin_init', [ $this, 'refresh_notifications' ] );
34 add_filter( 'body_class', [ $this, 'add_body_class' ] );
35
36 if ( ! empty( $this->app_data['plugin_basename'] ) ) {
37 register_deactivation_hook( $this->app_data['plugin_basename'], [ $this, 'on_plugin_deactivated' ] );
38 }
39
40 if ( ! empty( $this->app_data['theme_name'] ) ) {
41 add_action( 'switch_theme', [ $this, 'on_theme_deactivated' ], 10, 3 );
42 }
43 }
44
45 public function refresh_notifications(): void {
46 $this->get_notifications();
47 }
48
49 public function add_body_class( array $classes ): array {
50 $classes[] = $this->short_app_name . '-default';
51
52 return $classes;
53 }
54
55 public function get_notifications_by_conditions( $force_request = false ) {
56 $notifications = $this->get_notifications( $force_request );
57
58 $filtered_notifications = [];
59
60 foreach ( $notifications as $notification ) {
61 if ( empty( $notification['conditions'] ) ) {
62 $filtered_notifications = $this->add_to_array( $filtered_notifications, $notification );
63
64 continue;
65 }
66
67 if ( ! $this->check_conditions( $notification['conditions'] ) ) {
68 continue;
69 }
70
71 $filtered_notifications = $this->add_to_array( $filtered_notifications, $notification );
72 }
73
74 return $filtered_notifications;
75 }
76
77 private function get_notifications( $force_update = false, $additional_status = false ): array {
78 $notifications = static::get_transient( $this->transient_key );
79
80 if ( false === $notifications || $force_update ) {
81 $notifications = $this->fetch_data( $additional_status );
82 static::set_transient( $this->transient_key, $notifications );
83 }
84
85 return $notifications;
86 }
87
88 private function add_to_array( $filtered_notifications, $notification ) {
89 foreach ( $filtered_notifications as $filtered_notification ) {
90 if ( $filtered_notification['id'] === $notification['id'] ) {
91 return $filtered_notifications;
92 }
93 }
94
95 $filtered_notifications[] = $notification;
96
97 return $filtered_notifications;
98 }
99
100 private function check_conditions( $groups ): bool {
101 foreach ( $groups as $group ) {
102 if ( $this->check_group( $group ) ) {
103 return true;
104 }
105 }
106
107 return false;
108 }
109
110 private function check_group( $group ) {
111 $is_or_relation = ! empty( $group['relation'] ) && 'OR' === $group['relation'];
112 unset( $group['relation'] );
113 $result = false;
114
115 foreach ( $group as $condition ) {
116 // Reset results for each condition.
117 $result = false;
118 switch ( $condition['type'] ) {
119 case 'wordpress': // phpcs:ignore WordPress.WP.CapitalPDangit
120 // include an unmodified $wp_version
121 include ABSPATH . WPINC . '/version.php';
122 $result = version_compare( $wp_version, $condition['version'], $condition['operator'] );
123 break;
124 case 'multisite':
125 $result = is_multisite() === $condition['multisite'];
126 break;
127 case 'language':
128 $in_array = in_array( get_locale(), $condition['languages'], true );
129 $result = 'in' === $condition['operator'] ? $in_array : ! $in_array;
130 break;
131 case 'plugin':
132 if ( ! function_exists( 'is_plugin_active' ) ) {
133 require_once ABSPATH . 'wp-admin/includes/plugin.php';
134 }
135
136 $is_plugin_active = is_plugin_active( $condition['plugin'] );
137
138 if ( empty( $condition['operator'] ) ) {
139 $condition['operator'] = '==';
140 }
141
142 $result = '==' === $condition['operator'] ? $is_plugin_active : ! $is_plugin_active;
143 break;
144 case 'theme':
145 $theme = wp_get_theme();
146 if ( wp_get_theme()->parent() ) {
147 $theme = wp_get_theme()->parent();
148 }
149
150 if ( $theme->get_template() === $condition['theme'] ) {
151 $version = $theme->version;
152 } else {
153 $version = '';
154 }
155
156 $result = version_compare( $version, $condition['version'], $condition['operator'] );
157 break;
158
159 default:
160 $result = apply_filters( "$this->app_name/notifications/condition/{$condition['type']}", $result, $condition );
161 break;
162 }
163
164 if ( ( $is_or_relation && $result ) || ( ! $is_or_relation && ! $result ) ) {
165 return $result;
166 }
167 }
168
169 return $result;
170 }
171
172 private function fetch_data( $additional_status = false ): array {
173 $body_request = [
174 'api_version' => self::PACKAGE_VERSION,
175 'app_name' => $this->app_name,
176 'app_version' => $this->app_version,
177 'site_lang' => get_bloginfo( 'language' ),
178 'site_key' => $this->get_site_key(),
179 ];
180
181 $timeout = 10;
182
183 if ( ! empty( $additional_status ) ) {
184 $body_request['status'] = $additional_status;
185 $timeout = 3;
186 }
187
188 $response = wp_remote_get(
189 $this->api_endpoint,
190 [
191 'timeout' => $timeout,
192 'body' => $body_request,
193 ]
194 );
195
196 if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
197 return [];
198 }
199
200 $data = \json_decode( wp_remote_retrieve_body( $response ), true );
201
202 if ( empty( $data['notifications'] ) || ! is_array( $data['notifications'] ) ) {
203 return [];
204 }
205
206 return $data['notifications'];
207 }
208
209 private function get_site_key() {
210 $site_key = get_option( 'elementor_connect_site_key' );
211
212 if ( ! $site_key ) {
213 $site_key = md5( uniqid( wp_generate_password() ) );
214 update_option( 'elementor_connect_site_key', $site_key );
215 }
216
217 return $site_key;
218 }
219
220 private static function get_transient( $cache_key ) {
221 $cache = get_option( $cache_key );
222
223 if ( empty( $cache['timeout'] ) ) {
224 return false;
225 }
226
227 if ( time() > $cache['timeout'] ) {
228 return false;
229 }
230
231 return json_decode( $cache['value'], true );
232 }
233
234 private static function set_transient( $cache_key, $value, $expiration = '+12 hours' ) {
235 $data = [
236 'timeout' => strtotime( $expiration, time() ),
237 'value' => wp_json_encode( $value ),
238 ];
239
240 return update_option( $cache_key, $data, false );
241 }
242
243 public function on_plugin_deactivated(): void {
244 $this->get_notifications( true, 'deactivated' );
245 }
246
247 public function on_theme_deactivated( string $new_name, \WP_Theme $new_theme, \WP_Theme $old_theme ): void {
248 if ( $old_theme->get_template() === $this->app_data['theme_name'] ) {
249 $this->get_notifications( true, 'deactivated' );
250 }
251 }
252 }
253