Як зробити плагін, необхідний у темі wp, не використовуючи умовні оператори php при виклику окремої функції з цього плагіна?


10

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

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

    if(function_exist('plugin_function')) {
             plugin_function() // do something
    }

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

Дякую

Відповіді:


7

is_plugin_active()є досить крихким: він зламається, коли або автор плагіна перейменовує головний файл, або коли користувач перейменує каталог каталогів чи головний файл. Краще перевірити, чи існує певна публічна функція.

Щоб уникнути необхідності перевірки кожного разу, коли вам потрібен якийсь функціонал плагіна, ви можете показати повідомлення в області адміністратора:

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}

Ще одна альтернатива - використовувати щось на зразок http://tgmpluginactivation.com/


Якщо автор плагіна змінює ім'я функцій, про яке ви ставите запитання function_exists, звичайний користувач просто отримає повідомлення про те, що він не встановив плагін, на який покладається інший плагін. Проблема полягає в тому , що користувач дійсно буде встановлено плагін , а потім просто цікаво , чому це doens't роботи . О, і я не збираюсь вас проти цього.
кайзер

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

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

І я підтримав вашу відповідь, тому що вона не стосувалася питання, ІМО. Або ти вважаєш за краще я прихильно відмовлятись, не пропонуючи ніяких пояснень?
scribu

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

1

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

Ще одна швидка думка: я ніколи цього не пробував, але мені цікаво, чи не могли б ви зрозуміти якийсь розумний спосіб розмістити кілька гачків за один умовний. Можливо, ви могли відокремити всі умовні функції в іншому файлі та вимагати його лише у випадку if( function_exists( 'plugin_function' ) )повернення true(з розумінням того, що це недосконала перевірка.


0

Якщо вам потрібна лише плагінова сторінка, то є is_plugin_active(). Якщо вам це потрібно зовні, краще скопіюйте / вставте основну функцію у свою тему, а потім повторно використовуйте її:

if ( ! is_admin() )
{
/**
 * Check whether the plugin is active by checking the active_plugins list.
 *
 * @since 2.5.0
 *
 * @param string $plugin Base plugin path from plugins directory.
 * @return bool True, if in the active plugins list. False, not in the list.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

Умовно дозволяє уникнути помилок при подвійному визначенні функції.


Це насправді не відповідає на питання. Це просто замінює if(function_exist('plugin_function'))зif(is_plugin_active('plugin-file.php'))
scribu

0

Примітка. Ця відповідь якраз тут, щоб полегшити обговорення між @scribu та @kaiser. Моди: Будь ласка, не видаляйте. Користувачі / читачі: Будь ласка, не голосуйте. Якщо ви хочете слідкувати за обговоренням, подивіться журнал редагування / редагування. Якщо ви хочете долучитися до дискусії, відредагуйте відповідь. Якщо обговорення має результат, то воно буде позначене як таке. Дякую.


Сценарії

Існують також різні сценарії, які відрізняються від ваги, де ви могли б мати залежність від плагіна. (Приклади лише вигадані). Слово "(батьківський) плагін" можна обміняти з "Темою" з батьківської точки зору.

  1. (жорсткий) Дочірній плагін, який лише розширює функціональність або змінює відображення (і подібні) наявного плагіна, тому не може існувати без батьківського. Приклад: BuddyPress »BuddyPress-FunkyCommentDisplay
  2. (звичайний) Плагін, який має розширену функціональність, коли активований дочірній плагін. Приклад: jQueryAttachmentCarousel »jQuerySlideDeck
  3. (м'який) Плагін, який просто додає функцію. Приклад: DisneyWonderlandTheme »MickeysSocialLinks

У наступному я намагаюся накреслити те, що відбувається, коли ви оновлюєте плагін "інший", і чек більше не працює.

  • Оголошення 1) Плагін не міг існувати без активації BuddyPress ».
  • Оголошення 2) Плагін не міг запропонувати можливість переходу з каруселі на SlideDeck »Відображає провідне (я припускаю, що стилі змінені на SlideDeck).
  • Оголошення 3) MickeysSocialLinks зникають.

Перевірити

Є три можливості, щоб протистояти, якщо ви хочете знати, чи активний плагін:

  • A. Чи існує папка?
  • B. Чи існує основний файл - опція 'active_plugins'?
  • C. Чи існує певна функція?

Якщо я зараз візьму свій Плагін Internal Link Checker , який не має публічного API і не розрахований на розширення, я б не бачив причин (як автор) не змінювати внутрішню функцію іменування на вимогу або просто за бажанням . Тож якщо хтось спробує підправити цей плагін, тоді матеріал просто розірветься (залежно від функціональності та герметичності пакета) після оновлення. Те саме стосується імен файлів. У мене не було б жодної реальної причини (окрім того, що плагін деактивується під час оновлення), щоб не змінити ім'я файлу. Єдине, що стримує мене від зміни імені папки - це те, що перевірка та повідомлення про оновлення працює назви файлу - якщо він розміщений в офіційному репо.

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

функція »папка головного файлу»


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

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

Більше думок з цього приводу:

http://wordpress.org/support/topic/plugin-plugin-dependitions-unreliable-plugin-namingidentifying-scheme


Я думаю, що ми можемо поки що підсумувати це за трьома пунктами:

  • Ми говорили про трохи інші теми
  • Ми погоджуємось, що немає бронезахисного способу обійти те, що я вважав темою
  • З розуміння цього питання ви запропонували дійсний шлях

(Поки що) найрозумніший спосіб, який я можу придумати, що я вже бачив у деяких (набагато менше) плагінах:

// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );

Не задумуючись надто детально про це, але я гадаю, ви могли підключити своє повідомлення до перевірки фільтра "всі" та перевірити всередині поточного фільтра, якщо він був запущений, коли ви знаходитесь на shutdownгачку ...?


Використання гачків було б добре для "нормальних" і "слабких" залежностей. Єдиним недоліком є ​​те, що вам все-таки потрібно використовувати function_exists()або is_plugin_active()якщо ви хочете припинити, якщо залежність не дотримана. Використання фільтра "все" для цього буде занадто дорогим ІМО.

@scibu Це було націлене на "вашу" тему. (Я вже відмовився говорити про своє). :)

Отже, якщо вам потрібна залежність - і у вас є хороший автор - тоді він може запропонувати гачок замість / як заміну тегу шаблону. Тому що плагін зачепить його лише тоді, коли гак буде присутній, або просто нічого не робити. А з іншого боку, ви б не мали помилки, якщо плагінів немає.

Ось складна частина (або більше Q): Щоб написати адміністраторське повідомлення, щоб повідомити користувача про залежність "Вам потрібно встановити" DisneyWonderLinks «", ви можете перевірити це array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Я не впевнений, чи спрацювало б це, але масив afaik повинен бути доступний для обох (public / admin) сторін.


Це б не спрацювало. Тільки тому, що зворотний виклик зареєстровано на гачок, не означає, що гак буде спрацьовувати, коли очікується. Єдине, що націлило б на роботу, це використання гачка "відключення", про який ви згадали раніше:

add_action( 'shutdown', function() {
  if ( !did_action( 'template_tag_like_hook' ) )
    echo 'Problem.';
} );

Звичайно, це буде надруковано в самому низу, після </html>тегу, на передній частині (оскільки там зазвичай використовуються теги шаблонів), що не приносить великої користі.

Ви можете спробувати зберегти повідомлення в wp_options, а потім відобразити його в області адміністрування, але це відкрило б цілком нову банку черв'яків: недійсність, кешування плагінів тощо.


Для запису, це досить неортодоксальний спосіб використання функціональності сайту. Мені це нагадує c2.com/cgi/wiki
scribu

Так. Але я не мав уявлення, як ми можемо продовжувати дискусію, не приховуючи її від пізніших читачів.
кайзер

Я не усвідомлював би, що розміщення запитання викликало б досить дискусію :) Але це дійсно цікаво, і я дякую вам як за зусилля та час, що даєте поради, так і проводите обдумані дискусії. Я думаю, що порада scribu (одна з багатьох, що це є) щодо використання класу активації TGM могла б запропонувати рішення моєї відповіді хоча б з просто практичної точки зору, я розгляну її. Однак я все ще пильную всю дискусію, оскільки інші запропоновані методи мають сенс у певних сценаріях і мені дуже цікаво читати, дякую!
unfulvio
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.