สร้างการอ้างอิงเบ็ดที่อยู่เฉยๆ


10

ดูเหมือนว่านักพัฒนาปลั๊กอินจำนวนมากใช้เวลาเพิ่มตะขอตัวกรอง / แอ็คชั่นเพื่อให้ผู้ใช้ปรับแต่งการทำงานของผลิตภัณฑ์ อันไหนดี แต่สิ่งที่พวกเขามักจะไม่ทำคือให้รายชื่อของ hooks และจำนวนข้อโต้แย้งที่พวกเขาใช้

มีใครพบวิธีอัตโนมัติที่ดีที่สุดในการชี้ไปที่ไดเรกทอรี plugin (หรือ theme) และดูรายการ hooks ที่มีทั้งหมดหรือไม่

ฉันดูเหมือนปลั๊กอินที่สแกนหา hooks แต่เท่าที่ฉันสามารถบอกได้พวกเขาแสดงให้คุณเห็นว่ามีคนใดที่ถูกเรียกให้แสดงหน้าเว็บ ซึ่งฉันได้รับนั้นมีประโยชน์ แต่บางครั้งถ้าฉันรู้ว่าฉันมีปฏิสัมพันธ์กับปลั๊กอินเฉพาะฉันต้องการทราบทุกที่มันอาจให้ฉันขอการกระทำหรือตัวกรอง

ดังนั้นสิ่งที่ฉันกำลังมองหาคือสิ่งที่กำหนดให้ไดเรกทอรีรากของปลั๊กอินจะสร้างรายการที่แต่ละรายการรวมถึง:

  • แท็ก
  • ประเภท (การกระทำหรือตัวกรอง)
  • จำนวนอาร์กิวเมนต์
  • โดยที่มันถูกเรียก (ผ่านdo_action()หรือapply_filter()) ในแหล่งที่มา

สคริปต์จะดีมากเนื่องจากมันน่าจะเป็น HTMLify อย่างสมบูรณ์และแสดงให้ฉันเห็นใน UI ของผู้ดูแลระบบสำหรับทุกปลั๊กอิน แต่แม้แต่สคริปต์บรรทัดคำสั่งที่ส่งออกไฟล์สแตติกที่มีประโยชน์ก็ยอดเยี่ยมเช่นกัน


ดังนั้นคำถามคืออะไร หากคุณกำลังมองหาคำแนะนำปลั๊กอินอยู่นอกหัวข้อที่นี่
Mark Kaplun

ขออภัยไม่ต้องการเข้าไปไกลในวัชพืชพัฒนา WordPress Metaแต่ a) ฉันใหม่ที่นี่ดังนั้นฉันไม่ได้ตระหนักว่าการขอคำแนะนำปลั๊กอินเป็น OT ฉันอาจมี ... ความคิดเห็นบางอย่าง ... แต่ฉันก็ควรตระหนักก่อน b) OTOH ฉันแค่พยายามหาคำตอบให้กับคำถามของฉันไม่ว่าจะเป็นปลั๊กอินหรือเชลล์สคริปต์หรืออะไรก็ตาม ดังนั้นคำถามคือขอคำแนะนำปลั๊กอินอย่างเคร่งครัด !
yonatron

ดูเหมือนว่าทุกคนจะมีความสนุกสนานไม่มีอันตรายใด ๆ เกิดขึ้น "คัดค้าน" คำถามของฉันเป็นจริงเกี่ยวกับมันเป็นคำถามแยกวิเคราะห์ข้อความซึ่งเป็นที่น่าสนใจสำหรับคนที่ชอบเขียนซอฟต์แวร์สไตล์คอมไพเลอร์ แต่มีน้อยมากที่จะทำกับการเข้ารหัส wordpress จริง สำหรับบันทึกแม้แต่คำถามที่เกี่ยวกับ wordpress.org เช่นวิธีการส่งปลั๊กอินมักจะได้รับการโหวตเป็นนอกหัวข้อ
Mark Kaplun

คำตอบ:


6

ไม่มีสคริปต์หรือปลั๊กอินที่ฉันรู้ว่าจะทำสิ่งที่คุณต้องการ ตามที่คุณระบุไว้มีสคริปต์ ( แม้แต่ตัวแปรทั่วโลก ) ซึ่งคุณสามารถใช้เพื่อพิมพ์ตัวกรองและการกระทำที่กำลังใช้อยู่

สำหรับตัวกรองและแอ็คชั่นที่หยุดนิ่งฉันได้เขียนฟังก์ชั่นพื้นฐานสองอย่าง ( ด้วยความช่วยเหลือที่นี่และที่นั่น ) ซึ่งค้นหาทั้งหมดapply_filtersและdo_actionอินสแตนซ์ในไฟล์แล้วพิมพ์ออกมา

พื้นฐาน

  • เราจะใช้RecursiveDirectoryIterator, RecursiveIteratorIteratorและRegexIteratorเรียน PHP ได้รับไฟล์ทั้งหมด PHP ภายในไดเรกทอรี ตัวอย่างเช่นใน localhost ของฉันฉันได้ใช้E:\xammp\htdocs\wordpress\wp-includes

  • จากนั้นเราจะห่วงผ่านไฟล์และการค้นหาและผลตอบแทน ( preg_match_all) ทุกกรณีและapply_filters do_actionฉันได้ตั้งค่าให้ตรงกับอินสแตนซ์ที่ซ้อนกันของวงเล็บและเพื่อให้ตรงกับช่องว่างที่เป็นไปได้ระหว่างapply_filters/ do_actionและวงเล็บแรก

จากนั้นเราจะสร้างอาร์เรย์ที่มีตัวกรองและการกระทำทั้งหมดจากนั้นวนรอบอาร์เรย์และส่งออกชื่อไฟล์และตัวกรองและการกระทำ เราจะข้ามไฟล์โดยไม่มีตัวกรอง / การกระทำ

หมายเหตุที่สำคัญ

  • ฟังก์ชั่นนี้มีราคาแพงมาก เรียกใช้พวกเขาเฉพาะในการติดตั้งการทดสอบในท้องถิ่น

  • ปรับเปลี่ยนฟังก์ชั่นได้ตามต้องการ คุณสามารถตัดสินใจที่จะเขียนออกไปยังไฟล์สร้างหน้าแบ็กเอนด์พิเศษสำหรับการที่ตัวเลือกไม่ จำกัด

ตัวเลือกที่ 1

ฟังก์ชั่นตัวเลือกแรกนั้นง่ายมากเราจะคืนเนื้อหาของไฟล์เป็นสตริงโดยใช้file_get_contentsค้นหาapply_filters/ do_actionอินสแตนซ์และเพียงแค่ส่งชื่อไฟล์และชื่อตัวกรอง / แอ็คชั่น

ฉันได้แสดงความคิดเห็นรหัสสำหรับการติดตามได้ง่าย

function get_all_filters_and_actions( $path = '' )
{
    //Check if we have a path, if not, return false
    if ( !$path ) 
        return false;

    // Validate and sanitize path
    $path = filter_var( $path, FILTER_SANITIZE_URL );
    /**
     * If valiadtion fails, return false
     *
     * You can add an error message of something here to tell
     * the user that the URL validation failed
     */
    if ( !$path ) 
        return false;

    // Get each php file from the directory or URL  
    $dir   = new RecursiveDirectoryIterator( $path );
    $flat  = new RecursiveIteratorIterator( $dir );
    $files = new RegexIterator( $flat, '/\.php$/i' );

    if ( $files ) {

        $output = '';
        foreach($files as $name=>$file) {
            /**
             * Match and return all instances of apply_filters(**) or do_action(**)
             * The regex will match the following
             * - Any depth of nesting of parentheses, so apply_filters( 'filter_name', parameter( 1,2 ) ) will be matched
             * - Whitespaces that might exist between apply_filters or do_action and the first parentheses
             */
            // Use file_get_contents to get contents of the php file
            $get_file_content =  file_get_contents( $file );
            // Use htmlspecialchars() to avoid HTML in filters from rendering in page
            $save_content = htmlspecialchars( $get_file_content );
            preg_match_all( '/(apply_filters|do_action)\s*(\([^()]*(?:(?-1)[^()]*)*+\))/', $save_content, $matches );

            // Build an array to hold the file name as key and apply_filters/do_action values as value
            if ( $matches[0] )
                $array[$name] = $matches[0];
        }
        foreach ( $array as $file_name=>$value ) {

            $output .= '<ul>';
                $output .= '<strong>File Path: ' . $file_name .'</strong></br>';
                $output .= 'The following filters and/or actions are available';
                foreach ( $value as $k=>$v ) {
                    $output .= '<li>' . $v . '</li>';
                }
            $output .= '</ul>';
        }
        return $output;
    }

    return false;
}

คุณสามารถใช้งานได้ตามแม่แบบส่วนหน้าหรือส่วนหลัง

echo get_all_filters_and_actions( 'E:\xammp\htdocs\wordpress\wp-includes' );

สิ่งนี้จะพิมพ์

ป้อนคำอธิบายรูปภาพที่นี่

ตัวเลือก 2

ตัวเลือกนี้มีราคาแพงกว่าเล็กน้อยในการทำงาน ฟังก์ชันนี้ส่งคืนหมายเลขบรรทัดที่สามารถพบตัวกรอง / แอ็คชัน

ที่นี่เราใช้fileในการระเบิดไฟล์เป็นอาร์เรย์จากนั้นเราค้นหาและส่งกลับตัวกรอง / การกระทำและหมายเลขบรรทัด

function get_all_filters_and_actions2( $path = '' )
{
    //Check if we have a path, if not, return false
    if ( !$path ) 
        return false;

    // Validate and sanitize path
    $path = filter_var( $path, FILTER_SANITIZE_URL );
    /**
     * If valiadtion fails, return false
     *
     * You can add an error message of something here to tell
     * the user that the URL validation failed
     */
    if ( !$path ) 
        return false;

    // Get each php file from the directory or URL  
    $dir   = new RecursiveDirectoryIterator( $path );
    $flat  = new RecursiveIteratorIterator( $dir );
    $files = new RegexIterator( $flat, '/\.php$/i' );

    if ( $files ) {

        $output = '';
        $array  = [];
        foreach($files as $name=>$file) {
            /**
             * Match and return all instances of apply_filters(**) or do_action(**)
             * The regex will match the following
             * - Any depth of nesting of parentheses, so apply_filters( 'filter_name', parameter( 1,2 ) ) will be matched
             * - Whitespaces that might exist between apply_filters or do_action and the first parentheses
             */
            // Use file_get_contents to get contents of the php file
            $get_file_contents =  file( $file );
            foreach ( $get_file_contents as  $key=>$get_file_content ) {
                preg_match_all( '/(apply_filters|do_action)\s*(\([^()]*(?:(?-1)[^()]*)*+\))/', $get_file_content, $matches );

                if ( $matches[0] )
                    $array[$name][$key+1] = $matches[0];
            }
        }

        if ( $array ) {
            foreach ( $array as $file_name=>$values ) {
                $output .= '<ul>';
                    $output .= '<strong>File Path: ' . $file_name .'</strong></br>';
                    $output .= 'The following filters and/or actions are available';

                    foreach ( $values as $line_number=>$string ) {
                        $whitespaces = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
                        $output .= '<li>Line reference ' . $line_number . $whitespaces . $string[0] . '</li>';
                    }
                $output .= '</ul>';
            }
        }
        return $output;

    }

    return false;
}

คุณสามารถใช้งานได้ตามแม่แบบส่วนหน้าหรือส่วนหลัง

echo get_all_filters_and_actions2( 'E:\xammp\htdocs\wordpress\wp-includes' );

สิ่งนี้จะพิมพ์

ป้อนคำอธิบายรูปภาพที่นี่

แก้ไข

โดยพื้นฐานแล้วฉันสามารถทำได้โดยไม่ต้องใช้สคริปต์หมดเวลาหรือหน่วยความจำไม่เพียงพอ ด้วยรหัสในตัวเลือก 2 มันง่ายเหมือนกับการไปที่ไฟล์ดังกล่าวและบรรทัดดังกล่าวในซอร์สโค้ดจากนั้นรับค่าพารามิเตอร์ที่ถูกต้องทั้งหมดของตัวกรอง / แอ็คชันเช่นกันที่สำคัญรับฟังก์ชั่นและบริบทเพิ่มเติมที่ ใช้ตัวกรอง / การกระทำ


1
คุณมีเวลาว่างมากเกินไป;) แต่ในท้ายที่สุดมันก็ไม่เคยพอที่จะรู้ว่าตัวกรองคืออะไร แต่ยังรวมถึงค่าพารามิเตอร์และผลลัพธ์ที่คาดหวังและสิ่งนี้ไม่สามารถทำได้จากแหล่งที่มาโดยไม่ต้อง bactracking เพื่อรับบล็อก doc ในกรณี ของไฟล์หลักและอาจไม่พร้อมใช้งานในปลั๊กอินและธีมที่ไม่ใช่คอร์
Mark Kaplun

1
@ MarkKaplun นี่เป็นเพียงบางสิ่งที่ฉันทำงานได้อย่างรวดเร็ว :-) ฟังก์ชั่นด้านบนอย่างน้อยก็บอกคุณว่าตัวกรองและการดำเนินการอยู่ในไดเรกทอรีปลั๊กอิน / ชุดรูปแบบ / core ที่เฉพาะเจาะจง ยังคงมีความสำคัญมากที่จะกลับไปที่แหล่งที่มาและตรวจสอบให้แน่ใจว่าคุณเข้าใจว่าตัวกรองเฉพาะนั้นทำอะไรเป็นพิเศษ ปลั๊กอินและชุดรูปแบบบางอย่างมีเอกสารไม่ดีดังนั้นคุณยังต้องมีความรู้และพื้นหลังบางอย่างเพื่อทราบหรือคิดออกว่าตัวกรองที่เฉพาะเจาะจงทำงานอย่างไรในฟังก์ชั่นเฉพาะ ;-)
Pieter Goosen

@PieterGoosen ใช่ฉันมักจะตกลงกับการกระโดดกลับเพื่อดูแหล่งที่มา ถ้าฉันทำสิ่งนี้ในตอนแรกมันหมายความว่าปลั๊กอินมี hooks แต่ไม่จำเป็นต้องบล็อก doc สำหรับพวกเขา แต่ถ้าฉันดูที่พวกเขาใช้งานจริงมันช่วยให้ฉันรู้ว่าพวกเขามีค่าหรือไม่ อย่างไรก็ตามดูเหมือนว่าพวกเขาจะดี ฉันอาจแก้ไขไฟล์ที่ 2 เพื่อเขียนไปยังไฟล์ HTML เพราะฉันสามารถติดประกาศฟังก์ชันในปลั๊กอิน MU บนเซิร์ฟเวอร์ภายในและเรียกใช้จาก WP CLI
yonatron

@yonatron ดีใจที่เซ็นต์ทั้งสองของฉันช่วยในทางใดทางหนึ่ง หากคุณเคยเขียนการดัดแปลงของคุณเองจากรหัสของฉันคุณสามารถเพิ่มรหัสและคำอธิบายของคุณเป็นคำตอบ ( ซึ่งจะดีมาก ) ;-) สนุกกับ
Pieter Goosen

1
@PieterGoosen ใช้เวลาเท่าไหร่ในการเขียนสคริปต์นี้รวมถึงเอกสารน่ากลัวมาก ***** :)
Webloper

6

เสียงเหมือนWP Parserทำในสิ่งที่คุณกำลังมองหา มันถูกใช้เพื่อสร้างอย่างเป็นทางการของการอ้างอิงสำหรับนักพัฒนา มันแสดงรายการพารามิเตอร์ @since แท็กและการอ้างอิงไปยังแหล่งที่มา มันทำงานร่วมกับปลั๊กอิน WordPress ทั้งหมดและสามารถเข้าถึงได้ผ่านทางบรรทัดคำสั่ง:

wp parser create /path/to/source/code --user=<id|login>

1
ฉันไม่คุ้นเคยกับสคริปต์นั้นมากนัก แต่ดูเหมือนว่าจะต้องมีตัวกรองหรือการกระทำเพื่อให้ได้รับการบันทึกไว้อย่างดี จะขอบคุณข้อเสนอแนะเกี่ยวกับเรื่องนี้จาก @Rarst ;-)
Pieter Goosen

ฉันยังไม่ได้ลองเลย แต่จากคำอธิบายฉันคิดว่า Pieter เป็นห่วงเป้าหมาย ฉันต้องการค้นหา hooks ทั้งหมดไม่ใช่เฉพาะบล็อกนำหน้าที่มีรูปแบบที่ดีเท่านั้น ฉันคิดว่าคนที่ใช้เวลาในการแสดงความคิดเห็น hooks / ฟังก์ชั่นของพวกเขาโดยใช้การประชุม WordPress กำลังเรียกใช้สคริปต์ประเภทนี้และเผยแพร่อ้างอิง API บนเว็บไซต์สนับสนุนของพวกเขา ฉันรู้ว่ามีความเสี่ยงในเรื่องนี้เนื่องจากหากนักพัฒนาไม่ได้จัดทำเอกสารตัวกรองต่อสาธารณชนมันอาจถูกเปลี่ยน / เลิกใช้งานโดยไม่มีการเตือน แต่สำหรับปลั๊กอินบางตัวที่ฉันใช้ฉันไม่สามารถรอเอกสารให้แสดงทางออนไลน์ได้
yonatron

นอกจากนี้ยังแยกวิเคราะห์ hooks ที่ไม่มีเอกสาร ตัวอย่าง: developer.wordpress.org/reference/hooks/graceful_fail
Jan Beck

4

อย่างรวดเร็วและรุนแรง

*nixบรรทัดคำสั่งol ที่ดีนั้นมีประโยชน์เสมอ:

# grep  --line-number                                         \
        --exclude-dir=/path/to/some/directory                 \
        --include=*.php                                       \ 
        --recursive                                           \
        "add_filter\|do_action\|apply_filters"                \
        /path/to/wp-content/plugins/some-plugin               \ 
 | less

ตัวเลือกอื่น ๆ #man grepอีกมากมายผ่านทาง

แล้วเรายังสามารถสร้างสคริปต์ทุบตีง่ายwp-search.sh:

#!/bash/bin
grep --line-number                            \
    --exclude-dir=/path/to/some/directory     \
    --include=*.$1                            \
    --recursive $2 $3

และเรียกใช้ด้วย

 # bash wp-search.sh php "add_filter\|do_action\|apply_filters" /path/to/some-plugin

เอาท์พุทสวย

เราสามารถใช้แอ--colorททริบิวต์เพื่อทำให้สีของผลลัพธ์มีสีสันgrepแต่โปรดทราบว่าจะไม่สามารถใช้งานlessได้

ตัวเลือกอื่นคือการสร้างตาราง HTML สำหรับผลการค้นหา

นี่คือawkตัวอย่างที่ฉันสร้างขึ้นที่ให้ผลลัพธ์การค้นหาเป็นตาราง HTML ลงในresults.htmlไฟล์:

  | sed 's/:/: /2' \
  | awk ' \
        BEGIN { \
            print "<table><tr><th>Results</th><th>Location</th></tr>"  \
        } \
        { \
            $1=$1; location=$1; $1=""; print "<tr><td>" $0 "</td><td>" location "</td><tr>" \
        } \
        END {  \
           print "</table>" \
       }' \
 > results.html

ที่ฉันใช้เคล็ดลับนี้เพื่อลบพื้นที่สีขาวนำหน้าและอันนี้เพื่อพิมพ์ฟิลด์ทั้งหมดยกเว้นอันแรก

ฉันใช้sedที่นี่เพียงเพื่อเพิ่มพื้นที่พิเศษหลังเครื่องหมายทวิภาคที่สอง ( :) ในกรณีที่ไม่มีที่ว่าง

ต้นฉบับ

เราสามารถเพิ่มสิ่งนี้ลงในwp-search.shสคริปต์ของเรา:

#!/bash/bin
grep   --with-filename \
       --line-number \
       --exclude-dir=/path/to/some/directory \
       --include=*.$1 \
       --recursive $2 $3 \
| sed 's/:/: /2' \
| awk ' BEGIN { \
        print "<table><tr><th>Results</th><th>Location</th></tr>"  \
    } \
    { \
        $1=$1; location=$1; $1=""; print "<tr><td>" $0 "</td><td>" location "</td><tr>" \
    } \
    END {  \
        print "</table>" \
    }' \
> /path/to/results.html

สถานที่ที่คุณต้องปรับ/path/to/some/directoryและ/path/to/results.htmlความต้องการของคุณ

ตัวอย่าง - การค้นหาปลั๊กอิน

หากเราลองใช้wordpress-importerปลั๊กอินนี้กับ:

bash wp-search.sh php "add_filter\|do_action" /path/to/wp-content/plugins/wordpress-importer/

จากนั้นresults.htmlไฟล์จะแสดงเป็น:

ผล

ตัวอย่าง - ค้นหาแกน

ฉันทดสอบเวลาสำหรับแกน:

time bash wp-search.sh php "add_filter\|do_action" /path/to/wordpress/core/

real    0m0.083s
user    0m0.067s
sys     0m0.017s

และมันก็เร็ว!

หมายเหตุ

เพื่อให้ได้บริบทเพิ่มเติมเราอาจใช้-C NUMBERgrep

เราสามารถแก้ไขเอาต์พุต HTML ได้หลายวิธี แต่หวังว่าคุณจะสามารถปรับได้ตามความต้องการของคุณ


ขอบคุณ! ฉันใช้ grep อย่างฉับพลัน แต่ฉันเป็นมือใหม่ที่เก็บของที่ฉันไม่เคยแม้แต่จะใช้กับท่อสำหรับ OR สิ่งอื่น ๆ ที่ฉันต้องการเพิ่ม แต่เป็นตัวเลือกในการพิมพ์สวย ๆ การส่งออกของบรรทัด grep ข้างต้นยังคงเป็นเรื่องยากที่จะเรียด
yonatron

2
ฉันอัปเดตคำตอบด้วยตัวอย่างการพิมพ์ @yonatron
birgire
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.