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

AJAX Simply

Создавать AJAX запросы в WordPress не сложно, но можно еще проще... Для этого я сделал плагин AJAX Simply.

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

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

Ядро плагина состоит из двух небольших файлов .php и .js и его при необходимости можно легко встроить в любой проект без установки самого плагина (см. в конце).

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

Чтобы сразу стало ясно о чем речь, давайте представим, что мы установили AJAX Simply и создаем AJAX запрос, тогда код будет выглядеть так:

<!-- HTML -->

<form class="form">
	<input type="text" name="my_text" value="Привет, обработал!" />
	<textarea name="my_textarea">просто текст</textarea>
	<input type="submit" value="Отправить" >
</form>
// JS

jQuery('.form').submit( function(event){
	event.preventDefault(); // останавливаем отправку формы

	// AJAX запрос
	ajaxs( 'php_function', jQuery('.form') );
} );
// PHP

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

	$jx->alert( $jx->my_text );
	$jx->console( $jx->my_textarea );

}

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

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

  • в браузере alert-сообщение «Привет, обработал!»
  • в консоли браузера появится надпись «просто текст».

Т.е. ajaxs() соберет и отправит данные формы (поле my_text и my_textarea). Мы их получим в 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 кода. Такую защиту (проверку) плагин делает автоматически. Эту опцию нужно включить отдельно (см. заметки).

Этот «сухой» список показывает о скольком можно не беспокоится используя AJAX Simply, но он не может передать ощущения простоты. Чтобы хоть немного это почувствовать, смотрите примеры ниже.

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

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

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

JS функция отправки ajax

// POST запрос
ajaxs( action, data, doneFunc, alwaysFunc, failFunc );

// GET запрос
ajaxsGET( action, data, doneFunc, alwaysFunc, failFunc );

Обязательным является только параметр action.

Параметр data можно опустить:

ajaxs( action, doneFunc, alwaysFunc, failFunc );

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

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

Этими функциями можно заменить параметры: doneFunc, alwaysFunc, failFunc.

Если указать и параметры и доп. методы, то действия будут выполнены в порядке очередности: сначала параметры, затем добавленные методы.

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

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

Функция обработчик, которая будет использоваться в PHP. Вместо функции можно указать и метод класса.

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

  • 'php_function' или 'ajaxs_php_function'
    Название PHP функции, которая будет обрабатывать AJAX запрос.

    В PHP к указанному тут значению нужно добавить префикс:

    • ajaxs_ - ajaxs_php_function - для всех юзеров.
    • ajaxs_priv_ - ajaxs_priv_php_function - только для авторизованных.
  • 'Myclass::method' или 'AJAXS_Myclass::method' или 'Myclass::ajaxs_method'
    Название метода класса, который будет обрабатывать AJAX запрос. Метод должен быть статический. Использовать методы удобно для понятности кода - создали класс и добавляем в него методы.

    В PHP к указанному тут значению нужно добавить префикс:

    • AJAXS_ - AJAXS_Myclass::method - для всех юзеров.
    • AJAXS_PRIV_ - AJAXS_PRIV_Myclass::method - только для авторизованных.
    • ajaxs_ - Myclass::ajaxs_method - для всех юзеров.
    • ajaxs_priv_ - Myclass::ajaxs_priv_method - только для авторизованных.

Для понятности, префиксы: ajaxs_, ajaxs_priv_, AJAXS_, AJAXS_PRIV_ можно указать сразу в параметре action.

Также, в action можно указать скобки на конце () они в итоге будут удалены: 'php_function()', 'AJAXS_Class::method()' и т.д.

  • 'wp_ajax_{$action}'
    'wp_ajax_nopriv_{$action}'
    Стандартный хук WordPress, если функция/метод не найдены. Это обратная совместимость с привычным поведением WordPress.

    $action будет заменен на значение указанное в этом параметре. Т.е. если в action указать '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, который станет ключом.

    Пример:

    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 - это нарушит правильную работу плагина
    		//success : 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

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

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

PHP функция-обработчик в качестве единственного параметра получает объект $jx. В $jx->data содержаться все полученные от JS данные.

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

Разберем работу функции-обработчик на примере.

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

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

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

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

Теперь, получаем и обрабатываем данные в 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). JS получит эти данные в указанном виде.

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

<?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 функцию как строка.
	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( 'текст ошибки' );
}

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

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

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

Методы объекта $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->reload( $delay = 0 )
Многоразовая - перебивает данные предыдущего вызова.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

$jx->alert( $data )
Многоразовая - дополняет данные предыдущего вызова.
Тоже что console(), только получим алерт в браузере.
$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->jseval( $code )
Многоразовая - дополняет данные предыдущего вызова.

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

Пример:

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

События 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 ){} );

Все события вешаются на 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 кода не надо будет постоянно включать и выключать лоадер. Один раз прописали и забыли - очень удобно!

Настройки Ajax Simply

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

  • /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 коду:

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

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

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

# inline подключение скрипта

Плагин подключает один js файл. Он маленький и чтобы избавиться от лишнего HTTP запроса, код скрипта можно вывести прямо в HTML. Чтобы это сделать используйте хук в functions.php темы или в файле плагина:

## выводим код скрипта ajaxs прямо в HTML (inline)
add_filter( 'ajaxs_use_inline_js', '__return_true' );

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

Для фронтэнда посылать запросы на файл /wp-admin/admin-ajax.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. Иначе ничего работать не будет!

Продвинутые возможности

# URL файла обработчика AJAX запросов

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

ajaxsURL( action )

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

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

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

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

# Групповая проверка прав: хук 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 (или ничего не возвращать), чтобы плагин работал как обычно.

Примеры

#1 Возврат из PHP (echo)

Этот пример показывает, как в PHP функции обработчике мы можем просто вывести HTML на экран и JS его в результате получит...

<!-- HTML -->
<div class="contact"></div>
// JS
ajaxs( 'get_email', { email: 'foo@gmail.com' }, function( html ){
	$('.contact').html( html );
} );
<?php
function ajaxs_get_email( $jx ){
	?>
	<p class="myclass"><?php echo esc_html( $jx->email ) ?></p>
	<?php

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

#1.2 Возврат из PHP (return)

Допустим нам нужно обработать принятые данные в PHP и вернуть объект данных в JS:

<!-- HTML -->
<div class="my_form">
	<label><input type="checkbox" name="my_check" /> мой чекбокс </label>
	<select name="my_select">
		<option>Опция 1</option>
		<option>Опция 2</option>
	</select>
</div>
// JS
ajaxs( 'parse_form', $('.my_form'), function( data ){

	data.done;  //> true
	data.check; //> 'on' если чекбокс выделен
	data.sel;   //> 'Опция 1' или 'Опция 2'

} );
<?php
function ajaxs_parse_form( $jx ){
	return array(
		'check' => $jx->my_check,
		'sel'   => $jx->my_select,
		'done'  => true,
	);
}

Вернуть можно что угодно: объект/массив/число/строку/true/false. В этом примере возвращается массив.

#1.3 Возврат из PHP ($jx->done|error)

Методы $jx->done(), $jx->error() - отправляют объект и обрывают работу PHP. Это аналоги функций wp_send_json_success() и wp_send_json_error().

<!-- HTML -->
<div class="ajax-respond"></div>
// JS
ajaxs( 'my_function', function( res ){
	var $respond = jQuery('.ajax-respond');

	// УСПЕХ
	if( res.ok ){
		// сработал метод $jx->done()
		$respond.html( 'УСПЕХ:' + res.data );
	}

	// ошибка
	if( ! res.ok ) {
		// сработал метод $jx->error()
		$respond.html( 'ОШИБКА:' + res.data );
	}
} );
// PHP
// префикс 'ajaxs_priv_' означает, что функция сработает только для авторизованного в WP пользователя
function ajaxs_priv_my_function( $jx ){
	// какие-либо првоерки
	if( условие не выполняется ){
		$jx->error( 'описание ошбики' );
	}

	if( дургое условие не выполняется ){
		$jx->error( 'описание ошбики' );
	}

	$jx->done( 'Все проверки пройдены!' );

	// этот код выполнен не будет, потому что $jx->error() или $jx->done() обрывают работу PHP.
	echo 'строка которая не будет выведена';
}

#2 PHP функция-обработчик (function)

Этот пример показывает как указать какая функция PHP будет обрабатывать запрос.

// JS
ajaxs( 'my_function' );
// PHP

// вариант: префикс 'ajaxs_' - для всех юзеров
function ajaxs_my_function( $jx ){
	$jx->log( 'Сработал запрос с action = my_function' );
}

// вариант: префикс 'ajaxs_priv_' - только для авторизованных
function ajaxs_priv_my_function( $jx ){
	$jx->log( 'Сработал запрос с action = my_function' );
}

// вариант с хуком - как обычно в wordpress для обратной совместимосттю с WordPress
add_action( 'wp_ajax_my_function', 'ajax_handler_function' ); // для авторизованных
add_action( 'wp_ajax_nopriv_my_function', 'ajax_handler_function' ); // для неавторизованных
function ajax_handler_function( $jx ){
	$jx->log( 'Сработал запрос с action = my_function' );
}

Обратная совместимость в хуками WordPress дает возможность установить плагин и не переделывать уже написанный PHP код и при этом использовать функцию ajaxs() в JS. «Старый» PHP код будет работать как и до этого...

#2.2 PHP функция-обработчик (static method)

Этот пример показывает как указать статический метод класса, который будет обрабатывать запрос.

// JS
ajaxs( 'MY_Class::my_method' );
// PHP
class MY_Class {

	static function ajaxs_my_method( $jx ){
		$jx->console( 'Сработал метод: '. __METHOD__ );
	}

}

Или так

// PHP
class AJAXS_MY_Class {

	static function my_method( $jx ){
		$jx->console( 'Сработал метод: '. __METHOD__ );
	}

}

Обратите внимание на обязательные префиксы AJAXS_ у класса или ajaxs_ у метода.

Эти префиксы для понятности можно указать в вызываемой функции:

// JS
ajaxs( 'AJAXS_MY_Class::my_method' );

#3 AJAX Загрузка файлов (single)

<!-- HTML -->
<div class="form">
	<input type="file" name="file_single" />
</div>
// JS
// вариант: передача всей формы
ajaxs( 'upload_image', jQuery('.form') );

// вариант: передача file поля
ajaxs( 'upload_image', jQuery('[input name="file_single"]') );

// вариант: передача значения поля
var file = jQuery('[input name="file_single"]')[0].files[0];
ajaxs( 'upload_image', { file_single: file } );
// PHP
function ajaxs_upload_image( $jx ){
	$file = $jx->file_single;
	/* $file будет содержать:
	Array (
		[name]     => Alex-Lynn.jpg
		[type]     => image/jpeg
		[tmp_name] => /home/server/userdata/temp/phpEB56.tmp
		[error]    => 0
		[size]     => 34986
	)
	*/

	// обрабатываем полученный файл
}

#3.2 AJAX Загрузка файлов (multiple)

Передать несколько файлов можно в одном поле file или в нескольких. Рассмотрим оба варианта в примере:

<!-- HTML -->
<div class="files-upload-form">
	<p><input type="file" multiple="multiple" name="file_multiple[]" /> - множественный выбор файлов</p>

	<p><input type="file" name="file_split_multiple[]" /> - выбор одного файла</p>
	<p><input type="file" name="file_split_multiple[]" /> - выбор одного файла</p>
</div>
// JS
ajaxs( 'upload_image', jQuery('.files-upload-form') );
// PHP
function ajaxs_upload_image( $jx ){

	// обе переменные будут содержать одинаковый формат - стандарт PHP
	$jx->file_multiple;
	$jx->file_split_multiple;

	/*
	Array (
		[name] => Array (
				[0] => Alex-Lynn.jpg
				[1] => caliyan.jpg
			)

		[type] => Array (
				[0] => image/jpeg
				[1] => image/jpeg
			)

		[tmp_name] => Array (
				[0] => /home/server/userdata/temp/phpBA7C.tmp
				[1] => /home/server/userdata/temp/phpBA8D.tmp
			)

		[error] => Array (
				[0] => 0
				[1] => 0
			)

		[size] => Array (
				[0] => 34986
				[1] => 178154
			)
		[compact] => Array (
				[0] => Array (
					[name]     => Alex-Lynn.jpg
					[type]     => image/jpeg
					[tmp_name] => /home/server/userdata/temp/phpBA7C.tmp
					[error]    => 0
					[size]     => 34986
				)

				[1] => Array (
					[name]     => caliyan.jpg
					[type]     => image/jpeg
					[tmp_name] => /home/server/userdata/temp/phpBA8D.tmp
					[error]    => 0
					[size]     => 178154
				)
			)

	)
	*/

	// обрабатываем полученные файлы
}

ЗАМЕТКА: Обратите внимание на индекс compact он добавляется плагином для удобства обработки данных. С версии 1.1.9.

#3.3 AJAX Загрузка файлов (прогресс загрузки)

Этот пример показывает, как уведомлять пользователя о загрузке файла (сколько процентов файла уже загружено). Для этого используется параметр uploadProgress, в который нужно передать функцию, которая должна выводить куда-то полученный прогресс загрузки.

Для упрощения, PHP обработка запроса в примере не показана.

<!-- HTML -->
<form id="my_form">
	<input type="file" name="attached_file">

	<button type="submit">Send mail</button>
	<span class="file_upload_progress" ></span>
</form>
// JS
var data = {
	foo : jQuery('#my_form'),
	uploadProgress : function( percentComplete ){
		// выведем прогресс в HTML элемент .file_upload_progress
		jQuery('.file_upload_progress').text( percentComplete + '%' );
	}
};
ajaxs( 'upload_image', data );

#4 Использование $jx->html()

Допустим у нас есть контейнер, в который нужно вывести форму авторизации, такую форму легко получить с помощью функции wp_login_form().

<!-- HTML -->
<a class="auth_form_btn" href="#">Показать форму входа</a>
<div class="auth_form" style="display:none;"></div>
jQuery(function($){

	$('.auth_form_btn').click(function(ev){
		ev.preventDefault();

		ajaxs( 'show_auth_form' );
	});

});
function ajaxs_show_auth_form( $jx ){

	// добавим HTML в блок .auth_form
	$jx->html( '.auth_form', wp_login_form([ 'echo'=>false ]) );

	// покажем блок
	$jx->jseval( "jQuery('.auth_form').show();" );
}

Такая логика, делать что-то в JS из PHP мне не очень нравится, но иногда это очень удобно!

#5 Показ PHP ошибок

В WordPress показ ошибок для AJAX запросов полностью отключен и увидеть их можно только через лог файл. Это очень неудобно! Кто сталкивался, знает о чем я...

AJAX Simply выводит ошибки любого уровня в консоль, даже если это фатальная ошибка. Вывод ошибок работает только при включенном WP_DEBUG, поэтому не стоит беспокоится, что обычные пользователи могут увидеть ошибки или заметки, ведь на рабочем проекте WP_DEBUG отключен.

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

// JS
ajaxs( 'phpfunction' );
// PHP
function ajaxs_phpfunction( $jx ){
	// переменная, которой нет (ошибка уровня notice)
	$var['key'];

	// функция, которой нет в PHP (ошибка уровня fatal error)
	error_function_name();
}

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

Тут важно отметить, что плагин ловит ошибки с ранней стадии - с момента как подключился его главный файл. Так допустим, если есть ошибка в functions.php он её тоже поймает и выведет в консоль...

В идеале плагин лучше ставить в MU плагины, правда там не будут работать автообновления...

Встраивание плагина в проект (не плагин)

В этом случае вы не будете получать автоматических обновлений и это единственный минус...

Чтобы встроить плагин в проект вам нужно скопировать папку плагина в папку, вашего плагина, темы или в папку MU плагинов. Куда нужно, туда копируем.

Затем просто подключаем главный файл плагина: ajax-simply.php в ваш проект:

require_once 'путь_к_плагину/ajax-simply.php';

Все!

Если плагин встраивается в тему

То еще нужно открыть файл ajax-simply.php и переопределить константу AJAXS_URL. В итоге должно выглядеть так:

## для плагина или MU плагина
define( 'AJAXS_URL',  plugin_dir_url(__FILE__) );

## для темы
define( 'AJAXS_URL', strtr( AJAXS_PATH, array( wp_normalize_path(get_template_directory()) => get_template_directory_uri() ) ) );

Скачать

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

Информация

Текущая версия1.3.2
Последнее обновление2 месяца назад
Проверялся на версияхWordPress 3.0.1 - 4.9.5
Количество загрузок282

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

1.3.2

УЛУЧШЕНИЕ: неправильно подключался файл перевода для страницы настроек, когда плагин устанавливается в MU каталог (mu-plugins).

1.3.1
  • НОВОЕ: js функция ajaxsURL( action ) для удобного получения ajax URL, когда нужно отправить запрос на плагин не через встроенную фукнцию плагина ajaxs(). Например для плагина jQuery.validate(). Параметры при этом нужно передавать в POST данных.
1.3.0
  • НОВОЕ: теперь в параметре $data в $jx->done($data) или $jx->error($data) можно передать WP_Error объект, он будет обработан. $data в итоге превратиться в строку, со всеми сообщениями об ошибках, которые были в WP_Error объекте. $jx->done() при этом превратиться в $jx->error() автоматически, потому что в данных есть ошибка...
1.2.9.1
  • НОВОЕ: Добавил вывод сообщений ошибок в консоль при нерабочем nonce коде или для хука ajaxs_allow_process. А то иногда непонятно почему не срабатывает запрос...
1.2.9
  • НОВОЕ: Проверка подключенного jquery скрипта. Если jquery нет, он подключается автоматически с предупреждением об этом в консоли.
1.2.8
  • НОВОЕ: параметр 'data.largeFileError' для параметра data фукнции ajaxs(). Вместе с ним новые опции, для установки максимального размера загружаемого файла. Эти опции можно установить через фильтры: ajaxs_post_max_size и ajaxs_upload_max_filesize.
  • Поправлены мелкие баги в JS
1.2.7.1
  • БАГ: при преобразовании строк в числа.
1.2.7
  • НОВОЕ: в параметр data передавемый в AJAX собитии добавлены параметры action (текущий action указанный в ajaxs) и origin_data (неизменные данные указанные в ajaxs). Нужно это, чтобы удобно было идентифицировать ajaxs запрос при обработке JS событий и удобно пожно было получать DOM элементы если они были переданы в данных ajaxs.
1.2.6
  • НОВОЕ: для JS событий ajaxs_always и ajaxs_fail в принимаемые данные добавлен параметр jx.
  • БАГ: неправильно собирались данные для input с типом text, если в name указывался массив, пр: <input type="text" name="key[]">.
1.2.5
  • НОВОЕ: При получении значений через магические свойства, например '$jx->key', числа конвертируются из строки в число, а у строк удаляются пробелы на концах.
1.2.4
  • НОВОЕ: Если в JS (AJAX) передать переменную как булевое значение или число, то в PHP мы получаем его в виде строки: передали false > получили "false". Такое поведение иногда сильно затрудняет разработку, потому что порой непонятно почему не работает код: передали false, при получении проверям переменную в if(), но она работает, потому что там строка "false", что равно true при првоерке... Чтобы избавится от подобных проблем, теперь ajaxs конвертирует булевые значения в их реальные типы!
  • БАГ: Метод $jx->log() не полностью копировал $jx->console() - не понимал если передать сразу несколько параметров для вывода в лог.
1.2.3
  • БАГ: В файле опций были PHP комменты из-за которых в списке плагинов появляется плагин Primer...
1.2.2
  • НОВОЕ: Добавил страницу опций. Теперь можно удобно включать базовую nonce проверку, подключать скрипт inline и определять файл обработчика на фронте. Для этого всего не нужно дописывать хуки куда-то в код...
1.2.1
  • НОВОЕ: парметр 'uploadProgress' для второго параметра JS функции ajaxs(action, data). Он позволяет получить прогресс загрузки файла. В параметр нужно указать функцию, которая будет динамически получать процент загрузки файла в JS.
1.2.0
  • ИЗМЕН: теперь параметр data.ajax, передаваемый в параметрах фукнции ajaxs() удаляется на ранней стадии, чтобы не быть частью общих параметров. Это нужно для безопасности при авто-сборе значений полей формы.
1.1.9
  • НОВОЕ: Для удобаства: когда загружается несколько файлов (multiple) в массиве получаемых данных о файлах, добавлется новый индекс 'compact', куда собраны данные каздого файла в отдельный массив, как если бы не использовали multiple. Это иногда гораздо удобнее для обработки, особенно для WordPress. При этом прежняя структура массива не удаляется, а просто расширяется новым индексом 'compact'.
1.1.8
  • НОВОЕ: новый метод $jx->done() и $jx->ok() - копии $jx->success() (для удобства).
  • НОВОЕ: теперь методы $jx->success() и $jx->error() возвращают объект, в который для удобства добавлены новые параметры: error, ok.
1.1.6
  • ПРАВКА: $jx->jseval('return;') вызывало ошибку: Syntax Error: Illegal return statement.
1.1.5
  • НОВОЕ: $jx->call( $func_name, $param1, $param2, ... ) в вызываемую функцию параметры $param1, $param2, ... передаются как указано в $jx->call(). $func_name может содержать префикс window. он будет вырезан. $func_name может быть свойством вложенного в window объекта: пр. window.myObject.functionName или просто myObject.functionName.
1.1.4
  • НОВОЕ: $jx->success( $data ), $jx->error( $data ) - $data параметр стал необязательным.
1.1.3
  • НОВОЕ: метод $jx->log() = $jx->console(). Для удобства...
1.1.2
  • НОВОЕ: хук-фильтр 'ajaxs_allow_process'. Для вставки общих проверок через фильтр, перед обработкой запроса. Например, если для группы запросов нужна одна и та же проверка прав доступа, чтобы не писать каждый раз в фукнции обработчике одно и тоже, можно через этот хук добавить проверку один раз...
1.1.0
  • НОВОЕ: теперь можно еще и вызывать класс с любым именем, а префикс 'ajaxs_' или 'ajaxspriv' устанавливать для метода класса, а не для самого класса. Так иногда удобнее.
1.0
  • ИЗМЕНЕНИЕ: Для безопасности, теперь, название класса обработчика аякс запросов должно иметь префикс 'AJAXS_'. Произвольный доступ к методам класса через глобальную переменную или функцию был удален! Для этого нововведения, возможно нужно будет поправить свой PHP код! Изивините за неудобства, но это очень важный момент, который я не учел заранее!
0.950
  • НОВОЕ: Теперь, методы: $jx->console() и $jx->dump() могут принимать сразу несколько параметров. Как в JS: $jx->console( 'one', 'two', 'three', ... )
0.948
  • НОВОЕ: Переменная AJAX_Simply_Core::files стала магической.
0.947
  • НОВОЕ: Теперь, плагин ловит PHP ошибки на раннем этапе и показыавет их в консоли бразуера. Фатальные ошибки выделяются красным: console.error().
0.946
  • НОВОЕ: Теперь, если в ответе нет экстра параметров, он возвращается как есть, а не как сложный json объект... Это позволит интегрировать работу плагина со скриптами вроде jQuery.validate().
0.945
  • НОВОЕ: PHP ошибки включая фатальные теперь показываются в консоли браузера. Только если включен режим дебага - WP_DEBUG.
0.917
  • Более-менее стабильный релиз
33 коммента
Полезные 3 Все
  • Еее!)

    2
  • Отлично, берем на вооружение!)

    3
  • Bo3gyX

    Спасибо за плагин!
    Вопрос от новичка, в обработчике не работают функции типа update_post_meta, а мне нужно записать результат операции для дальнейшей обработки в php, что делать?

    • Kama6741

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

      • Bo3gyX cайт: rwsite.ru

        У меня почему-то не работает, ошибка в моем коде?
        Выложил - https://github.com/rwsite/Example-for-kama/blob/master/calc.php
        Результат должен быть записан в куку и например в мета-поле, что бы потом его можно было достать для других функций.

        • Kama6741

          Ответ по метаполю:

          global $post;
          update_post_meta( $post->ID, '_temp_field', esc_attr( $sections ) );
          setcookie( "ResultCalc", $sections ); // Передаем клиенту куку с результатом  - не рабоатет :( */   
          $sections = get_post_meta( get_the_ID(), '_temp_field', true )  ;

          Какой еще global $post;? это же AJAX запрос, там нет ни цикла ничего что принято в ВП во фронте. Тебе нужно в параметрах формы (скрытым полем) передать ID текущего поста и в обработке получить его. Т.е. вместо global $post; будет $post = get_post( $jx->post_id );. Потом уже можно юзать $post в обработчике. Можно $post глобально определить после получения, чтобы работали функции вроде get_the_ID(), хотя как правило такие функции в ajax не юзаются.

          Ответ по кукам:

          Чтобы кука правильно сохранилась, ей в AJAX запросе да и вообще, нужно указать путь, используй константу WP - COOKIEPATH:

          setcookie( 'cook_name', 'cook_value', time() + YEAR_IN_SECONDS, COOKIEPATH );

          Дело в том, что по умолчанию аякс запрос уходит на файл /wp-admin/admin-ajax.php и путь у куки по умолчанию ставится /wp-admin/, там и можно будет её получить, а ты наверное на фронте её ищешь... Ну и время жизни для куки ставь, а то она до окончания сессии только будет работать, а в ВП сессии вообще не устанавливаются...

          1
          • Bo3gyX cайт: rwsite.ru

            Спасибо за быстрый ответ, все понял, спасибо!)

  • @ Алан

    Я купил плагин, но не пойму как его подключить на фронте.
    На стороне сервера понятно, там мы устанавливаем плагин через WP, а на фронте как?
    Или весь JS код надо тоже писать в php файлах?

    Ответить4 месяца назад #
  • Привет!

    Появилась вот такая ошибка при попытке запуска функции через ajax.
    SyntaxError: Unexpected token < in JSON at position 2

    В чем может быть причина?

    Ответить4 месяца назад #
  • @ Алан

    Привет!
    При отправке формы в консоле появляется ошибка:
    Uncaught TypeError: Cannot read property 'url' of undefined
    at ajaxs (ajaxs.js?ver=1:106)

    То есть не существует свойства url на 106 строке в JS файле
    В чем может быть проблема?

    Ответить3 месяца назад #
    • Kama6741

      Тут у меня много вопросов.

      1) почему не ajaxs.min.js подключается?

      2) это только во фронте? Чтобы проверить работу плага в админке, зайди на страницу его настроек и обнови там настройки, они на базе самого этого плагина сохраняются, если пашет, то в админке все пашет. У тебя походу не подключается глобальная переменная, самая основная jxs.url. Видимо wp_localize_script() не пашет, но как такое может быть если ajaxs.js подключился, на него вешается localize. Что-то тут вообще не то... Скинь ссылку на пациента, так не знаю что может быть...

      3) попробуй в настройках плагина включить подключение скриптов inline.

      Ответить3 месяца назад #
      • @ Алан

        1) чтобы понять на какой строке ошибка.
        2) да, плагин вообще не создает скриптов и переменных на фронте(( Очень странно. Плагин активирован. Почему может не работать wp_localize_script()? Скорее всего проблема в нем.
        3) пробовал, все равно ничего не выводит.

        Ответить3 месяца назад #
        • Kama6741

          плагин вообще не создает скриптов и переменных на фронте

          А как тогда скрипт ajaxs.js срабатывает если он не подключается. Покажи кусок HTML кода где этот скрипт подключатся...

          1) В теме wp_head() wp_footer() функции подключаются?

          2) Плагины сжатия может установлены какие, типа Autoptimize?

          3) Если напрямую в HTML добавлять js, то wp_localize_script() вообще не используется... В этом случае в HTML появляется js код плагина? На этом сайте он так выглядит допустим (это inline вариант подключения):

          Ответить3 месяца назад #
          • @ Алан

            А как тогда скрипт ajaxs.js срабатывает если он не подключается. Покажи кусок HTML кода где этот скрипт подключатся...

            Я подключил его вручную, потому что после установки плагина сам он не подключается

            1) Да, подключаются.
            2) Нет
            3) Он в обоих случаях не вставляется.

            Если поймем в чем проблема, можно было бы указать это в документации для будущих пользователей.
            Может я могу тебе дать доступ в админку? Там можно в редакторе файлы темы посмотреть. Файлов пока не много, так как работу только начал, легко разобраться. Как в личку написать можно?

            Ответить3 месяца назад #
            • Kama6741

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

              Вопрос: зачем нужно отключать jQuery? Это важно? У меня есть мысль отвязать плагин от jQuery, но там повозиться придется и не уверен что в итоге так будет лучше для плагина...

              Вообще jquery очень часто нужен для разных плагинов ВП, с таким подходом ты будешь вылавливать баги работая с ВП постоянно!

              Ответить3 месяца назад #
              • Kama6741

                Посмотрел ща код плагина, он пытается подключить jQuery, если не он подключен. Но ты вообще дерегистрирровал jQuery (удалил из ВП можно сказать). В этом случае плагин уже не регистрирует jQuery и все остальное не подключается... Даже не знаю, стоит ли регистрировать его обратно из плагина, в этом случае?

                Ответить3 месяца назад #
  • привет
    пытаюсь загрузить контент поста по id через ajax и не выходит что я делаю не так?
    Почему то не работает get_post.

    js

    ajaxs('show_post', { post_id: 39 }, function( html ){
    	$('.o-proekte').html( html );
    } );

    php

    function ajaxs_show_post( $jx ){
    	$post_id = $jx->data['post_id'];
    	$post = get_post($post_id);
    	$post_content = $post->post_content;
    	$jx->html( '.o-proekte', $post_content );
     };
    
    1
    Ответитьмесяц назад #
    • Проблема была в мультисайтовости. Он рыскал в корневом сайте.
      Сделал запрос нужного сайта, а потом вытащил страницу из get_posts по слэгу. Все круто. Пока работает плагин. кайфы.

      1
      Ответитьмесяц назад #
    • Kama6741

      В JS тут function(html){} вообще можно убрать ты ведь через PHP уже указываешь что и куда нужно вставить через $jx->html(... Т.е. в JS будет просто:

      ajaxs('show_post', { post_id: 39 } );

      И в PHP коде рекомендую упрощать:

          $post_id = $jx->data['post_id'];
      	$post = get_post($post_id);
      
      // можно так
      	$post = get_post( $jx->post_id );
      1
      Ответитьмесяц назад #
  • вывожу форму через ajax при открытии модального окна с помощью вашего плагина и не подгружается grecaptcha

    пробывал grecaptcha.reset(); . не работает

    Ответитьмесяц назад #
    • Kama6741

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

      1
      Ответитьмесяц назад #
  • Функции типа _e() __() перевода не работают в php функции обработки.

    проверка is_textdomain_loaded() показала что перевод не подгружен.

    пытался в обработчике загрузить с помощью load_textdomain() но не помогло.

    Ответитьмесяц назад #
    • Kama6741

      Перевод должен быть загружен во время загрузки самого ВП... функция обработчик срабатывает в самом конце...

      В крайнем случае, можно загрузить переводы через load_textdomain() в начале функции обработчике, ты видимо что то не так указываешь в ней (путь до mo файла) поэтому не переводится...

      Ответитьмесяц назад #
      • @ Игорь

        Переводы успешно загружены в function.php и не в аякс все отлично переводится.
        Функция обработчик находится в файле php в папке plugins. Может в этом дело?

        Ответитьмесяц назад #
        • Kama6741

          Нет не в этом, функция обработчик срабатывает в самом конце. Переводы почему-то не подгружаются когда идет AJAX запрос - дело в этом. Например загрузка перевода может срабатывать с такой логикой:

          if( ! is_admin() ){
          	load_textdomain();
          }

          В таком случае во время аякс запроса переводы не будут загружаться, потому что по умолчанию аякс запрос отвечает условию is_admin()...

          Выхода тут два:

          • добавить в условие wp_doing_ajax() - ! is_admin() || wp_doing_ajax()
          • переопределить файл обработчика AJAXS для фронта (в статье есть как это делается), тогда аякс запрос на фронте не будет отвечать условию is_admin().
          Ответитьмесяц назад #
          • Такой логики нет.
            .Вот мой код загрузки перевода в function.php дочерней темы

            // Register translate
            add_action( 'after_setup_theme', 'my_child_theme_setup' );
            function my_child_theme_setup(){
            	load_child_theme_textdomain( 'Forum', get_stylesheet_directory() . '/languages' );
            }
            Ответитьмесяц назад #
            • Kama6741

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

              function my_child_theme_setup(){
              	load_child_theme_textdomain( 'Forum', get_stylesheet_directory() . '/languages' );
              
              	var_dump( is_dir(get_stylesheet_directory() . '/languages') );
              die;
              }

              Что-то у тебя там не то...

              Ответитьмесяц назад #
              • Подключил в обработчике

                load_textdomain('Forum', get_stylesheet_directory() . '/languages/'.$locale.'.mo' );
                

                Перевод пришлось загружать еще раз из-за того что у меня мультисайт.

                По той же причине в обработчике не работает get_locale(). Выводит по умолчанию "en_US" и даже switch_to_blog() не помог. Пришлось передавать локаль через data.

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

                Спасибо за участие в мучениях. Продолжаем работу.

                Ответитьмесяц назад #
                • Kama6741

                  Так в чем причина получается, мультисайт как-то влияет на локаль получается? Может у тебя для юзера локаль установлена?

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

                  Это как правило лишнее, чтобы это хоть сколько нибудь ощущалось, нужно иметь тысячи строк перевода...

                  Ответить29 дней назад #
                  • Так в чем причина получается, мультисайт как-то влияет на локаль получается? Может у тебя для юзера локаль установлена?

                    Да. Переводы не грузятся и локаль не определяется при запуске обработчика.
                    И локаль для юзера он тоже не видит.

                    Ответить26 дней назад #
                    • Kama6741

                      Хммм, странно что-то, совсем недавно работал с мультисайтом и также с ajaxs такой проблемы на наблюдал, все работало...

Здравствуйте, !     Войти . Зарегистрироваться