Створюйте сплячі посилання на гачок


10

Здається, що багато розробників плагінів потребують часу, щоб додати гачки фільтру / дії, щоб користувачі могли налаштувати функціональність своїх продуктів. Що чудово, але те, що вони часто не роблять, - це перелік гачків та кількість аргументів, які вони беруть.

Хтось знайшов найкращий автоматизований спосіб вказати на каталог плагінів (або теми) і побачити список усіх доступних гачків?

Мені здаються деякі плагіни, які шукають гачки, але, наскільки я можу сказати, вони показують, які саме з них викликаються, щоб відобразити певну сторінку. Що я можу бути корисним. Але іноді, якщо я знаю, що я взаємодію з певним плагіном, я хочу знати, яке місце воно може дати мені підключити дію чи фільтр.

Тож те, що я насправді шукаю, - це те, що, даючи кореневому каталогу плагінів, створить список, де кожен елемент включає:

  • тег
  • тип (дія чи фільтр)
  • кількість аргументів
  • де це називається (через do_action()або apply_filter()) у джерелі

Сценарій був би чудовим, оскільки це, мабуть, може добре HTMLфікувати всю справу і показати мені це правильно в інтерфейсі адміністратора для кожного плагіна. Але навіть сценарій командного рядка, який видає корисний статичний файл, був би чудовим.


так що питання? якщо ви шукаєте рекомендації щодо плагінів, це тут поза темою
Марк Каплун

Вибачте, я не хочу занадто сильно заглиблюватися в металеві бур'яни WordPress Development , але а) Я тут новачок, тому я не усвідомлював, що просити рекомендації щодо плагінів - це ОТ. Я, можливо, маю… деякі думки… з цього приводу, але все-таки я мав би зрозуміти це першим. б) OTOH, я просто намагаюся знайти будь-яке рішення мого питання, чи то існуючий плагін або скрипт оболонки, чи щось з нуля. Тож питання - суворо запит щодо рекомендацій щодо плагінів!
іонатрон

ну здається, що всі інші розважаються, тому шкоди не завдають. Моє "заперечення" на питання було насправді більше про те, що це питання розбору тексту, що цікаво для людей, які люблять писати програмне забезпечення в стилі компілятора, але має дуже мало спільного з фактичним кодуванням wordpress. Для запису навіть питання, що стосуються wordpress.org, як, наприклад, як подати плагін, зазвичай отримують голосування як поза тему.
Марк Каплун

Відповіді:


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;
}

Ви можете користуватися функцією "follow" на шаблоні, фронтені чи вихідному сервері

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;
}

Ви можете користуватися функцією "follow" на шаблоні, фронтені чи вихідному сервері

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

Це надрукується

введіть тут опис зображення

EDIT

Це в основному стільки, скільки я можу зробити, якщо сценарії не закінчуються або не вистачає пам'яті. З кодом у варіанті 2 це так само просто, як перейти до згаданого файлу та вказаного рядка у вихідному коді, а потім отримати всі дійсні значення параметрів фільтра / дії, а також, що важливо, отримати функцію та подальший контекст, у якому використовується фільтр / дія


1
у вас занадто багато вільного часу;) але врешті-решт, ніколи не достатньо знати, що таке фільтри, а також які очікувані значення параметрів та результати, і цього неможливо досягти з джерела без зворотного контролю, щоб отримати блок doc у випадку основних файлів і, мабуть, взагалі недоступні в непрофільних плагінах та темах.
Марк Каплун

1
@MarkKaplun це просто те, над чим я швидко працював :-). Наведені вище функції принаймні вказують вам, де фільтри та дії знаходяться в конкретних каталогіх плагінів / тем / основних. Все ще залишається дуже важливим повернутися до джерела і переконатися, що ви розумієте, що конкретно робить фільтр. Деякі плагіни та теми погано задокументовані, тому вам все одно знадобляться якісь знання та передумови, щоб знати чи з’ясувати, що робить конкретний фільтр у певній функції ;-)
Пітер Гузен

@PieterGoosen Так, я звичайно гаразд зі стрибками назад, щоб подивитися на джерело. Якщо я роблю це в першу чергу, це означає, що плагін має гачки, але не обов'язково док-блоки для них. Але якщо я погляну, де вони насправді використовуються, це допоможе мені зрозуміти, чи є вони цінними. У будь-якому випадку вони виглядають так, що вони можуть бути чудовими. Я можу навіть змінити їх 2-го, щоб просто записати у файл HTML, оскільки тоді я міг просто вставити декларацію функції у плагін MU на локальному сервері та запустити його з WP CLI.
йонатрон

@yonatron Радий, що мої два центи певним чином допомагають. Якщо ви коли-небудь прийдете написати свою модифікацію з мого коду, ви завжди можете додати свій код та пояснення як відповідь ( що буде чудово ) ;-). Насолоджуйтесь
Пітер Гусен

1
@PieterGoosen, скільки часу пішло на написання цього сценарію, а також на документування, ощасливив його чудовий ***** :)
Webloper

6

Звучить, що WP Parser робить те, що ви шукаєте. Він використовується для отримання офіційної довідки розробника . У ньому перераховані параметри, теги @since та посилання на джерело. Він працює з усіма плагінами WordPress і до нього можна отримати доступ через командний рядок:

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

1
Я не дуже знайомий із цим сценарієм, але, здається, потрібен фільтр чи дії, щоб вони були добре задокументовані. Будемо вдячні щодо цього відгуку від @Rarst ;-)
Пітер Гузен

Я ще не пробував цього, але, виходячи з опису, я думаю, що Пітер стурбований націленим. Я хочу знайти всі гачки, а не лише ті, яким передують добре відформатовані doc-блоки. Я думаю, що люди, які задіюють час, щоб коментувати свої гачки / функції за допомогою WordPress-конвенцій, вже використовують такий сценарій та публікують посилання API на своїх сайтах підтримки. Я розумію, що в цьому є певний ризик, оскільки якщо розробник не публічно публікує фільтр, він може бути змінений / застарілий без попередження, але для деяких плагінів, які я використовую, я не можу чекати, коли документи з’являться в Інтернеті.
йонатрон

Він також розбирає незадокументовані гачки. Приклад: developer.wordpress.org/reference/hooks/graceful_fail
Jan Beck

4

Форсаж

*nixКомандний рядок good 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.

Тоді ми навіть можемо створити простий скрипт bash 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 NUMBERгреп.

Ми можемо модифікувати вихід HTML різними способами, але, сподіваємось, ви зможете додатково налаштувати це під свої потреби.


Дякую! Я використовую grep у крайньому випадку, але я такий початківець при роботі з оболонками, що я ніколи навіть не зациклювався на використанні труб для АБО. Інше, що я хотів би додати, хоча це варіанти, щоб трохи роздрукувати його. Вихід з вищевказаної лінії грепп все ще буде досить важким.
іонатрон

2
Я оновив відповідь на прикладі симпатичного друку @yonatron
birgire
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.