Ajax у WordPress

Мета цієї статті показати, як використовувати AJAX при створенні тем і плагінів.

Корисне на тему:

Відео уроки про AJAX в WordPress:


AJAX в адмін-панелі WordPress

З того часу, як AJAX був вбудований в адмін-панель WP, використовувати функціонал AJAX у плагінах стало дуже зручно. Невеликий приклад. Все робиться в одному файлі (файлі плагіна чи файлі теми functions.php ).

#1. Додаємо javascript

Спочатку додаємо на сторінку адмінки javascript код, який надсилатиме AJAX запит.

<?php
//add_action( 'admin_print_scripts', 'my_action_javascript'); // таке підключення працюватиме не завжди
add_action( 'admin_print_footer_scripts', 'my_action_javascript', 99);
function my_action_javascript() {
	?>
	<script>
	jQuery(document).ready( function( $ ){
		var data = {
			action: 'my_action',
			whatever: 1234
		};

		// з версії 2.8 'ajaxurl' завжди визначений в адмінці
		jQuery.post( ajaxurl, data, function( response ){
			alert( 'Отримано із сервера: ' + response );
		} );
	} );
	</script>
	<?php
}
?>

З версії 2.8 JavaScript змінна ajaxurlвизначена глобально на всіх сторінках адмінки. Використовуйте її в js коді як посилання на файл обробник AJAX запиту. Зазвичай, це файл /wp-admin/admin-ajax.php . У темі (шаблоні) ця змінна не визначена. Щоб використовувати її у фронт-енді, її потрібно визначити самостійно. Як це зробити дивіться нижче.

#2. Створюємо PHP функцію

Тепер створимо PHP функцію, яка оброблятиме переданий AJAX запит. Для цього додаємо наступний код у functions.php (можна в плагін):

add_action( 'wp_ajax_my_action', 'my_action_callback');
function my_action_callback(){
	$whatever = intval( $_POST['whatever'] );

	$whatever += 10;
	echo $whatever;

	// вихід необхідний у тому, щоб у відповіді був нічого зайвого,
	// тільки те, що повертає функція
	wp_die();
}

Тут ми чіпляємося на хук wp_ajax_my_action – це динамічний хук і він виглядає так: wp_ajax_(action) , де замість (action) вставляється значення змінної що у першому коді: action = my_action .

От і все.

Прикладу вище достатньо, щоб розпочати використання AJAX в адмін-панелі WordPress.

За можливості завжди використовуйте wp_die() замість die() або exit(), функції обробки AJAX запиту. Так ви досягнете кращої інтеграції з WordPress і у разі помилок у коді отримаєте дані про них.


AJAX на фронтенді (у темі)

Перше в чому потрібно переконатися, чи встановлена ​​на сайті бібліотека jQuery.

У фронт-енді (зовнішній частині сайту) потрібно використовувати ще один хук для обробки запитів AJAX: wp_ajax_nopriv_(action) . Цей хук на відміну від wp_ajax_(action) спрацьовує для неавторизованих користувачів.

Тобто. щоб створити обробник запиту для всіх користувачів: авторизованих і ні, PHP функцію потрібно прикріплювати відразу до двох хуків:

add_action( 'wp_ajax_(action)', 'my_action_callback');
add_action( 'wp_ajax_nopriv_(action)', 'my_action_callback');

‘wp_ajax_nopriv_(action)’ можна не вказувати, якщо не потрібно, щоб запит AJAX оброблявся для неавторизованих користувачів.

Змінна ajaxurl

Нагадаю, що змінна ajaxurlє тільки в адмінці і її немає в лицьовій частині сайту (фронт-енде), тому її потрібно визначити (створити). Але ми назвемо її по-іншому – myajax.urlдля фронту так зручніше, тому що так в об’єкт myajax можна буде додати ще дані пов’язані з AJAX запитом.

Правильний спосіб створити таку змінну – це використовувати функцію wp_localize_script() .

// Підключаємо локалізацію в самому кінці скриптів, що підключаються до висновку, щоб скрипт
// 'twentyfifteen-script', до якого ми підключаємося, точно був доданий у чергу на висновок.
// Примітка: код можна вставити у будь-яке місце functions.php теми
add_action( 'wp_enqueue_scripts', 'myajax_data', 99);
function myajax_data(){

	// Перший параметр 'twentyfifteen-script' означає, що код буде прикріплений до скрипту з ID 'twentyfifteen-script'
	// 'twentyfifteen-script' повинен бути доданий у чергу на висновок, інакше WP не зрозуміє куди вставляти код локалізації
	// Примітка: зазвичай цей код потрібно додавати у functions.php там де підключаються скрипти, після вказаного скрипту
	wp_localize_script( 'twentyfifteen-script', 'myajax',
		array(
			'url' => admin_url('admin-ajax.php')
		)
	);

}

В результаті, отримаємо в head частини сайту прямо перед скриптом ‘twentyfifteen-script’:

<script type='text/javascript'>
/* <![CDATA[ */
var myajax = {"url":"http://example.com/wp-admin/admin-ajax.php"};
/* ]]> */
</script>
<script type='text/javascript' src='http://example.com/wp-content/themes/twentyfifteen/js/functions.js?ver=20150330'></script>

На цьому теорія AJAX закінчена, тепер все як для адмін частини, тільки замість ajaxurlвказуємо myajax.urlі потрібно прикріпити функцію обробник на ще один хук wp_ajax_nopriv_(action).

Приклад AJAX коду для фронт енду

<?php

add_action( 'wp_enqueue_scripts', 'myajax_data', 99);
function myajax_data(){

	wp_localize_script( 'twentyfifteen-script', 'myajax',
		array(
			'url' => admin_url('admin-ajax.php')
		)
	);

}

add_action( 'wp_footer', 'my_action_javascript', 99); // для фронту
function my_action_javascript() {
	?>
	<script type="text/javascript" >
	jQuery(document).ready(function($) {
		var data = {
			action: 'my_action',
			whatever: 1234
		};

		// 'ajaxurl' не визначено у фронті, тому ми додали її аналог за допомогою wp_localize_script()
		jQuery.post( myajax.url, data, function(response) {
			alert('Отримано з сервера:' + response);
		});
	});
	</script>
	<?php
}

add_action( 'wp_ajax_my_action', 'my_action_callback');
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback');
function my_action_callback() {
	$whatever = intval( $_POST['whatever'] );

	echo $whatever + 10;

	// Вихід потрібен для того, щоб у відповіді не було нічого зайвого, тільки те, що повертає функція
	wp_die();
}

Код розрахований на тему twentyfifteen. Вставляти код можна у теми functions.php.

Цей код буде працювати для будь-якої теми, єдине, що для цього потрібно – це поміняти назву основного скрипта теми twentyfifteen-script, який підключається після jquery.


Логічне підключення AJAX хуків

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

Функції обробники встановлені хукам:

  • wp_ajax_(action)
  • wp_ajax_nopriv_(action)

Обидва хуки завжди задовольняють умові wp_doing_ajax() :

if( wp_doing_ajax() ){}

// До версії WP 4.7
if( defined('DOING_AJAX') ){}

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

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

Приклад того, як рекомендується підключати всі AJAX хуки.

// підключаємо AJAX обробники, тільки коли в цьому є сенс
if( wp_doing_ajax() ){
	add_action( 'wp_ajax_myaction', 'ajax_handler');
	add_action( 'wp_ajax_nopriv_myaction', 'ajax_handler');
}

// або так до WP 4.7
if( defined('DOING_AJAX') ){
	add_action( 'wp_ajax_myaction', 'ajax_handler');
	add_action( 'wp_ajax_nopriv_myaction', 'ajax_handler');
}

У цьому випадку хуки будуть підключені тільки під час AJAX запиту та не будуть підключені при простому відвідуванні фронту, адмінки, REST або CRON запиту.

Нагадаю також, що дані, що відправляються з фронтенду, на файл wp-admin/admin-ajax.php обробляються вказаною в хуку довільною функцією ajax_handler() , незалежно авторизований користувач чи ні.


Захист: використовуємо nonce та перевіряємо права

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

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

Існує два види захисту, які потрібно використовувати в AJAX запитах у більшості випадків.

1. Код nonce (випадковий код)

Nonce – це унікальний рядок, який створюється і використовується один раз – одноразове число . Nonce перевірка використовується, коли потрібно переконатись, що запит був надісланий із зазначеного «місця».

У WordPress є функції check_ajax_referer() – це базові функції для створення та подальшої перевірки nonce коду. З їх допомогою ми будемо створювати захист nonce для AJAX запитів.

Для початку створимо nonce код:

add_action( 'wp_enqueue_scripts', 'myajax_data', 99);
function myajax_data(){

	wp_localize_script( 'twentyfifteen-script', 'myajax',
		array(
			'url' => admin_url('admin-ajax.php'),
			'nonce' => wp_create_nonce('myajax-nonce')
		)
	);

}

twentyfifteen-scriptця назва основного скрипта теми (див. вище), який підключається на сайті за допомогою wp_enqueue_script() .

Потім, в AJAX запит додамо змінну з кодом nonce :

var ajaxdata = {
	action : 'myajax-submit',
	nonce_code : myajax.nonce
};
jQuery.post( myajax.url, ajaxdata, function( response ) {
	alert (response);
});

Тепер, в обробці закидання необхідно перевірити код :

add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit');
add_action( 'wp_ajax_myajax-submit', 'myajax_submit');
function myajax_submit(){
	// перевіряємо nonce код, якщо перевірка не пройдена перериваємо обробку
	check_ajax_referer( 'myajax-nonce', 'nonce_code');
	// або так
	if( ! wp_verify_nonce( $_POST['nonce_code'], 'myajax-nonce' ) ) die( 'Stop!');

	// обробляємо дані та повертаємо
	echo 'Дані, що повертаються';

	// не забуваємо завершувати PHP
	wp_die();
}

wp_verify_nonce() і є її обгорткою для AJAX запитів.

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

2. Перевірка прав доступу

Тут AJAX запити будуть спрацьовувати тільки для користувачів із правом зазначеним правом, наприклад, author . Для всіх інших, включаючи неавторизованих користувачів, запит AJAX поверне помилку.

Особливість тут у тому, що не авторизовані користувачі теж повинні бачити повідомлення про помилку при запиті AJAX. Тому для них також потрібно обробляти запит і повернути повідомлення про помилку:

add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit');
add_action( 'wp_ajax_myajax-submit', 'myajax_submit');
function myajax_submit(){
	// перевіряємо nonce код, якщо перевірка не пройдена перериваємо обробку
	check_ajax_referer( 'myajax-nonce', 'nonce_code');

	// поточний користувач не має права автора або вище
	if( ! current_user_can('publish_posts') )
		die('Этот запрос доступен пользователям с правом автора или выше.')

	// ОК. У юзера есть нужные права!

	// Делаем что нужно и выводим данные на экран, чтобы вернуть их скрипту

	// Не забываем выходить
	wp_die();
}


Включаем кэширование для AJAX запросов

По умолчанию все AJAX запросы НЕ кэшируются браузером для этого PHP устанавливает специальные заголовки функцией nocache_headers().

Чаще всего AJAX запросы кэшировать и не надо, потому что они должны возвращать свежие данные, но бывают случаи когда такое кэширование может сэкономить ресурсы и увеличить скорость работы скрипта. Например, если у нас есть сложный фильтр товаров который юзеры используют постоянно. Тут было бы разумно кэшировать все результаты фильтра например на пару часов, все равно товары не добавляются с такой скоростью…

Как включить кэширование для указанных AJAX запросов смотрите во втором примере функции nocache_headers().


Отлавливаем баги, PHP ошибки

Проблемы могут возникнуть при AJAX запросе и появлении ошибок PHP. Заметки или сообщения могут изменить возвращаемый результат или вызвать ошибку javascript.

Дебаг (вывод ошибок на экран)

Вариант:

Как правило запросы отправляются с браузера в файл. Поэтому чтобы увидеть результат запроса, ошибку или что-либо еще, можно открыть панель разработчика, выбрать именно наш запрос среди многих и посмотреть что он вернул.

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

Вариант: включаем показ ошибок в AJAX запросах

WordPress по умолчанию не показывает ошибки для AJAX запросов даже если константа WP_DEBUG включена! Видно это в коде функции wp_debug_mode().

Несмотря на это такой показ можно включить, ведь на рабочих проектах у нас все равно WP_DEBUG отключена и боятся нам нечего, а вот баги выловить это помогает на ура!

Чтобы включить показ ошибок при AJAX запроса, нужно вставить такой код в файл темы functions.php или в плагин. Но лучшее его вставить как можно раньше, чтобы видеть ранние ошибки, лучше всего в MU плагины…

if( WP_DEBUG && WP_DEBUG_DISPLAY && (defined('DOING_AJAX') && DOING_AJAX) ){
	@ ini_set( 'display_errors', 1 );
}

Вариант: вывод данных в лог файл

Если по ходу написания кода нужно заглянуть в переменную $myvar, то еще можно использовать такой код в обработчике ajax запроса:

error_log( print_r($myvar, true) );

В результате, в файл логов сервера (error.log) будет записано содержимое переменной $myvar. Так можно выполнить ajax, и заглянуть в лог.

Вариант: вывод PHP ошибок в лог файл

Чтобы выводить PHP заметки и ошибки в лог файл, нужно включить константу wp-content.

Вариант:

Если не получается увидеть сообщение об ошибке и нужно работать в режиме разработчика, можно очистить буфер сразу перед возвратом данных:

ob_clean();
echo $whatever;
die();

После этого нужно посмотреть что возвращает запрос через дебаг браузера или как-то еще…

Вариант:

Также, для дебага можно воспользоваться инструментом FirePHP, который записывает ошибки в консоль браузера.

Ошибка при возвращении данных

Если AJAX запрос на в файл wp-admin/admin-ajax.php провалился, то будет возвращен ответ -1 или 0.

  • -1 – ошибка при проверке запроса. См. функцию check_ajax_referer()
  • 0 – обработка запроса вернула пустой результат
  • 0 – также возвращается по умолчанию во всех остальных случаях.


Плагины

Плагин AJAX Simply – добавляет класс, с помощью которого можно удобно и быстро писать AJAX запросы на стороне клиента и ответы на стороне сервера.

Качественный и надежный сервис по продвижению в Телеграмме предлагает совершить недорогую покупку подписчиков в группу. На сайте Вы найдете массу выгодных предложений с индивидуальными условиями для каждого сообщества. Например, Вы можете выбрать оптимальную скорость поступления ресурса, которая доходит до 1000 единиц в сутки. Успейте сделать заказ, пока на сайте действуют оптовые скидки.

Залишити коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *