In-Portal Developers Guide

This is a wiki-based Developers Guide for In-Portal Open Source CMS. The purpose of this guide is to provide advanced users, web developers and programmers with documentation on how to expand, customize and improve the functionality and the code the In-Portal software. Please consider contributing to our documentation writing effort.

K4:Formatters

From In-Portal Developers Guide

(Difference between revisions)
Jump to: navigation, search

Alex (Talk)
(категория)
Next diff →

Revision as of 15:24, 25 December 2008

Unit Configs Unit Configs
Статьи в этой категории

Contents

В K4 существует 2 способа отображения информации:

  • для записи в базу данных
  • для отображения пользователю

Классическим примером этому может служить ввод даты, т.к. пользователь вводит дату в понятном ему формате "28/12/2007 22:10:43" (dd/mm/yyyy hh:mm:ss), а в базе данных эта дата уже находиться в форме timestamp "1198872643" (количество секунд, прошедших с 1 января 1969 года). Для автоматического выполнения такого рода преобразований в K4 существует ряд классов, называемых форматеры (formatters). Они так называются потому что они осуществляют форматирование данных. Все форматеры унаследованы от класса kFormatter. У них есть как минимум 2 доступных метода (может увеличиваться в зависимости от форматера):

  • Format - осуществляет преобразования db_value -> form_value (прямое преобразование)
  • Parse - осуществляет преобразование form_value -> db_value (обратное преобразование)

Эти методы автоматически вызываются при использовании методов kDBBase::GetField (item и list) и kDBItem::SetField (item). Метод kDBBase::GetField кроме названия поля (первый параметр) также принимает и второй (необязательный) параметр $format с помощью которого можно задать другой формат вывода (см. опцию format у конкретного форматера) для текущего вызова этого метода. Этот формат также можно указывать в параметре format у тэго Field:

<inp2:prefix_Field name="CreatedOn" format="d-m-Y"/>

Форматеры не рекомендуется использовать в ручную.

Image:Tipbox Icon.gif Поведением форматера можно управлять указывая те или иные опции у поля, описанного в массиве Fields в unit configs.

kFormatter

Данный форматер используется на формах где требуется вводить числа (т.к. они форматируются согласно региональным установкам), а так же если требуется вводить адреса электронной почты. Этот форматер является базовым классом для всех форматеров, а так же позволяет использовать оператор строго равенства (===) на итоговое значение поля, т.к. производит приведение типов (type casting). Далее перечислены опции, которые использует этот форматер:

опция описание
type (string) Тип значения в поле (или тип поля). Используется при обеих преобразованиях значения поля. Например для отображения числа с 2 знаками после запятой (15.66) нужно использовать следующее значение данной опции: "'%01.2f'".
format (string) Формат отображаемого значения (метод Format). Используется как $format для функции sprintf.
regexp (string) Маска (регулярное выражение), которой должно соответствовать значение в поле (метод Parse). Ниже представлены самые распространённые регулярные выражения:
  • в поле должен быть адрес электронной почты - '/'.REGEX_EMAIL_USER.'@'.REGEX_EMAIL_DOMAIN.'/';
  • в поле не должно быть цифр - /^[^\d]+$/.
allow_html (int) В целях безопасности все данные, приходящие с Front-End преобразуются, используя функцию htmlspecialchars. Если для конкретного поля этого делать не требуется (напр. на поле подключён HTML редактор), то нужно указать у поля эту опцию.

kOptionsFormatter

Данный форматер используется на формах, где присутствует элементы ввода с ограниченным выбором (напр. dropdown, radio buttons, checkboxes, multiselect). Данный форматер может содержать статический (заранее определённый) набор опций, а так же динамический набор опций, формируемый при помощи указанного sql запроса. Далее перечислены опции, которые использует этот форматер:

опция описание
options (array) Набор опций в виде ассоциативного массива. На форме ввода будут отображаться значения этого массива, а в базу будут писаться его ключи. Например, если используется массив Array (1 => 'Yes', 2 => 'No'), то в базу будет писаться или 1 или 2, а пользователь будет видеть Yes или No соответственно. Использование нуля ("0"), в качестве ключа опции не рекомендуется, т.к. это может привести к некорректному выбору значения по умолчанию при создании новых записей. Не надо добавлять в начало массива пустую опцию. Для появления пустой опции на форме редактирования следует передать значение "1" в параметр "has_empty" блоку, использующемуся для отображения dropdown, напр.
<inp2:m_RenderElement name="inp_edit_options"
	prefix="test-prefix" field="DropdownField" title="la_fld_DropdownField" has_empty="1"
/>
use_phrases (boolean) Данная опция указывает на то, что значение каждой опции (не ключ) является фразой и перед показыванием пользователю его следует перевести используя метод Application::Phrase (происходит автоматически). До Core v 4.2.2 нужно так же указать эту опцию при использовании блока "inp_edit_options", иначе фразы в dropdown не будут переводиться.
options_sql (string) SQL запрос, используемый для получения динамического списка опций. Самый распространённый вариант это выборка из другой таблицы без условия, отсортированная по алфавиту. Примером может послужить данный sql запрос:
'SELECT %s FROM '.TABLE_PREFIX.'SampleTable ORDER BY SampleName'
В данном запросе "%s" будет заменено на комбинацию названий полей, использующихся для выборки опций.
option_key_field (string) Название колонки в sql запросе, из которой брать ключи опций (то, что будет в базе данных). Начиная с Core v 4.3.0 можно писать SQL выражение (напр. "CONCAT(FieldName, ' sample')").
option_title_field (string) Название колонки в sql запросе, из которой брать значения опций (то, что пользователь увидит). Начиная с Core v 4.3.0 можно писать SQL выражение (напр. "CONCAT(FieldName, ' sample')").
option_constrain (string) Фильтр, который был применён в запросе на выбор опций (тот, что после слова WHERE). Т.е. если в опции options_sql был применён фильтр, то его необходимо продублировать здесь. Используется для корректной выборки опций в блоке inp_edit_picker. Данная опция будет доступна только начиная с Core v 5.0.0.

Можно комбинировать статические и динамические опции, т.е. задавать полю опцию options и options_sql одновременно. В значениях опций поля, отвечающих за формирование динамических опций для форматера (options_sql, option_key_field, option_title_field) можно указывать ключевое слово "%2$s", которое замениться на ID текущего языка. Обычно это используется когда требуется построить список опций на текущем языке из многоязычного поля (т.е. поля, которое использует форматер kMultiLanguage).

kMultiLanguage

Данный форматер используется для обработки многоязычных полей, т.е. полей, значение в которых может изменяться в зависимости от языка, на котором просматривается сайт. Обычно это элементы (form controls) со свободным вводом данных (textbox, textarea), т.к. у элементов ввода с ограниченным выбором видимая пользователю часть состоит из переводов фраз. В базе данных для каждого поля, использующего этот форматер, автоматически создаётся (напр. при добавлении нового языка) по одной колонке на каждый язык. Название колонки состоит из ID языка и названия поля в формате "l<LanguageId>_<FieldName>", напр. для хранения значения поля TestField в языке с 1-м ID колонка будет называться "l1_TestField". Если требуется добавить новое многоязычное поле в базу данных, то надо:

  • добавить его описание в массив Fields в unit config
  • воспользоваться функцией "Re-build Multilanguage Fields" в секции "Configuration -> Service Tools" (Platform) или "Tools -> Service" (In-Portal).

Далее перечислены опции, которые использует этот форматер:

опция описание
format (string) Поддерживается только одно значение данной опции: "no_default". Если его указать, то значение из поля на основном (primary) языке не будет использоваться как значение поля для остальных языков, когда в них не будет своего значения.
db_type (string) Тип и размер значения поля в базе данных (напр. "varchar(255)", "text", "int(11)"). Используется при создании новый переводимых полей в базе данных.

Будьте внимательны, т.к. этот форматер добавляет префикс языка (напр. "l5_") только при чтении значения из поля (т.е. в методе Format). А при записи значения в поле (метод Parse) его нужно добавлять в ручную. Это можно наглядно увидеть из следующих примеров:

вход (метод и поле) название поля выход (метод и поле)
GetField('FieldName') меняется GetDBField('l5_FieldName')
GetField('l5_FieldName') не меняется GetDBField('l5_FieldName')
SetField('FieldName') не меняется SetDBField('FieldName')
SetField('l5_FieldName') не меняется SetDBField('l5_FieldName')

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

kDateFormatter

Данный форматер используется для работы с датой и временем. Он используется на формах, где присутствует элементы ввода даты, времени, даты и времени в одном поле. Дата и время на формах вводятся в понятной для человека форме, а в базе хранятся в форме timestamp. Формат даты и времени берётся из региональных настроек системы (Configuration -> Regional). Форматы, используемые данным форматером делятся на 2 группы:

  • input formats - используются для ввода данных из форм;
  • output formats - используются для отображения данных.

Такое разделение форматов обосновано ограничениями в работе форматера. Для анализа, введённой пользователем, даты и времени этот форматер использует регулярные выражения, в основе которых используются численно-буквенные последовательности фиксированной длинны. Это в некоторой мере ограничивает его возможности (напр. буква "F" из формата дат в php), поэтому для его корректной работы требуется ограничить набор доступных форматов ввода дат. В то же время на отображение дат это ограничение не накладывается. От этого и такое разделение. Далее перечислены опции, которые использует этот форматер:

опция описание
format (string) Формат, используемый для отображения даты и времени в одном поле (напр. в grid). Т.к. в региональных настройках форматы даты и времени вводятся отдельно, то для их объединения в единый формат используется значение опции date_time_separator (по умолчанию это проблел).
date_format (string) Формат, используемый для отображения даты (без времени). Если не задан, то берётся из поля DateFormat у объекта текущего языка. Если указать пустое значение, то в grid будет показываться только время без даты (т.к. обычно оно показывается вместе с датой).
time_format (string) Формат, используемый для отображения времени (без даты). Если не задан, то берётся из поля TimeFormat у объекта текущего языка. Если указать пустое значение, то в grid будет показываться только дата без времени (т.к. обычно она показывается вместе со временем).
input_format (string) Формат, используемый для ввода даты и времени в одном поле (напр. в grid). Т.к. в региональных настройках форматы даты и времени вводятся отдельно, то для их объединения в единый формат используется значение опции date_time_separator (по умолчанию это проблел).
input_date_format (string) Формат, используемый для ввода даты (без времени). Если не задан, то берётся из поля InputDateFormat у объекта текущего языка. Если указать пустое значение, то можно будет вводить время без даты (т.к. обычно оно вводиться вместе с датой).
input_time_format (string) Формат, используемый для ввода времени (без даты). Если не задан, то берётся из поля InputTimeFormat у объекта текущего языка. Если указать пустое значение, то можно будет вводить дату без времени (т.к. обычно она вводится вместе со временем).
date_time_separator (string) Символ, при помощи которого форматы даты и времени объединяются в единый формат. Используется в опциях format и input_format.
empty_time (string) Значение времени (в форме timestamp), которое будет использовано для формирования полноценного значения (дата и время) поля в базе данных в случае, когда время не будет задано (напр. из формы). По умолчанию используется утро (00:00:00) от текущей даты.
use_timezone (boolean) Указывает на то, что надо делать поправку на смещение по часовому поясу (time zone), используемое в операционной системе сервера при отображении даты и времени (по умолчанию "true"). В некоторых случаях добавляемое смещение (может быть отрицательным) может мешать. Когда заведомо известно, что показываемая дата с календарём никак не связана, а напр. является просто временным интервалом (абстрактное количество секунд без даты вообще), то лучше указать "false" в качестве значения данной опции.

В качестве значения любой из выше описанных опций задающих формат можно указать значение в форме "_regional_FieldName", где FieldName является названием поля из текущего объекта языка. В этом случае формат будет взят из указанного поля у объекта текущего языка.

Кроме преобразований значения поля этот форматер добавляет новое вычисляемое поле (calculated field), в котором будет отформатированное, по опции format (превращённого в аналогичный формат в SQL), значение поля. Это поле будет называться "<Field>_formatted" (где Field будет соответствовать названию поля с датой). Оно используется в In-Portal для поиска по полям, использующих этот форматер (если его не использовать, то поиск будет идти по значению timestamp). Для Platform эта проблема не актуальна, т.к. в grids над каждой колонкой используется индивидуальный фильтр с собственным форматом.

Так же этот форматер создаёт по 2 виртуальных поля и 2 вычисляемых поля (для редактируемых grids) на каждое поле, на которое он наложен. Они используются для отдельного хранения даты и времени (т.к. на формах редактирования тоже 2 поля):

  • <FieldName>_date - для даты (напр. CreatedOn_date);
  • <FieldName>_time - для времени (напр. CreatedOn_time).

Если требуется установить значение в поле, то надо пользоваться именно этими двумя полями:

$timestamp = adodb_mktime(); // то, что мы ставим (оригинальное поле с датой: DateField)
$object->SetDBField('DateField_date', $timestamp);
$object->SetDBField('DateField_time', $timestamp);
Image:Infobox Icon.gif Если ставить значение в поле на прямую (не использую данные виртуальные поля), то тогда это значение будет переписано значениями из соответствующих виртуальных полей.

kUploadFormatter

Это форматер используется для загрузки файлов на сервер. Существует 2 способа загрузки файлов на сервер, которые понимает этот форматер:



У каждого из них есть свои плюсы и минусы, но исторически сложилось, что в Platform используется индикатор загрузки файла, а в In-Portal нет. Далее перечислены опции, которые использует этот форматер:

Общие опции

опция описание
format (string) Данная опция допускает следующие значения:
  • full_url - вернуть ссылку для сохранения файла (для браузера)
  • full_path - вернуть полный путь к файлу на сервере (в файловой системе сервера)
  • file_size - вернуть размер файла в байтах
  • resize:WxH - вернуть масштабированную к указанному размеру картинку (W - ширина, H - высота)
  • img_size - вернуть размеры изображения для img HTML-тэга в виде: width="M" height="N" (доступно начиная с Core v 5.0.0);
  • wm:WM_FILENAME|H_MARGIN|V_MARGIN - наложить указанный водяной знак (watermark) на запрашиваемое изображение:
    • WM_FILENAME - файл, содержащий водяной знак (путь относительно директории с темой на Front-End);
    • H_MARGIN - смещение водяного знака на основном изображении по горизонтали:
      • C - по центру изображения;
      • положительное значение - отступ от левой границы изображения;
      • отрицательное значение - отступ от правой границы изображения;
    • V_MARGIN - смещение водяного знака на основном изображении по вертикали:
      • C - по центру изображения;
      • положительное значение - отступ от верхней границы изображения;
      • отрицательное значение - отступ от нижней границы изображения.

Значения resize и wm можно комбинировать используя точку с запятой, напр. 'resize:150x150;wm:platform/img/wm.png|-5|-5'.

Image:Infobox Icon.gif Если применяется формат "resize" или "files_resized" то предварительно необходимо создать директорию "resized" в директории, где хранятся исходные изображения.

В случае, когда требуется обработать поле, в котором находяться несколько файлов надо использовать значения:

  • file_urls - аналог full_url;
  • file_paths - аналог full_path (начиная с версии Core v 4.3.1);
  • file_sizes - аналог file_size;
  • files_resized - аналог resize (начиная с версии Core v 4.2.1);
  • img_sizes - аналог img_size (начиная с версии Core v 5.0.0);
  • wms - аналог wm (начиная с версии Core v 4.2.1).


Например для получения масштабированной версии изображения, хранящегося в поле требуется написать следующее:

<img src="<inp2:Field name='$field' format='resize:120x120'/>" <inp2:Field name='$field' format='resize:120x120;img_size' no_special='1'/> alt=""/>

Если не использовать параметр no_speial тэга Field, то кавычки вокруг размеров изображения заменятся на "&quot;" символы. Также можно указывать формат "img_size/img_sizes" без формата "resize/files_resized".

upload_dir (string) Директория, куда нужно сохранять закачанный файл. Задаётся относительно значения FULL_PATH константы, напр. "/system/user_files/manufactures/". Если некоторые составляющие пути можно заменить значением констант, то это конечно нужно сделать. Например в Platform есть константа WRITEBALE_BASE со значением "/system", которую можно здесь использовать. Обычно относительный путь для сохранения закачанных файлов (т.е. значение данной опции) определяют в файле constants.php у модуля "Custom" для последующего использования в дальнейшем.
max_size (int) Максимальный размер одного загружаемого файла в байтах. Если не задан, то будет использоваться значение константы MAX_UPLOAD_SIZE.

Опции только для загрузчика без индикатора

опция описание
size_field (string) Название поля, в которое записать размер загруженного файла.
orig_name_field (string) Название поля, в которое записать имя загруженного файла в системе пользователя (т.е. как он назывался на компьютере того, кто его загружал).
content_type_field (string) Название поля, в которое записать mime-тип загруженного файла, посланный браузером.
allowed_types (array) Mime-типы файлов, которые можно загружать. Если не указать ничего, то можно загружать любые файлы. Это наименее надёжный способ определения типа загруженного файла, т.к. он ориентируется на тот mime-тип, который браузер посылает на сервер (который можно легко сфабриковать). Например если браузер не знает (по расширению или заголовку файла) какой у него mime-тип, то он скорее всего пошлёт "text/plain", а это совсем не то, что надо. Идеальным вариантом является анализ уже загруженного файла используя функцию finfo_file для определения фактического mime-типа. Возможно после перехода на php5 так и сделаем (т.к. эта функция есть только в php5).

Опции только для загрузчика с индикатором

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

Image:Tipbox Icon.gif Если не задать хотя-бы один из ниже перечисленных параметров, кнопки "browse" и "upload" работать не будут!
опция описание
multiple (int) Максимальное количество файлов, которое можно загрузить в поле. Если загружено больше одного файла, то, в значении поля, имена файлов будут разделены символом вертикальной черты ("|").
direct_links (boolean) Строить прямые ссылки на сохранение загруженных файлов в swf upload control.
file_types (string) Маска для имён файлов, которые можно загружать на сервер. Например: '*.jpg;*.gif;*.png'.
files_description (string) Описание к указанной маске файлов, напр. '!la_title_ImageFiles!'. Значение данной опции не запрещает наличие и фраз и простого текста одновременно. Для того, чтобы текст был рассмотрен, как фраза его надо экранировать одинарными кавычками. Вот более сложный пример: 'sample text !la_phrase! other text'. В данном примере фразой будет текст la_phrase, а остальной текст останется без изменений.
Image:Infobox Icon.gif К сожалению на данный момент времени фразы, из значения данного параметра не переводятся (см. заявку).
Image:Infobox Icon.gif При использовании загрузчика с индикатором файл после закачки (нажатия кнопки "Upload") попадает в директорию "/system/tmp" и только если объект, содержащий поле для загрузки будет сохранён в базу данных (напр. события OnCreate, OnUpdate, OnPreSave, OnSave и т.п.) файл будет перемещён в директорию, указанную в опции upload_dir у используемого поля.

Результат загрузки файлов на сервер может быть удачным, а может и не быть. В таком случае будет показана ошибка. Самая распространённая ошибка о том, что нету права сохранять файлы в директорию заданную в опции upload_dir или директорию "/system/tmp". Так же бывают ошибки о том, что файл нельзя загрузить, т.к.

  • его размер больше требуемого;
  • его mime-тип не соответствует заданному.

Если файл не загружается по неизвестной причине, то надо проверить наличие атрибута enctype у HTML тэга form. Подробнее об этом здесь.