При разработке интерфейса магазина передо мной стояла задача не просто привести все к нужному виду и логике, но и обеспечить обновление версий движка, поэтому редактирование основных програмных модулей я исключил сразу. В качестве платформы был выбран Magento, который, как оказалось, предоставляет отличные средства для разработки собственных расширений, в том числе возможность замены стандартного функционала собственным. Этим мы и займемся.
Давайте рассмотрим конкретный пример. В большинстве магазинов копейки сейчас никто не использует, но по умолчанию — благодаря локали — они отображаются. Встала задача их убрать. Как выяснилось, можно сделать это простым редактированием компонента библиотеки Zend, но, во-первых, это противоречит первому предложению данного поста, а, во-вторых, мы же не ищем легких путей. :)
Итак, нам необходимо сделать следующее:
— переопределить класс, отвечающий за вывод форматированной цены;
— создать модуль, который будет этот класс содержать;
— сконфигурировать модуль так, чтобы переопределенный класс вызывался в случаях, при которых ранее активировался оригинальный класс;
— активировать новый модуль в системе.
Все приведенные пути относительны директории, в которую установлен Magento.
Как я уже говорил, Magento представляет хорошие возможности для разработки собственных модулей и расширения базового функционала. Основная часть рабочего кода системы (за исключением библиотек и фреймворков, на основе которых он написан) расположена в директории app. Если мы заглянем внутрь, то увидим там следующее содержимое:
app
|----- Mage.php
|----- code
|----- design
|----- etc
|----- locale
Mage.php — модуль, описывающий основной класс-хаб системы — Mage
code — весь код
design — как видно из названия, здесь располагаются описания дизайна: именно логика и шаблоны вывода блоков; описания непосредственно css-стилей, скрипты и картинки вынесены в отдельное место
etc — конфигурационные файлы
locale — базовые языковые файлы, или, другими словами, локализация вывода; под конкретный интерфейс локализованный вывод так же может быть частично или полностью переопределен в описаниях собственного интерфейса в поддиректориях design.
Для данной задачи нас интересует директория code. В ней мы видим три стандартные папки: core — содержит код основных модулей системы, а так же community и local, которые изначально пусты и предназначены для установки сторонних модулей (community) либо для разработанных самостоятельно (local). На самом деле различий между папкими никаких нет, но для удобства собственные модули будем складывать в папку local.
Итак, для начала нам нужно создать папку, которая будет содержать наши модули. Название этой папки будет являться названием пакета (package) модулей, которые мы разработам. Т.к. я разрабатывал модули под свой проект, папка у меня носит имя проекта — Cifrum.
Далее необходимо создать директорию, в которой будет находится модуль, одним из классов которого мы и будем реализовывать необходимую функциональность. Стандартный модуль, отвечающий за форматирование цены, называется Core, поэтому я назвал свой CoreC.
Создайте следующую структуру директорий:
Приведенный в конце список папок — стандартная структура модуля. Я не буду здесь подробно останавливаться на описании, если необходимо, вы можете ознакомиться с книгой php|architect’s Guide to Programming with Magento.
В данном случае нас будут интересовать две директории — это etc, в которой мы расположим файл config.xml, и Model, где и будет располагаться описание нашего класса.
Выводом форматированной цены занимается модуль Core, а конкректо класс Store, метод formatPrice(). Нам необходимо создать новый класс — наследник Mage_Core_Model_Store и переопределить его метод.
Давайте создадим файл Model/Store.php со следующим содержимым:
Давайте рассмотрим конкретный пример. В большинстве магазинов копейки сейчас никто не использует, но по умолчанию — благодаря локали — они отображаются. Встала задача их убрать. Как выяснилось, можно сделать это простым редактированием компонента библиотеки Zend, но, во-первых, это противоречит первому предложению данного поста, а, во-вторых, мы же не ищем легких путей. :)
Итак, нам необходимо сделать следующее:
— переопределить класс, отвечающий за вывод форматированной цены;
— создать модуль, который будет этот класс содержать;
— сконфигурировать модуль так, чтобы переопределенный класс вызывался в случаях, при которых ранее активировался оригинальный класс;
— активировать новый модуль в системе.
Все приведенные пути относительны директории, в которую установлен Magento.
Как я уже говорил, Magento представляет хорошие возможности для разработки собственных модулей и расширения базового функционала. Основная часть рабочего кода системы (за исключением библиотек и фреймворков, на основе которых он написан) расположена в директории app. Если мы заглянем внутрь, то увидим там следующее содержимое:
app
|----- Mage.php
|----- code
|----- design
|----- etc
|----- locale
Mage.php — модуль, описывающий основной класс-хаб системы — Mage
code — весь код
design — как видно из названия, здесь располагаются описания дизайна: именно логика и шаблоны вывода блоков; описания непосредственно css-стилей, скрипты и картинки вынесены в отдельное место
etc — конфигурационные файлы
locale — базовые языковые файлы, или, другими словами, локализация вывода; под конкретный интерфейс локализованный вывод так же может быть частично или полностью переопределен в описаниях собственного интерфейса в поддиректориях design.
Для данной задачи нас интересует директория code. В ней мы видим три стандартные папки: core — содержит код основных модулей системы, а так же community и local, которые изначально пусты и предназначены для установки сторонних модулей (community) либо для разработанных самостоятельно (local). На самом деле различий между папкими никаких нет, но для удобства собственные модули будем складывать в папку local.
Итак, для начала нам нужно создать папку, которая будет содержать наши модули. Название этой папки будет являться названием пакета (package) модулей, которые мы разработам. Т.к. я разрабатывал модули под свой проект, папка у меня носит имя проекта — Cifrum.
# pwd
/<Path To Magento>/app/code
# ll -a
total 10
drwxrwxr-x 5 vlad www 512 18 апр 09:37 .
drwxrwxr-x 6 vlad www 512 29 апр 19:30 ..
drwxrwxr-x 3 vlad www 512 29 апр 19:30 community
drwxrwxr-x 4 vlad www 512 18 апр 09:37 core
drwxrwxr-x 3 vlad www 512 27 апр 02:37 local
# ll -a local
total 6
drwxrwxr-x 3 vlad www 512 27 апр 02:37 .
drwxrwxr-x 5 vlad www 512 18 апр 09:37 ..
drwxrwxr-x 6 vlad www 512 29 апр 23:48 Cifrum
Далее необходимо создать директорию, в которой будет находится модуль, одним из классов которого мы и будем реализовывать необходимую функциональность. Стандартный модуль, отвечающий за форматирование цены, называется Core, поэтому я назвал свой CoreC.
Создайте следующую структуру директорий:
# ll -1aR /<Path To Magento>/app/code/local/
.
..
Cifrum
/<Path To Magento>/app/code/local/Cifrum:
.
..
CoreC
/<Path To Magento>/app/code/local/Cifrum/CoreC:
.
..
Block
Helper
Model
controllers
etc
sql
Приведенный в конце список папок — стандартная структура модуля. Я не буду здесь подробно останавливаться на описании, если необходимо, вы можете ознакомиться с книгой php|architect’s Guide to Programming with Magento.
В данном случае нас будут интересовать две директории — это etc, в которой мы расположим файл config.xml, и Model, где и будет располагаться описание нашего класса.
Выводом форматированной цены занимается модуль Core, а конкректо класс Store, метод formatPrice(). Нам необходимо создать новый класс — наследник Mage_Core_Model_Store и переопределить его метод.
Давайте создадим файл Model/Store.php со следующим содержимым:
<?php
/*****
Trying to rewrite Core_Model_Store
*/
// Описываем новый класс, наследующий стандартный класс, контролирующий работу с ценой
// app/code/core/Mage/Core/Model/Store.php
class Cifrum_CoreC_Model_Store extends Mage_Core_Model_Store
{
/**
*
* formatPrice without decimals, for rubles only for right now
*
*/
// Переопределяем функцию, форматирующую вывод
public function formatPrice($price, $includeContainer = true)
{
if($this->getCurrentCurrency()) {
$priceReturn = $this->getCurrentCurrency()->format($price, array(), $includeContainer);
//Not the cleanest method but the fastest for now…
if(preg_match('/руб/i', $priceReturn)) {
return $this->getCurrentCurrency()->format($price, array('precision' => 0), $includeContainer);
} else {
return $priceReturn;
}
}
return $price;
}
}
?>
* This source code was highlighted with Source Code Highlighter.
Как видно, мы берем код стандартной фукнции Mage_Core_Model_Store::formatPrice() и дописываем проверку на вхождение в строку подстроки “руб”. Не уверен, что будет работать на всех локалях (быть может, где-то фигурирует просто “р"), однако у меня работает.
Теперь нам необходимо указать, что же именно нужно делать с созданным нами классом. Для этого создаем etc/config.xml и наполняем его следующим:
<?xml version="1.0"?>
<config>
<modules>
<!-- Описание нашего модуля - название, версия, зависимости -->
<Cifrum_CoreC>
<version>0.0.1</version>
<depends>
<!-- no dependencies -->
</depends>
</Cifrum_CoreC>
<!-- -->
</modules>
<global>
<models>
<!-- а вот здесь мы переопределяем -->
<!-- стандартный класс на наш с помощью тэга <rewrite> -->
<core>
<rewrite>
<store>Cifrum_CoreC_Model_Store</store>
</rewrite>
</core>
<!-- -->
</models>
<resources></resources>
<blocks></blocks>
<corec>
<!-- config values -->
</corec>
</global>
<adminhtml>
<menu></menu>
<acl></acl>
<events></events>
<translate></translate>
</adminhtml>
<frontend>
<routers></routers>
<events></events>
<translate></translate>
<layout></layout>
</frontend>
<default>
<config_vars>
<!-- config values -->
</config_vars>
</default>
</config>
* This source code was highlighted with Source Code Highlighter.
Опять-таки, структура файла стандартная, нам нужно не все. Важные моменты я выделил комментариями. Вначале описываем название и версию нашего модуля, а ниже переопределяем с помощью тега <rewrite> системный вызов класса store модуля core.
Однако это не все. Нам нужно указать системе, что у нас есть новый модуль, активировать его.
Как вы помните, системные конфиги лежат в app/code/etc. Создаем и открываем файл app/etc/modules/Cifrum_All.xml, который в моем случае содержит описание всех модулей пакета Cifrum.
<?xml version="1.0"?>
<config>
<modules>
<Cifrum_CoreC>
<active>true</active>
<codePool>local</codePool>
</Cifrum_CoreC>
</modules>
</config>
* This source code was highlighted with Source Code Highlighter.
На этом, собственно, все. Обновив страницу магазина, мы увидим, что десятые части рублей исчезли.
Если есть вопросы или уточнения — пишите, с удовольствием пообщаюсь.
P.S. Прошу прощения за дикую смесь русских и английских комментариев — русские добавил по ходу написания статьи, для себя писал английские.