Инструменты пользователя

Инструменты сайта


Боковая панель

Разделы

Общее описание
История изменений
Рекомендации к обновлению
Планы на будущее
Известные проблемы
Онлайн демо
Случайная статья
Видео
Помощь проекту
Люди

FAQ



Редактировать сайдбар

stigma

API Stigma

В Ubilling начиная со стабильного релиза 1.2.0 появилась возможность использовать в ваших модулях общую реализацию стигматизации объектов. Собственно стигмы представляют из себя некие состояния каких-то рандомных объектов (items) в рамках какой то рандомной категории (scope). Использование API Stigma ближе всего по духу к API ADcomments.

Проще всего, объяснить работу этого механизма на примере «а давайте сделаем возможность где-нибудь, в каком-то нашем модуле, отмечать купил ли пользователь у нас роутер или он жадная свинья?». Конфигурация этой стигмы начинается с написания конфигурационного файла, который будет храниться в config/stigma/, пускай это будет userbuyrouter.ini в силу планируемого нами SCOPE «USERBUYROUTER». Да, имя файлика конфигурации стигмы для конкретного scope-а по-умолчанию это этот же scope в lowercase с расширением *.ini. Собственно он и будет у нас читаться при создании объекта стигмы с соответствующим SCOPE.

userbuyrouter.ini
[stigmasettings]
TYPE=radiolist
ACTIVECLASS=todaysig
ANIMATION=1
 
[buy]
NAME="Bought a router"
ICON=sellrouter
 
[nobuy]
NAME="Greedy pig"
ICON=pig
 
[unknown]
NAME="We dont know"

Коротко о формате конфига

Секция «stigmasettings» является служебной и обязательной. Она указывает на базовое поведение контролов в конкретном скоупе. Возможные типы (TYPE) на даный момент «radiolist» (выбирушка одного из всех) или «checklist» (множественная выбирушка). ANIMATION просто указывает, обновлять ли с сопуствующей анимацией контейнер стигматы при изменении состояния или делать это «тихо и незаметно». Так как состояние «купил у нас роутер» не может быть одновременно и «купил» и «не купил» мы используем тип «radiolist». Опция ACTIVECLASS указывает просто, каким CSS-классом будут подсвечиваться активные/выбранные состояния объектов в рамках данного scope.

Дальше все секции, не являющиеся stigmasettings описывают конкретные состояния объектов (items) в рамках конкретного SCOPE. Их может быть сколько угодно. Имя секции собственно будет идентификатором состояния сохраняемым в БД и должно быть по возможности коротким и уникальным. Базовыми характеристиками состояния кроме его идентификатора являются NAME (имя) и ICON (вы не поверите! иконка). Иконки состояний по-умолчанию храняться в skins/stigma/ с расширением *.png.

Кроме всего этого, реализована механика подгрузки кастомных файлов конфигурации и иконок, на случай если пользователи сами захотят расширить набор состояний, либо заменить иконки на какие-то свои, и чтобы это все переживало обновления. Кастомные файлы конфигурации и иконки, имеющие приоритет над умолчательными храняться в content/documents/mystigma в сабдиректориях confs и icons.

Практическое использование в коде

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

  if (ubRouting::checkGet('username')) {
        $userLogin = ubRouting::get('username');
 
        //создаем инстанс с нужным нам scope-ом.
        $userRouter = new Stigma('USERBUYROUTER');
        //зовем обработчик фоновых коллбеков на случай если у нас измениться состояние
        $userRouter->stigmaController();
        //показываем интерфейс изменения состояния для нашего конкретного пользователя
        show_window(__('User bought a router'), $userRouter->render($userLogin));
    }

Ну и собственно сразу получаем результат в виде панели управления состояниями пользователя.

А может хотим панельку поменьше?

show_window(__('User bought a router'), $userRouter->render($userLogin, '64'));

типа такой?

А может хотим read-only панельку для администраторов без какого-то права, но нормально работающую для администраторов наделенных этими правами? Тогда как-то так

    if (ubRouting::checkGet('username')) {
        $userLogin = ubRouting::get('username');
        $userRouter = new Stigma('USERBUYROUTER');
        $userRouterReadOnlyFlag = true;
        if (cfr('USERROUTEREDIT')) {
            $userRouter->stigmaController();
            $userRouterReadOnlyFlag = false;
        }
 
        show_window(__('User bought a router'), $userRouter->render($userLogin, '64', $userRouterReadOnlyFlag));
    }

А если мы хотим поросто где-то в другом месте показать тупо список существующих состояний этого пользователя?

show_window(__('User bought a router as text'), $userRouter->textRender($userLogin);

типа так

или вообще тупо проверить есть ли какие-то установленные состояния и получить их в виде массива для наших дальнейших дофига концептуальных бизнес-приложений?

 if ($userRouter->haveState($userLogin)) {
            $routerStates = $userRouter->getItemStates($userLogin);
        }

А еще мы можем получить все возможные для скоупа состояния с их текстовыми описаниями вот как-то так

$userRouter = new Stigma('USERBUYROUTER');
$allStates=$userRouter->getAllStates();
debarr($allStates);

Короче все настолько прямолинейно и брутально, насколько это возможно. А вообще посмотреть на публичные методы и чего у них в параметрах будет намного продуктивнее и понятнее.

О оптимизации быстродействия

В примере выше, мы создавали инстанс стигмы как

$userRouter = new Stigma('USERBUYROUTER');

Что в свою очередь загружало из базы все состояния всех айтемов в этом scop-е. Это может быть полезно, когда мы одним и тем же инстансом пытаемся работать с разными айтемами одним инстансом. Например читая/проверяя наличие состояний для разных айтемов одним и тем же инстансом. Типа как

 $allUsers = zb_UserGetAllDataCache();
 $userRouter = new Stigma('USERBUYROUTER');
 
    if (!empty($allUsers)) {
        foreach ($allUsers as $eachLogin => $eachData) {
            if ($userRouter->haveState($eachLogin)) {
                $routerStates = $userRouter->getItemStates($eachLogin);
 
                if (isset($routerStates['buy'])) {
                    show_success($eachLogin);
                }
 
                if (isset($routerStates['nobuy'])) {
                    show_warning($eachLogin . ' ' . __('gotcha!'));
                }
            }
        }
    }

но в нашем первом примере, логично было бы загружать из БД только состояние одного конкретного, интересующего нас айтема, а точнее, конкретного пользователя, которого мы поймали в GET-параметре username. В таком случае создание нашего инстанса должно бы выглядеть так:

   $userRouter = new Stigma('USERBUYROUTER', $userLogin);

что приведет к загрузке данных о состояниях только для айтема $userLogin в рамках scop-а USERBUYROUTER в процесе создания инстанса, и вполне себе позволит нам с ними работать. Но только вот для этого конкретного $userLogin.

stigma.txt · Последние изменения: 2021/09/30 09:10 — nightfly