Я уже обсуждал этот вопрос, но пока не нашел аккуратного решения.
Скажем, у нас есть приложение, в котором клиенты могут забронировать курс с помощью веб-сайта, а административный персонал также может забронировать курсы от имени клиентов, используя бэкэнд-систему. Я пытаюсь установить способ, чтобы администраторы HR кодифицировали ограничения, применяемые к разрешениям, например can_make_booking
, поскольку разрешение не просто логическое и не должно быть жестко закодировано в приложении.
В настоящий момент клиенты могут совершить бронирование, пока дата курса не указана как минимум в стандартном уведомлении «n» дней в будущем, они бронируют не более, чем количество доступных мест, и они платят как минимум сумму, подлежащую оплате (или nil, если их учетная запись установлена в счет-фактуру). Менеджеры могут заказывать с использованием бэкэнд-приложения, если дата назначения – в любое время.
Я представляю нечто подобное. Пусть администраторы HR добавят ограничения разрешений, такие как:
role permission constraint -------- ------------ ---------- customer make_booking 1 customer make_booking 2 customer make_booking 3 manager make_booking 5
Затем таблица ограничений,
constraint property operator value OR_parent ---------- ------------ -------- -------------------------- --------- 1 $course_date >= strtotime("+$notice days") NULL 2 $places_booked <= $places_available NULL 3 $paid >= $total NULL 4 $send_invoice == TRUE 3 5 $course_date >= strtotime("now") NULL
Связывание этих ограничений для роли клиента приведет к созданию чего-то вроде следующего eval
ed кода (ограничение №4 сопряжено с # 3 как часть последовательности OR):
if($course_date >= strtotime("+$notice days") && $places_booked <= $places_available && ($paid >= $total || $send_invoice == TRUE)){ // make the booking }
Каждое правило может использоваться независимо на каждом этапе, например, JavaScript и проверка формы, чтобы дать отзыв, если по какой-либо причине бронирование не может быть сделано.
Однако, скажем, HR хочет изменить правило для клиентов, чтобы им было разрешено одновременно заказывать по 3 места, а $paid
amount должна составлять как минимум $deposit
? В идеале я хотел бы позволить им динамически строить эти php-правила, не предоставляя им доступ к жестко написанному коду. Свойства и ценности могут быть подвергнуты санитарной обработке, так что eval
кода не является проблемой. Я не хочу жестко кодировать каждую комбинацию каждого правила, как и в некоторых случаях, не было бы четкого способа заранее угадать логику администратора персонажа.
Я посмотрел на версии утверждений Zend_ACL, но они, похоже, не предлагают динамизм, который я ищу. Что было бы хорошим способом реализовать эти динамические ограничения? Любые мысли из других сред? Благодаря!
Более подробная информация о проблеме из презентации CUSEC Зеда Шоу рассказывает о том, почему «ACL мертв» – http://vimeo.com/2723800
Ну, это одна из областей, которые все еще вызывают довольно большую дискуссию. Как говорят некоторые [кто? – думайте, что это был Этвуд среди других людей, но ссылка уходит от меня], приложение, которое может сделать все, уже сделано; он называется C. То, что вы хотите сделать границами почти в «слишком обобщенной» области, хотя я вижу, что значение не требуется программисту каждый раз при изменении бизнес-правила.
Если бы мне пришлось реализовать такую систему, я бы попытался ее разбить на домены. Вы сделали относительно хорошую работу уже со второй таблицей. Просто нормализуйте это на отдельные домены, которые используются для объединения бизнес-правил. Вы создаете бизнес-правило, состоящее из 1 или нескольких ограничений OR-ed вместе. Каждому ограничению требуется свойство, которое ограничено оператором в отношении термина. Термины могут быть сложными, поскольку они могут быть чем угодно: от свойства до функции, до составной функции. Вероятно, проще всего проверить свои бизнес-правила, чтобы узнать, что вам нужно. Начните с, скажем, свойств, булевых и обычных вещей, таких как «СЕЙЧАС».
Таким образом, сама схема будет, например, состоять из rules
, которые содержат несколько constraints
(очевидная польза заключается в том, что вы можете связать их с любой [группой пользователей / предложением / временем / другим доменом], который вы хотите). Они, в свою очередь, состоят из properties
, которые будут сопоставляться с одним из operators
(в основном справочной таблице, чтобы вы могли вводить пользовательские описательные имена для не-программистов, но в какой-то момент вы можете выбрать в нем пользовательские функции) и , конечно, одно из terms
. Последняя часть является самой сложной, поэтому вам, вероятно, придется квалифицировать ее с помощью идентификатора в term_types
чтобы вы знали, сравниваете ли вы с другим свойством или функцией. Вы также можете просто VARCHAR
его и создать поле с PHP, что не должно быть слишком сложным, учитывая, как у вас есть все параметры в properties
и / или functions
.
Это очень открытая система (и, вероятно, есть лучшие способы ее решения), поэтому, вероятно, это не стоит делать, если вы не знаете, что вам потребуется высокая степень динамичности в бизнес-правилах.