Подальшій опис не слід розцінювати як рекламу VirtueMart (далі VM). Мені не доводилося займатися торгівлею, тому довелося витратити деякий час на дослідження готових рішень для інтернет-магазинів. З безкоштовних продуктів сподобалися OpenCart і VM. Остаточний вибір припав на другий варіант з кількох причин, одна з яких простота супроводу, бо мій сайт працює на Joomla! По-можливості, уважно розгляньте код цього додатка. Встановіть PHP 7 на свій локальний сервер і оцінить працездатність VM. Можливо, матеріал даної статті також допоможе вам прийняти остаточне рішення про те, який програмний продукт використовувати в своєму інтернет-магазині.

Установка VM вкрай проста, тому я пропускаю цей крок. Додам тільки, що сайт багатомовний, тому необхідно завантажити і встановити файли підтримки відповідних мов. Далі описується робота з версією VM 3.0.14.

ПРИМІТКА: після установки всіх мов визначте мову за замовчуванням в діалозі Joomla! 'Extensions → Languages', наприклад, English. Справа в тому, що кореневою мовою в VM є англійська, і тому що не всі пакети інтернаціоналізації повністю переведені, то в разі відсутності якоїсь трансляції, можна дозволити повідомлення англійською мовою. Взагалі-то підтримка багатомовності в VM має нюанси в деяких випадках, але про це пізніше.

Починаємо з діалогу Конфігурація (VirtueMart → Configuration), де обов'язково дозволимо встановлені мови:

VM Languages
На наступному кроці описуємо Магазин (VirtueMart → Shop). Діалог простий, але слід все ж зазначити, що розмір картинки логотипу вашої компанії, який буде відображатися на інвойсах, повинен бути в межах 200х38 пікселів і бажано в форматі 'GIF', хоча оголошені підтримуваними і інші формати. Формати інших зображень також бажано стандартизувати для свого сайту. Наприклад, для фотографій виробів я буду використовувати розмір 200 х 149, 96 точок на дюйм.

Після цього визначаємося з валютами, допустимими для магазину, і перш за все створюємо заміщення їх назв в діалозі 'Extensions → Languages ​​→ Overrides' як для адміністративної панелі, так і для сайту. Тепер необхідно відкрити 'VirtueMart → Currencies', знайти необхідну валюту і зробити наведене нижче:

VM Currency Setup

Слід мати на увазі, що для основної валюти магазину, яка буде використовуватися при вказівці цін на товари, поле 'Exchange Rate' повинно мати значення 0. У той же час, це поле обов'язково має бути заповнено для інших використовуваних валют:

VM Currency Setup USD

ПРИМІТКА: основна валюта повинна залишатися незмінною протягом існування магазину. Невикористані валюти можна заборонити для публікації або видалити:

VM Currencies

Тепер додаємо ці валюти в діалозі 'VirtueMart → Shop':

VM Shop Currencies

Як видно з малюнка заміщення відбулося, але при зміні мови залишається незмінним (див. Список вгорі ліворуч). В панелі адміністратора це терпимо. Але на стороні сайту підстановки взагалі не відбувається:

VM Currency Translation Fail

Виходячи з того, що це ймовірно буде надалі виправлено, я вирішив обійти проблему простою заміною словесного опису валюти на її 3-х символьний код в діалозі 'VirtueMart → Currencies'. Також можна видалити непотрібні тепер заміщення 'VM_CURRENCY ...', які були внесені в 'Extensions → Languages ​​→ Overrides'. При цьому, я видалив кнопку 'Change currency'. Для цього створив заміщення модуля 'mod_virtuemart_currencies' і вніс в код його файлу 'default.php' зміни, представлені на наступному малюнку:

VM Currency Selector Override

Колірна легенда:

Жовтий: код закоментований
Синій: змінено назву
Червоний: доданий код

ПРИМІТКА: докладніше про методику створення заміщень в статті 'Пидтрімка мікророзмітки 'Стаття' в Joomla! 3.x '

Тепер модуль 'VM-Currencies Selector' виглядає на сайті так: 

VM New Currency Selector

Далі визначаємо Виробників і Категорії, до яких вони належать. У моєму випадку виробник всього один:

VM Manufacturer
Тепер нам потрібно створити кореневу категорію товарів 'Electronics' і вкласти в неї 'Door Bells'. Для цього відкриваємо діалог 'Product Categories' і послідовно описуємо їх для кожної мови, що підтримується сайтом.

ПРИМІТКА: список мов з'являється після першого збереження кожної категорії, що відображено на наступному скріншоті. Надалі, кнопку 'Save' необхідно натискати для збереження опису категорії на кожній мові.

VM Product Category

В результаті отримуємо таку структуру:

VM Product Categories

Створимо опис якого-небудь продукту в категорію 'Door Bells'. Наприклад, кнопки дзвінка:

VM Product Button
Тепер можна створити пункт Магазин в Головному Меню Joomla! На своєму сайті я зазвичай розміщую модулі додаткових меню в правій частині екрана. У разі магазину тут буде розташовувано список категорій товарів.

ПРИМІТКА: на даний момент VM підтримує 2 рівня вкладень в модулі списку категорій.

Щоб надалі не опинитися в скрутному становищі, якщо раптом знадобиться додати рівень вкладення, створимо спливаюче меню для пункту виклику діалогу магазину. Для цього треба вказати тип пункту меню 'External URL' і в полі 'Link' внести символ '#', щоб при повторному натисканні на кнопку не відбувалося перезавантаження картинки:

VM StoreMenuButton

Додамо підлеглий пункт 'Electronics' і вкажемо для нього тип 'VM Category Layout'. Повторимо процедуру для всіх мов і в підсумку отримаємо наступну структуру:

VM Menu Category
Таким чином, у нас з'явилася можливість при необхідності легко додавати додаткові рівні в меню магазину, і не хвилюватися про вищезгаданому обмеження в модулі списку категорій.

І нарешті, створимо для кожної мови модуль типу 'VM Category', де виберемо категорію 'Electronics' як батьківську:

VM Category Module

Перевіримо результат нашої праці:

VM Menu Front
Загалом заготівля є і на цьому можна було б закінчити цю тему, щоб скоріше зайнятися розробкою і виготовленням самого виробу. Але ж нас цікавить не тільки продаж, але навіть більшою мірою виробництво. А так як перше і друге є похідною від зацікавленості і ступеня задоволення нами інтересів споживача, то важливо закласти міцний фундамент для підтримки автоматизації взаємодії замовника і виробництва на всіх етапах. Тому, давайте пригальмуємо і спробуємо створити будь-яке замовлення, або подивимося як воно виглядає в численних прикладах, люб'язно наданих розробниками VM. З корисних даних для вирішення поставленого завдання в описувачі замовлення буде тільки поле SKU (артикул) і номер замовлення. Отже, повернемося до картинки опису продукту і розглянемо уважніше поле 'Product SKU'.

ПРИМІТКА: існує думка, що не треба описувати всі властивості продукту в артикулі, тому що він призначений для обробки людиною. Для більшості магазинів з цим твердженням можна погодитися, хоча в загальному випадку допустимою вважається його довжина до 30 символів, що вже не мало. Але в даному випадку нас цікавить максимальна підтримка автоматизації власного виробництва на замовлення, а не перепродаж продукції сторонніх виробників.

Опис формату артикулу (SKU)

Спочатку розглянемо алфавіт, який ми будемо застосовувати. У загальному випадку, оператор магазина може перемикати розкладку клавіатури при введенні інформації, а також, наприклад, диктувати значення артикулу в телефонній розмові. З метою зменшення ймовірності помилок, необхідно обмежити набір допустимих символів. Наприклад, в разі тільки англомовного магазина, ми могли б залішити всі цифри, більшість спеціальних знаків, а також символи латинського алфавіту, крім наступних:

'I' тому що схожий на '1'
'O' тому що схожий на '0'

Але тому що наш магазин багатомовний, то обмеження буде жорсткіше. Дозволяємо всі цифри і символи латинського алфавіту, крім символів кирилиці, накреслення яких схоже на латинські. Зі спеціальних символів залишаемо тільки знак 'мінус' (-), який будемо використовувати для поділу груп символів. Таким чином, список дозволених символів буде наступним:

D, F, G, J, L, N, Q, R, S, U, V, W, Z,-,0...9

Область діяльності передбачуваного підприємства обмежується виробництвом виробів електроніки і програмного забезпечення, тому і артикул будемо розробляти відповідний. Формат артикулу будь-якого виробу буде складатися з заголовка (HD), а також 2-х необов'язкових груп Незалежних (IP) і Залежних Параметрів (DP), завжди розташовуються в наступному порядку:

HD → IP-DP

При цьому, між HD і IP роздільник відсутній, а DP завжди відокремлюється символом «-». Як випливає з назви, до групи Незалежних Параметрів можуть бути віднесені функції пристрою, які не впливають на вибір інших. У той же час, пристрій може містити, наприклад, взаємовиключні для конкретної моделі параметри, які повинні бути виділені в групу Залежних Параметрів.

HD - заголовок має наступну структуру:

Код продукту: 2 цифри
наприклад, кнопка дверного дзвінка: 01
Код моделі: 3 цифри
наприклад, модель 'Colibry': 001
Тип продукту: 1 символ або цифра:
D - Виріб Електроніки в зборі (наприклад, кнопка дзвінка)
R - Друкована Плата з установленими елементами до виробу
електроніки
Z - порожня Друкована Плата до виробу електроніки
S - Програмне Забезпечення

 

Таким чином, для одного Виробу Електроніки ми можемо, при необхідності, виділити замовлення запасний друкованої плати або програмного забезпечення.

ПРИМІТКА: хорошим тоном є наявність в заголовку префікса довжиною 2-3 символу, що відображає назву виробника. Наприклад, в моєму випадку можна було-б визначити його як 'APO'. Але, по-перше ці символи заборонені в нашому конкретному алфавіті, а по-друге, бажано щоб кількість символів в артикулі було мінімальним. Тому, я не використовую префікс.

IP - група Незалежних Параметрів для певного типу продукту

Розглянемо його на прикладі Вироби Електроніки (тип продукту «D» за нашою класифікацією), яке завжди оформлено в якийсь корпус:

Матеріал корпусу: 1 символ L – метал
S – пластик
W – дерево 
Колір корпусу: 1 символ або цифра D - білий
F
- чорний
R
- червоний
G
- зелений
L
- синій
N
- помаранчевий
Q
- сірий
V
- жовтий
Форма корпусу: 1 символ або цифра  R - прямокутник
G - дзвін
S - серце

DP - група Залежних Параметрів

Вона представляє останню частину структури артикулу, яку ми також розглянемо на прикладі Виробу Електроніки 'Кнопка Дверного Дзвінка':

Роздільник: 1 символ "-"
Підсвічування кнопки (колір): 1 символ U - відсутне
Z
- змінюеться програмно
R
- червоний
G
- зелений
Звук: 1 символ U - відсутний
Q
- пьезо-баззер (підходить для простих мелодій)
D
- динамік (для поліфонії)

 

Таким чином артикул 'Кнопки Дверного Дзвінка' моделі 'Colibry' з наступними характеристиками:

Матеріал Корпусу: Пластик
Колір корпусу: Червоний
Форма корпусу: Серце
Підсвічування: Відсутне
Звук: Пьезо

буде описаний 12-ю символами: 01001DSRS-UQ.

Чи можна зробити короткий артикул?

Начебто вкрай простий виріб і раптом таке довге визначення. Ми можемо спробувати скоротити його, якщо звернемося до двійковій системі числення, і перепишемо все вищезгадане в такій формі:

Код продукту: 7 бит
 
Код моделі продукту: 10 бит  
Тип продукту: 2 бита 00 - Виріб Електроніки в зборі (наприклад, кнопка дзвінка)
01
- Друкована Плата з установленими елементами до виробу
електроніки
10
- порожня Друкована Плата до виробу електроніки
11
- Програмне Забезпечення
Матеріал корпусу: 2 бита 01 – метал
10 – пластик
11 – дерево
Колір корпусу: 3 бита 000 - білий
001
- чорний
010
- червоний
011
- зелений
100
- синій
101
- помаранчевий
110
- сірий
111
- жовтий
Форма корпусу: 2 бита 00 – прямокутник
01 – дзвін
10 – серце
Роздільник (-) В ЦЬОМУ ФОРМАТІ НЕ ВИКОРИСТОВУЄМО
Підсвічування кнопки (колір): 3 бита 000 - відсутне
001
- змінюваний програмно
010
- білий
011
- червоний
100
- зелений
Звук: 2 бита 00 - відсутній
01
- пьезо-баззер (підходить для простих мелодій)
10
- динамік (для поліфонії)

 

Разом 31 біт, які можуть бути представлені у вигляді семи символів по модулю 16 (Hex-format), і тоді артикул нашої 'Кнопки Дверного Дзвінка' моделі 'Colibry' і кодом форми корпусу 0010 буде виглядати так: 1004941. Так, ми скоротили описатель на 5 символів (з яких один роздільник '-' не несе смислового навантаження). А тепер розглянемо інші сторони такого підходу:

  • Якщо в першому випадку можна з часом звикнути до формату, то скорочений варіант абсолютно не інформативний для людини
  • Hex-format включає символи 'A, B, C, E', які ми виключили з алфавіту артикулу для нашого багатомовного сайту. Значить доведеться використовувати модуль 8, який дасть тільки числове уявлення. Це може здатися навіть зручним, але збільшить розмір артикулу. Для нашого прикладу код перетвориться в 100044501. Тобто скорочення складе вже не 5, а 3 символі.
  • При описі різноманітних продуктів в VM, нам доведеться багато разів заповнювати SKU для кожного варіанту, що в разі бітових полів напевно буде приводити до множинних помилок. Символьний формат тут явно виграє.
  • Цілком ймовірно, що нам доведеться самостійно складати запити до бази даних VM, які будуть простіши і зрозуміліши, якщо застосовувати символьний формат.
  • Для автоматизації обробки замовлень нам потрібен буде спеціалізований програмний парсер, скануючий замовлення на помилки в SKU, а також розподіляє його по процесам виготовлення виробу (вибір друкованої плати, комплектуючих і пошук кращого на даний момент постачальника комплектуючих, компіляція програмного забезпечення відповідно до вимог замовлення і т. д.). У разі бінарного варіанту, нам необхідно буде створювати його самостійно. Для символьного ж варіанту досить, наприклад, скласти JSON-схему необхідного артикулу, і обробити його стандартним парсером.

Таким чином я зупиняю вибір на первинному варіанті опису артикулу.

Реалізація підтримки SKU

Варіант №1

ПРИМІТКА: не поспішайте повторювати описувані події

Повернемося до створеного раніше описателю продукту 'Button' і внесемо такі зміни:

  • Змінимо назву на 'Root-Door Bell Button-Colibry', тим самим визначивши цей продукт кореневим, тому що передбачається виготовлення кнопок різних типів. При цьому словосполучення 'Root-' спеціально поставлено на початку, щоб в подальшому легко знаходити все кореневі описатели інших виробів сортуючи або фільтруючи список по полю 'Product Name'.
  • В поле SKU внесемо Постійне Значення Заголовка '01001D', яке вказує на те, що це 'Виріб Електроніки' з групи 'Door Bell Button', модель якого має ідентифікатор 'Colibry'. Таким чином, ми створили 2 пари 'назва - цифровий ідентифікатор' (01-Door Bell Button і 001-Colibry), що дозволяє в подальшому легко автоматизувати необхідні перевірки при виробництві, і в той же час не утруднює читання інформації людиною.
  • Знімемо позначку з чекбокса 'Published' тому що цей кореневої продукт містить не повний описатель і немає сенсу публікувати його, а значить і переводити описатель на різні мови також не потрібно. У закладці 'Product Status' вкажемо кількість товару рівним 0 (поле 'In Stock'). Зауважимо, що при цьому його 'Product Alias' також буде виключений з URL, але ціна буде входити в розрахунок вартості похідних продуктів. Тому, тут можна вказати деяку постійну частину вартості товару, яка буде присутня в будь-якому продукті, похідному від даного кореневого.

Таким чином, опис батьківського продукту буде мати наступний вигляд:

VM Real Product Button

Тепер ми можемо створювати описатели реальних продуктів, похідних від даного. У цьому ж діалозі натиснемо кнопку 'Add a Child Product' і створимо такий опис:

VM Product Child
Змінимо значення в полях 'Product Name' для кожної мови, а також відзначимо чекбокс 'Published'. Зверніть увагу, я присвоїв коротку назву аліасу, тому що VM автоматично додає до нього суфікс '-detail' і це треба враховувати, щоб не перевищити допустиму довжину URL, а також намагатися робити його осмисленим. Таким чином, відносний адреса опису даного продукту англійською мовою буде виглядати наступним чином:

'/en/store/electronics/bells/colibry-detail'

Також я залишив порожніми поля, що стосуються ціни цього дочірнього продукту. Справа в тому, що якщо заповнити їх тут, то VM НЕ буде додавати до загальної вартості базове значення, яке ми вказали для батьківського продукту. У той же час, VM буде це робити якщо ми введемо додаткові користувальницькі поля, за допомогою яких зможемо гнучко варіювати ціну. Як бачите я теж не заповнив поле 'Product SKU', тому що в даному випадку воно не фіксоване і його наповнення залежить від вибору користувача.

Отже, нам необхідно знайти зручні штатні засоби VM для:

  • ВИРОБНИЦТВА, щоб легко описувати різноманітні варіанти своїх виробів
  • ПОКУПЦЯ, щоб він міг легко вказати свої індивідуальні вимоги до товару з різноманітності, пропонованого нашим виробництвом

Ще раз розглянемо список з 5-ти параметрів, значення яких нам необхідно бачити в артикулі і якими користувач повинен мати можливість керувати при замовленні «Кнопки дзвінка»:

  • Матеріал корпусу (3 варіанти)
  • Колір корпусу (8 варіантів)
  • Форма корпусу (3 варіанти)
  • Підсвічування (4 варіанти)
  • Звук (3 варіанти)

Загальна кількість варіантів 3 х 8 х 3 х 4 х 3 = 864!

VM пропонує зручну можливість створювати різноманітні користувацькі поля за кількістю параметрів до 5-ти. Але в даному випадку нам це не підходить, тому що занадто велике кількість варіантів. Трудомістким в плані реалізації представлені також створення ієрархічних списків описателей дочірніх продуктів. Адже нам потрібно не тільки створити описатели, а й відображати різноманітні залежності в ціні кінцевого продукту, при цьому генеруючи необхідний SKU.

Варіант №2

Розділимо наші параметри на 2 групи:

Незалежні (IP)

  • Матеріал корпусу
  • Колір корпусу
  • Форма корпусу

Залежні (DP)

  • Підсвічування
  • Звук

Для кожної IP-групи створимо приховану Custom Fields Group. Наприклад, для «Матеріалу корпусу» вона буде такою:

VM CustomField Group
У кожну подібну групу вкладемо 2 призначених для користувача поля:

1. видиме типу «string» для відображення списку варіантів користувачеві

VM CustomField String

2. невидиме типу «property», для зберігання патерну SKU, що відповідає даній групі

VM CustomField Property

Для DP-групи створимо стандартне видиме мультиваріантне поле:

VM CustomField Multivariant
ПРИМІТКА: зверніть увагу, що заголовки видимих груп визначені у вигляді багатомовних заміщень, створення яких описано раніше.

На наступному скріншоті представлена частина списку створених груп Полів Користувача:

VM CustomFields

Тепер можна створити описувач продукту. Для цього в діалозі 'Products' натиснемо кнопку 'New' і опишемо, наприклад, базовий варіант кнопки «Colibry»:

VM Button Colibry
Зверніть увагу на заповнення поля 'Product SKU'. Тут немає даних про матеріал, колір і форму корпусу, але є відомості про відсутність звуку і підсвічування в даному варіанті кнопки. Зберігаємо цю форму (англійську) і редагуємо для кожної мови.

Ну ось і настав час застосувати наші Групи Користувальницьких Полів. Відкриємо відповідну закладку на цій же формі і виберемо групу або поле зі списку, підготовленого нами раніше. Я вибрав першим мультиваріантне поле, яке дозволяє описати обмеження зі спільного застосування звуку і підсвічування, хоча логічніше було б вказати його останнім. Справа в тому, що обробка застосовуваних нами різноманітних списків і списків типу «string» виконана в коді VM різними, і на мій погляд дещо конфліктуючими способами, що призводить до скидання покажчиків у всіх списках типу «string» при оновленні сторінки або зміні елемента вибору в розташованому на цій же сторінці мультиваріантному полі. Якщо списків на сторінці кілька, то це можна не відразу помітити і в підсумку збити користувача з пантелику, коли він натисне кнопку «Помістити в кошик». Я повідомив про це розробникам VM, ну а поки з цієї причини поставив мультиваріантне поле першим в списку в надії, що користувач працює з полями в напрямку зверху-вниз. Нижче показаний приклад заповнення такого поля:

VM ProductMultivariantField
Як бачите, воно додано 2 рази для підтримки описателей звуку і підсвічування. При цьому, списки кількості варіантів значно скорочені для даної моделі (по 2 на кожен параметр). Зверніть увагу, що для будь-якого виду вказується саме ціна, а не зміна до базової ціни і розширення поля «Product SKU» заповнюється в суворій відповідності з описаним раніше шаблоном, і тільки щодо DP-групи.

Далі додаємо елементи IP-групи:

VM ProductStringField
Як бачите дана модель виробу має тільки один тип матеріалу корпусу (VM_ED_BODY_PLASTIC) і ми могли б взагалі не вводити сюди список. Але тому що поруч на сторінці товарів може бути показаний інший тип кнопки, який має розширений список матеріалів (пластик, метал і т.д.), то на мій погляд відмінність в подачі інформації може збити покупця з пантелику. Далі ми бачимо опис 3-х варіантів кольору, два з яких додають до ціни виробу 5 одиниць вартості.

Повернемося до головного. У кожної подібної групи присутнє спеціальне поле типу «Property», вміст якого призначен для вказівки місця розташування і людино-читабельною подання даної частини в загальному паттерне SKU. Таким чином, наприклад, значення «2-D» призначає матеріалу VM_ED_BODY_WHITE символ «D» в паттерне SKU, який повинен бути розміщений другим в IP-частини патерну SKU даного типу продукту.

Відкриємо, фінальний список «Products» щодо нашої кнопки типу «Colibry» - всього 4 позиції:

VM ProductsList
Це тому що ми визначили для неї наступний список варіантів:

  • Матеріал корпусу (1 варіант)
  • Колір корпусу (4 варіанти)
  • Форма корпусу (1 варіант)
  • Підсвічування (2 варіанти)
  • Звук (2 варіанти)

Загальна кількість варіантів 1 х 4 х 1 х 2 х 2 = 16. Але, тому що загальна кількість продуктів в списку визначається полями в різноманітної групі, то їх у нас всього 4. Таким чином, для підтримки всіх 864 варіантів, визначених раніше, нам знадобиться описати всього 12 продуктів, тому що:

  • Підсвічування (4 варіанти)
  • Звук (3 варіанти)

Для покупця картинка також не рясніє різноманіттям варіантів груп і дочірніх підгруп, що дозволяє йому зосередитися на виборі необхідних функцій. Звичайно ж, медіа-елементи будуть присутні, але не нав'язливо:

VM ProductButtonColibry

Спробуємо оформити замовлення:

VM OrderError
Як бачимо інформації досить для того, щоб покупець міг переконатися, що всі замовлені властивості підтверджені в словесній формі, і за великим рахунком йому не має значення як виглядає SKU. Для нас же його точне оформлення вкрай важливо, тому що у нас немає співробітників, які читали б кожне замовлення і планували його виконання, розбиваючи на підпроцеси. Тому, необхідно створити заміщення коду VM, яке обробить описані раніше поля типу «Property», і автоматично модифікує SKU відповідним чином в момент оформлення замовлення. На перший погляд це можна зробити в коді компонента, зазначеного на наступному скріншоті:

VM TemplateCart
Невеликий відступ щодо правила, якому я намагаюся слідувати в разі необхідності внесення змін у сторонній код:

«Код заміни або доповнення повинен бути максимально коротким і бажано оформлений в один цілісний блок (тобто бути присутнім тільки в одному місці)»

Це дозволить в подальшому уникнути ситуацій, подібних показаної в гуморесці, де співак приніс на концерт свої ноти, але вони в такому стані, що піаніст не може розібратися в різноманітті позначок «тут грати, а тут не грати»

Piano

На жаль, мені не вдалося знайти в цьому компоненті місця, яке відповідає вказаному правилу внесення змін. Довелося зробити це в коді ядра VM і тому що це не стандартне рішення, то приводити його тут не стану. Скажу тільки, що додаток зроблено у вигляді одного короткого блоку коду, який в підсумку дозволяє правильно показати користувачеві всю інформацію, включаючи SKU:

VM OrderOk

На жаль, VM не робить підстановку багатомовних визначень при показі замовлень адміністратору, але в даному випадку це не велика проблема:

VM OrdersError
Отже, представлений підхід до опису продукту дозволяє:

  • оформляти структуру SKU в єдиному стандартному діалозі VM
  • легко змінювати порядок елементів в паттерне SKU і їх значення, незалежно від фізичного розміщення списків на формі
  • максимально виключити помилки при описі продукту, тому що SKU заповнюється автоматично при оформленні замовлення
  • поєднувати в описувач товару велику кількість списків різного типу
  • значно зменшити трудовитрати на опис різних варіантів продукту і його метатегов

Емуляція поштового агента

При підтвердженні замовлення, VM відправляє електронні листи покупцеві і продавцеві. Оскільки ми ведемо розробку на локальному сервері, то в цей момент відбудеться помилка відправки пошти. Необхідно самостійно встановити і налаштувати відповідне програмне забезпечення. У разі Linux це зазвичай 'sendmail'. Але я для цієї мети використовую найпростіший емулятор невідомого програміста, який знайшов в коментарях до однієї зі статей в Інтернеті. Ось його код:

#!/bin/sh
prefix="/var/www/sendmail"
date='date \+\%Y\%m\%d\%H\%M\%N'

name="$prefix/$date.eml"
while IFS=read line
do
   echo "$line" >> $name
done
chmod 666 $name

Помістіть його в файл, наприклад, під назвою 'fake_sendmail.sh' і збережіть в директорії '/usr/sbin/sendmail', присвоївши йому атрибут 'executable'. Створіть директорію 'sendmail' як зазначено в змінної 'prefix' коду. Вкажіть значення шляху до даного файлу 'sendmail' в 'php.ini':

sendmail_path = /usr/sbin/sendmail/fake_sendmail.sh

Відкрийте закладку 'Server' в діалозі Joomla! 'Global Configuration', і виберіть 'Sendmail' в якості поштового агента:

VM Mailer


Тепер поштові повідомлення будуть зберігатися в директорії 'sendmail' і їх можна переглядати стандартними засобами. Наприклад, так виглядає лист підтвердження відправки замовлення в 'Thunderbird Mail':

VM Order Shipped
Инструменти і документи

Операційна система: Linux (наприклад http://www.ubuntu.com/download)
Програми: LAMP (наприклад https://bitnami.com/stack/lamp)
CMS Joomla! (https://www.joomla.org/)
VirtueMart (http://extensions.joomla.org/extensions/extension/e-commerce/shopping-cart/virtuemart)
Опціонально: Netbeans (https://netbeans.org/downloads/)
Додаткове читання:

Apache HTTP Server (https://httpd.apache.org/docs/2.4)
MySQL (http://dev.mysql.com/doc)
MariaDB (https://mariadb.com/kb/en/mariadb/documentation/)
PHP (http://php.net/manual/en/index.php)
JavaScript (https://www.javascript.com/resources)
jQuery (https://jquery.com/)
The Linux Command Line (http://sourceforge.net/projects/linuxcommand/files/TLCL/13.07/TLCL-13.07.pdf/download)