WordPress как на ладони

AJAX Simply

Плагин для максимально простого создания AJAX запросов в WordPress.

О том, как пользоваться AJAX в WordPress я подробно описал в одноименной статье. Использование хуков для создания ajax запроса в WordPress - штука неудобная, каждый раз нужно создавать функцию и «вешать» её на хук. Также, AJAX запросы часто делаются для фронта и в этом случае нужно вешать функцию на два хука. Кроме этого нужно учитывать кучу мелочей, которые при разработке отнимают время, заставляя концентрироваться на банальных вещах.

Зачем для AJAX в WP используются хуки понятно, чтобы функции срабатывали в конце, и в них было доступно все, что есть в плагинах и темах. Но несмотря на это AJAX в WordPress можно значительно упростить и добавить удобные фишки. AJAX Simply делает именно это, в результате работа с AJAX в WordPress упрощается в разы.

Ядро плагина состоит из двух небольших файлов .php и .js.

Оглавление:

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

Давайте представим, что мы установили AJAX Simply и у нас есть форма которую нужно обработать через AJAX.

Для этого добавим атрибут onsubmit так:

<form class="my-form" onsubmit="ajaxs( 'ajaxs_php_function', this ); return false;">

	<input type="text" name="my_text" value="значение текстового поля" />
	<textarea name="my_textarea">текст в textarea</textarea>
	<input type="file" name="my_file" />

	<input type="submit" value="Отправить" >
</form>

Теперь, создадим php функцию, которая будет обрабатывать AJAX запрос:

// функция-обработчик запроса.
// ajaxs_ - это обязательный префикс.
function ajaxs_php_function( $jx ){

	// покажет алерт с текстом `значение текстового поля`
	$jx->alert( $jx->my_text );

	// выведет в консоль `текст в textarea`
	$jx->console( $jx->my_textarea );

	// выведет в консоль массив данных файла, через print_r()
	$jx->log( $jx->my_file );

	// очистим данные формы
	$jx->reset_form( '.my-form' );
}

Функцию можно вставлять куда угодно, например, в файл темы functions.php.

Готово! Теперь после нажатия на кнопку «Отправить» вы увидите:

  • в браузере alert-сообщение значение текстового поля$jx->alert().
  • в консоли браузера появится надпись текст в textarea$jx->console().
  • в консоли браузера появится данные переданного файла (в виде массива) — $jx->log.
  • данные формы будут очищены — $jx->reset_form().

Т.е. ajaxs() соберет и отправит данные формы (все поля). Мы их получим в PHP функции и можем с ними сделать что нужно, при этом из PHP «сказав», чтобы браузер вывел alert, сообщения в консоль и почистил форму.

Такой код будет работать и в админке WP и на фронт-энде.

ВАЖНО: плагин работает на основе библиотеки jQuery, поэтому не нужно её принудительно отключать в WordPress через wp_deregister_script('jquery').

Еще примеры, смотрите здесь.

Видео: пример создания AJAX формы контактов на сайте

Что конкретно упрощает плагин?

Плагин не создает что-то новое, а «оборачивает» всю работу с AJAX в свою логику и значительно её упрощает. Отправил-обработал-получил - все просто! Это значит, что в случае чего, легко можно использовать базовую логику AJAX запросов в WordPress - это привычные хуки и дополнительные переменные самого AJAX запроса.

О какой «возне» можно забыть:

  1. Забываем про хуки и указываем функцию обработчик прямо из JS файла. Можно указать и метод класса, статический или публичный.

  2. Забываем про глобальные переменные $_POST, $_GET и удобно получаем данные отправленные на сервер в едином формате, без необходимости помнить, каким методом данные были отправлены и что с данных нужно убрать экранирование.

  3. Забываем про «неудобности» при отправки данных с сервера обратно в JS: они могут быть массивами объектами, числами, строками и т.д. И все это с учетом типа данных.

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

  5. Забываем про URL запроса, который постоянно нужно передавать при создании AJAX запроса, и про то что его нужно сначала определить на фронте.

  6. Забываем про сложности при загрузке файлов через AJAX.

  7. Забываем про возню связанную с дебагом. Например, можно выдать данные в консоль браузера сразу из PHP (см. $jx->console()).

  8. Забываем про сложность с просмотром ошибок в PHP. Теперь при включенном WP_DEBUG ошибки любого уровня, включая фатальные, вы будите видеть в консоли браузера.

  9. Забываем про необходимость указать die или exit в конце PHP функции-обработчика.

  10. Забываем про защиту запросов с помощью nonce кода. Такую защиту (проверку) плагин делает автоматически. Эту опцию нужно включить отдельно (см. заметки).

  11. Код связанные с AJAX по проекту в целом будет, короче и обёрнут в структуру с документацией.

Хочу заметить, что плагин не создает никакой лишней нагрузки, как может показаться глядя на функционал. Все продумано и работает быстро! Единственное что он делает - это подключает +1 js файл 10KB (4KB в gzip).

Более того, если создать свой файл обработчик AJAX запросов для фронта, то нагрузка при запросах немного снизится (см. заметки).

Перейдем к документации AJAX Simply.

ajaxs()

В JS нужно использовать функцию ajaxs().

action - это единственный обязательный параметр.

// POST запрос
ajaxs( action );

// GET запрос
ajaxsGET( action );

// запрос с передачей параметров
ajaxs( action, data );

// Все возможные параметры
ajaxs( action, data, doneFunc, alwaysFunc, failFunc );

// Параметр data можно не указывать
ajaxs( action, doneFunc, alwaysFunc, failFunc );

Функции ajaxs() и ajaxsGET() возвращают то что возвращает jQuery.ajax(), поэтому к ним можно применять методы: .done(), .fail(), .always(), .then(). Пример:

ajaxs( 'my_function', { foo:'bar' } )
	.done( function( response ){
		// успешный ответ сервера
	} )
	.always( function( xhr, status ){
		// любой ответ сервера
	} )
	.fail( function( xhr, status, error ){
		// ошибка при ответе сервера
	} )

Если указать параметр doneFunc и метод .done(), то сначала выполнится doneFunc затем .done(). Тоже самое касается и alwaysFunc и .always(), failFunc и .fail().

Не рекомендуется использовать методы .fail(), .always(), .then()! Они выполняются после ajaxs() - это в некоторых случаях может вызвать конфликты.

Описание параметров

action(обязательный)

Название PHP функции или метода класса, который будет обрабатывать AJAX запрос.

Примеры:

ajaxs( 'ajaxs_php_function' )
ajaxs( 'AJAXS_Myclass::method' )
ajaxs( 'Myclass::ajaxs_method' )
ajaxs( '\\namespace\\AJAXS_Class::method' )
  • Префикс ajaxs_ в названии обязателен.
  • Если использовать префикс ajaxs_priv_, то функция будет срабатывать только для авторизованных пользователей.
  • Если указывается метод класса, то он должен быть статический.
  • Префикс можно писать в верхнем регистре: AJAXS_Myclass::method.

Для обратной совместимости, плагин работает на стандартных хуках WordPress:

(action) будет заменен на значение указанное в этом параметре action. Например, если в action указать ajaxs_php_function, то сработает один из хуков: wp_ajax_nopriv_php_function (для не авторизованных) или wp_ajax_php_function (для авторизованных).

data

Данные которые нужно передать вместе с AJAX запросом. Если данных нет, параметр можно пропустить. Можно указать:

  • Объект с данными.
  • HTML (DOM) элемент.
  • Объект с данными среди которых есть HTML (DOM) элемент.

Рассмотрим все варианты подробнее:

  • { key: 'val' }
    Объект с данными (ключ: значение).

    ajaxs( 'php_func', { my_key: 'my_val', num: 1 } );
  • HTML элемент (DOM элемент)
    Если передать HTML элемент, например, HTML форму, то будут собраны значения всех input, select, textarea полей из указанного элемента. У полей должен быть установлен атрибут name он станет ключом.

    Передавать можно любой элемент с полями формы, это НЕ обязательно должна быть форма <form>, может быть <div> или другой.

    Если в качестве элемента передается само поле формы, например <input>, то в данные добавится значение этого поля. У него также должен быть атрибут name, который станет ключом. В качестве альтернативы у поля вместо name может быть атрибут data-name или id и значение в атрибуте value.

    Пример:

    var element = document.getElementById('my_form');
    ajaxs( 'php_func', element );
  • jQuery элемент
    Тоже самое что передать элемент, только в виде jQuery объекта.

    var $element = jQuery('#my_form');
    ajaxs( 'php_func', $element );
  • Комбинирование - параметры и HTML элементы
    Можно передавать JS объект внутри которого будет HTML элемент(ы). Тогда в запрос будут добавлены данные объекта и данные полей из HTML элемента. При совпадении ключей, данные будут затирать друг друга в порядке очередности...

    var data = {
    	my_key : 'my_val',
    	foo    : jQuery('.my_form')
    }
    ajaxs( 'php_func', data );

    foo в данном случае нигде не используется и нужен только для целостности объекта.
    Реальные названия ключей будут взяты из атрибута name полей формы находящихся внутри элемента '.my_form'.

  • Файлы и поле файл типа: input[type="file"]
    Переданные в данных файлы будут обработаны и в PHP мы получим стандартный массив $_FILES.

    Для файлов работает все, что описано для варианта "HTML элемент". А именно:

    • Поле file может находится внутри переданного элемента (быть частью формы).

    • Поле file можно передать как отдельный элемент. Т.е. передать само поле file.

    • Можно комбинировать - передать объект данных среди которых будет HTML элемент с полем file.

    • Данные файла можно напрямую указать в объекте данных:

      var fileElement = jQuery('input[type="file"]')[0]
      var data = {
      	my_key : 'my_val',
      	myfile : fileElement.files[0] // первый файл
      }
      ajaxs( 'my_function', data );
  • Параметр data.ajax
    Позволяет указать дополнительные параметры AJAX запроса.

    Если в данных указать ключ ajax и в значении указать объект данных ключ: значение. То эти параметры станут параметрами AJAX запроса. Пример:

    data = {
    	my_key : 'my_val',       // просто значение
    	foo    : $('.my_form'),  // все поля формы my_form
    	ajax   : {
    		async      : false,
    		beforeSend : function( jqXHR, settings ){  },
    		method     : 'PUT',
    		// запрещается указывать success, error, complete - это
    		// нарушит правильную работу плагина
    		//success  : function(){}
    		//error    : function(){}
    		//complete : function(){}
    	}
    }
    ajaxs( 'my_func', data );

    Полный список параметров смотрите в описании jQuery.ajax.

  • Параметр data.uploadProgress
    С версии 1.2.1. Позволяет получить прогресс загрузки файла. В параметр нужно указать функцию, которая будет динамически получать процент загрузки файла по ходу его загрузки в браузере. Этот процент можно выводить в HTML элемент чтобы уведомить пользователя о процессе загрузки файла.

    data = {
    	foo            : $('.my_form'),  // все поля формы my_form
    	uploadProgress : function( percentComplete ){
    		$('.file_progress').text( percentComplete + '%' );
    	}
    }
    ajaxs( 'my_func', data );
  • Параметр data.largeFileError
    С версии 1.2.8. Позволяет перехватить ошибку, когда загружается файл с размером больше допустимых на сервер. Например, настройки сервера позволяют получить файл 10МБ, а загружается 11МБ. В этом случае юзер увидит alert() с ошибкой. Этот параметр позволяет перехватить это сообщение и вывести его в каком нибудь html блоке для ошибок. Пример использования:

    var data = {
    	foo : $form,
    	uploadProgress: function(persent){
    		$up_progress.text( persent + '%' );
    	},
    	largeFileError: function( curBigSize, allowedSize, filename ){
    		if( filename )
    			var msg = 'Ошибка: большой размер файла: '+ curBigSize +' (допустимо '+ allowedSize +')<br>Файл: '+ filename;
    		else
    			var msg = 'Ошибка: большой размер передаваемых данных: '+ curBigSize +' (допустимо '+ allowedSize +')';
    
    		$error_msg.html( msg ).show();
    	}
    };
    ajaxs( 'Add_Post::upload_files', data, function(res){ });

    Макс. допустимые размеры можно изменить в настройках плагина или через фильтры: ajaxs_post_max_size и ajaxs_upload_max_filesize. Фильтры должны вернуть число в байтах или в виде сокращения 500К, 10M, 1G.

doneFunc

Функция, которая сработает при успешном ответе сервера на AJAX запрос.

Получит ответ сервера: response.

В качестве параметра функция получит то, что вернет PHP функция обработчик - это может быть: число, строка, true/false, объект (простой или ассоциативный массив).

Пример:

ajaxs( 'my_function', data, function( response ){
	// для числа, строки, true/false
	response;

	// для простых массивов
	resp[0];
	resp[1];

	// для ассоциативных массивов
	resp.my_key;
	resp['my_key'];
});
alwaysFunc

Функция, которая срабатывает всегда - вернулся ответ или нет. На ней удобно снимать «лоадер» который был показан пользователю перед отправкой AJAX запроса...

Получит следующие параметры: xhr, status.

ajaxs( 'my_function', data,
	// success function
	function( result ){},
	// always function
	function( xhr, status ){},
);

Если нужно пропустить эту функцию, но определить следующую функцию: failFunc - ошибка ответа, то укажите здесь null или false.

failFunc

Функция, которая сработает, если запрос провалился. Например, когда сервер не ответил, или вернул 500 ответ, или когда вернувшиеся данные не удалось получить (вернулась не json строка) и т.д.

Получит следующие параметры: xhr, status, error.

ajaxs( 'my_function', data,
	// success function
	function( result ){},
	// always function
	null,
	// error function
	function( xhr, status, error ){
		alert( status +': '+ error );
	}
);

PHP

Функция которая обрабатывает ajax запрос должна называться:

  • ajaxs_(action)( $jx ) - для всех юзеров.
  • ajaxs_priv_(action)( $jx ) - только для авторизованных.
  • Названия функции для PHP классов смотрите выше, в описании параметра action.

PHP функция получает один параметр $jx.

В $jx->data содержаться все полученные от JS данные.

Также к данным можно обращаться напрямую $jx->my_name - это тоже самое что $jx->data['my_name']. При обращении напрямую преобразовывается тип, например строка в виде числа '5' станет числом 5. Также делаются другие полезные преобразования.

Создавать функцию можно где угодно она в результате вызывается в самом конце: после загрузки всего WP - всех плагинов, темы и инициализации всего этого. Так, например, её можно определить в файле MU плагина, в файле плагина, файле темы functions.php и где угодно еще.

Получение данных в PHP

Допустим, в JS мы отправили данные так:

var data = {
	color : 'Зеленый',
	item  : 'Яблоко',
	image : jQuery('input[name="item_image"][type="file"]')
};

ajaxs( 'my_func', data, function( response ){
	// обрабатываем ответ response
} );

Теперь, получаем и обрабатываем данные в PHP:

<?php
function ajaxs_my_function( $jx ){
	// $jx - это PHP объект

	// $_POST, $_GET содержат все данные запроса в исходном виде,
	// но они нам не нужны!
	// Все полученные от JS данные находятся в переменной (экранирование тут уже снято):
	$jx->data; //> array( color => Зеленый, item => Яблоко )

	// отдельный элемент данных
	$color = $jx->data['color']; //> Зеленый
	$item  = $jx->data['item'];  //> Яблоко

	// полученный от JS файл картинки
	$image = $_FILES['item_image']; //> массив данных файла.

	// МАГИЯ -----
	// данные можно получать напрямую:
	$jx->color;      //> Зеленый
	$jx->item;       //> Яблоко
	$jx->files;      //> массив всех файлов, тоже что и $_FILES, только с добавленным индексом 'compact'.
					 // 'compact' создан для удобства, когда передаются несколько файлов они собираются группами в compact.
					 // compact добавлен в версии 1.1.9
	$jx->item_image; //> массив данных файла
	$jx->item_image['compact']; //> массив данных файлов
								// при загрузки сразу нескольких файлов (multiple)
								// в индексе 'compact' хранится массив этих файлов в удобном формате - каждый файл
								// это отдельный массив с ключами: name, type, tmp_name, error

}

Возврат данных в PHP (ответ сервера)

PHP функция может просто вывести на экран (echo) или вернуть (return) любое значение (массив/строку/число/true/false). ajaxs() умно получит эти данные будь то число, строка, массив или объект.

В дополнении к возвращаемым данным можно использовать специальные методы. Например, метод $jx->reload(), этот метод «скажет» браузеру перезагрузить страницу.

В коде ниже показаны все возможные варианты возврата данных.

<?php
function ajaxs_my_function( $jx ){

	// МЕТОДЫ $jx объекта -----

	// в $jx есть специальные методы. Например:
	// говорит JS создать алерт
	$jx->alert( $jx->color );

	// говорит JS вывести данные в консоль
	$jx->console( $jx->item ); // коротко можно писать: $jx->log( $jx->item );

	// говорит JS (браузеру) обновить страницу через 1 секунду
	$jx->reload( 1000 );

	// ОТВЕТ СЕРВЕРА -----

	// Можно просто вернуть любое значение: массив/строку/число/true/false
	// тогда JS получит его как есть. Массивы будут получены как объекты.
	return array( 'color' => $jx->color );
	return array( 'color', $jx->color );
	return "Цвет: $jx->color"; // строка
	return 69;                 // число
	return true;               // логическое значение

	// Ответ через вывод на экран -----
	// Можно вывести строку на экран и она вернется
	// в JS функцию как строка - аналогично return.
	echo "Цвет: $jx->color";
	// или вывести строку так
	?>
	<div class="foo">Текст</div>
	<?php

	// Ответ с обрывом php скрипта -----
	// Внутри функции можно использовать: die, exit и обертки для них.
	// Если не использовать обрыв, то ajaxs сделает это сам по заверению работы функции.
	die( 'я свободная строка!' );      // не рекомендуется!
	wp_die( 'я свободная строка!' );   // рекомендуется!
	$jx->success( 'текст сообщения' ); // Аналог wp_send_json_success( 'текст сообщения' );
	$jx->error( 'текст ошибки' );      // Аналог wp_send_json_error( 'текст ошибки' );
}

Методы объекта $jx в PHP функции

Методы ниже можно использовать в PHP функции-обработчике запроса. Использование некоторых из них вы видели выше в примерах.

$jx->success( $data = null )
$jx->done( $data = null )
Одноразовая - обрывает работу PHP через die!

Отправит объект успешного выполнения и оборвет работу PHP с помощью die(). Аналог функции WP wp_send_json_success().

В результате JS получит такой объект:

{
	success : true,
	ok      : true,  // с версии 1.1.7 тоже что success
	error   : false, // с версии 1.1.7
	data    : DATA   // любые данные из PHP: строка/число/массив/true/false...
}

Важно: обрывает работу PHP и любой код после $jx->success() работать НЕ будет!

$jx->done(). С версии 1.1.7, для удобства вместо $jx->success() можно использовать $jx->done().

$jx->error( $data = null )
Одноразовая - обрывает работу PHP через die!

Отправит объект ошибки и оборвет работу PHP с помощью die(). Аналог функции WP wp_send_json_error().

В результате JS получит такой объект:

{
	success : false,
	ok      : false, // с версии 1.1.7 тоже что success
	error   : true,  // с версии 1.1.7
	data    : DATA   // любые данные из PHP: строка/число/массив/true/false...
}

Важно: обрывает работу PHP и любой код после $jx->error() работать НЕ будет!

С версии 1.3.0 в параметре $data в $jx->done($data) или $jx->error($data) можно передать WP_Error объект, он будет обработан. $data в итоге превратиться в строку, со всеми сообщениями об ошибках, которые были в WP_Error объекте. $jx->done() при этом превратиться в $jx->error() автоматически, потому что в данных есть ошибка...

$jx->refresh( $delay = 0 )
$jx->reload( $delay = 0 )
Многоразовая - перебивает данные предыдущего вызова.

«Скажет» JS перезагрузить страницу, с которой был отправлен AJAX запрос.

В $delay можно указать задержку в миллисекундах: 1000 мс = 1 сек.

$jx->redirect( $url, $delay = 0 )
Многоразовая - перебивает данные предыдущего вызова.

«Скажет» JS перейти на указанную в $url страницу. URL очищается с помощью wp_sanitize_redirect().

В $delay можно указать задержку в миллисекундах: 1000 мс = 1 сек.

$jx->console( $data )
$jx->log( $data )
Многоразовая - дополняет данные предыдущего вызова.

«Скажет» js вывести в консоль указанные данные.

В $data можно передать любые данные: строку/число/true/false/массив/объект. Массив, объект выведутся в формате print_r().

Можно указать сколько угодно параметров через запятую:

$jx->log( $data, $data2, ... );

В этом случае (с версии 1.4.0) данные в консоли будут сгруппированы (console.group()).

Заголовок группы можно задать, в первом параметре, добавьте в него строку начинающуюся с :::

$jx->log( '::Заголовок группы', $data, $data2, ... );

$jx->log() - это алиас $jx->console().

$jx->dump( $data )
Многоразовая - дополняет данные предыдущего вызова.

Тоже что console(), только указанные данные выводятся в формате var_dump().

Можно указать сколько угодно параметров через запятую: $jx->dump( $data, $data2, ... );

$jx->alert( $data )
Многоразовая - дополняет данные предыдущего вызова.
Тоже что console(), только получим алерт в браузере.
$jx->reset_form( $selector )
Многоразовая - дополняет данные предыдущего вызова.
Очищает данные формы. Форму которую нужно очистить выбирает по указанному селектору.
$jx->trigger( $event, $selector = false, $args = array() )
Многоразовая - дополняет данные предыдущего вызова.

Активирует указанное в $event JS событие на указном в $selector элементе. В $args можно передать данные, которые передадутся в функцию обрабатывающую событие.

Селектор может быть любой в стиле jQuery: jQuery('#myid').

Если селектор не указан, то событие будет активировано для документа: jQuery(document).trigger( event, vars ).

Пример. После обработки AJAX запроса, нам нужно эмулировать клик по ссылке .mylink (событие click):

function ajaxs_php_function( $jx ){
	$jx->trigger( 'click', '.mylink' );
}
$jx->call( $func_name, $param1, $param2, ... )
Многоразовая - дополняет данные предыдущего вызова.

«Говорит» JS вызвать указанную в $func_name функцию. Функция должна быть в видимости window. Например, если мы указали functionName, то будет вызвана функция window.functionName( $param1, $param2 ).

В $func_name для понятности можно указать префикс window.. Пр. window.functionName - это равносильно functionName.

$func_name может быть свойством вложенного в window объекта: пр. window.myObject.functionName - это равносильно myObject.functionName.

$jx->jscode( $code )
$jx->jseval( $code )
Многоразовая - дополняет данные предыдущего вызова.

«Просит» JS запустить указанный в $code JS код. Код должен быть оформлен по всем правилам javascript.

$jx->jseval('alert("Выполнил!");');

Алиас $jx->jscode( $code ) добавлен в версии 1.4.4

$jx->html( $selector, $html, $method )
Многоразовая - дополняет данные предыдущего вызова.

Вставит в указанный элемент указанный HTML код.

  • $selector(строка)
    Селектор по которому искать элемент в DOM дереве документа. Тут можно указать любой jQuery селектор: jQuery('селектор'), например: '#myid', '.myclass'...

  • $html(строка)
    HTML код, который будет вставлен в найденный элемент с помощью jQuery метода .html().

  • $method(строка) (с версии 1.4.3)
    Определяет каким методом нужно обработать указанный HTML. Например можно дополнить имеющийся HTML указав тут метод 'append'. Возможные значения:
    • html (по дефолту)
    • append
    • prepend
    • before
    • after
    • replace
$jx->append( $selector, $html )
$jx->prepend( $selector, $html )
$jx->before( $selector, $html )
$jx->after( $selector, $html )
$jx->replace( $selector, $html )
prepend/append - добавляет указанный HTML в начало или в конец указанного блока.
before/after - добавляет указанный HTML перед или после указанного блока.

replace - заменяет указанный блок указанным HTML кодом.

Все эти методы - это обертки метода $jx->html() с указанием третьего параметра $method. С версии 1.4.3.

$jx->remove( $selector )
Удаляет HTML элементы по указанному селектору. С версии 1.6.0.
$jx->hide( $selector )
Прячет HTML элементы выбранные по указанному селектору. Добавляется свойство display:none. С версии 1.6.0.
$jx->show( $selector )
Показывает HTML элементы выбранные по указанному селектору. Свойство display: обнуляется. С версии 1.6.0.

События AJAX Simply

Ловить моменты до или после выполнения AJAX запроса можно через события, которые срабатывают каждый раз при запуске функции ajaxs() или ajaxsGET().

// срабатывает прямо перед запросом
jQuery(document).on( 'ajaxs_start', function( event, data, jx ){} );

// после получения ответа: срабатывает всегда: при успехе или ошибке
jQuery(document).on( 'ajaxs_always', function( event, data, jx, xhr, status ){} );

// после получения ответа: успешный ответ
jQuery(document).on( 'ajaxs_done', function( event, data, jx ){} );

// после получения ответа: неожиданный ответ, ошибка ответа
jQuery(document).on( 'ajaxs_fail', function( event, data, jx, xhr, status, error ){} );

Все события срабатывают после функций success, error, complete (always), если эти функции определены как переменные ajaxs(). Например ajaxs( 'func', function(){} ).

Все эти события срабатывают до функций .done, .always, .fail, если эти функции были добавлены к объекту xhr который вернул ajaxs(). Например ajaxs().done(function(){}).

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

jQuery(document).on( 'ajaxs_done', function( event, data ){
	console.log( data );
});

Параметры:

  • event - объект (jQuery.Event) текущего js события.
  • data - параметры переданные при AJAX запросе. Если передавалась форма, то тут будут поля этой формы. Также в параметры добавляется название запроса (ключ action и исходные параметры переданные в функцию ajaxs (ключ origin_data).
  • jx - параметры самого AJAX запроса.
  • status - строка, статус ответа сервера.
  • error - сообщение об ошибке.
  • xhr - объект AJAX запроса. См. XMLHttpRequest.
Пример использования событий

Допустим у нас есть лоадер, который должен показываться при отправке любого AJAX запроса и прятаться при получении любого ответа (успешного или нет):

jQuery(document).on( 'ajaxs_start', function( event, data ){
	// показываем лоадер
});

jQuery(document).on( 'ajaxs_always', function( event, data ){
	// прячем лоадер
});

Теперь при написании js кода не надо будет постоянно включать и отключать лоадер. Один раз прописали и забыли - очень удобно!

Дополнительные возможности

PHP функция jx()

Эта функция очень удобна для дебагинга логики, которая выполняется в обработчике!

Если в функции обработчике используются другие функции и уже из них нужен доступ к текущему $jx объекту, то его можно получить через функцию jx(). Например:

function ajaxs_my_func( $jx ){
	$foo = my_func_help();
}
function my_func_help(){
	$data = array('нужные данные');

	// выведем $data в консоль
	jx()->console( $data );
}

jx() меня выручала десятки раз, очень удобно для дебага. Например, публикуем пост через ajax и что-то идет не так. Лезем, например, в код ядра WP, в функцию wp_insert_post() и там используем jx()->log( $myvar ), чтобы смотреть что находится в текущий момент в переменной $myvar.

PHP функция doing_ajaxs() - проверка что выполняется Ajax Simply запрос

Чтобы выполнять код только когда выполняется запрос Ajax Simply, используйте PHP функцию doing_ajaxs():

if( doing_ajaxs() ){
	// это запрос Ajax Simply, выведем сообщение в консоль
	jx()->log( 'Сообщение 1', 'Сообщение 2' );
}

Альтернатива атрибуту name

По умолчанию данные из формы собираются из полей с атрибутом name. Однако в некоторый случаях этот атрибут использовать неудобно. Для этого его можно заменить на id или data-name. Т.е. если в переданной форме нет input полей с attr "name", плагин будет искать input c атрибутом "id" или "data-name" в качестве имени.

Например:

<div onclick="ajaxs( 'ajaxs_my_function', this )"?>">
	<input type="text" id="param_name_1" value="value 1">
	<input type="text" id="param_name_2" value="value 2">
</div>
<div onclick="ajaxs( 'ajaxs_my_function', this )"?>">
	<input type="text" data-name="param_name_1" value="value 1">
	<input type="text" data-name="param_name_2" value="value 2">
</div>

JS функция ajaxsURL() - URL файла обработчика AJAX запросов

Можно получить JS функцией:

ajaxsURL( action )

Иногда бывает нужно использовать этот URL, например для скрипта jQuery.validate().

В параметре action нужно указать php функцию обработчик запроса: тоже что указываем в action для ajaxs().

Произвольные параметры можно добавить просто дописав их к URL:

var ajaxsurl = ajaxsURL('my_action') + '&foo=bar&love=you';

Вывод консоли в HTML документ

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

<pre id="ajaxs-console"></pre>

Теперь при ajaxs запросах все что выводится в консоль браузера также будет выводится внутри этого тега.

При каждом запросе содержимое этого тега обновляется, если нужно сохранять предыдущее содержимое, то можно добавить к тегу класс not-clear:

<pre id="ajaxs-console" class="not-clear"></pre>

Хук ajaxs_allow_process - Групповая проверка прав

Для удобства в плагине есть хук-фильтр: ajaxs_allow_process. Так он выглядит в коде:

$allow = apply_filters( 'ajaxs_allow_process', true, $action, $jx );
if( ! $allow && $allow !== null ){
	wp_die( -1, 403 );
}

Он срабатывает в начале обработки каждого AJAX запроса и позволяет прервать обработку запроса.

Хук используется для вставки общих проверок, перед обработкой запроса. Например, если для группы запросов нужна одна и та же проверка прав доступа, чтобы не писать каждый раз в функции обработчике одно и тоже, можно через этот хук добавить проверку один раз...

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

Представим, что у нас есть класс My_Class, который содержит методы обрабатывающие AJAX запросы. Таких методов там 10 штук и для всех нужна одна и та же проверка права: current_user_can('edit_others_posts'). Теперь, чтобы в начале каждого метода не писать:

if( ! current_user_can('edit_others_posts') ) return;

Перенесем эту проверку в хук, так:

// общая проверка прав доступа для всех ajax запросов
add_filter( 'ajaxs_allow_process', function( $allow, $action ){

	// обрываем, если это наш класс, и нет права
	if( false !== strpos($action, 'My_Class') && ! current_user_can('edit_others_posts') ){
		return false; // обрываем запрос
	}

}, 10, 2 );

Все, теперь при обработке любого запроса направленного на метод класса My_Class будет срабатывать проверка и если она не пройдена, то обработка AJAX запроса будет прервана.

Такой подход поможет упростить код и оградит от багов (дыр), если вдруг забудем сделать нужную проверку.

Функция хука 'ajaxs_allow_process' должна вернуть false, чтобы прервать обработку запроса или вернуть $allow, чтобы плагин работал как обычно.

Настройки Ajax Simply

Все настройки доступны на скрытой странице настроек.

Эти ссылки пригодятся, когда плагин установлен в mu-plugins или в тему:

  • /wp-admin/options.php?page=ajaxs_opt_page
  • /wp-admin/network/settings.php?page=ajaxs_opt_page (для мультисайта)

Также, зайти на эту страницу можно по ссылке со страницы плагинов (если плагин установлен как стандартный плагин):

# Защита nonce

Базовая Nonce проверка в плагине по умолчанию отключена, чтобы он нормально работал с плагинами страничного кэширования... Как включить см. ниже.

Но, вообще-то такая проверка нужна! Поэтому важные запросы проверяйте самостоятельно. Пользуйтесь хотя бы базовым nonce кодом от плагина, он отправляется при любом запросе. Чтобы его проверить при обработке запроса в PHP, используйте такой код:

## PHP функция-обработчик
function ajaxs_my_func( $jx ){
	// Проверка nonce кода
	if( ! wp_verify_nonce( $jx->ajaxs_nonce, 'ajaxs_action' ) )
		return; // обрываем

	// nonce проверка пройдена, делаем что-нужно...
}

Или с помощью функции check_ajax_referer()

## PHP функция-обработчик
function ajaxs_my_func( $jx ){
	check_ajax_referer( 'ajaxs_action', 'ajaxs_nonce' ); // обрываем

	// nonce проверка пройдена, делаем что-нужно...
}

Включаем базовую nonce проверку для всех запросов

Чтобы не проверять каждый запрос кодом выше, а просто писать код, можно включить базовую проверку для всех запросов по умолчанию и плагин будет каждый запрос проверять на соответствие его базовому nonce коду.

Сделать это можно на странице настроек плагина (см выше).

Или через хук, например, в файле темы functions.php:

## разрешим ajaxs выполнять базовую nonce проверку для всех запросов
add_filter( 'allow_ajaxs_nonce', '__return_true' );

Это хороший плюс к защите. Если вдруг забыли выставить nonce проверку, плагин сделает это за вас.

Важные запросы (удаление изменение данных), нужно защищать еще одним, своим уникальным nonce кодом!

Отключаем базовую nonce проверку для отдельного запроса (с версии 1.4.5)

Когда базовая проверка включена в настройках, есть возможно отключить её для отдельного запроса. Для этого в запросе нужно передать не пустой параметр skip_basic_nonce:

ajaxs( 'functionName', { skip_basic_nonce:1, string:'foo' }, function( res ){
	console.log( res )
} )

# Переопределение файла-обработчика на фронте

Для фронтэнда посылать запросы на файл /wp-admin/admin-ajax.php не очень продуктивно, потому что там подгружается все что нужно в админке. Ссылку на такой файл можно переопределить:

Сделать это можно на странице настроек плагина (см выше).

Или через хук, например, в файле темы functions.php:

## переопределяем файл обработчик AJAX запросов для фронта (/wp-admin/admin-ajax.php)
add_action( 'ajaxs_front_request_url', function(){
	return get_template_directory_uri() . '/front-ajaxs.php';
});

Этот код показывает как поместить такой файл в тему. Для этого в корне темы нужно создать файл front-ajaxs.php и в него поместить код файла /wp-admin/admin-ajax.php. Далее нужно удалить от туда лишние проверки, константу WP_ADMIN и хук admin_init. Т.е. выглядеть он будет так:

<?php
/**
 * WordPress AJAX handler for the front-end
 */

define( 'DOING_AJAX', true );

// Load WordPress
require_once $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php'; // IMPORTANT: set correct path!!!

// Allow for cross-domain requests (from the front end).
send_origin_headers();

// Require an action parameter
if ( empty( $_REQUEST['action'] ) )
	wp_die( '0', 400 );

@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
@header( 'X-Robots-Tag: noindex' );

send_nosniff_header();
nocache_headers();

if ( is_user_logged_in() )
	$action = 'wp_ajax_' . $_REQUEST['action'];
else
	$action = 'wp_ajax_nopriv_' . $_REQUEST['action'];

if ( ! has_action( $action ) )
	wp_die( '0', 400 );

do_action( $action );

// Default status
die( '0' );

Очень важно правильно указать путь до файла wp-load.php. Иначе ничего работать не будет!

Скачать

Плагин платный, обновляется он также как плагины WordPress - автоматически.

49 комментариев
Полезные 3 Все
    Войти