Поиск места в коде откуда была вызвана функция _doing_it_wrong()

Click here to view original web page at wp-kama.ru

К сожалению, по логам (см. Отладка в WordPress) от _doing_it_wrong() не ясно, в каком месте была сгенерирована ошибка, например:

[05-Dec-2022 15:34:53 UTC] PHP Notice:  Функция WP_Scripts::localize вызвана <strong>неправильно</strong>.
Параметр <code>$l10n</code> должен быть массивом. Для передачи произвольных данных в скрипты используйте
функцию <code>wp_add_inline_script()</code>. Дополнительную информацию можно найти на странице
<a href="https://ru.wordpress.org/support/article/debugging-in-wordpress/">«Отладка в WordPress»</a>.
(Это сообщение было добавлено в версии 5.7.0.) in F:\server\www\site.edit\wp-includes\functions.php on line 5835

Логирование (дебаг) этой ошибки на первый взгляд непростая задача, потому что по самой ошибке вообще непонятно, что её вызвало.

Чтобы найти место в коде, где появилась ошибка doing_it_wrong, можно использовать такой код:

add_filter( 'doing_it_wrong_trigger_error', 'doing_it_wrong__add_debug_backtrace' );

/**
 * Логирует ошибки от _doing_it_wrong().
 *
 * @param bool $trigger
 *
 * @return bool mixed
 */
function doing_it_wrong__add_debug_backtrace( $trigger ) {
	if ( true === $trigger ) {
		error_log(
			print_r( wp_debug_backtrace_summary( null, null, false ), true )
		);
	}

	return $trigger;
}

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

[05-Dec-2022 15:34:53 UTC] Array
(
	[0] => doing_it_wrong_trigger_error_logger
	[1] => WP_Hook->apply_filters
	[2] => apply_filters('doing_it_wrong_trigger_error')
	[3] => _doing_it_wrong
	[4] => WP_Scripts->localize
	[5] => wp_localize_script
	[6] => WPML_ST_Theme_Plugin_Localization_Resources->enqueue_scripts
	[7] => WP_Hook->apply_filters
	[8] => WP_Hook->do_action
	[9] => do_action('admin_enqueue_scripts')
	[10] => require_once('wp-admin/admin-header.php')
)

[05-Dec-2022 15:34:53 UTC] PHP Notice:  Функция WP_Scripts::localize вызвана <strong>неправильно</strong>.
Параметр <code>$l10n</code> должен быть массивом. Для передачи произвольных данных в скрипты используйте
функцию <code>wp_add_inline_script()</code>. Дополнительную информацию можно найти на странице
<a href="https://ru.wordpress.org/support/article/debugging-in-wordpress/">«Отладка в WordPress»</a>.
(Это сообщение было добавлено в версии 5.7.0.) in F:\server\www\site.edit\wp-includes\functions.php on line 5835

Сразу видно в каком классе и его методе что-то не так. С помощью не долгих поисков находим проблемный участок кода:

// ...

wp_enqueue_style(
	'wpml-theme-plugin-localization-scan',
	WPML_ST_URL . '/res/css/theme-plugin-localization/theme-plugin-localization.css',
	array(),
	WPML_ST_VERSION
);

wp_localize_script(
	'wpml-theme-plugin-localization-scan',
	'wpml_groups_to_scan',
	get_option( WPML_ST_Themes_And_Plugins_Updates::WPML_ST_ITEMS_TO_SCAN )
);

wp_enqueue_script(
	'wpml-st-tracking-all-strings-as-english-notice',
	WPML_ST_URL . '/res/js/tracking-all-strings-as-english-notice.js',
	array( 'jquery' ),
	WPML_ST_VERSION
);

// ...

Он находится в файле:

wp-content/plugins/wpml-string-translation/classes/menus/theme-plugin-localization-ui/class-wpml-st-theme-plugin-localization-resources.php

Вы можете скофигурировать wp_debug_backtrace_summary() как-то по-своему. Или можно использовать функции трассировки PHP: debug_print_backtrace() или debug_backtrace().

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

add_filter( 'doing_it_wrong_trigger_error', 'doing_it_wrong__add_debug_backtrace' );

/**
 * Логирует ошибки от _doing_it_wrong().
 *
 * @param bool $trigger
 *
 * @return bool
 */
function doing_it_wrong__add_debug_backtrace( $trigger ) {
	if ( $trigger ) {
		$excludes  = [ 'WPML_ST_Theme_Plugin_Localization_Resources->enqueue_scripts', 'some_other_function' ];
		$backtrace = wp_debug_backtrace_summary( null, null, false );
		$hide      = array_intersect( $excludes, $backtrace );

		if ( $hide ) {
			$trigger = false;
		} else {
			error_log( print_r( $backtrace, true ) );
		}
	}

	return $trigger;
}