Користувальницькькі налаштування

Налаштування сайту


Сайдбар

Розділи

Загальний опис
Історія змін
Рекомендації до оновлення
Плани на майбутнє
Відомі проблеми
Онлайн демо
Допомога проекту
Люди
Трохи про безпеку

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.1664019551.txt.gz · Востаннє змінено: 2022/09/24 14:39 повз 127.0.0.1