Использование modRegistry

В MODX есть очень хорошая штука для хранения временных данных — объекты modRegistry. В народе их еще называют регистры, видимо из-за исторических параллелей.

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

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

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

Что же делать? Верно! Нужно разрешать проводить эту операцию не чаще одного раза в n минут для каждого сайта.

Если вы не знакомы с modRegistry, то будете изобретать какие-то решения с сессией (куками), которые можно легко обойти, или использовать свою таблицу (файлы).

А ведь можно сделать гораздо проще, используя возможности MODX:
// Разрешаем делать бэкапы не чаще раза в 10 минут
$ttl = 600;

// Загружаем сервис регистров
$registry = $modx->getService('registry', 'registry.modRegistry');
// Загружаем класс регистров, работающий с БД (есть еще и файловый класс)
$registry = $registry->getRegister('user', 'registry.modDbRegister');

// Подключаемся к сервису
$registry->connect();

// Задаём нашу тему сообщений
$topic = '/backup/';

// Уникальный ключ для текущего юзера
// В моём примере это сочетание id юзера и id сайта, для которого создаётся бэкап
$key = md5($modx->user->id . $site_id);

// Подписываемся на тему, используя наш ключ
$registry->subscribe($topic . $key);

// Проверяем, есть ли там сообщение?
// В параметрах указано не удалять его после чтения
$res = $registry->read(array('poll_limit' => 1, 'remove_read' => false));

// Если сообщение есть - выдаём сообщение об ошибке
if (!empty($res)) {
	return "Ошибка! {$ttl} минут еще не прошло!";
}

// А если нет - выполняем нашу очень важную операцию
// ...
// и отправляем новое сообщение в тему.

// Для этого нам нужно снова подписаться на тему, но уже без указания ключа
$registry->subscribe($topic);

// Ключ теперь в сообщении, которое мы отправляем
$registry->send(
	// Тема
	$topic,
	// Сообщение с ключом и значением true
	array($key => true),
	// Самое главное - время жизни сообщения
	array('ttl' => $ttl)
);

Теперь в течении 10 минут при попытке прочитать сообщение по уникальному ключу юзер-сайт для темы backup мы получим true, а после — null.

Если получаем true — юзеру еще нельзя совершать действие. А если null — то можно, и по завершении операции нужно создать новое сообщение на следующие 10 минут.

Выходит очень мощное хранилище временных данных, которое вы всегда можете использовать в своих дополнениях.
Например, Sendex его использует для подписки юзеров, а Office для сброса паролей.
Василий Наумкин
12 июня 2014, 02:57
modx.pro
13
3 126
+8

Комментарии: 1

Иван Брежнев
16 июня 2014, 02:42
0
Полезный инструмент, спасибо!
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    1