PluginProbe ʕ •ᴥ•ʔ
Atarim – Visual Feedback, Review & AI Collaboration / trunk
Atarim – Visual Feedback, Review & AI Collaboration vtrunk
trunk 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.2.0 3.2.1 3.22 3.22.1 3.22.2 3.22.3 3.22.4 3.22.5 3.22.6 3.3.0 3.3.1 3.3.2 3.3.2.1 3.3.2.2 3.3.3 3.30 3.31 3.32 3.4 3.4.1 3.4.3 3.4.4 3.5 3.5.1 3.6 3.6.1 3.7 3.8 3.9 3.9.1 3.9.2 3.9.3 3.9.4 3.9.6 3.9.6.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.2 4.2.1 4.2.2 4.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.4
atarim-visual-collaboration / includes / class-functions.php
atarim-visual-collaboration / includes Last commit date
class-ajax-functions.php 4 months ago class-define-constant.php 2 months ago class-functions.php 3 months ago do-it.php 2 months ago inject-script.php 3 months ago
class-functions.php
382 lines
1 <?php
2 if (! defined('ABSPATH')) {
3 exit; // Exit if accessed directly
4 }
5
6 class AVCF_Functions {
7
8 public function __construct() {}
9
10 // function is used to get site settings data by key
11 Public function avcf_get_setting_data($key, $default = '') {
12 return get_option($key, $default);
13 }
14
15 Public function avcf_update_settings($key, $value) {
16 update_option( $key, $value, false );
17 }
18
19 public function avcf_setting_screen() {
20 if (is_admin()) {
21 $wpf_current_screen = get_current_screen();
22 if ($wpf_current_screen->id == 'settings_page_atarim-visual-collaboration') {
23 return true;
24 }
25 }
26 return false;
27 }
28
29 public function avcf_make_api_call($url, $data, $apikey = '', $token = '', $method = 'POST', $is_print = false) {
30 $header = array(
31 'Content-Type' => 'application/json; charset=utf-8',
32 'Accept' => 'application/json',
33 'response-signature' => '',
34 );
35
36 if ($apikey != '') {
37 $header['api-key'] = $apikey;
38 }
39
40 if ($token != '') {
41 $header['Authorization'] = 'Bearer ' . $token;
42 }
43
44 $args = array(
45 'headers' => $header,
46 'timeout' => 100,
47 );
48
49 $response = null;
50
51 switch ($method) {
52 case 'POST':
53 $args['body'] = is_array($data) ? wp_json_encode($data) : $data;
54 $response = wp_remote_post($url, $args);
55 break;
56
57 case 'GET':
58 if (is_array($data) && ! empty($data)) {
59 $url = add_query_arg($data, $url);
60 $response = wp_remote_get($url, $args);
61 } else {
62 $response = wp_remote_get($url, $args);
63 }
64 break;
65
66 default:
67 return array(
68 'error' => true,
69 'message' => "Unsupported HTTP method: $method",
70 );
71 }
72
73
74 if($is_print) {
75 return $response;
76 }
77
78 if (is_wp_error($response)) {
79 return array(
80 'status_code' => 500,
81 'message' => $response->get_error_message(),
82 );
83 }
84
85 $status_code = wp_remote_retrieve_response_code($response);
86 if ($status_code === 200) {
87 $body = wp_remote_retrieve_body($response);
88 $content_type = wp_remote_retrieve_header($response, 'content-type');
89
90 if (strpos($content_type, 'application/json') !== false) {
91 return array(
92 'status_code' => $status_code,
93 'data' => json_decode($body, true),
94 );
95 }
96
97 return array(
98 'status_code' => $status_code,
99 'data' => $body,
100 );
101 } else {
102 return array(
103 'status_code' => $status_code,
104 'error' => json_decode(wp_remote_retrieve_body($response), true),
105 );
106 }
107 }
108
109 public function avcf_validate_nonce() {
110 if (! isset($_POST['avc_nonce']) ||
111 ! wp_verify_nonce(
112 sanitize_text_field(wp_unslash($_POST['avc_nonce'])),
113 'avc-script-nonce'
114 )
115 ) {
116 return false;
117 }
118
119 return true;
120 }
121
122 public function avcf_user_consent_form() {
123 $logo = $this->avcf_get_setting_data('avc_collab_logo');
124 if ($logo == '') {
125 $logo = AVCF_PLUGIN_URL . 'images/logo.svg';
126 }
127
128 $currentpageurl = $this->get_current_page_url();
129 $screenshot = $this->avcf_image_exists_checker('https://api.urlbox.io/v1/N2okA12ymiQKeGym/png?url=' . $currentpageurl, AVCF_PLUGIN_URL . 'images/placeholderr.png');
130
131 $consent_modal = "<div class='avc_user_consent_container'>
132 <div class='avc_user_consent_wrapper'>
133 <div class='avc_user_consent_modal'>
134 <div class='avc_start_collab_modal'>
135 <img src='" . $logo . "' class='avc_user_consent_logo'>
136 <div class='avc_user_consent_title'>Dive Into Real-Time Collaboration</div>
137 <div class='avc_user_consent_button'>
138 <img src='" . AVCF_PLUGIN_URL . 'images/loader-2.svg' . "' class='avc_consent_loader'>
139 <img src='" . AVCF_PLUGIN_URL . 'images/wordpress-alt.svg' . "' class='avc_user_consent_button_img'>
140 <span class='avc_user_consent_button_text'>Connect Your WordPress Account</span>
141 </div>
142 <div class='avc_user_consent_terms'>By clicking this button, you agree to our <a href='https://atarim.io/terms-and-conditions/' target='_blank'>terms & conditions</a></div>
143 </div>
144 <div class='avc_consent_meta_info'>
145 <div class='avc_user_consent_close'>&times;</div>
146 <div class='avc_consent_meta_title'>Ready To Give Your Feedback?</div>
147 <div class='avc_consent_meta_desc'>Simply click any part of the page to leave a comment and instantly notify others who are doing the work, so they can get it done fast!</div>
148 <div class='avc_consent_meta_img'>
149 <img src='" . AVCF_PLUGIN_URL . 'images/comment-overlay.png' . "' class='avc_comment_overlay'>
150 <img src='" . $screenshot . "' class='avc_current_screen'>
151 </div>
152 </div>
153 </div>
154 </div>
155 </div>";
156 return $consent_modal;
157 }
158
159 public function avcf_user_consent_modal_trigger() {
160 $favicon = $this->avcf_get_setting_data('avc_collab_favicon');
161 if ($favicon == '') {
162 $favicon = AVCF_PLUGIN_URL . 'images/atarim_icon.svg';
163 }
164
165 $trigger = '<div class="avc_consent_form_launcher">
166 <img src="'. $favicon .'" alt="poweredby">
167 </div>';
168 return $trigger;
169 }
170
171 public function avcf_image_exists_checker( $imageUrl, $alterimg ) {
172 $imageUrl = str_replace(' ', '%20', $imageUrl);
173 // Check if the URL is reachable
174 if ( $imageUrl != '' ) {
175 if ( @getimagesize( $imageUrl ) ) {
176 return $imageUrl;
177 }
178 }
179 return $alterimg;
180 }
181
182 public function avcf_get_user_detail($field) {
183 $valid_fields = ['id', 'email', 'first_name', 'last_name', 'role'];
184 if (! in_array($field, $valid_fields, true)) {
185 return new WP_Error('invalid_key', 'The provided key is not valid. Allowed keys are: ' . implode(', ', $valid_fields) . '.');
186 }
187
188 if (! is_user_logged_in()) {
189 return new WP_Error('not_logged_in', 'You must be logged in to retrieve user details.');
190 }
191
192 $current_user = wp_get_current_user();
193 switch ($field) {
194 case 'id':
195 return $current_user->ID;
196 case 'email':
197 return $current_user->user_email;
198 case 'first_name':
199 return get_user_meta($current_user->ID, 'first_name', true);
200 case 'last_name':
201 return get_user_meta($current_user->ID, 'last_name', true);
202 case 'role':
203 return !empty($current_user->roles) ? $current_user->roles[0] : null;
204 default:
205 return new WP_Error('unexpected_error', 'An unexpected error occurred.');
206 }
207 }
208 public function avcf_allowed_user_role() {
209 $selected_roles = (array)$this->avcf_get_setting_data('avc_selected_role', ['administrator', 'editor']);
210 $role = $this->avcf_get_user_detail('role');
211 if (is_wp_error($role)) {
212 return false;
213 }
214
215 return in_array($role, $selected_roles, true);
216 }
217
218 public function remove_url_parameter($url, $removeparam) {
219 // Parse the URL to get its components
220 $urlParts = parse_url($url);
221 $newUrl = '';
222
223 // If there's no query string, no need to do anything
224 if (! empty($urlParts['query'])) {
225
226 // Parse the query string to get an associative array of the parameters
227 parse_str($urlParts['query'], $queryParams);
228
229 // Remove the parameter from the query array
230 if(! empty($removeparam)) {
231 foreach($removeparam as $param) {
232 unset($queryParams[$param]);
233 }
234 }
235
236 // Rebuild the query string without the removed parameter
237 $newQueryString = http_build_query($queryParams);
238 // Rebuild the full URL without the removed parameter
239 $newUrl = $urlParts['scheme'] . '://' . $urlParts['host'] . $urlParts['path'];
240 if (! empty($newQueryString)) {
241 $newUrl .= '?' . $newQueryString;
242 }
243 } else {
244 $newUrl = $url;
245 }
246
247 return $newUrl;
248 }
249
250 public function get_collab_js($site_id, $is_setting_screen = false) {
251
252 $headless_attr = $is_setting_screen ? ' data-atarim-mode="headless"' : '';
253 return '<script defer type="module"'
254 . ' src="' . AVCF_SCRIPT_URL . '"'
255 . ' data-siteid="' . esc_attr( $site_id ) . '"'
256 . ' data-site-type="wordpress"'
257 . $headless_attr
258 . '></script>';
259 }
260
261 public function avcf_get_whitelabel() {
262 $data = [
263 'site_id' => $this->avcf_get_setting_data('avc_site_id'),
264 ];
265
266 $response = $this->avcf_make_api_call(
267 AVCF_CRM_API . 'wp-api/site/whitelabel',
268 $data,
269 '',
270 '',
271 'GET'
272 );
273
274 if ($response['status_code'] === 200 && isset($response['data']['wpfeedback_logo'])) {
275 $this->avcf_update_settings('avc_collab_logo', $response['data']['wpfeedback_logo']);
276 $this->avcf_update_settings('avc_collab_favicon', $response['data']['wpfeedback_favicon']);
277 $this->avcf_update_settings('avc_collab_color', $response['data']['wpfeedback_color']);
278 }
279 }
280
281 public function get_current_page_url() {
282 $scheme = is_ssl() ? 'https://' : 'http://';
283
284 $host = '';
285 if ( isset( $_SERVER['HTTP_HOST'] ) ) {
286 $host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) );
287 $host = preg_replace( '/[^a-zA-Z0-9\.\-:]/', '', $host );
288 }
289
290 $request_uri = '';
291 if ( isset( $_SERVER['REQUEST_URI'] ) ) {
292 $request_uri = wp_unslash( $_SERVER['REQUEST_URI'] );
293 $request_uri = preg_replace( '/[\x00-\x1F\x7F]/', '', $request_uri );
294 }
295
296 return esc_url_raw( $scheme . $host . $request_uri );
297 }
298
299 public function avcf_update_site_data() {
300 $site_id = $this->avcf_get_setting_data('wpf_site_id');
301
302 $response = $this->avcf_make_api_call(
303 AVCF_CRM_API . 'encrypt/' . $site_id,
304 '',
305 '',
306 '',
307 'GET'
308 );
309
310 if ($response['status_code'] === 200 && ! empty($response['data'])) {
311 $this->avcf_update_settings('avc_site_id', $response['data']);
312 $this->avcf_update_settings('avc_initial_setup_complete', 'yes');
313 $this->avcf_update_settings('avc_collab_active', 'yes');
314 $this->avcf_update_settings('avc_license', 'valid');
315 $this->avcf_get_whitelabel();
316 $savedRoles = $this->avcf_get_setting_data('wpf_selcted_role', '');
317 if (is_string($savedRoles) || $savedRoles != '') {
318 $roles = array_filter(array_map('trim', explode(',', $savedRoles)));
319 $this->avcf_update_settings('avc_selected_role', $roles);
320 }
321 }
322 }
323
324 public function avcf_get_site_visibility($site_id) {
325 $site_id = trim((string) $site_id);
326 if ($site_id === '') {
327 return array(
328 'status_code' => 400,
329 'data' => array('site_visibility' => null),
330 );
331 }
332
333 // Cache for 10 minutes to avoid hitting API on every page load
334 $cache_key = 'avc_site_visibility_' . md5($site_id);
335 $cached = get_transient($cache_key);
336 if ($cached !== false) {
337 return array(
338 'status_code' => 200,
339 'data' => array('site_visibility' => $cached),
340 );
341 }
342
343 $response = $this->avcf_make_api_call(
344 AVCF_CRM_API . 'site/' . rawurlencode($site_id) . '/visibility',
345 array(),
346 '',
347 '',
348 'GET'
349 );
350
351 if (
352 isset($response['status_code']) &&
353 (int) $response['status_code'] === 200 &&
354 isset($response['data']['site_visibility'])
355 ) {
356 $visibility = strtolower(trim((string) $response['data']['site_visibility']));
357 if (! in_array($visibility, array('public', 'locked', 'private'), true)) {
358 $visibility = null;
359 }
360
361 set_transient($cache_key, $visibility, 1 * MINUTE_IN_SECONDS);
362
363 $response['data']['site_visibility'] = $visibility;
364 return $response;
365 }
366
367 // Cache failures briefly too (prevents hammering if API is down)
368 set_transient($cache_key, null, 1 * MINUTE_IN_SECONDS);
369
370 return $response;
371 }
372
373 public function avcf_is_site_public($site_id) {
374 $resp = $this->avcf_get_site_visibility($site_id);
375
376 return (
377 isset($resp['status_code'], $resp['data']['site_visibility']) &&
378 (int) $resp['status_code'] === 200 &&
379 $resp['data']['site_visibility'] === 'public'
380 );
381 }
382 }