WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

SHORTINIT константа: WordPress среда с минимальной нагрузкой

Дадим возможность улитке разгоняться

Меня волновал вопрос: как можно использовать объект $wpdb и Базу Данных сайта с которой я работаю, но чтобы при этом минимально подгружать среду WP. Иногда бывает нужно, при использовании Ajax получить или записать данные в БД и ничего больше: не нужны фильтры, не нужна проверка на авторизацию пользователя, не нужны функции WоrdPress, не нужны всякие проверки и куча подгружаемых функций. В общем, не нужно ничего кроме возможности общаться с Базой Данных привычными для WordPress методами.

Решить такую задачу можно, считав данные подключения к БД из файла wp-config.php и отдельно подключится к БД. Но это не очень удобно и потребует лишнего кода, который по сути уже есть в файлах WordPress. А то получатся очередные костыли.

С версии 3.4 разработчики WordPress позаботились об этом и добавили константу SHORTINIT в wp-settings.php:

// Останавливаем основную загрузку WordPress если нам нужна только база.
if ( SHORTINIT )
	return false;

Работает она так:

// указываем, что нам нужен минимум от WP
define('SHORTINIT', true);

// подгружаем среду WordPress
// WP делает некоторые проверки и подгружает только самое необходимое для подключения к БД
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );

// тут мы можем общаться с БД. Но практически никакие функции WP работать не будут.
// Глобальные переменные $wp, $wp_query, $wp_the_query не установлены...
global $wpdb;
$result = $wpdb->get_results("SELECT post_title FROM $wpdb->posts WHERE post_type='post'");

if( $result )
	foreach( $result as $post ){
		echo "$post->post_title <br>";
	}

Конкретные числа

Чтобы посмотреть чем отличаются инициализации с SHORTINIT и без. Я замерил: количество SQL запросов, время на выполнение кода и используемая память. Вот что получилось:

require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
// 5 SQL за 0.1 сек., память: 14.92 mb

define('SHORTINIT', true);
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
// 0 SQL за 0.02 сек., память: 2.35 mb

Таким образом SHORTINIT, грубо, по всем параметрам снижает нагрузку в 5 раз. Неплохо!

Что работает при SHORTINIT

При использовании SHORTINIT система фильтров: apply_filters() do_action() уже работает. Фильтры прописаны основные (файл: /wp-includes/default-filters.php) Те что вы указывали в functions.php вашей темы и многие другие работать не будут.

Из привычных функций: esc_attr(), is_single(), the_content(), get_permalink() и т.д. не работает ни одна. Вот все функции которые подключаются:

Авторизация при SHORTINIT

Пример проверки авторизации и получения всех прав пользователя с SHORTINIT

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

// указываем, что нам нужен минимум от WP
define('SHORTINIT', true);

// подгружаем среду WordPress
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp/wp-load.php' );

// укороченная версия wp_hash из pluggable.php
function wp_hash( $data ){
	$salt = LOGGED_IN_KEY . LOGGED_IN_SALT;
	return hash_hmac('md5', $data, $salt);
}

function hash_token( $token ){
	if( function_exists( 'hash' ) )
		return hash( 'sha256', $token );
	else
		return sha1( $token );
}

function curr_user_can($capability){
	global $all_caps;
	return isset( $all_caps[$capability] ) && $all_caps[$capability];
}

function get_curr_user_can(){
	global $wpdb;
	$_options = $wpdb->get_results("SELECT `option_name`, `option_value` FROM $wpdb->options WHERE `option_name` IN ('siteurl', '".$wpdb->prefix."user_roles')", 'OBJECT_K');
	if(!$_options)
		return array( 'error', 'Опции не найдены' );

	$_c_hash = md5( $_options['siteurl']->option_value );
	if( !isset( $_COOKIE['wordpress_logged_in_'.$_c_hash] ) )
		return array( 'error', 'Кука отсутствует' );

	$cookie          = $_COOKIE['wordpress_logged_in_'.$_c_hash];
	$cookie_elements = explode('|', $cookie);
	if( count( $cookie_elements ) !== 4 )
		return array( 'error', 'Кука битая' );

	$username   = $cookie_elements[0];
	$expiration = $cookie_elements[1];
	$token      = $cookie_elements[2];
	$hmac       = $cookie_elements[3];

	if( $expiration < time() )
		return array( 'error', 'Время сессии истекло' );

	$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE `user_login`=%s", $username) , 'OBJECT' );
	if( ! $user )
		return array( 'error', 'Нет такого юзера' );

	$pass_frag = substr($user->user_pass, 8, 4);
	$key       = wp_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token );
	$algo      = function_exists( 'hash' ) ? 'sha256' : 'sha1';
	$hash      = hash_hmac( $algo, $username . '|' . $expiration . '|' . $token, $key );
	if( ! hash_equals( $hash, $hmac ) )
		return array( 'error', 'Хэш не эквивалентен' );

	$user_options = $wpdb->get_results("SELECT `meta_key` ,`meta_value` FROM $wpdb->usermeta WHERE (`user_id`=".$user->ID.") AND (`meta_key` IN ('session_tokens', '".$wpdb->prefix."capabilities') )", OBJECT_K );
	if(!$user_options)
		return array( 'error', 'Юзер опции не установлены' );

	$sessions = unserialize($user_options['session_tokens']->meta_value);
	$verifier = hash_token( $token );
	if( !isset( $sessions[ $verifier ] ) )
		return array( 'error', 'Токен авторизации отсутствует' );

	if( $sessions[$verifier]['expiration'] < time() )
		return array( 'error', 'Время сессии истекло' );

	$role_caps = unserialize( $_options[ $wpdb->prefix.'user_roles' ]->option_value );
	$user_caps = unserialize( $user_options[ $wpdb->prefix.'capabilities' ]->meta_value );
	$all_caps  = array();
	foreach($user_caps as $key => $value){
		if( isset($role_caps[$key]) && $value )
			$all_caps = array_merge( $all_caps, $role_caps[$key]['capabilities'] );
		else
			$all_caps[$key] = $value;
	}
	return array( 'success', $all_caps );
}

Первый протестированный вариант кода

Код тестировался на WP 4.5. В ранних или поздних версиях возможно нужно будет изменить проверку...

// указываем, что нам нужен минимум от WP
define('SHORTINIT', true);

// подгружаем среду WordPress
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp/wp-load.php' );

// укороченная версия wp_hash из pluggable.php
function wp_hash($data) {
	$salt = LOGGED_IN_KEY . LOGGED_IN_SALT;
	return hash_hmac('md5', $data, $salt);
}

function hash_token( $token ) {
	if ( function_exists( 'hash' ) ) {
		return hash( 'sha256', $token );
	} else {
		return sha1( $token );
	}
}

global $wpdb;

// получаем значение siteurl и список ролей из БД, неудачно - прерываем выполнение скрипта
$_options = $wpdb->get_results("SELECT `option_name`, `option_value` FROM $wpdb->options WHERE `option_name` IN ('siteurl', '".$wpdb->prefix."user_roles')", 'OBJECT_K');
if (!$_options) exit;

// получаем md5 хеш для siteurl - он формирует ключ куки
$_c_hash = md5( $_options['siteurl']->option_value );

if ( !isset( $_COOKIE['wordpress_logged_in_'.$_c_hash] ) ) exit;

// получаем параметр, разбиваем на элементы
$cookie = $_COOKIE['wordpress_logged_in_'.$_c_hash];
$cookie_elements = explode('|', $cookie);

// кол-во элементов = 4, если нет - параметр куки поврежден, прерываем скрипт
if ( count( $cookie_elements ) !== 4 ) exit;
list( $username, $expiration, $token, $hmac ) = $cookie_elements;

// проверяем время жизни куки, если истекло - прерываем скрипт
if ( $expiration < time() ) exit; 

// получаем данные о пользователе из БД по логину, не удалось - прерываем скрипт
$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE `user_login`=%s", $username) , 'OBJECT' );
if ( ! $user ) exit;

$pass_frag = substr($user->user_pass, 8, 4);
$key = wp_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token );

$algo = function_exists( 'hash' ) ? 'sha256' : 'sha1';
$hash = hash_hmac( $algo, $username . '|' . $expiration . '|' . $token, $key );
// хеш код из куки не совпал с вычисленным - прерываем скрипт
if ( ! hash_equals( $hash, $hmac ) ) exit;

// проверяем сессию
// получаем сессии пользователя и доп. права по user ID из usermeta, не получили - прерываем скрипт
$user_options = $wpdb->get_results("SELECT `meta_key` ,`meta_value` FROM $wpdb->usermeta WHERE (`user_id`=".$user->ID.") AND (`meta_key` IN ('session_tokens', '".$wpdb->prefix."capabilities') )", OBJECT_K );
if (!$user_options) exit;

$sessions = unserialize($user_options['session_tokens']->meta_value);
$verifier = hash_token( $token );

// сессия не найдена или устарела - прерываем скрипт
if ( isset( $sessions[ $verifier ] ) ) {
	if ( $sessions[$verifier]['expiration'] < time() ) exit; 
} else exit;

// наборы прав для ролей и пользователя
$role_caps = unserialize( $_options[ $wpdb->prefix.'user_roles' ]->option_value );
$user_caps = unserialize( $user_options[ $wpdb->prefix.'capabilities' ]->meta_value );
$all_caps = array();
// формируем общий набор прав пользователя
foreach ($user_caps as $key => $value){
	//$key есть в наборе ролей - значит, это роль 
	if ( isset($role_caps[$key]) && $value ) 
		$all_caps = array_merge( $all_caps, $role_caps[$key]['capabilities'] );
	// это ключ-право пользователя
	else
		$all_caps[$key] = $value;
}

// аналог current_user_can()
function curr_user_can($capability){
	global $all_caps;
	return isset( $all_caps[$capability] ) && $all_caps[$capability];
}

// все проверки пройдены, можно выполнять запросы

// массив прав текущего пользователя
print_r( $all_caps );
26 комментов
Полезные 2 Все
  • Otshelnik-Fm203 cайт: otshelnik-fm.ru

    То-есть запросы (используя класс $wpdb) в базу будут работать, а query_posts и get_posts не работают

    1
    Ответить5.4 лет назад #
    • Kama7199

      Ага. Если это вопрос smile Ничего не работает из привычного. Чистый PHP можно сказать.

      1
      Ответить5.4 лет назад #
      • Otshelnik-Fm203 cайт: otshelnik-fm.ru

        Да, торопливый вопрос был ))

        Народ пишет, что если нужно использовать не включенную функцию - просто подключите нужный файл вордпресса. Тот который отвечает за её обработку:

        require( ABSPATH . WPINC . '/formatting.php' );
        require( ABSPATH . WPINC . '/meta.php' );
        require( ABSPATH . WPINC . '/post.php' );

        Но для этого нужно знать тонкости движка. Собственно за этим мы тут и собрались. Будем изучать

        А как загружается вордпресс указано в статье

        2
        Ответить5.4 лет назад #
  • Сергей cайт: selena-luna.ru

    Очень полезная и информативная статья.
    Спасибо.

    1
    Ответить5.3 лет назад #
  • Ната

    Kama, прям-таки обнять и расцеловать вас хочется! Огромнейшее спасибо за этот пост! Пол дня билась головой о монитор в надежде понять, как WP скрывает данные из своих баз, мило намекая, что строчка-то нужная, конечно, найдена, только вот $row все равно будет false, и никакими php-функциями из него инфу не вытянешь, если к нужному файлу (созданному для ответа на Ajax-запрос) хотя бы минимальная среда WP не подгружена. А много подгружать ну, о-очень не хотелось. Причем, этот способ избавляет и от необходимости открыто светить в подобных файлах параметры для связи с БД, что может быть очень полезно при доработке кодов от сайтов-партнеров, с которыми предполагается обмен информацией из баз данных. В итоге: а) скорость; б) конфиденциальность; в) умопромрачительная простота в реализации. Круто!

    Ответить5.3 лет назад #
  • kite

    Кул, спс!
    Поюзал. Дергал через плагин и через сторониий файл, фсе верно...терь буду использовать.
    Твой сайт - настольная книга для меня.

    1
    Ответить4.9 года назад #
  • campusboy3137 cайт: www.youtube.com/c/wpplus

    Ребята, возможно это относится к этой статье. С помощью ajax хочу обработать php файл. В виджете я вставляю:

    <script type="text/javascript">
    	$(document).ready(function() {
    		$('#addcont').load('/url/video.inc.php');
    	});
    </script>

    Файл video.inc.php

    <?php
    <iframe width="336" height="180" src="//www.youtube.com/embed/xxxxxxx" frameborder="0" allowfullscreen></iframe>
    <section style="margin-top:10px;">
    <article class="main-adventure"><?=T("SHG","EasterEvent","Пасха")?> 2015: <strong><?=T("ADN","EasterGarrunTrapper","Зверолов Гаррун")?></strong></article>
    <article class="main-adventure"><?=S("Page","Author","Автор")?>: <strong>oSettlers</strong> // <?=T("LAB","Date","Дата")?>: <strong>23.02.2015</strong></article>
    </section>
    ?>

    Проблема, что функции типа S("Page","Author","Автор") являются локализацией (мультисайт). И, естественно, мне ajax возвращает 500 ошибку. Вопрос: как мне минимально подгрузить среду WP, чтобы эти функции обработались?

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

    Дабл P.S.: В общем, подключил wp-load.php и заработало. Всем спасибо за ответы smile А если серьезно, как добавлять "модули" в таких случаях? К примеру, есть php файл, спрятанный в глубинах дерева папок на сервере, я хочу в него подгрузить только шапку сайта. Такое возможно?

    Трибл P.S.: ошибки перестали выскакивать, но всё равно функции перевода не отрабатываются как положено. В общем, проблема не решена.

    Ответить3.8 года назад #
  • Виктор

    Почему при подключении функций WordPress к стороннему php скрипту путем:

    require($_SERVER['DOCUMENT_ROOT'].'/wp-load.php');

    На странице вместо кириллических символов отображаются кракозябры?
    Как можно это исправить?

    Ответить3.3 года назад #
    • Kama7199

      Переведите php файл в кодировку utf-8

      Ответить3.3 года назад #
      • Виктор

        Добавил вначале файла:

        header( 'Content-Type: text/html; charset=utf-8' );

        Теперь все хорошо отображается.

        1
        Ответить3.3 года назад #
  • Не нашел готового кода, чтобы при SHORTINIT выполнялась авторизация по кукам, в результате слепил из кусков ядра такую конструкцию:

    Обновление: И еще одна правка, финальная - добавлена curr_user_can() вместо не загруженной current_user_can() и комментарии

    // указываем, что нам нужен минимум от WP
    define('SHORTINIT', true);
    
    // подгружаем среду WordPress
    require_once( $_SERVER['DOCUMENT_ROOT'] . '/jr/wp-load.php' );
    
    // укороченная версия wp_hash из pluggable.php
    function wp_hash($data) {
    	$salt = LOGGED_IN_KEY . LOGGED_IN_SALT;
    	return hash_hmac('md5', $data, $salt);
    }
    
    function hash_token( $token ) {
    	if ( function_exists( 'hash' ) ) {
    		return hash( 'sha256', $token );
    	} else {
    		return sha1( $token );
    	}
    }
    
    global $wpdb;
    
    // получаем значение siteurl и список ролей из БД, неудачно - прерываем выполнение скрипта
    $_options = $wpdb->get_results("SELECT `option_name`, `option_value` FROM $wpdb->options WHERE `option_name` IN ('siteurl', '".$wpdb->prefix."user_roles')", 'OBJECT_K');
    if (!$_options) exit;
    
    // получаем md5 хеш для siteurl - он формирует ключ куки
    $_c_hash = md5( $_options['siteurl']->option_value );
    
    if ( !isset( $_COOKIE['wordpress_logged_in_'.$_c_hash] ) ) exit;
    
    // получаем параметр, разбиваем на элементы
    $cookie = $_COOKIE['wordpress_logged_in_'.$_c_hash];
    $cookie_elements = explode('|', $cookie);
    
    // кол-во элементов = 4, если нет - параметр куки поврежден, прерываем скрипт
    if ( count( $cookie_elements ) !== 4 ) exit;
    list( $username, $expiration, $token, $hmac ) = $cookie_elements;
    
    // проверяем время жизни куки, если истекло - прерываем скрипт
    if ( $expiration < time() ) exit; 
    
    // получаем данные о пользователе из БД по логину, не удалось - прерываем скрипт
    $user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE `user_login`=%s", $username) , 'OBJECT' );
    if ( ! $user ) exit;
    
    $pass_frag = substr($user->user_pass, 8, 4);
    $key = wp_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token );
    
    $algo = function_exists( 'hash' ) ? 'sha256' : 'sha1';
    $hash = hash_hmac( $algo, $username . '|' . $expiration . '|' . $token, $key );
    // хеш код из куки не совпал с вычисленным - прерываем скрипт
    if ( ! hash_equals( $hash, $hmac ) ) exit;
    
    // проверяем сессию
    // получаем сессии пользователя и доп. права по user ID из usermeta, не получили - прерываем скрипт
    $user_options = $wpdb->get_results("SELECT `meta_key` ,`meta_value` FROM $wpdb->usermeta WHERE (`user_id`=".$user->ID.") AND (`meta_key` IN ('session_tokens', '".$wpdb->prefix."capabilities') )", 'OBJECT_K');
    if (!$user_options) exit;
    
    $sessions = unserialize($user_options['session_tokens']->meta_value);
    $verifier = hash_token( $token );
    
    // сессия не найдена или устарела - прерываем скрипт
    if ( isset( $sessions[ $verifier ] ) ) {
    	if ( $sessions[$verifier]['expiration'] < time() ) exit; 
    } else exit;
    
    // наборы прав для ролей и пользователя
    $role_caps = unserialize( $_options[ $wpdb->prefix.'user_roles' ]->option_value );
    $user_caps = unserialize( $user_options[ $wpdb->prefix.'capabilities' ]->meta_value );
    $all_caps = array();
    // формируем общий набор прав пользователя
    foreach ($user_caps as $key => $value){
    	// это название роли, добавляем ее набор прав в общий набор
    	if ( isset($role_caps[$key]) && $value ) 
    		$all_caps = array_merge( $all_caps, $role_caps[$key]['capabilities'] );
    	// это отдельный ключ-право пользователя. Если активен - добавляем в общий набор
    	else if ($value)
    		$all_caps = array_merge( $all_caps, array($key => $value) );
    }
    
    // аналог current_user_can()
    function curr_user_can($capability){
    	global $all_caps;
    	return isset( $all_caps[$capability] ) && $all_caps[$capability];
    }
    
    // все проверки пройдены, можно выполнять запросы
    
    if ( !curr_user_can('delete_users') )
    	echo ('Нет прав на удаление пользователей');

    Может, кому нибудь пригодится.

    3
    Ответить2.5 года назад #
    • Kama7199

      Спасибо за код, действительно может пригодиться кому-то! thank_you

      1
      Ответить2.5 года назад #
    • Внесу поправку: функцию

      function hash_equals($a, $b)

      определенную в начале, необходимо удалить, т.к. она уже определена в /wp-includes/compat.php, а он при SHORTINIT подключается.

      1
      Ответить2.5 года назад #
    • И еще одна правка, финальная - добавлена curr_user_can() вместо не загруженной current_user_can() и комментарии

      // код перенесен в первый комментарий...

      Думаю, предыдущие версии можно удалить / обновить

      1
      Ответить2.5 года назад #
      • Kama7199

        Вот этот вариант еще интереснее! Если все работает как я вижу по коду - то это действительно полезный код.

        Но, там проблема может быть с разными версиями WP, там принципы авторизации разные. Как текущая рабочая версия и скелет для подобных операций - ваш код - просто находка!

        Ответить2.5 года назад #
      • Kama7199

        Тестанул код - все работает как и ожидалось - круто! Добавил его в статью. К сожалению нет никакой ссылки на твой профиль где-нибудь, чтобы указать авторство.

        Ответить2.5 года назад #
        • С проверкой авторизации проблем за месяц не возникало, а вот с правами практически сразу обнаружились:

          foreach ($user_caps as $key => $value){
          	// это название роли, добавляем ее набор прав в общий набор
          	// мне не ясно, для чего $user_capsp['id_роли'] = true/false. Роль можно отключать?
          	// если в WP допускается использ. нескольких ролей, то право с      
          	//$value=false нельзя замещать, а в данном коде "кто последний тот и прав"
          	if ( isset($role_caps[$key]) && $value ) 
          		$all_caps = array_merge( $all_caps, $role_caps[$key]['capabilities'] );
          	// это отдельный ключ-право пользователя
          	// если это ключ-право = false, он должен отключить одноименн. возможность роли, а он будет отброшен
          	else if ($value)
          		// тут можно упростить
          		$all_caps = array_merge( $all_caps, array($key => $value) );
          }

          Сейчас у меня работает вариант

          foreach ($user_caps as $key => $value){
          	//$key есть в наборе ролей - значит, это роль 
          	if ( isset($role_caps[$key]) && $value ) 
          		$all_caps = array_merge( $all_caps, $role_caps[$key]['capabilities'] );
          	// это ключ-право пользователя
          	else
          		$all_caps[$key] = $value;
          }
          4
          Ответить2.5 года назад #
          • Kama7199

            Спасибо, обновил эту часть в коде, в статье.

            Ответить2.5 года назад #
            • Михаил cайт: mehanoid.pro
              function wp_hash($data){
              	$salt = LOGGED_IN_KEY . LOGGED_IN_SALT;
              	return hash_hmac('md5', $data, $salt);
              }
              
              function hash_token( $token ){
              	if( function_exists( 'hash' ) )
              		return hash( 'sha256', $token );
              	else
              		return sha1( $token );
              }
              
              function curr_user_can($capability){
              	global $all_caps;
              	return isset( $all_caps[$capability] ) && $all_caps[$capability];
              }
              
              function get_curr_user_can(){
              	global $wpdb;
              	$_options = $wpdb->get_results("SELECT `option_name`, `option_value` FROM $wpdb->options WHERE `option_name` IN ('siteurl', '".$wpdb->prefix."user_roles')", 'OBJECT_K');
              	if(!$_options)
              		return array( 'error', 'Опции не найдены' );
              
              	$_c_hash = md5( $_options['siteurl']->option_value );
              	if( !isset( $_COOKIE['wordpress_logged_in_'.$_c_hash] ) )
              		return array( 'error', 'Кука отсутствует' );
              
              	$cookie          = $_COOKIE['wordpress_logged_in_'.$_c_hash];
              	$cookie_elements = explode('|', $cookie);
              	if( count( $cookie_elements ) !== 4 )
              		return array( 'error', 'Кука битая' );
              
              	$username   = $cookie_elements[0];
              	$expiration = $cookie_elements[1];
              	$token      = $cookie_elements[2];
              	$hmac       = $cookie_elements[3];
              
              	if( $expiration < time() )
              		return array( 'error', 'Время сессии истекло' );
              
              	$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE `user_login`=%s", $username) , 'OBJECT' );
              	if( ! $user )
              		return array( 'error', 'Нет такого юзера' );
              
              	$pass_frag = substr($user->user_pass, 8, 4);
              	$key       = wp_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token );
              	$algo      = function_exists( 'hash' ) ? 'sha256' : 'sha1';
              	$hash      = hash_hmac( $algo, $username . '|' . $expiration . '|' . $token, $key );
              	if( ! hash_equals( $hash, $hmac ) )
              		return array( 'error', 'Хэш не эквивалентен' );
              
              	$user_options = $wpdb->get_results("SELECT `meta_key` ,`meta_value` FROM $wpdb->usermeta WHERE (`user_id`=".$user->ID.") AND (`meta_key` IN ('session_tokens', '".$wpdb->prefix."capabilities') )", OBJECT_K );
              	if(!$user_options)
              		return array( 'error', 'Юзер опции не установлены' );
              
              	$sessions = unserialize($user_options['session_tokens']->meta_value);
              	$verifier = hash_token( $token );
              	if( !isset( $sessions[ $verifier ] ) )
              		return array( 'error', 'Токен авторизации отсутствует' );
              
              	if( $sessions[$verifier]['expiration'] < time() )
              		return array( 'error', 'Время сессии истекло' );
              
              	$role_caps = unserialize( $_options[ $wpdb->prefix.'user_roles' ]->option_value );
              	$user_caps = unserialize( $user_options[ $wpdb->prefix.'capabilities' ]->meta_value );
              	$all_caps  = array();
              	foreach($user_caps as $key => $value){
              		if( isset($role_caps[$key]) && $value )
              			$all_caps = array_merge( $all_caps, $role_caps[$key]['capabilities'] );
              		else
              			$all_caps[$key] = $value;
              	}
              	return array( 'success', $all_caps );
              }

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

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

                Добавил код в статью, спасибо! А на какой версии ВП тестировался код?

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

    Добрый вечер. заставляю выполняться php файл. Подскажите как к нему прикрутить функции только woocomerce? То есть через минимальную загрузку WP как подрубить плагин?

    Ответить2.2 года назад #
    • Проще подгрузить в php файл весь WordPress, не используя SHORTINIT.
      В начале php файла вставить

      // подгружаем среду WordPress
      require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );

      WordPress подгрузится полностью, с плагинами.

      Или переписать плагин, удовлетворив зависимости.
      Или взять из плагина необходимые куски, удовлетворив зависимости.
      Или вообще пересмотреть подход к задаче.
      Вариантов много.

      2
      Ответить2.2 года назад #
  • Дима

    Кажетса здесь проблема: $user_options = $wpdb->get_results("SELECT meta_key,meta_value FROM $wpdb->usermeta WHERE (user_id=".$user->ID.") AND (meta_key IN ('session_tokens', '".$wpdb->prefix."capabilities') )", OBJECT_K );

    ... не работает. Помогите пожалуйста!

    Ответить2.1 года назад #
    • Если что-то не работает, как минимум, нужно после запроса на следующей строке вывести содержимое $user_options:

      var_dump($user_options);
      или
      print_r($user_options);

      и смотреть, в чем проблема

      1
      Ответить2 года назад #
Здравствуйте, !     Войти . Зарегистрироваться