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

 
 

Всі статті даної серії:

  1. Magento для PHP MVC розробників (Alan Storm) – ч.1/11
  2. Magento для PHP MVC розробників – розбір Контролера (ч.2/11)
  3. Magento для PHP MVC розробників – Макети, Блоки та Шаблони (ч.3/11)
  4. Magento для PHP MVC розробників – Моделі та основи ORM (ч.4/11)
  5. Magento для PHP MVC розробників – Інсталювання Ресурсу (ч.5/11)
  6. Magento для PHP MVC розробників – Розширений ORM – EAV (ч.6/11)
  7. Magento для PHP MVC розробників – Особлива конфігурація системи (ч.7/11)
  8. Magento для PHP MVC розробників – Поглиблене налаштування системи (ч.8/11)
  9. Magento для PHP MVC розробників – Колекції Varien Data (ч.9/11)
  10. Magento для PHP MVC розробників – Перевизначення і оновлюваність системи (ч.10/11)
  11. Magento для PHP MVC розробників – Конфігурація системи за замовчуванням (ч.11/11)