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)