<?php
defined( 'ABSPATH' ) or die( 'Something went wrong.' );

/**
 * Malware Scanners scan class.
 *
 * @package SecuPress
 * @subpackage SecuPress_Scan
 * @since 2.6
 */
class SecuPress_Scan_Malware_Scanners extends SecuPress_Scan implements SecuPress_Scan_Interface {

	/** Constants. ============================================================================== */

	/**
	 * Class version.
	 *
	 * @var (string)
	 */
	const VERSION = '1.0';


	/** Properties. ============================================================================= */

	/**
	 * The reference to the *Singleton* instance of this class.
	 *
	 * @var (object)
	 */
	protected static $_instance;

	/**
	 * Tells if a scanner is fixable by SecuPress. The value "pro" means it's fixable only with the version PRO.
	 *
	 * @var (bool|string)
	 */
	protected $fixable = false;


	/** Init and messages. ====================================================================== */

	/**
	 * Init.
	 *
	 * @since 2.6
	 */
	protected function init() {
		$this->title    = __( 'Check if malware scanners have detected suspicious files.', 'secupress' );
		$this->more     = __( 'The malware scanners analyze your files and database to detect suspicious content, modified files, or files that should not be part of your WordPress installation.', 'secupress' );
		$this->more_fix = static::get_messages( 300 );
	}


	/**
	 * Get messages.
	 *
	 * @since 2.6
	 *
	 * @param (int) $message_id A message ID.
	 *
	 * @return (string|array) A message if a message ID is provided. An array containing all messages otherwise.
	 */
	public static function get_messages( $message_id = null ) {
		$_200 = sprintf( __( 'Open %sMalware Scanner%s.', 'secupress' ), '<a href="' . secupress_admin_url( 'modules','file-system' ) . '">', '</a>' );
		$_100 = ! secupress_is_pro() ? sprintf( __( 'The %sPRO version%s will be more accurate.', 'secupress' ), '<a href="' . secupress_admin_url( 'get-pro' ) . '">', '</a>' ) : ' ' . $_200;
		$messages = array(
			// "good"
			0   => __( 'No suspicious files or content detected by the malware scanners.', 'secupress' ),
			// "warning"
			100 => sprintf( __( 'Your installation may contain malwares hidden in files or content.%s', 'secupress' ), $_100 ),
			// "bad"
			200 => sprintf( __( 'The malware scanners have detected suspicious files or content on your installation. %s', 'secupress' ), $_200 ),
			// "cantfix"
			300 => __( 'Cannot be fixed automatically. You need to review the detected files manually and remove or fix them.', 'secupress' ),
		);

		if ( isset( $message_id ) ) {
			return isset( $messages[ $message_id ] ) ? $messages[ $message_id ] : __( 'Unknown message', 'secupress' );
		}

		return $messages;
	}


	/** Getters. ================================================================================ */

	/**
	 * Get the documentation URL.
	 *
	 * @since 2.6
	 *
	 * @return (string)
	 */
	public static function get_docs_url() {
		return __( 'https://docs.secupress.me/article/235-malware-scanners', 'secupress' );
	}


	/** Scan. =================================================================================== */

	/**
	 * Scan for flaw(s).
	 *
	 * @since 2.6
	 *
	 * @return (array) The scan results.
	 */
	public function scan() {

		$activated = $this->filter_scanner( __CLASS__ );
		if ( true === $activated ) {
			$this->add_message( 0 );
			return parent::scan();
		}

		if ( ! secupress_is_pro() || ! function_exists( 'secupress_file_scanner_get_result' ) ) {
			$this->add_message( 100 );
			$this->add_pre_fix_message( 300 );
			return parent::scan();
		}

		$results = secupress_file_scanner_get_result();

		if ( ! is_array( $results ) ) {
			$this->add_message( 100 );
			$this->add_pre_fix_message( 300 );
			return parent::scan();
		}

		$has_content = ! empty( array_filter( $results ) );

		if ( $has_content ) {
			$this->add_message( 200 );
		} else {
			$this->add_message( 0 );
		}

		$this->add_pre_fix_message( 300 );

		return parent::scan();
	}


	/** Fix. ==================================================================================== */

	/**
	 * Try to fix the flaw(s).
	 *
	 * @since 2.6
	 *
	 * @return (array) The fix results.
	 */
	public function fix() {
		$this->add_fix_message( 300 );
		return parent::fix();
	}

}

