Де, коли та як правильно стерти правила перезапису в межах плагіну?


10

У мене виникає дивна проблема, коли правила перезапису не спрацьовують належним чином.

Я спробував використовувати flush_rewrite_rules();і flush_rewrite_rules(true);.

Я також спробував глобалізувати $wp_rewriteвикористання $wp_rewrite->flush_rules();та$wp_rewrite->flush_rules(true);

Жодне з яких, здається, не відповідає правильності переписання правил. Ці дзвінки справді стирають правила перезапису при дзвінку. Звідки я це знаю? Використання рішення для налагодження промивання правил перезапису .

Наразі я переписав правила, що розмиваються щодо активації плагінів та дезактивації плагінів. Ніяких питань там немає.

У мене є сторінка налаштувань адміністрування плагінів, щоб користувачі могли налаштувати плагін. Деякі з налаштувань коригують структуру постійної посилання, тому правила перезапису потрібно списати на сторінці налаштувань плагіну "Зберегти настройки". (Використовує стандарт update_option();) для збереження налаштувань.

Хочу зазначити, що залежно від заданих налаштувань створюються спеціальні типи публікацій, щоб відповідати визначеним користувачем параметрам. Тож правила перезапису повинні бути стерті відразу після збереження налаштувань. Тут все не працює належним чином.

Наведене вище рішення посилань для налагодження правил перезапису, представлене програмою @toscho, показує, що вона стирає тонни правил перезапису. Однак, відвідуючи спеціальний елемент спеціального типу публікації або навіть спеціальний архів типу публікації з цього приводу, кожен повертається як 404 помилки.

Спеціальний тип публікації зареєстровано правильно та належним чином. Я точно знаю, що це не проблема.

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

Потім користувацькі типи публікацій завантажуються завжди та завантажуються initяк звичайні.

Чомусь правила перезапису не стираються належним чином, тому що, як я вже говорив раніше, відвідуючи окремі або архівні розділи спеціального типу публікації, повертаються 404 помилки.

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

Що робить ця сторінка налаштувань постійних посилань адміністрації, що я не роблю, що дозволяє переписати правила належним чином розмиватись, а мої - ні?

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

Чи є певний момент у WordPress, коли промивання правил перезапису просто більше не стирає ВСІ правила?

admin_menu - Сторінка налаштувань плагіна додається до адміністрування WordPress.

add_options_page() - Сторінка налаштувань плагіна додається в меню Налаштування.

Сторінка налаштувань відображається під час зворотного дзвінка для add_options_page(). Це також $_POSTобробляється для оновлення налаштувань плагіна та правил перезапису.

Оскільки це вже довге питання, я б готовий надати кодові блоки (якщо це допоможе) в посилання на сторонній сайт, що допоможе створити дійсну відповідь.


1
це здається, що, можливо, ви неправильно впорядкували, важко сказати, не бачачи якогось коду. на сторінку адміністратора постійних посилань просто дзвонить flush_rewrite_rules, яка просто видаляє rewrite_rulesпараметр і відновлює його, ви можете відкрити файл wp-admin/options-permalinks.phpі подивитися, де це відбувається. оскільки ця операція просто видаляє всю опцію, частково не можна очистити правила.
Міло

@Milo Я думаю, ти маєш рацію. У мене завантажений клас, на initякому реєструються типи публікацій. Я зрозумів, що налаштування сторінки зберігаються, і сторінка буде перезавантажена ... потім знову запустити initгачок, щоб зареєструвати необхідні типи публікацій. Тому я подумав, що типи публікацій уже завантажуються, і все, що мені потрібно було зробити, це оновити параметр, а потім стерти правила перезапису зі своєї сторінки налаштувань плагіна. Я опублікую відповідь про те, як я зрозумів рішення.
Майкл Еклунд

Просто попередження flush_rewrite_rules () у моєму плагіні виявилося частиною проблеми для мене. Я видалив PHP гак і закінчився лише оновленням постійних посилань вручну, і мої CPT 404 помилки зникли.
міол

Відповіді:


5

Найкраще місце для стирання правил перезапису - це активація / деактивація плагінів.

function myplugin_activate() {
    // register taxonomies/post types here
    flush_rewrite_rules();
}

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );

Дивіться статтю про кодекс

Вибачтеся заздалегідь, я не прозвучав до вашого питання, тому це трохи відповідь на вирізання файлів cookie.


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

1
Я думав, що це може бути так, але я дуже втомився, коли читав ваше запитання. Рішення ialocin виглядає багатообіцяюче, сподіваємось, ви його відпрацювали.
helgatheviking

4

Важко сказати, що не так, не бачачи свого коду. Але після збереження деяких налаштувань практично підключити, admin_initяк показано нижче, щоб очистити правила перезапису.

Код:

add_action('admin_init', 'wpse_123401_plugin_settings_flush_rewrite');
function wpse_123401_plugin_settings_flush_rewrite() {
    if ( get_option('plugin_settings_have_changed') == true ) {
        flush_rewrite_rules();
        update_option('plugin_settings_have_changed', false);
    }
}


Ви повинні встановити опцію десь на сторінці налаштувань або точну, де в процесі збереження налаштувань. Робити це без можливості погано, тому що ви не хочете щоразу стиратися з правилами.


Примітка: неперевірена


2
Або, можливо, ти можеш скористатися тимчасовим? Але, безумовно, +1 для того, щоб не змивати правила на кожному admin_init.
helgatheviking

Ви, звичайно, маєте рацію щодо перехідного періоду, я вважаю, що я вибрав це *_option()через сторінку налаштувань. @helgatheviking
Ніколай

Це було дуже корисно. У мене була схожа ситуація з Майклом. У кінцевому підсумку я включив пропозицію Helga щодо використання перехідного періоду, і я встановив його у функції перевірки параметрів. Мені потрібно було встановити перехідний процес на помилковий після змивання, інакше він просто змивався на кожному завантаженні сторінки адміністратора, поки не минув термін. Тож функціонально використання опції або перехідного періоду було однаковим. Я думаю, що перехідне може бути приємним лише для того, щоб таблиця параметрів була трохи чистішою. Але незначний момент.
MatthewLee

Різниця дійсно незначна, особливо якщо перехідні періоди постійні, не закінчуються, але, звичайно, перехідні мають інші можливості, переваги, які приємно мати. @MatthewLee
Nicolai

3

У мене був файл класу типів публікацій, який відповідав за зчитування параметрів параметрів плагіна та створення необхідних спеціальних типів публікацій на основі налаштувань, визначених користувачем.

Цей файл класу типів публікацій був завантажений на гачок init.

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

Типи публікацій ніколи не були зареєстровані, оскільки налаштування ще не були встановлені. Клас реєстрації типів повідомлень закінчувався достроково, не було зареєстровано типів повідомлень.

Рішення було:

  1. Оновіть настройки плагіна.
  2. Завантажте файл класу типів публікацій ТОЛЬКО один раз тут, щоб створити нові правила перезапису.
  3. Скиньте правила перезапису.

(Раніше ... кроку 2 не було - Як було сказано вище ...)

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

З якоїсь причини мені довелося додати виклик JavaScript для переадресації на поточну сторінку, виконавши вищевказані три кроки.

Я також повинен був додати дзвінок flush_rewrite_rules();на сторінку налаштувань адміністрування плагіна.

Тож задля того, щоб усе розмилося ...

Крок 1) Перейдіть на сторінку налаштувань адміністрування плагіна. - Початковий змив.

Крок 2) Оновіть настройки плагіна. - Другий флеш.

Крок 3) Сторінка перенаправляє на сторінку налаштувань плагіна. Викликаючи ... Третій та остаточний флеш (те саме, що і початковий флеш - Виконано автоматично під час відвідування сторінки налаштувань плагіну)

Я не кажу, що це практичне рішення, але воно працювало на мене. Дуже дивна проблема і, швидше за все, стосується моєї інфраструктури кодування.


1

@ tazo-todua це спрацювало і для мене під час використання мультисайту.

add_action( 'wpmu_new_blog', 'set_my_permalink_structure', 11, 2 );

function set_my_permalink_structure( $blog_id ) {

    switch_to_blog( $blog_id );

    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure( '/%postname%/' );
    $wp_rewrite->flush_rules();
    $wp_rewrite->init();

    restore_current_blog();
}


0

У мене були точно такі самі проблеми. У своєму плагіні у мене є типи публікацій, які динамічно створюються. Тому вони не можуть бути зареєстровані за register_post_type()допомогою статичного методу під час activation_hookі, отже, ще не активні, коли flush_rewrite_rules()виконується під час цього гака (що зазвичай є рекомендованим способом стирання правил перезапису).

Найчистішим рішенням, яке я міг придумати в кінцевому підсумку, було змивання правил перезапису після реєстрації типів публікацій, але, звичайно, лише в тому випадку, якщо таке промивання насправді необхідне (тому що робота повільна). У моєму випадку я фактично маю декілька користувацьких типів публікацій, які успадковуються від одного базового класу, і тому було бажано реалізувати код, який виконує промивання там.

Чи потрібно промивання, можна вирішити, подивившись на вихід get_option( 'rewrite_rules' ):

class MyPostTypeClass {

public final function register_as_custom_post_type() {
    ...   //do all the setup of your post type here     
    $args = array(
                  ... //populate the other arguments as you see fit
                  'rewrite' => array('slug' => 'slug-of-your-post-type')
                 );
    register_post_type('post-type-name-of-your-post-type', $args );

    $rewrite_rules_must_be_fluhed = true;
    foreach( get_option( 'rewrite_rules' ) as $key => $rule)
        if(strpos($key, $args['rewrite']['slug'] ) === 0)
        {
            $rewrite_rules_must_be_fluhed = false;
            break;
        }
    if($rewrite_rules_must_be_fluhed)
        flush_rewrite_rules(true);
}
}

Недоліки:

  • Певною мірою покладається на те, на якому точні правила перезапису створюються під час роботи WP register_post_type().
  • Перевірка необхідності промивання під час кожного завантаження сторінки також створює деякий накладний обсяг.

Переваги:

  • Повністю капсульований у класі, що представляє тип посади.
  • Промиває правила перезапису лише у разі необхідності.

Використовуйте це лише в тому випадку, якщо ви не можете зареєструвати тип своєї пошти у статичній функції, яка може дзвонити під час як initі activation_hook!

Залежність від того, як register_post_type()виглядають правила перезапису, створені під час вигляду, можна зменшити, замінивши тест if(strpos($key, $args['rewrite']['slug'] ) === 0)чимось більш детальним, тобто регулярним виразом.

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