. */ if (!defined('ABSPATH')) { exit; } define('backhe_yis_VERSION', '1.0.0'); define('backhe_yis_PLUGIN_FILE', __FILE__); define('backhe_yis_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('backhe_yis_PLUGIN_URL', plugin_dir_url(__FILE__)); /** * Autoload necessary classes */ spl_autoload_register(function($class) { if (strpos($class, 'backhe_yis_') !== 0) { return; } $base = str_replace('backhe_yis_', '', $class); $base = strtolower(str_replace('_', '-', $base)); $candidates = array( backhe_yis_PLUGIN_DIR . 'includes/class-' . $base . '.php', backhe_yis_PLUGIN_DIR . 'admin/class-' . $base . '.php', ); foreach ($candidates as $file) { if (file_exists($file)) { require_once $file; return; } } }); /** * Init main plugin class */ class Backhe_YIS_Media { public static $instance; /** @var backhe_yis_Admin_Menu */ public $admin_menu; /** @var backhe_yis_Email_Notifier */ public $email_notifier; /** @var backhe_yis_System_Info */ public $system_info; /** @var backhe_yis_update_Checker */ public $update_checker; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } public function __construct() { $this->system_info = new backhe_yis_System_Info(); $this->update_checker = new backhe_yis_update_Checker(); $this->email_notifier = new backhe_yis_Email_Notifier(); $this->admin_menu = new backhe_yis_Admin_Menu(); add_action('admin_enqueue_scripts', array($this, 'admin_assets')); add_action('plugins_loaded', array($this, 'load_textdomain')); add_action('init', array($this, 'register_settings')); // AJAX add_action('wp_ajax_backhe_yis_manual_check', array($this, 'ajax_manual_check')); add_action('wp_ajax_backhe_yis_send_test_email', array($this, 'ajax_send_test_email')); add_action('wp_ajax_backhe_yis_update_single', array($this, 'ajax_update_single')); add_action('wp_ajax_backhe_yis_update_all', array($this, 'ajax_update_all')); // Scheduled events add_action('backhe_yis_scheduled_check', array($this, 'scheduled_check')); // Hook for update completion notifications add_action('upgrader_process_complete', array($this, 'notify_on_update'), 10, 2); register_activation_hook(backhe_yis_PLUGIN_FILE, array('Backhe_YIS_Media', 'activate')); register_deactivation_hook(backhe_yis_PLUGIN_FILE, array('Backhe_YIS_Media', 'deactivate')); } public function load_textdomain() { // load_plugin_textdomain() ist seit WordPress 4.6 nicht mehr nötig // WordPress lädt Übersetzungen automatisch für Plugins von WordPress.org } public function register_settings() { register_setting('backhe_yis_settings_group', 'backhe_yis_settings', array( 'sanitize_callback' => array($this, 'sanitize_settings') )); } public function sanitize_settings($input) { $sanitized = array(); $sanitized['email_enabled'] = isset($input['email_enabled']) ? '1' : '0'; $sanitized['recipient_type'] = sanitize_text_field($input['recipient_type'] ?? 'admin'); $sanitized['custom_email'] = sanitize_email($input['custom_email'] ?? ''); $sanitized['custom_email_2'] = sanitize_email($input['custom_email_2'] ?? ''); $sanitized['selected_user'] = absint($input['selected_user'] ?? 0); $sanitized['notification_frequency'] = sanitize_text_field($input['notification_frequency'] ?? 'daily'); $sanitized['custom_days'] = absint($input['custom_days'] ?? 1); $sanitized['notify_on_updates'] = isset($input['notify_on_updates']) ? '1' : '0'; $sanitized['allowed_roles'] = isset($input['allowed_roles']) && is_array($input['allowed_roles']) ? array_map('sanitize_text_field', $input['allowed_roles']) : array('administrator'); return $sanitized; } public function admin_assets($hook) { if (strpos($hook, 'backhe_yis_admin') === false) { return; } // CSS einbinden wp_enqueue_style( 'backhe-yis-admin-style', backhe_yis_PLUGIN_URL . 'assets/admin-style.css', array(), backhe_yis_VERSION ); // JavaScript einbinden wp_enqueue_script( 'backhe-yis-admin-script', backhe_yis_PLUGIN_URL . 'assets/admin-script.js', array('jquery'), backhe_yis_VERSION, true ); // Lokalisierungsdaten wp_localize_script('backhe-yis-admin-script', 'backheYisAdmin', array( 'pruefeText' => __('Prüfe...', 'admin-backend-and-update-helper'), 'manuellPruefenText' => __('Manuell prüfen', 'admin-backend-and-update-helper'), 'sendeText' => __('Sende...', 'admin-backend-and-update-helper'), 'testEmailText' => __('Test-E-Mail senden', 'admin-backend-and-update-helper'), 'fehlerText' => __('Fehler', 'admin-backend-and-update-helper'), 'keineEmailText' => __('Bitte E-Mail eingeben', 'admin-backend-and-update-helper'), 'updateText' => __('Aktualisiere...', 'admin-backend-and-update-helper'), 'updateAllText' => __('Alle Updates installieren', 'admin-backend-and-update-helper'), 'adminEmail' => get_option('admin_email'), 'nonceManualCheck' => wp_create_nonce('backhe_yis_manual_check'), 'nonceTestEmail' => wp_create_nonce('backhe_yis_test_email'), 'nonceUpdate' => wp_create_nonce('backhe_yis_update') )); // Inline JavaScript aus admin-page.php hier einbinden $inline_js = " jQuery(document).ready(function($) { // Show/hide conditional fields function updateRecipientFields() { var type = $('input[name=\"backhe_yis_settings[recipient_type]\"]:checked').val(); $('#user-select-wrapper').hide(); $('#custom-email-wrapper').hide(); if (type === 'user') { $('#user-select-wrapper').slideDown(); } if (type === 'custom') { $('#custom-email-wrapper').slideDown(); } } function updateFrequencyFields() { var freq = $('#notification-frequency').val(); if (freq === 'custom') { $('#custom-days-wrapper').slideDown(); } else { $('#custom-days-wrapper').slideUp(); } } updateRecipientFields(); updateFrequencyFields(); $('input[name=\"backhe_yis_settings[recipient_type]\"]').on('change', updateRecipientFields); $('#notification-frequency').on('change', updateFrequencyFields); // Manual check button $('#backhe-manual-check-btn').on('click', function() { var btn = $(this); btn.prop('disabled', true).text(backheYisAdmin.pruefeText); $.post(ajaxurl, { action: 'backhe_yis_manual_check', nonce: backheYisAdmin.nonceManualCheck }, function(response) { if (response.success) { alert(response.data.message); $('#last-check-time').text(response.data.timestamp); location.reload(); } else { alert(response.data.message || backheYisAdmin.fehlerText); } }).fail(function() { alert(backheYisAdmin.fehlerText); }).always(function() { btn.prop('disabled', false).text(backheYisAdmin.manuellPruefenText); }); }); // Test email button $('#backhe-test-email-btn').on('click', function() { var btn = $(this); var type = $('input[name=\"backhe_yis_settings[recipient_type]\"]:checked').val(); var recipient = ''; var recipient_2 = ''; if (type === 'admin') { recipient = backheYisAdmin.adminEmail; } else if (type === 'user') { var userText = $('select[name=\"backhe_yis_settings[selected_user]\"] option:selected').text(); var match = userText.match(/\((.+)\)/); recipient = match ? match[1] : ''; } else if (type === 'custom') { recipient = $('input[name=\"backhe_yis_settings[custom_email]\"]').val(); recipient_2 = $('input[name=\"backhe_yis_settings[custom_email_2]\"]').val(); } if (!recipient) { alert(backheYisAdmin.keineEmailText); return; } btn.prop('disabled', true).text(backheYisAdmin.sendeText); $.post(ajaxurl, { action: 'backhe_yis_send_test_email', nonce: backheYisAdmin.nonceTestEmail, recipient: recipient, recipient_2: recipient_2 }, function(response) { if (response.success) { alert(response.data.message); } else { alert(response.data.message || backheYisAdmin.fehlerText); } }).fail(function() { alert(backheYisAdmin.fehlerText); }).always(function() { btn.prop('disabled', false).text(backheYisAdmin.testEmailText); }); }); // Single update button $('.backhe-update-single-btn').on('click', function() { var btn = $(this); var type = btn.data('type'); var slug = btn.data('slug'); var originalText = btn.text(); if (!confirm('Möchten Sie dieses Update wirklich installieren?')) { return; } btn.prop('disabled', true).text(backheYisAdmin.updateText); $.post(ajaxurl, { action: 'backhe_yis_update_single', nonce: backheYisAdmin.nonceUpdate, type: type, slug: slug }, function(response) { if (response.success) { alert(response.data.message); location.reload(); } else { alert(response.data.message || backheYisAdmin.fehlerText); btn.prop('disabled', false).text(originalText); } }).fail(function() { alert(backheYisAdmin.fehlerText); btn.prop('disabled', false).text(originalText); }); }); // Update all button $('#backhe-update-all-btn').on('click', function() { var btn = $(this); var originalText = btn.text(); if (!confirm('Möchten Sie wirklich alle Updates installieren? Dies kann einige Minuten dauern.')) { return; } btn.prop('disabled', true).text(backheYisAdmin.updateText); $.post(ajaxurl, { action: 'backhe_yis_update_all', nonce: backheYisAdmin.nonceUpdate }, function(response) { if (response.success) { alert(response.data.message); location.reload(); } else { alert(response.data.message || backheYisAdmin.fehlerText); btn.prop('disabled', false).text(originalText); } }).fail(function() { alert(backheYisAdmin.fehlerText); btn.prop('disabled', false).text(originalText); }); }); }); "; wp_add_inline_script('backhe-yis-admin-script', $inline_js); } public function ajax_manual_check() { check_ajax_referer( 'backhe_yis_manual_check', 'nonce' ); $updates = $this->update_checker->check_all_updates(); $update_count = $this->update_checker->get_update_count( $updates ); update_option( 'backhe_yis_last_check', time() ); // translators: 1: Number of updates found, 2: Singular or plural form of "Update". wp_send_json_success( array( 'message' => sprintf( // translators: %1$d is the number of updates, %2$s is the singular/plural form of "Update". __( 'Prüfung abgeschlossen: %1$d %2$s gefunden.', 'admin-backend-and-update-helper' ), $update_count, _n( 'Update', 'Updates', $update_count, 'admin-backend-and-update-helper' ) ), 'timestamp' => date_i18n( 'd.m.Y H:i:s' ), ) ); } public function ajax_send_test_email() { check_ajax_referer('backhe_yis_test_email', 'nonce'); $recipient = isset($_POST['recipient']) ? sanitize_email(wp_unslash($_POST['recipient'])) : ''; $recipient_2 = isset($_POST['recipient_2']) ? sanitize_email(wp_unslash($_POST['recipient_2'])) : ''; $success = $this->email_notifier->send_test_email($recipient, $recipient_2); wp_send_json(array( 'success' => $success, 'data' => array( 'message' => $success ? __('Test-E-Mail erfolgreich versendet!', 'admin-backend-and-update-helper') : __('Fehler beim Versand der Test-E-Mail.', 'admin-backend-and-update-helper') ) )); } public function ajax_update_single() { check_ajax_referer('backhe_yis_update', 'nonce'); if (!current_user_can('update_plugins') && !current_user_can('update_themes') && !current_user_can('update_core')) { wp_send_json_error(array('message' => __('Keine Berechtigung', 'admin-backend-and-update-helper'))); } $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : ''; $slug = isset($_POST['slug']) ? sanitize_text_field(wp_unslash($_POST['slug'])) : ''; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; require_once ABSPATH . 'wp-admin/includes/file.php'; $result = false; if ($type === 'plugin') { $upgrader = new Plugin_Upgrader(new WP_Ajax_Upgrader_Skin()); $result = $upgrader->upgrade($slug); } elseif ($type === 'theme') { $upgrader = new Theme_Upgrader(new WP_Ajax_Upgrader_Skin()); $result = $upgrader->upgrade($slug); } elseif ($type === 'core') { $upgrader = new Core_Upgrader(new WP_Ajax_Upgrader_Skin()); $result = $upgrader->upgrade(get_site_transient('update_core')->updates[0]); } if (is_wp_error($result)) { wp_send_json_error(array('message' => $result->get_error_message())); } elseif ($result === false) { wp_send_json_error(array('message' => __('Update fehlgeschlagen', 'admin-backend-and-update-helper'))); } else { wp_send_json_success(array('message' => __('Update erfolgreich installiert', 'admin-backend-and-update-helper'))); } } public function ajax_update_all() { check_ajax_referer('backhe_yis_update', 'nonce'); if (!current_user_can('update_plugins') && !current_user_can('update_themes') && !current_user_can('update_core')) { wp_send_json_error(array('message' => __('Keine Berechtigung', 'admin-backend-and-update-helper'))); } require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; require_once ABSPATH . 'wp-admin/includes/file.php'; $updates = $this->update_checker->check_all_updates(); $results = array('success' => 0, 'failed' => 0); // Update Core if (!empty($updates['core'])) { $upgrader = new Core_Upgrader(new WP_Ajax_Upgrader_Skin()); $result = $upgrader->upgrade(get_site_transient('update_core')->updates[0]); if (!is_wp_error($result) && $result !== false) { $results['success']++; } else { $results['failed']++; } } // Update Plugins if (!empty($updates['plugins'])) { $upgrader = new Plugin_Upgrader(new WP_Ajax_Upgrader_Skin()); foreach ($updates['plugins'] as $plugin) { $result = $upgrader->upgrade($plugin['plugin_file']); if (!is_wp_error($result) && $result !== false) { $results['success']++; } else { $results['failed']++; } } } // Update Themes if (!empty($updates['themes'])) { $upgrader = new Theme_Upgrader(new WP_Ajax_Upgrader_Skin()); foreach ($updates['themes'] as $theme) { $result = $upgrader->upgrade($theme['stylesheet']); if (!is_wp_error($result) && $result !== false) { $results['success']++; } else { $results['failed']++; } } } // translators: 1: Number of successful updates, 2: Number of failed updates. wp_send_json_success( array( 'message' => sprintf( // translators: %1$d is the number of successful updates, %2$d is the number of failed updates. __( '%1$d Updates erfolgreich, %2$d fehlgeschlagen', 'admin-backend-and-update-helper' ), (int) $results['success'], (int) $results['failed'] ), ) ); } public function scheduled_check() { $updates = $this->update_checker->check_all_updates(); $update_count = $this->update_checker->get_update_count($updates); if ($update_count > 0) { $this->email_notifier->send_notification($updates); } update_option('backhe_yis_last_check', time()); } public function notify_on_update($upgrader_object, $options) { $settings = get_option('backhe_yis_settings', array()); if (empty($settings['notify_on_updates']) || $settings['notify_on_updates'] !== '1') { return; } $this->email_notifier->send_update_completion_notification($options); } public static function activate() { $settings = get_option('backhe_yis_settings', array()); $frequency = $settings['notification_frequency'] ?? 'daily'; self::schedule_event($frequency, $settings); } public static function schedule_event($frequency, $settings = array()) { wp_clear_scheduled_hook('backhe_yis_scheduled_check'); $interval = 'daily'; $custom_days = isset($settings['custom_days']) ? absint($settings['custom_days']) : 1; switch ($frequency) { case 'hourly': $interval = 'hourly'; break; case 'twicedaily': $interval = 'twicedaily'; break; case 'daily': $interval = 'daily'; break; case 'weekly': $interval = 'weekly'; break; case 'biweekly': add_filter('cron_schedules', function($schedules) { $schedules['biweekly'] = array( 'interval' => 1209600, 'display' => __('Alle zwei Wochen', 'admin-backend-and-update-helper') ); return $schedules; }); $interval = 'biweekly'; break; case 'monthly': add_filter('cron_schedules', function($schedules) { $schedules['monthly'] = array( 'interval' => 2592000, 'display' => __('Monatlich', 'admin-backend-and-update-helper') ); return $schedules; }); $interval = 'monthly'; break; case 'custom': add_filter('cron_schedules', function($schedules) use ($custom_days) { $schedules['custom_days'] = array( 'interval' => $custom_days * 86400, // translators: %d is the number of days 'display' => sprintf(__('Alle %d Tage', 'admin-backend-and-update-helper'), $custom_days) ); return $schedules; }); $interval = 'custom_days'; break; } if (!wp_next_scheduled('backhe_yis_scheduled_check')) { wp_schedule_event(time() + 60, $interval, 'backhe_yis_scheduled_check'); } } public static function deactivate() { wp_clear_scheduled_hook('backhe_yis_scheduled_check'); } } Backhe_YIS_Media::get_instance();