%s',
add_query_arg(
array(
'page' => 'antivirus'
),
admin_url('options-general.php')
),
__('Settings')
)
)
);
}
/**
* Links in der Plugins-Verwaltung
*
* @since 0.1
* @change 1.1
*
* @param array $links Array mit Links
* @param string $file Name des Plugins
* @return array $links Array mit erweitertem Link
*/
public static function init_row_meta($data, $page)
{
if ( $page == self::$base ) {
$data = array_merge(
$data,
array(
sprintf(
'%s',
esc_html__('Flattr plugin', 'antivirus')
),
sprintf(
'%s',
esc_html__('Follow on Google+', 'antivirus')
)
)
);
}
return $data;
}
/**
* Aktion bei Aktivierung des Plugins
*
* @since 0.1
* @change 0.8
*/
public static function install()
{
/* Option anlegen */
add_option(
'antivirus',
array(),
'',
'no'
);
/* Cron aktivieren */
if ( self::get_option('cronjob_enable') ) {
self::init_scheduled_hook();
}
}
/**
* Uninstallation des Plugins pro MU-Blog
*
* @since 1.1
* @change 1.1
*/
public static function uninstall()
{
/* Global */
global $wpdb;
/* Remove settings */
delete_option('antivirus');
/* Clean DB */
$wpdb->query("OPTIMIZE TABLE `" .$wpdb->options. "`");
}
/**
* Rückgabe eines Optionsfeldes
*
* @since 0.1
* @change 0.8
*
* @param string $field Name des Feldes
* @return mixed Wert des Feldes
*/
private static function get_option($field)
{
if ( !$options = wp_cache_get('antivirus') ) {
$options = get_option('antivirus');
wp_cache_set(
'antivirus',
$options
);
}
return @$options[$field];
}
/**
* Aktualisiert ein Optionsfeld
*
* @since 0.1
* @change 0.8
*
* @param string $field Name des Feldes
* @param mixed Wert des Feldes
*/
private static function update_option($field, $value)
{
self::update_options(
array(
$field => $value
)
);
}
/**
* Aktualisiert mehrere Optionsfelder
*
* @since 0.1
* @change 0.8
*
* @param array $data Array mit Feldern
*/
private static function update_options($data)
{
/* Option zuweisen */
$options = array_merge(
(array)get_option('antivirus'),
$data
);
/* DB updaten */
update_option(
'antivirus',
$options
);
/* Cache updaten */
wp_cache_set(
'antivirus',
$options
);
}
/**
* Initialisierung des Cronjobs
*
* @since 0.1
* @change 0.8
*/
private static function init_scheduled_hook()
{
if ( !wp_next_scheduled('antivirus_daily_cronjob') ) {
wp_schedule_event(
time(),
'daily',
'antivirus_daily_cronjob'
);
}
}
/**
* Beendigung des Cronjobs
*
* @since 0.1
* @change 0.8
*/
public static function clear_scheduled_hook()
{
if ( wp_next_scheduled('antivirus_daily_cronjob') ) {
wp_clear_scheduled_hook('antivirus_daily_cronjob');
}
}
/**
* Ausführung des Cronjobs
*
* @since 0.1
* @change 1.0
*/
public static function exe_daily_cronjob()
{
/* Kein Cronjob? */
if ( !self::get_option('cronjob_enable') ) {
return;
}
/* Timestamp updaten */
self::update_option(
'cronjob_timestamp',
time()
);
/* Files prüfen */
if ( self::check_theme_files() or self::check_permalink_structure() ) {
/* Sprache laden */
self::load_plugin_lang();
/* E-Mail-Adresse */
$email = sanitize_email(self::get_option('notify_email'));
$email = ( (!empty($email) && is_email($email)) ? $email : get_bloginfo('admin_email') );
/* Send it! */
wp_mail(
$email,
sprintf(
'[%s] %s',
get_bloginfo('name'),
esc_html__('Suspicion on a virus', 'antivirus')
),
sprintf(
"%s\r\n%s\r\n\r\n\r\n%s\r\n%s\r\n",
esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
get_bloginfo('url'),
esc_html__('Notify message by AntiVirus for WordPress', 'antivirus'),
esc_html__('http://wpantivirus.com', 'antivirus')
)
);
/* Alert speichern */
self::update_option(
'cronjob_alert',
1
);
}
}
/**
* Initialisierung der GUI
*
* @since 0.1
* @change 0.8
*/
public static function init_admin_menu()
{
/* Menü anlegen */
add_options_page(
'AntiVirus',
'
AntiVirus',
'manage_options',
'antivirus',
array(
__CLASS__,
'show_admin_menu'
)
);
}
/**
* Initialisierung von JavaScript
*
* @since 0.8
* @change 1.1
*/
public static function add_enqueue_script()
{
/* Infos auslesen */
$data = get_plugin_data(__FILE__);
/* JS einbinden */
wp_register_script(
'av_script',
plugins_url('js/script.js', __FILE__),
array('jquery'),
$data['Version']
);
/* Script einbinden */
wp_enqueue_script('av_script');
/* Script lokalisieren */
wp_localize_script(
'av_script',
'av_settings',
array(
'nonce' => wp_create_nonce('av_ajax_nonce'),
'ajax' => admin_url('admin-ajax.php'),
'theme' => urlencode(self::get_theme_name()),
'msg_1' => esc_html__('There is no virus', 'antivirus'),
'msg_2' => esc_html__('View line', 'antivirus'),
'msg_3' => esc_html__('Scan finished', 'antivirus')
)
);
}
/**
* Initialisierung von Stylesheets
*
* @since 0.8
* @change 1.1
*/
public static function add_enqueue_style()
{
/* Infos auslesen */
$data = get_plugin_data(__FILE__);
/* CSS registrieren */
wp_register_style(
'av_css',
plugins_url('css/style.css', __FILE__),
array(),
$data['Version']
);
/* CSS einbinden */
wp_enqueue_style('av_css');
}
/**
* Prüfung der WordPress-Version
*
* @since 0.1
* @change 0.1
*
* @param integer $version Gesuchte WP-Version
* @return boolean TRUE, wenn mindestens gesuchte
*/
private static function is_min_wp($version)
{
return version_compare(
$GLOBALS['wp_version'],
$version. 'alpha',
'>='
);
}
/**
* Rückgabe des aktuellen Theme
*
* @since 0.1
* @change 0.8
*
* @return array $themes Array mit Theme-Eigenschaften
*/
private static function get_current_theme()
{
/* Themes auslesen */
if ( $themes = get_themes() ) {
/* Aktuelles Theme */
if ($theme = get_current_theme()) {
if (array_key_exists((string)$theme, $themes)) {
return $themes[$theme];
}
}
}
return false;
}
/**
* Rückgabe von Dateien des aktuellen Theme
*
* @since 0.1
* @change 0.8
*
* @return array $files Array mit Dateien
*/
private static function get_theme_files()
{
/* Theme vorhanden? */
if ( !$theme = self::get_current_theme() ) {
return false;
}
/* Keine Files? */
if ( empty($theme['Template Files']) ) {
return false;
}
/* Zurückgeben */
return array_unique(
array_map(
create_function(
'$v',
'return str_replace(array(WP_CONTENT_DIR, "wp-content"), "", $v);'
),
$theme['Template Files']
)
);
}
/**
* Rückgabe des Namen des aktuellen Theme
*
* @since 0.1
* @change 0.8
*
* @return string $theme Name des aktuellen Theme
*/
private static function get_theme_name()
{
if ( $theme = self::get_current_theme() ) {
if (!empty($theme['Name'])) {
return $theme['Name'];
}
}
return false;
}
/**
* Rückgabe der WhiteList
*
* @since 0.1
* @change 0.8
*
* @return array return Array mit MD5-Werten
*/
private static function get_white_list()
{
return explode(
':',
self::get_option('white_list')
);
}
/**
* Ausführung von AJAX
*
* @since 0.1
* @change 0.8
*/
public static function get_ajax_response()
{
/* Referer prüfen */
check_ajax_referer('av_ajax_nonce');
/* Zusätzliche Prüfung */
if ( empty($_POST['_action_request']) ) {
exit();
}
/* Init */
$values = array();
$output = '';
/* Ausgabe starten */
switch ($_POST['_action_request']) {
case 'get_theme_files':
self::update_option(
'cronjob_alert',
0
);
$values = self::get_theme_files();
break;
case 'check_theme_file':
if ( !empty($_POST['_theme_file']) && $lines = self::check_theme_file($_POST['_theme_file']) ) {
foreach ($lines as $num => $line) {
foreach ($line as $string) {
$values[] = $num;
$values[] = htmlentities($string, ENT_QUOTES);
$values[] = md5($num . $string);
}
}
}
break;
case 'update_white_list':
if ( !empty($_POST['_file_md5']) ) {
self::update_option(
'white_list',
implode(
':',
array_unique(
array_merge(
self::get_white_list(),
array($_POST['_file_md5'])
)
)
)
);
$values = array($_POST['_file_md5']);
}
break;
default:
break;
}
/* Ausgabe starten */
if ($values) {
$output = sprintf(
"['%s']",
implode("', '", $values)
);
/* Header senden */
header('Content-Type: plain/text');
/* Ausgeben */
echo sprintf(
'{data:%s, nonce:"%s"}',
$output,
$_POST['_ajax_nonce']
);
}
/* Raus! */
exit();
}
/**
* Rückgabe des Dateiinhaltes
*
* @since 0.1
* @change 0.8
*
* @return array $file Array mit Dateizeilen
*/
private static function get_file_content($file)
{
return file(WP_CONTENT_DIR . $file);
}
/**
* Kürzung eines Strings
*
* @since 0.1
* @change 0.1
*
* @param string $line Eigenetliche Zeile als String
* @param string $tag Gesuchtes Tag
* @param integer $max Anzahl der Zeichen rechts und links
* @return string $output Gekürzter String
*/
public static function get_dotted_line($line, $tag, $max = 100)
{
/* Keine Werte? */
if ( !$line or !$tag ) {
return false;
}
/* Differenz ermitteln */
if ( strlen($tag) > $max ) {
return $tag;
}
/* Differenz ermitteln */
$left = round(($max - strlen($tag)) / 2);
/* Wert konvertieren */
$tag = preg_quote($tag);
/* String kürzen */
$output = preg_replace(
'/(' .$tag. ')(.{' .$left. '}).{0,}$/',
'$1$2 ...',
$line
);
$output = preg_replace(
'/^.{0,}(.{' .$left. ',})(' .$tag. ')/',
'... $1$2',
$output
);
return $output;
}
/**
* Definition des Regexp
*
* @since 0.1
* @change 1.0
*
* @return string return Regulärer Ausdruck
*/
private static function get_preg_match()
{
return '/(assert|file_get_contents|curl_exec|popen|proc_open|unserialize|eval|base64_encode|base64_decode|create_function|exec|shell_exec|system|passthru|ob_get_contents|file|curl_init|readfile|fopen|fsockopen|pfsockopen|fclose|fread|include|include_once|require|require_once|file_put_contents)\s*?\(/';
}
/**
* Prüfung einer Zeile
*
* @since 0.1
* @change 1.1
*
* @param string $line Zeile zur Prüfung
* @param integer $num Nummer zur Prüfung
* @return string $line Zeile mit Resultaten
*/
private static function check_file_line($line = '', $num)
{
/* Wert trimmen */
$line = trim((string)$line);
/* Leere Werte? */
if ( !$line or !isset($num) ) {
return false;
}
/* Werte initialisieren */
$results = array();
$output = array();
/* Befehle suchen */
preg_match_all(
self::get_preg_match(),
$line,
$matches
);
/* Ergebnis speichern */
if ( $matches[1] ) {
$results = $matches[1];
}
/* Base64 suchen */
preg_match_all(
'/[\'\"\$\\ \/]*?([a-zA-Z0-9]{' .strlen(base64_encode('sergej + swetlana = love.')). ',})/',
$line,
$matches
);
/* Ergebnis speichern */
if ( $matches[1] ) {
$results = array_merge($results, $matches[1]);
}
/* Frames suchen */
preg_match_all(
'/<\s*?(frame)/',
$line,
$matches
);
/* Ergebnis speichern */
if ( $matches[1] ) {
$results = array_merge($results, $matches[1]);
}
/* Option suchen */
preg_match(
'/get_option\s*\(\s*[\'"](.*?)[\'"]\s*\)/',
$line,
$matches
);
/* Option prüfen */
if ( $matches && $matches[1] && self::check_file_line(get_option($matches[1]), $num) ) {
array_push($results, 'get_option');
}
/* Ergebnisse? */
if ( $results ) {
/* Keine Duplikate */
$results = array_unique($results);
/* White-Liste */
$md5 = self::get_white_list();
/* Resultate loopen */
foreach ($results as $tag) {
$string = str_replace(
$tag,
'@span@' .$tag. '@/span@',
self::get_dotted_line($line, $tag)
);
/* In der Whitelist? */
if (!in_array(md5($num . $string), $md5)) {
$output[] = $string;
}
}
return $output;
}
return false;
}
/**
* Prüfung der Dateien des aktuellen Theme
*
* @since 0.1
* @change 0.8
*
* @return array $results Array mit Ergebnissen
*/
private static function check_theme_files()
{
/* Files vorhanden? */
if ( !$files = self::get_theme_files() ) {
return false;
}
/* Init */
$results = array();
/* Files loopen */
foreach($files as $file) {
if ($result = self::check_theme_file($file)) {
$results[$file] = $result;
}
}
/* Werte vorhanden? */
if ( !empty($results) ) {
return $results;
}
return false;
}
/**
* Prüfung einer Datei
*
* @since 0.1
* @change 0.8
*
* @param string $file Datei zur Prüfung
* @return array $results Array mit Ergebnissen
*/
private static function check_theme_file($file)
{
/* Kein File? */
if ( !$file ) {
return false;
}
/* Inhalt auslesen */
if ( !$content = self::get_file_content($file) ) {
return false;
}
/* Init */
$results = array();
/* Zeilen loopen */
foreach($content as $num => $line) {
if ($result = self::check_file_line($line, $num)) {
$results[$num] = $result;
}
}
/* Werte vorhanden? */
if ( !empty($results) ) {
return $results;
}
return false;
}
/**
* Prüfung des Permalinks
*
* @since 0.1
* @change 0.8
*
* @return mixed $matches FALSE, wenn kein Fund
*/
private static function check_permalink_structure()
{
if ( $structure = get_option('permalink_structure') ) {
/* Befehle suchen */
preg_match_all(
self::get_preg_match(),
$structure,
$matches
);
/* Ergebnis speichern */
if ( $matches[1] ) {
return $matches[1];
}
}
return false;
}
/**
* Prüfung der Admin-Seite
*
* @since 0.1
* @change 0.8
*
* @param integer $page Gesuchte Seite
* @return boolean TRUE, wenn die aktuelle auch die gesuchte Seite ist
*/
private static function is_current_page($page)
{
switch($page) {
case 'home':
return ( !empty($_REQUEST['page']) && $_REQUEST['page'] == 'antivirus' );
case 'index':
case 'plugins':
return (!empty($GLOBALS['pagenow']) && $GLOBALS['pagenow'] == sprintf('%s.php', $page));
default:
return false;
}
}
/**
* Anzeige des Version-Hinweises
*
* @since 0.1
* @change 0.8
*/
public static function show_version_notice()
{
/* Keine Ausgabe? */
if ( self::is_min_wp('2.8') ) {
return;
}
/* Warnung */
echo sprintf(
'
%s %s
%s: %s %s