WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru Рекомендуемые продукты со скидкой от Template Monster

register_activation_hook() WP 2.0

Регистрирует функцию, которая будет срабатывать во время активации плагина.

Эта функция прикрепляет указанную callback функцию к хуку activate_(plugin) и является оберткой для этого хука.

(plugin) в хуке activate_(plugin) заменяется названием относительного пусти до главного файла плагина. Например, если плагин расположен: wp-content/plugins/sampleplugin/sample.php, то название хука будет: activate_sampleplugin/sample.php.

С версии 3.1. хук срабатывает только во время активации плагина, и не срабатывает во время автоматического обновления плагина.

Как это работает

Плагин активируется функцией activate_plugin(), в которой срабатывает хук activate_(plugin).

Функция activate_plugin() в ядре вызывается уже после загрузки среды ВП. Эта функция подключает главный файл плагина (и все что в нем указано), а затем через хук активирует указанную callback-функцию. За счет этого в нашей callback-функции доступны все функции и классы плагина. Но, так как все основные хуки WP уже сработали во время загрузки среды ВП, то никакие события плагина повешенные на хуки, например plugins_loaded, уже не сработают при подключении главного файла плагина. А значит наш плагин будет подключен, но не полностью: не так как он должен подключаться, когда уже активирован.

Так, например, если плагин делает что-либо во время события plugins_loaded, то все эти действия просто не произойдут при активации плагина. Например, если он подключает файл перевода, то файл перевода не будут подключен в момент срабатывания callback-функции указанной для register_activation_hook().

Как правило, после срабатывания callback-функции есть 2 события на которые можно повесить функции: activated_plugin и shutdown.

Чтобы сделать что-то неординарное при активации плагина, смотрите пример 5.

Правила использования

Функция не будет работать, если вызвать её в момент срабатывания какого-либо хука, например plugins_loaded, init. Функция должна вызываться напрямую из главного файла плагина. Правила активации:

  1. register_activation_hook() должен вызываться из основного файла плагина, из того где расположена директива Plugin Name: ... и не должна вызываться из какого-либо хука, вроде plugins_loaded или init.

  2. Функция хука должна быть в том же файле что и хук или подключаться заранее из другого файла.

  3. В функции хука не работает вывод на экран (echo). Потому что происходит редирект и echo вы не увидите. Но можно использовать die().

  4. Глобальные переменные (если они есть) должны быть определены явно, чтобы был доступ к ним из функции хука.

Заметка про область переменных

При активации плагина, главный файл плагина подключается не в глобальной области, а внутри функции activate_plugin(). Поэтому переменные, которые в обычном режиме работы плагина считаются глобальными, не будут глобальными.

Так, функция, которая используется в register_activation_hook() может не видеть глобальные переменные, даже если вы объявили их как глобальные внутри этой функции. Пример:

$myvar = 'что-то';

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_activate(){
	global $myvar;
	echo $myvar;   // Переменная не равна 'что-то'
}

Из-за этой особенности, глобальные переменные всегда нужно указывать явно. Все глобальные переменные должны быть определены как глобальные, даже если переменная указывается в теле плагина. Только в этом случае будет доступ к ним где угодно. Пример:

global $myvar; // указываем явно что это глобальная переменная
$myvar = 'что-то';

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_activate(){
	global $myvar;
	echo $myvar;   //> что-то
}

Хуков нет.

Возвращает

null. Ничего не возвращает.

Использование

register_activation_hook( $file, $function );
$file(строка) (обязательный)
Путь до главного php файла плагина включая название самого плагина. Обычно используется волшебная константа PHP __FILE__.
$function(строка/массив/лямбда) (обязательный)

Название функции обратного вызова. Для классов используйте массив: array( $this, 'название_функции' );.

Функция получит логическую переменную $network_wide - активируется ли плагин для всей сети сайтов, при мультисайте.

Примеры

Хорошие примеры использования активации, деактивации и удаления плагина внутри класса (ООП), смотрите в примерах register_deactivation_hook.

#1. Запуск функции при активации плагина

Предположим у нас есть функция my_plugin_activate() в основном файле плагина: wp-content/plugins/myplugin/myplugin.php, тогда для запуска этой функции во время активации плагина используйте такой код:

register_activation_hook( __FILE__, 'my_plugin_activate' );

function my_plugin_activate() {
	// Код активации ...
}

#2. Запуск метода класса

Если плагин использует PHP класс, код активации добавляется так:

register_activation_hook( __FILE__, array( 'My_Plugin', 'install' ) );

class My_Plugin {
	 static function install() {
			// Не создавайте здесь никакого вывода ...
	 }
}

#3. Запуск метода класса из отдельного файла

Если класс, который содержит функцию активации находится в отдельном файле, то регистрируйте функцию активации так:

include_once __DIR__ . '/class-My_Plugin.php';
register_activation_hook( __FILE__, array( 'My_Plugin', 'on_activate_function' ) );

#4. Запуск метода класса из самого класса

Если вы находитесь внутри __construct(). Важно, __FILE__ должен «смотреть» на главный файл плагина:

register_activation_hook( __FILE__, array( $this, 'YOUR_METHOD_NAME' ) );

#5 Делаем что-либо сразу после активации плагина

После активации плагина срабатывают только два хука: activated_plugin и shutdown.

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

Когда такое решение не подходит, можно использовать опции WP: сохранять данные в опцию и затем проверять наличие опции, и делать что-либо, если опция есть:

// Основной файл плагина.
...

function my_plugin_activate() {
  // добавляем опцию, чтобы потом если она есть сделать что-либо.
  add_option( 'Activated_Plugin', 'Plugin-Slug' );

  // Здесь код активации ...
}
register_activation_hook( __FILE__, 'my_plugin_activate' );

function load_plugin() {

	if ( is_admin() && get_option( 'Activated_Plugin' ) == 'Plugin-Slug' ) {
		// удаляем добавленную опцию, чтобы она больше не срабатывала
		// и делаем что нужно...
		delete_option( 'Activated_Plugin' );

		// Делаем что-либо единожды, после активации плагина
		// Например: add_action( 'init', 'my_init_function' );
	}
}
add_action( 'admin_init', 'load_plugin' );

Другой вариант сделать что-то во время активации плагина - это создать свое событие так:

function my_plugin_activate(){
	// Устанавливаем свой хук, чтобы к нему можно было прицепиться из файлов самого плагина
	do_action( 'my_plugin_activate' );
}
register_activation_hook( __FILE__, 'my_plugin_activate' );

#6 Еще демонстрация использования функции

Небольшой плагин, демонстрирующий как нужно использовать функцию:

/*
Plugin Name: A Test
Description: A Test
*/

require_once dirname(__FILE__) . '/my_other_file.php';

/* 
Этот код не будет работать. Хук активации должен вызываться из основного файла.
register_activation_hook ( dirname(__FILE__) . '/my_other_file.php', 'my_other_function');
*/

// Это рабочий код.
register_activation_hook( __FILE__, 'test_activated' );

/* 
Это правильный вариант объявления и доступа к глобальным переменным.
Глобальные переменные должны объявляться четко. 
Без этого у вас не будет доступа к ним.
*/
global $some_var;    
$some_var = 'hey';

// Функция активации
function test_activated(){

   // тут $some_var не будет равно hey
   global $some_var;

   // А тут $some_var будет равно hey
   // Эта функция определена в файле 'my_other_file.php'
   my_other_function();

   /* 
   Этот вариант не будет работать. 

   Если нужно записать логи во временный файл, используйте fopen/fwrite.

   Если вы хотите проверить, работает ли хук активации, 
   используйте exit() внутри функции хука.
   */
   echo 'test_activated called!';
}

Список изменений

С версии 2.0.0 Введена.

Код register activation hook: wp-includes/plugin.php WP 5.2.3

<?php
function register_activation_hook( $file, $function ) {
	$file = plugin_basename( $file );
	add_action( 'activate_' . $file, $function );
}

Cвязанные функции

Из раздела: Плагины, хуки

4 коммента
  • @ Явер

    На функцию register_activation_hook вешаю создание страниц. Вопрос в том, как локализовать заголовки?

    Ответить1.5 года назад #
    • Кажется разобрался сам:
      Подключаем файл локализации:

      add_action('plugins_loaded', 'init_plugin');
      function init_plugin() {
      	// Локализация
      	load_plugin_textdomain( 'domain', false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' );
      
      }
      Сначала переводим:
      register_activation_hook( __FILE__, 'init_plugin' );
      Теперь создаем странички:
      register_activation_hook( __FILE__, 'create_page' );

      Для создания страничек пользуем wp_insert_post.

      1
      Ответить1.5 года назад #
      • UP
        Использование wp_insert_post вызывает ошибку при активации плагина вида: "Плагин произвёл при активации 1025 символов неожиданного вывода. Если вы заметите ошибку «headers already sent», проблемы с RSS-лентами или другие неполадки, попробуйте деактивировать или удалить этот плагин."
        Помогите, пожалуйста её побороть.

        Ответить1.5 года назад #
  • goccose

    Здравствуйте. Помогите разобраться почему не работает код. Код достает данные из XML файла и импортирует их в базу данных. Если его вставить в шаблон сайта, то он работает. Но если я создаю плагин, то при активации ничего не происходит. Мне всего лишь нужно, чтобы этот код срабатывал 1 раз при активации плагина.

    /*
    Plugin Name: Import XML
    Version:     1.0
    */
    
    register_activation_hook(WP_PLUGIN_DIR.'/import-xml/import-xml.php', 'myplugin_activate');
    
    function myplugin_activate() {
    
    $xml = simplexml_load_file('price_test.xml');
    
    $args = array( 'post_type' => 'post',
    	'tax_query' => array(
    		array(
    			'taxonomy' => 'brend',
    			'field' => 'slug',
    			'terms' => array( 'test' ),
    			'operator' => 'IN',
    		)
    	), 'nopaging' => 1,
    );
    
    $my_query = new WP_Query;
    $my_posts = $my_query->query($args);
    
    foreach( $my_posts as $my_post ){
    
    $post_id = $my_post->ID; // ID поста
    $array=maybe_unserialize(get_post_meta( $post_id, '_eshop_product',true ));
    
    $i = 1; 
    
    do {
    
    $option=$array['products'][$i]['option']; // получаем название опции
    $price_1 = $array['products'][$i]['price']; // получаем цену опции
    
    $d = 1; // создаем счетчик, чтобы при совпадении артикула удалить первую цену
    
    foreach ($xml->offer as $offer) { // перебираем все артикулы XML файле
    $article = $offer->articul;  // получаем артикул из XML файла
    if ($article != ''){
    if (preg_match("/$article/", $option)) { // если совпадает артикул
     //   echo 'У поста с ID <b>' . $post_id . '</b> найдено совпадение артикула <b>' . $article . '</b> в строке <b>'. $option . '</b> цена <b>'. $offer->price . ' </b><br> ';
    	$price = $offer->price; // получаем цену из XML файла
    	if ($d == '1') { $price_1 = 0; } // если это первое совпадение удаляем старую цену
    	$price_1 = $price_1 + $price; // складываем старую цену с новой ценой
    	$d++; }}
    
    								}
    
    $array['products'][$i]['price'] = "".$price_1."";
    
    $i++;
    
    } while ($option != '');
    
    //$b=serialize($array); 
    
    update_post_meta( $post_id, '_eshop_product', $array);
    
    //echo $b;
    
    } 
    }
    
    1
    Ответить1.4 года назад #
Здравствуйте, !     Войти . Зарегистрироваться