It may well be that our online catalogue is not updated yet. We have a vast network of ingredients, our supply chain team will be happy to entertain any ingrendient enquiry.
When developing an online store based on Magento 2, you might face the problem of extending the standard Magento 2 or Magento extensions functionality.
Editing Magento core files or modules is not allowed because these changes will be overwritten during the .
So, how to make changes to the storefront (frontend) template file, css, js?
WARNING! The following instructions cannot be used to override the layout files.
Override module view-files in the app/code folder.
Let's say you need to change this file:
app/code/Magefan/Blog/view/frontend/templates/post/view.phtml
Make its copy in the theme folder with the following path:
app/design/frontend/ThemeVendor/themename/Magefan_Blog/templates/post/view.phtml
Make the necessary changes to the newly created theme file.
If your own theme is missing from your Magento installation, create new theme.
Override module view-files in the vendor folder.
Let's say you need to change this file:
vendor/magefan/module-blog/view/frontend/web/css/blog-custom.css
If you want to change type from dropdown to text in Magento 2, all you need to do is to run the following SQL queries (please make a Database backup before execution):
1. This query will change the attribute settings and convert it to a text attribute.
UPDATE eav_attribute SET backend_type = "varchar", frontend_input = "text", source_model = ""WHERE attribute_code = "MY_ATTRIBUTE_CODE";
2. This query will copy dropdown attribute data to the text attribute value table and replace the option IDs with their actual labels (text).
INSERT INTO catalog_product_entity_varchar SELECT null as value_id, pei.attribute_id, pei.store_id, pei.entity_id, aov.value as value FROM catalog_product_entity_int pei LEFT JOIN eav_attribute_option ao ON pei.attribute_id = ao.attribute_id LEFT JOIN eav_attribute_option_value aov ON ao.option_id = aov.option_id WHERE pei.value IS NOT NULL AND pei.attribute_id = (SELECT attribute_id FROM eav_attribute WHERE attribute_code = "MY_ATTRIBUTE_CODE") AND aov.store_id =
Sometimes, during Magento 2 customization you need to get the store Information programmatically. You may need to get a current Store ID, Store Code, Name, Website ID, or .
To retrieve this data use the singleton instance of the following class:
\Magento\Store\Model\StoreManagerInterface
For example, you can include it in your class constructor and then call:
<?phpnamespace \MyCompany\ExampleModule\Model;class Example{ private $storeManager;
public function __construct(
...
\Magento\Store\Model\StoreManagerInterface $storeManager,
...
) { ...
$this->storeManager = $storeManager;
...
}
/** * Examples */ public function execute() { /* Get Current Store ID */ $storeId = $this->storeManager->getStore()->getId(); /* Get Current Store Code */ $storeCode = $this->storeManager->getStore()->getCode(); /* Get Current Store Name */ $storeName = $this->storeManager->getStore()->getName();
Get URL in the .phtml template files
1. Get URL of the store homepage (http://domain.com/):
<?= $this->getUrl() ?>
2. Get URL of some page, e.g. "Contact Us" (http://domain.com/contacts/):
<?= $this->getUrl('contacts') ?>
3. Get URL of the theme static file, e.g.:
app/design/frontend/ThemeVendor/theme_name/web/css/custom.cssapp/design/frontend/ThemeVendor/theme_name/Magefan_Blog/web/js/lazyload.jsapp/code/Magefan_Blog/view/frontend/web/js/lazyload.jsvendor/magefan/module-blog/view/frontend/web/js/lazyload.js
use the following code:
<?= $this->getViewFileUrl('css/custom.css') ?><?= $this->getViewFileUrl('Magefan_Blog::js/lazyload.js') ?>
4. Get URL of the static file in pub/media:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();$mediaUrl = $objectManager->get(Magento\Store\Model\StoreManagerInterface::class) ->getStore() ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
<?= $mediaUrl ?>wysiwyg/image.png
Attention! You should not use media files in the theme
The etc/adminhtml/menu.xml file is used to control the Magento 2 admin panel menu and add new items to it, in particular.
Create this file in , to add new menu element:
etc/adminhtml/menu.xml
and add the following code there:
<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd"> <menu> <add id="VendorName_ModuleName::key1" title="Title 1" module="VendorName_ModuleName" parent="OtherVendorName_OtherModuleName::content" sortOrder="10" resource="VendorName_ModuleName::key1"/> <add id="VendorName_ModuleName::key2" title="Title 2" module="VendorName_ModuleName" parent="VendorName_ModuleName::key1" sortOrder="10" action="path/controllerName" resource="VendorName_ModuleName::key2"/> </menu></config>
id - a unique ;title - text of the element;module - defines what module the element belongs to;parent - identifier of the parent menu item;sortOrder
In the we described how to create your own section on the Magento 2 configuration page (Stores > Configuration).
In order to set the default values for the configuration fields, you need to create the following file in the :
etc/config.xml
and add this code:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> <default> <section_id> <group_id> <field_id>default_value</field_id> </group_id> </section_id> </default></config>
The section_id/group_id/field_id hierarchy has to match the structure in the system.xml file.
To clear the cache, run the CLI command:
php bin/magento cache:clean
Check the result.
In the examples, we create a module for FAQ. The modified module code can be viewed on GitHub.
In the we explained how to configure and delimitate access rights for the Magento 2 admin panel users. In this article, you will learn how to create your own access rules (Role Resources).
You need to create ACL file (ACL - Access Control List) in your :
etc/acl.xml
add the following code there:
<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd"> <acl> <resources> <resource id="Magento_Backend::admin"> <resource id="Magento_Backend::content"> <resource id="VendorName_ModuleName::key1" title="Title 1" sortOrder="10"> <resource id="VendorName_ModuleName::key2" title="Title 2" sortOrder="10" /> </resource> </resource> <resource id="Magento_Backend::stores"> <resource id="Magento_Backend::stores_settings">
To find the Magento 2 configuration page navigate to Magento 2 Admin Panel > Stores > Configuration.
All tabs and forms on this page are customized using this file
etc/adminhtml/system.xml
that the majority of contains.
Add the following code to the system.xml file in your module to create your custom section:
<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> <system> <tab id="tab_id" translate="label" sortOrder="110"> <label>My Tab</label> </tab> <section id="section_id" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1"> <class>separator-top</class> <label>My Section</label> <tab>tab_id</tab> <resource>VendorName_ModuleName::acl_path</resource> <group id="group_id" translate="label" type="text" sortOrder="10"
To add a new table to the Magento 2 database, you need to create a file in the :
app/code/<VendorName>/<ModuleName>/Setup/InstallSchema.php
add the following code to it:
<?php
namespace VendorName\ModuleName\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;use Magento\Framework\Setup\ModuleContextInterface;use Magento\Framework\Setup\SchemaSetupInterface;use Magento\Framework\DB\Adapter\AdapterInterface;
class InstallSchema implements InstallSchemaInterface{ public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $installer = $setup; $installer->startSetup();
//new table script will be there
$installer->endSetup(); }}
InstallSchema.php — is a file that is responsible for modifying the database structure during module installation. When executing the CLI command php bin/magento setup:upgrade Magento 2 checks whether a new module has appeared in the system and if it contains the InstallSchema.php
Since you already know how to and to display the "Hello World" text on your own page, in this article we will show you how to display it in the new block.
1. Add a new PHP class block.
Create this file:
app/code/<VendorName>/<ModuleName>/Block/SomeName.php
and add the following code to it:
<?php
namespace VendorName\ModuleName\Block;
class SomeName extends \Magento\Framework\View\Element\Template{ public function getWelcomeText() { return 'Hello World'; }}
where,
SomeName is a random name in CamelCase format.\Magento\Framework\View\Element\Template — a class from which you inherit your own block that interacts with the template.getWelcomeText — a public method we created to return the text "Hello World". You can create a name for it yourself.
2. Add a template file (template .phtml file)
Create this file:
app/code/<VendorName>/<ModuleName>/view/frontend/templates/some-name.phtml
and add the following code there:
<h1><?php echo $block->escapeHtml($block->getWelcomeText())
To display "Hello World" on your own page in Magento 2, follow these steps:
1. Register a router for the storefront.
Create this file:
app/code/<VendorName>/<ModuleName>/etc/frontend/routes.xml
and add the following code there:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="standard"> <route id="VendorName_ModuleName" frontName="path"> <module name="VendorName_ModuleName" /> </route> </router></config>
You can use the developer name (VendorName) associated with the module name (ModuleName) as the router id. The frontName is used in the URL to access your controllers.
Both names have to be unique.
2. Create a controller.
Add the new file:
app/code/<VendorName>/<ModuleName>/Controller/Index/Index.php
add the following code in it:
<?php
namespace VendorName\ModuleName\Controller\Index;
class Index extends \Magento\Framework\App\Action\Action{
To create basic Magento 2 module you need only 2 files: module.xml and registration.php.
1. Firstly, create the :
app/code/<VendorName>/<ModuleName>/
and the folder that will contain the module configuration files:
app/code/<VendorName>/<ModuleName>/etc/
If the app/code folder is missing from your Magento 2 installation, please create one.
2. Place the module.xml file with the following contents in the app/code/<VendorName>/<ModuleName>/etc/ folder
<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="VendorName_ModuleName" setup_version="2.0.0"> <sequence> <module name="Magento_Cms"/> <module name="Magento_Catalog"/> </sequence> </module></config>
sequence is not a required element and is intended to define the modules which your module depends on. If the dependencies are unknown, they can be specified
If you face an unexpected 301 or 302 redirect in Magento 2 and you don't know why it happens or what code causes it, you can easily find this out by temporarily editing the following files:
/vendor/magento/framework/HTTP/PhpEnvironment/Response.php
/vendor/magento/framework/Controller/Result/Redirect.php
Open Response.php and add the following line to the beginning of the setRedirect function:
var_dump($url); \Magento\Framework\Debug::backtrace(false, true, false); exit();
Example:
public function setRedirect($url, $code = 302){
var_dump($url); \Magento\Framework\Debug::backtrace(false, true, false); exit(); $this->setHeader('Location', $url, true) ->setHttpResponseCode($code); return $this;}
Now open the second Redirect.php file and add this:
var_dump($this->url); \Magento\Framework\Debug::backtrace(false, true, false); exit();
after each line containing:
$this->url =
Example:
public function setRefererUrl(){ $this->url = $this->redirect->getRefererUrl();
In case you work with a lot of different Magento instances as a temporary project you might want to have a nice method to check debug backtrace of some function execution in Magento 2 quickly without installing or enabling additional software on the server, e.g. Xdebug.
In this case, you can use the native Magento backtrace function from \Magento\Framework\Debug class and call it whenever you need:
\Magento\Framework\Debug::backtrace(false, true, false);
As a result, you will get this nice HTML debug-backtrace:
You can also call the exit function to stop further code execution right after the backtrace.
Here is more information about the backtrace method:
/** * Prints or returns a backtrace * * @param bool $return return or print * @param bool $html output in HTML format * @param bool $withArgs add short arguments of methods * @return string|bool */ public static function backtrace($return = false, $html = true, $withArgs = true)
Additional Debug Backtrace
Modules in the Magento 2 file structure
Module files in Magento 2 are located in 2 directories.
1. app/code/<VendorName>/<ModuleName>/
2. vendor/<vendor-name>/<module-name>/
Vendor Name — is the name of the company/person that developed the module. In some cases, the name of the vendor may coincide with the name of the customer's company. Therefore, before developing a new module, the name should be agreed upon. In the examples, we use our name — Magefan.
Module files developed on order or modules from other companies installed via FTP are located in the app/code folder.
The vendor folder contains Magento 2 root modules, as well as modules installed using the Web Setup Wizard or Composer. You will find the Magento root modules in the vendor/magento folder.
Interesting to know:In the Magento 2 repository (dev branch) on GitHub (https://github.com/magento/magento2), all root modules are in the app code/Magento folder. And all PHP libraries are in lib/internal/Magento.
When a visitor scrolls the web-page down It is convenient to display a button that will allow easily, by a one-click move customer back to the top of the page.
(button example)
To enable such a button on your website please follow these simple steps:
1. Create default.xml layout file in your theme directory:
/app/design/frontend/ThemeVendor/ThemeName/Magento_Theme/layout/default.xml
2. Paste the XML code:
<?xml version="1.0"?><page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="before.body.end"> <block name="magefan.go.to.top" template="Magento_Theme::gototop.phtml" /> </referenceContainer> </body></page>
3. Create gototop.phtml template file:
/app/design/frontend/ThemeVendor/ThemeName/Magento_Theme/templates/gototop.phtml
4. Paste the code:
<style type="text/css"> #mfbacktop { background: #324367; border: 2px solid white; border-radius:
The sortOrder property for in Magento 2 determines when to call them (before, after, or around a method), on condition more than one plugin is configured for the same method.
<config>
<type name="{ObservedType}">
<plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false" />
</type>
</config>
Prioritizing rules are as follows:
Before executing the original method, Magento will run before plugins from the smallest to the biggest value in sortOrder.
The part of the plugin around code will also be executed from the smallest to the biggest value before calling the original method (callable).
The after plugin is called from the biggest to the smallest after calling the original method.
Example:
Suppose there are three plugin classes (Plugin10, Plugin20, Plugin30). Each plugin class has before, after and around methods for the same method. sortOrder looks as follows for each of them:
Plugin10 - 10Plugin20 - 20Plugin30 - 30
The
If you don't want to , the other way is to run reindex via CLI.
To using CLI (Command Line Interface), navigate to your Magento folder in a terminal and use the following command:
php bin/magento indexer:reindex
It will reindex all indexes. Here is an example of the successful reindex execution:
Design Config Grid index has been rebuilt successfully in 00:00:00Customer Grid index has been rebuilt successfully in 00:00:00Category Products index has been rebuilt successfully in 00:00:01Product Categories index has been rebuilt successfully in 00:00:00Catalog Rule Product index has been rebuilt successfully in 00:00:01Product EAV index has been rebuilt successfully in 00:00:02Stock index has been rebuilt successfully in 00:00:00Product Price index has been rebuilt successfully in 00:00:01Catalog Product Rule index has been rebuilt successfully in 00:00:00Catalog Search index has been rebuilt successfully in 00:00:02
In case you need to reindex some specific index type, please use its name
If you have a product attribute and want to assign it to a single attribute set, it's easy to do via Magento 2 Admin Panel > Stores > Attributes > Attribute Set.But what if you need to assign it to all your attribute sets? What if you have 50+ or ever 100+ attribute sets? It can be time costly.
So what you can do, is to create a simple script that will do all job for you.
1. Create a PHP file "myscript.php" in your Magento 2 root directory.
2. Insert the code:
<?phperror_reporting(E_ALL);ini_set('display_errors', 1);
$ATTRIBUTE_CODE = 'my_attribute';$ATTRIBUTE_GROUP = 'General';
use Magento\Framework\App\Bootstrap;require __DIR__ . '/app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();$state = $objectManager->get(Magento\Framework\App\State::class);$state->setAreaCode('adminhtml');/* Attribute assign logic */
$eavSetup = $objectManager->create(\Magento\Eav\Setup\EavSetup::class);$config = $objectManager->get(\Magento\Catalog\Model\Config::class);$attributeManagement
Have you ever wondered how easy it is to check the quality of your own code, your colleagues' code, or a third-party module you want to use on a Magento project?
The Magento development team has created the Magento Extension Quality Program Coding Standard (Magento EQP), which allows you to check the code compliance with the standard, as well as identify the following shortcomings:
- SQL queries execution in the loop;- use of dangerous functions;- use of super-global variables;- excessive code complexity;- Unjustified collections loads.
Installation
You can install the Magento EQP via Composer, running this CLI command:
git clone https://github.com/magento/magento-coding-standard.gitcd magento-coding-standardcomposer install
In case you don't have the composer, you can download it here.
Checking
To check the code (which is, for example, in the /path/to/your/extension folder), go to the Magento EQP folder:
cd /path/to/magento-coding-standard
and run the following