PluginProbe
WebTotem Security / 2.4.19
WebTotem Security v2.4.19
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / lib / Helper.php

Helper.php in WebTotem Security 2.4.19, at lib/Helper.php

1,728 lines 48.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('WEBTOTEM_INIT') || WEBTOTEM_INIT !== true) {
4 if (!headers_sent()) {
5 header('HTTP/1.1 403 Forbidden');
6 }
7 exit(1);
8 }
9
10 /**
11 * WebTotem Base class for Wordpress.
12 */
13 class WebTotem {
14
15 /**
16 * Returns an URL from the admin dashboard.
17 *
18 * @param string $url
19 * Optional trailing of the URL.
20 * @return string
21 * Full valid URL from the admin dashboard.
22 */
23 public static function adminURL($url = '') {
24 if (self::isMultiSite() and is_super_admin()) {
25 return network_admin_url($url);
26 }
27 return admin_url($url);
28 }
29
30 /**
31 * Define role of current user.
32 *
33 */
34 public static function getUserRole() {
35
36 if (defined('WEBTOTEM_USER_ROLE')) {
37 return true;
38 }
39 $current_user = wp_get_current_user();
40 if ( !($current_user instanceof WP_User) ){
41 $user_role = 0;
42 } else {
43 $roles = $current_user->roles;
44
45 if(in_array('administrator', $roles)) {
46 $user_role = 1;
47 } elseif(in_array('editor', $roles)) {
48 $user_role = 2;
49 } else {
50 $user_role = 0;
51 }
52 }
53
54 define( 'WEBTOTEM_USER_ROLE', $user_role );
55
56 return true;
57 }
58
59 /**
60 * Check whether the current site is working as a multi-site instance.
61 *
62 * @return bool
63 * Either TRUE or FALSE in case WordPress is being used as a multi-site instance.
64 */
65 public static function isMultiSite() {
66 return (bool) ( (function_exists('is_multisite') && is_multisite()) || (defined('MULTISITE') && MULTISITE == true) );
67 }
68
69 /**
70 * Returns the md5 hash representing the content of a file.
71 *
72 * @param string $file
73 * Relative path to the file.
74 * @return string
75 * Seven first characters in the hash of the file.
76 */
77 public static function fileVersion($file = '') {
78 return substr(md5_file(WEBTOTEM_PLUGIN_PATH . '/' . $file), 0, 7);
79 }
80
81 /**
82 * Returns full path to image.
83 *
84 * @param string $image
85 * Relative path to the file.
86 * @return string
87 * Full path to image.
88 */
89 public static function getImagePath($image) {
90 return WEBTOTEM_URL. '/includes/img/' . $image;
91 }
92
93 /**
94 * Convert object to array.
95 *
96 * @param array $data
97 * Array.
98 * @return array
99 * Returns array.
100 */
101 public static function convertObjectToArray($data) {
102
103 if(!is_array($data)) $data = (array)$data;
104 array_walk_recursive($data, function(&$item){
105 if(is_object($item)) $item = (array)$item;
106 });
107
108 return $data;
109 }
110
111 /**
112 * Returns user IP address.
113 *
114 * @return string
115 * Returns user IP address.
116 */
117 public static function getUserIP() {
118 $arr = [
119 'HTTP_CLIENT_IP',
120 'HTTP_X_FORWARDED_FOR',
121 'HTTP_X_FORWARDED',
122 'HTTP_X_CLUSTER_CLIENT_IP',
123 'HTTP_FORWARDED_FOR',
124 'HTTP_FORWARDED',
125 'HTTP_CF_CONNECTING_IP',
126 'REMOTE_ADDR'
127 ];
128
129 foreach ($arr as $key){
130 if (array_key_exists($key, $_SERVER) === true) {
131 foreach (explode(',', $_SERVER[$key]) as $ip) {
132 $ip = trim($ip);
133 $ip = filter_var($ip, FILTER_VALIDATE_IP);
134 if (!empty($ip)) {
135 return $ip;
136 }
137 }
138 }
139 }
140 return false;
141 }
142
143 /**
144 * Convert the file size to а human-readable format.
145 *
146 * @param string $bytes
147 * File size in bytes.
148 * @param string $decimals
149 * The number of characters after the decimal point.
150 *
151 * @return string
152 * Returns the file size in a human-readable format.
153 */
154 public static function humanFilesize($bytes, $decimals = 2) {
155 $factor = floor((strlen($bytes) - 1) / 3);
156 $unit_of_measurement = ($factor > 0) ? substr("KMGT", $factor - 1, 1) : '';
157 return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . $unit_of_measurement . 'B';
158 }
159
160 /**
161 * Check whether the file is publicly accessible.
162 *
163 * @param string $url
164 * http link to the file.
165 * @param string $path
166 * The path to the file.
167 *
168 * @return bool
169 */
170 public static function isPubliclyAccessible($url, $path) {
171 $response = wp_remote_get($url);
172
173 if ((int) floor(((int) wp_remote_retrieve_response_code($response) / 100)) === 2) {
174 $handle = @fopen($path, 'r');
175 if ($handle) {
176 $contents = fread($handle, 700);
177 fclose($handle);
178 $remoteContents = substr(wp_remote_retrieve_body($response), 0, 700);
179
180 return $contents === $remoteContents;
181 }
182 }
183 return false;
184 }
185
186 /**
187 * Check that the training period has passed for the firewall.
188 *
189 * @param string $created_at
190 * Date when the waf configuration was created.
191 *
192 * @return bool
193 * Returns boolean.
194 */
195 public static function isWafTraining($created_at) {
196 if($created_at) {
197 $when_waf_trained = strtotime('+2 day', strtotime($created_at));
198 $today = strtotime('today');
199
200 return ($when_waf_trained < $today) ? FALSE : TRUE;
201 }
202 return FALSE;
203 }
204
205 /**
206 * Check if the data for the period is available.
207 *
208 * @param string $created_at
209 * Date when the agent manager was created.
210 *
211 * @return array
212 * Returns an array with periods.
213 */
214 public static function isPeriodAvailable($created_at) {
215
216 $diff = strtotime(gmdate("Y-m-d H:i:s")) - strtotime($created_at);
217 $daysCount = floor($diff / 86400);
218
219 return [
220 'monthly' => $daysCount > 7,
221 'yearly' => $daysCount > 30,
222 ];
223
224 }
225
226
227
228 /**
229 * Converting a date to the appropriate format.
230 *
231 * @param string $date
232 * Date in any format.
233 * @param string $format
234 * The format to which you want to convert the date.
235 *
236 * @return string
237 * Returns converted Date.
238 */
239 public static function dateFormatter($date, $format = 'M j, Y \/ H:i') {
240 if (!$date) {
241 return __('Unknown', 'wtotem');
242 }
243
244 $time_zone = WebTotemOption::getOption('time_zone_offset');
245 $user_time = ($time_zone) ? strtotime($time_zone . 'hours', strtotime($date)) : strtotime($date);
246
247 return date_i18n($format, $user_time);
248 }
249
250 /**
251 * Get theme mode data.
252 *
253 * @return array
254 * Returns array with current theme data.
255 */
256 public static function getThemeMode() {
257 $theme_mode = WebTotemOption::getSessionOption('theme_mode');
258 return [
259 "is_dark_mode" => $theme_mode == 'dark' ? 'wtotem_theme—dark' : '',
260 "dark_mode_checked" => $theme_mode == 'dark' ? 'checked' : '',
261 ];
262 }
263
264 /**
265 * Get current user language.
266 *
267 * @return string
268 * Returns current language in 2-letter abbreviations
269 */
270 public static function getLanguage() {
271 $current_language = substr(get_bloginfo('language'), 0,2);
272 $language = (in_array($current_language,['ru','en','pl'])) ? $current_language : 'en' ;
273 return $language;
274 }
275
276 /**
277 * Converting a date to the appropriate format.
278 *
279 * @param string|array $days
280 * Number of days or period to convert.
281 *
282 * @return array
283 * Returns an array of two values "from" and "to"
284 */
285 public static function getPeriod($days) {
286
287 if (!$days) {
288 $days = 30;
289 }
290
291 switch ($days) {
292
293 case is_array($days):
294 $to = $days[1] ?: $days[0];
295 $period = [
296 'from' => strtotime(date('Y-m-d 00:00:01', strtotime($days[0]))),
297 'to' => strtotime(date('Y-m-d 23:59:59', strtotime($to))),
298 ];
299 break;
300
301 case $days <= 1:
302 $period = [
303 'from' => strtotime('-24 hours'),
304 'to' => time(),
305 ];
306 break;
307
308 default:
309 $period = [
310 'from' => time() - ($days * 86400),
311 'to' => time(),
312 ];
313 }
314
315 return $period;
316 }
317
318 /**
319 * Convert an array to a string with quotation marks.
320 *
321 * @param array $array
322 * Data array.
323 *
324 * @return string
325 * Array of data converted to string.
326 */
327 public static function convertArrayToString($array) {
328 if(empty($array)){
329 return '';
330 }
331 return '"' . implode('","', $array) . '"';
332 }
333
334 /**
335 * Converting the response to a readable form.
336 *
337 * @param string $message
338 * Message response from the API server to the request.
339 *
340 * @return string|bool
341 * Returns a message.
342 */
343 public static function messageForHuman($message) {
344
345 $definition = $message;
346
347 switch ($message) {
348 case 'HOSTS_LIMIT_EXCEEDED':
349 $definition = __('Limit of adding sites exceeded.', 'wtotem');
350 break;
351
352 case 'USER_ALREADY_REGISTERED':
353 $definition = __('A user with this email already exists.', 'wtotem');
354 break;
355
356 case 'DUPLICATE_HOST':
357 $definition = __('Duplicate host', 'wtotem');
358 break;
359
360 case 'INVALID_DOMAIN_NAME':
361 $definition = __('Invalid Domain Name', 'wtotem');
362 break;
363 default:
364 $definition = str_replace("_", " ", $definition);
365 $definition = ucfirst(strtolower($definition));
366
367 }
368 return $definition;
369 }
370
371 /**
372 * Get the data associated with the status.
373 *
374 * @param string $status
375 * Module or agent status.
376 *
377 * @return array
378 * Returns an array with status data.
379 */
380 public static function getStatusData($status) {
381 $path = self::getImagePath('');
382 $status = ($status == "installed") ? 'working' : $status;
383
384 switch ($status) {
385
386 case 'clean':
387 case 'up':
388 case 'installed':
389 case 'working':
390 $status_data = [
391 'class' => 'is--status--ok',
392 'image' => $path . 'check-mark.svg',
393 'icon' => $path . 'icon_success_status.svg',
394 ];
395 break;
396
397 case 'pending':
398 $status_data = [
399 'class' => 'is--status--pending',
400 'image' => $path . 'loading.svg',
401 'icon' => $path . 'alert-warning.svg',
402 ];
403 break;
404
405 case 'pause':
406 case 'modified':
407 $status_data = [
408 'class' => 'is--status--pending',
409 'image' => $path . 'warning.svg',
410 'icon' => $path . 'alert-warning.svg',
411 ];
412 break;
413
414 case 'expired':
415 case 'no_cert':
416 case 'expires':
417 case 'open_ports':
418 case 'not_supported':
419 case 'not_registered':
420 $status_data = [
421 'class' => 'is--status--warning',
422 'image' => $path . 'warning.svg',
423 'icon' => $path . 'alert-warning.svg',
424 ];
425 break;
426
427 case 'invalid':
428 case 'error':
429 case 'down':
430 case 'expires_today':
431 case 'infected':
432 case 'deface':
433 case 'not_installed':
434 $status_data = [
435 'class' => 'is--status--error',
436 'image' => $path . 'warning.svg',
437 'icon' => $path . 'alert-warning.svg',
438 ];
439 break;
440
441 default:
442 $status_data = [
443 'class' => 'is--status--pending',
444 'image' => $path . 'warning.svg',
445 'icon' => $path . 'alert-warning.svg',
446 ];
447 }
448 $status_data['name'] = $status;
449 $status_data['text'] = self::getStatusText($status);
450 $status_data['tooltips'] = self::getTooltips($status);
451
452 return $status_data;
453 }
454
455 /**
456 * Get a readable status text.
457 *
458 * @param string $status
459 * Module or agent status.
460 *
461 * @return string
462 * Returns the status text in the current language.
463 */
464 public static function getStatusText($status) {
465 $statuses = [
466 'warning' => __('Warning', 'wtotem'),
467 'error' => __('Error', 'wtotem'),
468 'success' => __('Success', 'wtotem'),
469 'info' => __('Info', 'wtotem'),
470 'invalid' => __('Invalid', 'wtotem'),
471 'ok' => __('Everything is OK', 'wtotem'),
472 'expired' => __('Expired', 'wtotem'),
473 'expires' => __('Expires', 'wtotem'),
474 'expires_today' => __('Expires today', 'wtotem'),
475 'missing' => __('Missing', 'wtotem'),
476 'active' => __('Active', 'wtotem'),
477 'inactive' => __('Inactive', 'wtotem'),
478 'pending' => __('Pending', 'wtotem'),
479 'pause' => __('Disabled', 'wtotem'),
480 'available' => __('Available', 'wtotem'),
481 'not_supported' => __('Not supported', 'wtotem'),
482 'not_registered' => __('Not registered', 'wtotem'),
483 'unsupported' => __('Unsupported', 'wtotem'),
484 'clean' => __('Clean', 'wtotem'),
485 'clear' => __('Clear', 'wtotem'),
486 'blacklisted' => __('Infected', 'wtotem'),
487 'miner_detected' => __('Infected', 'wtotem'),
488 'deface' => __('Deface', 'wtotem'),
489 'modified' => __('Modified', 'wtotem'),
490 'detected' => __('Detected', 'wtotem'),
491 'open_ports' => __('Open ports', 'wtotem'),
492 'blocked' => __('Blocked', 'wtotem'),
493 'connected' => __('Connected', 'wtotem'),
494 'attacks_detected' => __('Attacks detected', 'wtotem'),
495 'signature_found' => __('Signature found', 'wtotem'),
496 'file_changes' => __('File changes', 'wtotem'),
497 'no_cert' => __('No cert', 'wtotem'),
498 'down' => __('Down', 'wtotem'),
499 'up' => __('Up', 'wtotem'),
500 'infected' => __('Infected', 'wtotem'),
501 'not_installed' => __('Need to install', 'wtotem'),
502 'agent_not_available' => __('Agent not available', 'wtotem'),
503 'update_error' => __('Update error', 'wtotem'),
504 'session_error' => __('Session Error', 'wtotem'),
505 'internal_error' => __('Internal Error', 'wtotem'),
506 'installing' => __('Installing', 'wtotem'),
507 'installed' => __('Installed', 'wtotem'),
508 'working' => __('Working', 'wtotem'),
509 "critical" => __('Critical', 'wtotem'),
510 "deleted" => __('Deleted', 'wtotem'),
511 "changed" => __('Changed', 'wtotem'),
512 "new" => __('New', 'wtotem'),
513 "scanned" => __('Scanned', 'wtotem'),
514 "quarantine" => __('In quarantine', 'wtotem'),
515 ];
516
517 return (array_key_exists($status, $statuses)) ? $statuses[$status] : $status;
518 }
519
520 /**
521 * Get tooltips text for status.
522 *
523 * @param string $status
524 * Module or agent status.
525 *
526 * @return string
527 * Returns the status tooltip in the current language.
528 */
529 public static function getTooltips($status) {
530 $tooltips = [
531 'invalid' => __('Invalid -The certificate is invalid. Please, make sure that relevant certificate details filled correctly.', 'wtotem'),
532 'expired' => __('Expired - The certificate has expired. Connection is not secure. Please, renew it.', 'wtotem'),
533 'expires' => __('Expires - The certificate expires soon. Please, take actions.', 'wtotem'),
534 'expires_today' => __('Expires today - The certificate expires today. Please, take actions.', 'wtotem'),
535 'error' => __("Error - Something went wrong. Please, contact us, we'll fix the problem.", 'wtotem'),
536 'pending' => __('Pending - System processes your website. Data will be available soon.', 'wtotem'),
537 'pause' => __('Pause - The module is paused.', 'wtotem'),
538 'clean' => __('Everything is OK - Nothing to worry about. Everything is alright.', 'wtotem'),
539 'deface' => __("Deface - Website hacked. Please, contact us, we'll fix the problem.", 'wtotem'),
540 'open_ports' => __('Open ports - Open ports detected. Your website is vulnerable to attacks.', 'wtotem'),
541 'blocked' => __('Blocked - The module is blocked due to billing issues.', 'wtotem'),
542 'no_cert' => __("No cert - You don't have SSL certificate. We recommend you to install it for security concerns.", 'wtotem'),
543 'down' => __('Down - The website is not available for visitors.', 'wtotem'),
544 'up' => __('Up - The website is available for visitors.', 'wtotem'),
545 'infected' => __('Infected - The website site is blacklisted and may have infected files. Please, check antivirus module.', 'wtotem'),
546 'installing' => __('It means that the agent installation is in progress. Usually, it takes up to one hour.', 'wtotem'),
547 'agent_not_available' => __('We cannot locate the agent right now.', 'wtotem'),
548 'update_error' => __('It seems that your agent failed to update due to permissions restrictions.', 'wtotem'),
549 'session_error' => __('This means that the agent did not create a secure session. Possible causes include network issues, wrong server configuration, third-party firewalls. Please contact our support..', 'wtotem'),
550 'internal_error' => __('It means that the server is overloaded or there might be some problems with the connection. Usually, the issue resolves itself within 10-15 minutes. If the status does not change during two hours, please cordially contact our support..', 'wtotem'),
551 'working' => __('Everything is alright.', 'wtotem'),
552 'installed' => __('Everything is alright.', 'wtotem'),
553 'not_installed' => __('You need to install agent manager to activate antivirus and firewall.', 'wtotem'),
554 ];
555
556 return (array_key_exists($status, $tooltips)) ? $tooltips[$status] : '';
557 }
558
559 /**
560 * Converting site data.
561 *
562 * @param array $data
563 * Sites data from WebTotem.
564 *
565 * @return array
566 * Converted data.
567 */
568 public static function allSitesData($data) {
569
570 $local_sites = get_sites();
571 $main_host = WebTotemOption::getMainHost();
572 $domains = [];
573
574 foreach ($local_sites as $site){
575 $domain = untrailingslashit($site->domain . $site->path);
576 $domains[$domain] = $domain;
577 }
578
579 $sites = [];
580 if(array_key_exists('edges', $data)){
581 foreach ($data['edges'] as $site) {
582 $site = $site['node'];
583 // Take sites only from the multisite network.
584 if(array_key_exists($site['hostname'], $domains)) {
585 unset($domains[$site['hostname']]);
586 $sites[] = [
587 'hostname' => $site['hostname'],
588 'title' => $site['title'],
589 'main_host' => $main_host['id'] == $site['id'],
590 'host_id' => $site['id'],
591 'url' => admin_url('admin.php?page=wtotem_dashboard&hid=' . $site['id']),
592 'firewall' => [
593 'status' => self::getStatusData($site['firewall']['status']),
594 ],
595 'antivirus' => [
596 'status' => self::getStatusData($site['antivirus']['status']),
597 ],
598 'stacks' => self::getStacksData($site['maliciousScript']['stack']),
599 'services' => self::getSiteServicesData($site),
600 ];
601 }
602 }
603
604 }
605 return $sites;
606 }
607
608 /**
609 * Converting stacks data.
610 *
611 * @param array $stacks
612 * Stacks data from WebTotem.
613 *
614 * @return array
615 * Converted data.
616 */
617 protected static function getStacksData($stacks) {
618 $apps = file_get_contents(WEBTOTEM_PLUGIN_PATH . '/includes/js/apps.json');
619 $apps = json_decode($apps, true);
620
621 $path = 'https://assets.wtotem.net/images/apps/';
622 $defaultIcon = WEBTOTEM_URL . '/includes/img/defaultTechnologiesIcon.svg';
623
624 $stackList = array_slice($stacks, 0,3);
625 $list = [];
626 foreach ($stackList as $key => $stack){
627 $list[$key] = [
628 'name' => $stack['name'],
629 'icon' => $path . ($apps[$stack['name']]['icon'] ?: $defaultIcon),
630 ];
631 }
632
633 if(count($stacks) <= 3){
634 $other['count'] = 0;
635 $other['names'] = [];
636 } else {
637 $otherStacks = array_slice($stacks, 3);
638 $other['count'] = count($otherStacks);
639 foreach ($otherStacks as $stack){
640 $other['names'][] = $stack['name'];
641 }
642 }
643 if($other['names']){
644 $other['names'] = implode(",", $other['names']);
645 }
646 return ['list' => $list, 'other' => $other];
647 }
648
649 /**
650 * Converting services data.
651 *
652 * @param $data
653 * Site data from WebTotem.
654 *
655 * @return array
656 * Converted data.
657 */
658 protected static function getSiteServicesData($data) {
659
660 $services = [
661 'ssl' => 'ssl',
662 'availability' => 'wa',
663 'reputation' => 'rc',
664 'ports' => 'ps',
665 'deface' => 'dc',
666 'domain' => 'dec',
667 ];
668
669 $list = [];
670 $other['count'] = 0;
671 $other['names'] = [];
672
673 foreach ($services as $key => $service){
674 if(array_key_exists($key, $data) and is_array($data[$key]) and array_key_exists('status', $data[$key])){
675 $status = self::getServiceStatus($data[$key]['status']);
676
677 if(in_array($status['color'], ['red', 'yellow'])){
678 if(count($list) < 2){
679 $color = $status['color'] == 'red' ? 'white/' : '';
680
681 $list[$key] = [
682 'status' => $status,
683 'icon' => 'services/'. $color . $service . '.svg',
684 'name' => self::getServiceName( $service ),
685 ];
686 } else {
687 $other['names'][] = self::getServiceName( $service );
688 $other['count']++;
689 }
690 }
691
692 }
693 }
694 if($other['names']){
695 $other['names'] = implode(",", $other['names']);
696 }
697 return ['list' => $list, 'other' => $other];
698 }
699
700 /**
701 * Get the data associated with the status.
702 *
703 * @param string $status
704 * Module or agent status.
705 *
706 * @return array
707 * Returns an array with status data.
708 */
709 public static function getServiceStatus($status) {
710 switch ($status) {
711
712 case 'expired':
713 case 'invalid':
714 case 'error':
715 case 'expires_today':
716 case 'down':
717 case 'infected':
718 case 'deface':
719 case 'not_installed':
720 case 'quarantine':
721 $status_data = [
722 'color' => 'red',
723 ];
724 break;
725
726 case 'no_cert':
727 case 'expires':
728 case 'open_ports':
729 case 'modified':
730 case 'not_supported':
731 case 'not_registered':
732 case 'blocked':
733 case 'pause':
734 case 'internal_error':
735 case 'update_error':
736 case 'config_error':
737 case 'agent_not_available':
738 case 'session_error':
739 $status_data = [
740 'color' => 'yellow',
741 ];
742 break;
743
744 case 'clean':
745 case 'installed':
746 case 'up':
747 case 'scanned':
748 case 'working':
749 $status_data = [
750 'color' => 'green',
751 ];
752 break;
753
754 case 'deleted':
755 $status_data = [
756 'color' => 'black',
757 ];
758 break;
759
760 case 'installing':
761 case 'pending':
762 default:
763 $status_data = [
764 'color' => 'gray',
765 ];
766 break;
767
768 }
769
770 return $status_data;
771 }
772
773 /**
774 * Get the translation of service.
775 *
776 * @param $service
777 * Service short name.
778 *
779 * @return string
780 * Translation of service.
781 */
782 public static function getServiceName($service){
783 $services = [
784 "wa" => __('Availability', 'wtotem'),
785 "rc" => __('Reputation', 'wtotem'),
786 "ssl" => 'SSL',
787 "cms" => __('Technologies', 'wtotem'),
788 "dc" => __('Deface', 'wtotem'),
789 "ps" => __('Ports', 'wtotem'),
790 "waf" => __('Firewall', 'wtotem'),
791 "av" => __('Antivirus', 'wtotem'),
792 "dec" => __('Domain', 'wtotem'),
793 ];
794 return $services[$service];
795 }
796
797 /**
798 * Get reports with modules list.
799 *
800 * @param array $edges
801 * Data on generated reports.
802 *
803 * @return array
804 * Returns an array with converted data.
805 */
806 public static function getReports(array $edges) {
807 $modulesLang = [
808 'wa' => __('Availability log', 'wtotem'),
809 'dc' => __('Deface log', 'wtotem'),
810 'ps' => __('Port log', 'wtotem'),
811 'rc' => __('Reputation log', 'wtotem'),
812 'sc' => __('Evaluation log', 'wtotem'),
813 'av' => __('Antivirus log', 'wtotem'),
814 'waf' => __('Firewall log', 'wtotem'),
815 ];
816
817 $reports = [];
818
819 foreach ($edges as $edge) {
820 if (in_array(FALSE, $edge["node"])) {
821 $arr = [];
822 foreach ($edge["node"] as $module => $value) {
823 if ($value == TRUE && array_key_exists($module, $modulesLang)) {
824 $arr[] = $modulesLang[$module];
825 }
826 }
827 $modules = implode(", ", $arr);
828 }
829 else {
830 $modules = __('All modules', 'wtotem');
831 }
832
833 $reports[] = [
834 'id' => $edge["node"]['id'],
835 'modules' => $modules,
836 'created_at' => self::dateFormatter($edge["node"]['createdAt']),
837 ];
838 }
839
840 return $reports;
841 }
842
843 /**
844 * Get reputation status description.
845 *
846 * @param string $status
847 * Reputation status.
848 *
849 * @return string
850 * Returns a description of the reputation status
851 */
852 public static function getReputationInfo($status) {
853 switch ($status) {
854 case 'clean':
855 $data = __("Don't worry, your reputation is good", 'wtotem');
856 break;
857
858 case 'infected':
859 $data = __('Oh, your reputation is bad', 'wtotem');
860 break;
861
862 default:
863 $data = __('Information is being updated', 'wtotem');
864 }
865 return $data;
866 }
867
868 /**
869 * Get blacklists entries counts.
870 *
871 * @param string $status
872 * Reputation status.
873 * @param array $virus_list
874 * Sources where the site can be blacklisted.
875 *
876 * @return int
877 * Number of references in blacklists.
878 */
879 public static function blacklistsEntries($status, array $virus_list) {
880 $count = 0;
881 if ($status != "clean") {
882 foreach ($virus_list as &$list) {
883 if (!empty($list['virus']['type'])) {
884 $count++;
885 }
886 }
887 }
888 return $count;
889 }
890
891 /**
892 * Classification of the rating in the letter grades.
893 *
894 * @param int $score
895 * Site rating from 1 to 100.
896 *
897 * @return array
898 * Returns an array of data.
899 */
900 public static function scoreGrading($score) {
901 if ($score < 0 || $score > 100) {
902 return ['grade' => '', 'color' => ''];
903 }
904
905 $scores = [
906 100 => 'A+',
907 90 => 'A',
908 80 => 'A-',
909 70 => 'B+',
910 60 => 'B',
911 50 => 'B-',
912 35 => 'C+',
913 20 => 'C',
914 0 => 'C-',
915 ];
916
917 foreach ($scores as $key => $value) {
918 if ($score >= $key) {
919 $grade = $value;
920 break;
921 }
922 }
923
924 // Set a color depending on the grade.
925 switch ($score) {
926 case $score >= 80:
927 $color = 'green';
928 break;
929
930 case $score >= 50:
931 $color = 'orange';
932 break;
933
934 default:
935 $color = 'red';
936 }
937
938 return ['grade' => $grade, 'color' => $color];
939 }
940
941 /**
942 * Calculate the number of remaining days.
943 *
944 * @param string $date
945 * Expiry date.
946 *
947 * @return string
948 * Returns the number of days before the expiration date.
949 */
950 public static function daysLeft($date) {
951 if ((int) $date === 0) {
952 $days_left = 0;
953 }
954 else {
955 $now = new \DateTime();
956 $expiry_date = new \DateTime();
957 $timestamp = strtotime($date);
958 $expiry_date->setTimestamp($timestamp);
959 $days_left = $expiry_date->diff($now)->format("%a");
960 }
961 return $days_left;
962 }
963
964 /**
965 * Converting the firewall logs.
966 *
967 * @param array $logs_
968 * Firewall logs from WebTotem.
969 *
970 * @return array
971 * Converted array of logs.
972 */
973 public static function wafLogs(array $logs_) {
974 $logs = [];
975 foreach ($logs_ as $key => $log) {
976 $log = $log['node'];
977
978 $logs[$key]['ip'] = $log['ip'];
979 $logs[$key]['request'] = htmlspecialchars(urldecode($log['request']));
980 $logs[$key]['time'] = self::dateFormatter($log['time']);
981 $logs[$key]['country_code'] = strtolower($log['country']);
982 $logs[$key]['country'] = $log['location']['country']['nameEn'];
983 $logs[$key]['blocked'] = $log['blocked'] ? __('Blocked IP', 'wtotem') : __('Not blocked', 'wtotem');
984
985 $more = [
986 'ip' => $log['ip'],
987 'proxy_ip' => $log['proxyIp'],
988 'source' => $log['source'],
989 'request' => htmlspecialchars(urldecode($log['request'])),
990 'user_agent' => $log['userAgent'],
991 'time' => self::dateFormatter($log['time']),
992 'type' => $log['type'],
993 'category' => $log['category'],
994 'country' => $log['location']['country']['nameEn'],
995 'payload' => htmlspecialchars(urldecode($log['payload'])),
996 ];
997
998 $logs[$key]['more'] = json_encode($more);
999 }
1000 return $logs;
1001 }
1002
1003 /**
1004 * Converting firewall data to json for a D3 chart.
1005 *
1006 * @param array $charts
1007 * Charts data from WebTotem.
1008 *
1009 * @return array
1010 * Returns the converted data for chart.
1011 */
1012 public static function generateWafChart(array $charts) {
1013 $sum = 0;
1014 foreach ($charts as $chart) {
1015 $sum += $chart['attacks'];
1016 }
1017 if ($sum == 0) {
1018 return ['chart' => FALSE, 'count_attacks' => 0, 'count_blocks' => 0];
1019 }
1020
1021 // Get days count.
1022 $charts_ = $charts;
1023 $first = array_shift($charts_);
1024 $last = array_pop($charts_);
1025 $days = ceil((strtotime($last['time']) - strtotime($first['time'])) / 86400);
1026
1027 // Set variables.
1028 $count_attacks = $count_blocks = 0;
1029
1030 foreach ($charts as $chart) {
1031 if ($days <= 1) {
1032 $time_zone = WebTotemOption::getOption('time_zone_offset');
1033 $userTime = ($time_zone) ? strtotime($time_zone . ' hours', strtotime($chart['time'])) : strtotime($chart['time']);
1034 }
1035 if (($chart['attacks'] and $days == 2) or $days != 2) {
1036 $result[] = [
1037 'date' => ($days <= 1) ? date("Y-m-d H:00:00", $userTime) : date("Y-m-d", strtotime($chart['time'])),
1038 'count' => $chart['blocked'],
1039 'attacks' => $chart['attacks'],
1040 'blocked' => $chart['blocked'],
1041 ];
1042 $count_attacks += $chart['attacks'];
1043 $count_blocks += $chart['blocked'];
1044 }
1045 }
1046
1047 if (!isset($result)) {
1048 return [
1049 'chart' => FALSE,
1050 'count_attacks' => 0,
1051 'count_blocks' => 0,
1052 'days' => 0,
1053 ];
1054 }
1055
1056 return [
1057 'chart' => json_encode($result),
1058 'count_attacks' => $count_attacks,
1059 'count_blocks' => $count_blocks,
1060 'days' => $days,
1061 ];
1062 }
1063
1064 /**
1065 * Converting data to json for a D3 chart.
1066 *
1067 * @param array $charts
1068 * Charts data from WebTotem.
1069 * @param int $days
1070 * The number of days to build the chart.
1071 *
1072 * @return bool|string
1073 * Returns the converted data for chart.
1074 */
1075 public static function generateChart(array $charts, $days = 7) {
1076 $sum = 0;
1077 foreach ($charts as $chart) {
1078 $sum += $chart['value'];
1079 }
1080 if ($sum == 0) {
1081 return FALSE;
1082 }
1083
1084 $result = [];
1085
1086 foreach ($charts as $chart) {
1087 if ($days <= 1) {
1088 $time_zone = WebTotemOption::getOption('time_zone_offset');
1089 $userTime = ($time_zone) ? strtotime($time_zone . 'hours', strtotime($chart['time'])) : strtotime($chart['time']);
1090 }
1091 $result[] = [
1092 'date' => ($days <= 1) ? date("Y-m-d H:00:00", $userTime) : date("Y-m-d", strtotime($chart['time'])),
1093 'value' => $chart['value'],
1094 ];
1095 }
1096
1097 return json_encode($result, TRUE);
1098 }
1099
1100 /**
1101 * Converting data to json for a D3 chart.
1102 *
1103 * @param array $data
1104 * Charts data from WebTotem.
1105 *
1106 * @return array|bool
1107 * Returns the converted data for chart.
1108 */
1109 public static function generateAttacksMapChart(array $data) {
1110 $attacks = [];
1111 $countries = [];
1112 $labels = [];
1113 foreach ($data as $value) {
1114 $attacks[] = $value['attacks'];
1115 $labels[] = self::getCountryName($value['country']);
1116 $countries[] = $value['location']['country']['nameEn'];
1117 }
1118 $result = ['attacks' => $attacks, 'countries' => $countries, 'labels' => $labels];
1119
1120 if (!$attacks) {
1121 return FALSE;
1122 }
1123
1124 return json_encode($result, TRUE);
1125 }
1126
1127 /**
1128 * Reassembling the antivirus logs.
1129 *
1130 * @param array $logs_
1131 * Antivirus logs from WebTotem.
1132 *
1133 * @return array
1134 * Reassembled array of logs.
1135 */
1136 public static function getAntivirusLogs(array $logs_) {
1137 $logs = [];
1138 foreach ($logs_ as $key => $log) {
1139 $log = $log['node'];
1140
1141 $file_info = new SplFileInfo(urldecode($log['filePath']));
1142
1143 $log['original_path'] = $log['filePath'];
1144 $log['file_path'] = $file_info->getPath() . '/';
1145 $log['file_name'] = $file_info->getFilename();
1146 $log['time'] = self::dateFormatter($log['time']);
1147 $log['permissions_changed'] = $log['permissionsChanged'];
1148 $log['status'] = self::getStatusData($log['event']);
1149 $log['class'] = 'wt-text--green';
1150
1151 switch ($log['event']) {
1152 case 'modified':
1153 case 'quarantine':
1154 $log['class'] = "wt-text--yellow";
1155 break;
1156
1157 case 'deleted':
1158 $log['class'] = "wt-text--light-gray";
1159 break;
1160
1161 case 'infected':
1162 $log['class'] = "wt-text--red";
1163 break;
1164 }
1165
1166 $logs[$key] = $log;
1167 }
1168 return $logs;
1169 }
1170
1171 /**
1172 * Reassembling the quarantine logs.
1173 *
1174 * @param array $logs_
1175 * Quarantine logs from WebTotem.
1176 *
1177 * @return array
1178 * Reassembled array of logs.
1179 */
1180 public static function getQuarantineLogs(array $logs_) {
1181 $logs = [];
1182 foreach ($logs_ as $key => $log) {
1183 $logs[$key] = $log;
1184 $logs[$key]['path'] = urldecode($log['path']);
1185 $logs[$key]['date'] = self::dateFormatter($log['date']);
1186 }
1187
1188 return $logs;
1189 }
1190
1191 /**
1192 * Generate an array of IP address data.
1193 *
1194 * @param array $data
1195 * IP addresses data from WebTotem.
1196 * @param string $list_name
1197 * Allow or deny list.
1198 *
1199 * @return array
1200 * Returns array of data.
1201 */
1202 public static function getIpList(array $data, $list_name) {
1203 $list = [];
1204 foreach ($data as $item) {
1205 $list[] = [
1206 'ip' => $item['ip'],
1207 'id' => $item['id'],
1208 'created_at' => self::dateFormatter($item['createdAt']),
1209 'list_name' => $list_name,
1210 ];
1211 }
1212 return $list;
1213 }
1214
1215 /**
1216 * Generate an array of URL address data.
1217 *
1218 * @param array $data
1219 * URL addresses data from WebTotem.
1220 *
1221 * @return array
1222 * Returns array of data.
1223 */
1224 public static function getUrlAllowList(array $data) {
1225 $list = [];
1226 foreach ($data as $item) {
1227 $list[] = [
1228 'url' => $item['url'],
1229 'id' => $item['id'],
1230 'created_at' => self::dateFormatter($item['createdAt']),
1231 'list_name' => 'url_allow',
1232 ];
1233 }
1234 return $list;
1235 }
1236
1237 /**
1238 * Convert IP list to be transferred to WebTotem.
1239 *
1240 * @param string $data
1241 * IP list.
1242 *
1243 * @return string
1244 * Returns the converted string.
1245 */
1246 public static function convertIpListForApi($data) {
1247 if (!$data) {
1248 return FALSE;
1249 }
1250
1251 $ips = preg_split("/(?(?=[\s,])[^.]|^$)/", $data);
1252
1253 if (is_array($ips)) {
1254 $ips_ = '[';
1255 foreach ($ips as $ip) {
1256 if (!empty($ip)) {
1257 $ips_ .= '"' . $ip . '",';
1258 }
1259 }
1260 $ips_ = substr($ips_, 0, -1);
1261 $ips_ .= ']';
1262 }
1263 else {
1264 $ips_ = '"' . $ips . '"';
1265 }
1266
1267 return $ips_;
1268 }
1269
1270 /**
1271 * Get data of the country with the most attacks.
1272 *
1273 * @param array $map
1274 * Map logs from WebTotem.
1275 *
1276 * @return array
1277 * Returns array of data.
1278 */
1279 public static function getMostAttacksData($map) {
1280
1281 if ($map) {
1282 $most_attacks_key = array_search(max(array_column($map, 'attacks')), array_column($map, 'attacks'));
1283 $total_attacks = array_sum(array_column($map, 'attacks'));
1284
1285 $data['percent'] = ($total_attacks) ? round($map[$most_attacks_key]['attacks'] / $total_attacks * 100) : 0;
1286 $data['country'] = self::getCountryName($map[$most_attacks_key]['country']);
1287 $data['offset'] = 176 / 100 * (100 - $data['percent']);
1288
1289 return $data;
1290 }
1291
1292 return ['percent' => 0, 'country' => FALSE, 'offset' => 0];
1293 }
1294
1295 /**
1296 * Get data on the three most attacking countries.
1297 *
1298 * @param array $map
1299 * Map logs from WebTotem.
1300 *
1301 * @return array
1302 * Returns array of data.
1303 */
1304 public static function getTreeMostAttacksData($map) {
1305 $total_attacks = array_sum(array_column($map, 'attacks'));
1306
1307 if ($map) {
1308 array_multisort (array_column($map, 'attacks'), SORT_DESC, $map);
1309 $data = array_slice($map, 0, 3);
1310
1311 foreach ($data as $key => $value){
1312 $data[$key]['percent'] = round($value['attacks'] / $total_attacks * 100);
1313 $data[$key]['country'] = self::getCountryName($value['country']);
1314 }
1315
1316 return $data;
1317 }
1318
1319 return [];
1320 }
1321
1322 /**
1323 * Getting the country name by two-letter code.
1324 *
1325 * @param string $key
1326 * Two-letter code.
1327 *
1328 * @return string
1329 * Returns country name.
1330 */
1331 public static function getCountryName($key) {
1332 $countries = WebTotemCountryManager::getStandardList();
1333 $key = (string) $key;
1334
1335 return (array_key_exists($key, $countries)) ? $countries[$key] : $key;
1336 }
1337
1338 /**
1339 * Get configs data.
1340 *
1341 * @param array $array
1342 * Original array.
1343 * @param string $key
1344 * The key to use as an index.
1345 *
1346 * @return array
1347 * Configs data array.
1348 */
1349 public static function getConfigsData(array $array, $key) {
1350 $configs = self::arrayMapIndex($array, $key);
1351
1352 foreach ($configs as $service => $config){
1353 $configs[$service]['checked'] = ($config['isActive']) ? 'checked' : '';
1354 $configs[$service]['notification_checked'] = (isset($config['notifications']) && $config['notifications']) ? 'checked' : '';
1355 }
1356
1357 return $configs;
1358 }
1359
1360 /**
1361 * Get waf setting data.
1362 *
1363 * @param array $settings
1364 * Original array.
1365 *
1366 * @return array
1367 * Configs data array.
1368 */
1369 public static function getWafSettingData(array $settings) {
1370 $_settings['gdn']['checked'] = (isset($settings['gdn']) && !$settings['gdn']) ? '' : 'checked';
1371 $_settings['dos'] = [
1372 'checked' => (isset($settings['dosProtection']) && !$settings['dosProtection']) ? '' : 'checked',
1373 'visually' => (isset($settings['dosProtection']) && !$settings['dosProtection']) ? 'visually-hidden' : '',
1374 ];
1375 $_settings['dos_limit'] = $settings['dosLimit'] ?: 1000;
1376
1377 $_settings['login_attempt'] = [
1378 'checked' => (isset($settings['loginAttemptsProtection']) && !$settings['loginAttemptsProtection']) ? '' : 'checked',
1379 'visually' => (isset($settings['loginAttemptsProtection']) && !$settings['loginAttemptsProtection']) ? 'visually-hidden' : '',
1380 ];
1381 $_settings['login_attempt_limit'] = $settings['loginAttemptsLimit'] ?: 20;
1382
1383 return $_settings;
1384 }
1385
1386 /**
1387 * Get plugin settings data.
1388 *
1389 * @return array
1390 * Configs data array.
1391 */
1392 public static function getPluginSettingsData() {
1393
1394 $settings = WebTotemOption::getPluginSettings();
1395 $_settings = $settings;
1396
1397 $_settings['hide_wp_version_checked'] = (array_key_exists('hide_wp_version', $settings) and $settings['hide_wp_version']) ? 'checked' : '';
1398 $_settings['recaptcha_checked'] = (array_key_exists('recaptcha', $settings) and $settings['recaptcha']) ? 'checked' : '';
1399 $_settings['two_factor_checked'] = (array_key_exists('two_factor', $settings) and $settings['two_factor']) ? 'checked' : '';
1400
1401 return $_settings;
1402 }
1403
1404 /**
1405 * Replace array indexes by key.
1406 *
1407 * @param array $array
1408 * Original array.
1409 * @param string $key
1410 * The key to use as an index.
1411 *
1412 * @return array
1413 * Returns a new array.
1414 */
1415 public static function arrayMapIndex(array $array, $key) {
1416 $new_array = [];
1417 foreach ($array as $item) {
1418 if (array_key_exists($key, $item)) {
1419 $new_array[$item[$key]] = $item;
1420 }
1421 }
1422 return $new_array;
1423 }
1424
1425 /**
1426 * Generate random string.
1427 *
1428 * @param int $length
1429 * The required length of the string.
1430 *
1431 * @return string
1432 * Returns random string.
1433 */
1434 public static function generateRandomString( int $length = 10): string {
1435 $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
1436 $charactersLength = strlen($characters);
1437 $randomString = '';
1438 for ($i = 0; $i < $length; $i++) {
1439 $randomString .= $characters[rand(0, $charactersLength - 1)];
1440 }
1441 return $randomString;
1442 }
1443
1444 /**
1445 * Encodes the less than, greater than, ampersand,double quote
1446 * and single quote characters. Will never double encode entities.
1447 *
1448 * @see https://developer.wordpress.org/reference/functions/esc_attr/
1449 *
1450 * @param string $text
1451 * The text which is to be encoded.
1452 *
1453 * @return string
1454 * The encoded text with HTML entities.
1455 */
1456 public static function escape($text = '') {
1457 return esc_attr($text);
1458 }
1459
1460 /**
1461 * Throw generic exception.
1462 *
1463 * @throws Exception
1464 *
1465 * @param string $message
1466 * Error or information message.
1467 * @param string $type
1468 * Either info or error.
1469 *
1470 * @return bool
1471 * False all the time, used for debug.
1472 */
1473 public static function throwException($message, $type = 'error') {
1474 if (defined('WTOTEM_THROW_EXCEPTIONS') && WTOTEM_THROW_EXCEPTIONS === true && is_string($message) ) {
1475 $message = str_replace( '<strong>WebTotem:</strong>', ($type === 'error' ? __('Error:', 'wtotem') : __('Info:', 'wtotem')), $message );
1476 throw new Exception($message, $type === 'error' ? 157 : 333);
1477 }
1478 return false;
1479 }
1480
1481 /**
1482 * Get audit logs data
1483 *
1484 * @return array
1485 */
1486 public static function getAuditLogs($data, $dates_count) {
1487 $logs = [];
1488 foreach ($data as $datum){
1489 $date_time = strtotime($datum['created_at']);
1490 $date = date_i18n('M j, Y', $date_time);
1491
1492 $logs[$date]['date'] = $date;
1493 $logs[$date]['count'] = $dates_count[$date];
1494 $logs[$date]['logs'][] = [
1495 'time' => date_i18n('H:i', $date_time),
1496 'user_name' => $datum['user_name'],
1497 'status' => $datum['status'],
1498 'title' => $datum['title'],
1499 'event' => $datum['event'],
1500 'description' => $datum['description'],
1501 'ip' => $datum['ip'],
1502 'viewed' => (int) !$datum['viewed']
1503 ];
1504 }
1505 return $logs;
1506 }
1507
1508 /**
1509 * Get confidential files data
1510 *
1511 * @return array
1512 */
1513 public static function getConfidentialFiles($data) {
1514 foreach ($data as $key => $datum){
1515 $data[$key]['modified_at'] = date_i18n('M j, Y \/ H:i', strtotime($datum['modified_at']));
1516 $data[$key]['size'] = self::humanFilesize($datum['size']);
1517 $data[$key]['name'] = urldecode($datum['name']);
1518 $data[$key]['path'] = urldecode($datum['path']);
1519 }
1520 return $data;
1521 }
1522
1523 /**
1524 * Building navigation and forming a template
1525 *
1526 * @param integer $limit
1527 * number of entries per 1 page
1528 * @param integer $count_all
1529 * total number of all entries
1530 * @param integer $currentPage
1531 * the number of the page being viewed
1532 * @param integer $nextPrev
1533 * Show the "Forward" and "Back" buttons
1534 * @return mixed
1535 * Generated navigation template ready for output
1536 */
1537 public static function paginationBuild($limit, $count_all, $currentPage = 1, $nextPrev = true) {
1538 if( $limit < 1 OR $count_all <= $limit ) return '';
1539 $count_pages = ceil( $count_all / $limit );
1540
1541 $spread = 3;
1542 $separator = "<i>...</i>";
1543 $wrap = "<div class=\"wtotem_pagination\">{pages}</div>";
1544
1545 $nextTitle = '';
1546 $prevTitle = '';
1547
1548 $currentPage = intval( $currentPage );
1549 if( $currentPage < 1 ) $currentPage = 1;
1550
1551 $shift_start = max( $currentPage - $spread, 2 );
1552 $shift_end = min( $currentPage + $spread, $count_pages-1 );
1553 if( $shift_end < $spread * 2 ) {
1554 $shift_end = min( $spread * 2, $count_pages-1 );
1555 }
1556 if( $shift_end == $count_pages - 1 AND $shift_start > 3 ) {
1557 $shift_start = max( 3, min( $count_pages - $spread * 2 + 1, $shift_start ) );
1558 }
1559
1560 $list = self::getPaginationItem( 1, $currentPage );
1561
1562 if ($shift_start == 3) {
1563 $list .= self::getPaginationItem( 2, $currentPage );
1564 } elseif ( $shift_start > 3 ) {
1565 $list .= $separator;
1566 }
1567
1568 for( $i = $shift_start; $i <= $shift_end; $i++ ) {
1569 $list .= self::getPaginationItem( $i, $currentPage );
1570 }
1571
1572 $last_page = $count_pages - 1;
1573 if( $shift_end == $last_page-1 ){
1574 $list .= self::getPaginationItem( $last_page, $currentPage );
1575 } elseif( $shift_end < $last_page ) {
1576 $list .= $separator;
1577 }
1578
1579 $list .= self::getPaginationItem( $count_pages, $currentPage );
1580
1581 if( $nextPrev ) {
1582 $list = self::getPaginationItem(
1583 $currentPage > 1 ? $currentPage - 1 : 0,
1584 $currentPage,
1585 $nextTitle,
1586 true )
1587 . $list
1588 . self::getPaginationItem(
1589 $currentPage < $count_pages ? $currentPage + 1 : 0,
1590 $currentPage,
1591 $prevTitle,
1592 true
1593 );
1594 }
1595
1596 return str_replace( "{pages}", $list, $wrap );
1597 }
1598
1599 /**
1600 * Button/Link Formation
1601 * @param int $page_num
1602 * page number
1603 * @param string $currentPage
1604 * current page
1605 * @param string $page_name
1606 * if specified, the text will be displayed instead of the page number
1607 * @return string
1608 * span block with active page or link.
1609 */
1610 public static function getPaginationItem( $page_num, $currentPage, $page_name = '' ) {
1611 if($page_num === 0){return '';}
1612 $page_name = $page_name ?: $page_num;
1613
1614 if( $currentPage == $page_num ) {
1615 return "<span class=\"wtotem_pagination__number wtotem_pagination__number_active\">{$page_name}</span>";
1616 } else {
1617 return "<a href=\"#\" data-page=\"{$page_num}\" class=\"wtotem_pagination__number\">{$page_name}</a>";
1618 }
1619 }
1620
1621 /**
1622 * Get notifications array.
1623 *
1624 * @return array
1625 * Returns notifications array.
1626 */
1627 public static function getNotifications() {
1628
1629 $notifications_data = WebTotemOption::getNotificationsData();
1630 $notifications = [];
1631
1632 foreach ($notifications_data as $notification) {
1633 switch ($notification['type']) {
1634 case 'error':
1635 $image = 'alert-error.svg';
1636 $class = 'wtotem_alert__title_red';
1637 break;
1638
1639 case 'warning':
1640 $image = 'alert-warning.svg';
1641 $class = 'wtotem_alert__title_yellow';
1642 break;
1643
1644 case 'success':
1645 $image = 'alert-success.svg';
1646 $class = 'wtotem_alert__title_green';
1647 break;
1648
1649 case 'info':
1650 $image = 'info-blue.svg';
1651 $class = 'wtotem_alert__title_blue';
1652 break;
1653 }
1654
1655 $notifications[] = [
1656 "text" => $notification['notice'],
1657 "id" => self::generateRandomString(8),
1658 "type" => self::getStatusText($notification['type']),
1659 "type_raw" => $notification['type'],
1660 "image" => $image,
1661 "class" => $class,
1662 ];
1663 }
1664
1665 return $notifications;
1666 }
1667
1668 /**
1669 * Get current agent installation statuses.
1670 *
1671 * @param array $agents_statuses
1672 * Agents statuses got from the WebTotem API.
1673 *
1674 * @return array
1675 * Returns an array with agent installation status data.
1676 */
1677 public static function getAgentsStatuses(array $agents_statuses) {
1678 $agents = ['am', 'waf', 'av'];
1679 $installing_statuses = [
1680 'not_installed',
1681 'installing',
1682 'internal_error',
1683 'update_error',
1684 'config_error',
1685 'session_error',
1686 ];
1687
1688 $process_statuses = [];
1689 $option_statuses = [];
1690
1691 foreach ($agents as $agent) {
1692 $status = WebTotemAgentManager::checkInstalledService($agent);
1693 $option_statuses[$agent] = $status['option_status'] ?: FALSE;
1694
1695 if ($agent == 'am') {
1696 if ($status['file_status']) {
1697 $process_statuses[$agent] = 'installed';
1698 }
1699 else {
1700 $process_statuses[$agent] = 'failed';
1701 }
1702 }
1703 else {
1704 if ($status['file_status']) {
1705 if (in_array($agents_statuses[$agent], $installing_statuses)) {
1706 $process_statuses[$agent] = 'installing';
1707 }
1708 elseif ($agents_statuses[$agent] == 'agent_not_available') {
1709 $process_statuses[$agent] = 'failed';
1710 }
1711 else {
1712 $process_statuses[$agent] = 'installed';
1713 }
1714 }
1715 else {
1716 $process_statuses[$agent] = 'installing';
1717 }
1718 }
1719 }
1720
1721 return [
1722 'process_statuses' => $process_statuses,
1723 'option_statuses' => $option_statuses,
1724 ];
1725 }
1726
1727 }
1728