Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Aphorismen
Applications
Business Economics & Admin.
My Computers
Cooking
Devices
Folders
Food
Hardware
Infos
Software Development
Sports
Operation Instructions
Todos
Test
Help
Glossary
Community portal
adaptions
Sidebar anpassen
Wiki RB4
Search
Search
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Magento
(section)
Page
Discussion
English
Read
Edit
View history
Toolbox
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Magento Software Architecture== * layers: ** presentation ** service ** domain ** persistence [[File:MagentoLayerArchitecture.png]] ===Presentation Layer=== The graphic and appearance information is called '''(custom) theme'''. A theme is a component of Magento application which provides a consistent look and feel (visual design) for entire application area (for example, storefront or Magento admin) using a combination of custom templates, layouts, styles or images. Out-of-the-box Magento application provides two design themes: '''Luma''', as a demonstration theme, and '''Blank''' as a basis for custom theme creation. Theme Layout files provided by themes: * Page configuration and generic layout files: <THEME_DIR>/<Namespace>_<Module>/layout Page layout files: <THEME_DIR>/<Namespace>_<Module>/page_layout The default or standard layouts are located in: <MAGENTO_DIR>/vendor/magento/module-theme/view/frontend/layout/default.xml <MOGENTO_DIR>/vendor/magento/module-backend/view/adminhtml/layout/default.xml <MOGENTO_DIR>/vendor/magento/theme-frontend-luma/ // Luma theme The basic components of page design are * '''layouts''': structure of a web page using an XML file that identifies all the containers and blocks composing the page (1) * '''containers''': placeholders within that web page structure assigning content structure to a page using container tags within a layout XML file (2) * '''blocks''': render the [[Magento#UI_Components|UI components]] on a page using block tags within a layout XML file (3) * '''templates''': blocks use templates to generate the HTML to insert into its parent structural block [[File:MagentoPageConcepts.PNG]] There are two options to influence the layout: [https://devdocs.magento.com/guides/v2.2/frontend-dev-guide/layouts/layout-override.html override] or [https://devdocs.magento.com/guides/v2.2/frontend-dev-guide/layouts/layout-extend.html extend]. '''Extending''' layout file is used for modifying of the default one, without replacing, but сhanging and amplifying it with the instructions. If you need to make a lot of changes or if the layout file contains an instruction that we can not change in the file extension, then the only option will be to '''override''' such file. The difference and how-to is described [https://belvg.com/blog/overriding-layout-files-in-magento-2.html here]. ====UI Components==== Magento UI components are implemented as a standard module named Magento_UI ([https://devdocs.magento.com/guides/v2.2/ui_comp_guide/bk-ui_comps.html see official doc]). ===Service Layer=== * bridges presentation and domain layer * provides '''service contracts''' (PHP interface, REST/SOAP API): a service contract is a set of PHP interfaces that is defined by a module. This contract comprises data interfaces and service interfaces. It is recommended to use Magento’s existing service contracts e.g. <code>Magento\Sales\Api\Data\OrderInterface</code> (in <MAGENTO_DIR>\vendor\magento\module-sales\Api\Data\OrderInterface.php) rather than <code>Magento\Sales\Model\Order</code>. ===Business/Domain Layer=== * implementents the business logic * modul communication via event [[#Events_and_Observers| events and observers]], [[#Plugins|plugins]] and di.xml ===Persistance Layer=== * see [https://devdocs.magento.com/guides/v2.1/extension-dev-guide/persistent-entities.html official documentation] * implements CRUD (create, read, update, delete) requests * there are 3 types of classes: ** '''model''' classes: don't contain any code for communicating with the DB (base class <code>\Magento\Framework\Model\AbstractModel </code>) ** '''resource''' classes: read and write to the DB ** '''collection''' classes: array of individual model instances which implement IteratorAggregate and Countable * models and resources are often seen as an unified thing called model ====Adding Attributes to Entities==== * there are two ways to extend attributes: custom attributes and [[#Extension_Attributes|extension attributes]]. =====Extension Attributes===== * (see [https://devdocs.magento.com/guides/v2.2/extension-dev-guide/attributes.html here] or [https://store.fooman.co.nz/blog/an-introduction-to-extension-attributes.html here]) Every interface that extends \Magento\Framework\Api\ExtensibleDataInterface can be extended by extension attributes. * /etc/extension_attributes.xml * interface declaration ===Events and Observers=== '''Events''' are dispatched by Magento 2 modules whenever specific actions are triggered. When an event dispatches, it passes data to the observer that is configured to watch (or monitor) that event. You can dispatch Magento 2 Events using the Magento\Framework\Event\Manager class. This class can be obtained through dependency injection by defining the dependency in the constructor method of the class. '''Observers''' are executed whenever a specific event for which they were set to listen is triggered. * a list of [https://cyrillschumacher.com/magento-2.3-list-of-all-dispatched-events/ events] * another list of [https://www.magestore.com/magento-2-tutorial/use-event-magento-2/ events] For implemention see [[Magento#Observer|here]]. ====payment_method_is_active==== * called in \vendor\magento\module-payment\Model\Method\AbstractMethod->isAvailable() (search for event => around line 864) * parameter: ** result as DataObject ** methodInstance as AbstractMethod ** quote as CartInterface (see \vendor\magento\module-quote\Api\Data\CartInterface.php) ===Collections=== Documentation is good in [[Magento#Sources|Kindle book]]. $customerCollection = $this->customerFactory->create(); $customerCollection->addAttributeToFilter('created_at', ['to' => $dl]); ===Modules=== A Magento '''module''' is a directory with subdirectories containing blocks, controllers, helpers, and models that are needed to create a specific store feature. It has a life cycle that allows them to be installed, deleted, or disabled. Modules typically live in the vendor directory of a Magento installation, in a directory with the following PSR-0 compliant format: vendor/<VENDORNAME>/<MODULENAME> or you can just create the app/code/<VENDORNAME>/<MODULENAME> directory (<MODULE_ROOT_DIR>) and the required directories within it. Inside the <MODULE_ROOT_DIR> you will find all the code related to this module. The name used for registration is usually <code><VENDORNAME>'''_'''<MODULENAME></code>. ====registration.php==== * mandatory *<MODULE_ROOT_DIR>|<THEME_ROOT_DIR>/'''registration.php''' <?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, // or \Magento\Framework\Component\ComponentRegistrar::THEME 'Wendweb_BrinkmannCustomer', // see DB table setup_module __DIR__ ); ====module.xml==== * mandatory *<MODULE_ROOT_DIR>/etc/'''module.xml''' declares the module by configuration like name, version, dependencies, ... <config> <module name="<VENDORNAME>_<MODULENAME>" setup_version="<MAJOR_VERSION>.<MINOR_VERSION>.<PATCH_VERSION>"> [<sequence> <module name ="<VENDORNAME>_<MODULENAME>" /> <DEPENDENCY_LIST> </sequence>] </module> </config> ====config.xml==== * optional * <MODULE_ROOT_DIR>/etc/'''config.xml''' * system configuration file ([https://devdocs.magento.com/guides/v2.3/config-guide/config/config-files.html official documentation]) * the default values of the attributes are somehow the 'reset to factory values', they are used if no corresponding XPath DB entry is found in [[Magento#DB_Tables| table core_config_data]] * if a module is deinstalled or the name or path is changed they have to be deleted manually from the DB =====General===== <config> <default> [<section_id>|[[Magento#Carriers|<CARRIERS_SECTION>]] // see [[Magento#system.xml|system.xml]] <group_id> // see [[Magento#system.xml|system.xml]] <field_id>...</field_id> // see [[Magento#system.xml|system.xml]] ... </group_id> </section_id>] [[Magento#Carriers|<CARRIERS>]] </default> </config> =====Carriers===== * A '''Carrier''' represents a shipping carrier, just like in real world (ex. FedEx). * XPath (e.g. in table core_config_data) is carriers/<CODENAME>/<ATTRIBUTE> ... <default> <carriers> // carries is for shipping, other options ??? <<CODENAME>> // same as $_code property in model class <<CONFIG_ATTRIBUTE>><SYSTEM_DEFAULT_VALUE></<CONFIG_ATTRIBUTE>> // name used in [[Magento#system.xml|system.xml]] and in code <active><0|???></active> // mandatory, active or not <model> <FILEPATH_FILENAME_WO_EXT> // mandatory, model class with same name as FILENAME </model> <title><TEXT></title> // mandatory, displayed in the frontend as name of shipping carrier and in backend as title <sallowspecific><0|1></sallowspecific> // mandatory, for carries: available in all countries or only in selected countries <sort_order></sort_order> // mandatory <name><TEXT></name> // optional, shown in frontend as name of shipping method and in backend as method </<CODENAME>> </carriers> </default> ====webapi.xml==== * <MODULE_ROOT_DIR>/etc/'''webapi.xml''' * Magento relies on PHP doc in the methods of the named service class, especially @param and @return annotations ====system.xml==== * optional * <MODULE_ROOT_DIR>/etc/adminhtml/system.xml * default values in [[Magento#config.xml|config.xml]] * used for Magento system configuration ... <system> ... <section id=["carriers"|"<NAME>"]> ... <group id="<CODENAME>"> // same as $_code attribute in shipping class and [[Magento#config.xml|config.xml]] <label><LABEL></label> <field id="<CONFIG_ATTRIBUTE>" type="<TYPE>"> // for TYPEs see /magento/framework/Data/Form/Element/Renderer/Factory.php row 26 or [https://devdocs.magento.com/guides/v2.2/ui_comp_guide/components/ui-textarea.html here] <label><LABEL></label> [<validate><VALIDATE>{ <VALIDATE>}</validate>] // see below for standard or [[Magento#Custom_Client_Validation|here]] for custom validation [<source_model><MODEL></source_model>] [<frontend_class><CLASS></frontend_class>] [<comment><COMMENT></comment>] // will be displayed in small letters below the field [<tooltip><TOOL_TIP></tooltip>] [<backend_model><CLASS_NAMESPACE></backend_model>] // e.g. used for server side validation </field> ... </group> </section> </system> VALIDATE := // see [https://blog.mdnsolutions.com/set-up-validators-for-a-system-xml-fields/ here] 'validate-no-html-tags' => 'HTML tags are not allowed' 'validate-select' => 'Please select an option.' 'validate-no-empty' 'validate-alphanum-with-spaces' 'validate-street' 'validate-phoneStrict' 'validate-phoneLax' 'validate-fax' 'required-entry' => 'This is a required field.' 'validate-number' => 'Please enter a valid number in this field.' 'validate-digits' => 'Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.' 'validate-date' => 'Please enter a valid date.' 'validate-email' => 'Please enter a valid email address. For example johndoe@domain.com.' 'validate-emailSender' 'validate-password' 'validate-admin-password' 'validate-url' => 'Please enter a valid URL. Protocol is required (http://, https:// or ftp://)' 'validate-clean-url' 'validate-xml-identifier' 'validate-ssn' 'validate-zip-us' 'validate-date-au' 'validate-currency-dollar' 'validate-not-negative-number' => 'Please enter a number 0 or greater in this field.' 'validate-zero-or-greater' => 'Please enter a number 0 or greater in this field.' 'validate-state' => 'Please select State/Province.' 'validate-cc-number' => 'Please enter a valid credit card number.' 'validate-data' => 'Please use only letters (a-z or A-Z), numbers (0-9) or underscore(_) in this field, first character should be a letter.' * all elements below <system> have the following attributes: ** showInDefault=["0"|"1"], showInWebsite=["0"|"1"] and showInStore=["0"|"1"] which control whether the element is shown in the corresponding configuration level. * data is stored in stored in [[Magento#DB_Tables|DB table]] 'core_config_data' with key <SECTION_ID>/<GROUP_ID>/<FIELD_ID> =====Custom Client Validation===== * for client side validation via JavaScript [http://magehelper.blogspot.com/2018/03/add-custom-js-on-magento-2-admin.html see here] or [https://magento.stackexchange.com/questions/139023/custom-field-validation-in-system-xml/144330 here] ====acl.xml==== *optional *<MODULE_ROOT_DIR>/etc/'''acl.xml''' ====Controller==== For an example see [https://www.mageplaza.com/magento-2-module-development/how-to-create-controllers-magento-2.html here] Controller is a class located in module Controller folder, responsible for specific Url or group of Url’s. All controllers extend <code>\Magento\Framework\App\Action\Action</code>. There are two different Controller, for frontend and for backend. =====routes.xml===== * <MODULE_ROOT_DIR>/etc/(frontend|adminhtml)/routes.xml <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="(standard|admin)"> <route id="<ROUTE_NAME>" frontName="<FRONT_NAME>"> <module name="<MODULE_NAME>" /> </route> </router> </config> * defines controller * called by <SHOP_URL>/<FRONT_NAME>/<ACTION_PATH>/<ACTION_CLASSNAME>, where ACTION_PATH is the sub-directory tree below the controller directory <code><MODULE_ROOT_DIR>\Controller\</code>. ====Model Classes==== *module declaration in <MODULE_ROOT_DIR>/Model/ =====Simple Model===== * <MODULE_ROOT_DIR>/Model/[<SUB_DIR>/]<MODELNAME>.php class <MODELNAME> extends \Magento\Framework\Model\AbstractModel { protected function _construct() { $this->_init('<VENDORNAME>\<MODULENAME>\Model\ResourceModel\<MODELNAME>'); // tells Magento about resource class * resource declaration in <MODULE_ROOT_DIR>/Model/ResourceModel/<MODELNAME>.php class <MODELNAME> extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { protected function _construct() { $this->_init('<TABLENAME>', '<PRIMARY_KEY_COLUMN>'); * create collection in <MODULE_ROOT_DIR>/Model/ResourceModel/<MODELNAME>/Collection.php class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { protected function _construct() { $this->_init('<FULL_MODEL_CLASSNAME>', '<FULL_RESOURCE_CLASSNAME>'); * <MODULE_ROOT_DIR>/Model/<MODELNAME>.php class <MODELNAME> extends \Magento\Framework\Model\AbstractModel { protected function _construct() { $this->_init('<VENDORNAME>\<MODULENAME>\Model\ResourceModel\<MODELNAME>'); // tells Magento about resource class * resource declaration in <MODULE_ROOT_DIR>/Model/ResourceModel/<MODELNAME>.php class <MODELNAME> extends \Magento\Framework\Model\Entity\AbstractEntity { protected function _construct() { $this->_read = $this->_write = } public function getEntityType() { ... } * create collection in <MODULE_ROOT_DIR>/Model/ResourceModel/<MODELNAME>/Collection.php class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { protected function _construct() { $this->_init('<FULL_MODEL_CLASSNAME>', '<FULL_RESOURCE_CLASSNAME>'); ====Observer==== *definition /etc/events.xml // global events /adminhtml/events.xml /frontend/events.xml <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="<EVENTNAME>"> <observer name="<MY_OBSERVER_NAME>" instance="<VENDORNAME>\<MODULENAME>\Observer\<CLASSNAME>" /> </event> </config> * class file located in <MODULE_ROOT_DIR/Observer class <MyObserverClass> implements ObserverInterface { public function execute(Observer $observer) { $parameter = $observer->getEvent->get<PARAMETER>(); // passed via eventManager->dispatch(<EVENTNAME>, // [ <PARAMETER> => $parameter ]); * to find out which parameter are passed via standard events search M2 source code for event and look up parameter ====Setup/Uninstall==== * see [[Magento#Upgrade_Module|here]] when which method is called * <MODULE_ROOT_DIR>/Setup InstallData.php InstallSchema.php Recurring.php // run every time magento setup:upgrade is run Uninstall.php UpgradeData.php UpgradeSchema.php ====Base Layout==== Base Layout files are provided by modules. Conventional location * Page configuration and generic layout files: <MODULE_DIR>/view/frontend/layout * Page layout files: <MODULE_DIR>/view/frontend/page_layout ====UI==== * <MODULE_ROOT_DIR>/Ui ====Views==== * /view/adminhtml * /view/frontend ====Api==== * <MODULE_ROOT_DIR>/Api contains the [[#Repository|repository]] interface. * <MODULE_ROOT_DIR>/Api/Data contains the data interface of the model (e.g. getter and setter) and the search result interface. ====Helper==== * /Helper ====Console==== * /Console ====Localization==== * /i18n ====Block==== * <MODULE_ROOT_DIR>/Block ====Plugins==== A [https://devdocs.magento.com/guides/v2.2/extension-dev-guide/plugins.html '''plugin'''], or interceptor, is a class that modifies the behavior of public class functions by intercepting a function call and running code before, after, or around that function call. '''Plugins''' allow you to target changing/adding/removing functionality on the method level. Magento 2 plugins allow us to execute code before (e.g. to change parameter of the standard method), after (e.g. to change the output of the standard method) or around any public method. The di.xml file in your module declares a plugin for a class object. <config> <type name="{ObservedType}"> <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false" /> </type> </config> Conention is to name the PluginClassName as <code>\<VENDOR>\<MODULE>\Plugin\<MODEL>Plugin</code>. =====Before Methods===== Magento runs all '''before''' methods ahead of the call to an observed method. These methods must have the same name as the observed method with ‘before’ as the prefix and first parameter must of type of the model. It is usually used to modifiy the arguments. =====After Methods===== Magento runs all '''after''' methods following the completion of the observed method. Magento requires these methods have a return value and they must have the same name as the observed method with ‘after’ as the prefix. public function '''after'''<MethodName>( <ClassOfOriginalMethod> $subject, $result, // result of the orginal method <ParameterListOfOrginalMethod>) // all which are used from left to right, the most rightest is the last parameter needed { // to modify the original result, change $result and return it } =====Around Methods===== Magento runs the code in '''around''' methods before and after their observed methods. Using these methods allow you to override an observed method. Around methods must have the same name as the observed method with ‘around’ as the prefix. * /Plugin ====Commands==== * see [https://inviqa.com/blog/magento-2-tutorial-how-to-create-command-line-module here] or UweHeuer testcmd ===Caching=== * located in /var/ directory ===Code Generation=== * Factory, Proxy and Interceptor classes are generated and stored in /var/generation/ ===Custom Attributes=== Different factories have to be used for different entities: * CustomerSetupFactory ** Customer ** Customer Address * SalesSetupFactory ** CreditMemo ** Invoice ** Order * QuoteSetupFactory ** Quote ** QuoteItem ** QuotePayment * CategorySetupFactory * Category * Product
Summary:
Please note that all contributions to Wiki RB4 may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Uwe Heuer Wiki New:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Toggle limited content width