Compare commits

..

No commits in common. "main" and "1.2" have entirely different histories.
main ... 1.2

View File

@ -1,305 +1,325 @@
<?php <?php
/** /**
* Plugin Name: WP Multi Search * Plugin Name: WP-Multi Search
* Plugin URI: https://git.viper.ipv64.net/M_Viper/WP-Multi-Search * Plugin URI: https://git.viper.ipv64.net/M_Viper/WP-Multi-Search
* Description: Fügt eine Suchfunktion als Shortcode, Widget und Menüeintrag hinzu. (Shortcode: [custom_search]) * Description: Fügt eine Suchfunktion als Shortcode, Widget und Menüeintrag hinzu.(Shortcode: [display_search_form])
* Version: 1.6 * Version: 1.2
* Author: M_Viper * Author: M_Viper
* Author URI: https://m-viper.de * Author URI: https://m-viper.de
* Requires at least: 6.7.2 * Requires at least: 6.7.2
* Tested up to: 6.7.2 * Tested up to: 6.7.2
* License: GPL2 * License: GPL2
* License URI: https://www.gnu.org/licenses/gpl-2.0.html * License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: wp-multi-search * Text Domain: wp-multi-search
* Tags: search, author-search * Tags: search Autor-search
*/ */
if (!defined('ABSPATH')) { if (!defined('ABSPATH')) {
exit; exit; // Sicherheitsmaßnahme
} }
/* // 1⃣ **Suchformular-Funktion mit integriertem CSS**
* WP Multi Toolkit Prüfung function csp_search_form() {
*/ ob_start();
$search_type = isset($_GET['search_type']) ? sanitize_text_field($_GET['search_type']) : 'all';
// Funktion zur Überprüfung des WP Multi Toolkit Plugins ?>
function wp_multi_search_check_dependency() { <style>
if (!function_exists('is_plugin_active')) { .csp-search-form {
include_once(ABSPATH . 'wp-admin/includes/plugin.php'); display: flex;
} flex-direction: column;
gap: 8px;
// Prüft, ob WP Multi Toolkit installiert und aktiv ist max-width: auto;
if (!is_plugin_active('wp-multi-toolkit/wp-multi-toolkit.php')) { margin: 10px auto;
add_action('admin_notices', 'wp_multi_search_dependency_notice'); padding: 15px;
return false; background: #f8f9fa;
} border-radius: 15px;
return true; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
} }
// Fehlermeldung für Admin-Bereich mit Download-Button .csp-search-fields {
function wp_multi_search_dependency_notice() { display: flex;
?> gap: 8px;
<div class="notice notice-error"> }
<p>
<?php _e('Das Plugin "WP Multi Search" benötigt "WP Multi Toolkit", um zu funktionieren. Bitte installieren und aktivieren Sie "WP Multi Toolkit".', 'wp-multi-search'); ?> .csp-search-form input[type="text"] {
<a href="https://git.viper.ipv64.net/M_Viper/wp-multi-toolkit/releases" target="_blank" class="button button-primary" style="margin-left: 10px;"> flex: 1;
<?php _e('WP Multi Toolkit herunterladen', 'wp-multi-search'); ?> padding: 10px;
</a> border: 1px solid #ddd;
</p> border-radius: 20px;
</div> font-size: 16px;
<?php }
}
.csp-search-type {
// Plugin nur initialisieren, wenn Abhängigkeit erfüllt ist display: flex;
if (wp_multi_search_check_dependency()) { gap: 10px;
// Hier würde der restliche Plugin-Code folgen margin-bottom: 10px;
}
} else {
// Optional: Plugin komplett deaktivieren, wenn Abhängigkeit fehlt .csp-search-type label {
add_action('admin_init', function() { display: flex;
deactivate_plugins(plugin_basename(__FILE__)); align-items: center;
}); gap: 5px;
} cursor: pointer;
}
.csp-search-type input[type="radio"] {
margin: 0;
}
.csp-search-form input[type="submit"] {
background: #0073aa;
color: white;
border: none;
padding: 10px 15px;
border-radius: 20px;
/* cursor: pointer;
* Suchfunktion font-size: 16px;
*/ transition: background 0.3s;
}
.csp-search-form input[type="submit"]:hover {
background: #005f8d;
}
</style>
define('CSP_PLUGIN_VERSION', '1.5'); <form class="csp-search-form" role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
define('CSP_PLUGIN_DIR', plugin_dir_path(__FILE__)); <div class="csp-search-type">
<label>
function csp_load_textdomain() { <input type="radio" name="search_type" value="all" <?php checked($search_type, 'all'); ?>>
load_plugin_textdomain('wp-multi-search', false, dirname(plugin_basename(__FILE__)) . '/languages'); <?php _e('Alle Inhalte', 'textdomain'); ?>
} </label>
add_action('plugins_loaded', 'csp_load_textdomain'); <label>
<input type="radio" name="search_type" value="title" <?php checked($search_type, 'title'); ?>>
function csp_search_form() { <?php _e('Nur Titel', 'textdomain'); ?>
try { </label>
$valid_types = ['all', 'title', 'guest_author']; <label>
$search_type = isset($_GET['search_type']) ? sanitize_text_field($_GET['search_type']) : 'all'; <input type="radio" name="search_type" value="guest_author" <?php checked($search_type, 'guest_author'); ?>>
if (!in_array($search_type, $valid_types)) { <?php _e('Nur Gastautoren', 'textdomain'); ?>
$search_type = 'all'; </label>
} </div>
<div class="csp-search-fields">
ob_start(); <input type="text" name="s" placeholder="🔍 Suchbegriff eingeben" value="<?php echo esc_attr(get_search_query()); ?>">
?> <input type="submit" value="Suchen">
<style> </div>
.csp-search-form { display: flex; flex-direction: column; gap: 8px; max-width: 500px; margin: 10px auto; padding: 15px; background: #f8f9fa; border-radius: 15px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } </form>
.csp-search-fields { display: flex; gap: 8px; } <?php
.csp-search-form input[type="text"] { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 20px; font-size: 16px; } return ob_get_clean();
.csp-search-type { display: flex; gap: 10px; margin-bottom: 10px; } }
.csp-search-type label { display: flex; align-items: center; gap: 5px; cursor: pointer; }
.csp-search-type input[type="radio"] { margin: 0; } // 2⃣ **Shortcode für das Suchformular**
.csp-search-form input[type="submit"] { background: #0073aa; color: white; border: none; padding: 10px 15px; border-radius: 20px; cursor: pointer; font-size: 16px; transition: background 0.3s; } add_shortcode('custom_search', 'csp_search_form');
.csp-search-form input[type="submit"]:hover { background: #005f8d; }
</style> // 3⃣ **Suchfeld als Widget**
<form class="csp-search-form" role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>"> class CSP_Search_Widget extends WP_Widget {
<div class="csp-search-type"> public function __construct() {
<label><input type="radio" name="search_type" value="all" <?php checked($search_type, 'all'); ?>><?php _e('Alle Inhalte', 'wp-multi-search'); ?></label> parent::__construct(
<label><input type="radio" name="search_type" value="title" <?php checked($search_type, 'title'); ?>><?php _e('Titel', 'wp-multi-search'); ?></label> 'csp_search_widget',
<label><input type="radio" name="search_type" value="guest_author" <?php checked($search_type, 'guest_author'); ?>><?php _e('Autoren', 'wp-multi-search'); ?></label> __('Suche Widget', 'textdomain'),
</div> array('description' => __('Suchfeld mit Optionen für Titel- und Gastautoren-Suche', 'textdomain'))
<div class="csp-search-fields"> );
<input type="text" name="s" placeholder="🔍 Suchbegriff eingeben" value="<?php echo esc_attr(get_search_query()); ?>"> }
<input type="submit" value="<?php _e('Suchen', 'wp-multi-search'); ?>">
</div> public function widget($args, $instance) {
</form> echo $args['before_widget'];
<?php echo '<h3 class="widget-title">' . __('Suche', 'textdomain') . '</h3>';
return ob_get_clean(); echo csp_search_form();
} catch (Exception $e) { echo $args['after_widget'];
return '<p>' . __('Ein Fehler ist aufgetreten', 'wp-multi-search') . '</p>'; }
} }
}
function csp_register_widget() {
add_shortcode('custom_search', 'csp_search_form'); register_widget('CSP_Search_Widget');
}
class CSP_Search_Widget extends WP_Widget { add_action('widgets_init', 'csp_register_widget');
public function __construct() {
parent::__construct('csp_search_widget', __('Suche Widget', 'wp-multi-search'), array('description' => __('Suchfeld mit Optionen für Titel- und Gastautoren-Suche', 'wp-multi-search'))); // 4⃣ **Einstellungsseite hinzufügen**
} function csp_add_menu_page() {
public function widget($args, $instance) { echo $args['before_widget'] . '<h3 class="widget-title">' . __('Suche', 'wp-multi-search') . '</h3>' . csp_search_form() . $args['after_widget']; } add_options_page(
public function form($instance) { echo '<p>' . __('Keine Einstellungen verfügbar', 'wp-multi-search') . '</p>'; } 'WP-Multi-Search Settings',
public function update($new_instance, $old_instance) { return $new_instance; } 'WP-Multi-Search',
} 'manage_options',
'custom-search-settings',
function csp_register_widget() { register_widget('CSP_Search_Widget'); } 'csp_render_settings_page'
add_action('widgets_init', 'csp_register_widget'); );
}
function csp_add_menu_page() { add_action('admin_menu', 'csp_add_menu_page');
add_options_page('WP-Multi-Search Settings', 'WP-Multi-Search', 'manage_options', 'custom-search-settings', 'csp_render_settings_page');
} // 5⃣ **Einstellungsseite rendern**
add_action('admin_menu', 'csp_add_menu_page'); function csp_render_settings_page() {
?>
function csp_render_settings_page() { <div class="wrap">
if (isset($_POST['csp_settings_nonce']) && !wp_verify_nonce($_POST['csp_settings_nonce'], 'csp_settings_save')) { <h1>WP-Multi Search Settings</h1>
wp_die('Security check failed'); <form method="post" action="options.php">
} <?php
?> settings_fields('csp_settings_group');
<div class="wrap"> do_settings_sections('custom-search-settings');
<h1><?php _e('WP-Multi Search Settings', 'wp-multi-search'); ?></h1> submit_button();
<form method="post" action="options.php"> ?>
<?php settings_fields('csp_settings_group'); do_settings_sections('custom-search-settings'); wp_nonce_field('csp_settings_save', 'csp_settings_nonce'); submit_button(); ?> </form>
</form> </div>
</div> <?php
<?php }
}
// 6⃣ **Einstellungen registrieren**
function csp_register_settings() { function csp_register_settings() {
register_setting('csp_settings_group', 'csp_shiftnav_position', array('sanitize_callback' => 'sanitize_text_field')); register_setting('csp_settings_group', 'csp_shiftnav_position');
add_settings_section('csp_main_section', 'ShiftNav Position', 'csp_section_callback', 'custom-search-settings');
add_settings_field('csp_shiftnav_position_select', 'Select ShiftNav Position', 'csp_shiftnav_position_select_callback', 'custom-search-settings', 'csp_main_section'); add_settings_section(
} 'csp_main_section',
add_action('admin_init', 'csp_register_settings'); 'ShiftNav Position',
'csp_section_callback',
function csp_section_callback() { echo __('Choose where to display the search form in ShiftNav:', 'wp-multi-search'); } 'custom-search-settings'
);
function csp_shiftnav_position_select_callback() {
$positions = array('top' => __('Top of ShiftNav', 'wp-multi-search'), 'bottom' => __('Bottom of ShiftNav', 'wp-multi-search'), 'none' => __('Do not display in ShiftNav', 'wp-multi-search')); add_settings_field(
$selected_position = get_option('csp_shiftnav_position', 'none'); 'csp_shiftnav_position_select',
echo '<select name="csp_shiftnav_position">'; 'Select ShiftNav Position',
foreach ($positions as $value => $label) { 'csp_shiftnav_position_select_callback',
echo '<option value="' . esc_attr($value) . '" ' . selected($selected_position, $value, false) . '>' . esc_html($label) . '</option>'; 'custom-search-settings',
} 'csp_main_section'
echo '</select>'; );
} }
add_action('admin_init', 'csp_register_settings');
function csp_insert_search_form_in_shiftnav($nav_menu, $args) {
if (!isset($args->theme_location) || $args->theme_location !== 'shiftnav') return $nav_menu; // 7⃣ **Callback für die Sektion**
$position = get_option('csp_shiftnav_position', 'none'); function csp_section_callback() {
if ($position === 'none') return $nav_menu; echo 'Choose where to display the search form in ShiftNav:';
$search_form = '<li class="menu-item">' . csp_search_form() . '</li>'; }
return $position === 'top' ? $search_form . $nav_menu : $nav_menu . $search_form;
} // 8⃣ **Callback für das Auswahlfeld**
add_filter('wp_nav_menu_items', 'csp_insert_search_form_in_shiftnav', 10, 2); function csp_shiftnav_position_select_callback() {
$positions = array(
function csp_custom_search_results($query) { 'top' => 'Top of ShiftNav',
if (!is_admin() && $query->is_search() && $query->is_main_query()) { 'bottom' => 'Bottom of ShiftNav',
$query->set('post_status', 'publish'); 'none' => 'Do not display in ShiftNav'
);
$search_type = isset($_GET['search_type']) ? sanitize_text_field($_GET['search_type']) : 'all'; $selected_position = get_option('csp_shiftnav_position', 'none');
$search_term = $query->get('s');
echo '<select name="csp_shiftnav_position">';
switch($search_type) { foreach ($positions as $value => $label) {
case 'title': echo '<option value="' . esc_attr($value) . '" ' . selected($selected_position, $value, false) . '>' . esc_html($label) . '</option>';
$query->set('post_title_like', $search_term); }
$query->set('s', ''); echo '</select>';
add_filter('posts_where', 'csp_title_search_where', 10, 2); }
break;
// 9⃣ **Funktion zum Einfügen des Suchformulars in ShiftNav**
case 'guest_author': function csp_insert_search_form_in_shiftnav($nav_menu, $args) {
$meta_query = array( // Überprüfen, ob es sich um das ShiftNav-Menü handelt
array( if ($args->theme_location !== 'shiftnav') {
'key' => '_guest_author', return $nav_menu;
'value' => $search_term, }
'compare' => 'LIKE'
) $position = get_option('csp_shiftnav_position', 'none');
); if ($position === 'none') {
$query->set('meta_query', $meta_query); return $nav_menu;
$query->set('s', ''); }
$query->set('post_type', 'post');
break; $search_form = '<li class="menu-item">' . csp_search_form() . '</li>';
default: if ($position === 'top') {
$query->set('_meta_or_title', $search_term); return $search_form . $nav_menu;
add_filter('posts_search', 'csp_custom_search_where', 10, 2); } elseif ($position === 'bottom') {
add_filter('posts_join', 'csp_custom_search_join', 10, 2); return $nav_menu . $search_form;
add_filter('posts_groupby', 'csp_custom_search_groupby', 10, 2); }
break;
} return $nav_menu;
}
add_filter('posts_request', function($sql) { add_filter('wp_nav_menu_items', 'csp_insert_search_form_in_shiftnav', 10, 2);
error_log('SQL Query: ' . $sql);
return $sql; // 🔟 **Aktualisierte Suchfunktion mit Suchtyp-Unterscheidung**
}); function csp_custom_search_results($query) {
if (!is_admin() && $query->is_search() && $query->is_main_query()) {
add_action('wp', function() use ($search_type) { $search_type = isset($_GET['search_type']) ? sanitize_text_field($_GET['search_type']) : 'all';
switch($search_type) { $search_term = $query->get('s');
case 'title':
remove_filter('posts_where', 'csp_title_search_where', 10); switch($search_type) {
break; case 'title':
case 'guest_author': $query->set('post_title_like', $search_term);
break; $query->set('s', '');
default: add_filter('posts_where', 'csp_title_search_where', 10, 2);
remove_filter('posts_search', 'csp_custom_search_where', 10); break;
remove_filter('posts_join', 'csp_custom_search_join', 10);
remove_filter('posts_groupby', 'csp_custom_search_groupby', 10); case 'guest_author':
break; $meta_query = array(
} array(
}); 'key' => '_guest_author',
} 'value' => $search_term,
} 'compare' => '='
add_action('pre_get_posts', 'csp_custom_search_results'); )
);
function csp_title_search_where($where, $query) { $query->set('meta_query', $meta_query);
global $wpdb; $query->set('s', '');
if ($search_term = $query->get('post_title_like')) { $query->set('post_type', 'post');
$where .= $wpdb->prepare( break;
" AND {$wpdb->posts}.post_title LIKE %s",
'%' . $wpdb->esc_like($search_term) . '%' default: // 'all'
); $query->set('_meta_or_title', $search_term);
} add_filter('posts_search', 'csp_custom_search_where', 10, 2);
return $where; add_filter('posts_join', 'csp_custom_search_join', 10, 2);
} add_filter('posts_groupby', 'csp_custom_search_groupby', 10, 2);
break;
function csp_custom_search_where($where, $query) { }
global $wpdb; }
if ($search_term = $query->get('_meta_or_title')) { }
$search = '%' . $wpdb->esc_like($search_term) . '%'; add_action('pre_get_posts', 'csp_custom_search_results');
$where .= $wpdb->prepare(
" AND ({$wpdb->posts}.post_title LIKE %s // 1⃣1⃣ **Hilfsfunktionen für verschiedene Suchtypen**
OR {$wpdb->posts}.post_content LIKE %s function csp_title_search_where($where, $query) {
OR {$wpdb->posts}.post_excerpt LIKE %s global $wpdb;
OR guest_author.meta_value LIKE %s if ($search_term = $query->get('post_title_like')) {
OR {$wpdb->users}.display_name LIKE %s)", $where .= $wpdb->prepare(
$search, $search, $search, $search, $search " AND {$wpdb->posts}.post_title LIKE %s",
); '%' . $wpdb->esc_like($search_term) . '%'
} );
return $where; }
} return $where;
}
function csp_custom_search_join($join, $query) {
global $wpdb; function csp_custom_search_where($where, $query) {
if ($query->get('_meta_or_title')) { global $wpdb;
$join .= " LEFT JOIN {$wpdb->postmeta} guest_author ON ({$wpdb->posts}.ID = guest_author.post_id AND guest_author.meta_key = '_guest_author')"; if ($search_term = $query->get('_meta_or_title')) {
$join .= " LEFT JOIN {$wpdb->users} ON ({$wpdb->posts}.post_author = {$wpdb->users}.ID)"; $search = '%' . $wpdb->esc_like($search_term) . '%';
} $where .= $wpdb->prepare(
return $join; " OR ({$wpdb->posts}.post_title LIKE %s)
} OR ({$wpdb->posts}.post_content LIKE %s)
OR ({$wpdb->posts}.post_excerpt LIKE %s)
function csp_custom_search_groupby($groupby, $query) { OR (guest_author.meta_value LIKE %s)
global $wpdb; OR ({$wpdb->users}.display_name LIKE %s)",
if ($query->get('_meta_or_title')) { $search, $search, $search, $search, $search
$groupby = "{$wpdb->posts}.ID"; );
} }
return $groupby; return $where;
} }
function csp_guest_author_search_where($where, $query) { function csp_custom_search_join($join, $query) {
global $wpdb; global $wpdb;
if ($query->get('meta_query')) { if ($query->get('_meta_or_title')) {
$where .= " AND EXISTS ( $join .= " LEFT JOIN {$wpdb->postmeta} guest_author ON ({$wpdb->posts}.ID = guest_author.post_id AND guest_author.meta_key = '_guest_author')";
SELECT 1 FROM {$wpdb->postmeta} $join .= " LEFT JOIN {$wpdb->users} ON ({$wpdb->posts}.post_author = {$wpdb->users}.ID)";
WHERE {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID }
AND {$wpdb->postmeta}.meta_key = '_guest_author' return $join;
AND {$wpdb->postmeta}.meta_value LIKE '%" . $wpdb->esc_like($query->get('s')) . "%' }
)";
} function csp_custom_search_groupby($groupby, $query) {
return $where; global $wpdb;
} if ($query->get('_meta_or_title')) {
add_filter('posts_where', 'csp_guest_author_search_where', 10, 2); $groupby = "{$wpdb->posts}.ID";
}
return $groupby;
}
// 1⃣2⃣ **Hilfsfunktion für Gastautoren-Suche**
function csp_guest_author_search_where($where, $query) {
global $wpdb;
if ($query->get('meta_query')) {
$where .= " AND EXISTS (
SELECT 1 FROM {$wpdb->postmeta}
WHERE {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID
AND {$wpdb->postmeta}.meta_key = '_guest_author'
AND {$wpdb->postmeta}.meta_value != ''
)";
}
return $where;
}
add_filter('posts_where', 'csp_guest_author_search_where', 10, 2);
?>