WP-Multi-Search/wp-multi-search.php

348 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Plugin Name: 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])
* Version: 1.4
* Author: M_Viper
* Author URI: https://m-viper.de
* Requires at least: 6.7.2
* Tested up to: 6.7.2
* License: GPL2
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: wp-multi-search
* Tags: search Autor-search
*/
if (!defined('ABSPATH')) {
exit; // Sicherheitsmaßnahme
}
// Textdomain laden
function csp_load_textdomain() {
load_plugin_textdomain('wp-multi-search', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
add_action('plugins_loaded', 'csp_load_textdomain');
// 1⃣ **Suchformular-Funktion mit integriertem CSS**
function csp_search_form() {
ob_start();
$search_type = isset($_GET['search_type']) ? sanitize_text_field($_GET['search_type']) : 'all';
?>
<style>
.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);
}
.csp-search-fields {
display: flex;
gap: 8px;
}
.csp-search-form input[type="text"] {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 20px;
font-size: 16px;
}
.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;
}
.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;
}
.csp-search-form input[type="submit"]:hover {
background: #005f8d;
}
</style>
<form class="csp-search-form" role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
<div class="csp-search-type">
<label>
<input type="radio" name="search_type" value="all" <?php checked($search_type, 'all'); ?>>
<?php _e('Alle Inhalte', 'wp-multi-search'); ?>
</label>
<label>
<input type="radio" name="search_type" value="title" <?php checked($search_type, 'title'); ?>>
<?php _e('Titel', 'wp-multi-search'); ?>
</label>
<label>
<input type="radio" name="search_type" value="guest_author" <?php checked($search_type, 'guest_author'); ?>>
<?php _e('Autoren', 'wp-multi-search'); ?>
</label>
</div>
<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>
</form>
<?php
return ob_get_clean();
}
// 2⃣ **Shortcode für das Suchformular**
add_shortcode('custom_search', 'csp_search_form');
// 3⃣ **Suchfeld als Widget**
class CSP_Search_Widget extends WP_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'))
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
echo '<h3 class="widget-title">' . __('Suche', 'wp-multi-search') . '</h3>';
echo csp_search_form();
echo $args['after_widget'];
}
}
function csp_register_widget() {
register_widget('CSP_Search_Widget');
}
add_action('widgets_init', 'csp_register_widget');
// 4⃣ **Einstellungsseite hinzufügen**
function csp_add_menu_page() {
add_options_page(
'WP-Multi-Search Settings',
'WP-Multi-Search',
'manage_options',
'custom-search-settings',
'csp_render_settings_page'
);
}
add_action('admin_menu', 'csp_add_menu_page');
// 5⃣ **Einstellungsseite rendern**
function csp_render_settings_page() {
?>
<div class="wrap">
<h1><?php _e('WP-Multi Search Settings', 'wp-multi-search'); ?></h1>
<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>
</div>
<?php
}
// 6⃣ **Einstellungen registrieren**
function csp_register_settings() {
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_action('admin_init', 'csp_register_settings');
// 7⃣ **Callback für die Sektion**
function csp_section_callback() {
echo __('Choose where to display the search form in ShiftNav:', 'wp-multi-search');
}
// 8⃣ **Callback für das Auswahlfeld**
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')
);
$selected_position = get_option('csp_shiftnav_position', 'none');
echo '<select name="csp_shiftnav_position">';
foreach ($positions as $value => $label) {
echo '<option value="' . esc_attr($value) . '" ' . selected($selected_position, $value, false) . '>' . esc_html($label) . '</option>';
}
echo '</select>';
}
// 9⃣ **Funktion zum Einfügen des Suchformulars in ShiftNav**
function csp_insert_search_form_in_shiftnav($nav_menu, $args) {
if ($args->theme_location !== 'shiftnav') {
return $nav_menu;
}
$position = get_option('csp_shiftnav_position', 'none');
if ($position === 'none') {
return $nav_menu;
}
$search_form = '<li class="menu-item">' . csp_search_form() . '</li>';
if ($position === 'top') {
return $search_form . $nav_menu;
} elseif ($position === 'bottom') {
return $nav_menu . $search_form;
}
return $nav_menu;
}
add_filter('wp_nav_menu_items', 'csp_insert_search_form_in_shiftnav', 10, 2);
// 🔟 **Aktualisierte Suchfunktion mit Suchtyp-Unterscheidung**
function csp_custom_search_results($query) {
if (!is_admin() && $query->is_search() && $query->is_main_query()) {
$search_type = isset($_GET['search_type']) ? sanitize_text_field($_GET['search_type']) : 'all';
$search_term = $query->get('s');
switch($search_type) {
case 'title':
$query->set('post_title_like', $search_term);
$query->set('s', '');
add_filter('posts_where', 'csp_title_search_where', 10, 2);
break;
case 'guest_author':
$meta_query = array(
array(
'key' => '_guest_author',
'value' => $search_term,
'compare' => '='
)
);
$query->set('meta_query', $meta_query);
$query->set('s', '');
$query->set('post_type', 'post');
break;
default: // 'all'
$query->set('_meta_or_title', $search_term);
add_filter('posts_search', 'csp_custom_search_where', 10, 2);
add_filter('posts_join', 'csp_custom_search_join', 10, 2);
add_filter('posts_groupby', 'csp_custom_search_groupby', 10, 2);
break;
}
// Filter nach der Abfrage entfernen
add_action('wp', function() use ($search_type) {
switch($search_type) {
case 'title':
remove_filter('posts_where', 'csp_title_search_where', 10);
break;
case 'guest_author':
// Keine zusätzlichen Filter zum Entfernen
break;
default:
remove_filter('posts_search', 'csp_custom_search_where', 10);
remove_filter('posts_join', 'csp_custom_search_join', 10);
remove_filter('posts_groupby', 'csp_custom_search_groupby', 10);
break;
}
});
}
}
add_action('pre_get_posts', 'csp_custom_search_results');
// 1⃣1⃣ **Hilfsfunktionen für verschiedene Suchtypen**
function csp_title_search_where($where, $query) {
global $wpdb;
if ($search_term = $query->get('post_title_like')) {
$where .= $wpdb->prepare(
" AND {$wpdb->posts}.post_title LIKE %s",
'%' . $wpdb->esc_like($search_term) . '%'
);
}
return $where;
}
function csp_custom_search_where($where, $query) {
global $wpdb;
if ($search_term = $query->get('_meta_or_title')) {
$search = '%' . $wpdb->esc_like($search_term) . '%';
$where .= $wpdb->prepare(
" OR ({$wpdb->posts}.post_title LIKE %s)
OR ({$wpdb->posts}.post_content LIKE %s)
OR ({$wpdb->posts}.post_excerpt LIKE %s)
OR (guest_author.meta_value LIKE %s)
OR ({$wpdb->users}.display_name LIKE %s)",
$search, $search, $search, $search, $search
);
}
return $where;
}
function csp_custom_search_join($join, $query) {
global $wpdb;
if ($query->get('_meta_or_title')) {
$join .= " LEFT JOIN {$wpdb->postmeta} guest_author ON ({$wpdb->posts}.ID = guest_author.post_id AND guest_author.meta_key = '_guest_author')";
$join .= " LEFT JOIN {$wpdb->users} ON ({$wpdb->posts}.post_author = {$wpdb->users}.ID)";
}
return $join;
}
function csp_custom_search_groupby($groupby, $query) {
global $wpdb;
if ($query->get('_meta_or_title')) {
$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);
?>