From e9af9d8fca4c6501cf3e9c189fb5d330326b197e Mon Sep 17 00:00:00 2001 From: alexandergull Date: Mon, 23 Dec 2024 19:22:05 +0500 Subject: [PATCH] New. Scanner. Several weakspots curing implemented. Weakspots workwith log implemented. --- css/spbc-settings.min.css | 2 +- css/src/spbc-settings.css | 1 + inc/spbc-settings.php | 20 +-- lib/CleantalkSP/SpbctWP/DB/SQLSchema.php | 2 + lib/CleantalkSP/SpbctWP/Scanner/Cure.php | 33 +++- .../SpbctWP/Scanner/CureLog/CureLog.php | 158 +++++++++++++----- .../SpbctWP/Scanner/CureLog/CureLogRecord.php | 25 +++ .../SpbctWP/Scanner/Stages/CureStage.php | 144 ++++++++-------- 8 files changed, 245 insertions(+), 140 deletions(-) diff --git a/css/spbc-settings.min.css b/css/spbc-settings.min.css index 427c79e4b..21be758fc 100644 --- a/css/spbc-settings.min.css +++ b/css/spbc-settings.min.css @@ -1 +1 @@ -.spbc_auto_link,.spbc_manual_link_scan{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;cursor:pointer}.circle{border-radius:50%;align-items:center;justify-content:center;position:relative;background-color:#03A9F4;clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 0,50% 0,50% 50%,50% 50%)}.circle-inner{width:100%;height:100%;border-radius:50%;background:#f7f7f7;transform:scale(.7)}.circle--small{width:16px;height:16px}.circle--mid{width:30px;height:30px}.-animation--circle{animation:animation-circle 2s linear forwards}.-animation--30s{animation-duration:30s!important}.-animation--2min{animation-duration:120s!important}@keyframes animation-circle{12.5%{clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 0,0 0,50% 50%,50% 50%)}25%{clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 50%,0 50%,50% 50%,50% 50%)}37.5%{clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 100%,0 100%,50% 50%,50% 50%)}50%{clip-path:polygon(50% 0,100% 0,100% 100%,50% 100%,50% 100%,50% 100%,50% 100%,50% 50%,50% 50%)}62.5%{clip-path:polygon(50% 0,100% 0,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%,50% 50%,50% 50%)}75%{clip-path:polygon(50% 0,100% 0,100% 50%,100% 50%,100% 50%,100% 50%,100% 50%,50% 50%,50% 50%)}87.5%{clip-path:polygon(50% 0,100% 0,100% 0,100% 0,100% 0,100% 0,100% 0,50% 50%,50% 50%)}100%{clip-path:polygon(50% 0,50% 0,50% 0,50% 0,50% 0,50% 0,50% 0,50% 50%,50% 50%)}}#confirmation-code--resend .circle{margin-left:5px;display:inline-block;vertical-align:text-bottom}.spbc---hidden,.spbc_waf_reason{display:none}#spbcTopWarning{margin-bottom:5px}#spbcTopWarning h3{margin:10px 0 5px}#spbcTopWarning h4{margin:10px}#spbcTopWarning h4 span{margin-top:5px}#spbc_gdpr_open_modal:hover{cursor:pointer}.spbc---gray{color:gray}.spbc---red{color:red}.spbc_bold{font-weight:800}.spbc---top{z-index:9999!important}.spbc_waf_reason_title{text-decoration:underline}.spbc_waf_reason_title:hover+.spbc_waf_reason{display:inline}.spbc_warning_counter{margin:0 5px;padding:0 7px;font-size:14px;height:23px;display:inline-block;text-align:center;border-radius:3px}.spbc_sub_setting{margin-left:30px!important}.spbc_sub2_setting{margin-left:60px!important}.spbc_affiliate_shortcode{width:inherit!important;min-width:inherit!important}.spbc_warning_counter--black{color:#fff;background-color:#000}.spbc_warning_counter--red{color:#000;background-color:red}.spbc_warning_counter--orange{color:#000;background-color:orange}.spbc_warning_counter--green{color:#000;background-color:green}.spbc_highlighted{outline-offset:5px;outline-color:red;outline-width:3px!important;outline-style:solid!important}.spbc_status_icon{vertical-align:text-bottom;margin:0 5px}.spbc_progressbar_counter{position:absolute;height:22px;width:100%;left:0;top:0;text-align:center}.spbc_progressbar_counter span{vertical-align:sub;line-height:22px;font-weight:600;font-size:18px}.spbc_preloader,.spbc_preloader_button{margin-left:5px;vertical-align:text-top;display:none}.spbc_compare_file_row_wrapper,.spbc_view_file_row,.spbc_view_file_row_wrapper{line-height:19px}.ui-progressbar-value{background-image:url(../images/pbar-ani.gif)!important}.spbc_preloader{width:20px}.spbc_preloader_button{height:15px}.spbc_spinner_big{display:block;margin:40px auto}.spbc_scan_result_row td{text-align:center}.spbc_scan_result_row td:nth-child(1){text-align:left}.spbc_scan_result_row td:nth-child(2){text-align:right}.spbc_scan_result_row td:last-child button{margin-left:3px}.spbc_view_file_row_wrapper:nth-child(odd){background:#ccc}.spbc_view_file_row_wrapper:nth-child(even){background:#ddd}.spbc_auto_link,.spbc_compare_file_row_wrapper:nth-child(odd){background:#ccc}.spbc_view_file_row_num{display:inline-block;width:30px;margin:0 0 0 5px;border-right:1px solid #000}.spbc_view_file_row{display:inline;margin:0 0 0 5px;font-size:1em;word-break:break-all}.spbc_compare_file_headings{text-align:center;width:100%;display:inline-block;font-weight:700}.spbc_compare_file_row_wrapper:nth-child(even){background:#ddd}.spbc_compare_file_row_num{display:inline-block;width:20px;box-shadow:-2px 0 0 0 #000,2px 0 0 0 #000;padding:0 1%}.spbc_compare_file_row{display:inline-block;width:45%;margin:0;padding:0 1%}table.spbc_table_general{width:100%;border:0;border-spacing:0;border-collapse:collapse}table.spbc_table_general td,table.spbc_table_general th{position:relative;border:1px solid #666;padding:2px 10px}.spbcShortText{display:inline-block;width:100%}.spbcFullText,.spbcFullText-right{display:none;position:absolute;background:rgba(150,150,150,.9);padding:7px;z-index:20;color:#fff}.spbcFullText{top:-5px;border:1px solid #333;border-radius:5px}.spbcFullText-right{top:0;right:0;border:1px solid #333;border-radius:5px}.spbcFullText a{color:#fff}.spbcFullText a:hover{color:#ddd}#spbc_scan_accordion .column-primary{position:initial}#spbc_scan_accordion tbody tr{position:relative}.spbc_accordion_category_wrapper{padding:0 5px 10px;border:1px solid #d3d3d3;border-radius:3px;margin-bottom:5px}.spbc_accordion_category_header{color:#026E88;font-weight:800;margin-left:10px!important}div.pagination{margin:10px}ul.pagination{display:inline-block;margin:0}li.pagination{display:inline-block;margin-left:10px}span.current_page{font-size:1.3em;font-weight:600}.spbc_new{color:red;position:relative;font-size:10px;vertical-align:bottom;top:-8px}.spbc_wrapper_settings{margin:10px 0 0}.spbc_page_header_info_common_wrapper{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:1%}.spbc_page_header_info__block_label{top:3px;left:3px;position:relative;background:#f4f4f4;border:1px solid #DDD;border-radius:3px;padding:2px 5px;font-size:10px;color:gray}.spbc_page_header_info__block_body{border:1px solid #DDD;background:#f4f4f4;padding:1%}.spbc_page_header_info__block_row{overflow-wrap:anywhere;font-size:13px}.spbc_page_header_info_left_column{width:66%}.spbc_page_header_info__state_block{width:60%}.spbc_page_header_info_right_column{width:33%}.spbc_page_header_info__about_block{width:100%;height:auto}.spbc_page_header_info__about_block__divider{padding:5px}.spbc_page_header_info__error_block{width:100%}.spbc_page_buttons_wrapper{display:flex;margin-bottom:-10px}.spbc_page_buttons_header{display:inline-block;margin-right:7px}.spbc_page_mob_info__about_block{display:none}.spbc_tabs_nav_wrapper{display:flex;background-color:#fff;margin:15px 15px 0 0;overflow-x:auto}@media screen and (max-width:1200px){.spbc_tabs_nav_wrapper{flex-direction:column}}.spbc_tab_nav{display:inline-block;margin:10px 0 0 .5em;padding:5px 10px;height:24px;font-size:14px;line-height:24px;color:#555;cursor:pointer;font-weight:400}.spbc_tab_nav--active,.spbc_tab_nav:hover{margin-bottom:-1px;border-bottom:2px solid #026E88}.spbc_tab_nav svg{stroke:#000;stroke-width:.5}.spbc_tab_nav--active{color:#026E88;font-weight:800}.spbc_tab_nav--active svg{stroke:#026E88;stroke-width:1}.spbc_tab_nav-title{margin-left:5px;width:max-content}.spbc_tabs_nav_wrapper::-webkit-scrollbar{display:none}.spbc_tab{display:none;margin:0;background-color:#fff}.spbc_tab--active{display:block}.spbc_tab_fields_group{position:relative;min-width:255px;margin:10px auto;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fdfdfd}.spbc_group_header{margin:0 0 10px;padding:10px;border-bottom:1px solid #eee}.spbc_group_header>h3{margin:0}.spbc_group_header>h3>a{color:#1d2327;text-decoration:none}.spbc_wrapper_field{margin:0 15px 15px}.spbc_long_description__show:hover{color:#aaa;cursor:pointer}.spbc_settings_description{font-size:9pt;color:#888}.spbc_settings_description select{display:inline;position:relative;transform:scale(.7);left:-50px}.spbc_tab-settings_general input[type=text]{min-width:255px;width:100%}.spbc_short_text_field input{min-width:70px!important;width:70px!important}.spbc_middle_text_field input{min-width:200px!important;width:200px!important}.spbc_long_text_field input[type=text]{min-width:200px;width:500px}.spbc_wrapper_field label{vertical-align:baseline}.spbc_wrapper_field h4{margin:10px 15px 5px}.spbc_wrapper_footer{margin:15px}#spbc_wrapper_error{margin:0;padding:5px}#spbc_wrapper_error h3,#spbc_wrapper_error h4{margin:5px}#showHideLink{display:inline-block;margin-top:5px;color:#777}.spbc__wrapper--center{margin:10px 0;text-align:center}.spbc__show_more_logs{display:none}.spbc_settings_banner{display:inline-block;margin:1em 0;vertical-align:top;text-align:center}#spbc_translate_plugin{margin-left:10px}.spbc_rate_block{border:1px dashed #666;width:400px;padding:.2em}#spbc_translate_plugin .spbc_button_rate{margin-bottom:10px}.spbc_button_rate{display:inline-block;text-align:center;vertical-align:middle;padding:12px 24px;border:1px solid #216298;border-radius:8px;background:#35a0f7;background:-webkit-gradient(linear,left top,left bottom,from(#35a0f7),to(#216298));background:-moz-linear-gradient(top,#35a0f7,#216298);background:linear-gradient(to bottom,#35a0f7,#216298);text-shadow:#153e5f 1px 1px 1px;font:normal normal bold 16px verdana;color:#fff;text-decoration:none}.spbc_button_rate:focus,.spbc_button_rate:hover{border:1px solid #297bbe;background:#40c0ff;background:-webkit-gradient(linear,left top,left bottom,from(#40c0ff),to(#2876b6));background:-moz-linear-gradient(top,#40c0ff,#2876b6);background:linear-gradient(to bottom,#40c0ff,#2876b6);color:#fff;text-decoration:none}.spbc_button_rate:active{background:#216298;background:-webkit-gradient(linear,left top,left bottom,from(#216298),to(#216298));background:-moz-linear-gradient(top,#216298,#216298);background:linear-gradient(to bottom,#216298,#216298)}#spbc_rate_plugin .spbc_button_rate:before{content:"\0000a0";display:inline-block;height:24px;width:24px;line-height:24px;margin:0 4px -6px -4px;position:relative;top:0;left:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACjElEQVRIie1UTWsTURQ9dzKpofQLobQFlxqENF1JG0GE6sKuRLDtTKaBkJUIRdwpba2g9ge48gMEUUyTbrUutFmk1X6Q7kxDgi1YUSmlpsGYiTXtuy7GCYnaSRu3PczAfe/dd8695z0ecIAKsFVK0DQNLpcL8Xi8KgHZalFRNWe7uyMs2+RtkBQIjQerU/k3uVceHhmdyed/8NbWFg8OXrlXDY+020JdXf2NQMB/yuE4hHw+j5yur1df7h9QvQMXpiKRHSEECyF4cvJlQVG149VwlZ1BX58fsn1H7e29+OhMd7cEAMyM6PTMNAgfFUWrJSIAQgCAYAKIAECABACABGFt7fPPaDRqjItVqyrqG5vGAn7/kMfTBYMIyGQyeD0VMZKYweYGM2ZjpnR+eWVl8V08fnYiNP6t1Jbzc3PzbNryP38stsiKqp0uWuTz+eBqd9/s6uo02vpdPTOXxZuZDB7cfwgQGa0TIEmS7nA4PhhDkgBgdXV1FkTzRYHCtjjS4XZ3mGQmSsdEhKbGRqhqPwRz0ZOlRKImGBy/FA4F31gd8tG2tjaZmf+VUybS2tpaNpfeTMsADu+2xxRw2O12ENFftpTG6XQat26PQZIIzEA2m/1SKBSGGXhhWZmiaifezs7yfhGdnmFF1TqtuM0OksvvlzMnPZ4mq+RkMoVsNlu83ImlxDqATxUFwqHg94aGhsc9PeeuNjc372pRMpnExsZX5HI5xBZjd3aEuBsOBTcs7TGherXaa9eHIqlUioUQltYIIXhkZPT5XnjL7qXi1Wpkm6w5nccGWlpanLJNlkGQyEw1Pui6rs8tLFx+9vTJq30JlKK/3ycRCQkSFZ8Dcwszi4lwUOylgwNUxC8cBKAS7hIWzwAAAABJRU5ErkJggg==) left center no-repeat;background-size:100% 100%}.spbc_auto_link,.spbc_manual_link,.spbc_manual_link_scan{display:inline-block;height:28px;border-width:1px;border-style:solid;-webkit-appearance:none;white-space:nowrap}.spbc_rate_block_stars{margin:1em 0}.star-icon{color:#ddd;font-size:18px;position:relative}.star-icon.full:before{color:#FDE16D;content:'\2605';position:absolute;left:0;text-shadow:0 0 2px rgba(0,0,0,.7)}.spbc_hint{color:#666}p.spbc_hint{margin:0}.spbc_hint_warning{font-size:17px;font-weight:600;text-align:center;color:#eb8f00}.spbc_auto_link,.spbc_manual_link,.spbc_manual_link_scan{font-size:13px;text-decoration:none}.spbc_hint--link{color:#aaa;text-decoration:underline;cursor:pointer}.spbc_hint--top_right{position:relative;float:right;top:0;right:10px}.spbc_auto_link{border-color:#999;-webkit-box-shadow:inset 0 1px 0 rgba(200,200,200,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(200,200,200,.5),0 1px 0 rgba(0,0,0,.15);color:#000;line-height:26px;margin:0;padding:0 10px 1px;-webkit-border-radius:2px;border-radius:2px;box-sizing:border-box}.spbc_auto_link:hover{color:#fff}.spbc_manual_link_scan{color:#fff;background:#026E88;border-color:#026E88;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);line-height:26px;margin:0;padding:0 10px 1px;border-radius:3px;-webkit-border-radius:3px;box-sizing:border-box}.spbc_manual_link{background:#fff;border-color:#026E88;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);color:#026E88!important;line-height:26px;margin:0;padding:0 10px 1px;cursor:pointer;border-radius:3px;-webkit-border-radius:3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.spbc_manual_link:hover,button.ct_support_link{text-decoration:underline}.spbc_page_buttons_links_basic_align{display:flex;align-items:center;justify-content:center;gap:5px}.spbc-btn-as-link{padding:0;margin:0;vertical-align:baseline;color:gray;border:0;border-bottom:1px solid;cursor:pointer}#spbc-account-email[contenteditable=true]{padding:6px;background-color:#fff;border:1px solid #ccc}.spbc_long_desc,.spbc_popup_tip--wrapper{min-width:80px;min-height:80px;max-width:500px;padding:10px;z-index:10}.spbc_dismiss{width:20px;height:20px;border-radius:5px}.spbc-links:visited{color:#fff}.spbc_long_desc{position:absolute;background:#5a5a5a;color:#fff}@media screen and (max-width:900px){.spbc_long_desc{left:inherit!important}.spbc_long_desc__angle_top_left{display:none}}.spbc_long_desc p{color:#fff!important}i.animate-spin{-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;display:inline-block;font-size:25px;line-height:20px;color:rgba(120,200,230,1);margin:25px}@keyframes spin{to{transform:rotate(359deg)}}.spbc_long_desc__angle,.spbc_long_desc__angle_top_left{-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);position:absolute;width:10px;height:10px;background:#5a5a5a}.spbc_long_desc__cancel{position:absolute;top:5px;right:5px;color:rgba(255,255,255,.5)}.spbc_long_desc__cancel:hover{color:#fff}.spbc_long_desc__link,.spbc_long_desc__title{color:rgba(120,200,230,1)}.spbc_long_desc__angle{top:5px;left:-17px;transform:rotate(135deg);-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.spbc_long_desc__angle_top_left{top:-10px;left:-9px;transform:rotate(135deg);-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.spbc_long_desc__title{margin:0}.spbc_long_desc__link:hover{color:rgba(140,220,250,1)}.spbc_long_desc h4{color:#50a0be;margin:10px 0 3px}.spbc_long_desc span{margin:0 0 0 10px;display:inline-block}.spbc_long_desc img{width:300px}.spbc_popup_tip--icon---show:hover{color:#aaa;cursor:pointer}.spbc_popup_tip--wrapper{position:absolute;background:#5a5a5a;color:#fff}.spbc_popup_tip--icon---cancel{position:absolute;top:0;right:5px;color:rgba(255,255,255,.5)}.spbc_popup_tip--icon---cancel:hover{color:#fff}.spbc_popup_tip--angle{position:absolute;top:5px;left:-17px;width:10px;height:10px;background:#5a5a5a;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg);-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.spbc_popup_tip--title{color:rgba(120,200,230,1);margin:0}.spbc_popup_tip--text{color:#fff!important}tr:hover .spbc_hint--wrapper{display:none}.spbc_log-wrapper{padding:5px;border:1px solid #000;width:98%;min-height:300px;height:300px;border-bottom:5px dashed #5a5a5a}.spbc_log-wrapper .panel-body{height:100%;overflow-y:auto}.spbc_log-line{margin:0;padding:0 5px}.spbc_log-line:nth-child(odd){background:#d3d3d3}.spbc_log-block_header{margin:10px 0}.spbc_log-input--checkbox,.spbc_log-label--checkbox{width:auto}button.ct_support_link{border:none;background:0 0;color:#666;cursor:pointer}#spbc-modal-content{text-align:center}#spbc-modal-content>*{display:block;width:100%;margin:0}.spbc-modal-header{font-size:15px;font-weight:500}.spbc-modal-buttons-block{display:flex!important;gap:10px;justify-content:center}.spbc-modal-button{width:40%;height:35px;font-size:14px;font-weight:500;border:1px solid #60656b;background:#fff;border-radius:5px;cursor:pointer}.spbc-modal-button:hover{background:#2ea2cc;color:#fff;border:1px solid #2ea2cc}.spbc-modal-file_path{color:#026E88}.spbc-modal-file_path_wrapper{margin:4% 0 1%;padding:5px;border:1px solid #F5F5FD;border-radius:4px}.spbc-popup-msg{width:98%;height:15px;text-align:center;padding:4px;border-radius:7px;position:relative;top:0;right:0;bottom:0;left:0;margin:auto}.popup--green{background:#DFD;color:#060;border:1px solid #060}.popup--red{background:#FDD;color:#600;border:1px solid #600}#spbcscan-results-log-module{min-height:300px;height:300px;border-bottom:5px dashed #5a5a5a}#spbcscan-results-log-module .panel-body{height:100%;overflow-y:auto}#spbcscan-scanner-caption h4{margin:10px 0;font-size:14px}#spbcscan-results-log-caption p{font-size:13px;margin:0 0 6px}#spbcscan-scanner-caption{display:flex;flex-wrap:wrap;flex-direction:row-reverse}#spbcscan-scanner-caption .column:first-child{width:75%;flex:0 0 75%}#spbcscan-scanner-caption .column:last-child{width:25%;flex:0 0 25%;padding-right:10px;box-sizing:border-box}.spbc-scan-log-title{color:#1d2327;font-size:1.3em;margin:0 0 15px!important;font-weight:600}.spbc--status{position:relative;padding-left:26px}.spbc--marker-green::before,.spbc--marker-red::before,.spbc--marker-yellow::before{content:'';position:absolute;width:10px;height:10px;border-radius:50%;left:10px;top:4px}.spbc--marker-green::before{background:#1dda23}.spbc--marker-yellow::before{background:#ffb000}.spbc--marker-red::before{background:#d63638}button#spbc_setting_get_key_auto:disabled{background:#ccc;color:#111;text-decoration:none}.spbc_critical_updates-names{text-transform:uppercase;font-weight:500}.spbc_critical_updates-h_names{font-size:15px}.spbc_critical_updates-legend{border:1px solid #eee;padding:0 0 0 10px;margin:5px 0 0;color:#666}.spbc_critical_updates-no_vulnerabilities{color:green;font-size:15px;font-weight:500;margin:5px 0 0 30px}.spbct_notice{display:flex;justify-content:space-between}.spbct_notice-dismiss{position:relative;top:0;right:1px;border:none;margin:0;padding:9px;background:0 0;color:#787c82;cursor:pointer}.spbc_accordion_header_caption__update_status{display:inline-flex;flex-direction:row;flex-wrap:nowrap;width:45%;align-items:flex-end;justify-content:flex-end}.spbc_accordion_header_caption__updated{display:inline;color:#FFF;font-weight:700}.spbc_setting__textarea{width:400px;height:150px}.spbc-settings-general-wrapper{display:flex;flex-direction:row;flex-wrap:nowrap}.spbc-quicknav--bar_wrapper{display:flex;flex-direction:column;flex-wrap:nowrap;justify-content:flex-start;height:fit-content;position:sticky;top:5vh}.spbc-quicknav--links_wrapper{display:flex;flex-direction:column;flex-wrap:nowrap;justify-content:center;padding:3px;border:1px solid #e5e5e5;margin:10px}.spbc-quicknav--link{margin:3px;width:-webkit-fill-available;width:-moz-available;text-align:left;display:flex;flex-direction:row;justify-content:flex-start}#spbc_quicknav--header{color:#026E88;text-align:center;margin:5px 0}.spbc_quicknav--save_button{margin:10px 5px!important;height:40px}.spbc_settings--save_button_custom{position:sticky;bottom:0;display:flex;justify-content:center;flex-direction:row;align-items:baseline;flex-wrap:nowrap;padding:15px 0}html{scroll-behavior:smooth} \ No newline at end of file +.spbc_auto_link,.spbc_manual_link_scan{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;cursor:pointer}.circle{border-radius:50%;align-items:center;justify-content:center;position:relative;background-color:#03A9F4;clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 0,50% 0,50% 50%,50% 50%)}.circle-inner{width:100%;height:100%;border-radius:50%;background:#f7f7f7;transform:scale(.7)}.circle--small{width:16px;height:16px}.circle--mid{width:30px;height:30px}.-animation--circle{animation:animation-circle 2s linear forwards}.-animation--30s{animation-duration:30s!important}.-animation--2min{animation-duration:120s!important}@keyframes animation-circle{12.5%{clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 0,0 0,50% 50%,50% 50%)}25%{clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 50%,0 50%,50% 50%,50% 50%)}37.5%{clip-path:polygon(50% 0,100% 0,100% 100%,0 100%,0 100%,0 100%,0 100%,50% 50%,50% 50%)}50%{clip-path:polygon(50% 0,100% 0,100% 100%,50% 100%,50% 100%,50% 100%,50% 100%,50% 50%,50% 50%)}62.5%{clip-path:polygon(50% 0,100% 0,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%,50% 50%,50% 50%)}75%{clip-path:polygon(50% 0,100% 0,100% 50%,100% 50%,100% 50%,100% 50%,100% 50%,50% 50%,50% 50%)}87.5%{clip-path:polygon(50% 0,100% 0,100% 0,100% 0,100% 0,100% 0,100% 0,50% 50%,50% 50%)}100%{clip-path:polygon(50% 0,50% 0,50% 0,50% 0,50% 0,50% 0,50% 0,50% 50%,50% 50%)}}#confirmation-code--resend .circle{margin-left:5px;display:inline-block;vertical-align:text-bottom}.spbc---hidden,.spbc_waf_reason{display:none}#spbcTopWarning{margin-bottom:5px}#spbcTopWarning h3{margin:10px 0 5px}#spbcTopWarning h4{margin:10px}#spbcTopWarning h4 span{margin-top:5px}#spbc_gdpr_open_modal:hover{cursor:pointer}.spbc---gray{color:gray}.spbc---red{color:red}.spbc---green{color:#037603}.spbc_bold{font-weight:800}.spbc---top{z-index:9999!important}.spbc_waf_reason_title{text-decoration:underline}.spbc_waf_reason_title:hover+.spbc_waf_reason{display:inline}.spbc_warning_counter{margin:0 5px;padding:0 7px;font-size:14px;height:23px;display:inline-block;text-align:center;border-radius:3px}.spbc_sub_setting{margin-left:30px!important}.spbc_sub2_setting{margin-left:60px!important}.spbc_affiliate_shortcode{width:inherit!important;min-width:inherit!important}.spbc_warning_counter--black{color:#fff;background-color:#000}.spbc_warning_counter--red{color:#000;background-color:red}.spbc_warning_counter--orange{color:#000;background-color:orange}.spbc_warning_counter--green{color:#000;background-color:green}.spbc_highlighted{outline-offset:5px;outline-color:red;outline-width:3px!important;outline-style:solid!important}.spbc_status_icon{vertical-align:text-bottom;margin:0 5px}.spbc_progressbar_counter{position:absolute;height:22px;width:100%;left:0;top:0;text-align:center}.spbc_progressbar_counter span{vertical-align:sub;line-height:22px;font-weight:600;font-size:18px}.spbc_preloader,.spbc_preloader_button{margin-left:5px;vertical-align:text-top;display:none}.spbc_compare_file_row_wrapper,.spbc_view_file_row,.spbc_view_file_row_wrapper{line-height:19px}.ui-progressbar-value{background-image:url(../images/pbar-ani.gif)!important}.spbc_preloader{width:20px}.spbc_preloader_button{height:15px}.spbc_spinner_big{display:block;margin:40px auto}.spbc_scan_result_row td{text-align:center}.spbc_scan_result_row td:nth-child(1){text-align:left}.spbc_scan_result_row td:nth-child(2){text-align:right}.spbc_scan_result_row td:last-child button{margin-left:3px}.spbc_view_file_row_wrapper:nth-child(odd){background:#ccc}.spbc_view_file_row_wrapper:nth-child(even){background:#ddd}.spbc_auto_link,.spbc_compare_file_row_wrapper:nth-child(odd){background:#ccc}.spbc_view_file_row_num{display:inline-block;width:30px;margin:0 0 0 5px;border-right:1px solid #000}.spbc_view_file_row{display:inline;margin:0 0 0 5px;font-size:1em;word-break:break-all}.spbc_compare_file_headings{text-align:center;width:100%;display:inline-block;font-weight:700}.spbc_compare_file_row_wrapper:nth-child(even){background:#ddd}.spbc_compare_file_row_num{display:inline-block;width:20px;box-shadow:-2px 0 0 0 #000,2px 0 0 0 #000;padding:0 1%}.spbc_compare_file_row{display:inline-block;width:45%;margin:0;padding:0 1%}table.spbc_table_general{width:100%;border:0;border-spacing:0;border-collapse:collapse}table.spbc_table_general td,table.spbc_table_general th{position:relative;border:1px solid #666;padding:2px 10px}.spbcShortText{display:inline-block;width:100%}.spbcFullText,.spbcFullText-right{display:none;position:absolute;background:rgba(150,150,150,.9);padding:7px;z-index:20;color:#fff}.spbcFullText{top:-5px;border:1px solid #333;border-radius:5px}.spbcFullText-right{top:0;right:0;border:1px solid #333;border-radius:5px}.spbcFullText a{color:#fff}.spbcFullText a:hover{color:#ddd}#spbc_scan_accordion .column-primary{position:initial}#spbc_scan_accordion tbody tr{position:relative}.spbc_accordion_category_wrapper{padding:0 5px 10px;border:1px solid #d3d3d3;border-radius:3px;margin-bottom:5px}.spbc_accordion_category_header{color:#026E88;font-weight:800;margin-left:10px!important}div.pagination{margin:10px}ul.pagination{display:inline-block;margin:0}li.pagination{display:inline-block;margin-left:10px}span.current_page{font-size:1.3em;font-weight:600}.spbc_new{color:red;position:relative;font-size:10px;vertical-align:bottom;top:-8px}.spbc_wrapper_settings{margin:10px 0 0}.spbc_page_header_info_common_wrapper{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:1%}.spbc_page_header_info__block_label{top:3px;left:3px;position:relative;background:#f4f4f4;border:1px solid #DDD;border-radius:3px;padding:2px 5px;font-size:10px;color:gray}.spbc_page_header_info__block_body{border:1px solid #DDD;background:#f4f4f4;padding:1%}.spbc_page_header_info__block_row{overflow-wrap:anywhere;font-size:13px}.spbc_page_header_info_left_column{width:66%}.spbc_page_header_info__state_block{width:60%}.spbc_page_header_info_right_column{width:33%}.spbc_page_header_info__about_block{width:100%;height:auto}.spbc_page_header_info__about_block__divider{padding:5px}.spbc_page_header_info__error_block{width:100%}.spbc_page_buttons_wrapper{display:flex;margin-bottom:-10px}.spbc_page_buttons_header{display:inline-block;margin-right:7px}.spbc_page_mob_info__about_block{display:none}.spbc_tabs_nav_wrapper{display:flex;background-color:#fff;margin:15px 15px 0 0;overflow-x:auto}@media screen and (max-width:1200px){.spbc_tabs_nav_wrapper{flex-direction:column}}.spbc_tab_nav{display:inline-block;margin:10px 0 0 .5em;padding:5px 10px;height:24px;font-size:14px;line-height:24px;color:#555;cursor:pointer;font-weight:400}.spbc_tab_nav--active,.spbc_tab_nav:hover{margin-bottom:-1px;border-bottom:2px solid #026E88}.spbc_tab_nav svg{stroke:#000;stroke-width:.5}.spbc_tab_nav--active{color:#026E88;font-weight:800}.spbc_tab_nav--active svg{stroke:#026E88;stroke-width:1}.spbc_tab_nav-title{margin-left:5px;width:max-content}.spbc_tabs_nav_wrapper::-webkit-scrollbar{display:none}.spbc_tab{display:none;margin:0;background-color:#fff}.spbc_tab--active{display:block}.spbc_tab_fields_group{position:relative;min-width:255px;margin:10px auto;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fdfdfd}.spbc_group_header{margin:0 0 10px;padding:10px;border-bottom:1px solid #eee}.spbc_group_header>h3{margin:0}.spbc_group_header>h3>a{color:#1d2327;text-decoration:none}.spbc_wrapper_field{margin:0 15px 15px}.spbc_long_description__show:hover{color:#aaa;cursor:pointer}.spbc_settings_description{font-size:9pt;color:#888}.spbc_settings_description select{display:inline;position:relative;transform:scale(.7);left:-50px}.spbc_tab-settings_general input[type=text]{min-width:255px;width:100%}.spbc_short_text_field input{min-width:70px!important;width:70px!important}.spbc_middle_text_field input{min-width:200px!important;width:200px!important}.spbc_long_text_field input[type=text]{min-width:200px;width:500px}.spbc_wrapper_field label{vertical-align:baseline}.spbc_wrapper_field h4{margin:10px 15px 5px}.spbc_wrapper_footer{margin:15px}#spbc_wrapper_error{margin:0;padding:5px}#spbc_wrapper_error h3,#spbc_wrapper_error h4{margin:5px}#showHideLink{display:inline-block;margin-top:5px;color:#777}.spbc__wrapper--center{margin:10px 0;text-align:center}.spbc__show_more_logs{display:none}.spbc_settings_banner{display:inline-block;margin:1em 0;vertical-align:top;text-align:center}#spbc_translate_plugin{margin-left:10px}.spbc_rate_block{border:1px dashed #666;width:400px;padding:.2em}#spbc_translate_plugin .spbc_button_rate{margin-bottom:10px}.spbc_button_rate{display:inline-block;text-align:center;vertical-align:middle;padding:12px 24px;border:1px solid #216298;border-radius:8px;background:#35a0f7;background:-webkit-gradient(linear,left top,left bottom,from(#35a0f7),to(#216298));background:-moz-linear-gradient(top,#35a0f7,#216298);background:linear-gradient(to bottom,#35a0f7,#216298);text-shadow:#153e5f 1px 1px 1px;font:normal normal bold 16px verdana;color:#fff;text-decoration:none}.spbc_button_rate:focus,.spbc_button_rate:hover{border:1px solid #297bbe;background:#40c0ff;background:-webkit-gradient(linear,left top,left bottom,from(#40c0ff),to(#2876b6));background:-moz-linear-gradient(top,#40c0ff,#2876b6);background:linear-gradient(to bottom,#40c0ff,#2876b6);color:#fff;text-decoration:none}.spbc_button_rate:active{background:#216298;background:-webkit-gradient(linear,left top,left bottom,from(#216298),to(#216298));background:-moz-linear-gradient(top,#216298,#216298);background:linear-gradient(to bottom,#216298,#216298)}#spbc_rate_plugin .spbc_button_rate:before{content:"\0000a0";display:inline-block;height:24px;width:24px;line-height:24px;margin:0 4px -6px -4px;position:relative;top:0;left:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACjElEQVRIie1UTWsTURQ9dzKpofQLobQFlxqENF1JG0GE6sKuRLDtTKaBkJUIRdwpba2g9ge48gMEUUyTbrUutFmk1X6Q7kxDgi1YUSmlpsGYiTXtuy7GCYnaSRu3PczAfe/dd8695z0ecIAKsFVK0DQNLpcL8Xi8KgHZalFRNWe7uyMs2+RtkBQIjQerU/k3uVceHhmdyed/8NbWFg8OXrlXDY+020JdXf2NQMB/yuE4hHw+j5yur1df7h9QvQMXpiKRHSEECyF4cvJlQVG149VwlZ1BX58fsn1H7e29+OhMd7cEAMyM6PTMNAgfFUWrJSIAQgCAYAKIAECABACABGFt7fPPaDRqjItVqyrqG5vGAn7/kMfTBYMIyGQyeD0VMZKYweYGM2ZjpnR+eWVl8V08fnYiNP6t1Jbzc3PzbNryP38stsiKqp0uWuTz+eBqd9/s6uo02vpdPTOXxZuZDB7cfwgQGa0TIEmS7nA4PhhDkgBgdXV1FkTzRYHCtjjS4XZ3mGQmSsdEhKbGRqhqPwRz0ZOlRKImGBy/FA4F31gd8tG2tjaZmf+VUybS2tpaNpfeTMsADu+2xxRw2O12ENFftpTG6XQat26PQZIIzEA2m/1SKBSGGXhhWZmiaifezs7yfhGdnmFF1TqtuM0OksvvlzMnPZ4mq+RkMoVsNlu83ImlxDqATxUFwqHg94aGhsc9PeeuNjc372pRMpnExsZX5HI5xBZjd3aEuBsOBTcs7TGherXaa9eHIqlUioUQltYIIXhkZPT5XnjL7qXi1Wpkm6w5nccGWlpanLJNlkGQyEw1Pui6rs8tLFx+9vTJq30JlKK/3ycRCQkSFZ8Dcwszi4lwUOylgwNUxC8cBKAS7hIWzwAAAABJRU5ErkJggg==) left center no-repeat;background-size:100% 100%}.spbc_auto_link,.spbc_manual_link,.spbc_manual_link_scan{display:inline-block;height:28px;border-width:1px;border-style:solid;-webkit-appearance:none;white-space:nowrap}.spbc_rate_block_stars{margin:1em 0}.star-icon{color:#ddd;font-size:18px;position:relative}.star-icon.full:before{color:#FDE16D;content:'\2605';position:absolute;left:0;text-shadow:0 0 2px rgba(0,0,0,.7)}.spbc_hint{color:#666}p.spbc_hint{margin:0}.spbc_hint_warning{font-size:17px;font-weight:600;text-align:center;color:#eb8f00}.spbc_auto_link,.spbc_manual_link,.spbc_manual_link_scan{font-size:13px;text-decoration:none}.spbc_hint--link{color:#aaa;text-decoration:underline;cursor:pointer}.spbc_hint--top_right{position:relative;float:right;top:0;right:10px}.spbc_auto_link{border-color:#999;-webkit-box-shadow:inset 0 1px 0 rgba(200,200,200,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(200,200,200,.5),0 1px 0 rgba(0,0,0,.15);color:#000;line-height:26px;margin:0;padding:0 10px 1px;-webkit-border-radius:2px;border-radius:2px;box-sizing:border-box}.spbc_auto_link:hover{color:#fff}.spbc_manual_link_scan{color:#fff;background:#026E88;border-color:#026E88;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);line-height:26px;margin:0;padding:0 10px 1px;border-radius:3px;-webkit-border-radius:3px;box-sizing:border-box}.spbc_manual_link{background:#fff;border-color:#026E88;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);color:#026E88!important;line-height:26px;margin:0;padding:0 10px 1px;cursor:pointer;border-radius:3px;-webkit-border-radius:3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.spbc_manual_link:hover,button.ct_support_link{text-decoration:underline}.spbc_page_buttons_links_basic_align{display:flex;align-items:center;justify-content:center;gap:5px}.spbc-btn-as-link{padding:0;margin:0;vertical-align:baseline;color:gray;border:0;border-bottom:1px solid;cursor:pointer}#spbc-account-email[contenteditable=true]{padding:6px;background-color:#fff;border:1px solid #ccc}.spbc_long_desc,.spbc_popup_tip--wrapper{min-width:80px;min-height:80px;max-width:500px;padding:10px;z-index:10}.spbc_dismiss{width:20px;height:20px;border-radius:5px}.spbc-links:visited{color:#fff}.spbc_long_desc{position:absolute;background:#5a5a5a;color:#fff}@media screen and (max-width:900px){.spbc_long_desc{left:inherit!important}.spbc_long_desc__angle_top_left{display:none}}.spbc_long_desc p{color:#fff!important}i.animate-spin{-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;display:inline-block;font-size:25px;line-height:20px;color:rgba(120,200,230,1);margin:25px}@keyframes spin{to{transform:rotate(359deg)}}.spbc_long_desc__angle,.spbc_long_desc__angle_top_left{-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);position:absolute;width:10px;height:10px;background:#5a5a5a}.spbc_long_desc__cancel{position:absolute;top:5px;right:5px;color:rgba(255,255,255,.5)}.spbc_long_desc__cancel:hover{color:#fff}.spbc_long_desc__link,.spbc_long_desc__title{color:rgba(120,200,230,1)}.spbc_long_desc__angle{top:5px;left:-17px;transform:rotate(135deg);-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.spbc_long_desc__angle_top_left{top:-10px;left:-9px;transform:rotate(135deg);-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.spbc_long_desc__title{margin:0}.spbc_long_desc__link:hover{color:rgba(140,220,250,1)}.spbc_long_desc h4{color:#50a0be;margin:10px 0 3px}.spbc_long_desc span{margin:0 0 0 10px;display:inline-block}.spbc_long_desc img{width:300px}.spbc_popup_tip--icon---show:hover{color:#aaa;cursor:pointer}.spbc_popup_tip--wrapper{position:absolute;background:#5a5a5a;color:#fff}.spbc_popup_tip--icon---cancel{position:absolute;top:0;right:5px;color:rgba(255,255,255,.5)}.spbc_popup_tip--icon---cancel:hover{color:#fff}.spbc_popup_tip--angle{position:absolute;top:5px;left:-17px;width:10px;height:10px;background:#5a5a5a;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg);-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%}.spbc_popup_tip--title{color:rgba(120,200,230,1);margin:0}.spbc_popup_tip--text{color:#fff!important}tr:hover .spbc_hint--wrapper{display:none}.spbc_log-wrapper{padding:5px;border:1px solid #000;width:98%;min-height:300px;height:300px;border-bottom:5px dashed #5a5a5a}.spbc_log-wrapper .panel-body{height:100%;overflow-y:auto}.spbc_log-line{margin:0;padding:0 5px}.spbc_log-line:nth-child(odd){background:#d3d3d3}.spbc_log-block_header{margin:10px 0}.spbc_log-input--checkbox,.spbc_log-label--checkbox{width:auto}button.ct_support_link{border:none;background:0 0;color:#666;cursor:pointer}#spbc-modal-content{text-align:center}#spbc-modal-content>*{display:block;width:100%;margin:0}.spbc-modal-header{font-size:15px;font-weight:500}.spbc-modal-buttons-block{display:flex!important;gap:10px;justify-content:center}.spbc-modal-button{width:40%;height:35px;font-size:14px;font-weight:500;border:1px solid #60656b;background:#fff;border-radius:5px;cursor:pointer}.spbc-modal-button:hover{background:#2ea2cc;color:#fff;border:1px solid #2ea2cc}.spbc-modal-file_path{color:#026E88}.spbc-modal-file_path_wrapper{margin:4% 0 1%;padding:5px;border:1px solid #F5F5FD;border-radius:4px}.spbc-popup-msg{width:98%;height:15px;text-align:center;padding:4px;border-radius:7px;position:relative;top:0;right:0;bottom:0;left:0;margin:auto}.popup--green{background:#DFD;color:#060;border:1px solid #060}.popup--red{background:#FDD;color:#600;border:1px solid #600}#spbcscan-results-log-module{min-height:300px;height:300px;border-bottom:5px dashed #5a5a5a}#spbcscan-results-log-module .panel-body{height:100%;overflow-y:auto}#spbcscan-scanner-caption h4{margin:10px 0;font-size:14px}#spbcscan-results-log-caption p{font-size:13px;margin:0 0 6px}#spbcscan-scanner-caption{display:flex;flex-wrap:wrap;flex-direction:row-reverse}#spbcscan-scanner-caption .column:first-child{width:75%;flex:0 0 75%}#spbcscan-scanner-caption .column:last-child{width:25%;flex:0 0 25%;padding-right:10px;box-sizing:border-box}.spbc-scan-log-title{color:#1d2327;font-size:1.3em;margin:0 0 15px!important;font-weight:600}.spbc--status{position:relative;padding-left:26px}.spbc--marker-green::before,.spbc--marker-red::before,.spbc--marker-yellow::before{content:'';position:absolute;width:10px;height:10px;border-radius:50%;left:10px;top:4px}.spbc--marker-green::before{background:#1dda23}.spbc--marker-yellow::before{background:#ffb000}.spbc--marker-red::before{background:#d63638}button#spbc_setting_get_key_auto:disabled{background:#ccc;color:#111;text-decoration:none}.spbc_critical_updates-names{text-transform:uppercase;font-weight:500}.spbc_critical_updates-h_names{font-size:15px}.spbc_critical_updates-legend{border:1px solid #eee;padding:0 0 0 10px;margin:5px 0 0;color:#666}.spbc_critical_updates-no_vulnerabilities{color:green;font-size:15px;font-weight:500;margin:5px 0 0 30px}.spbct_notice{display:flex;justify-content:space-between}.spbct_notice-dismiss{position:relative;top:0;right:1px;border:none;margin:0;padding:9px;background:0 0;color:#787c82;cursor:pointer}.spbc_accordion_header_caption__update_status{display:inline-flex;flex-direction:row;flex-wrap:nowrap;width:45%;align-items:flex-end;justify-content:flex-end}.spbc_accordion_header_caption__updated{display:inline;color:#FFF;font-weight:700}.spbc_setting__textarea{width:400px;height:150px}.spbc-settings-general-wrapper{display:flex;flex-direction:row;flex-wrap:nowrap}.spbc-quicknav--bar_wrapper{display:flex;flex-direction:column;flex-wrap:nowrap;justify-content:flex-start;height:fit-content;position:sticky;top:5vh}.spbc-quicknav--links_wrapper{display:flex;flex-direction:column;flex-wrap:nowrap;justify-content:center;padding:3px;border:1px solid #e5e5e5;margin:10px}.spbc-quicknav--link{margin:3px;width:-webkit-fill-available;width:-moz-available;text-align:left;display:flex;flex-direction:row;justify-content:flex-start}#spbc_quicknav--header{color:#026E88;text-align:center;margin:5px 0}.spbc_quicknav--save_button{margin:10px 5px!important;height:40px}.spbc_settings--save_button_custom{position:sticky;bottom:0;display:flex;justify-content:center;flex-direction:row;align-items:baseline;flex-wrap:nowrap;padding:15px 0}html{scroll-behavior:smooth} \ No newline at end of file diff --git a/css/src/spbc-settings.css b/css/src/spbc-settings.css index 12a0b0624..24cf87081 100644 --- a/css/src/spbc-settings.css +++ b/css/src/spbc-settings.css @@ -55,6 +55,7 @@ .spbc---gray{color: gray;} .spbc---red{color: red;} +.spbc---green{color: #037603;} .spbc_bold{font-weight: 800;} diff --git a/inc/spbc-settings.php b/inc/spbc-settings.php index 66994e96d..3dcbae5c5 100644 --- a/inc/spbc-settings.php +++ b/inc/spbc-settings.php @@ -4407,11 +4407,11 @@ function spbc_list_table__get_args_by_type($table_type) 'if_empty_items' => __('There are no automatically cured files.', 'security-malware-firewall'), 'columns' => array( 'cb' => array('heading' => '', 'class' => 'check-column', 'width_percent' => 2), - 'real_path' => array('heading' => 'Path','primary' => true,), - 'last_cure_date' => array('heading' => 'Cure date',), - 'cured' => array('heading' => 'Status',), - 'cci_cured' => array('heading' => 'Threats cured count',), - 'fail_reason' => array('heading' => 'Reason of fail',), + 'real_path' => array('heading' => 'Path','primary' => true, 'width_percent' => 27), + 'last_cure_date' => array('heading' => 'Cure date', 'width_percent' => 10), + 'cured' => array('heading' => 'Status', 'width_percent' => 13), + 'weak_spots_cured' => array('heading' => 'Threats cured', 'width_percent' => 24), + 'weak_spots_uncured' => array('heading' => 'Threats uncured', 'width_percent' => 24), ), 'order_by' => array('real_path' => 'asc'), 'pagination' => array( @@ -4422,7 +4422,7 @@ function spbc_list_table__get_args_by_type($table_type) $cure_log = new Scanner\CureLog\CureLog(); if ( !$cure_log->hasFailedCureTries() ) { - unset($args['columns']['fail_reason']); + unset($args['columns']['weak_spots_uncured']); } break; case 'skipped': @@ -5785,7 +5785,7 @@ function spbc_scanner__cure_log_data_prepare(&$table) if ($table->items_count) { foreach ($table->rows as $_key => $row) { // Add Cure action if file was not cure - if ($row->cured !== 'FAILED') { + if ($row->cured === 'CURED') { unset($row->actions['cure']); } @@ -5799,9 +5799,9 @@ function spbc_scanner__cure_log_data_prepare(&$table) 'actions' => $row->actions, 'real_path' => $row->real_path, 'last_cure_date' => $row->last_cure_date, - 'cured' => $cure_status_string, - 'cci_cured' => $row->cci_cured, - 'fail_reason' => $row->fail_reason, + 'cured' => $cure_status_string, + 'weak_spots_cured' => $row->weak_spots_cured, + 'weak_spots_uncured' => $row->weak_spots_uncured, ); } } diff --git a/lib/CleantalkSP/SpbctWP/DB/SQLSchema.php b/lib/CleantalkSP/SpbctWP/DB/SQLSchema.php index dd4dd240a..d174590f7 100644 --- a/lib/CleantalkSP/SpbctWP/DB/SQLSchema.php +++ b/lib/CleantalkSP/SpbctWP/DB/SQLSchema.php @@ -253,6 +253,8 @@ class SQLSchema extends \CleantalkSP\Common\DB\SQLSchema array('field' => 'cured_hash', 'type' => 'char(32)', 'null' => 'no'), array('field' => 'real_path', 'type' => 'varchar(512)', 'null' => 'no'), array('field' => 'cured', 'type' => 'tinyint', 'null' => 'no',), + array('field' => 'weak_spots_cured', 'type' => 'varchar(512)', 'null' => 'no',), + array('field' => 'weak_spots_uncured', 'type' => 'varchar(512)', 'null' => 'no',), array('field' => 'has_backup', 'type' => 'tinyint', 'null' => 'no',), array('field' => 'cci_cured', 'type' => 'tinyint', 'null' => 'yes', 'default' => 'NULL'), array('field' => 'fail_reason', 'type' => 'varchar(512)', 'null' => 'yes', 'default' => 'NULL'), diff --git a/lib/CleantalkSP/SpbctWP/Scanner/Cure.php b/lib/CleantalkSP/SpbctWP/Scanner/Cure.php index 79065ed68..4f2e82d6c 100644 --- a/lib/CleantalkSP/SpbctWP/Scanner/Cure.php +++ b/lib/CleantalkSP/SpbctWP/Scanner/Cure.php @@ -30,34 +30,47 @@ class Cure public $result = true; + public $weak_spots_result = array(); + public function __construct($file) { global $wpdb; $weak_spots = json_decode($file['weak_spots'], true); + $counter = 0; if ( ! empty($weak_spots['SIGNATURES']) ) { foreach ( $weak_spots['SIGNATURES'] as $_string => $signatures_in_string ) { + $this->weak_spots_result[$counter] = array( + 'weak_spots_file_line' => $_string, + 'signature_id' => '', + 'cured' => 0, + 'error' => '' + ); foreach ( $signatures_in_string as $signature_id ) { + $this->weak_spots_result[$counter]['signature_id'] = $signature_id; $tmp = $wpdb->get_results( 'SELECT * FROM ' . SPBC_TBL_SCAN_SIGNATURES . ' WHERE id = "' . $signature_id . '"', OBJECT ); $this->signature = $tmp[0]; - - $result = $this->signatureCure($file, $this->signature); - if ( ! empty($result['error']) ) { - $this->result = $result; - return; - } + $result = $this->signatureCure($file, $this->signature, $this->weak_spots_result[$counter]); + $this->weak_spots_result[$counter]['cured'] = (int)$result; } + $counter++; } } else { $this->result = array('error' => 'COULD NOT GET SIGNATURE FROM DB'); } } - public function signatureCure($file, $signature) + /** + * @param $file + * @param $signature + * @param array $weak_spots_log + * @return bool + */ + public function signatureCure($file, $signature, &$weak_spots_log) { global $spbc; @@ -114,7 +127,8 @@ public function signatureCure($file, $signature) $this->objects[] = $object; if ( ! empty($result['error']) ) { - return $result; + $weak_spots_log['error'] = $result['error']; + return false; } if ( ! $spbc->settings['there_was_signature_treatment'] ) { @@ -123,7 +137,10 @@ public function signatureCure($file, $signature) } } } + return true; } + $weak_spots_log['error'] = __('No cure instruction found for line.', 'security-malware-firewall'); + return false; } /** diff --git a/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLog.php b/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLog.php index cbdfaa588..44b4deae1 100644 --- a/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLog.php +++ b/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLog.php @@ -26,24 +26,13 @@ public function getCountData() return (int)$result->cnt; } - /** - * Clear cure log table. - * @return void - * @psalm-suppress PossiblyUnusedMethod - */ - public function clearLogDataFromFailedCures() - { - $query = 'DELETE FROM ' . SPBC_TBL_CURE_LOG . ' WHERE cured <> 1'; - $this->db->execute($query); - } - /** * Check if there is failed cure tries * @return bool */ public function hasFailedCureTries() { - $query = 'SELECT COUNT(*) as cnt FROM ' . SPBC_TBL_CURE_LOG . ' WHERE cured = 0'; + $query = 'SELECT COUNT(*) as cnt FROM ' . SPBC_TBL_CURE_LOG . ' WHERE cured <> 1'; $result = $this->db->fetch($query); return (bool)$result->cnt; } @@ -56,7 +45,7 @@ public function getDataToAccordion($offset = 0, $amount = 20) { $offset = intval($offset); $amount = intval($amount); - $query = 'SELECT fast_hash, real_path, cured, cci_cured, has_backup, fail_reason, last_cure_date FROM ' . SPBC_TBL_CURE_LOG . ' ORDER BY last_cure_date DESC LIMIT ' . $offset . ',' . $amount . ';'; + $query = 'SELECT fast_hash, real_path, cured, cci_cured, weak_spots_cured, weak_spots_uncured, has_backup, fail_reason, last_cure_date FROM ' . SPBC_TBL_CURE_LOG . ' ORDER BY cured LIMIT ' . $offset . ',' . $amount . ';'; $result = $this->db->fetchAll($query, OBJECT); if ( empty($result) ) { @@ -64,11 +53,34 @@ public function getDataToAccordion($offset = 0, $amount = 20) } foreach ($result as $row) { - if ( isset($row->cured) && $row->cured == 1 ) { - $row->cured = 'CURED'; + if ( isset($row->cured) ) { + if ( $row->cured == '1' ) { + $row->cured = 'CURED'; + } else if ( $row->cured == '0' ) { + $row->cured = 'FAILED'; + } else { + $row->cured = 'PARTIALLY CURED'; + } + } + + if ( !empty($row->weak_spots_cured) && is_string($row->weak_spots_cured) ) { + $template = '
'; + $template .= self::getThreatTemplate($row->weak_spots_cured, true); + $template .= '
'; + $row->weak_spots_cured = $template; + } else { + $row->weak_spots_cured = '-'; + } + + if ( !empty($row->weak_spots_uncured) && is_string($row->weak_spots_uncured) ) { + $template = '
'; + $template .= self::getThreatTemplate($row->weak_spots_uncured, false); + $template .= '
'; + $row->weak_spots_uncured = $template; } else { - $row->cured = 'FAILED'; + $row->weak_spots_uncured = '-'; } + if ( !empty($row->last_cure_date) ) { $row->last_cure_date = date("M d Y H:i:s", $row->last_cure_date); } else { @@ -78,6 +90,48 @@ public function getDataToAccordion($offset = 0, $amount = 20) return $result; } + private static function getThreatTemplate($weak_spots_json, $is_cured = true) + { + $out = ''; + $array = json_decode($weak_spots_json, true); + if ( !is_array($array) ) { + $array = array(); + } + + $details_class = $is_cured ? 'spbc-icon-ok spbc---green' : 'spbc-icon-cancel spbc---red'; + + $out .= count($array) + ? '' . __('Total', "security-malware-firewall") . ': ' . count($array) . ' ' + : __('-', "security-malware-firewall"); + + + foreach ($array as $data) { + $line = isset($data['line']) ? $data['line'] : ''; + $signature_id = isset($data['signature_id']) ? $data['signature_id'] : ''; + $error = isset($data['error']) ? $data['error'] : ''; + $out .= sprintf( + ' +
+

' + . __('Code line number', "security-malware-firewall") . ': %s, ' + . __('SID', "security-malware-firewall") . ': %s +
+

+ ' + . (!empty($error) ? __('Error:', "security-malware-firewall") : 'OK') . ' %s + +

+

+
+ ', + $line, + $signature_id, + $error + ); + } + return empty($out) ? '-' : $out; + } + /** * Returns cure log data for PDF report * @return array|object @@ -94,11 +148,16 @@ public function getDataToPDF() } foreach ($result as &$row) { - if ( isset($row['cured']) && $row['cured'] == 1 ) { - $row['cured'] = 'CURED'; - } else { - $row['cured'] = 'FAILED'; + if ( isset($row->cured) ) { + if ( $row->cured == '1' ) { + $row['cured'] = 'CURED'; + } else if ( $row->cured === '0' ) { + $row['cured'] = 'FAILED'; + } else { + $row['cured'] = 'PARTIALLY CURED'; + } } + if ( !empty($row['last_cure_date']) ) { $row['last_cure_date'] = date("M d Y H:i:s", $row['last_cure_date']); } else { @@ -123,8 +182,8 @@ public function logCureResult(CureLogRecord $cure_log_record) $this->db->prepare( 'INSERT INTO ' . SPBC_TBL_CURE_LOG - . ' (`fast_hash`, `full_hash`, `cured_hash`, `real_path`, `cured`, `cci_cured`,`has_backup`,`fail_reason`, `last_cure_date`, `scanner_start_local_date`) VALUES' - . "(%s, %s, %s, %s, %d, %s, %d, %s, %d, %s)" + . ' (`fast_hash`, `full_hash`, `cured_hash`, `real_path`, `cured`, `weak_spots_cured`, `weak_spots_uncured`, `cci_cured`, `has_backup`,`fail_reason`, `last_cure_date`, `scanner_start_local_date`) VALUES' + . "(%s, %s, %s, %s, %d, %s, %s, %d, %d, %s, %d, %s)" . 'ON DUPLICATE KEY UPDATE cured = VALUES(`cured`), last_cure_date = VALUES(`last_cure_date`), @@ -133,12 +192,16 @@ public function logCureResult(CureLogRecord $cure_log_record) cci_cured = VALUES(`cci_cured`), has_backup = VALUES(`has_backup`), fail_reason = VALUES(`fail_reason`), + weak_spots_cured = VALUES(`weak_spots_cured`), + weak_spots_uncured = VALUES(`weak_spots_uncured`), last_cure_date = VALUES(`last_cure_date`)', array($cure_log_record->fast_hash, $cure_log_record->full_hash, $cure_log_record->cured_hash, $cure_log_record->real_path, $cure_log_record->cured, + $cure_log_record->weak_spots_cured, + $cure_log_record->weak_spots_uncured, $cure_log_record->cci_cured, $cure_log_record->has_backup, $cure_log_record->fail_reason, @@ -146,27 +209,36 @@ public function logCureResult(CureLogRecord $cure_log_record) $cure_log_record->scanner_start_local_date, ) )->execute(); + } -// $this->db->prepare( -// 'INSERT INTO ' . SPBC_TBL_CURE_LOG -// . ' (`fast_hash`, `full_hash`, `cured_hash`, `real_path`, `cured`, `cci_cured`,`has_backup`,`fail_reason`, `last_cure_date`, `scanner_start_local_date`) VALUES' -// . "(%s, %s, %s, %s, %d, %s, %d, %s, %d, %s)" -// . 'ON DUPLICATE KEY UPDATE -// cured = VALUES(`cured`), -// last_cure_date = VALUES(`last_cure_date`), -// fail_reason = VALUES(`fail_reason`), -// scanner_start_local_date = VALUES(`scanner_start_local_date`)', -// array($cure_log_record->fast_hash, -// $cure_log_record->full_hash, -// $cure_log_record->cured_hash, -// $cure_log_record->real_path, -// $cure_log_record->cured, -// $cure_log_record->cci_cured, -// $cure_log_record->has_backup, -// $cure_log_record->fail_reason, -// $cure_log_record->last_cure_date, -// $cure_log_record->scanner_start_local_date, -// ) -// )->execute(); + /** + * @param $weak_spots_result + * @return string[] + */ + public static function parseWeakSpotsFromCureResult($weak_spots_result) + { + $cured = array(); + $uncured = array(); + foreach ($weak_spots_result as $_counter => $data) { + $result_row = array( + 'line' => isset($data['weak_spots_file_line']) ? $data['weak_spots_file_line'] : '', + 'signature_id' => isset($data['signature_id']) ? $data['signature_id'] : '', + 'error' => isset($data['error']) ? $data['error'] : '', + ); + if (isset($data['cured']) && $data['cured'] === 1) { + $cured[] = $result_row; + } else { + $uncured[] = $result_row; + } + } + $cured = json_encode($cured); + $uncured = json_encode($uncured); + if (empty($cured)) { + $cured = ''; + } + if (empty($cured)) { + $uncured = ''; + } + return array('cured' => $cured, 'uncured' => $uncured); } } diff --git a/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLogRecord.php b/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLogRecord.php index 8801772d0..b9c69a9d8 100644 --- a/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLogRecord.php +++ b/lib/CleantalkSP/SpbctWP/Scanner/CureLog/CureLogRecord.php @@ -27,6 +27,14 @@ class CureLogRecord extends DTO * @var int */ public $cured = 0; + /** + * @var string + */ + public $weak_spots_cured = ''; + /** + * @var string + */ + public $weak_spots_uncured = ''; /** * @var int */ @@ -59,6 +67,8 @@ class CureLogRecord extends DTO 'cured_hash', 'real_path', 'cured', + 'weak_spots_cured', + 'weak_spots_uncured', 'cci_cured', 'fail_reason', 'last_cure_date', @@ -70,4 +80,19 @@ public function __construct($data) { parent::__construct($data); } + + /** + * @param $prop + * @return array + */ + public function getPropAsArray($prop = '') + { + if (is_string($prop) && isset($this->$prop) && is_string($this->$prop)) { + $json = json_decode($this->$prop, true); + if ($json !== false) { + return $json; + } + } + return array(); + } } diff --git a/lib/CleantalkSP/SpbctWP/Scanner/Stages/CureStage.php b/lib/CleantalkSP/SpbctWP/Scanner/Stages/CureStage.php index a14875cc1..c56e4eaa8 100644 --- a/lib/CleantalkSP/SpbctWP/Scanner/Stages/CureStage.php +++ b/lib/CleantalkSP/SpbctWP/Scanner/Stages/CureStage.php @@ -161,15 +161,17 @@ public function processCure($file) 'cured_hash' => '', 'real_path' => isset($file['path']) ? $file['path'] : '', 'cured' => 0, - 'has_backup' => 0, + 'weak_spots_cured' => '', + 'weak_spots_uncured' => '', 'cci_cured' => null, + 'has_backup' => 0, 'fail_reason' => '', 'last_cure_date' => time(), 'heuristic_rescan_result' => null, 'scanner_start_local_date' => $spbc->data['scanner']['scanner_start_local_date'], )); - $cure_log_record = $this->preCheckFile($file, $cure_log_record, $weak_spots_decoded); + $cure_log_record = $this->preCheckFile($file, $cure_log_record); if ( $cure_log_record->fail_reason ) { return $cure_log_record; @@ -177,18 +179,25 @@ public function processCure($file) //process Cure $cure_file_result = $this->doCureFile($file); + if ( isset($cure_file_result->result['error']) ) { + $cure_log_record->cured = 0; + $cure_log_record->fail_reason = $cure_file_result->result['error']; + return $cure_log_record; + } + $weak_spots_result = CureLog::parseWeakSpotsFromCureResult($cure_file_result->weak_spots_result); + $cure_log_record->weak_spots_cured = $weak_spots_result['cured']; + $cure_log_record->weak_spots_uncured = $weak_spots_result['uncured']; //update hash after cure $cure_log_record->cured_hash = md5_file(spbc_get_root_path() . $file['path']); //update table $cure_log_record = $this->updateScanResultsTableOnAfterCure( - $cure_file_result, $file, $cure_log_record, $weak_spots_decoded ); //if cured, rescan file with heuristic - if ( empty($cure_log_record->fail_reason) ) { + if ( $cure_log_record->cured !== 0 ) { $recheck_result = $this->rescanFileHeuristic($file); $cure_log_record->heuristic_rescan_result = json_encode($recheck_result); //if rescanned, update results table @@ -205,27 +214,18 @@ public function processCure($file) * * @param array $file An associative array representing the file to be checked. * @param CureLogRecord $cure_log_record An instance of the CureLogRecord class. This is used to log the results of the cure process. - * @param array $weak_spots_decoded An associative array representing the JSON decoded weak spots in the file. * * @return CureLogRecord The updated CureLogRecord instance. This may contain a failure reason if the file cannot be cured. */ - private function preCheckFile($file, $cure_log_record, $weak_spots_decoded) + private function preCheckFile($file, $cure_log_record) { - - //check if even one of file signatures is curable - if ( !$this->fileHasCurableSignatures($weak_spots_decoded) ) { - //can not be cured, log this and return cure_log_record - $cure_log_record->cured = 0; - $cure_log_record->fail_reason = 'No CCI found.'; - return $cure_log_record; - } - spbc_backup__files_with_signatures(true); //check if file has backup if ( !$this->fileHasBackup($file) ) { //cure is not safe without backups, log this and return cure_log_record - $cure_log_record->fail_reason = 'File has no backup.'; + $cure_log_record->cured = 0; + $cure_log_record->fail_reason = __('File has no backup.', "security-malware-firewall"); return $cure_log_record; } else { $cure_log_record->has_backup = 1; @@ -234,40 +234,6 @@ private function preCheckFile($file, $cure_log_record, $weak_spots_decoded) return $cure_log_record; } - /** - * This method checks if the file has curable signatures. - * - * @param array $weak_spots_on_file An associative array representing the weak spots in the file. - * - * @return bool Returns true if the file has curable signatures, false otherwise. - */ - public function fileHasCurableSignatures($weak_spots_on_file) - { - //init empty string of signatures - $signatures_in_file = ''; - if ( !empty($weak_spots_on_file['SIGNATURES']) ) { - $signatures_in_file = array(); - foreach ( $weak_spots_on_file['SIGNATURES'] as $signatures_in_string ) { - $signatures_in_file = array_merge( - $signatures_in_file, - array_diff($signatures_in_string, $signatures_in_file) - ); - } - $signatures_in_file = implode(',', $signatures_in_file); - } - - //check if signature can be cured - has instructions - $signatures_with_cci = !empty($signatures_in_file) - ? $this->db->fetchAll( - 'SELECT * ' - . ' FROM ' . SPBC_TBL_SCAN_SIGNATURES - . ' WHERE id IN (' . $signatures_in_file . ') AND cci IS NOT NULL AND cci <> \'\'' - . ' LIMIT 1' - ) - : false; - return is_array($signatures_with_cci) && !empty($signatures_with_cci); - } - /** * This method checks if the file has a backup. * @@ -295,49 +261,71 @@ private function doCureFile($file) /** * This method updates the scan results table after the cure process. * - * @param Cure $cure_result The result of the cure process. This is an instance of the Cure class. * @param array $file An associative array representing the file that was cured. * @param CureLogRecord $cure_log_record An instance of the CureLogRecord class. This is used to log the results of the cure process. * @param array $weak_spots_decoded An associative array representing the JSON decoded weak spots in the file. * * @return CureLogRecord The updated CureLogRecord instance. This may contain a failure reason if the file cannot be cured. */ - private function updateScanResultsTableOnAfterCure($cure_result, $file, $cure_log_record, $weak_spots_decoded) + private function updateScanResultsTableOnAfterCure($file, $cure_log_record, $weak_spots_decoded) { - if ( !empty($cure_result->result['error']) ) { + $log_uncured = $cure_log_record->getPropAsArray('weak_spots_uncured'); + $log_cured = $cure_log_record->getPropAsArray('weak_spots_cured'); + + if ( !empty($log_uncured) && !empty($log_cured) ) { //if Cure process errored keep the reason - $cure_log_record->fail_reason = $cure_result->result['error']; - } else { - //new log way + $cure_log_record->fail_reason = __('Partially success, has uncured weak spots.', 'security-malware-firewall'); + $cure_log_record->cured = -1; + } else if ( empty($log_uncured) && !empty($log_cured) ) { $cure_log_record->cured = 1; - $cure_log_record->cci_cured = count($weak_spots_decoded['SIGNATURES']); + } else { + $cure_log_record->fail_reason = __('Has uncured weak spots.', 'security-malware-firewall'); + $cure_log_record->cured = 0; + } - //file is cured, remove signatures weakspots - unset($weak_spots_decoded['SIGNATURES']); + $weak_spots_lines_to_remove = array_map( + function ($weak_spot) { + return $weak_spot['line']; + }, + $log_cured + ); - //process any other weakspots to save them - if ( empty($weak_spots_decoded) ) { - $weak_spots_encoded = 'NULL'; - $severity = 'NULL'; - $status = 'OK'; - } else { - $weak_spots_encoded = QueueHelper::prepareParamForSQLQuery(json_encode($weak_spots_decoded)); - $severity = $file['severity']; - $status = $file['status']; + //file is partially or fully cured, remove signatures weakspots + if ( !empty($weak_spots_lines_to_remove) ) { + foreach ($weak_spots_decoded['SIGNATURES'] as $line => $_data) { + if ( in_array($line, $weak_spots_lines_to_remove) ) { + unset($weak_spots_decoded['SIGNATURES'][$line]); + } } + } - //update scan results table - $this->db->execute( - 'UPDATE ' . SPBC_TBL_SCAN_FILES - . ' SET ' - . 'weak_spots = ' . $weak_spots_encoded . ',' - . 'severity = "' . $severity . '",' - . 'full_hash = "' . $cure_log_record->cured_hash . '",' - . 'status = "' . $status . '"' - . ' WHERE fast_hash = "' . $file['fast_hash'] . '";' - ); + if (empty($weak_spots_decoded['SIGNATURES'])) { + unset($weak_spots_decoded['SIGNATURES']); } + //process any other weakspots to save them + if ( empty($weak_spots_decoded) ) { + $weak_spots_encoded = 'NULL'; + $severity = 'NULL'; + $status = 'OK'; + } else { + $weak_spots_encoded = QueueHelper::prepareParamForSQLQuery(json_encode($weak_spots_decoded)); + $severity = $file['severity']; + $status = $file['status']; + } + + //update scan results table + $this->db->execute( + 'UPDATE ' . SPBC_TBL_SCAN_FILES + . ' SET ' + . 'weak_spots = ' . $weak_spots_encoded . ',' + . 'severity = "' . $severity . '",' + . 'full_hash = "' . $cure_log_record->cured_hash . '",' + . 'status = "' . $status . '"' + . ' WHERE fast_hash = "' . $file['fast_hash'] . '";' + ); + + return $cure_log_record; }