Pull to refresh

Как я Magento изменял, или Меняем базовый функционал на простом примере

Reading time6 min
Views4.2K
При разработке интерфейса магазина передо мной стояла задача не просто привести все к нужному виду и логике, но и обеспечить обновление версий движка, поэтому редактирование основных програмных модулей я исключил сразу. В качестве платформы был выбран 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.

# 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. Прошу прощения за дикую смесь русских и английских комментариев — русские добавил по ходу написания статьи, для себя писал английские.
Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
+1
Comments4

Articles