diff --git a/inc/spbc-settings.php b/inc/spbc-settings.php
index 7825b8305..631d7e2b0 100644
--- a/inc/spbc-settings.php
+++ b/inc/spbc-settings.php
@@ -2978,6 +2978,7 @@ function spbc_field_scanner()
echo
'
'
+ . '' . __('Self check', 'security-malware-firewall') . ' -> '
. '' . __('Receiving core hashes', 'security-malware-firewall') . ' -> '
. '' . __('Receiving plugin and theme hashes', 'security-malware-firewall') . ' -> '
. '' . __('Preparing', 'security-malware-firewall') . ' -> '
diff --git a/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php b/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php
index 600e046b2..40cdef815 100755
--- a/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php
+++ b/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php
@@ -31,6 +31,7 @@
use CleantalkSP\SpbctWP\Helpers\Helper as QueueHelper;
use CleantalkSP\SpbctWP\Helpers\CSV;
use CleantalkSP\SpbctWP\RemoteCalls;
+use CleantalkSP\SpbctWP\Scanner\Stages\SelfCheckStage;
use CleantalkSP\SpbctWP\Scanner\Stages\SendResultsStage;
class ScannerQueue
@@ -39,6 +40,7 @@ class ScannerQueue
* @var string[] List of scan stages
*/
public static $stages = array(
+ 'self_check',
'get_cms_hashes',
'get_modules_hashes',
'clean_results',
@@ -306,6 +308,14 @@ public static function controllerFront()
wp_send_json($out);
}
+ public function self_check() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+ {
+ $selfCheck = new SelfCheckStage();
+ $selfCheck->run();
+
+ return ['end' => true];
+ }
+
/**
* Receive CMS hash
*
diff --git a/lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php b/lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php
new file mode 100644
index 000000000..f8b57a1cc
--- /dev/null
+++ b/lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php
@@ -0,0 +1,185 @@
+url = $this->setUrl();
+ $this->seal = $this->calculateSeal();
+ }
+
+ /**
+ * Run self check and cure
+ */
+ public function run()
+ {
+ $check = $this->check();
+
+ if (count($check) > 0) {
+ // TODO: Send to Cleantalk
+ // TODO: log
+
+ // $this->sendToCleantalk($check);
+ // $this->writeLog($check);
+ $this->cure($check);
+ }
+
+ return true;
+ }
+
+ /**
+ * Check files
+ */
+ private function check()
+ {
+ $files = $this->getFiles('check');
+
+ foreach ($files as $key) {
+ if ($key === $this->seal) {
+ unset($files[$key]);
+ }
+ }
+
+ return $files;
+ }
+
+ /**
+ * Set url
+ */
+ private function setUrl()
+ {
+ $url = 'https://plugins.svn.wordpress.org/security-malware-firewall/tags/';
+ $version = preg_replace('/[^\d.]/', '', SPBC_VERSION);
+ $url .= $version . '/';
+
+ $response = wp_remote_get($url . 'security-malware-firewall.php');
+ $code = wp_remote_retrieve_response_code($response);
+ if ($code !== 200) {
+ $url = 'https://plugins.svn.wordpress.org/security-malware-firewall/trunk/';
+ }
+
+ return $url;
+ }
+
+ /**
+ * Calculate seal
+ */
+ private function calculateSeal()
+ {
+ $files = $this->getFiles('calculate');
+
+ $frequency = array_count_values($files);
+ arsort($frequency);
+
+ reset($frequency);
+ return key($frequency);
+ }
+
+ /**
+ * Get files
+ */
+ private function getFiles($type)
+ {
+ $result = [];
+
+ $iterator = new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator($this->dir, \RecursiveDirectoryIterator::SKIP_DOTS),
+ \RecursiveIteratorIterator::SELF_FIRST,
+ \RecursiveIteratorIterator::CATCH_GET_CHILD
+ );
+
+ foreach ($iterator as $fileinfo) {
+ if ($fileinfo->getFilename() === '.' || $fileinfo->getFilename() === '..') {
+ continue;
+ }
+
+ if ($fileinfo->getExtension() !== 'php') {
+ continue;
+ }
+
+ if ($fileinfo->getFilename() === 'SelfCheck.php') {
+ continue;
+ }
+
+ if (strpos($fileinfo->getPathname(), $this->dir . 'vendor') !== false) {
+ continue;
+ }
+
+ if (strpos($fileinfo->getPathname(), $this->dir . 'node_modules') !== false) {
+ continue;
+ }
+
+ if (strpos($fileinfo->getPathname(), $this->dir . 'backups') !== false) {
+ continue;
+ }
+
+ if ($type === 'calculate') {
+ $result[] = $fileinfo->getMTime();
+ continue;
+ }
+
+ if ($type === 'check') {
+ $result[$fileinfo->getMTime()] = str_replace($this->dir, '', $fileinfo->getPathname());
+ continue;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Cure
+ */
+ private function cure($check)
+ {
+ foreach ($check as $file) {
+ $response = wp_remote_get($this->url . $file);
+ $code = wp_remote_retrieve_response_code($response);
+
+ if ($code !== 200) {
+ // TODO: alient file, handle it
+ continue;
+ }
+
+ if (is_wp_error($response)) {
+ // TODO: handle error
+ continue;
+ }
+
+ $body = wp_remote_retrieve_body($response);
+ if (empty($body)) {
+ // TODO: handle error
+ continue;
+ }
+
+ $success = file_put_contents($this->dir . $file, $body);
+ if (!$success) {
+ // TODO: handle error
+ continue;
+ }
+
+ // TODO: log
+ }
+ }
+}