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>.

Они определяют:

  1. Где загружается файл с изображением
  2. Базовый путь URI, который используется при воспроизведении тега <img>

 

Во-первых, давайте рассмотрим тег <upload_dir/>

<upload_dir config="system/filesystem/media" scope_info="1">sales/store/logo</upload_dir>

 

Здесь есть три основные вещи:

  1. Базовый путь для загрузки изображения
  2. Путь, от базового, по которому нужно загружать это конкретное поле изображения
  3. Следует ли добавлять текущую конфигурацию к пути

 

Путь к загрузке базового изображения устанавливается с помощью атрибута 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

 
 

 

Share

Последние посты

Сомерсет Моэм

Когда вы станете старше, вы поймете, что в мире можно хоть как-нибудь жить только при… Читать далее

27/03/2024

Михаил Грушевский

Все учатся своему родному языку, а наша беда такова, что нужно учить его больше, чем… Читать далее

26/03/2024

ТОП-5 надежных покерных обменников

Профессиональный покер – это многочисленные турниры и крупные суммы, что требует правильной настройки финансовых инструментов.… Читать далее

25/03/2024

Гай Юлий Цезарь

Все вокруг стремятся истребить врагов, но не объединиться с друзьями Гай Юлий Цезарь   Читать далее

24/03/2024

Как выбрать оптимальный смартфон для ребенка?

Сегодняшние дети сталкиваются с технологиями с самого раннего возраста, и смартфон уже давно перестал быть… Читать далее

22/03/2024

Выбираем электроскутер: важные критерии и характеристики

Лет 20 назад наблюдался пик популярности скутеров с двигателем внутреннего сгорания (ДВС). Маленькие, юркие, с… Читать далее

21/03/2024