Magento для PHP MVC разработчиков – Углубленная настройка системы (ч.8/11)
В прошлый раз мы говорили об особой конфигурации системы Magento. Если вы пропустили эту статью, вернитесь и прочтите ее. Итак, а здесь мы продолжим рассмотрение темы и осмотрим более подробно теги настроек, которые вы можете использовать в отдельных полях:
<fields> <!-- ... ---> <fieldname translate="label"> <label>Field Name</label> <frontend_type>text</frontend_type> <sort_order>2</sort_order> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>0</show_in_store> </fieldname> <!-- ... ---> </fields>
Итак, что означают все эти теги?
<label/> та <comment/>
Эти теги позволяют устанавливать текст, который будет виден пользователям в админке в поле Настройки системы.
Заголовок (label) отображается слева от поля формы, а комментарий отображается непосредственно под полем.
<show_in_default/>, <show_in_website/>, <show_in_store/>
Это булевы поля со значением либо 1
, либо 0
. Они указывают на то, будет ли поле настройки отображаться при просмотре конфигурации системы в режиме просмотра по умолчанию, просмотре веб-сайта или просмотре магазина.
Неявное предположение состоит в том, что они также контролируют, какие параметры можно настраивать на каждом уровне. Тем не менее, ничего в бэкенде не подтверждает это предположение. То есть поле может быть настроено следующим образом:
<show_in_store>0</show_in_store>
но все равно будет возможно (хотя и не рекомендуется) устанавливать и получать значение этого поля на уровне магазина с помощью программных средств.
<sort_order/>
<sort_order/>
— это численное значение, которое используется для определения порядка полей в их родительском контейнере. Чем выше число, тем ниже поле будет показываться на экране.
<frontend_type/>
Этот тег определяет тип поля, который будет использоваться для сбора значения конфигурации. Вот некоторые из основных поддерживаемых значений:
- image
- label
- multiselect
- password
- select
- text
- textarea
- time
Значение этого поля используется в паттерне стиля для создания экземпляра класса в формате:
Varien_Data_Form_Element_Type
где «Type» – это значение текстового узла <frontend_type/>
. Это происходит в методе addField
класса Varien_Data_Form_Element_Abstract
, как показано ниже:
class Varien_Data_Form_Abstract extends Varien_Object { //... public function addField($elementId, $type, $config, $after=false) { if (isset($this->_types[$type])) { $className = $this->_types[$type]; } else { $className = 'Varien_Data_Form_Element_'.ucfirst(strtolower($type)); } $element = new $className($config); $element->setId($elementId); if ($element->getRequired()) { $element->addClass('required-entry'); } $this->addElement($element, $after); return $element; } }
<frontend_class/>
Не дайте себя обмануть, <frontend_class/>
не является Сгруппированным Названием Класса. Тег <frontend_class/>
может использоваться для изменения атрибута класса тега в элементе формы, созданного для поля. То есть это поле конфигурации позволяет добавить CSS класс для тега формы.
Например, поле, настроенное следующим образом:
<frontend_type>select</frontend_type> <frontend_class>free-method</frontend_class>
будет выглядеть так:
<select class="free-method">
<validate/>
На первый взгляд <validate/>
кажется чем-то очень сложным. Но этот тег всего лишь добавляет CSS класс полю формы. Такая конфигурация:
<validate>validate-email</validate>
добавит следующий CSS-класс элементу формы:
<input type="text" class="validate-email" />
Как и почти везде в Magento, это еще не все. Наличие этого CSS класса у элемента будет инициировать процедуру проверки на клиентской стороне. Например, вышеупомянутый код приведет к тому, что будет запущена JavaScript проверка электронной почты в этом поле. Если данные в этом поле не проходят проверку, пользователь не сможет сохранить форму конфигурации.
Вы можете ознакомиться с доступными процедурами JavaScript проверки в файле:
js/prototype/validation.js
и вот так выглядит вышеуказанная процедура проверки электронной почты в этом файле:
['validate-email', 'Please enter a valid email address. For example johndoe@domain.com.', function (v) { return Validation.get('IsEmpty').test(v) || /^[a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]+(\.[a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*\.([a-z]{2,})/i.test(v) }],
которая выглядит ужасно, но она является весьма полезным регулярным выражением проверки эл.почты.
<can_be_empty/>
Тег <can_be_empty/>
используется в полях с множественным выбором. Короче говоря: если вы хотите разрешить валидный «не выбрано» в конфигурации, воспользуйтесь этим полем.
Что происходит за кулисами, если значением can_be_empty
является true
? Система генерирует скрытое поле на странице настройки системы:
Файл: lib/Varien/Data/Form/Element/Multiselect.php if ($this->getCanBeEmpty()) { $html .= '<input type="hidden" name="' . parent::getName() . '" value="" />'; }
которое обеспечивает то, что код обработки формы позволит «пустой» выбор.
<depends/>
<depends/>
позволяет указать, что ваше поле конфигурации будет отображаться только тогда, когда другое поле конфигурации в той же группе имеет определенное значение.
Например, конфигурация системы Paypal Express имеет следующую определенную зависимость:
<specificcountry translate="label"> <label>Countries Payment Applicable From</label> <frontend_type>multiselect</frontend_type> <sort_order>110</sort_order> <source_model>adminhtml/system_config_source_country</source_model> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>0</show_in_store> <depends><allowspecific>1</allowspecific></depends> </specificcountry>
Вы заметили этот тег:
<depends><allowspecific>1</allowspecific></depends>
Он говорит системе, что если есть поле <allowspecific>
(определенное следующим образом):
<allowspecific translate="label"> <label>Payment Applicable From</label> <frontend_type>select</frontend_type> <sort_order>100</sort_order> <source_model>adminhtml/system_config_source_payment_allspecificcountries</source_model> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>0</show_in_store> </allowspecific>
которое имеет значение «1», тогда поле «specificcountry» должно отображаться. Это происходит мгновенно с помощью определенного кода JavaScript.
Хотя это работает с любыми полями, которые присылают события onchange
, система core Magento использует эту функцию только тогда, когда родительское поле выбрано.
<source_model/>
Тег <source_model/>
указывает на класс Модели (в формате URI/Сгруппированное Имя Класса) для заполнения полей параметрами по умолчанию. В дополнение к стандартному Сгруппированному Имени Класса Magento, расширенный поддерживаемый синтаксис выглядит так:
module/modelname::methodName
Система будет делать экземпляр модели с getModel('module/modelname')
и вызывать его метод methodName
для получения массива пар значение/заголовок для использования в качестве источника. Если имя метода отсутствует, будет вызван метод toOptionArray
по умолчанию.
<frontend_model/>
По умолчанию Элементы формы Magento рендерятся с помощью класса Блока:
Mage_Adminhtml_Block_System_Config_Form_Field
Однако, если вы хотите использовать специальный рендер для поля «Настройка системы», вы можете указать другой класс блока (в формате URI/Сгруппированное Имя Класса) используя тег <frontend_model/>
.
Например, поле last_update
в группе adminnotification
:
<last_update translate="label"> <label>Last update</label> <frontend_type>label</frontend_type> <frontend_model>adminhtml/system_config_form_field_notification</frontend_model> <sort_order>3</sort_order> <show_in_default>1</show_in_default> <show_in_website>0</show_in_website> <show_in_store>0</show_in_store> </last_update>
указывает, что следует использовать для рендеринга поле adminhtml/system_config_form_field_notification
. Эта запись переводится в следующий класс:
Файл: app/code/core/Mage/Adminhtml/Block/System/Config/Form/Field/Notification.php class Mage_Adminhtml_Block_System_Config_Form_Field_Notification extends Mage_Adminhtml_Block_System_Config_Form_Field { protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) { $element->setValue(Mage::app()->loadCache('admin_notifications_lastcheck')); $format = Mage::app()->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM); return Mage::app()->getLocale()->date(intval($element->getValue()))->toString($format); } }
Метод _getElementHtml
обеспечивает отображение введенной даты с таким же форматом.
<backend_model/>
После того, как форма будет отправлена Magento, ее значения должны быть сохранены в базе данных. В полях «Конфигурация системы», как правило, это касается класса Модели:
Mage_Core_Model_Config_Data
Однако могут быть случаи, когда вам нужно, чтобы ваша конфигурация системы использовала другую модель бэкэнда. Тег <backend_model/>
позволяет указать другой класс модели (с помощью формата URI/Сгруппированное Имя Класса).
Чаще всего это нужно для того, чтобы выполнить дополнительные действия, когда поле сохранено. Расширяя класс Mage_Core_Model_Config_Data
вашей собственной моделью и определяя метод _beforeSave
и/или _afterSave
в вашей модели, вы можете применять дополнительные действия, когда изменяется значение конфигурации.
Например, рассмотрим поле import
в группе tablerate
:
<import translate="label"> <label>Import</label> <frontend_type>import</frontend_type> <backend_model>adminhtml/system_config_backend_shipping_tablerate</backend_model> <sort_order>6</sort_order> <show_in_default>0</show_in_default> <show_in_website>1</show_in_website> <show_in_store>0</show_in_store> </import>
Сгруппированное Имя Класса adminhtml/system_config_backend_shipping_tablerate
превращается в следующий класс:
class Mage_Adminhtml_Model_System_Config_Backend_Shipping_Tablerate extends Mage_Core_Model_Config_Data { public function _afterSave() { Mage::getResourceModel('shipping/carrier_tablerate')->uploadAndImport($this); } }
Здесь срабатывает метод _afterSave
(который вызывается после сохранения модели), чтобы обновить Модель shipping/carrier_tablerate
информацией с только что загруженного файла.
<upload_dir/>
и <base_url/>
Оба этих тега используются в полях «Конфигурация системы», которые используют поле
<frontend_type>image</frontend_type>
с моделью бэкенда
<backend_model>adminhtml/system_config_backend_image</backend_model>.
Они определяют:
- Где загружается файл с изображением
- Базовый путь URI, который используется при воспроизведении тега
<img>
Во-первых, давайте рассмотрим тег <upload_dir/>
<upload_dir config="system/filesystem/media" scope_info="1">sales/store/logo</upload_dir>
Здесь есть три основные вещи:
- Базовый путь для загрузки изображения
- Путь, от базового, по которому нужно загружать это конкретное поле изображения
- Следует ли добавлять текущую конфигурацию к пути
Путь к загрузке базового изображения устанавливается с помощью атрибута config (выше это system/filesystem/media
). Он указывает путь к конфигурации системы. То есть это значение системной конфигурации Magento (которая относится к {{root_dir}}/media
в инсталляции Community Edition по умолчанию).
После того, как найден базовый путь загрузки изображения, нам нужно расширить это подкаталогом для загрузки. Для этого мы добавляем значение текстовому узлу <upload_dir/>
:
sales/store/logo
к значению базового пути загрузки изображения, что даст нам нечто подобное:
{root-magento}/media/sales/store/logo
Наконец, если для атрибута scope установлено значение «1», текущий контекст конфигурации будет преобразован в путь. Если вы загружали изображения в контексте default
, то вы получите путь типа:
{root-magento}/media/sales/store/logo/default
Однако, если вы загрузили изображение в контексте определенного магазина, вы получите путь типа:
{root-magento}/media/sales/store/logo/stores/5
где «5» – это идентификатор магазина, из которого вы сейчас редактируете настройки.
Когда мы загружаем изображения, только контекст и название картинки сохраняются в конфиге. Это означает, что нам нужно сообщить системе, какой базовый URL-адрес использовать для нашего изображения.
<base_url type="media" scope_info="1">sales/store/logo</base_url>
Область scope_info
и текстовый узел функционируют так же, как и <upload_dir/>
. Где <base_url/>
отличается в настройке базового URI изображения (который, естественно, будет отличаться от локального базового файлового пути).
Базовый путь устанавливается с помощью атрибута type
. Заданное значение будет передано в метод getBaseUrl
в глобальном объекте Mage
для установления базового URL-адреса изображения. Приведенный выше пример будет выглядеть примерно так:
Mage::getBaseUrl('media')
Вы можете увидеть весь код в классе Mage_Adminhtml_Block_System_Config_Form_Field_Image
.
class Mage_Adminhtml_Block_System_Config_Form_Field_Image extends Varien_Data_Form_Element_Image { //... protected function _getUrl() { $url = parent::_getUrl(); $config = $this->getFieldConfig(); /* @var $config Varien_Simplexml_Element */ if (!empty($config->base_url)) { $el = $config->descend('base_url'); $urlType = empty($el['type']) ? 'link' : (string)$el['type']; $url = Mage::getBaseUrl($urlType) . (string)$config->base_url . '/' . $url; } return $url; } //... }
Краткий вывод
Как видно из сегодняшнего обзора, конфигурация админпанели Magento – это мощная система, которая является практически средой готовых приложений и решений. Используя функциональные возможности, встроенные в систему, вы можете быстро и надежно создавать новые пользовательские функции для своих магазинов и своих клиентов.
Автор: Alan Storm (http://alanstorm.com/magento_system_configuration_in_depth_tutorial/)
Перевод на русский: SebWeo
- Magento для PHP MVC разработчиков (Alan Storm) – ч.1/11
- Magento для PHP MVC разработчиков – разбор контроллера (ч.2/11)
- Magento для PHP MVC разработчиков – Макеты, Блоки и Шаблоны (ч.3/11)
- Magento для PHP MVC разработчиков – Модели и основы ORM (ч.4/11)
- Magento для PHP MVC разработчиков – Инсталлирование Ресурса (ч.5/11)
- Magento для PHP MVC разработчиков – Расширенный ORM – EAV (ч.6/11)
- Magento для PHP MVC разработчиков – Особая конфигурация системы (ч.7/11)
- Magento для PHP MVC разработчиков – Углубленная настройка системы (ч.8/11)
- Magento для PHP MVC разработчиков – Коллекции Varien Data (ч.9/11)
- Magento для PHP MVC разработчиков – Переопределение и обновляемость системы (ч.10/11)
- Magento для PHP MVC разработчиков – Конфигурация системы по умолчанию (ч.11/11)