Мой набор сниппетов для functions.php

Набор сниппетов для functions.php

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

Пригодится каждому

Автоматическое удаление license.txt и readme.html

Наверняка вы читали, что в целях безопасности рекомендуется удалять из корневой папки сайта файлы license.txt и readme.html. Сниппет ниже выполняет это автоматически. Удобно, т. к. лично я постоянно забывал удалять их вручную. Особенно это стало актуальным, когда WordPress начал обновляться автоматически.

## Удаление файлов license.txt и readme.html для защиты
if( is_admin() && ! defined('DOING_AJAX') ){
	$license_file = ABSPATH .'/license.txt';
	$readme_file = ABSPATH .'/readme.html';

	if( file_exists($license_file) && current_user_can('manage_options') ){
		$deleted = unlink($license_file) && unlink($readme_file);

		if( ! $deleted  )
			$GLOBALS['readmedel'] = 'Не удалось удалить файлы: license.txt и readme.html из папки `'. ABSPATH .'`. Удалите их вручную!';
		else
			$GLOBALS['readmedel'] = 'Файлы: license.txt и readme.html удалены из из папки `'. ABSPATH .'`.';

		add_action( 'admin_notices', function(){  echo '<div class="error is-dismissible"><p>'. $GLOBALS['readmedel'] .'</p></div>'; } );
	}
}

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

Отключение принудительной проверки новых версий WordPress, тем и плагинов в админке.

Собственно, в комментариях в коде подробно описано, что делает этот код, поэтому дублировать не буду. Автор сниппета Kama.

/**
 * Отключаем принудительную проверку новых версий WP, плагинов и темы в админке,
 * чтобы она не тормозила, когда долго не заходил и зашел...
 * Все проверки будут происходить незаметно через крон или при заходе на страницу: "Консоль > Обновления".
 *
 * @see https://wp-kama.ru/filecode/wp-includes/update.php
 * @author Kama (https://wp-kama.ru)
 * @version 1.0
 */
if( is_admin() ){
	// отключим проверку обновлений при любом заходе в админку...
	remove_action( 'admin_init', '_maybe_update_core' );
	remove_action( 'admin_init', '_maybe_update_plugins' );
	remove_action( 'admin_init', '_maybe_update_themes' );

	// отключим проверку обновлений при заходе на специальную страницу в админке...
	remove_action( 'load-plugins.php', 'wp_update_plugins' );
	remove_action( 'load-themes.php', 'wp_update_themes' );

	// оставим принудительную проверку при заходе на страницу обновлений...
	//remove_action( 'load-update-core.php', 'wp_update_plugins' );
	//remove_action( 'load-update-core.php', 'wp_update_themes' );

	// внутренняя страница админки "Update/Install Plugin" или "Update/Install Theme" - оставим не мешает...
	//remove_action( 'load-update.php', 'wp_update_plugins' );
	//remove_action( 'load-update.php', 'wp_update_themes' );

	// событие крона не трогаем, через него будет проверяться наличие обновлений - тут все отлично!
	//remove_action( 'wp_version_check', 'wp_version_check' );
	//remove_action( 'wp_update_plugins', 'wp_update_plugins' );
	//remove_action( 'wp_update_themes', 'wp_update_themes' );

	/**
	 * отключим проверку необходимости обновить браузер в консоли - мы всегда юзаем топовые браузеры!
	 * эта проверка происходит раз в неделю...
	 * @see https://wp-kama.ru/function/wp_check_browser_version
	 */
	add_filter( 'pre_site_transient_browser_'. md5( $_SERVER['HTTP_USER_AGENT'] ), '__return_true' );
}

Добавление протокола Telegram и Viber для использования в ссылках

Как-то делали посадочную страницу и столкнулись с тем, что при добавлении ссылки с tg:// WordPress затирал протокол и ссылка на Телеграм не работала. То же самое с Вайбером и Скайпом.

Полечили, добавив в functions.php следующий код:

//Добавляем поддержку протоколов для Телеграма и Вайбера
function ss_allow_skype_protocol( $protocols ){
    $protocols[] = 'tg';
    $protocols[] = 'viber';    
    return $protocols;
}
add_filter( 'kses_allowed_protocols' , 'ss_allow_skype_protocol' );

Для Woocommerce

Оставляем пользователя на той же странице после авторизаци

Использовали в одном из проектов с онлайн обучением. Было очень неудобно, когда человека перебрасывало в личный кабинет после авторизации.

//Оставляем пользователя на той же странице после авторизаци
function woo_login_redirect( $redirect_to ) {
    if ( wp_get_referer() ) {
        $redirect_to = wp_get_referer();
    }
    return $redirect_to;
}
add_filter( 'woocommerce_login_redirect', 'woo_login_redirect' );

Продлеваем срок действия печенек

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

Правда, не сработает, если человек вернулся с другого устройства или браузера.

function ext_auth_cookie( $expiration, $user_id, $remember ){
    if( !user_can( $user_id, 'manage_options' ) ){
        $expiration = 31536000; // Тут ставим время в секундах. Здесь установлено на год.
    }
    return $expiration;
}
add_filter( 'auth_cookie_expiration','ext_auth_cookie', 10, 3 );

Принудительный перевод статуса виртуального заказа в завершенный

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

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

function virtual_order_payment_complete_order_status( $order_status, $order_id ) {
  $order = wc_get_order( $order_id );
  if ( 'processing' == $order_status &&
       ( 'on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status ) ) {
    $virtual_order = null;
    if ( count( $order->get_items() ) > 0 ) {
      foreach( $order->get_items() as $item ) {
        if ( 'line_item' == $item['type'] ) {
          $_product = $order->get_product_from_item( $item );
          if ( ! $_product->is_virtual() ) {
            // once we've found one non-virtual product we know we're done, break out of the loop
            $virtual_order = false;
            break;
          } else {
            $virtual_order = true;
          }
        }
      }
    }
    // virtual order, mark as completed
    if ( $virtual_order ) {
      return 'completed';
    }
  }
  // non-virtual order, return original status
  return $order_status;
}
add_filter( 'woocommerce_payment_complete_order_status', 'virtual_order_payment_complete_order_status', 10, 2 );

Уведомление на почту при заказе «В ожидании оплаты»

В одном из проектов пришлось применить этот сниппет. Подключили вариант оплаты в рассрочку от Тинькофф. Соответственно, деньги поступают сильно не сразу, если вообще рассрочка будет одобрена. Клиент попросил, чтобы такие заказы тоже падали на почту, чтобы пока идёт рассмотрение, подписание и перечисление денег, можно было проверить остатки и подготовить товар к отправке.

// New order notification only for "Pending" Order status
add_action( 'woocommerce_checkout_order_processed', 'pending_new_order_notification', 20, 1 );
function pending_new_order_notification( $order_id ) {
    // Get an instance of the WC_Order object
    $order = wc_get_order( $order_id );

    // Only for "pending" order status
    if( ! $order->has_status( 'pending' ) ) return;

    // Get an instance of the WC_Email_New_Order object
    $wc_email = WC()->mailer()->get_emails()['WC_Email_New_Order'];

    ## -- Customizing Heading, subject (and optionally add recipients)  -- ##
    // Change Subject
    $wc_email->settings['subject'] = __('Новый заказ #{order_number} в ожидании оплаты');
    // Change Heading
    $wc_email->settings['heading'] = __('Заказ в ожидании оплаты'); 
    // $wc_email->settings['recipient'] .= ','; // Add email recipients (coma separated)

    // Send "New Email" notification (to admin)
    $wc_email->trigger( $order_id );
}

Пока всё. Думаю, буду дополнять этот набор по мере появления новых сниппетов на вооружении. Сохраните пост в закладки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *