व्यवस्थापक में users.php से सभी उपयोगकर्ता मेटा की खोज कैसे करें


14

व्यवस्थापक क्षेत्र (wp-admin / users.php) में सूचीबद्ध उपयोगकर्ताओं के शीर्ष पर खोज फ़ॉर्म सीमित है और सभी उपयोगकर्ता मेटा फ़ील्ड जैसे कि बायो, इंस्टेंट मैसेंजर हैंडल इत्यादि को नहीं खोजता है। एक प्लगइन खोजने में सक्षम है जो इसे जोड़ सकता है।

क्या किसी को एक प्लगइन या किसी फ़ंक्शन के बारे में पता है जो मैं बना सकता हूं जो _usermeta DB में सभी तिथि के लिए इस खोज का विस्तार कर सकता है - आदर्श रूप से एक प्लगइन या फ़ंक्शन द्वारा बनाए गए अतिरिक्त फ़ील्ड भी।

जवाबों:


24

नमस्ते @ user2041:

स्पष्ट रूप से जैसा कि आप जानते हैं कि आपको उस खोज को संशोधित करने की आवश्यकता है जो आप प्रदर्शन के लिए WP_User_Searchउपयोग की गई कक्षा के उदाहरण में मानों को संशोधित करके कर सकते हैं ( /wp-admin/includes/user.phpयदि आप इसका अध्ययन करना चाहते हैं तो स्रोत कोड पा सकते हैं ।)

WP_User_Searchवस्तु

यहां print_r()उस शब्द का क्या है जो वर्डप्रेस 3.0.3 के साथ दिखता है जब " TEST" शब्द खोज रहा है और बिना किसी अन्य प्लगइन्स के जो इसे प्रभावित कर सकता है:

WP_User_Search Object
(
  [results] => 
  [search_term] => TEST
  [page] => 1
  [role] => 
  [raw_page] => 
  [users_per_page] => 50
  [first_user] => 0
  [last_user] => 
  [query_limit] =>  LIMIT 0, 50
  [query_orderby] =>  ORDER BY user_login
  [query_from] =>  FROM wp_users
  [query_where] =>  WHERE 1=1 AND (user_login LIKE '%TEST%' OR user_nicename LIKE '%TEST%' OR user_email LIKE '%TEST%' OR user_url LIKE '%TEST%' OR display_name LIKE '%TEST%')
  [total_users_for_query] => 0
  [too_many_total_users] => 
  [search_errors] => 
  [paging_text] => 
)

pre_user_searchहुक

WP_User_Searchऑब्जेक्ट के मूल्यों को संशोधित करने के लिए, आप 'pre_user_search'हुक का उपयोग करेंगे जो वस्तु का वर्तमान उदाहरण प्राप्त करता है; मैंने print_r()उस हुक के भीतर से इसके मूल्यों तक पहुंच प्राप्त करने के लिए कॉल किया जो मैंने ऊपर प्रदर्शित किया था।

निम्नलिखित उदाहरण जिसे आप अपनी थीम की functions.phpफ़ाइल में कॉपी कर सकते हैं या आप एक प्लगइन के लिए PHP फ़ाइल में उपयोग कर सकते हैं जो आप लिख रहे हैं , अन्य क्षेत्रों पर खोज करने में सक्षम होने के अलावा उपयोगकर्ता के विवरण पर खोज करने की क्षमता जोड़ता है । फ़ंक्शन query_fromऔर के query_whereगुणों को संशोधित करता है$user_search वस्तु जिसे समझने के लिए आपको SQL के साथ सहज होना चाहिए।

हुक में सावधान संशोधित एसक्यूएल

yoursite_pre_user_search()फ़ंक्शन में कोड मानता है कि किसी अन्य प्लगइन ने query_whereइसके पहले खंड को संशोधित नहीं किया है; अगर एक और प्लगइन जहां खंड में संशोधन किया है ऐसी है कि जगह 'WHERE 1=1 AND ('के साथ "WHERE 1=1 AND ({$description_where} OR"अब काम करता है तो यह भी टूट जाएगा। एसक्यूएल को इस तरह से संशोधित करते समय एक और प्लगइन द्वारा तोड़ा नहीं जा सकता इसके अलावा एक मजबूत जोड़ लिखना बहुत कठिन है, लेकिन यह वही है जो यह है।

हुक में SQL सम्मिलित करते समय अग्रणी और अनुगामी रिक्त स्थान जोड़ें

यह भी ध्यान दें कि वर्डप्रेस में एसक्यूएल का उपयोग करते समय हमेशा अग्रणी और अनुगामी रिक्त स्थान को शामिल करना एक अच्छा विचार है " INNER JOIN {$wpdb->usermeta} ON "अन्यथा आपकी एसक्यूएल क्वेरी में निम्नलिखित हो सकता है जहां पहले कोई स्थान नहीं है "INNER", जो निश्चित रूप से विफल होगा " FROM wp_postsINNER JOIN {$wpdb->usermeta} ON ":।

"{$wpdb->table_name"}हार्डकोडिंग टेबल नामों के बजाय का उपयोग करें

अगली बार $wpdbसंपत्तियों का उपयोग हमेशा संदर्भ तालिका के नामों के संदर्भ में करें क्योंकि साइट ने तालिका के उपसर्ग 'wp_'को कुछ और से बदल दिया है। इस प्रकार हार्डकोडिंग के बजाय "{$wpdb->users}.ID" (दोहरे भावों के साथ, एकल नहीं) को संदर्भित करना बेहतर है "wp_users.ID"

क्वेरी को केवल तब तक सीमित करें जब खोज शब्द मौजूद हों

अंत में केवल क्वेरी को संशोधित करना है जब कोई खोज शब्द है जिसे आप ऑब्जेक्ट search_termकी संपत्ति का निरीक्षण करके परीक्षण कर सकते हैं WP_User_Search

के लिए yoursite_pre_user_search()समारोह'pre_user_search'

add_action('pre_user_search','yoursite_pre_user_search');
function yoursite_pre_user_search($user_search) {
  global $wpdb;
  if (!is_null($user_search->search_term)) {
    $user_search->query_from .= " INNER JOIN {$wpdb->usermeta} ON " . 
      "{$wpdb->users}.ID={$wpdb->usermeta}.user_id AND " .
      "{$wpdb->usermeta}.meta_key='description' ";
    $description_where = $wpdb->prepare("{$wpdb->usermeta}.meta_value LIKE '%s'",
      "%{$user_search->search_term}%");
    $user_search->query_where = str_replace('WHERE 1=1 AND (',
      "WHERE 1=1 AND ({$description_where} OR ",$user_search->query_where);    
  }
}

प्रत्येक मेटा कुंजी-मूल्य जोड़ी की खोज के लिए SQL की आवश्यकता होती है JOIN

निश्चित रूप से संभावित कारण वर्डप्रेस आपको usermeta क्षेत्रों पर खोज करने की अनुमति नहीं देता है, यह है कि प्रत्येक एक JOINक्वेरी में SQL जोड़ता है और बहुत अधिक जुड़ाव वाले क्वेरी को वास्तव में धीमा कर सकता है। यदि आपको वास्तव में कई क्षेत्रों में खोज करने की आवश्यकता है तो मैं '_search_cache'usermeta में एक फ़ील्ड बनाऊंगा जो अन्य सभी सूचनाओं को एक usermeta फ़ील्ड में एकत्रित करता है, केवल सभी को खोज करने के लिए केवल एक सम्मिलित होने की आवश्यकता होती है।

मेटा कीज़ में लीडिंग अंडरस्कोर वर्डप्रेस नॉट टू डिस्प्ले को बताता है

ध्यान दें कि अग्रणी अंडरस्कोर '_search_cache'वर्डप्रेस को बताता है कि यह एक आंतरिक मूल्य है और उपयोगकर्ता को कभी प्रदर्शित करने के लिए कुछ नहीं।

'profile_update'और 'user_register'हुक के साथ एक खोज कैश बनाएँ

तो आपको दोनों को हुक करने की आवश्यकता होगी 'profile_update'और 'user_register'एक उपयोगकर्ता को बचाने और क्रमशः एक नया उपयोगकर्ता पंजीकृत करने पर ट्रिगर किया जाएगा। आप उन हुक में सभी मेटा कीज़ और उनके मानों को पकड़ सकते हैं (लेकिन उन मानों को छोड़ दें जो क्रमबद्ध या URL एनकोडेड ऐरे हैं) और फिर उन्हें '_search_cache'कुंजी का उपयोग करके एक लंबे मेटा मान के रूप में संग्रहीत करने के लिए उन्हें सम्मिलित करें ।

मेटा '|'कुंजी-मूल्य जोड़े के रूप में मेटा स्टोर करें

मैंने सभी प्रमुख नामों और उनके सभी मूल्यों को हथियाने और उन्हें कॉलन (":") के साथ एक बड़ी स्ट्रिंग में बदलने का फैसला किया, जो मूल्यों और ऊर्ध्वाधर सलाखों से कुंजी को अलग कर रहे हैं ("|") इस तरह से कुंजी-मूल्य जोड़े को अलग करना (I) 'उन्हें कई रेखाओं में लपेट दिया ताकि आप उन्हें दाईं ओर स्क्रॉल किए बिना कर सकें):

nickname:mikeschinkel|first_name:mikeschinkel|description:This is my bio|
rich_editing:true|comment_shortcuts:false|admin_color:fresh|use_ssl:null|
wp_user_level:10|last_activity:2010-07-28 01:25:46|screen_layout_dashboard:2|
plugins_last_view:recent|screen_layout_post:2|screen_layout_page:2|
business_name:NewClarity LLC|business_description:WordPress Plugin Consulting|
phone:null|last_name:null|aim:null|yim:null|jabber:null|
people_lists_linkedin_url:null

मेटा उपयोग का विशेष खोजों में सक्षम बनाता है key:value

कुंजी और मूल्यों को जोड़ने के रूप में हमने किया था कि आप " rich_editing:true" जैसी खोजों को उन सभी को ढूंढने की अनुमति दें जिनके पास समृद्ध संपादन है, या phone:nullबिना फ़ोन नंबर के उन लोगों को खोजने के लिए " " खोजें।

लेकिन खोज कलाकृतियों से सावधान रहें

बेशक इस तकनीक का उपयोग संभवतः "व्यापार" की खोज जैसी अवांछित खोज कलाकृतियों को बनाता है और सभी को सूचीबद्ध किया जाएगा। यदि यह समस्या है तो आप इस तरह के विस्तृत कैश का उपयोग नहीं करना चाहेंगे।

के लिए yoursite_profile_update()समारोह 'profile_update'और'user_register'

फ़ंक्शन के लिए yoursite_profile_update(), जैसा कि yoursite_pre_user_search()ऊपर आपके विषय की functions.phpफ़ाइल में कॉपी किया जा सकता है या आप एक प्लगइन के लिए PHP फ़ाइल में उपयोग कर सकते हैं जिसे आप लिख रहे हैं:

add_action('profile_update','yoursite_profile_update');
add_action('user_register','yoursite_profile_update');
function yoursite_profile_update($user_id) {
  $metavalues = get_user_metavalues(array($user_id));
  $skip_keys = array(
    'wp_user-settings-time',
    'nav_menu_recently_edited',
    'wp_dashboard_quick_press_last_post_id',
  );
  foreach($metavalues[$user_id] as $index => $meta) {
    if (preg_match('#^a:[0-9]+:{.*}$#ms',$meta->meta_value))
      unset($metavalues[$index]); // Remove any serialized arrays
    else if (preg_match_all('#[^=]+=[^&]\&#',"{$meta->meta_value}&",$m)>0)
      unset($metavalues[$index]); // Remove any URL encoded arrays
    else if (in_array($meta->meta_key,$skip_keys))
      unset($metavalues[$index]); // Skip and uninteresting keys
    else if (empty($meta->meta_value)) // Allow searching for empty
      $metavalues[$index] = "{$meta->meta_key }:null";
    else if ($meta->meta_key!='_search_cache') // Allow searching for everything else
      $metavalues[$index] = "{$meta->meta_key }:{$meta->meta_value}";
  }
  $search_cache = implode('|',$metavalues);
  update_user_meta($user_id,'_search_cache',$search_cache);
}

सभी दिलचस्प मेटा मानों की खोज के लिए yoursite_pre_user_search()एकल SQL JOINको सक्षम करने वाले अपडेट किए गए फ़ंक्शन

निश्चित रूप yoursite_profile_update()से किसी भी प्रभाव के लिए आपको विवरण के बजाय मेटा कुंजी yoursite_pre_user_search()का उपयोग करने के लिए संशोधित करने की आवश्यकता होगी '_search_cache', जो हमारे पास यहां है (ऊपर बताए गए समान केट के साथ):

add_action('pre_user_search','yoursite_pre_user_search');
function yoursite_pre_user_search($user_search) {
  global $wpdb;
  if (!is_null($user_search->search_term)) {
    $user_search->query_from .= " INNER JOIN {$wpdb->usermeta} ON " . 
      "{$wpdb->users}.ID={$wpdb->usermeta}.user_id AND " . 
      "{$wpdb->usermeta}.meta_key='_search_cache' ";
    $meta_where = $wpdb->prepare("{$wpdb->usermeta}.meta_value LIKE '%s'",
      "%{$user_search->search_term}%");
    $user_search->query_where = str_replace('WHERE 1=1 AND (',
      "WHERE 1=1 AND ({$meta_where} OR ",$user_search->query_where);
  }
}

@MikeSchinkel महान, पूरी तरह से जवाब! यह इस साइट पर कई बार में से एक है जहां मैं चाहता हूं कि मैं एक गैर-स्टॉक प्रश्न के लिए इस तरह के शोधपूर्ण उत्तर के लिए कई अपवॉट्स दे सकता हूं।
मथसम्मथ

धन्यवाद @MathSmath - सीखना कि लोग इसकी सराहना करते हैं, जो मुझे बनाए रखता है। :)
माइकस्किंकेल

माइक, पूरी तरह से उत्तर के लिए धन्यवाद! मैं इसे अपने विषय में आज बाद में काम करूँगा और देखता हूँ कि यह किसके पास जाता है।
जॉन चांडलर

माइक, हम पास हैं, लेकिन ..! स्पष्ट रूप से यह मुझे सही शुरुआत से दूर कर रहा है। या तो आप पहले उल्लेख किए गए एकल फ़ंक्शन का उपयोग कर रहे हैं, या profile_update का उपयोग करने के दो कार्य उचित परिणाम खोजने और प्राप्त करने की क्षमता के संदर्भ में काम कर रहे हैं। दुर्भाग्य से, ये फ़ंक्शंस लिस्टिंग के साथ खिलवाड़ कर रहे हैं जब मैं पहली बार users.php (जो कोई खोज शब्द निर्दिष्ट नहीं है) को खींचता हूं। यह सभी उपयोगकर्ताओं को नहीं दिखा रहा है। जब मैं ऑल फिल्टर पर क्लिक करता हूं, तो यह केवल दो दिखाता है (चार में से), जिनमें से एक मैं हूं, और जब मैं एडमिनिस्ट्रेटर पर क्लिक करता हूं तो यह किसी भी उपयोगकर्ता को नहीं करता है - मुझे भी नहीं! कोई विचार?
जॉन चैंडलर

थोड़ी और जानकारी। मैंने 'कंपनी' नामक क्षेत्र को खोजने के लिए पहला फ़ंक्शन संपादित किया, जिसे मैंने अतिरिक्त उपयोगकर्ता विवरण प्लगइन के माध्यम से जोड़ा। यह तब काम करता है जब मैं एक कंपनी के नाम वाले उपयोगकर्ता की खोज करता हूं। लेकिन, ऐसा प्रतीत होता है कि ऑल द्वारा छँटाई, बिना किसी खोज के, केवल उन दो परिणामों को वापस कर रहा है जिनके पास कंपनी क्षेत्र में डेटा है, और उन उपयोगकर्ताओं को वापस नहीं कर रहे हैं जिनके पास कंपनी क्षेत्र में कोई डेटा नहीं है।
जॉन चांडलर

5

मैंने वास्तव में माइकस्किंकेल के दृष्टिकोण और उपरोक्त पूरी तरह से स्पष्टीकरण की सराहना की। यह सुपर-सहायक था। मुझे यह मेरे लिए काम करने के लिए नहीं मिल सका क्योंकि pre_user_search को पदावनत कर दिया गया है और वास्तव में 3.2 में काम नहीं करता है। मैं सिर्फ pre_user_query के साथ इसे बाहर स्विच करने की कोशिश की, लेकिन वह भी काम नहीं किया। बात यह है, ऐसा लगता है कि $ user_search-> search_term अब काम नहीं करता है इसलिए मैंने अभी $ _GET ['s'] का उपयोग किया है। मैंने कुछ हैकिंग की और 3.2 में काम करने में सक्षम था। केवल एक चीज जिसे आपको सेट करने की आवश्यकता है, वह है आपकी खोज योग्य मेटाडेटा की सरणी।

//Searching Meta Data in Admin
add_action('pre_user_query','yoursite_pre_user_search');
function yoursite_pre_user_search($user_search) {
    global $wpdb;
    if (!isset($_GET['s'])) return;

    //Enter Your Meta Fields To Query
    $search_array = array("customer_id", "postal_code", "churchorganization_name", "first_name", "last_name");

    $user_search->query_from .= " INNER JOIN {$wpdb->usermeta} ON {$wpdb->users}.ID={$wpdb->usermeta}.user_id AND (";
    for($i=0;$i<count($search_array);$i++) {
        if ($i > 0) $user_search->query_from .= " OR ";
            $user_search->query_from .= "{$wpdb->usermeta}.meta_key='" . $search_array[$i] . "'";
        }
    $user_search->query_from .= ")";        
    $custom_where = $wpdb->prepare("{$wpdb->usermeta}.meta_value LIKE '%s'", "%" . $_GET['s'] . "%");
    $user_search->query_where = str_replace('WHERE 1=1 AND (', "WHERE 1=1 AND ({$custom_where} OR ",$user_search->query_where);    
}

आशा है कि यह किसी की मदद करता है।


किसी को भी इस के साथ किसी भी हाल के अनुभव है? व्यक्तिगत रूप से, मुझे इनमें से कोई भी कोड काम नहीं कर सकता है, जिसमें नवीनतम शामिल हैं। मैंने कुछ अन्य विकल्पों की कोशिश की है, लेकिन परिणाम अंकुरण के साथ समस्याओं को पाया है
रॉबर्ट एंड्रयूज

1

FYI करें, इस विषय पर खोज करने वाले (उपयोगकर्ता पैनल खोज क्वेरी को समायोजित करने के लिए) और इस उत्कृष्ट पृष्ठ को खोजने के लिए, WP_User_Search को WP_User_Query द्वारा 3.1 के रूप में चित्रित किया गया है: http://codex.wordpress.org/assass_Reference/WP_User_Query


1

यहाँ Wordpress के नवीनतम संस्करण का एक समाधान है।

add_action( 'pre_user_query', 'yoursite_pre_user_search'  );
    function yoursite_pre_user_search( $query ) {
        $query->query_where .= "YOUR QUERY '" . str_replace("*", "%", $query->query_vars[ 'search' ] ) . "')";
    }

-1

यह वही है जो मैं वर्डप्रेस 4.7.1 के लिए आया था जो सभी उपयोगकर्ता मेटा डेटा में वाइल्डकार्ड खोज जोड़ता है।


add_action( 'pre_user_query', 'ds_pre_user_search'  );
function ds_pre_user_search( $query ) {
    global $wpdb;

    if( empty($_REQUEST['s']) ){return;}
    $query->query_from .= ' LEFT JOIN '.$wpdb->usermeta.' ON '.$wpdb->usermeta.'.user_id = '.$wpdb->users.'.ID';
    $query->query_where = "WHERE 1=1 AND (user_login LIKE '%".$_REQUEST['s']."%' OR ID = '".$_REQUEST['s']."' OR meta_value LIKE '%".$_REQUEST['s']."%')";
    return $query;
}

मूल रूप से हम सिर्फ उपयोगकर्ता आईडी पर उपयोगकर्ता और user_meta टेबल से जुड़ रहे हैं और meta_value कॉलम पर खोज को शामिल करने के लिए WHERE क्लॉज का पुनर्निर्माण कर रहे हैं।


1
आप यहाँ जो सुझाव दे रहे हैं वह बहुत खतरनाक है ! आपको कभी भी, उपयोगकर्ता द्वारा डीबी में जो भी प्रदान किया जाता है , उसे पास नहीं करना चाहिए । वे आपकी तालिकाओं को छोड़ सकते हैं, अपने डेटाबेस को हाईजैक कर सकते हैं - SQL इंजेक्शन को खोज वाक्यांश के रूप में देख सकते हैं - या बस अपने सभी डेटा को एन्क्रिप्ट कर सकते हैं। "%".like_escape( $_GET['s'] )."%"इसके बजाय करो । वही अन्य सभी उपयोगकर्ता प्रदान किए गए डेटा के लिए जाता है । आपकी खोज का क्षेत्र आपके डेटा के लिए एक खुला प्रवेश द्वार बन जाता है।
केसर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.