📜 ⬆️ ⬇️

How I changed Magento, or Change basic functionality with a simple example

When developing the store interface, I was faced with the task of not just bringing everything to the desired form and logic, but also providing for updating the engine versions, so I excluded editing the main software modules right away. Magento was chosen as a platform, which, as it turned out, provides excellent tools for developing your own extensions, including the ability to replace the standard functionality with your own. This is what we will do.

Let's look at a specific example. In most stores, no one uses a penny now, but by default, thanks to the locale, they are displayed. There was a task to remove them. As it turned out, you can do this by simply editing the component of the Zend library, but, first, it contradicts the first sentence of this post, and, second, we are not looking for easy ways. :)


')
So, we need to do the following:
- override the class responsible for outputting a formatted price;
- create a module that will contain this class;
- configure the module so that the overridden class is called in cases in which the original class was previously activated;
- activate a new module in the system.

All paths listed are relative to the directory in which Magento is installed.

As I already said, Magento represents good opportunities for developing your own modules and extending the basic functionality. The main part of the working system code (with the exception of the libraries and frameworks on which it is written) is located in the app directory. If we look inside, we will see the following contents there:

app
| ----- Mage.php
| ----- code
| ----- design
| ----- etc
| ----- locale

Mage.php - a module describing the main class hub of the system - Mage
code - all code
design - as the name implies, here are the descriptions of the design: it is the logic and output patterns of the blocks; descriptions of css-styles directly, scripts and images are moved to a separate place
etc - configuration files
locale - basic language files, or, in other words, localization of output; for a specific interface, localized output can also be partially or completely redefined in the descriptions of its own interface in the design subdirectories.

For this task, we are interested in the code directory. In it, we see three standard folders: core - contains the code for the main modules of the system, as well as community and local , which are initially empty and are designed to install third-party modules (community) or for those developed independently ( local ). In fact, there are no differences between folders, but for convenience, we will add our own modules to the local folder.

So, first we need to create a folder that will contain our modules. The name of this folder will be the name of the package (package) of modules that we will develop. Because I developed modules for my project, my folder is named after the project - 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


Next you need to create a directory in which the module will be located, one of the classes of which we will implement the necessary functionality. The standard module responsible for formatting prices is called Core, so I called my CoreC.

Create the following directory structure:

# 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


The folder list at the end is a standard module structure. I will not elaborate on the description here; if necessary, you can read the book php | architect's Guide to Programming with Magento .

In this case, we will be interested in two directories - this is the etc , in which we will place the config.xml file, and the Model , where the description of our class will be located.

The Core module deals with formatted pricing, and the Store class, formatPrice () method. We need to create a new class - a successor of Mage_Core_Model_Store and override its method.

Let's create a Model / Store.php file with the following contents:

<?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 .
<?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 .
<?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 .



As you can see, we take the standard function code Mage_Core_Model_Store :: formatPrice () and add a check to include the string “rub” in the string. I'm not sure that it will work on all locales (maybe, somewhere, it’s just “p”), but it works for me.

Now we need to specify what exactly needs to be done with the class we created. To do this, create etc / config.xml and fill it with the following:

<? 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 .
<? 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 .
<? 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 .



Again, the file structure is standard, we do not need everything. I highlighted the important points with comments. First, we describe the name and version of our module, and below we use the <rewrite> tag to redefine the system call to the core module's store class.

However, this is not all. We need to tell the system that we have a new module, activate it.
As you remember, system configs are in app / code / etc. We create and open the app / etc / modules / Cifrum_All.xml file , which in my case contains a description of all the modules of the Cifrum package.

<? 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 .
<? 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 .
<? 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 .



On this, in fact, everything. By updating the store page, we will see that tenths of rubles have disappeared.

If you have any questions or clarifications - write, happy to talk.

PS I apologize for the wild mix of Russian and English comments - Russians added while writing this article, I wrote English for myself.

Source: https://habr.com/ru/post/63902/


All Articles