├── 7. Catalog ├── 5. Other Skills │ ├── 5. Describe custom product options in Magento.md │ ├── 1. Choose optimal catalog structure (EAV vs. Flat) for a given implementation.md │ ├── 3. Modify, extend, and troubleshoot the Magento layered (“filter”) navigation.md │ ├── 4. Troubleshoot and customize Magento indexes.md │ ├── 6. Questions.md │ └── 2. Implement, troubleshoot, and modify Magento tax rules.md ├── 2. Price Generation │ ├── 1. Identify basic concepts of price generation in Magento.md │ └── 2. Modify and adjust price generation for products (for example, during integration of third-party software).md ├── 1. Product Types │ ├── 3. Identify how custom product types interact with indexing, SQL, and underlying data structures.md │ ├── 4. Questions.md │ └── 1. Identify and describe standard product types.md ├── 6. Additional Notes │ └── Questions.md └── 4. Catalog Price Rules │ └── 1. Identify how catalog price rules are implemented in Magento.md ├── 5. EAV ├── 1. EAV Concepts │ ├── 2. Describe the database schema for EAV entities.md │ ├── 3. Describe the EAV entity structure and its difference from the standard core resource mode.md │ ├── 4. Describe the EAV load-and-save process and its differences from the regular loadand-save process.md │ └── 5. Questions.md ├── 3. Additional Notes │ ├── Questions.md │ └── Answers.md └── 2. EAV Attributes │ ├── 4. Questions.md │ ├── 3. Describe how to create and customize attributes.md │ ├── 1. Identify the purpose of attribute frontend, source, and backend models.md │ └── 2. Describe how to implement the interface of attribute frontend, source, and backend models.md ├── 4. Databases ├── 1. Models, Resource Models & Collections │ ├── 3. Describe how Magento works with database tables .md │ ├── 9. Describe the role and hierarchy of setup objects in Magento.md │ ├── 8. Describe the hierarchy of database-related classes in Magento.md │ ├── 10. Questions.md │ ├── 7. Describe the collection interface (filtering:sorting:grouping).md │ ├── 4. Describe the load-and-save process for a regular entity.md │ ├── 5. Describe group save operations.md │ └── 6. Describe the role of Zend_Db_Select in Magento.md ├── 2. Install:Update Scripts │ ├── 3. Identify how to use the DDL class in setup scripts.md │ ├── 4. Questions.md │ ├── 2. Write install and upgrade scripts using set-up resources.md │ └── 1. Describe the install:upgrade workflow.md └── 3. Additional Notes │ └── Questions.md ├── 1. Basics ├── 1. Architecture │ ├── 5. Identify and explain the main Magento design areas (adminhtml and frontend).md │ ├── 4. Describe Magento skin and JavaScript files location.md │ ├── 2. Describe typical Magento module structure.md │ ├── 1. Describe Magento codepools.md │ ├── 3. Describe Magento templates and layout files location.md │ ├── 6. Explain class naming conventions and their relationship with the autoloader.md │ └── 7. Describe methods for resolving module conflicts.md ├── 2. Configuration │ ├── 5. Identify the function and proper use of automatically available events, including*_load_after.md │ ├── 4. Register an Observer.md │ ├── 3. Describe the process and configuration of class overrides in Magento.md │ ├── 2. Describe class group configuration and use in factory methods.md │ ├── 6. Setting up a CRON.md │ ├── Questions.md │ └── 1.Explain how Magento loads and manipulates configuration information.md ├── 3. Internationalization │ ├── 3. Describe the advantages and disadvantages of using subdomains and subdirectories in internationalization.md │ ├── 1. Describe how to plan for internationalization of a Magento site.md │ ├── Questions.md │ └── 2. Describe the use of Magento translate classes and translate files.md └── 4. Additional Notes │ └── Questions.md ├── 2. Request Flow ├── 5. Module Initalization │ ├── 2. Describe the effect of module dependencies.md │ ├── Questions.md │ └── 1. Describe the steps needed to create and register a new module.md ├── 7. Flushing Data │ ├── Questions.md │ └── 1. JavaScript and CSS.md ├── 6. Design and layout initialization │ ├── Questions.md │ └── 1. Design and layout initialization.md ├── 8. Additional Notes │ ├── Questions.md │ └── Answers.md ├── 2. Front Controller │ └── Questions.md ├── 1. Application Initialization │ ├── Questions.md │ └── 1. Describe the steps for application initialization.md └── 3. URL Rewrites │ └── 1. Describe URL structure:processing in Magento.md ├── 9.Sales & Customers ├── 1. Sales │ ├── 5. Describe the implementation of the three partial order operations (partial invoice, partial shipping, and partial refund).md │ ├── 3. Describe the order shipment structure and process.md │ ├── 6. Describe cancel operations.md │ ├── 4. Describe the architecture and processing of refunds.md │ └── 2. Card operations (capturing and authorization).md ├── 2. Customers │ ├── 2. Describe how to add, modify, and display customer attributes.md │ └── 1. Describe the architecture of the customer module.md └── 3. Additional Notes │ ├── Questions.md │ └── Answers.md ├── 8. Checkout ├── 2. Shopping Cart Price Rules │ └── 1. Describe how shopping cart price rules work and how they can be customized.md ├── 3. Shipping and payment methods in Magento │ └── 2. Describe the shipping rates calculation process.md ├── 5. Additional Notes │ └── Questions.md └── 4. Magento multishipping implementation │ └── 1. Describe how to extend the Magento multishipping implementation.md ├── LICENSE ├── 3. Rendering ├── 1. Theme.md ├── 3. Design layout, XML schema, and CMS content directives.md └── 2. Blocks.md ├── README.md └── 6. Adminhtml └── 1. Common Structure ├── 1. Describe the similarities and differences between adminhtml and frontend interface and routing.md └── 2. Describe the components and types of cache clearing using the adminhtml interface.md /7. Catalog/5. Other Skills/5. Describe custom product options in Magento.md: -------------------------------------------------------------------------------- 1 | # 5. Describe custom product options in Magento 2 | -------------------------------------------------------------------------------- /7. Catalog/5. Other Skills/1. Choose optimal catalog structure (EAV vs. Flat) for a given implementation.md: -------------------------------------------------------------------------------- 1 | # Choose optimal catalog structure (EAV vs. Flat) for a given implementation 2 | 3 | Flat tables improve performance as it is from table but its a big catalogue with lots of attributes EAV maybe more suited. 4 | -------------------------------------------------------------------------------- /5. EAV/1. EAV Concepts/2. Describe the database schema for EAV entities.md: -------------------------------------------------------------------------------- 1 | # Describe the database schema for EAV entities 2 | 3 | Please see previous [notes](https://github.com/colinmurphy/magento-exam-notes/blob/master/5.%20EAV/1.%20EAV%20Concepts/1.%20Define%20basic%20EAV%20concepts%20and%20class%20hierarchy.md#L509) for details. 4 | -------------------------------------------------------------------------------- /7. Catalog/5. Other Skills/3. Modify, extend, and troubleshoot the Magento layered (“filter”) navigation.md: -------------------------------------------------------------------------------- 1 | # Modify, extend, and troubleshoot the Magento layered (“filter”) navigation 2 | 3 | Filters extend from *Mage_Catalog_Model_Layer_Filter_Abstract*. 4 | Filters will appear in the layered navigation depending on the attribute settings. 5 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/3. Describe how Magento works with database tables .md: -------------------------------------------------------------------------------- 1 | # Describe how Magento works with database tables 2 | 3 | See [Basic Concepts](https://github.com/colinmurphy/magento-exam-notes/blob/master/4.%20Databases/1.%20Models%2C%20Resource%20Models%20%26%20Collections/1.%20Basic%20Concepts.md) for more details. 4 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/5. Identify and explain the main Magento design areas (adminhtml and frontend).md: -------------------------------------------------------------------------------- 1 | # Identify and explain the main Magento design areas (adminhtml and frontend) 2 | 3 | ## 1. adminhtml 4 | 5 | This is for anything related to backend/admin part of the site. 6 | 7 | 8 | ## 2. frontend 9 | 10 | This is for anything related to the frontend part of the site. 11 | -------------------------------------------------------------------------------- /2. Request Flow/5. Module Initalization/2. Describe the effect of module dependencies.md: -------------------------------------------------------------------------------- 1 | # Describe the effect of module dependencies 2 | 3 | - The module will be loaded after the other dependencies 4 | - If the module does not exist or has not been loaded rtit will not be loaded it break the system and throw a exception 5 | 6 | The exception will be thrown in Mage_Core_Model_Config->_sortModuleDepends(); 7 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/9. Describe the role and hierarchy of setup objects in Magento.md: -------------------------------------------------------------------------------- 1 | # Describe the role and hierarchy of setup objects in Magento 2 | 3 | To allow modules make changes to the database from install/upgrade sql and data scripts. 4 | 5 | 6 | # Further Reading 7 | 8 | [http://devdocs.magento.com/guides/m1x/magefordev/mage-for-dev-6.html](http://devdocs.magento.com/guides/m1x/magefordev/mage-for-dev-6.html) 9 | -------------------------------------------------------------------------------- /7. Catalog/5. Other Skills/4. Troubleshoot and customize Magento indexes.md: -------------------------------------------------------------------------------- 1 | # Troubleshoot and customize Magento indexes 2 | 3 | Check the following classes: 4 | 5 | - Mage_Index_Model_Indexer_Abstract 6 | 7 | Then depending on the catalog type: 8 | 9 | - Mage_Catalog_Model_Product_indexer_Eav 10 | - Mage_Catalog_Model_Product_Indexer_Flat 11 | 12 | If its a price related issue 13 | 14 | - Mage_Catalog_Model_Product_Indexer_Price 15 | 16 | If its a stock issue 17 | 18 | - Mage_CatalogInventory_Model_Indexer_Stock 19 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/4. Describe Magento skin and JavaScript files location.md: -------------------------------------------------------------------------------- 1 | # Describe Magento skin and JavaScript files location 2 | 3 | ## 1. Skin 4 | 5 | This can be found in the root under *skin* 6 | 7 | Your skin directory for your theme can be found under *skin/{{area}}/{{package}}/{{theme}}* 8 | 9 | 10 | ## 2. JavaScript 11 | 12 | There are 2 types: 13 | 14 | - Skin JavaScript 15 | - JavaScript Libraries/Frameworks 16 | 17 | Skin JavaScript can be found under *skin/{{area}}/{{package}}/{{theme}}/js* 18 | 19 | JavaScript libraries can be found under *js/{{library}}* 20 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/2. Describe typical Magento module structure.md: -------------------------------------------------------------------------------- 1 | # Describe typical Magento module structure 2 | 3 | ## 1. Overview 4 | 5 | A module directory has typically the following directories: 6 | 7 | - Block 8 | - controllers 9 | - data 10 | - etc 11 | - Helper 12 | - Model 13 | - sql 14 | 15 | 16 | ## 2. Further Reading 17 | 18 | - [http://blog.belvg.com/magento-certification-module-structure.html](http://blog.belvg.com/magento-certification-module-structure.html) 19 | - [http://magestudyguide.com/#describe-typical-magento-module-structure](http://magestudyguide.com/#describe-typical-magento-module-structure) 20 | -------------------------------------------------------------------------------- /9.Sales & Customers/1. Sales/5. Describe the implementation of the three partial order operations (partial invoice, partial shipping, and partial refund).md: -------------------------------------------------------------------------------- 1 | # Describe the implementation of the three partial order operations (partial invoice, partial shipping, and partial refund): 2 | 3 | # Overview 4 | 5 | Partial Order Operations have 3 types of refunds: 6 | 7 | - Orders 8 | - Invoices 9 | - Shipping 10 | 11 | These are when only parts of the order are refunded. 12 | 13 | ## How do partial order operations affect order state? 14 | 15 | It sets it to processing. 16 | 17 | 18 | ## How is data for partial operations stored? 19 | 20 | In the different entity tables. 21 | -------------------------------------------------------------------------------- /1. Basics/2. Configuration/5. Identify the function and proper use of automatically available events, including*_load_after.md: -------------------------------------------------------------------------------- 1 | # Identify the function and proper use of automatically available events, including load_after, etc. 2 | 3 | # 1. Overview 4 | 5 | You should know the following dispatch events type: 6 | 7 | - *_load_after 8 | - *_save_before 9 | - *_save_after 10 | - *_delete_before 11 | - *_delete_after 12 | 13 | 14 | customer_address_save_before = runs just before saving customer address 15 | customer_address_save_after = runs immediately after saving customer address 16 | catalog_product_save_before = runs just before saving product 17 | catalog_product_save_after = runs just after saving product 18 | -------------------------------------------------------------------------------- /2. Request Flow/7. Flushing Data/Questions.md: -------------------------------------------------------------------------------- 1 | ## Which events are associated with sending output? 2 | 3 | There are 4: 4 | 5 | - controller_front_init_before 6 | - controller_front_init_routers 7 | - controller_front_send_response_before 8 | - controller_front_send_response_after 9 | 10 | 11 | ## Which class is responsible for sending output? 12 | 13 | Mage_Core_Controller_Response_Http 14 | 15 | ## What are possible issues when this output is not sent to the browser using the typical output mechanism, but is instead sent to the browser directly? 16 | 17 | Layout, Blocks not rendered 18 | 19 | 20 | ## How are redirects handled? 21 | 22 | With the core_url_rewrite table in the class *Mage_Core_Model_Url_Rewrite_Request* 23 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/8. Describe the hierarchy of database-related classes in Magento.md: -------------------------------------------------------------------------------- 1 | # Describe the hierarchy of database-related classes in Magento 2 | 3 | - Magento_Db_Adapter_Pdo_Mysql 4 | Adapter class used for interacting with the database. 5 | 6 | - Mage_Core_Model_Resource 7 | Core resource model. Used to get connections with adapters. 8 | 9 | - Varien_Db_Select 10 | Extends from Zend_Db_Select and is used to make queries. 11 | 12 | - Mage_Core_Model_Resource_Setup 13 | Setup Class for data and SQL scripts and also get connection 14 | 15 | - Mage_Core_Model_Resource_Db_Abstract 16 | Abstract Class for Resource Models 17 | 18 | - Varien_Data_Collection_Db 19 | Class for Collections. 20 | -------------------------------------------------------------------------------- /5. EAV/3. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | # 1. Concepts 2 | 3 | Name all 8 entity types 4 | How do you load all 8 types 5 | Name the table entity types are stored from 6 | How do we change the setup class for a resource 7 | What is the name of the abstract class for EAV Resource Model & Collection 8 | How do we register a new EAV type 9 | How do we create tables for the EAV type 10 | Name all fields which can be passed in to create a EAV type and what their purpose is 11 | Name all the entity attribute value table types (text, decimal) 12 | 13 | 14 | # 2. Attributes 15 | 16 | Do you use entity_type_code or entity_model when creating/update EAV attribute 17 | Differences between create and update attribute 18 | How do you get attribute value for a model 19 | -------------------------------------------------------------------------------- /7. Catalog/2. Price Generation/1. Identify basic concepts of price generation in Magento.md: -------------------------------------------------------------------------------- 1 | # Identify basic concepts of price generation in Magento 2 | 3 | Prices are taken from the price model of a product using $this->getPrice() or $this->getFinalPrice(); 4 | 5 | 6 | # 1. Different Price Models 7 | 8 | # 1.1. Grouped Products - Mage_Catalog_Model_Product_Type_Grouped_Price 9 | 10 | Returns the price of the simple associated product. 11 | 12 | # 1.2. Configurable Products - Mage_Catalog_Model_Product_Type_Configurable_Price 13 | 14 | This combines the base price and the relative price of the simple product stored in **catalog_product_super_attribute_pricing**. 15 | 16 | # 1.3. Downloadable Products - Mage_Downloadable_Model_Product_Price 17 | 18 | 19 | # 1.4. Bundle Products - Mage_Bundle_Model_Product_Price 20 | -------------------------------------------------------------------------------- /9.Sales & Customers/1. Sales/3. Describe the order shipment structure and process.md: -------------------------------------------------------------------------------- 1 | # Describe the order shipment structure and process: 2 | 3 | 4 | Mage_Sales_Model_Order_Shipment 5 | sales_flat_shipment 6 | 7 | ## How shipment templates be customized? 8 | 9 | Through email templates. 10 | 11 | ## How can different items from a single order be shipped to multiple addresses? Is it possible at all? 12 | 13 | Multiple shipments can be created for an order and can be directed to multiple addresses but only for multi-shipping orders. 14 | 15 | ## How does Magento store shipping and tracking information? 16 | 17 | This is an EAV "shipment" and is stored in the following tables: 18 | 19 | - sales_flat_shipment 20 | - sales_flat_shipment_comment 21 | - sales_flat_shipment_grid 22 | - sales_flat_shipment_item 23 | - sales_flat_shipment_track 24 | -------------------------------------------------------------------------------- /9.Sales & Customers/1. Sales/6. Describe cancel operations.md: -------------------------------------------------------------------------------- 1 | # Describe cancel operations: 2 | 3 | Magento orders can be cancelled until all items have been invoice, e.g. during the pending or processing state. This automatically cancels payment and order items (which just set cancelled tax amounts on the item). Invoices can be cancelled, returning order totals to pre-invoice state. Same goes for credit memos. Only shipments cannot be cancelled. 4 | 5 | ## What cancel operations are available for the various order entities in Magento (order, order item, shipment, invoice, credit memo)? Do all of them support cancellation? 6 | 7 | Support: 8 | - Order 9 | - Order Item 10 | 11 | Do Not Support: 12 | 13 | - invoice 14 | - shipment 15 | - credit memo 16 | 17 | ## How are taxes processed during cancel operations? 18 | 19 | They are returned to their previous state e.g. quote 20 | -------------------------------------------------------------------------------- /1. Basics/3. Internationalization/3. Describe the advantages and disadvantages of using subdomains and subdirectories in internationalization.md: -------------------------------------------------------------------------------- 1 | # Describe the advantages and disadvantages of using subdomains and subdirectories in internationalization 2 | 3 | # 1. Subdomain 4 | 5 | ## Advantages 6 | - Can be hosted separately 7 | - Easier for linking content 8 | - Better usability (recognizable country from the domain). 9 | - Can host site in different countries for SEO purposes 10 | - Cleaner URL's 11 | 12 | ## Disadvantages 13 | 14 | - Extra link building is required. 15 | - More difficult to maintain 16 | 17 | # 2. Subdirectory 18 | 19 | ## Advantages 20 | 21 | - Strengthen name-recognition for the primary domain 22 | - Increases SEO hit on the primary domain 23 | - Easier to manage 24 | 25 | ## Disadvantages 26 | 27 | - Can't host site in different countries for SEO purposes 28 | - URL's become messy on larger sites 29 | -------------------------------------------------------------------------------- /5. EAV/2. EAV Attributes/4. Questions.md: -------------------------------------------------------------------------------- 1 | ## Which setup methods are available to work with EAV entities? 2 | 3 | - addAttribute 4 | - addAttributeGroup 5 | - addAttributeOption 6 | - addAttributeSet 7 | - addAttributeToGroup 8 | - addAttributeToSet 9 | - addEntityType 10 | - updateAttribute 11 | - updateAttributeCode 12 | - updateAttributeSet 13 | - updateEntityType 14 | 15 | 16 | ## How can an EAV setup class be instantiated in a setup script if not specified in the XML configuration for a setup resource? 17 | 18 | Create a new object $class = Mage_Eav_Model_Entity_Setup(); 19 | 20 | 21 | ## What is the difference between addAttribute() and updateAttribute()? 22 | 23 | addAttribute creates a attribute where updateAttribute updates an attribute. 24 | 25 | ## What are the advantages of using a custom setup class for manipulating EAV attributes in a custom module? 26 | 27 | Can define your own default values and attributes and override other methods. 28 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/1. Describe Magento codepools.md: -------------------------------------------------------------------------------- 1 | # Describe Magento codepools 2 | 3 | ## 1. Overview 4 | 5 | There are 3 codepools under the app/code directory: 6 | 7 | - local 8 | - community 9 | - core 10 | 11 | 12 | ## 2. Autoloading 13 | 14 | In *app/Mage.php* these 3 paths are loaded using *set_include_path* using a trick 15 | of imploding the array of paths with a double colon and passing it as the parameter for this function. 16 | 17 | **Note:** the *lib* directory is also added the at the end of the array of paths. The *lib* directory contains core libraries for Magento such as the Zend Framework. 18 | 19 | This will include the 3 codepool paths instead of 1. When the autoloader is searching for a file it will look in these 3 sub-directories for the file in order listed above. 20 | 21 | If you wanted to add your own codepool you would add a path to *$paths* array. 22 | 23 | The autoloader class is *Varien_Autoload* and can be found in the *lib/Varien* directory. 24 | -------------------------------------------------------------------------------- /1. Basics/3. Internationalization/1. Describe how to plan for internationalization of a Magento site.md: -------------------------------------------------------------------------------- 1 | # Describe how to plan for internationalization of a Magento site 2 | 3 | For an in depth article on everything related in this section please read 4 | [http://blog.belvg.com/magento-certified-developer-exam-internationalization.html](http://blog.belvg.com/magento-certified-developer-exam-internationalization.html). 5 | 6 | Some other factors along with the factors mentioned in the blog which would determine how you would setup a multi-store are the following: 7 | 8 | **Pricing** 9 | 10 | If you had separate pricing per store you would need to setup multiple websites. 11 | However if the pricing was being converted per currency you would not need separate websites. 12 | 13 | The recommended method of setting up a store with different languages is 1 website, 1 store and multiple store views. 14 | 15 | **Customers** 16 | 17 | Customers are per website basis so if you were migrating to Magento and had 2 different set of customers you would have to setup multiple stores. 18 | -------------------------------------------------------------------------------- /8. Checkout/2. Shopping Cart Price Rules/1. Describe how shopping cart price rules work and how they can be customized.md: -------------------------------------------------------------------------------- 1 | # Describe how shopping cart price rules work and how they can be customized 2 | 3 | Please read notes on [Identify how catalog price rules are implemented in Magento](https://github.com/colinmurphy/magento-exam-notes/blob/master/7.%20Catalog/4.%20Catalog%20Price%20Rules/1.%20Identify%20how%20catalog%20price%20rules%20are%20implemented%20in%20Magento.md#L1) for more information. 4 | 5 | # Questions 6 | 7 | ## Which module is responsible for shopping cart price rules? 8 | 9 | Mage_SalesRule 10 | 11 | ## What is the difference between shopping cart and catalog price rules? 12 | 13 | Cart applies rule to quote whereas price rules apply to products in the cart. 14 | 15 | ## What are the limitations of Magento shopping cart rules? 16 | 17 | - Only 1 voucher can be applied at once but multiple rules can be applied. 18 | - Rules cannot rely on each other 19 | - For admin area orders, shopping cart price rules can be disabled on specific items but they are always applied on all items in the frontend. 20 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/3. Describe Magento templates and layout files location.md: -------------------------------------------------------------------------------- 1 | # Describe Magento templates and layout files location 2 | 3 | ## 1. Design Areas 4 | 5 | When you go to app/design you have following 3 design areas: 6 | 7 | - install 8 | - frontend 9 | - adminhtml 10 | 11 | 12 | ## 2. Templates 13 | 14 | Templates files will be found under *app/design/{{area}}/{{package}}/{{theme}}/template* directory e.g. app/design/frontend/rwd/default/template/ would contain all RWD theme frontend template files. 15 | 16 | 17 | ## 3. Layout 18 | 19 | Layout files will be found under *app/design/{{area}}/{{package}}/{{theme}}/layout* directory. 20 | This would generally only contain your local.xml for your theme or your theme XML files. 21 | 22 | 23 | ### 3.1 Child Themes 24 | 25 | If your theme is a child theme you would have a theme.xml file found under *app/design/{{area}}/{{package}}/{{theme}}/etc/theme.xml* 26 | 27 | For example if it was a child theme of the RWD theme, we would add the following to our theme.xml file: 28 | 29 | 30 | 31 | rwd/default 32 | 33 | -------------------------------------------------------------------------------- /7. Catalog/5. Other Skills/6. Questions.md: -------------------------------------------------------------------------------- 1 | ## When and how are the catalog flat tables updated when a product is modified? 2 | 3 | ## Which factors are used by the Mage_Tax module to apply the correct tax rate (or rates) to a product price? 4 | 5 | 1. Customer Group/ Product Class 6 | 2. Address - calculated on - shipping/billing/origin 7 | 3. Website/Store 8 | 4. Configuration Settings 9 | 10 | ## How can attributes with custom source models be integrated into layered navigation filtering? 11 | 12 | Mage_Catalog_Model_Layer_Filter_Abstract 13 | 14 | ## Which classes are responsible for rendering the layered navigation? 15 | 16 | Mage_Catalog_Model_Layer_Filter_Abstract 17 | 18 | ## Which indexes are used for the layered navigation? 19 | 20 | ## Which steps are needed to integrate a custom indexer into the framework offered by the Mage_Index module? 21 | 22 | ## How are custom product options stored on quote and order items? 23 | 24 | ## How can you specify custom product options on-the-fly on quote items? 25 | 26 | ## How are custom product options copied from quote to order items? 27 | 28 | ## How are custom product options processed when a product is added to the cart? 29 | -------------------------------------------------------------------------------- /1. Basics/3. Internationalization/Questions.md: -------------------------------------------------------------------------------- 1 | ### 1. Which method is used for translating strings, and on which types of objects is it generally available? 2 | 3 | 4 | - Module Translation: CSV in /app/locale 5 | - Theme Translation: CSV in /app/design/{area}/{package}/{theme{}/locale (theme folder translate) 6 | - Database Translation: Database (table core_translate) 7 | 8 | 9 | ### 2. In what way does the developer mode influence how Magento handles translations? 10 | 11 | Not sure how to answer but making strings translatable. 12 | 13 | 14 | ### 3. How many options exist to add a custom translation for any given string? 15 | 16 | - Database Translation 17 | - Module Translation 18 | - Theme Translation 19 | 20 | ### 4. What is the priority of translation options? 21 | 22 | - Database Translations 23 | - Theme Translations 24 | - Module Translation 25 | 26 | 27 | ### 5. How are translation conflicts (when two modules translate the same string) processed by Magento? 28 | 29 | **Example:** 30 | 31 | Mage::helper("module_a")->__("Hello"); 32 | Mage::helper("module_b")->__("Hello"); 33 | 34 | In the method _addData() will create 2 keys for each module to keep module string separate. 35 | -------------------------------------------------------------------------------- /9.Sales & Customers/2. Customers/2. Describe how to add, modify, and display customer attributes.md: -------------------------------------------------------------------------------- 1 | # Describe how to add, modify, and display customer attributes 2 | 3 | ## Add Customer Attribute 4 | 5 | - Install Script 6 | - Add to Form 7 | - How does form get field 8 | - How does form convert to quote 9 | 10 | 11 | # Questions 12 | 13 | ## How is customer information validated? 14 | 15 | ## How can customer-related email templates be manipulated? 16 | 17 | 1. Create new Email template. 18 | 2. Update configuration setting for template under Customer Configuration. 19 | 20 | ## What is the difference between shipping and billing addresses for a customer? 21 | 22 | Nothing. It will only affect Tax if used by the Tax module. 23 | 24 | ## How does the number of shipping and billing address entities affect the frontend interface for customers? 25 | 26 | It doesn't 27 | 28 | ## How does customer information affect prices and taxes? 29 | 30 | Catalog Price Rules, Shopping Cart Rules & Tax. 31 | 32 | ## How can attributes be added to a customer address? 33 | 34 | ## How are custom address attributes you added converted to an order address? 35 | 36 | ## Can a customer be added to two customer groups at the same time? 37 | No. 38 | -------------------------------------------------------------------------------- /2. Request Flow/5. Module Initalization/Questions.md: -------------------------------------------------------------------------------- 1 | ## 1. What does "Magento loads modules" mean? 2 | 3 | 1. app/etc/modules/ 4 | 2. Sort modules 5 | 3. config.xml is loaded and added to config tree 6 | 7 | ## 2. In which order are Magento modules loaded? 8 | 9 | 1. Mage_All.xml 10 | 2. Mage xml 11 | 3. Any other xml files 12 | 13 | This is set when returning array of files to be loaded. 14 | 15 | ## 3. Which core class loads modules? 16 | 17 | Mage_Core_Model_Config 18 | 19 | ## 4. What are the consequences of one module depending on another module? 20 | 21 | The module must be loaded and exist or otherwise it will cause Magento to throw an exception. 22 | 23 | ## 5. During the initialization of Magento, when are modules loaded in? 24 | 25 | They are loaded before Front Controller Dispatch and after caching has been checked. 26 | 27 | ## 6. Why is the load order important? 28 | 29 | Dependencies and core functionality 30 | 31 | ## 7. What is the difference regarding module loading between Mage::run() and Mage::app()? 32 | 33 | **Note:** Important. 34 | 35 | Mage::app() – Initialize application without request processing. 36 | Mage::run() – Run application. Run process responsible for request processing and sending response. 37 | -------------------------------------------------------------------------------- /5. EAV/2. EAV Attributes/3. Describe how to create and customize attributes.md: -------------------------------------------------------------------------------- 1 | # Describe how to create and customize attributes 2 | 3 | # 1. Create 4 | 5 | $installer->addAttribute( 6 | "colin_eav_blog", 7 | "intro", 8 | array( 9 | 'type' => 'text', 10 | 'label' => "Intro", 11 | 'input' => 'textarea', 12 | 'class' => '', 13 | 'backend' => '', 14 | 'frontend' => '', 15 | 'source' => '', 16 | 'required' => true, 17 | 'user_defined' => true, 18 | 'default' => '', 19 | 'unique' => true, 20 | ) 21 | ); 22 | 23 | # 2. Update 24 | 25 | $this->startSetup(); 26 | $helper = Mage::helper("core"); 27 | // Entity Type Code, Attribute Code, Attribute, Value 28 | $this->updateAttribute("colin_eav_blog", "content", "frontend_model", "colin_eav/attribute_frontend_content"); 29 | $this->endSetup(); 30 | 31 | # 3. Delete 32 | 33 | $setup = Mage::getResourceModel('catalog/setup','catalog_setup'); 34 | $setup->removeAttribute('catalog_product','attr_code'); 35 | -------------------------------------------------------------------------------- /4. Databases/2. Install:Update Scripts/3. Identify how to use the DDL class in setup scripts.md: -------------------------------------------------------------------------------- 1 | # Identify how to use the DDL class in setup scripts 2 | 3 | This is used to help: 4 | 5 | - create tables 6 | - create columns 7 | - add helpers (constants) for values 8 | 9 | 10 | # 1. addColumn 11 | 12 | This accepts the following parameters 13 | 14 | 1. Name 15 | 2. Type 16 | 3. Size 17 | 4. Options (array) 18 | 5. Comments 19 | 20 | So in our install script in previous notes we ran the following to create a column. 21 | 22 | $table->addColumn( 23 | 'id', 24 | Varien_Db_Ddl_Table::TYPE_INTEGER, 25 | 11, 26 | array( 27 | 'identity' => true, 28 | 'primary' => true 29 | ) 30 | ) 31 | 32 | # 1.1. Options 33 | 34 | It can accept the following Options 35 | 36 | - primary: boolean 37 | - default: boolean 38 | - nullable: boolean 39 | - auto_increment: boolean 40 | 41 | # 2. Other Methods to Do 42 | 43 | 44 | - dropColumn() 45 | - changeColumn() 46 | - modifyColumn() 47 | - addForeignKey() 48 | - dropForeignKey() 49 | - getForeignKeys() 50 | - insertOnDuplicate() 51 | - insertMultiple() 52 | - insertArray() 53 | 54 | 55 | # Other Useful Methods 56 | 57 | 58 | - dropTemporaryTable() 59 | - truncateTable() 60 | - isTableExists() 61 | - showTableStatus() 62 | - describeTable() 63 | - createTableByDdl() 64 | - modifyColumnByDdl() 65 | - renameTable() 66 | - tableColumnExists() 67 | -------------------------------------------------------------------------------- /7. Catalog/ 1. Product Types/3. Identify how custom product types interact with indexing, SQL, and underlying data structures.md: -------------------------------------------------------------------------------- 1 | # Identify how custom product types interact with indexing, SQL, and underlying data structures 2 | 3 | Please read [http://www.slideshare.net/ivanchepurnyi/magento-indexes](http://www.slideshare.net/ivanchepurnyi/magento-indexes) for more notes. 4 | 5 | 6 | Index Entities: 7 | 8 | - Product 9 | - Product Inventory 10 | - Category 11 | - Tag 12 | 13 | Scope: 14 | 15 | - Customer Group 16 | - Website 17 | - Store Group 18 | - Store View 19 | 20 | 21 | Process: 22 | 23 | Controller - Mage_Index_Model_Indexer 24 | Process - Mage_Index_Model_Process 25 | Indexer Base - Mage_Index_Model_Indexer_Abstract 26 | 27 | Mage_Index_Model_Indexer_Abstract 28 | 29 | Catalog: 30 | 31 | 1. Mage_Catalog_Model_Product_Indexer_EAV 32 | 2. Mage_Catalog_Model_Product_Indexer_Flat 33 | 3. Mage_Catalog_Model_Product_Indexer_Price 34 | 35 | Inventory: 36 | 37 | 1. Mage_Catalog_Model_Product_Indexer_Stock 38 | 39 | 40 | - How does indexing work for catalog_product_price 41 | - Tables 42 | 43 | - How indexing is called 44 | - Different types of indexing 45 | - How does it affect pricing 46 | 47 | 48 | # Futher Reading 49 | 50 | - [http://www.slideshare.net/ivanchepurnyi/magento-indexes](http://www.slideshare.net/ivanchepurnyi/magento-indexes) 51 | - [http://magento.stackexchange.com/questions/22157/how-indexing-works-in-magento](http://magento.stackexchange.com/questions/22157/how-indexing-works-in-magento) 52 | - 53 | -------------------------------------------------------------------------------- /7. Catalog/ 1. Product Types/4. Questions.md: -------------------------------------------------------------------------------- 1 | ## Which product types exist in Magento? 2 | 3 | 1. Simple 4 | 2. Grouped 5 | 3. Configurable 6 | 4. Virtual 7 | 5. Downloadable 8 | 6. Bundle 9 | 10 | ## Which product types are implemented as part of the Mage_Catalog module, and which are not? 11 | 12 | **Mage_Catalog**: 13 | 14 | 1. Simple 15 | 2. Grouped 16 | 3. Configurable 17 | 4. Virtual 18 | 19 | 20 | **Mage_Downloadable** 21 | 22 | 1. Downloadable 23 | 24 | **Mage_Bundle** 25 | 26 | 1. Bundle 27 | 28 | ## What steps need to be taken in order to implement a custom product type? 29 | 30 | 1. Add product type under xpath global/catalog/product/type/{type} 31 | 2. Add a product type class which extends from Mage_Catalog_Model_Product_Type_Abstract 32 | 33 | ## How do the different product types handle calculation? 34 | 35 | - Using the price model and then returning the price in the method getFinalPrice() 36 | 37 | ## Which indexing processes does the product type influence? 38 | 39 | Product Price - Mage_Catalog_Model_Product_Indexer_Price 40 | Magento also gets the price from the index table when using collections. 41 | 42 | ## Which product types implement a parent-child relationship between product entities? 43 | 44 | 1. Grouped 45 | 2. Configurable 46 | 3. Bundle 47 | 48 | ## Which database tables are shared between product types, and which ones are specific to one product type? 49 | 50 | - Configurable: catalog_product_super_link 51 | - Configurable, Grouped, Bundle: catalog_product_relation 52 | - Grouped - catalog_product_link (also used for related, cross and upsells) 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Colin Murphy 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of magento-exam-notes nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /2. Request Flow/6. Design and layout initialization/Questions.md: -------------------------------------------------------------------------------- 1 | ## Which ways exist to specify the layout update handles that will be processed during a request? 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ## Which classes are responsible for the layout being loaded? 13 | 14 | - Mage_Core_Controller_Front_Action 15 | - Mage_Core_Controller_Varien_Action 16 | - Mage_Core_Model_Layout 17 | - Mage_Core_Model_Layout_Handle 18 | - Mage_Core_Model_Layout_Element 19 | 20 | ## How are layout xml directives processed? 21 | 22 | 1. Mage_Core_Controller_Varien_Action::loadLayout() – processes the request to load layout 23 | 2. Mage_Core_Model_Layout::\_\_construct() – loads layout xml 24 | 3. Mage_Core_Model_Layout_Update::load() – load layout updates by handles 25 | 26 | ## Which configuration adds a file containing layout xml updates to a module? 27 | 28 | Modules config.xml 29 | 30 | 31 | 32 | 33 | 34 | catalog.xml 35 | 36 | 37 | 38 | 39 | 40 | ## Why is the load order of layout xml files important? 41 | 42 | All layout files are merged in one XML object Mage_Core_Model_Layout_Element. 43 | The later the file is loaded, the less chance it will be overridden by another layout.xml file. 44 | 45 | This is why local.xml is loaded last or as of 1.9 the themes.xml file/files. 46 | -------------------------------------------------------------------------------- /8. Checkout/3. Shipping and payment methods in Magento/2. Describe the shipping rates calculation process.md: -------------------------------------------------------------------------------- 1 | # Describe the shipping rates calculation process: 2 | 3 | In **Mage_Sales_Model_Quote_Address** Mage_Shipping_Model_Shipping->collectRates() is called. 4 | 5 | $result = Mage::getModel('shipping/shipping')->collectRates($request)->getResult(); 6 | 7 | This then gets all the carriers and checks their credentials (country etc) and calls collectRates($request) for each valid carrier. 8 | 9 | 10 | # Questions 11 | ## How does Magento calculate shipping rates? 12 | 13 | 1. Firstly it gets all carriers under default -> carriers. 14 | 2. It then validates and calls the collectRates method which returns a Mage_Shipping_Model_Rate_Result object with rates in the 15 | Mage_Shipping_Model_Rate_Result_Method class. 16 | 17 | ## What is the hierarchy of shipping information in Magento? 18 | 19 | Rates are stored in sales_flat_quote_shipping_rate 20 | 21 | ## How does the TableRate shipping method work? 22 | 23 | This allows for a CSV to be uploaded and imported into **shipping_tablerate** table. 24 | 25 | This contains: 26 | 27 | 1. website_id 28 | 2. dest_country_id 29 | 3. dest_region_id 30 | 4. dest_zip 31 | 5. condition_name 32 | 6. condition_value 33 | 7. price 34 | 8. cost 35 | 36 | It can have the following conditions: 37 | 38 | 1. Price vs Destination - code: price 39 | 2. Weight vs Destination - code: weight 40 | 3. Items vs Destination - code: qty 41 | 42 | 43 | ## How do US shipping methods (FedEX, UPS, USPS) work? 44 | 45 | These methods use the abstract class Mage_Usa_Model_Shipping_Carrier_Abstract to collect the rate. 46 | They are usually made through 3rd party services via HTTP or SOAP requests. 47 | -------------------------------------------------------------------------------- /4. Databases/3. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | # 1. Models, Resource Models & Collections 2 | 3 | - How do you register a custom table for a Resource Model 4 | - What is the xpath for the table name for the custom table 5 | - How do you register a model, resource model and collection to use a custom table 6 | - Name abstract classes for Model, Resource Model and Collections 7 | - How do you register a setup script in the config.xml 8 | - What is the name of the class does $this refer to in a SQL setup script 9 | - What is the name of the class does $this->getConnection() refer to in a SQL setup script 10 | - How do you register a custom connection 11 | - How do you override the default_setup connection outside of local.xml file 12 | - What are the different ways of loading a row with Mage::getModel() 13 | - How would you save additional data after a product was saved 14 | - How do you get Varien_Db_Select in Magento 15 | - How to make from, where, and, or query in Magento using Varien_Db_Select 16 | - How do you make a join query with Varien_Db_Select 17 | - What methods are available for joins with Varien_Db_Select 18 | - How do you filter a field in a collection 19 | - How do you filter a attribute in a collection 20 | - How do you order a Collections 21 | - How do you set a limit for a Collection 22 | 23 | # 2. Install/Update Scripts 24 | 25 | - What is the name of the method to get Table name for Mage_Core_Model_Resource and Mage_Core_Model_Mysql4_Abstract 26 | - How do you create a table with a install script 27 | - How do you start and end a setup script 28 | - Name the methods which are called for install/upgrade setup and data scripts in the Request Initialization 29 | - path to install setup script and data script 30 | - path to upgrade setup script and data script 31 | -------------------------------------------------------------------------------- /2. Request Flow/8. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | # 1. Application Initialization 2 | 3 | - List the events which happen in index.php 4 | - What are the parameters for MAGE_RUN_CODE 5 | - What are the parameters for MAGE_RUN_TYPE 6 | - How do you set a different website in the .htaccess file for Apache web server 7 | - How do you init the Mage_Core_Model_App env without a request 8 | - What is the order of base, module & database loaded and what are their methods and class 9 | - What order are modules loaded in and what method sorts the modules 10 | - What is loaded after module files are loaded 11 | - What is the name of the resource config (Mage_Core_Model_Resource_Config) 12 | - Mage_Core_Model_Resource_Config->loadToXml() what does it load into the config 13 | - How and when are the two main types of setup script executed? 14 | 15 | # 2. Front Controller 16 | 17 | - Name the class for the Front, Frontend and Admin router 18 | - What are the use node frontend and admin router 19 | - What are the 4 routers in order 20 | - How do you add a router before the default router 21 | - What action class does a frontend and admin router extend from 22 | - What is the method a new router needs and what abstract class should it extend from 23 | - What are the xpaths for web configuration 24 | 25 | # 3. Modules 26 | - What class is responsible for loading Modules 27 | - What is the difference regarding module loading between Mage::run() and Mage::app()? 28 | 29 | # 4. Layout Initialization 30 | - What class is responsible for layout 31 | - What are the 2 methods required to render layout in a Controller 32 | - What is the config for a module to add its own layout xml file 33 | - What does Mage_Core_Controller_Varien_Action->loadLayout() do 34 | - How are directives parsed 35 | - How do you add a custom layout handle 36 | - How do you add content from an observer 37 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/6. Explain class naming conventions and their relationship with the autoloader.md: -------------------------------------------------------------------------------- 1 | # Explain class naming conventions and their relationship with the autoloader 2 | 3 | ## 1. Overview 4 | 5 | As previously mentioned the autoloader can be found under the "lib/Varien" directory. 6 | 7 | A class is loaded as follows: 8 | 9 | ## 2. Sets the include paths 10 | 11 | As explained previously there are 4 include paths loaded with the *set_include_path* function in *app/Mage.php*. 12 | 13 | The *lib/Varien/Autoload.php* file is included once so the class *Varien_Autoload* can be called. 14 | 15 | 16 | ## 3. Autoloader 17 | 18 | 19 | The *autoload* method of the class is registered with *spl_autoload_register* function. 20 | 21 | This method then does the following when autoloading a class: 22 | 23 | - Replaces any underscore with a space 24 | - Uppercases the filename using *ucwords* 25 | - Replaces the space with the *DIRECTORY_SEPARATOR* 26 | - Appends .php to the end of the file 27 | 28 | 29 | So for instance the class *Mage_Catalog_Model_Product* filename would autoload the file *Mage/Catalog/Model/Product.php*. 30 | 31 | As the includes are set, PHP would search in all 3 codepools for this file so eventually it would find the file under *app/code/core/Mage/Catalog/Model/Product.php*. 32 | 33 | 34 | ## 4. Further Reading 35 | 36 | - [http://magestudyguide.com/#explain-class-naming-conventions-and-their-relationship-with-the-autoloader](http://magestudyguide.com/#explain-class-naming-conventions-and-their-relationship-with-the-autoloader) 37 | 38 | - [http://blog.belvg.com/get-ready-for-magento-certified-developer-exam-class-naming-conventions-and-their-relationship-with-the-autoloader.html](http://blog.belvg.com/get-ready-for-magento-certified-developer-exam-class-naming-conventions-and-their-relationship-with-the-autoloader.html) 39 | -------------------------------------------------------------------------------- /1. Basics/4. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | 2 | # 1. Architecture 3 | 4 | - What is the order of codepools loaded 5 | - Name all locations an Autoloader will search for a file 6 | - Name the class of the Autoloader 7 | - How do you register a parent theme 8 | - Where can JavaScript files be located 9 | - How do you register JavaScript in your theme 10 | - How do you resolve a Configuration conflict 11 | - How do you resolve a Rewrite conflict 12 | 13 | # 2. Configuration 14 | 15 | - What is the xpath for Mage_Core_Model_Sales_Order 16 | - How do you rewrite Mage_Core_Model_Sales_Order 17 | - What is the xpath for a rewrite for Mage_Page_Block_Html_Head 18 | - When a factory file is not found, where is the last place the method checks e.g. Colin_Basics_Block_Head 19 | - In which order does local.xml, module config.xml and database config load in. 20 | - How do you set default value for a store and website 21 | - How do you register a controller 22 | - How do you rewrite the catalog controller 23 | - How do you load a controller before or after the catalog controller 24 | - How do you create an event for an observer 25 | - Name the observer class 26 | - How do you register a CRON 27 | - What does Mage_Cron_Model_Observer::dispatch() do 28 | - How do you register default values for a store in the config.xml 29 | - How do you register default values for a website in the config.XML 30 | - How do you get an instance of a block 31 | - Difference between getModel and getSingleton 32 | - How do you get version of Magento 33 | - How do you register a variable 34 | - What is Mage::registry used for 35 | 36 | # 3. Internationalization 37 | 38 | - Name the main class for translations 39 | - Name the different type of translations 40 | - What is the order of translations being loaded 41 | - How does developer mode affect translations 42 | - How does a module add a translation file 43 | -------------------------------------------------------------------------------- /4. Databases/2. Install:Update Scripts/4. Questions.md: -------------------------------------------------------------------------------- 1 | ## 1. Under which circumstances are setup scripts executed? 2 | 3 | - Page is not cached 4 | - Version number has changed 5 | 6 | ## 2. What is the difference between the different classes used to execute setup scripts? 7 | 8 | 1. Non EAV/Flat: Mage_Core_Model_Resource_Setup 9 | 2. EAV: Mage_Eav_Model_Entity_Setup 10 | 11 | ## 3. Which is the base setup class for flat table entities, and which one the base for EAV entities? 12 | 13 | 1. Non EAV/Flat: Mage_Core_Model_Resource_Setup 14 | 2. EAV: Mage_Eav_Model_Entity_Setup 15 | 16 | ## 4. Which methods are generally available in setup scripts to manipulate database tables and indexes? 17 | 18 | - addColumn() 19 | - dropColumn() 20 | - changeColumn() 21 | - modifyColumn() 22 | - dropTemporaryTable() 23 | - truncateTable() 24 | - isTableExists() 25 | - showTableStatus() 26 | - describeTable() 27 | - createTableByDdl() 28 | - modifyColumnByDdl() 29 | - renameTable() 30 | - tableColumnExists() 31 | - addForeignKey() 32 | - dropForeignKey() 33 | - getForeignKeys() 34 | - insertOnDuplicate() 35 | - insertMultiple() 36 | - insertArray() 37 | 38 | ## 5. What is the difference between addAttribute() and updateAttribute() in EAV setup scripts? 39 | 40 | – addAttribute: if id is existed then updateAttributes was called otherwise it will insert new attribute and attribute options. 41 | – updateAttributes: Update Attribute data and Attribute additional data. 42 | 43 | ## 6. How can you implement a rollback in Magento? 44 | 45 | Change the version number and the following part is called in Mage_Core_Model_Resource_Setup->applyUpdates() 46 | 47 | if ($dbVer !== false) { 48 | $status = version_compare($configVer, $dbVer); 49 | switch ($status) { 50 | case self::VERSION_COMPARE_LOWER: 51 | $this->\_rollbackResourceDb($configVer, $dbVer); 52 | break; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /9.Sales & Customers/3. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | # 1. Admin Order Creation 2 | 3 | - How do you prevent a payment method being used by an admin order 4 | - What is the controller for creating admin Orders 5 | - What is abstract class for admin order controllers 6 | - How does Magento calculate price when an order is created from the admin 7 | - Which steps are necessary in order to create an order from the admin? 8 | - What happens when existing orders are edited in the admin? 9 | - Describe the differences in order creation between the frontend and the admin? 10 | 11 | # 2. Order Status & State 12 | 13 | - Difference between status and state 14 | - List all states in order 15 | - How do you add your own state 16 | - How do you add statuses to a state 17 | - When would an order be closed 18 | - If an order is invoiced or shipped, what status would it be 19 | - If an order is complete, can it be refunded (credit memo) 20 | 21 | # 3. Fieldsets 22 | 23 | # 4. Card Authorization and Capture 24 | 25 | - Which class is responsible for capturing funds 26 | - What class is responsible for creating an invoice 27 | - What class is the payment class 28 | - Whats the difference between authorize and capture 29 | - When are invoices created 30 | - What are the different types of captures 31 | - How would a custom payment gateway authorize and capture funds 32 | 33 | # 5. Credit Memos 34 | 35 | - What state is an order set to after being refunded. 36 | - When can an order not be refunded? 37 | - How does Magento process taxes when refunding an order? 38 | - How does Magento process shipping fees when refunding an order? 39 | - What is the difference between online and offline refunding? 40 | - What is the role of the credit memo total models in Magento? 41 | 42 | # 6. Cancelled Orders 43 | 44 | - When can an order be cancelled 45 | 46 | # 7. Partial Order Operations 47 | 48 | - What are the different types 49 | - How do they affect the state of an order 50 | -------------------------------------------------------------------------------- /9.Sales & Customers/1. Sales/4. Describe the architecture and processing of refunds.md: -------------------------------------------------------------------------------- 1 | # Describe the architecture and processing of refunds: 2 | 3 | # 1. Overview 4 | 5 | Invoices in Magento are Credit Memos. Orders can only be refunded when the order has been invoiced. 6 | Magento stores the refund in the EAV "credimemo" and refunded in the class **Mage_Sales_Model_Order_Creditmemo**. 7 | The payment method Mage_Payment_Model_Method_Abstract->refund() is also used when refunding a order. 8 | 9 | 10 | # 1. How to refund 11 | 12 | 1. Go to Sales -> Order 13 | 2. Edit Order 14 | 3. Click "Credit Memo" 15 | 4. Click Refund 16 | 17 | In the controller **Mage_Adminhtml_Sales_Order_CreditmemoController->newAction** creates the invoice. 18 | At this point **Mage_Sales_Model_Order_Creditmemo->refund()** is called which creates the refund. 19 | 20 | The order status is set to closed. 21 | 22 | 23 | # 2. Tables 24 | 25 | **sales_flat_creditmemo** 26 | 27 | Stores the payment information, created date etc 28 | 29 | **sales_flat_creditmemo_comment** 30 | 31 | Stores any comments. 32 | 33 | **sales_flat_creditmemo_grid** 34 | 35 | Stores totals. 36 | 37 | **sales_flat_creditmemo_item** 38 | 39 | Stores items which are returend. 40 | 41 | # Questions 42 | 43 | Which classes are involved, and which tables are used to store refund information? 44 | 45 | See above 46 | 47 | 48 | ## How does Magento process taxes when refunding an order? 49 | 50 | It basis it off admin tax origin. 51 | 52 | ## How does Magento process shipping fees when refunding an order? 53 | 54 | Handled by the Credit Memo model when calculating diffent totals. 55 | 56 | ## What is the difference between online and offline refunding? 57 | 58 | Offline refunds refund the order on Magento without actually taking care of the refund transaction. Whereas online does both. 59 | 60 | ## What is the role of the credit memo total models in Magento? 61 | 62 | Credit memo totals keep a track on how much is refunded per total. 63 | -------------------------------------------------------------------------------- /1. Basics/2. Configuration/4. Register an Observer.md: -------------------------------------------------------------------------------- 1 | # Register an Observer 2 | 3 | ## 1. Overview 4 | 5 | There is 2 parts to an observer: 6 | 1. Creating an observer in a controller/model/helper/block class 7 | 2. Calling the observer with XML and your code 8 | 9 | 10 | ## 2. Create an observer 11 | 12 | You create an observer using the factory method *Mage::dispatchEvent($name, array $data = array())* 13 | 14 | In the example below we are going to duplicate the quantity by 2 for the final price. 15 | So the observer in Magento is: 16 | 17 | 18 | Mage::dispatchEvent('catalog_product_get_final_price', array('product' => $product, 'qty' => $qty)); 19 | 20 | ## 3. Call Observer in your Module 21 | 22 | So in your config.xml under the global -> events node we would add the following. 23 | 24 | 25 | 26 | 27 | 28 | 29 | singleton 30 | Colin_Bootstrap_Model_Observer_Price 31 | duplicateFinalPrice 32 | 33 | 34 | 35 | 36 | 37 | As you can see *catalog_product_get_final_price* is the name of the observer event. 38 | 39 | Then in a observer class you would add the following: 40 | 41 | class Colin_Bootstrap_Model_Observer_Price extends Mage_Core_Model_Abstract 42 | { 43 | 44 | /** 45 | * Duplicates the final Price 46 | * 47 | * @param Varien_Event_Observer $observer 48 | */ 49 | public function duplicateFinalPrice($observer) 50 | { 51 | $price = $observer->getEvent()->getProduct()->getFinalPrice(); 52 | $price = $price * 2; 53 | $observer->getEvent()->getProduct()->setFinalPrice($price); 54 | } 55 | 56 | } 57 | 58 | Please note that parameter product is called using $observer->getEvent()->getProduct() 59 | Similarly if we wanted to get the quantity it would be $observer->getEvent()->getQty() 60 | -------------------------------------------------------------------------------- /5. EAV/1. EAV Concepts/3. Describe the EAV entity structure and its difference from the standard core resource mode.md: -------------------------------------------------------------------------------- 1 | # Describe the EAV entity structure and its difference from the standard core resource mode 2 | 3 | Excluding the obvious differences below is a list of differences 4 | 5 | 6 | ## 1. Different Resource Model 7 | 8 | 9 | **Flat Resource:** 10 | 11 | This sets the main table and field. 12 | 13 | class Colin_Database_Model_Resource_Results extends Mage_Core_Model_Resource_Db_Abstract 14 | { 15 | protected function _construct() 16 | { 17 | $this->_init('colin_database/results', 'id'); 18 | } 19 | } 20 | 21 | **EAV Resource:** 22 | 23 | This sets the EAV type and connections. 24 | 25 | 26 | class Colin_EAV_Model_Resource_Blog extends Mage_Eav_Model_Entity_Abstract 27 | { 28 | protected function _construct() 29 | { 30 | $resource = Mage::getSingleton('core/resource'); 31 | $this->setType('colin_eav_blog'); 32 | $this->setConnection( 33 | $resource->getConnection('core_read'), 34 | $resource->getConnection('core_write') 35 | ); 36 | } 37 | } 38 | 39 | 40 | ## 2. Different Collection 41 | 42 | **Flat Resource:** 43 | 44 | class Colin_Database_Model_Resource_Results_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract 45 | { 46 | public function _construct() 47 | { 48 | $this->_init('colin_database/results'); 49 | } 50 | } 51 | 52 | **EAV Resource:** 53 | 54 | class Colin_Eav_Model_Resource_Blog_Collection extends Mage_Eav_Model_Entity_Collection_Abstract 55 | { 56 | protected function _construct() 57 | { 58 | $this->_init('colin_eav/blog'); 59 | } 60 | } 61 | 62 | ## 3. Different Setup Model 63 | 64 | - **Flat Resource:** Extends from Mage_Core_Model_Resource_Setup 65 | - **EAV Resource:** Extends from Mage_Eav_Model_Entity_Setup 66 | 67 | 68 | ## 4. Different Filters & Selects for Collections 69 | 70 | - **Flat Resource:** ->addFieldToFilter(); 71 | - **EAV Resource:** ->addAttributeToFilter(); 72 | -------------------------------------------------------------------------------- /5. EAV/1. EAV Concepts/4. Describe the EAV load-and-save process and its differences from the regular loadand-save process.md: -------------------------------------------------------------------------------- 1 | # Describe the EAV load-and-save process and its differences from the regular load and save process 2 | 3 | 4 | # 1. Load 5 | 6 | ## 1.1. Flat 7 | 8 | **Example:** We will load the following table 9 | 10 | $flat = Mage::getModel('colin_database/results')->load(1); 11 | 12 | The model calls the Resource model load in between *_beforeSave()* and *_afterSave()* 13 | 14 | **Mage_Core_Model_Resource_Db_Abstract->load()** 15 | 16 | This does the following: 17 | 18 | 1. Gets the main field 19 | 2. Creates a Varien_Db_Select object for the query with the main field in 20 | 21 | 22 | $select = $this->_getLoadSelect($field, $value, $object); 23 | 24 | So the query if called the __toString method would be 25 | 26 | SELECT `football_results`.* FROM `football_results` WHERE (`football_results`.`id`=1) 27 | 28 | 3. Fetches Row from Read Adapter 29 | 30 | $read->fetchRow($select); 31 | 32 | 33 | ## 1.2. EAV 34 | 35 | 36 | **Example:** 37 | 38 | $eav = Mage::getModel('colin_eav/blog')->load(1); 39 | 40 | This does the same and calls the Resource Model load. 41 | 42 | **Mage_Eav_Model_Entity_Abstract->load($object, $entityId, $attributes = array())** 43 | 44 | 1. Loads the main row from "blog_entity". 45 | 46 | $select = $this->_getLoadRowSelect($object, $entityId); 47 | $row = $this->_getReadAdapter()->fetchRow($select); 48 | 49 | 50 | 2. Checks if $attribute is empty. If it is it will load all attributes with *loadAllAttributes* or otherwise loop through the attributes and load each one by *getAttribute($code)*. 51 | 52 | 53 | 3. Loads attributes to the $object with 54 | 55 | 56 | $this->_loadModelAttributes($object) 57 | 58 | 59 | ### 1.2.1. loadAllAttributes 60 | 61 | This will get an array of attributes with the following code and then load the attribute with *getAttribute($code)* 62 | 63 | $attributeCodes = Mage::getSingleton('eav/config') 64 | ->getEntityAttributeCodes($this->getEntityType(), $object); 65 | 66 | 67 | # 2. Save 68 | 69 | - Flat tables save to 1 row in **Mage_Core_Model_Resource_Db_Abstract->save($object)** 70 | - EAV tables save to multiple tables with **Mage_Eav_Model_Entity_Abstract->save($object)** 71 | -------------------------------------------------------------------------------- /2. Request Flow/2. Front Controller/Questions.md: -------------------------------------------------------------------------------- 1 | # Which ways exist in Magento to add router classes 2 | 3 | There are 2 ways: 4 | 1. Web -> routers in config.xml 5 | 2. Observer 6 | 7 | 8 | # 1. Web -> Routers 9 | 10 | *app/etc/code/local/Colin/Request/config.xml* 11 | 12 | 13 | 14 | 15 | 16 | 17 | my_area_name 18 | Colin_Request_Controller_Router 19 | 20 | 21 | 22 | 23 | *app/etc/code/local/Colin/Request/Controller/Router.php* 24 | 25 | 26 | class Colin_Request_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract 27 | { 28 | public function match(Zend_Controller_Request_Http $request) 29 | { 30 | // Match URL and router here 31 | } 32 | } 33 | 34 | 35 | # 2. Observer 36 | 37 | 38 | *app/code/local/Colin/Request/config.xml* 39 | 40 | 41 | 42 | 43 | 44 | 45 | singleton 46 | Colin_Request_Model_Observer 47 | controllerFrontInitRouters 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *app/code/local/Colin/Request/Model/Observer.php* 56 | 57 | 58 | class Colin_Request_Model_Observer extends Mage_Core_Model_Abstract 59 | { 60 | 61 | public function controllerFrontInitRouters($observer) 62 | { 63 | $front = $observer->getEvent()->getFront(); 64 | $router = new Colin_Request_Controller_Router_First(); 65 | $front->addRouter('first', $router); 66 | } 67 | 68 | } 69 | 70 | 71 | *app/code/local/Colin/Request/Controller/Router.php* 72 | 73 | class Colin_Request_Controller_Router_First extends Mage_Core_Controller_Varien_Router_Abstract 74 | { 75 | public function match(Zend_Controller_Request_Http $request) 76 | { 77 | // Do custom check and add controller before 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /3. Rendering/1. Theme.md: -------------------------------------------------------------------------------- 1 | # Themes 2 | 3 | ## How you can use themes to customize core functionality? 4 | 5 | You can change the layout, skin and blocks of the website. 6 | 7 | ## How can you implement different designs for different stores using Magento themes? 8 | 9 | **Example:** 10 | 11 | Website -> Store -> 12 | - 1. English Store 13 | - 2. French Store 14 | 15 | So you would have a package called "batman" and a theme called "default". 16 | This extends from base/default (in 1.8) 17 | 18 | You also have a theme called "returns" 19 | 20 | So for 1.8 (exam currently used) you would add everything into batman/default. 21 | 22 | Then any changes you needed for the 2nd theme which you use on the French store you would add to "returns" theme. 23 | 24 | You could also have both sites running off batman/default but specify a different part to use in "returns": 25 | 26 | 1. Translations 27 | 2. Templates 28 | 3. Skin 29 | 4. Layout 30 | 5. Default (Theme) 31 | 32 | Also if you needed different design for category, product and CMS pages thats possible too. 33 | 34 | ## In which two ways you can register custom theme? 35 | 36 | - System -> Configuration -> Design 37 | - System -> Design for seasonal design like Christmas 38 | 39 | 40 | ## What is the difference between package and theme? 41 | 42 | Package is a placeholder for multiple themes. 43 | 44 | ## What happens if the requested file is missed in your theme/package? 45 | 46 | It will look in the parent theme (default) and then base/default. 47 | In 1.9 (not part of the exam) it will keep looking in parent themes which could be a lot more than 2. 48 | 49 | ## Which kind of paths (absolute or relative) does Magento use for templates and layout files? 50 | 51 | Uses relative. 52 | 53 | 54 | ## How exactly can Magento define which physical file correspond to certain template/layout to use? 55 | 56 | Mage_Core_Model_Design_Package 57 | ->getLayoutFilename() 58 | ->getTemplateFilename() 59 | 60 | Both methods call getFilename($file, $params = array()); 61 | 62 | 63 | ## Which classes and methods need to be rewritten in order to add additional directories to the fallback list? 64 | 65 | Mage_Core_Model_Design_Fallback->getFallbackScheme(); 66 | Mage_Core_Model_Design_Package->_fallback(); 67 | Mage_Core_Model_Design_Package->getFilename(); 68 | Mage_Core_Model_Design_Package->getSkinUrl(); 69 | -------------------------------------------------------------------------------- /1. Basics/2. Configuration/3. Describe the process and configuration of class overrides in Magento.md: -------------------------------------------------------------------------------- 1 | # Describe the process and configuration of class overrides in Magento 2 | 3 | 4 | ## 1. Overview 5 | 6 | This was covered for models, blocks and helpers in the wiki [Explain how Magento loads and manipulates configuration information](https://github.com/colinmurphy/magento-exam-notes/blob/master/1.%20Basics/2.%20Configuration/1.Explain%20how%20Magento%20loads%20and%20manipulates%20configuration%20information.md) 7 | 8 | 9 | Example: 10 | 11 | 12 | 13 | 14 | 15 | Colin_Two_Model_Rewrite_Sales_Order 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ## 2. Controllers 24 | 25 | Controllers are loaded differently than models, blocks or helpers. This will be covered in the Request Flow but for now this is how you would rewrite a controller. 26 | 27 | In this example we are going to override the product controller. 28 | 29 | ## 2.1 Example 1: Replace Controller 30 | 31 | So in our config.xml we would add the following: 32 | 33 | 34 | 35 | 36 | 37 | standard 38 | 39 | Colin_Bootstrap 40 | catalog 41 | 42 | 43 | 44 | 45 | 46 | We would then require the product controller in our new controller. 47 | 48 | *app/code/local/Colin/Bootstrap/controllers/ProductController* 49 | 50 | require_once MAGENTO_ROOT . '/app/code/core/Mage/Catalog/controllers/ProductController.php'; 51 | class Colin_Bootstrap_ProductController extends Mage_Catalog_ProductController 52 | { 53 | 54 | } 55 | 56 | ## 2.2 Example 2: Before/After Controller 57 | 58 | Magento allows you to a controller to load before/after a controller. 59 | We would add the following to our config.xml 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Colin_Request 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /2. Request Flow/1. Application Initialization/Questions.md: -------------------------------------------------------------------------------- 1 | ### 1. How and when is the include path set up and the auto loader registered? 2 | 3 | - These are loaded once the Mage file has been included in the index.php before Mage::run(); 4 | - This uses an array of set_include_paths to search the 3 codepools and lib directories for files. 5 | - Classes are loaded by separating the underscore as the directory separator in the autoload class and found in the 4 include directories. 6 | 7 | More info on autoloading can be found [here](https://github.com/colinmurphy/magento-exam-notes/blob/master/1.%20Basics/1.%20Architecture/6.%20Explain%20class%20naming%20conventions%20and%20their%20relationship%20with%20the%20autoloader.md) 8 | 9 | ### 2. How and when does Magento load the base configuration, the module configuration, and the database configuration? 10 | 11 | 1. Base - Mage_Core_Model_Config->loadBase() 12 | 2. Module - Mage_Core_Model_Config->loadModules() 13 | 3. Database - Mage_Core_Model_Config->loadDb() 14 | 15 | 16 | ### 3. How and when are the two main types of setup script executed? 17 | 18 | - Mage_Core_Model_Resource_Setup->applyAllUpdates() - Resource Scripts 19 | - Mage_Core_Model_Resource_Setup->applyAllDataUpdates() - Data Scripts 20 | 21 | applyAllUpdates() called in *Mage_Core_Model_App->_initModules()* after module config loaded. 22 | applyAllDataUpdates called in *Mage_Core_Model_App->run()* after modules loaded and store parameters set. 23 | 24 | 25 | ### 4. When does Magento decide which store view to use, and when is the current locale set? 26 | 27 | 1. In the index.php we set the run type and code. 28 | 2. Then after the module config is loaded we call - Mage_Core_Model_App->run() calls *Mage_Core_Model_App->_initCurrentStore();* 29 | 30 | #### Mage_Core_Model_App->\_initCurrentStore(); 31 | 32 | This sets the property current store by doing a switch statement on the type (website/store/group) and then getting the code from the config XML. 33 | 34 | 35 | ### 5. Which ways exist in Magento to specify the current store view? 36 | 37 | #### 1. index.php/.htaccess 38 | 39 | $\_SERVER['Mage_RUN_CODE'] and $\_SERVER['Mage_RUN_TYPE']; 40 | 41 | e.g. 42 | 43 | SetEnv MAGE_RUN_TYPE "website" 44 | SetEnv MAGE_RUN_CODE "german" 45 | 46 | 47 | ### 6. When are the request and response objects initialized? 48 | 49 | Early on when Mage_Core_Model_App->run() is called. 50 | Though the request and response would need to set as values in the options which is not passed in the method by default. 51 | -------------------------------------------------------------------------------- /7. Catalog/5. Other Skills/2. Implement, troubleshoot, and modify Magento tax rules.md: -------------------------------------------------------------------------------- 1 | # Implement, troubleshoot, and modify Magento tax rules 2 | 3 | 4 | 5 | # 1. Tax Classes 6 | 7 | Tax has 2 tax classes: 8 | 9 | 1. Product 10 | 2. Customer Group 11 | 12 | These classes are applied to products and customer groups and is used then to add tax using a tax rule. 13 | When you create a customer group you set a name and customer tax class. 14 | When you create a product you set a tax group. 15 | 16 | # 2. Tax Rates 17 | 18 | Taxes are stored in the **tax_calculation_rate** table. They have the following options: 19 | 20 | - Identifier 21 | - Country 22 | - State 23 | - Zip/Post Code 24 | - Percent 25 | 26 | 27 | # 3. Tax Rules 28 | 29 | So in Magento Tax is applied to a customer group or product with a certain tax class. These are set in the Tax Rules. 30 | 31 | Tax Rules have the following parameters: 32 | 33 | - Name 34 | - Customer Tax Class - multiselect of customer tax classes it applies to 35 | - Product Tax Class - multiselect of product tax classes it applies to 36 | - Tax Rate - multiselect of tax rates to apply to 37 | - Priority - Used to sort the order of rules. If an order has multiple rules with the same priority they are combined and applied. 38 | 39 | 40 | # 4. How Tax is Calulated 41 | 42 | Tax is determined by the following factors: 43 | 44 | 1. Customer Group/Product Tax Class 45 | 2. Address - configuration setting and can be based on shipping, billing address or origin 46 | 47 | Other factors which affect the total are under System -> Configuration -> Tax -> Calculation Settings: 48 | 49 | **1. Tax Calculation Method Based On** 50 | - Total 51 | - Unit Price 52 | - Row Total 53 | 54 | **2. Catalog Prices** 55 | Whether prices added include/exclude tax added by admin. 56 | 57 | **3. Shipping Prices** 58 | Whether shipping prices include/exclude tax added by admin. 59 | 60 | **4. Apply Customer Tax** 61 | Apply before/after discount 62 | 63 | **5. Apply Discount On Prices** 64 | Apply discount on products inc/exc tax if apply after discount is selected in the precious option. 65 | 66 | **6. Apply Tax On** 67 | - Custom Price if available 68 | - Original Price 69 | 70 | **7. Enable Cross Border Trade** 71 | When catalog price includes tax, enable this setting will fix the price no matter what the customer's tax rate is. 72 | 73 | 74 | # Further Reading 75 | 76 | - [http://www.divisionlab.com/solvingmagento/taxes-in-magento-module-mage_tax/](http://www.divisionlab.com/solvingmagento/taxes-in-magento-module-mage_tax/) 77 | -------------------------------------------------------------------------------- /7. Catalog/6. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | # 1. Product Type 2 | 3 | - What 2 things do we need to do to create a product type 4 | - What is the xpath for a new product type 5 | - What are the parameters for a new product type 6 | - How do we implement a new price model 7 | - What option is required to allow product type have child products 8 | - What node is used to set allowed child products of a parent product type 9 | - How do we get a type instance class 10 | - What table is grouped products relationships stored in 11 | - What is link_type_id for cross sells, upsells and related products 12 | - What table is configurable products relationships stored in 13 | - What table is pricing for associated products for configurables stored in 14 | - What table is downloads stored in 15 | - What table is download pricing stored in 16 | - What table is associated bundle products stored in 17 | - What table are parent/child products stored in 18 | - What table is custom options stored in 19 | - What table is tiered pricing stored in 20 | 21 | 22 | # 2. Indexing 23 | 24 | # 3. Price Generation 25 | 26 | - What are the different price models 27 | - How do you change a price 28 | - Under what circumstances are product prices read from the index tables? 29 | - How do custom product options influence price calculation? 30 | - How are product tier prices implemented and displayed? 31 | 32 | # 4. Catalog Price Rules 33 | 34 | - What module is responsible for catalog price rules 35 | - What table are catalog price rules added to 36 | - How are catalog prices applied and what class and method is used to apply the discount 37 | - What are the 4 types of discounts 38 | - If a discount is applied to the catalog price rule and shopping cart rule and they both are set to stop processing which discounts get applied 39 | - What table is catalog rules saved to 40 | 41 | 42 | # 5. Tax 43 | 44 | - What module deals with Tax 45 | - Name 2 tax class types 46 | - What are the main tax tables 47 | - What are the parameters for Tax Rate 48 | - What are the main tax options for configuration and how do they affect pricing 49 | - If 2 tax rules have the same priority and apply to the address, what happens 50 | - If 2 tax rules have different priorities and apply to the address, what happens 51 | - If 2 tax rates in a rule, what happens 52 | - What are the 3 options for Tax Calculation Method Based On 53 | - How is tax calculated and in what class and method 54 | 55 | 56 | # 6. Custom Options 57 | 58 | 59 | # 6. Other Skills 60 | 61 | - What is the name of the class for product filters 62 | -------------------------------------------------------------------------------- /1. Basics/2. Configuration/2. Describe class group configuration and use in factory methods.md: -------------------------------------------------------------------------------- 1 | # Describe class group configuration and use in factory methods 2 | 3 | 4 | ## Overview 5 | 6 | **Note:** Please note this was covered in the wiki [Explain how Magento loads and manipulates configuration information](https://github.com/colinmurphy/magento-exam-notes/blob/master/1.%20Basics/2.%20Configuration/1.Explain%20how%20Magento%20loads%20and%20manipulates%20configuration%20information.md) 7 | 8 | Below is a list of Factory methods used to get a class in Magento. 9 | 10 | $helper = Mage::helper( 'core' ); 11 | $model = Mage::getModel( 'sales/order' ); 12 | $resourceModel = Mage::getResourceModel( 'catalog/product' ); 13 | $modelSingleton = Mage::getSingleton( "sales/order" ); 14 | $resourceModelSingleton = Mage::getResourceSingleton( 'catalog/product' ); 15 | 16 | 17 | 18 | ## 1. Notes on some Factory Methods 19 | 20 | 21 | #### Helper - $helper - Mage::helper('core'); 22 | 23 | If there is no forward slash, "/data" is appended to the string. 24 | So in the example above it would load *Mage_Core_Helper_Data* 25 | 26 | 27 | #### Resource Model - Mage::getResourceModel('catalog/product'); 28 | 29 | 30 | When registering a resource model your config.xml would like the following: 31 | 32 | 33 | 34 | Mage_Catalog_Model 35 | catalog_resource 36 | 37 | 38 | Mage_Catalog_Model_Resource 39 | 40 | 41 | There is 2 important parts to note, the *resourceModel* node and the class node in *catalog resource*. 42 | 43 | So this method replaces the group name (catalog) with the resource model node name (catalog_resource) before calling the method *getModelInstance* which resolves the class name. 44 | 45 | This is changed in the method *_getResourceModelFactoryClassName*. 46 | 47 | 48 | #### Singleton = Mage::getSingleton("sales/order"); 49 | 50 | This is the same as Mage::getModel() but the only difference is that the class when loaded is added to the registry using the Singleton Pattern. This stops the class from be loaded twice. 51 | 52 | 53 | The model is saved to the static *$registry* property in the class *Mage*. 54 | 55 | $registryKey = '_singleton/'.$modelClass; 56 | if (!self::registry($registryKey)) { 57 | self::register($registryKey, self::getModel($modelClass, $arguments)); 58 | } 59 | return self::registry($registryKey); 60 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/10. Questions.md: -------------------------------------------------------------------------------- 1 | ## 1. Which methods exist to access the table of a resource model? 2 | 3 | Mage::getModel('core/resource')->getTableName('colin_database/results'); 4 | Mage::getModel('core/resource')->getMainTable('colin_database/results'); 5 | 6 | ## 2. Which methods exist to create joins between tables on collections and on select instances? 7 | 8 | - join() 9 | - joinInner() 10 | - joinLeft() 11 | - joinRight() 12 | - joinFull() 13 | - joinCross() 14 | - joinNatural() 15 | 16 | ## 3. How does Magento support different RDBMSs? 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 1 30 | 0 31 | 32 | 33 | 34 | 35 | wordpress_db 36 | 37 | 38 | 39 | 40 | wordpress_db 41 | 42 | 43 | 44 | 45 | 46 | $resource = Mage::getModel('core/resource')->getConnection('wordpress_read'); 47 | 48 | 49 | ## 4. How do table name lookups work, and what is the purpose of making table names configurable? 50 | 51 | Mage::getModel('core/resource')->getTableName('colin_database/results'); 52 | 53 | Which events are fired automatically during CRUD operations? 54 | 55 | - model_load_before 56 | - model_load_after 57 | - mode_save_before 58 | - model_save_after 59 | - model_delete_before 60 | - model_delete_after 61 | - model_delete_commit_after 62 | 63 | ## 5. How does Magento figure out if a save() call needs to create an INSERT or an UPDATE query? 64 | 65 | Checks for *$object->getId()* 66 | 67 | ## 6. How many ways exist to specify filters on a flat table collection? 68 | 69 | - $model->getCollection()->addFieldToFilter() 70 | - $model->getCollection()->getSelect()->where() 71 | 72 | 73 | ## 7. Which methods exist to influence the ordering of the result set for flat table collections? 74 | 75 | - $model->getCollection()->setOrder($field, $dir) 76 | - $model->getCollection()->getSelect()->order("$query") 77 | -------------------------------------------------------------------------------- /2. Request Flow/7. Flushing Data/1. JavaScript and CSS.md: -------------------------------------------------------------------------------- 1 | # How JavaScript and CSS is added 2 | 3 | # 1. Overview - Mage_Page_Block_Html_Head 4 | 5 | - JS and CSS added by Mage_Page_Block_Html_Head::getCssJsHtml() called in template. 6 | - JS added by addItem, addJs, addJsIe 7 | - CSS added by addItem, addCss, addCssIe 8 | - Ultimately all these methods call addItem 9 | - CSS & JS can be merged by config setting 10 | 11 | # 2. addItem 12 | 13 | **layout.xml** 14 | 15 | 16 | 17 | skin_css 18 | css/styles-ie.css 19 | 20 | lt IE 8 21 | 22 | 23 | 24 | **method** 25 | 26 | public function addItem($type, $name, $params=null, $if=null, $cond=null) 27 | { 28 | if ($type==='skin_css' && empty($params)) { 29 | $params = 'media="all"'; 30 | } 31 | $this->\_data['items'][$type.'/'.$name] = array( 32 | 'type' => $type, 33 | 'name' => $name, 34 | 'params' => $params, 35 | 'if' => $if, 36 | 'cond' => $cond, 37 | ); 38 | return $this; 39 | } 40 | 41 | **Output** 42 | 43 | 46 | 47 | 48 | # Merge CSS/JS 49 | 50 | So when returning items it checks to see if CSS/JS should be merged 51 | 52 | $shouldMergeJs = Mage::getStoreConfigFlag('dev/js/merge_files'); 53 | $shouldMergeCss = Mage::getStoreConfigFlag('dev/css/merge_css_files'); 54 | 55 | 56 | When adding HTML to variable $html which is returned element at the end it does the following: 57 | 58 | 59 | $html .= $this->\_prepareStaticAndSkinElements(''."\n", 60 | empty($items['js_css']) ? array() : $items['js_css'], 61 | empty($items['skin_css']) ? array() : $items['skin_css'], 62 | $shouldMergeCss ? array(Mage::getDesign(), 'getMergedCssUrl') : null 63 | ); 64 | 65 | 66 | The *$shouldMergeCss* get the model class *Mage_Core_Model_Design_Package* which is passed into *_prepareStaticAndSkinElements* 67 | 68 | Then in the method *_prepareStaticAndSkinElements* it calls *Mage_Core_Model_Design_Package->getMergedCssUrl()* which merges the CSS together and returns it. 69 | 70 | This is the same for JavaScript except it calls *getMergedJsUrl()* instead. 71 | 72 | 73 | # Further Reading 74 | 75 | [http://blog.belvg.com/magento-certified-developer-exam-flushing-data-output.html](http://blog.belvg.com/magento-certified-developer-exam-flushing-data-output.html) 76 | -------------------------------------------------------------------------------- /8. Checkout/5. Additional Notes/Questions.md: -------------------------------------------------------------------------------- 1 | # 1. Quote 2 | 3 | - What are the main tables for a quote and what their purpose 4 | - How does a a single shipping and MultiShipping quote differ 5 | - What is the class for a one page checkout and a MultiShipping checkout 6 | - Where is additional information for a quote stored 7 | - Difference between grand_total and base_grand_total 8 | - What class and method adds a product to the cart/quote 9 | - How do product types apply add their own data to a quote when a product is added to the cart 10 | - When exactly does inventory decrementing occur 11 | - When exactly does card authorization and capturing occur 12 | 13 | 14 | # 2. Totals 15 | 16 | - How do you register a total 17 | - What are the main parameters for a total 18 | - What is the order in which totals are applied to a quote 19 | - What class calculates and applies the totals 20 | - What are the default totals in Magento in order 21 | - How do you add a custom total 22 | - How do you display a custom total 23 | - What are the 4 types totals are used for 24 | 25 | # 3. Shopping Cart Rules 26 | 27 | - Which module is responsible for shopping cart price rules? 28 | - What is the difference between shopping cart and catalog price rules? 29 | - What are the limitations of Magento shopping cart rules? 30 | 31 | # 4. Shipping Methods 32 | 33 | - How do you register a shipping method 34 | - What parameters are for a shipping method 35 | - What abstract class and interface does a shipping method use 36 | - What methods are required for a shipping method and also what property should be set 37 | - How do you set shipping methods 38 | - How do you set the rate 39 | - What should be added to a Mage_Shipping_Model_Rate_Result_Method 40 | 41 | 42 | # 5. Payment Methods 43 | 44 | - What is the xpath for a payment method 45 | - What are the configuration options for a method 46 | - What class does a payment method extend from and what methods are required 47 | - How would you add and validate custom data 48 | - How would you enable logging for debugData 49 | - What property would you set to capture the full credit card number 50 | - What property would you set to prevent refunds 51 | - What properties would you set to authorize and capture 52 | - What property would you use to prevent Multishipping 53 | - What property would you use to prevent use in admin 54 | 55 | # 6. Multishipping 56 | 57 | - How does the storage of quotes for multishipping and onepage checkouts differ? 58 | - Which quotes in a multishipping checkout flow will be virtual? 59 | - How can different product types be split among multiple addresses when using multishipping in Magento? 60 | - How many times are total models executed on a multishipping checkout in Magento? 61 | - Which model is responsible for multishipping checkout in Magento? 62 | -------------------------------------------------------------------------------- /1. Basics/3. Internationalization/2. Describe the use of Magento translate classes and translate files.md: -------------------------------------------------------------------------------- 1 | # Describe the use of Magento translate classes and translate files 2 | 3 | ## 1. Overview 4 | 5 | A better and more in depth explanation can be found here at 6 | [http://blog.belvg.com/magento-certified-developer-exam-internationalization.html](http://blog.belvg.com/magento-certified-developer-exam-internationalization.html). 7 | 8 | 9 | ## 2. Types of Translations 10 | 11 | There are 3 types of translations: 12 | 13 | 1. Theme Translations 14 | 2. Module Translations 15 | 3. Database Translations 16 | 17 | 18 | ### 2.1. Theme Translations 19 | 20 | These are translations which are found in the "translate.csv" file in the theme under the locale folder 21 | 22 | **Example** 23 | 24 | If we were translating our store for German the translate file would be found under the following: 25 | 26 | app/design/{{package}}/{{theme}}/locale/de_DE/translate.csv 27 | 28 | And a example of translating a string is 29 | 30 | "Recently Viewed Products", "Kürzlich angesehene Produkte" 31 | 32 | ### 2.2 Module Translations 33 | 34 | These are module translations which are found under the app/locale/{{locale_code}} directory. 35 | 36 | **Example** 37 | 38 | This is how we would translate the search string for the German store 39 | 40 | File would be under: 41 | 42 | app/locale/de_DE/Mage_Core.csv 43 | 44 | 45 | String would be: 46 | 47 | "Search entire store here...", "Suchen Sie hier ganzen Laden ..." 48 | 49 | 50 | ### 2.3 Database Translations 51 | 52 | 53 | This is translations made on the website when you turn on the inline translation editor under System -> Configuration -> Developer -> Translate Inline. 54 | 55 | These values are stored in the core_translate table. 56 | 57 | 58 | ## 3. Priority 59 | 60 | The priority of translating strings are as follows: 61 | 62 | 1. Database Translations 63 | 2. Theme Translations 64 | 3. Module Translations 65 | 66 | 67 | 68 | ## 4. How Translations work in Magento 69 | 70 | The __() in Mage_Core_Model_Abstract gets the arguments and calls *Mage_Core_Model_Translate->translate($args)* 71 | 72 | When the *Mage_Core_Model_Translate* class is loaded it does the following in the *init* method 73 | 74 | - Checks for cache and if so sets the _data property with the cache 75 | Otherwise it 76 | 77 | - Loads the modules translation files and adds the translations to _addData() 78 | - Loads the theme translation files and adds the translations to _addData() 79 | - Loads the database translations and adds the translations to _addData() 80 | 81 | The _addData() method adds the string to an property _data which is called to get a string translation 82 | 83 | However if Developer Mode is set it, Magento doesn't use translations unrelated to module. 84 | -------------------------------------------------------------------------------- /9.Sales & Customers/2. Customers/1. Describe the architecture of the customer module.md: -------------------------------------------------------------------------------- 1 | # Describe the architecture of the customer module 2 | 3 | There are 4 main sections for a customer: 4 | 5 | 1. Address 6 | 2. Customer 7 | 3. Customer Group 8 | 4. Attribute 9 | 10 | Customers have 2 entities: 11 | 12 | 1. customer 13 | 2. customer_address 14 | 15 | 16 | # 1. Customer 17 | 18 | ## Tables 19 | 20 | **customer_entity** 21 | 22 | This stores the following: 23 | 24 | 1. entity_id 25 | 2. customer_id 26 | 3. attribute_set_id 27 | 4. website_id 28 | 5. email 29 | 6. group 30 | 7. increment_id 31 | 8. store_id 32 | 9. created_at 33 | 10. updated_at 34 | 11. is_active 35 | 12. disable_auto_group_change 36 | 37 | It also has the following tables to store attributes like any normal EAV system. 38 | 39 | 1. customer_entity_datetime 40 | 2. customer_entity_decimal 41 | 3. customer_entity_int 42 | 4. customer_entity_text 43 | 5. customer_entity_varchar 44 | 45 | ## Classes 46 | 47 | - Mage_Customer_Model_Customer 48 | - Mage_Customer_Model_Resource_Customer 49 | - Mage_Customer_Model_Resource_Customer_Collection 50 | 51 | 52 | ## Configuration Options 53 | 54 | Under Customers -> Customer Configuration here are some options to be aware of: 55 | 56 | 1. Account Sharing (per website/global) 57 | 2. Group Assignment based on address (disabled by default) 58 | 3. Welcome emails 59 | 4. Show middle name, prefix, date of birth, tax/vat, gender 60 | 5. Redirect customer to dashboard on login 61 | 6. Address templates 62 | 7. Enable Captcha 63 | 64 | # 2. Customer Address 65 | 66 | ## Tables 67 | 68 | **customer_address_entity** 69 | 70 | 1. entity_id 71 | 2. entity_type_id 72 | 3. attribute_set_id 73 | 4. increment_id 74 | 5. parent_id (customer_entity id) 75 | 6. created_at 76 | 7. updated_at 77 | 8. is_active 78 | 79 | We then have the following normal tables in EAV: 80 | 81 | 1. customer_address_entity_datetime 82 | 2. customer_address_entity_decimal 83 | 3. customer_address_entity_int 84 | 4. customer_address_entity_text 85 | 5. customer_address_entity_varchar 86 | 87 | ## Classes 88 | 89 | - Mage_Customer_Model_Address 90 | - Mage_Customer_Model_Resource_Address 91 | - Mage_Customer_Model_Resource_Address_Collection 92 | 93 | ## Billing vs Shipping 94 | 95 | This is saved in the quote model in **Mage_Sales_Model_Quote_Address->getAddressType** 96 | 97 | 98 | # 3. Other Tables 99 | 100 | **customer_form_attribute** 101 | 102 | This contains form code and attribute id for each form for Customers. These are used for forms and also to copy over values when creating a quote (see next notes.) 103 | 104 | e.g 105 | 106 | | form_code | attribute_id | 107 | | :------------- | :------------- | 108 | | adminhtml_customer | 17 | 109 | -------------------------------------------------------------------------------- /7. Catalog/2. Price Generation/2. Modify and adjust price generation for products (for example, during integration of third-party software).md: -------------------------------------------------------------------------------- 1 | # Modify and adjust price generation for products (for example, during integration of third-party software): 2 | 3 | # 1. Change Price 4 | 5 | Please read [Create Product Type notes](https://github.com/colinmurphy/magento-exam-notes/blob/master/7.%20Catalog/%201.%20Product%20Types/2.%20Create%20Product%20Type.md#L1) for more information on how to change price. 6 | 7 | You can also ajust the price for existing products by: 8 | 9 | - Adding an observer for **catalog_product_get_final_price**. See [Add An Observer](https://github.com/colinmurphy/magento-exam-notes/blob/master/7.%20Catalog/%201.%20Product%20Types/2.%20Create%20Product%20Type.md#L8) 10 | - Override the price model class 11 | 12 | 13 | # 2. Questions 14 | 15 | 16 | 17 | ## Under what circumstances are product prices read from the index tables? 18 | 19 | When using collections. In the class **Mage_Catalog_Model_Resource_Product_Collection** the method *_preparePriceExpressionParameters()* is used to get the price from the index table. 20 | 21 | ## From which modules do classes participate in price calculation? 22 | 23 | Mage_Catalog_Model_Product_Type_Price 24 | 25 | 26 | ## Which ways exist to specify custom prices during runtime? 27 | 28 | Use observer catalog_product_get_final_price 29 | 30 | ## How do custom product options influence price calculation? 31 | 32 | If a custom product option has a price, then this is appended to the price of the product. 33 | 34 | ## How are product tier prices implemented and displayed? 35 | 36 | Tiered pricing is stored *catalog_product_entity_tier_price* 37 | The price model check the quantity against the quantity in this table along with customer group and website/store. 38 | 39 | They are then displayed in *template/catalog/product/view/tierprices.phtml* 40 | 41 | ## What is the priority of the different prices that can be specified for products (price, special price, group price, tier price, etc.)? 42 | 43 | Get calculated price, if it is set, else: 44 | Get base price 45 | - apply group prices, 46 | - apply tier prices, 47 | - apply special prices (not sales rules) 48 | 49 | Get final price 50 | dispatch event catalog_product_get_final_price 51 | - Apply catalog price rules to product on frontend 52 | Apply configurable items price (for config products) 53 | Apply options price 54 | Return final price 55 | 56 | 57 | # 3. Further Reading 58 | 59 | - [http://blog.magestore.com/magento-blog-price-generation/](http://blog.magestore.com/magento-blog-price-generation/) 60 | - [http://stackoverflow.com/questions/14443991/under-what-circumstances-are-product-prices-read-from-the-index-tables-in-magent](http://stackoverflow.com/questions/14443991/under-what-circumstances-are-product-prices-read-from-the-index-tables-in-magent) 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | These are notes I compiled while studying for the Magento Certified Developer Exam. 4 | 5 | There will be not much updates to these notes but if you spot anything that is wrong or misspelled or if you feel you can contribute please make a pull request and I will review the commit. 6 | 7 | 8 | # 1. Overview of the Exam 9 | 10 | 1. Basics 6% 11 | 2. Request Flow 7% 12 | 3. Rendering 7% 13 | 4. Databases 13% 14 | 5. EAV 10% 15 | 6. Adminhtml 7% 16 | 7. Catalog 10% 17 | 8. Checkout 16% 18 | 9. Sales & Customers 11% 19 | 10. Advanced 13% 20 | 21 | 22 | ### 1.2 Structure of the Exam 23 | 24 | - 72 Questions 25 | - 70 Marked 26 | - 15 Unmarked 27 | - 37 Pass Rate 28 | 29 | **Note:** Magento states there are 85 questions and 70 marked but when I undertook the exam it was 72 questions with 70 marked. 30 | 31 | 32 | # 2. Resources 33 | 34 | ## 2.1. Books 35 | 36 | - No Frills Magento Layout by Alan Storm [http://store.pulsestorm.net/products/no-frills-magento-layout](http://store.pulsestorm.net/products/no-frills-magento-layout) 37 | - Grokking Book - Book 1: Basics and Request Flow by Vinai Kopp and Ben Marks [https://shop.vinaikopp.com/grokking-magento/](https://shop.vinaikopp.com/grokking-magento/#!/home) 38 | - Magento Best Practices Handbook by Alessandro Ronchi [https://leanpub.com/magebp](https://leanpub.com/magebp) 39 | 40 | ## 2.2. Online Resources 41 | 42 | - Mage Study Guide by Meanbee [http://magestudyguide.com/](http://magestudyguide.com/) 43 | 44 | - Belvg Blog [http://blog.belvg.com/category/magento-news/developer-certification](http://blog.belvg.com/category/magento-news/developer-certification) 45 | - Mage Cert [http://magecert.com/](http://magecert.com/) 46 | - Quizlet Flash Cards [https://quizlet.com/20443995/flashcards](https://quizlet.com/20443995/flashcards) 47 | - Magentools Online Quiz [http://magento-quiz.magestore.com/](http://magento-quiz.magestore.com/) 48 | - Magentools Study Answers [http://magentools.com/blog/magento-certification-preparation-study-guide-answers/](http://magentools.com/blog/magento-certification-preparation-study-guide-answers/) 49 | - Quizlet Study Answers [https://quizlet.com/20443995/magento-certification-preparation-study-guide-answers-flash-cards/](https://quizlet.com/20443995/magento-certification-preparation-study-guide-answers-flash-cards/) 50 | - Division Lab [http://www.divisionlab.com/solvingmagento/](http://www.divisionlab.com/solvingmagento/) 51 | 52 | 53 | # 3. Study Plan 54 | 55 | *This is a rough idea on how to study each chapter* 56 | 57 | - Create Answers for each part from: 58 | 59 | - Blogs 60 | - Mage Study Guide 61 | - Stack Overflow 62 | 63 | 64 | 65 | - Do Group Guide Exercises 66 | - Create Dummy Questions and Answers 67 | - Revise Notes 68 | -------------------------------------------------------------------------------- /2. Request Flow/5. Module Initalization/1. Describe the steps needed to create and register a new module.md: -------------------------------------------------------------------------------- 1 | # Describe the steps needed to create and register a new module 2 | 3 | **Note:** This really just gives an overview of how modules are loaded but covers how to create and register a module. 4 | 5 | **Important:** app/etc/local.xml is loaded at the start of the process and is merged back in after the modules are loaded to prevent the local.xml values from be overriden. 6 | 7 | # Overview of Request Process for Modules 8 | 9 | 1. index.php 10 | 2. Mage::run() 11 | 3. Mage_Core_Model_App->run() (which eventually loads the config.xml and local.xml files first into Mage_Core_Model_Config) 12 | 4. Mage_Core_Model_App->_initModules() 13 | 5. Mage_Core_Model_Config->loadModules() 14 | 6. Mage_Core_Model_Config->_loadDeclaredModules(); 15 | 7. Mage_Core_Model_Config->loadModulesConfiguration(); 16 | 8. Merge back in app/etc/local.xml 17 | 18 | 19 | # 1. Get Module XML Files - 20 | 21 | So in the method _loadDeclaredModules() it does the following: 22 | 23 | Mage_Core_Model_Config->_getDeclaredModuleFiles() returns an array of all XML files found under app/etc/modules. 24 | 25 | **Note** These are ordered by Mage_All, Mage files and then any other file when returning the array. 26 | 27 | Example of a module XML file is 28 | 29 | 30 | 31 | 32 | 33 | local 34 | true 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | # 2. Sort Modules 44 | 45 | So in the same method the XML is added in a new instance of Mage_Core_Model_Config_Base() class and then some checks to see if the module is active and exists. 46 | 47 | Then the method *_sortModuleDepends* is called and sorts the modules with the node into an order for the Mage_Core_Model_Config_Base() 48 | 49 | # 3. Appended to Mage_Core_Model_Config 50 | 51 | Then the Mage_Core_Model_Config_Base() class of all sorted modules is extended onto the node "modules" for the Mage_Core_Model_Config class. 52 | 53 | # 4. Load Module config.xml 54 | 55 | So in the method *loadModulesConfiguration()* this loads in the config.xml files of the modules. 56 | 57 | So in a config.xml file you would have the following: 58 | 59 | 60 | 61 | 62 | 63 | 64 | 0.0.1 65 | 66 | 67 | 68 | # 5. Merge local.xml 69 | 70 | After this method is complete, the loadModules() method then gets the app/etc/local.xml file and extends it from the class so none of the local.xml is overridden (e.g. database details) 71 | 72 | 73 | # Further Reading 74 | [http://blog.belvg.com/magento-certified-developer-exam-module-initialization.html](http://blog.belvg.com/magento-certified-developer-exam-module-initialization.html) 75 | -------------------------------------------------------------------------------- /5. EAV/3. Additional Notes/Answers.md: -------------------------------------------------------------------------------- 1 | # 1. Concepts 2 | 3 | ## Name all 8 entity types 4 | 5 | | Name | Entity Type Code | Entity Model | 6 | | :------------- | :------------- | :------------- | 7 | | 1. Customer | customer | customer/customer | 8 | | 2. Customer Address | customer_address | customer/address | 9 | | 3. Product | catalog_product | catalog/product | 10 | | 4. Category | catalog_category | catalog/category | 11 | | 5. Order | order | sales/order | 12 | | 6. Invoice | invoice | sales/order_invoice | 13 | | 7. Credit Memo | creditmemo | sales/order_creditmemo | 14 | | 8. Shipment | shipment | sales/shipment | 15 | 16 | ## How do you load all 8 types 17 | 18 | Mage::getModel('customer/customer') 19 | Mage::getModel('customer/address') 20 | Mage::getModel('catalog/product') 21 | Mage::getModel('catalog/category') 22 | Mage::getModel('sales/order') 23 | Mage::getModel('sales/order_invoice') 24 | Mage::getModel('sales/order_creditmemo') 25 | Mage::getModel('sales/shipment') 26 | 27 | 28 | ## Name the table entity types are stored from 29 | 30 | eav_entity_type 31 | 32 | ## How do we change the setup class for a resource 33 | 34 | Add a class to the setup in config. 35 | The xpath would be global/resources/name_of_resource/setup/class 36 | 37 | 38 | ## What is the name of the abstract class for EAV Resource Model & Collection 39 | 40 | - Resource Model: Mage_Eav_Model_Entity_Abstract 41 | - Collection: Mage_Eav_Model_Entity_Collection_Abstract 42 | 43 | ## How do we register a new EAV type 44 | 45 | 1. Create module with model, resource model, table and setup script in config. 46 | 2. Resource Model extends from Mage_Eav_Model_Entity_Abstract and sets a type using setType 47 | 3. Collection extends from Mage_Eav_Model_Entity_Collection_Abstract and sets the resource model 48 | 4. Setup class extends from or is Mage_Eav_Model_Entity_Setup 49 | 5. Run $this->addEntityType($name, array $params) which creates the entity type in eav_entity_type table 50 | 6. Add tables to resource model and run $this->createEntityTables($table) 51 | 7. Add Attributes using $this->addAttribute() 52 | 53 | ## How do we create tables for the EAV type 54 | 55 | $this->createEntityTables($table) 56 | 57 | ## Name all fields which can be passed in to create a EAV type and what their purpose is 58 | 59 | 60 | ## Name all the entity attribute value table types (text, decimal) 61 | 62 | 1. char 63 | 2. text 64 | 3. datetime 65 | 4. int 66 | 5. varchar 67 | 6. decimal 68 | 69 | 70 | 71 | # 2. Attributes 72 | 73 | ## Do you use entity_type_code or entity_model when creating/update EAV attribute 74 | 75 | entity_type_code. We only use entity model when getting Model/collection. 76 | 77 | ## Differences between create and update attribute 78 | 79 | $this->addAttribute($eav_type, $name, array $params) 80 | $this->updateAttribute($eav_type, $attribute, $column, $value); e.g. update frontend_model 81 | 82 | 83 | ## How do you get attribute value for a model 84 | 85 | echo Mage::getSingleton('eav/config') 86 | ->getAttribute("colin_eav_blog", 'content') 87 | ->getFrontend() 88 | ->getExcerpt($blog, 10); 89 | -------------------------------------------------------------------------------- /5. EAV/1. EAV Concepts/5. Questions.md: -------------------------------------------------------------------------------- 1 | ## 1. Which classes in Mage_Eav are used as resource models and which are used as regular models? 2 | 3 | 1. Non EAV 4 | - Model : Mage_Core_Model_Abstract 5 | 6 | 2. EAV 7 | - Resource Model: Mage_Eav_Model_Entity_Abstract 8 | - Collection: Mage_Eav_Model_Entity_Collection_Abstract 9 | 10 | ## 2. How do flat and EAV resource models differ? 11 | 12 | Flat model sets the main table and field. 13 | 14 | 15 | class Colin_Database_Model_Resource_Results extends Mage_Core_Model_Resource_Db_Abstract 16 | { 17 | protected function _construct() 18 | { 19 | $this->_init('colin_database/results', 'id'); 20 | } 21 | } 22 | 23 | 24 | EAV sets the EAV type and connection. 25 | 26 | 27 | class Colin_EAV_Model_Resource_Blog extends Mage_Eav_Model_Entity_Abstract 28 | { 29 | protected function _construct() 30 | { 31 | $resource = Mage::getSingleton('core/resource'); 32 | $this->setType('colin_eav_blog'); 33 | $this->setConnection( 34 | $resource->getConnection('core_read'), 35 | $resource->getConnection('core_write') 36 | ); 37 | } 38 | } 39 | 40 | 41 | ## 3. Which entities in a native Magento installation use EAV resource models and why? 42 | 43 | 44 | | Name | Entity Type Code | Entity Model | 45 | | :------------- | :------------- | :------------- | 46 | | 1. Customer | customer | customer/customer | 47 | | 2. Customer Address | customer_address | customer/address | 48 | | 3. Product | catalog_product | catalog/product | 49 | | 4. Category | catalog_category | catalog/category | 50 | | 5. Order | order | sales/order | 51 | | 6. Invoice | invoice | sales/order_invoice | 52 | | 7. Credit Memo | creditmemo | sales/order_creditmemo | 53 | | 8. Shipment | shipment | sales/shipment | 54 | 55 | **Why:** 56 | 57 | - Easy to add/remove attributes 58 | - Database extends vertically not horizontally with new columns 59 | 60 | 61 | ## 4. What are the advantages and disadvantages of EAV over flat table resource models? 62 | 63 | **Advantages** 64 | 65 | - Easy to add new attributes 66 | - No additioal columns need to be added when adding a new attribute 67 | 68 | 69 | **Disadvantages** 70 | 71 | - Speed and Performance for Database Queries 72 | 73 | 74 | ## 5. How are store and website scope attribute values implemented in the Magento EAV system? 75 | 76 | store_id for the main entity table and also the attribute tables. 77 | 78 | ## 6. How does the model distinguish between insert and update operations? 79 | 80 | - If no id exists then it creates the entity otherwise updates the entity 81 | - If value is empty it deletes the row/entity 82 | 83 | ## 7. How do load and save processes for EAV entities differ from those for flat table entities? What parts are identical? 84 | 85 | **Same:** 86 | 87 | - Uses same Model abstract class 88 | 89 | **Differences:** 90 | 91 | - EAV Resource Model loads main table and attributes while Flat loads 1 row 92 | - EAV saves to multiple tables while FLAT saves to one table 93 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/7. Describe the collection interface (filtering:sorting:grouping).md: -------------------------------------------------------------------------------- 1 | # Describe the collection interface (filtering:sorting:grouping) 2 | 3 | # 1. Filtering 4 | 5 | 6 | There are 2 methods for filtering data in collections (excluding getSelect and making a query that way) 7 | 8 | 1. addFieldToFilter - non EAV 9 | 2. addAttributeToFilter - EAV 10 | 11 | Both methods accept 2 parameters - field and then condition which could be a string or an array. 12 | 13 | ## 1.1. Basic Query 14 | 15 | $collection = Mage::getModel('colin_database/results')->getCollection(); 16 | $collection->addFieldToFilter('home', 4); 17 | var_dump((string)$collection->getSelect()); 18 | // SELECT `main_table`.* FROM `football_results` AS `main_table` WHERE (home = '4') 19 | // Same as $collection->getSelect()->where('home = 4'); 20 | 21 | 22 | ## 1.2. Filter Queries 23 | 24 | Some basic equals, not equals, greater, less than or like. 25 | 26 | $collection->addFieldToFilter('home', array('eq' => '4')); 27 | $collection->addFieldToFilter('home', array('neq' => '4')); 28 | $collection->addFieldToFilter('home', array('gt' => '4')); 29 | $collection->addFieldToFilter('home', array('gt' => '4')); 30 | $collection->addFieldToFilter('home', array('like' => '4')); 31 | 32 | ## 1.3. In Query 33 | 34 | $collection->addFieldToFilter('home', array('in' => array(1, 2))); 35 | $collection->addFieldToFilter('home', array('nin' => array(1, 2))); 36 | //SELECT `main_table`.* FROM `football_results` AS `main_table` WHERE (home IN(1, 2)) 37 | 38 | ## 1.4. From/To Query 39 | 40 | $collection->addFieldToFilter('home', array('from' => 1, 'to' => 2)); 41 | //SELECT `main_table`.* FROM `football_results` AS `main_table` WHERE (home >= 1 AND home <= 2) 42 | 43 | 44 | ## 1.5. Attribute Query 45 | 46 | $collection = Mage::getModel('catalog/product')->getCollection(); 47 | $collection->addAttributeToFilter("status", 1); 48 | 49 | ## 1.6. OR Query 50 | 51 | So if we wanted to get results with home score = 4 or away score = 0 we would do the following: 52 | 53 | 54 | $collection->addFieldToFilter( 55 | array('home', 'away'), 56 | array(4, 0) 57 | ); 58 | var_dump((string)$collection->getSelect()); 59 | // SELECT `main_table`.* FROM `football_results` AS `main_table` WHERE ((home = '4') OR (away = '0') 60 | 61 | 62 | ## 1.7. AND Query 63 | 64 | You can add as many addFieldToFilter or addAttributeToFilter and it will combine the conditions with AND 65 | 66 | 67 | $collection->addFieldToFilter('home', 4); 68 | $collection->addFieldToFilter('away', 0); 69 | var_dump((string)$collection->getSelect()); 70 | // SELECT `main_table`.* FROM `football_results` AS `main_table` WHERE ((home = '4') AND (away = '0') 71 | 72 | 73 | # 2. Sorting 74 | 75 | There are 2 methods which both call *_setOrder* method 76 | 77 | 1. addOrder 78 | 2. setOrder 79 | 80 | ``` 81 | $collection = Mage::getModel('colin_database/results')->getCollection(); 82 | $collection->addOrder('home', Zend_Db_Select::SQL_ASC); 83 | $collection->setOrder('home', Zend_Db_Select::SQL_ASC); 84 | ``` 85 | 86 | We can also limit in 2 ways 87 | 88 | $collection->setCurPage(1)->setPageSize(5); 89 | $collection->getSelect()->limit(5); 90 | -------------------------------------------------------------------------------- /6. Adminhtml/1. Common Structure/1. Describe the similarities and differences between adminhtml and frontend interface and routing.md: -------------------------------------------------------------------------------- 1 | # Describe the similarities and differences between adminhtml and frontend interface and routing: 2 | 3 | Both the main (frontend) and admin routers are registered under global -> web -> routers 4 | 5 | 6 | 7 | 8 | 9 | admin 10 | Mage_Core_Controller_Varien_Router_Admin 11 | 12 | 13 | frontend 14 | Mage_Core_Controller_Varien_Router_Standard 15 | 16 | 17 | 18 | 19 | However if we wanted to register a router the different is the **** parameter and also the **area** e.g. frontend or admin. 20 | 21 | 22 | **Frontend** 23 | 24 | 25 | 26 | 27 | standard 28 | 29 | Mage_Catalog 30 | catalog 31 | 32 | 33 | 34 | 35 | **Admin** 36 | 37 | 38 | 39 | 40 | admin 41 | 42 | Colin_Adminhtml 43 | slider 44 | 45 | 46 | 47 | 48 | 49 | 50 | We also need to set a menu and ACL for the user to access this (more later on). 51 | 52 | Also frontend router extends from *Mage_Core_Controller_Front_Action* and admin router extends from **Mage_Adminhtml_Controller_Action** 53 | 54 | 55 | # Questions 56 | 57 | ## Which areas in configuration are only loaded for the admin area? 58 | 59 | All routers under **admin** 60 | 61 | ## What is the difference between admin and frontend controllers? 62 | 63 | - Frontend extends **Mage_Core_Controller_Front_Action** 64 | - Admin Extends **Mage_Adminhtml_Controller_Action** 65 | 66 | ## When does Magento figure out which area to use on the current page? 67 | 68 | In **Mage_Core_Controller_Varien_Front->dispatch()** it figures it out by going through the 4 controllers. 69 | 70 | See [https://github.com/colinmurphy/magento-exam-notes/blob/master/2.%20Request%20Flow/4.%20Request%20Routing/1.Describe%20request%20routing(request)%20flow%20in%20Magento.md#L1](https://github.com/colinmurphy/magento-exam-notes/blob/master/2.%20Request%20Flow/4.%20Request%20Routing/1.Describe%20request%20routing(request)%20flow%20in%20Magento.md#L1) for more details. 71 | 72 | ## How you can make your controller work under the /admin route 73 | 74 | Register a router under admin (See above). 75 | 76 | 77 | # Further Reading 78 | 79 | - [https://github.com/colinmurphy/magento-exam-notes/blob/master/2.%20Request%20Flow/4.%20Request%20Routing/1.Describe%20request%20routing(request)%20flow%20in%20Magento.md#L1](https://github.com/colinmurphy/magento-exam-notes/blob/master/2.%20Request%20Flow/4.%20Request%20Routing/1.Describe%20request%20routing(request)%20flow%20in%20Magento.md#L1) 80 | - [http://www.brideo.co.uk/magento-certification-notes/adminhtml/Common-Structure-Architecture/](http://www.brideo.co.uk/magento-certification-notes/adminhtml/Common-Structure-Architecture/) 81 | -------------------------------------------------------------------------------- /6. Adminhtml/1. Common Structure/2. Describe the components and types of cache clearing using the adminhtml interface.md: -------------------------------------------------------------------------------- 1 | # Describe the components and types of cache clearing using the adminhtml interface 2 | 3 | 4 | ## At which moment does Magento check if a user is logged in or not? 5 | 6 | Using the observer **Mage_Admin_Model_Observer->actionPreDispatchAdmin()** 7 | 8 | This is registered in the Mage_Adminhtml config.xml module. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | admin/observer 17 | actionPreDispatchAdmin 18 | 19 | 20 | 21 | 22 | 23 | ## Which class do most Magento adminhtml blocks extend? 24 | 25 | **Mage_Adminthml_Block_Template** 26 | 27 | This extends from **Mage_Core_Block_Template** but adds an observer to the *_toHtml* method. 28 | 29 | 30 | protected function _toHtml() 31 | { 32 | Mage::dispatchEvent('adminhtml_block_html_before', array('block' => $this)); 33 | return parent::_toHtml(); 34 | } 35 | 36 | 37 | ## What are the roles of adminhtml config? 38 | 39 | Explained under ACL but here is the syntax which can be added to either config.xml or adminhtml.xml but adminhtml.xml is where it usually is added. 40 | 41 | 42 | 43 | <{some_module}> 44 | 45 | <{some_node} translate="title" module="{some_module}"> 46 | Some Title 47 | 60 48 | 49 | 51 | 52 | 53 | 54 | 55 | ## What are the differences between the different cache types on the admin cache cleaning page? 56 | 57 | There are 3 types: 58 | 59 | 1. config 60 | 2. blocks 61 | 3. api 62 | 63 | | Cache | Tag | 64 | | :------------- | :------------- | 65 | | Configuration System | CONFIG | 66 | | Layouts | LAYOUT_GENERAL_CACHE_TAG | 67 | | Blocks HTML output | BLOCK_HTML | 68 | | Translations | TRANSLATE | 69 | | Collections Data | COLLECTION_DATA | 70 | | EAV types and attributes | EAV | 71 | | Web Services Configuration(api.xml) | CONFIG_API | 72 | | Web Services Configuration(api2.xml) | CONFIG_API2 | 73 | 74 | 75 | 76 | 77 | ## What is the difference between “flush storage” and “flush Magento cache”? 78 | 79 | **Flush Storage** 80 | 81 | This calls **Mage_Core_Model_Cache::flush()** method. 82 | This clears all cache. 83 | 84 | **Flush Magento Cache** 85 | 86 | This calls **Mage_Core_Model_Cache::clean()** method. 87 | 88 | This only clears only **MAGE** and **CONFIG** cache. 89 | 90 | ## How you can clear the cache without using the UI? 91 | 92 | Mage_Core_Model_Cache::flush 93 | Mage_Core_Model_Cache::clean 94 | Zend_Cache_Core::clean(); 95 | 96 | # Further Reading 97 | 98 | - [http://www.brideo.co.uk/magento-certification-notes/adminhtml/Common-Structure-Architecture/](http://www.brideo.co.uk/magento-certification-notes/adminhtml/Common-Structure-Architecture/) 99 | - [http://magecert.com/adminhtml.html](http://magecert.com/adminhtml.html) 100 | -------------------------------------------------------------------------------- /8. Checkout/4. Magento multishipping implementation/1. Describe how to extend the Magento multishipping implementation.md: -------------------------------------------------------------------------------- 1 | # Describe how to extend the Magento multishipping implementation 2 | 3 | # 1. Options 4 | 5 | Multishipping is enabled/disabled under Sales -> Shipping Settings -> Options. 6 | It has 2 options: 7 | 8 | 1. Enable/Disable 9 | 2. Maximum Qty Allowed for Shipping to Multiple Addresses 10 | 11 | # 2. Checkout Flow 12 | 13 | So if you allow multishipping the following will happen with the checkout process. 14 | 15 | 16 | 1. Different Checkout Controller 17 | 2. Select Address for each item 18 | 3. Select Shipping Method for each address 19 | 4. Select Billing Address and Payment Method 20 | 5. Place Order 21 | 22 | ### Select Address 23 | 24 | Checkout URL will be checkout/multishipping/ instead of checkout/onepage and use **Mage_Checkout_MultishippingController** instead of **Mage_Checkout_OnepageController**. These both extend from **Mage_Checkout_Controller_Action** which adds a method to make sure the customer is logged in. 25 | 26 | You will need to select an existing address for each product quantity (e.g. if you had ordered 2 of the same product then you will need to select 2 addresses for each quantity). 27 | 28 | In the database quote items are added to sales_flat_quote_address_item as quote items are added to the shipping address instead of the quote. 29 | 30 | ### Shipping Methods 31 | 32 | Then at the next step you need to select shipping method for each address. This then calculates the totals for each shipping address. 33 | 34 | ### Billing Information Payment Method 35 | 36 | The next step is to set the billing information and payment method. 37 | 38 | 39 | # 3. How different product types work with Multishipping 40 | 41 | ## Virtual Product 42 | 43 | These are stored in the **flat_sales_quote_address_item** as normal but their shipping address is actually the billing address as they have no shipping 44 | 45 | ## Bundle Products 46 | 47 | Grouped products get added to the cart as multiple separate products, so they can be selected to be shipped to different addresses using the regular multi-shipping checkout process. However, bundled products cannot be split among multiple addresses. 48 | 49 | 50 | 51 | 52 | # 4. Questions 53 | 54 | ## How does the storage of quotes for multishipping and onepage checkouts differ? 55 | 56 | Quote Items are stored in **flat_sales_quote_address_item**. 57 | 58 | ## Which quotes in a multishipping checkout flow will be virtual? 59 | 60 | Virtual Products will be added to **flat_sales_quote_address_item** but it does not have a shipping address. Instead the item is added to the billing address. 61 | 62 | ## How can different product types be split among multiple addresses when using multishipping in Magento? 63 | 64 | The items are added to flat_sales_quote_address_item and then they set a parent address id which is based in flat_sales_quote_address table. 65 | 66 | ## How many times are total models executed on a multishipping checkout in Magento? 67 | 68 | For each address. 69 | 70 | ## Which model is responsible for multishipping checkout in Magento? 71 | 72 | 73 | | One Page Checkout | Multi Shipping | 74 | | :------------- | :------------- | 75 | | Mage_Checkout_OnepageController | Mage_Checkout_MultishippingController | 76 | | Mage_Checkout_Model_Type_Onepage | Mage_Checkout_Model_Type_Mulitishipping | 77 | 78 | 79 | 80 | # Further Reading 81 | 82 | - [http://www.divisionlab.com/solvingmagento/magento-multishipping-checkout/](http://www.divisionlab.com/solvingmagento/magento-multishipping-checkout/) 83 | - [http://magecert.com/checkout.html](http://magecert.com/checkout.html) 84 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/4. Describe the load-and-save process for a regular entity.md: -------------------------------------------------------------------------------- 1 | # Describe the load-and-save process for a regular entity 2 | 3 | # 1. Background 4 | 5 | So to go over setting up a custom table we would add the following to our config.xml 6 | 7 | ## 1.1. Config.xml 8 | 9 | 10 | 11 | 12 | 13 | Colin_Database_Model 14 | colin_database_resource 15 | 16 | 17 | Colin_Database_Model_Resource 18 | 19 | 20 | football_results
21 |
22 |
23 |
24 |
25 | 26 | 27 | ## 1.2. Model 28 | 29 | This sets the resource model in the *_construct* method. 30 | 31 | protected function _construct() 32 | { 33 | $this->_init('colin_database/results'); 34 | } 35 | 36 | ## 1.3. Resource Model 37 | 38 | This sets the main table and main field to use in the *_construct* method. If you don't set a main field, then it will use 'id' as default. 39 | 40 | protected function _construct() 41 | { 42 | $this->_init('colin_database/results', 'id'); 43 | } 44 | 45 | ## 1.4. Collection 46 | 47 | This sets the model and resource model to use. By default if you don't set the resource model it will use the name of the model. 48 | 49 | public function _construct() 50 | { 51 | $this->_init('colin_database/results'); 52 | } 53 | 54 | 55 | # 2. Load by Model 56 | 57 | $model = Mage::getModel('colin_database/results')->load(1); 58 | 59 | This loads a table with using the main field ('id'). 60 | 61 | This calls the resource model ->load() which accepts a model, table and field in the class *Mage_Core_Model_Resource_Db_Abstract* 62 | The resource model is set with the *_init* method *_init('colin_database/results', 'id')*. 63 | 64 | This then gets the ReadAdapter **Magento_Db_Adapter_Pdo_Mysql** and queries the database with *fetchRow*. 65 | 66 | 67 | You can also set a second parameter instead of the main field e.g. 68 | 69 | $model = Mage::getModel('colin_database/results') 70 | ->load(3, 'home'); 71 | $model = Mage::getModel('catalog/product') 72 | ->load('my-sku', 'sku'); 73 | 74 | 75 | # 3. Load by Collection 76 | 77 | 78 | You can load products by Collection 79 | 80 | $model = Mage::getModel('colin_database/results')->getCollection(); 81 | $model = Mage::getModel('colin_database/results')->getResourceCollection(); 82 | 83 | This will load all results. It uses the resource model set in *_init* to get the collection. 84 | You can also filter, sort and group results. This will be covered in part 7 of this chapter. 85 | 86 | 87 | # 4. Save by Model 88 | 89 | Example: 90 | 91 | $data = array( 92 | 'home' => rand(0, 5), 93 | 'away' => rand(0, 5), 94 | ); 95 | 96 | $model = Mage::getModel('colin_database/results'); 97 | $model->setData($data)->save(); 98 | var_dump($model->getId()); 99 | 100 | This saves a row. This calls the method save in the abstract class *Mage_Core_Model_Abstract* which then calls the Resource Model save method in the abstract class *Mage_Core_Model_Resource_Db_Abstract*. 101 | 102 | This calls the write adapter *Magento_Db_Adapter_Pdo_Mysql* to save the data. 103 | 104 | It also calls 2 methods *_beforeSave()* and *_afterSave()* before and after a save. 105 | 106 | The events are covered in the next chapter. 107 | -------------------------------------------------------------------------------- /5. EAV/2. EAV Attributes/1. Identify the purpose of attribute frontend, source, and backend models.md: -------------------------------------------------------------------------------- 1 | # Identify the purpose of attribute frontend, source, and backend models 2 | 3 | # 1. Overview of eav_attribute table 4 | 5 | In the eav_attribute table where the attributes are stored they have the following columns 6 | 7 | 1. attribute_id 8 | 2. entity_type_id 9 | 3. attribute_code 10 | 4. attribute_model 11 | 5. backend_model 12 | 6. backend_type 13 | 7. backend_table 14 | 8. frontend_model 15 | 9. frontend_input 16 | 10. frontend_label 17 | 11. frontend_class 18 | 12. source_model 19 | 13. is_required 20 | 14. is_user_defined 21 | 15. default_value 22 | 16. is_unique 23 | 17. note 24 | 25 | 26 | ### attribute_id 27 | 28 | Id of the attribute 29 | 30 | ## entity_type_id 31 | 32 | Id of the entity in eav_entity_type table 33 | 34 | ## attribute_code 35 | 36 | Name of attribute 37 | 38 | ## attribute_model 39 | 40 | Attribute model for getting the row. Default is Mage_Eav_Model_Entity_Attribute 41 | 42 | ## backend_model 43 | 44 | Model for dealing with saving/deleting entity in the backend. 45 | 46 | ## backend_type 47 | 48 | It can be of 6 types 49 | 50 | 1. varchar 51 | 2. int 52 | 3. text 53 | 4. decimal 54 | 5. datetime 55 | 6. static 56 | 57 | **Note:** static means the value is stored in main entity table e.g. catalog_product_entity instead of one of the attribute tables. 58 | 59 | 60 | ## backend_table 61 | 62 | Not used really but used to set the table for the backend. 63 | 64 | 65 | ## frontend_model 66 | 67 | Model for frontend for getting the value and label. 68 | 69 | $this->getValue(); 70 | $this->getLabel(); 71 | 72 | **Note:** Frontend models extend from Mage_Eav_Model_Entity_Attribute_Frontend_Abstract 73 | 74 | 75 | **Example:** image for the catalog. 76 | 77 | In the database the value is "catalog/product_attribute_frontend_image". This refers to the class "Mage_Catalog_Model_Product_Attribute_Frontend_Image" and there is an additional method getUrl() to get the image URL in the class. 78 | 79 | ## frontend_input 80 | 81 | Defines what type of input it is for forms. 82 | 83 | ## frontend_label 84 | 85 | Label for the frontend. 86 | 87 | ## frontend_class 88 | 89 | This assigns CSS classes when you call $attribute->getClass(); 90 | 91 | ## source_model 92 | 93 | Class for getting a source model. Used for selects and multiselect. 94 | 95 | The class must have the public method *toOptionArray()* which returns an array of key values. 96 | 97 | **Example:** 98 | 99 | For the catalog status the value "catalog/status" is stored in the database so the class "Mage_Catalog_Model_Product_Status" is loaded. 100 | 101 | 102 | public function getOptionArray() 103 | { 104 | return array( 105 | self::STATUS_ENABLED => Mage::helper('catalog')->__('Enabled'), 106 | self::STATUS_DISABLED => Mage::helper('catalog')->__('Disabled') 107 | ); 108 | } 109 | 110 | ## is_required 111 | 112 | Boolean is required or not. 113 | 114 | ## is_user_defined 115 | 116 | Whether the attributes was created by Magento or store. 117 | 118 | ## default_value 119 | 120 | Default value when no value is set. 121 | 122 | ## is_unique 123 | 124 | Whether or not the value should be unique from other values of that attribute. 125 | 126 | ## note 127 | 128 | Used to add notes in the backend. Example meta description. 129 | 130 | # 2. Further Reading 131 | 132 | - [http://www.divisionlab.com/solvingmagento/magento-eav-system/](http://www.divisionlab.com/solvingmagento/magento-eav-system/) 133 | - [https://www.demacmedia.com/magento-commerce/mini-tutorial-eav_attribute-table-in-magento/](https://www.demacmedia.com/magento-commerce/mini-tutorial-eav_attribute-table-in-magento/) 134 | -------------------------------------------------------------------------------- /4. Databases/2. Install:Update Scripts/2. Write install and upgrade scripts using set-up resources.md: -------------------------------------------------------------------------------- 1 | # Write install and upgrade scripts using set-up resources 2 | 3 | Please re-read notes for this chapter but these are the scripts we used for installing and upgrading our football results table. I have added in a new column for match rating for the upgrade scripts. 4 | 5 | 6 | 7 | # 1. Setup Install Script 8 | 9 | **sql/colin_database_results/install-0.0.1.php** 10 | 11 | 12 | // $this Mage_Core_Model_Resource_Setup 13 | $this->startSetup(); 14 | // $conn Magento_Db_Adapter_Pdo_Mysql 15 | $conn = $this->getConnection(); 16 | $table = $conn->newTable($this->getTable('colin_database/results')); 17 | 18 | $table 19 | ->addColumn( 20 | 'id', 21 | Varien_Db_Ddl_Table::TYPE_INTEGER, 22 | 11, 23 | array( 24 | 'identity' => true, 25 | 'primary' => true 26 | ) 27 | ) 28 | ->addColumn( 29 | 'home', 30 | Varien_Db_Ddl_Table::TYPE_INTEGER, 31 | 11, 32 | array( 33 | 'nullable' => false, 34 | ) 35 | ) 36 | ->addColumn( 37 | 'away', 38 | Varien_Db_Ddl_Table::TYPE_INTEGER, 39 | 11, 40 | array( 41 | 'nullable' => false, 42 | ) 43 | ) 44 | ->addColumn( 45 | 'date', 46 | Varien_Db_Ddl_Table::TYPE_TIMESTAMP, 47 | null, 48 | array( 49 | 'nullable' => false, 50 | 'default' => Varien_Db_Ddl_Table::TIMESTAMP_INIT 51 | ) 52 | ); 53 | 54 | $this->getConnection()->createTable($table); 55 | $this->endSetup(); 56 | 57 | 58 | # 2. Setup Upgrade Script 59 | 60 | **sql/colin_database_results/upgrade-0.0.1-0.0.2.php** 61 | 62 | 63 | $this->startSetup(); 64 | $conn = $this->getConnection(); 65 | $table = $this->getTable('colin_database/results'); 66 | 67 | $conn->addColumn( 68 | $table, 69 | 'match_rating', 70 | array( 71 | 'type' => Varien_Db_Ddl_Table::TYPE_INTEGER, 72 | 'nullable' => true, 73 | 'default' => 5, 74 | 'comment' => 'Match Rating from 1 - 10' 75 | ) 76 | ); 77 | $this->endSetup(); 78 | 79 | 80 | # 3. Data Install Script 81 | 82 | **data/colin_database_results/install-0.0.1.php** 83 | 84 | $results = array( 85 | array( 86 | 'home' => 2, 87 | 'away' => 0, 88 | 'date' => strtotime('-3 weeks') 89 | ), 90 | array( 91 | 'home' => 1, 92 | 'away' => 1, 93 | 'date' => strtotime('-2 weeks') 94 | ), 95 | array( 96 | 'home' => 0, 97 | 'away' => 3, 98 | 'date' => strtotime('-1 week') 99 | ), 100 | array( 101 | 'home' => 4, 102 | 'away' => 2, 103 | ) 104 | ); 105 | 106 | foreach ($results as $result) { 107 | Mage::getModel('colin_database/results') 108 | ->setData($result) 109 | ->save(); 110 | } 111 | 112 | 113 | # 4. Data Upgrade Script 114 | 115 | **data/colin_database_results/install-0.0.1.php** 116 | 117 | 118 | $collection = Mage::getModel('colin_database/results')->getCollection(); 119 | 120 | foreach ($collection as $result) 121 | { 122 | $result->setMatchRating(rand(1, 10)); 123 | $result->save(); 124 | } 125 | 126 | 127 | 128 | # Further Reading 129 | 130 | - [http://inchoo.net/magento/magento-install-install-upgrade-data-and-data-upgrade-scripts/](http://inchoo.net/magento/magento-install-install-upgrade-data-and-data-upgrade-scripts/) 131 | -------------------------------------------------------------------------------- /9.Sales & Customers/1. Sales/2. Card operations (capturing and authorization).md: -------------------------------------------------------------------------------- 1 | # Card operations (capturing and authorization) 2 | 3 | # Overview 4 | 5 | 6 | **Mage_Payment_Model_Method_Abstract** and **Mage_Payment_Model_Method_Cc** is responsible for card operations. 7 | 8 | Before we look at the different payment methods we should look at quote to order to invoice process. 9 | 10 | 11 | # 1. Overview Quote -> Order -> Invoice 12 | 13 | When an order is placed an existing quote is converted into an order. 14 | 15 | The order tables have the following and are a EAV type "order": 16 | 17 | **sales_flat_order** 18 | 19 | Stores the main order information such as the quote id, amount, tax etc. 20 | It also stores the state and status of an order. 21 | 22 | **sales_flat_order_address** 23 | 24 | This stores the address (shipping & billing) 25 | 26 | **sales_flat_order_grid** 27 | 28 | Stores information for the sales grid. 29 | 30 | **sales_flat_order_item** 31 | 32 | Contains the products and the different charges per product. 33 | 34 | **sales_flat_order_payment** 35 | 36 | This stores the payment details. 37 | 38 | **sales_flat_order_status_history** 39 | 40 | Stores the different changes in statuses for all orders. 41 | 42 | Mage_Payment_Model_Method_Cc 43 | 44 | 45 | ## Order to Invoice 46 | 47 | When an order state is to complete an invoice is automatically created. 48 | An order is set to processing by the payment method when the method has been charged. 49 | 50 | The invoice is created as follows: 51 | 52 | In the class **Mage_Sales_Model_Order_Payment** the method **capture** calls **Mage_Sales_Model_Order->prepareInvoice()**. 53 | 54 | 55 | This creates the invoice **Mage_Sales_Model_Order_Invoice** 56 | 57 | public function prepareInvoice($qtys = array()) 58 | { 59 | $invoice = Mage::getModel('sales/service_order', $this)->prepareInvoice($qtys); 60 | return $invoice; 61 | } 62 | 63 | ## Invoice tables 64 | 65 | **sales_flat_invoice** 66 | 67 | This stores the invoice information. 68 | 69 | **sales_flat_invoice_comments** 70 | 71 | Stores comments about the invoice/order 72 | 73 | **sales_flat_invoice_grid** 74 | 75 | Stores the totals and billing name. 76 | 77 | **sales_flat_invoice_item** 78 | 79 | Stores the products for the invoice. 80 | 81 | 82 | 83 | # 2. Capture vs authorize 84 | 85 | Capture collects the payment information and awaits the 3rd party to authorize the payment where as authorize is where Magento can make payment on behalf of the user. 86 | 87 | 88 | # Questions 89 | 90 | 91 | ## Which classes and methods are responsible for credit card operations (for example authorization or capturing)? 92 | 93 | Mage_Payment_Model_Method_Abstract 94 | Mage_Payment_Model_Method_Cc 95 | 96 | ## What is the difference between “pay” and “capture” operations? 97 | 98 | Capture collects the payment information whereas pay updates the totals for the invoices. 99 | 100 | ## What are the roles of the order, order_payment, invoice, and payment methods in the process of charging a card? 101 | 102 | 1. Order: save buying information. 103 | 2. Order payment: save payment information (price, card information) 104 | 3. Invoice: save information that customer paid. 105 | 4. Payment methods: process charge. 106 | 107 | ## What are the roles of the total models in the context of the invoice object? 108 | 109 | Recalulate the price after finishing the transaction. 110 | 111 | ## How does Magento store information about invoices? 112 | 113 | In the sales_flat invoice tables. 114 | 115 | 116 | # Further Reading 117 | 118 | - [http://magecert.com/sales.html](http://magecert.com/sales.html) 119 | - [http://brideo.co.uk/magento-certification-notes/request-flow/Sales/](http://brideo.co.uk/magento-certification-notes/request-flow/Sales/ ) 120 | 121 | - [http://stackoverflow.com/questions/5366551/magento-payment-flow](http://stackoverflow.com/questions/5366551/magento-payment-flow) 122 | - [http://inchoo.net/magento/magento-quote-order-invoice-workflow/](http://inchoo.net/magento/magento-quote-order-invoice-workflow/) 123 | -------------------------------------------------------------------------------- /1. Basics/1. Architecture/7. Describe methods for resolving module conflicts.md: -------------------------------------------------------------------------------- 1 | # Describe methods for resolving module conflicts 2 | 3 | ## 1. Overview 4 | 5 | 6 | There are 3 types of conflicts in Magento. 7 | 8 | - Configuration conflicts 9 | - Rewrite conflicts 10 | - Theme conflicts 11 | 12 | 13 | ## 2. Configuration conflicts 14 | 15 | This is where 2 modules conflict as they depend on the same module. 16 | Sometimes this will cause conflicts when loading files or classes. 17 | 18 | 19 | ### 2.1 Example 20 | 21 | Module_One and Module_Two both depend Mage Core. 22 | 23 | 24 | *app/etc/modules/Module_One.xml* 25 | 26 | 27 | 28 | 29 | true 30 | community 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *app/etc/modules/Module_Two.xml* 39 | 40 | 41 | 42 | 43 | true 44 | community 45 | 46 | 47 | 48 | 49 | 50 | ### 2.2 Solution 51 | 52 | The solution is that one of the modules should depend on the other module not Mage_Core. 53 | 54 | *app/etc/modules/Module_Two.xml* 55 | 56 | 57 | 58 | 59 | true 60 | community 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ## 3. Rewrite conflicts 69 | 70 | This is where you have 2 classes from different modules rewriting the same class and running into conflicts. 71 | 72 | 73 | ### 3.1 Example 74 | 75 | So for instance if Module_One and Module_Two both rewrite the *Mage_Sales_Model_Order* class they would have the following in their */etc/config.xml*. 76 | 77 | 78 | *Module_One/etc/config.xml* 79 | 80 | 81 | 82 | 83 | 84 | Module_One_Model_Rewrite_Sales_Order 85 | 86 | 87 | 88 | 89 | *Module_Two/etc/config.xml* 90 | 91 | 92 | 93 | 94 | 95 | Module_Two_Model_Rewrite_Sales_Order 96 | 97 | 98 | 99 | 100 | 101 | ### 3.2 Solution 102 | 103 | One of the classes would need extend the other rewrite class and we would remove the rewrite of the extended class. 104 | 105 | So in this example we will make Module Two extend from Module One rewrite class. 106 | 107 | 108 | 1. The following XML would be removed 109 | 110 | *Module_One/etc/config.xml* 111 | 112 | 113 | 114 | 115 | 116 | Module_One_Model_Rewrite_Sales_Order 117 | 118 | 119 | 120 | 121 | 122 | 2. The rewrite class would be extended from Module Ones class. 123 | 124 | *app/code/community/Module_Two/Model/Rewrite/Sales/Order.php* 125 | 126 | 127 | class Module_Two_Model_Rewrite_Sales_Order extends Module_One_Model_Rewrite_Sales_Order { 128 | ... 129 | } 130 | 131 | 132 | 133 | ## 4. Theme conflicts 134 | 135 | Sometimes there are conflicts with layout XML with themes and modules. 136 | 137 | One solution to debug the issue is to turn on hints under *System -> Config -> Advanced -> Developer -> Debug* in the store view. 138 | 139 | If you are using PhpStorm and Magicento you can go into any block or template and check where its being called in the layout using the cmd + b command. Not useful for the exam but useful in real life. 140 | 141 | 142 | ## 5. Further Reading 143 | 144 | [http://blog.belvg.com/get-ready-for-magento-certified-developer-exam-describing-methods-for-resolving-module-conflicts.html](http://blog.belvg.com/get-ready-for-magento-certified-developer-exam-describing-methods-for-resolving-module-conflicts.html) 145 | -------------------------------------------------------------------------------- /1. Basics/2. Configuration/6. Setting up a CRON.md: -------------------------------------------------------------------------------- 1 | # Setting up a CRON 2 | 3 | 4 | # 1. Registering a CRON 5 | 6 | You register a CRON in your modules config.xml file under global node 7 | 8 | 9 | 10 | 11 | 12 | 13 | */1 * * * * 14 | 15 | 16 | colin_bootstrap/observer_cron::runCustomCronJob 17 | 18 | 19 | 20 | 21 | 22 | **colin_bootstrap_cron** name of the CRON stored in the database (more below) 23 | **cron_expr** CRON expression 24 | **colin_bootstrap/observer_cron::runCustomCronJob** Class and method for running your custom CRON. 25 | 26 | The class would then look like the code below. 27 | 28 | **app/code/local/Colin/Bootstrap/Model/Observer/Cron.php** 29 | 30 | 31 | class Colin_Bootstrap_Model_Observer_Cron extends Mage_Core_Model_Abstract 32 | { 33 | public function runCustomCronJob(Mage_Cron_Model_Schedule $observer) 34 | { 35 | Mage::log("Cron has ran.", null, 'cron.log', true); 36 | return $this; 37 | } 38 | 39 | } 40 | 41 | 42 | 43 | # 2. How Magento CRON's work 44 | 45 | So we have looked at how to create a CRON but lets look at how it works: 46 | 47 | - A CRON from the server calls the Magento cron.php in the project root 48 | - cron.php loads events observers and dispatches the events 49 | 50 | 51 | So in the cron.php the following bit of code is called: 52 | 53 | Mage::getConfig()->init()->loadEventObservers('crontab'); 54 | 55 | 56 | This loops through the observers for each crontab area and dispatches their event. 57 | 58 | So Mage_Cron_Model_Observer::dispatch() is called in this loop and this does the following: 59 | 60 | 1. Process scheduled cron queue: Magento reads the cron schedule table for jobs that need to be executed this very second and jobs that should have already been executed, i.e. with timestamps in the past, that haven’t expired. The expiry limit is also a parameter, configurable in the admin panel. After all the work, dispatch method calls two generate() and cleanup() methods 61 | 62 | 2. Generate tasks schedule: Mage_Cron_Model_Observer->generate(), this method searches final configuration file for content of nodes ($config = Mage::getConfig()->getNode(‘crontab/jobs’); ), reading elements to find out when and how often they need to be executed and pulls this data into the cron_schedule table. 63 | 64 | 3. Cleanup: Mage_Cron_Model_Observer->cleanup(), this method deletes completed (with ‘success’ status) or missed ($time < $now – $scheduleLifetime, where $scheduleLifetime are set in Magento admin area) jobs from cron_schedule DB table. 65 | 66 | **Note::** Information above extracted from [http://blog.belvg.com/magento-certified-developer-exam-setting-up-a-cron-job.html](http://blog.belvg.com/magento-certified-developer-exam-setting-up-a-cron-job.html) 67 | 68 | 69 | # 3. Magento Admin configuration 70 | 71 | Mage_Cron_Model_Observer know how and when to do the following tasks above based off the configuration settings for the CRON. These can be found under System -> Configuration -> System and in the Cron tab. 72 | 73 | - **Generate Schedules Every** - Schedules the setup frequency of the CRON jobs in the database, 74 | - **Schedule Ahead for** - How far to schedule ahead for. 75 | - **Missed if Not Run Within** - How many minutes can a CRON be run after it was scheduled. Otherwise it will be set to "miss" when the CRON runs and the time has exceeded. 76 | - **History Cleanup Every** - Magento will clean up history not more than setup amount of minutes. 77 | - **Success History Lifetime** - How long completed tasks with "success" will be stored in the database. 78 | - **Failure History Lifetime** - How long completed tasks with "missed" or "error" will be stored in the database. 79 | 80 | 81 | 82 | ## Further Reading 83 | [http://blog.belvg.com/magento-certified-developer-exam-setting-up-a-cron-job.html](http://blog.belvg.com/magento-certified-developer-exam-setting-up-a-cron-job.html) 84 | -------------------------------------------------------------------------------- /4. Databases/2. Install:Update Scripts/1. Describe the install:upgrade workflow.md: -------------------------------------------------------------------------------- 1 | # Describe the install/upgrade workflow 2 | 3 | Please read [Basic Concepts](https://github.com/colinmurphy/magento-exam-notes/blob/master/4.%20Databases/1.%20Models%2C%20Resource%20Models%20%26%20Collections/1.%20Basic%20Concepts.md) for more information. 4 | 5 | 6 | Below is an explanation of how these scripts are called 7 | 8 | # 1. config.xml 9 | 10 | There are 3 parts: 11 | - Module Version Number 12 | - Model & Resource Registration 13 | - Resource setup 14 | 15 | 16 | **Module Version Number** 17 | 18 | 19 | 20 | 0.0.1 21 | 22 | 23 | 24 | **Model and Resource Model Registration** 25 | 26 | 27 | 28 | 29 | Colin_Database_Model 30 | colin_database_resource 31 | 32 | 33 | Colin_Database_Model_Resource 34 | 35 | 36 | football_results
37 |
38 |
39 |
40 |
41 |
42 | 43 | **Resource Setup Registration** 44 | 45 | 46 | 47 | 48 | 49 | Colin_Database 50 | 51 | 52 | 53 | 54 | 55 | 56 | These version numbers are stored in the core_resource table for both version and data version of a module as they updated in 2 different methods: 57 | 58 | | code | version | data_version | 59 | | :------------- | :------------- | :------------- | 60 | | colin_database_setup | 0.0.1 | 0.0.1 | 61 | 62 | 63 | # 2. Request Flow 64 | 65 | # 2.1. Install/Update Setup Scripts 66 | 67 | If the request is not cached then *Mage_Core_Model_App* calls the method *_initModules*. 68 | 69 | This method does the following: 70 | 71 | 1. Loads the modules in *Mage_Core_Model_Config->loadModules()* 72 | 2. Runs the updates for the install/upgrade scripts 73 | 3. Loads the database configuration 74 | 75 | So the following method is called: 76 | 77 | Mage_Core_Model_Resource_Setup::applyAllUpdates(); 78 | 79 | This looks for modules with different "version" numbers and then runs the install/upgrade file. 80 | 81 | So for colin_database_setup it will look under the "Colin_Database" module directory for: 82 | 83 | sql/colin_database_setup/install-0.0.1.php 84 | sql/colin_database_setup/upgrade-0.0.1-0.0.2.php 85 | 86 | So the method loops through the global/resource/setup configs and do the following: 87 | 88 | **Note:** If the module is EAV it will use the class *Mage_Eav_Model_Entity_Setup* instead of *Mage_Core_Model_Resource_Setup*. 89 | 90 | It will create new setup classes Mage_Core_Model_Resource_Setup and call the method *applyUpdates()* 91 | 92 | foreach ($resources as $resName => $resource) { 93 | if (!$resource->setup) { 94 | continue; 95 | } 96 | $className = __CLASS__; 97 | if (isset($resource->setup->class)) { 98 | $className = $resource->setup->getClassName(); 99 | } 100 | $setupClass = new $className($resName); 101 | $setupClass->applyUpdates(); 102 | if ($setupClass->getCallAfterApplyAllUpdates()) { 103 | $afterApplyUpdates[] = $setupClass; 104 | } 105 | } 106 | 107 | This will then check the db version and then run the install/update scripts for that module 108 | 109 | 110 | 111 | # 2.2. Install/Update Data Scripts 112 | 113 | Later on the Request Initialization process the following method is called in the method *run()*. 114 | 115 | Mage_Core_Model_Resource_Setup::applyAllDataUpdates 116 | 117 | This then applies all install/upgrade data scripts. 118 | 119 | The file names would be: 120 | 121 | data/colin_database_setup/data-install-0.0.1.php 122 | data/colin_database_setup/data-upgrade-0.0.1-0.0.2.php 123 | -------------------------------------------------------------------------------- /3. Rendering/3. Design layout, XML schema, and CMS content directives.md: -------------------------------------------------------------------------------- 1 | # Design layout, XML schema, and CMS content directives 2 | 3 | 4 | ### How are ``, ``, and `` used in Magento layout? 5 | 6 | - Update - updates applied after blocks are being processed 7 | - Block - template files 8 | - Action - Calls a method 9 | 10 | 11 | ### Which classes and methods determine which nodes from layout XML correspond to certain URLs? 12 | 13 | - Mage_Core_Controller_Varien_Front 14 | - Mage_Core_Model_Layout 15 | - Mage_Core_Model_Layout_Update 16 | - Mage_Core_Model_Layout_Package 17 | 18 | ### How can layout XML files be registered for the frontend and adminhtml areas? 19 | 20 | 21 | 22 | 23 | 24 | catalog.xml 25 | 26 | 27 | 28 | 29 | or 30 | 31 | 32 | 33 | 34 | 35 | catalog.xml 36 | 37 | 38 | 39 | 40 | ### How can code be modified or added to Magento pages using the following methods? 41 | − Template customizations 42 | 43 | or 64 | 65 | 66 | 67 | colin_request/observer 68 | generateBlocks 69 | singleton 70 | 71 | 72 | 73 |
74 |
75 | 76 | app/code/local/Colin/Request/Model/Observer.php 77 | 78 | 79 | public function generateBlocks($observer) 80 | { 81 | $block = $observer->getEvent()->getBlock(); 82 | if ($block->getType() == 'page/html_header') { 83 | // Do Something 84 | } 85 | 86 | if ($block->getNameInLayout() === 'content') { 87 | $text = Mage::app()->getLayout()->createBlock('core/text', 'my_string', array('before', '-')); 88 | $text->setText('Hello World'); 89 | $block->append($text); 90 | } 91 | 92 | } 93 | 94 | ### How can variables be passed to the block using the following methods? 95 | − From layout xml file 96 | value 97 | 98 | − From controller 99 | getData('name'); 100 | 101 | 102 | − From one block to another 103 | $this->getLayout()->getBlock('name')->getData('name'); 104 | 105 | − From an arbitrary location (for example, install/upgrade scripts,models) 106 | Mage::app()->getLayout()->getBlock('name')->getData('name'); 107 | 108 | 109 | ### Describe various ways to add and customize JavaScript to specific request scopes: 110 | 111 | **addItem** 112 | 113 | 114 | 115 | skin_js 116 | js/script.js 117 | 118 | 119 | 120 | **addJs** (for libraries under js directory not skin) 121 | 122 | 123 | 124 | library/script.js 125 | 126 | 127 | 128 | **addJsIe** (for libraries under js directory not skin) 129 | 130 | 131 | 132 | library/ie.js 133 | 134 | 135 | 136 | 137 | ### Which block is responsible for rendering JavaScript in Magento? 138 | 139 | Mage_Page_Block_Html_Head 140 | 141 | ### Which modes of including JavaScript does Magento support? 142 | 143 | addItem, addJs, addJsIe 144 | 145 | ### Which classes and files should be checked if a link to a custom JavaScript file isn’t being rendered on a page? 146 | 147 | - Xml file that is adding the js 148 | - skin/js and js directories to see if the file exists 149 | - Mage_Page_Block_Html_Head class 150 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/5. Describe group save operations.md: -------------------------------------------------------------------------------- 1 | # Describe group save operations 2 | 3 | When a flat table or entity is being saved it calls the method save() in *Mage_Core_Model_Abstract* class. 4 | 5 | This calls 2 events before and after save. These methods both generate dispatch events which can be used to manipulate data. 6 | 7 | 8 | $this->_beforeSave(); 9 | if ($this->_dataSaveAllowed) { 10 | $this->_getResource()->save($this); 11 | $this->_afterSave(); 12 | } 13 | 14 | 15 | # 1. _beforeSave() 16 | 17 | 18 | protected function _beforeSave() 19 | { 20 | if (!$this->getId()) { 21 | $this->isObjectNew(true); 22 | } 23 | Mage::dispatchEvent('model_save_before', array('object'=>$this)); 24 | Mage::dispatchEvent($this->_eventPrefix.'_save_before', $this->_getEventData()); 25 | return $this; 26 | } 27 | 28 | As you can see this generates 2 dispatch events: 29 | 30 | - model_save_before 31 | - {{event}}_save_before e.g. (customer_address_save_before, catalog_product_save_before) 32 | 33 | 34 | # 2. _afterSave() 35 | 36 | This is the same as before only replacing "before" with "after" and also clearing the model cache. 37 | 38 | protected function _afterSave() 39 | { 40 | $this->cleanModelCache(); 41 | Mage::dispatchEvent('model_save_after', array('object'=>$this)); 42 | Mage::dispatchEvent($this->_eventPrefix.'_save_after', $this->_getEventData()); 43 | return $this; 44 | } 45 | 46 | 47 | # 3. Examples of Save Before/After 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | singleton 56 | yourmodule/observer 57 | customer_address_save_before 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | singleton 66 | yourmodule/observer 67 | customer_address_save_after 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | singleton 76 | yourmodule/observer 77 | catalog_product_save_before 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | singleton 86 | yourmodule/observer 87 | catalog_product_save_after 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | class YourNamespace_YourModule_Model_Observer 96 | { 97 | public function customer_address_save_before($observer) 98 | { 99 | $address = $observer->getCustomerAddress(); 100 | //echo "
"; print_r($address->getData()); exit;
101 |             // do something here
102 |         }
103 | 
104 |         public function customer_address_save_after($observer)
105 |         {
106 |             $address = $observer->getCustomerAddress();
107 |             //echo "
"; print_r($address->getData()); exit;
108 |             // do something here
109 |         }
110 | 
111 |         public function catalog_product_save_before($observer)
112 |         {
113 |             $product = $observer->getProduct();
114 |             //echo "
"; print_r($product->getData()); exit;
115 |             // do something here
116 |         }
117 | 
118 |         public function catalog_product_save_after($observer)
119 |         {
120 |             $product = $observer->getProduct();
121 |             //echo "
"; print_r($product->getData()); exit;
122 |             // do something here
123 |         }
124 |     }
125 | 


--------------------------------------------------------------------------------
/2. Request Flow/8. Additional Notes/Answers.md:
--------------------------------------------------------------------------------
  1 | # 1. Application Initialization
  2 | 
  3 | 
  4 | ##  List the events which happen in index.php
  5 | 
  6 | - Checks PHP version
  7 | - Adds compiler
  8 | - Checks for downloader
  9 | - Checks for Mage.php
 10 | - Mage::run($code, $type)
 11 | 
 12 | ##  What are the parameters for MAGE_RUN_CODE
 13 | 
 14 | - store
 15 | - group
 16 | - website
 17 | 
 18 | ##  How do you set a different website in the .htaccess file for Apache web server
 19 | 
 20 | 
 21 |     SetEnv MAGE_RUN_CODE website
 22 |     SetEnv MAGE_RUN_TYPE de
 23 | 
 24 | 
 25 | ##  How do you init the Mage_Core_Model_App env without a request
 26 | 
 27 |   Mage::app()
 28 | 
 29 | ##  What is the order of base, module & database loaded and what are their methods and class
 30 | 
 31 | 1. Base   Mage_Core_Model_Config->loadBase()
 32 | 2. Modules Mage_Core_Model_Config->loadModules()
 33 | 3. Database Mage_Core_Model_Config->loadDb()
 34 | 
 35 | ##  What order are modules loaded in and what method sorts the modules
 36 | 
 37 | 1. Mage_All.xml
 38 | 2. Mage*.xml
 39 | 3. All other xml files
 40 | 
 41 | This loaded in *Mage_Core_Model_Config->_getDeclaredModuleFiles()*
 42 | 
 43 | 
 44 | ##  What is loaded after module files are loaded
 45 | 
 46 | Database and then local.xml
 47 | 
 48 | 
 49 | ##  What is the name of the resource config
 50 | 
 51 | Mage_Core_Model_Resource_Config
 52 | 
 53 | 
 54 | ## Mage_Core_Model_Resource_Config->loadToXml() what does it load into the config
 55 | 
 56 | 1. Loads website into website node
 57 | 2. Loads stores into store node
 58 | 3. Loads config and database config into default node
 59 | 
 60 | ##  How and when are the two main types of setup script executed?
 61 | 
 62 | 1. Mage_Core_Model_Resource_Setup::applyAllUpdates()
 63 | 2. Mage_Core_Model_Resource_Setup::applyAllDataUpdates()
 64 | 
 65 | 
 66 | # 2. Front Controller
 67 | 
 68 | 
 69 | ##  Name the class for the Front, Frontend and Admin router
 70 | 
 71 | 1. Mage_Core_Controller_Varien_Front
 72 | 2. Mage_Core_Controller_Varien_Router_Standard
 73 | 3. Mage_Core_Controller_Varien_Router_Admin
 74 | 
 75 | ##  What are the use node frontend and admin router
 76 | 
 77 | standard and admin
 78 | 
 79 | ##  What are the 4 routers in order
 80 | 
 81 | 1. Admin - Mage_Core_Controller_Varien_Router_Admin
 82 | 2. Standard - Mage_Core_Controller_Varien_Router_Standard
 83 | 3. CMS - Mage_Cms_PageController
 84 | 4. Default - Mage_Core_Controller_Varien_Router_Default
 85 | 
 86 | ##  How do you add a router before the default router
 87 | 
 88 | Using the observer controller_front_init_routers
 89 | 
 90 | ##  What action class does a frontend and admin router extend from
 91 | 
 92 | Mage_Core_Controller_Varien_Router_Abstract
 93 | 
 94 | ##  What is the method a new router needs and what abstract class should it extend from
 95 | 
 96 | public function match(Zend_Controller_Request_Http $request)
 97 | 
 98 | 
 99 | # 3. Modules
100 | 
101 | ##  What class is responsible for loading Modules
102 | 
103 | Mage_Core_Model_Config
104 | 
105 | ##  What is the difference regarding module loading between Mage::run() and Mage::app()?
106 | 
107 | Mage::app() will run Magento without processing a request whereas Mage::run() will process a request.
108 | 
109 | # 4. Layout Initialization
110 | 
111 | ##  What class is responsible for layout
112 | 
113 | Mage_Core_Model_Layout
114 | 
115 | ##  What are the 2 methods required to render layout in a Controller
116 | 
117 | $this->loadLayout()
118 | $this->renderLayout()
119 | 
120 | 
121 | ##  What is the config for a module to add its own layout xml file
122 | 
123 | 
124 |       
125 |         
126 |           
127 |             
128 |               custom_layout.xml
129 | 
130 | 
131 | ##  What does Mage_Core_Controller_Varien_Action->loadLayout() do
132 | 
133 | 1. Generates the layout handles
134 | 2. Generates the layouts and blocks
135 | 
136 | 
137 | ##  How do you add a custom layout handle
138 | 
139 | 
140 |     
141 |       
142 |           
143 |               colin_request/observer
144 |               controllerActionLayoutLoadBefore
145 |           
146 |       
147 |     
148 | 
149 | 
150 |     public function controllerActionLayoutLoadBefore(Varien_Event_Observer $observer)
151 |     {
152 | 
153 |         $layout = $observer->getEvent()->getLayout();
154 |         $layout->getUpdate()->addHandle('my_custom_handle');
155 |     }
156 | 
157 | 
158 | 
159 | ##  How do you add content from an observer
160 | 
161 | Use the observer core_block_abstract_prepare_layout_before and add a block
162 | 


--------------------------------------------------------------------------------
/1. Basics/2. Configuration/Questions.md:
--------------------------------------------------------------------------------
  1 | ### 1. How does the framework discover active modules and their configuration?
  2 | 
  3 | 
  4 |     Mage_Core_Model_Config->_loadDeclaredModules()
  5 | 
  6 | 
  7 | This method searches for any xml files under app/etc/modules and loads the modules.
  8 | Firstly it calls *_getDeclaredModuleFiles* to get all the files
  9 | 
 10 | It then loops through the files and does the following:
 11 | 
 12 | - Loads the module configuration
 13 | - Adds the modules names which it depends into an array
 14 | - Sorts the modules it depends on in *_sortModuleDepends*
 15 | - Creates the configuration *Mage_Core_Model_Config_Base* and adds the XML ** to the class
 16 | - Adds modules to the configuration
 17 | - Adds the modules it depends on to the configuration
 18 | 
 19 | ### 2. What are the common methods with which the framework accesses its configuration values and areas?
 20 | 
 21 | 
 22 | - Mage::->getStoreConfig($path);
 23 | - Mage::app()->getStore()->getConfig($path);
 24 | - Mage::getStoreConfigFlag($path); *Checks if a value exists*
 25 | - Mage::getConfig()->getNode($path);
 26 | 
 27 | 
 28 | ### 3. How are per-store configuration values established in the XML DOM?
 29 | 
 30 | The per-store config values are defined in the config.xml file of your module under the  node and under the 
 31 | 
 32 | **Example:** If you wanted to override the theme
 33 | 
 34 |     
 35 |         
 36 |             
 37 |                 
 38 |                     default
 39 |                 
 40 |                 
 41 |                     modern
 42 |                 
 43 |             
 44 |         
 45 |     
 46 | 
 47 | 
 48 | You can also do this with the  and  nodes
 49 | 
 50 | 
 51 |     
 52 |         
 53 |             
 54 |                 
 55 |                     default
 56 |                 
 57 |                 
 58 |                     modern
 59 |                 
 60 |             
 61 |         
 62 |     
 63 | 
 64 | 
 65 | 
 66 | 
 67 | **Note:** Answer taken from [http://magestudyguide.com/#how-are-per-store-configuration-values-established-in-the-xml-dom?](http://magestudyguide.com/#how-are-per-store-configuration-values-established-in-the-xml-dom?)
 68 | 
 69 | 
 70 | ### 4. By what process do the factory methods and autoloader enable class instantiation?
 71 | 
 72 | - Varien_Autoload
 73 | - spl_autoload_register
 74 | 
 75 | For further information please read [Explain how Magento loads and manipulates configuration information](https://github.com/colinmurphy/magento-exam-notes/blob/master/1.%20Basics/2.%20Configuration/1.Explain%20how%20Magento%20loads%20and%20manipulates%20configuration%20information.md)
 76 | 
 77 | ### 5. Which class types have configured prefixes, and how does this relate to class overrides?
 78 | 
 79 | Not too sure about this question but I think this is what it means:
 80 | 
 81 | You can override classes in 2 ways:
 82 | 
 83 | - Config Rewrite
 84 | - Adding a class file relative in another codePool that is loaded beforehand.
 85 | e.g. create app/code/local/Mage/Core/Model/Product.php to override Mage_Catalog_Model_Product
 86 | 
 87 | This is not recommended but can be done due to the multiple paths used in set_include_path() in app/Mage.php.
 88 | 
 89 | 
 90 | ### 6. Which class types and files have explicit paths?
 91 | 
 92 | Not sure what this means?
 93 | 
 94 | ### 7. What configuration parameters are available for event observers?
 95 | 
 96 | **type**
 97 | 
 98 | - model
 99 | - object
100 | - none
101 | - singleton
102 | 
103 | **class**
104 | 
105 | Name of the class of the observer e.g. Colin_Bootstrap_Model_Observer
106 | 
107 | 
108 | **method**
109 | 
110 | Name of the method called
111 | 
112 | ### 8. What are the interface and configuration options for automatically fired events?
113 | 
114 | This is registering an observer.
115 | 
116 | ### 9. What is the structure of event observers, and how are properties accessed therein?
117 | 
118 | This is how an observer works e.g.
119 | 
120 |       Mage::dispatchEvent('catalog_product_get_final_price', array('product' => $product, 'qty' => $qty));
121 | 
122 | 
123 | Parameters are then accessed as follows:
124 | 
125 |     public function myObserverMethod($observer)
126 |     {
127 |       $product = $observer->getEvent()->getProduct();
128 |       $qty = $observer->getEvent()->getQty();
129 |       /* Do something */
130 |     }
131 | 
132 | ### 10. What configuration parameters are available for cron jobs?
133 | 
134 | Under global -> events -> crontab -> name_of_cron there are:
135 | 
136 | - schedule -> cron_expr
137 | - run -> model
138 | 
139 | Example:
140 | 
141 |       
142 |           
143 |               
144 |                   
145 |                       
146 |                          */1 * * * *
147 |                       
148 |                       
149 |                           colin_bootstrap/observer_cron::runCustomCronJob
150 |                       
151 |                   
152 |               
153 |           
154 | 


--------------------------------------------------------------------------------
/7. Catalog/ 1. Product Types/1. Identify and describe standard product types.md:
--------------------------------------------------------------------------------
  1 | # Identify and describe standard product types
  2 | 
  3 | # 0. Overview
  4 | 
  5 | There are 6 types:
  6 | 
  7 | 1. Simple
  8 | 2. Grouped
  9 | 3. Configurable
 10 | 4. Virtual
 11 | 5. Downloadable
 12 | 6. Bundle
 13 | 
 14 | These are set in the config.xml which we will go through in the next part.
 15 | 
 16 | 
 17 | ## 0.1. Product Types
 18 | 
 19 | Products are setup in the config.xml (more next part) and all product types extend from **Mage_Catalog_Model_Product_Type_Abstract**.
 20 | 
 21 | ### Mage_Catalog vs non Mage_Catalog
 22 | 
 23 | **Mage_Catalog Products:**
 24 | 
 25 | 1. Simple - Mage_Catalog_Model_Product_Type_Simple
 26 | 2. Grouped - Mage_Catalog_Model_Product_Type_Grouped
 27 | 3. Configurable - Mage_Catalog_Model_Product_Type_Configurable
 28 | 4. Virtual - Mage_Catalog_Model_Product_Type_Virtual
 29 | 
 30 | **Mage_Bundle**
 31 | 
 32 | 5. Bundle - Mage_Bundle_Model_Product_Type
 33 | 
 34 | **Mage_Downloadable**
 35 | 
 36 | 6. Downloadable - Mage_Downloadable_Model_Product_Type
 37 | 
 38 | This also extends from **Mage_Catalog_Model_Product_Type_Virtual**
 39 | 
 40 | 
 41 | ### Get a Product Type
 42 | To get a product type you would run the following bit of code:
 43 | 
 44 | 
 45 |     $product->getTypeInstance();
 46 | 
 47 | 
 48 | # 1. Simple Product
 49 | 
 50 | **Type:** Mage_Catalog_Model_Product_Type_Simple
 51 | 
 52 | 
 53 | # 2. Grouped Product
 54 | 
 55 | **Type:** Mage_Catalog_Model_Product_Type_Grouped
 56 | 
 57 | 
 58 | ## Table Structure
 59 | 
 60 | This is for multiple products which are grouped. The simple products are stored in the **catalog_product_link** table.
 61 | 
 62 | Example:
 63 | 
 64 | | link_id     | product_id     | linked_product_id     | link_type_id     |
 65 | | :------------- | :------------- | :------------- | :------------- |
 66 | | 1    | 3     | 1      | 3      |
 67 | | 2    | 3     | 2      | 3      |
 68 | 
 69 | - **link_id** - unique
 70 | - **product_id** - grouped product
 71 | - **linked_product_id** - simple product
 72 | - **link_type_id** -  The link type is 3 as its a super product and the values for the link type are stored in **catalog_product_link_type** table.
 73 | 
 74 | **Note:** This is also where related, cross sells and upsells are stored. The only difference is the link_type_id.
 75 | 
 76 | **Note:** A further table *catalog_product_relation* also stores all relations (configurable, bundle etc). It only stores the parent and child id.
 77 | 
 78 | ## Get Associated Products
 79 | 
 80 | 
 81 |     $product = Mage::getModel("catalog/product")->load(3);
 82 |     $grouped = $product->getTypeInstance(true);
 83 |     foreach($grouped->getAssociatedProducts($product) as $simple) {
 84 |         echo $simple->getSku() . "
"; 85 | } 86 | 87 | # 3. Configurable Product 88 | 89 | **Type:** Mage_Catalog_Model_Product_Type_Configurable 90 | 91 | ## Tables 92 | 93 | Configurable products are stored **catalog_product_super_link**. This stores the product id and parent id of the configurable products. 94 | 95 | | link_id | product_id | parent_id | 96 | | :------------- | :------------- | :------------- | 97 | | 1 | 1 | 4 | 98 | | 1 | 2 | 2 | 99 | 100 | 101 | 102 | Configurable Attributes are stored in **catalog_product_super_attribute**. This stores the product id and attribute id used to create the configurable product. 103 | 104 | 105 | Pricing is stored in **catalog_product_super_attribute_pricing** for the different products. This price is used to add/subtract from the configurable product price. 106 | 107 | 108 | # 4. Virtual 109 | 110 | **Type:** Mage_Catalog_Model_Product_Type_Virtual 111 | 112 | These are virtual products such as a subscription service. The difference between Virtual and Downloadable is that you can download a file/files. 113 | 114 | # 5. Downloadable 115 | 116 | **Type:** Mage_Downloadable_Model_Product_Type 117 | 118 | These are products with downloadable files. 119 | 120 | ## Tables 121 | 122 | Downloadable Products are stored in **downloadable_link** table. This contains the file, sample file(optional), sharable, max number of downloads, type and number of downloads. 123 | 124 | **downloadable_link_price** stores the price of individual downloadable products. Downloadable Products have a base price. 125 | 126 | ## Get Links 127 | 128 | 129 | //@var Mage_Catalog_Model_Product $product 130 | $product = Mage::getModel("catalog/product")->load(6); 131 | //@var Mage_Downloadable_Model_Product_Type $downloadable 132 | $downloadable = $product->getTypeInstance(true); 133 | 134 | $links = $downloadable->getLinks($product); 135 | foreach($links as $link) { 136 | $file = Mage::getUrl("media/downloadble/files/links/") . $link['link_file']; 137 | echo $file; 138 | } 139 | 140 | 141 | You can also get samples with $downloadble->getSamples($downloadble); 142 | 143 | 144 | # 6. Bundle 145 | 146 | **Type:** Mage_Bundle_Model_Product_Type 147 | 148 | 149 | These are bundle products where a user can select multiple simple products. Bundle products have a base price and individual simple products can also have an additional price. These are added under Bundle items and can also their price can be fixed or percent. 150 | 151 | 152 | ## Tables 153 | 154 | **catalog_product_bundle_selection:** stores the simple products and prices. 155 | Bundle products also have their own index tables. 156 | -------------------------------------------------------------------------------- /2. Request Flow/6. Design and layout initialization/1. Design and layout initialization.md: -------------------------------------------------------------------------------- 1 | # Design and layout initialization 2 | 3 | Identify the steps in the request flow in which: 4 | 5 | 1. Design data is populated 6 | 2. Layout configuration files are parsed 7 | 3. Layout is compiled 8 | 4. Output is rendered 9 | 10 | **Note:** Read Alan Storm's No Frill Magento Layout Chapter 3 11 | 12 | Overview 13 | 14 | - controller created by router 15 | - controller extends Mage_Core_Controller_Front_Action which extends from Mage_Core_Controller_Varien_Action 16 | - $this->loadLayout() method called to generate handles, layout and blocks 17 | - $this->renderLayout() method to output blocks 18 | 19 | 20 | 21 | # 1 Mage_Core_Controller_Varien_Action - loadLayout() - generate handles 22 | 23 | So Magento generates 5 handles in order: 24 | 25 | 1. default 26 | 2. STORE_{store_view_code} e.g. STORE_default or STORE_de 27 | 3. THEME_{area}_{package}_{theme} e.g. THEME_frontend_colin_default 28 | 4. module_controller_action e.g. catalog_product_view or colin_request_index_index 29 | 5. customer_logged_in/customer_logged_out 30 | 31 | Handles are stored in Mage_Core_Model_Layout_Update and the layout class is Mage_Core_Model_Layout. 32 | 33 | You can add a handle like so in PHP: 34 | 35 | $this->getLayout()->getUpdate()->addHandle(); 36 | 37 | 38 | 39 | # 2. Mage_Core_Model_Layout - generateXml() 40 | 41 | Then this method is called in loadLayout(); 42 | Please note Alan Storm's No Frills Magento Layout book in Chapter 3 gives a better explanation of this process. 43 | 44 | Layout XML files are added in config.xml files as follows: 45 | 46 | 47 | 48 | 49 | 50 | catalog.xml 51 | 52 | 53 | 54 | 55 | 56 | Theses files are merged in *Mage_Core_Model_Layout_Update->getFileLayoutUpdatesXml()* then the local.xml file is appended along with theme files (not part of exam as it is still based on 1.8). 57 | 58 | XML is returned by $xml = $this->getUpdate()->asSimplexml(); 59 | 60 | At this point any remove elements are removed from the XML. 61 | 62 | 63 | 64 | **Note:** Dispatch Event at the top before layout XML is loaded 65 | 66 | Mage::dispatchEvent( 67 | 'controller_action_layout_generate_xml_before', 68 | array('action'=>$this, 'layout'=>$this->getLayout()) 69 | ); 70 | 71 | 72 | # 3. Mage_Core_Model_Layout - generateLayoutBlocks() 73 | 74 | So before this is called the XML is all XML and no blocks, references or update handles have been used/created. 75 | We did note that elements with are already removed. 76 | 77 | So we loop through the XML *Mage_Core_Model_Layout_Element* and run a switch statement to create the output 78 | 79 | switch ($node->getName()) { 80 | case 'block': 81 | $this->_generateBlock($node, $parent); 82 | $this->generateBlocks($node); 83 | break; 84 | 85 | case 'reference': 86 | $this->generateBlocks($node); 87 | break; 88 | 89 | case 'action': 90 | $this->_generateAction($node, $parent); 91 | break; 92 | } 93 | 94 | 95 | These eventually lead to calling the addBlock/createBlock method 96 | 97 | $this->addBlock($block, $blockName); 98 | $this->addBlock('page/html', 'root'); 99 | $this->addBlock('core/text_list', 'top.menu'); 100 | 101 | These blocks will be covered in Chapter 3 Rendering. 102 | 103 | In the method createBlock it adds the block to a property $_block 104 | 105 | $this->_blocks[$name] = $block; 106 | 107 | 108 | 109 | 110 | **Note:** 111 | Dispatch Events before/after blocks created 112 | 113 | Mage::dispatchEvent( 114 | 'controller_action_layout_generate_blocks_before', 115 | array('action'=>$this, 'layout'=>$this->getLayout()) 116 | ); 117 | 118 | Mage::dispatchEvent( 119 | 'controller_action_layout_generate_blocks_after', 120 | array('action'=>$this, 'layout'=>$this->getLayout()) 121 | ); 122 | 123 | 124 | Dispatch Event after a block is created 125 | 126 | 127 | Mage::dispatchEvent('core_layout_block_create_after', array('block'=>$block)); 128 | 129 | 130 | # 4. Mage_Core_Controller_Varien_Action -> renderLayout(); 131 | 132 | So in your controller you would call this method to render the layout and append it to the body of the response object *Mage_Core_Controller_Response_Http* 133 | 134 | This calls the method Mage_Core_Model_Layout->getOutput() which outputs the blocks: 135 | 136 | public function getOutput() 137 | { 138 | $out = ''; 139 | if (!empty($this->_output)) { 140 | foreach ($this->_output as $callback) { 141 | $out .= $this->getBlock($callback[0])->$callback[1](); 142 | } 143 | } 144 | 145 | return $out; 146 | } 147 | 148 | 149 | **Notes:** These dispatch events called before the layout is rendered 150 | 151 | Mage::dispatchEvent('controller_action_layout_render_before'); 152 | Mage::dispatchEvent('controller_action_layout_render_before_'.$this->getFullActionName()); 153 | 154 | 155 | # References 156 | [http://devdocs.magento.com/guides/m1x/magefordev/mage-for-dev-4.html](http://devdocs.magento.com/guides/m1x/magefordev/mage-for-dev-4.html) 157 | -------------------------------------------------------------------------------- /9.Sales & Customers/3. Additional Notes/Answers.md: -------------------------------------------------------------------------------- 1 | # 1. Admin Order Creation 2 | 3 | 4 | ## How do you prevent a payment method being used by an admin order 5 | 6 | Set the property *$_canUseInternal* to false in the payment method. 7 | 8 | ## What is the controller for creating admin Orders 9 | 10 | Mage_Adminhtml_Sales_Order_CreateController 11 | 12 | ## What is abstract class for admin order controllers 13 | 14 | Mage_Adminhtml_Controller_Action 15 | 16 | ## How does Magento calculate price when an order is created from the admin 17 | 18 | In *Mage_Adminhtml_Sales_Order_CreateController_processActionData()* 19 | 20 | ## Which steps are necessary in order to create an order from the admin? 21 | 22 | 1. Create Order Under Sales -> Orders 23 | 2. Select Customer 24 | 3. Select Store and enter details 25 | 4. Add Products 26 | 5. Set Billing Address 27 | 6. Set Shipping Address 28 | 7. Set Shipping Method 29 | 8. Set Payment Method 30 | 9. Place Order 31 | 32 | ## What happens when existing orders are edited in the admin? 33 | 34 | They are re-created with using the same order number and a "-1" added to the order number 35 | 36 | 37 | # 2. Order Status & State 38 | 39 | ## Difference between status and state 40 | 41 | State is an internal state for Magento which can have multiple statuses 42 | 43 | ## List all statuses 44 | 45 | Answer from [http://magento.stackexchange.com/a/516/6617](http://magento.stackexchange.com/a/516/6617) 46 | 47 | - **Pending:** Pending orders are brand new orders that have not been processed. Typically, these orders need to be invoiced and shipped. 48 | - **Pending PayPal:** Pending PayPal orders are brand new orders that have not been cleared by PayPal. [...] 49 | - **Processing:** Processing means that orders have either been invoiced or shipped, but not both. 50 | - **Complete:** Orders marked as complete have been invoiced and have shipped. 51 | - **Cancelled:** Cancelled orders should be used if orders are cancelled or if the orders have not been paid for. 52 | - **Closed:** Closed orders are orders that have had a credit memo assigned to it and the customer has been refunded for their order. 53 | - **On Hold:** Orders placed on hold must be taken off hold before continuing any further actions. 54 | 55 | ## List all the states in order 56 | 57 | 1. new 58 | 2. pending_payment 59 | 3. processing 60 | 4. complete 61 | 5. closed 62 | 6. canceled 63 | 7. holded 64 | 65 | 66 | ## How do you add your own state 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | This is a state description 76 | 77 | 78 | 79 | 80 | 1 81 | 82 | 83 | 84 | 85 | ## When would an order be closed 86 | 87 | When its refunded/credit memo. 88 | 89 | ## If an order is invoiced or shipped, what status would it be 90 | 91 | Processing. 92 | 93 | ## If an order is complete, can it be refunded (credit memo) 94 | 95 | No. If the order has been completed, it can't be refunded. 96 | Can also depend on payment method allowing refunds. 97 | 98 | # Card Authorization and Capture 99 | 100 | ## Which class is responsible for capturing funds 101 | 102 | The payment method which is called by the invoice class 103 | 104 | ## When are invoices created 105 | 106 | When an order is billed or in admin. 107 | 108 | ## What class is the payment class 109 | 110 | Mage_Sales_Model_Order_Payment 111 | 112 | ## Whats the difference between authorize and capture 113 | 114 | 1. Authorize - It checks the funds and informs the payment service to block those funds from being used. 115 | 2. Capture - This captures the funds. 116 | 117 | ## What are the different types of captures 118 | 119 | Online & Offline Capture. 120 | 121 | ## How would a custom payment gateway authorize and capture funds 122 | 123 | Using the methods authorize and capture providing their properties have been set to true. 124 | 125 | 126 | # 5. Credit Memos 127 | 128 | 129 | # What state is an order set to after being refunded 130 | 131 | Closed. 132 | 133 | # When can an order not be refunded? 134 | 135 | When the order is complete and the payment method does not allow refunds. 136 | 137 | # How does Magento process taxes when refunding an order? 138 | 139 | It basis it off admin tax origin. 140 | 141 | # How does Magento process shipping fees when refunding an order? 142 | 143 | Handled by the Credit Memo model when calculating different totals. 144 | 145 | # What is the difference between online and offline refunding? 146 | 147 | Offline refunds refund the order on Magento without actually taking care of the refund transaction. Whereas online does both. 148 | 149 | # What is the role of the credit memo total models in Magento? 150 | 151 | Credit memo totals keep a track on how much is refunded per total. 152 | 153 | # 6. Cancelled Orders 154 | 155 | ## When can an order be cancelled 156 | 157 | 1. Payment method allows for the order to be void e.g. the property *$_canVoid* 158 | 2. If all items have not been invoiced 159 | 3. If the order is not cancelled, complete or closed 160 | 4. Or if the order is not already flagged as cancelled 161 | 162 | # 7. Partial Order Operations 163 | 164 | ## What are the different types 165 | 166 | 1. Order 167 | 2. Invoice 168 | 3. Shipping 169 | 170 | ## How do they affect the state of an order 171 | 172 | They set the order state to processing. 173 | -------------------------------------------------------------------------------- /7. Catalog/4. Catalog Price Rules/1. Identify how catalog price rules are implemented in Magento.md: -------------------------------------------------------------------------------- 1 | # Identify how catalog price rules are implemented in Magento: 2 | 3 | # 1. Overview 4 | 5 | There are 2 types of price rules in Magento: 6 | 7 | - Catalog Price Rules 8 | - Shopping Cart Rules 9 | 10 | Product Price rules are applied to the product and while the shopping cart rule will be applied to the cart. 11 | Shopping Cart Rules will be covered in the next Chapter. 12 | 13 | 14 | # 2. Structure 15 | 16 | Catalog Price Rules can be broken into 3 parts and these are all stored in the **catalogrule** table. 17 | 18 | 19 | ## 2.1. Information 20 | 21 | - Name 22 | - Status 23 | - Websites - Multiselect of websites the rule applies to 24 | - Customer Groups - Multiselect of customer groups the rule applies to 25 | - From & To Date 26 | - Priority - The priority of when the rule is applied. Important if another catalog rule sets to stop processing rules. 27 | 28 | 29 | ## 2.2. Conditions 30 | 31 | Conditions are serialized and are used to determine whether a product is to apply the discount providing they have the valid credentials listed above. 32 | 33 | So a rule can have multiple conditions and also use the following to set the conditon. 34 | 35 | 1. Category 36 | 2. Attribute set 37 | 3. Attribute 38 | 39 | **Note:** An attribute must set "Use for Promo Rule Conditions" to "Yes". 40 | 41 | These can use the following filters to evaluate whether the discount can be applied: 42 | 43 | - is 44 | - is not 45 | - greater than 46 | - equals or greater than 47 | - equals or less than 48 | - greater than 49 | - less than 50 | - contains 51 | - does not contain 52 | - is one of 53 | - is not one of 54 | 55 | 56 | ## 2.3. Actions/Pricing 57 | 58 | The price is then determined by the following: 59 | 60 | **Apply** 61 | 62 | There are 4 types: 63 | 64 | 1. By Percentage of the Original Price 65 | 2. By Fixed Amount 66 | 3. To Percentage of the Original Price 67 | 4. To Fixed Amount 68 | 69 | **Discount Amount** 70 | 71 | The amount e.g. 50 would be either percentage or price. 72 | 73 | **Enable Discount to Subproducts** 74 | 75 | If applying to a grouped, configurable or bundle product. 76 | 77 | **Stop Further Rules Processing** 78 | 79 | If this is set to yes then it will stop anymore discounts being added. 80 | 81 | **Important:** If this is set to yes it does not stop shopping cart discounts being applied as they are stored in different tables. 82 | 83 | 84 | # 3. How it works 85 | 86 | ## 3.1. Table Structure 87 | 88 | So when rules are applied and saved they are stored in the following tables. 89 | **Note:** This does not use EAV. 90 | 91 | 1. **catalogrule** - Stores each rule 92 | 2. **catalogrule_customer_group** - Stores the rule id and customer group id 93 | 3. **catalogrule_group_website** - Stores the rule id and website id 94 | 4. **catalogrule_product** - Stores the product and type of discount when rules are applied. 95 | 4. **catalogrule_product_price** - Stores the actual discount for each product for each website. 96 | 97 | 98 | ## 3.2. How Discounts are applied 99 | 100 | So when "Apply Rules" is clicked or the product prices are reindexed the catalogrule_product and catalogrule_product_price tables are updated in **Mage_CatalogRule_Model_Rule->applyAll()** 101 | 102 | The observers for indexing are added in the config: 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | catalogrule/observer 111 | prepareCatalogProductPriceIndexTable 112 | 113 | 114 | 115 | 116 | 117 | 118 | catalogrule/observer 119 | catalogProductTypeConfigurablePrice 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | This in turn goes through each product and checks the conditions and saves the discounted price for each product and each websites in the **catalogrule_product_price** table. 128 | 129 | It then overrides the product and collection prices using 2 observers: 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | catalogrule/observer 138 | processFrontFinalPrice 139 | 140 | 141 | 142 | 143 | 144 | 145 | catalogrule/observer 146 | prepareCatalogProductCollectionPrices 147 | 148 | 149 | 150 | 151 | 152 | So in **Mage_CatalogRule_Model_Observer** is where also the discounts are checked and returned. 153 | 154 | # 3. Further Reading 155 | 156 | - [http://www.divisionlab.com/solvingmagento/magento-catalog-price-rules/](http://www.divisionlab.com/solvingmagento/magento-catalog-price-rules/) 157 | 158 | - [http://goweb.vn/kien-thuc-web-vi/thiet-ke-web/77identify-how-catalog-price-rules-are-implemented-in-magent...-966.html](http://goweb.vn/kien-thuc-web-vi/thiet-ke-web/77identify-how-catalog-price-rules-are-implemented-in-magent...-966.html) 159 | -------------------------------------------------------------------------------- /4. Databases/1. Models, Resource Models & Collections/6. Describe the role of Zend_Db_Select in Magento.md: -------------------------------------------------------------------------------- 1 | # Describe the role of Zend_Db_Select in Magento 2 | 3 | # 1. Integration with Magento 4 | 5 | When you getSelect() in a collection this uses this class. It used by Magento to make queries to the database. 6 | 7 | Magento Collections extend from *Mage_Core_Model_Resource_Db_Collection_Abstract* which extends from *Varien_Data_Collection_Db*. 8 | 9 | When $this->setConnection($conn) is called with the $conn as the adapter *Zend_Db_Adapter_Abstract* it sets the _select property as *Zend_Db_Adapter_Abstract->select()* which returns a new class of *Zend_Db_Select*. 10 | 11 | 12 | # 2. How to get Zend_Db_Select in Magento 13 | 14 | There are 2 ways: 15 | 16 | 1. Collection ->getSelect() 17 | 2. Get Connection Adapter ->select() 18 | 19 | See below for examples: 20 | 21 | 22 | # 3. Common Methods for Zend_Db_Select 23 | 24 | 25 | Below is a controller with some queries using the Varien_Db_Select. 26 | 27 | 28 | class Colin_Database_SelectController extends Mage_Core_Controller_Front_Action 29 | { 30 | 31 | public function fromAction() 32 | { 33 | /** @var Varien_Db_Select $select */ 34 | $resource = Mage::getSingleton('core/resource'); 35 | /** @var Magento_Db_Adapter_Pdo_Mysql $adapter */ 36 | $adapter = $resource->getConnection('core_read'); 37 | /** @var Varien_Db_Select $select */ 38 | $select = $adapter->select(); 39 | 40 | // $select->from(array('p', => 'catalog_product_entity') 41 | $select->from('catalog_product_entity') 42 | ->where('entity_id = 1') 43 | ->where('entity_type_id = 4'); 44 | var_dump($select->__toString()); 45 | //SELECT `catalog_product_entity`.* FROM `catalog_product_entity` WHERE (entity_id = 1) AND (entity_type_id = 4) 46 | } 47 | 48 | public function columnAction() 49 | { 50 | /** @var Varien_Db_Select $select */ 51 | $resource = Mage::getSingleton('core/resource'); 52 | /** @var Magento_Db_Adapter_Pdo_Mysql $adapter */ 53 | $adapter = $resource->getConnection('core_read'); 54 | /** @var Varien_Db_Select $select */ 55 | $select = $adapter->select(); 56 | $select->from( 57 | array('p' => 'catalog_product_entity'), 58 | array('entity_id') 59 | ) 60 | ->where('p.entity_id = 1'); 61 | var_dump($select->__toString()); 62 | //SELECT `p`.`entity_id` FROM `catalog_product_entity` AS `p` WHERE (p.entity_id = 1) 63 | } 64 | 65 | public function orAction() 66 | { 67 | /** @var Varien_Db_Select $select */ 68 | $resource = Mage::getSingleton('core/resource'); 69 | /** @var Magento_Db_Adapter_Pdo_Mysql $adapter */ 70 | $adapter = $resource->getConnection('core_read'); 71 | /** @var Varien_Db_Select $select */ 72 | $select = $adapter->select(); 73 | 74 | $select->from(array('f' => 'football_results')) 75 | ->where('home = 3') 76 | ->orWhere('home = 2'); 77 | var_dump($select->__toString()); 78 | // SELECT `f`.* FROM `football_results` AS `f` WHERE (home = 3) OR (home = 2) 79 | } 80 | 81 | 82 | public function whereAction() 83 | { 84 | /** @var Varien_Db_Select $select */ 85 | $select = Mage::getModel('colin_database/results')->getCollection()->getSelect(); 86 | /** @var Varien_Db_Statement_Pdo_Mysql $statement */ 87 | $statement = $select->where("home = '3'")->query(); 88 | var_dump($statement->fetchAll()); 89 | } 90 | 91 | public function groupAction() 92 | { 93 | /** @var Varien_Db_Select $select */ 94 | $select = Mage::getModel('catalog/product')->getCollection()->getSelect(); 95 | /** @var Varien_Db_Statement_Pdo_Mysql $statement */ 96 | $select->group("e.entity_id"); 97 | var_dump($select->__toString()); 98 | //SELECT `e`.* FROM `catalog_product_entity` AS `e` GROUP BY `entity_id` 99 | } 100 | 101 | public function joinAction() 102 | { 103 | $resource = Mage::getSingleton('core/resource'); 104 | /** @var Magento_Db_Adapter_Pdo_Mysql $adapter */ 105 | $adapter = $resource->getConnection('core_read'); 106 | /** @var Varien_Db_Select $select */ 107 | $select = $adapter->select(); 108 | 109 | $select->from(array('c' => 'catalog_product_entity')) 110 | ->join( 111 | array('t' => 'catalog_product_entity_text'), 112 | 'c.entity_id = t.entity_id' 113 | ) 114 | ->group(array('c.entity_id')); 115 | var_dump($select->__toString()); 116 | 117 | // SELECT `c`.*, `t`.* FROM `catalog_product_entity` AS `c` 118 | // INNER JOIN `catalog_product_entity_text` AS `t` 119 | // ON c.entity_id = t.entity_id 120 | // GROUP BY `c`.`entity_id` 121 | 122 | /** 123 | * Can also use 124 | * 125 | * joinLeft 126 | * joinRight 127 | * joinFull 128 | * joinCross 129 | * joinNatural 130 | * joinUsing 131 | */ 132 | } 133 | 134 | } 135 | 136 | # 4. Further Reading 137 | 138 | - [http://framework.zend.com/manual/1.12/en/zend.db.select.html](http://framework.zend.com/manual/1.12/en/zend.db.select.html) 139 | - [http://fishpig.co.uk/magento/tutorials/direct-sql-queries/](http://fishpig.co.uk/magento/tutorials/direct-sql-queries/) 140 | 141 | - [http://excellencemagentoblog.com/question/describe-the-role-of-zend_db_select-in-magento/](http://excellencemagentoblog.com/question/describe-the-role-of-zend_db_select-in-magento/) 142 | -------------------------------------------------------------------------------- /2. Request Flow/3. URL Rewrites/1. Describe URL structure:processing in Magento.md: -------------------------------------------------------------------------------- 1 | # Describe URL structure/processing in Magento 2 | 3 | 4 | 5 | # 1. Overview of table core_url_rewrite 6 | 7 | **1. url_rewrite_id** 8 | 9 | **2. store_id** 10 | 11 | **3. id_path** 12 | 13 | Unique id used. 14 | e.g. product/1 or category/1 or 55306700_1436466387 (custom redirect) 15 | 16 | **4. request_path** 17 | 18 | Path of current URL e.g. sample-product.html 19 | 20 | **5. target_path** 21 | 22 | Magento path of current URL 23 | e.g. catalog/product/view/id/1 or my-sample-product.html (custom redirect) 24 | 25 | **6. is_system** 26 | 27 | Is URL created automatically by Magento (used for re-indexing) 28 | 29 | **7. options** 30 | 31 | Custom redirects would be set as "RP" or "R" 32 | 33 | 34 | **8. description** 35 | 36 | **9. category_id** 37 | 38 | Category ID of the URL. 39 | 40 | **10. product_id** 41 | 42 | Product ID of the URL. 43 | 44 | # 2. URL types 45 | 46 | So there are 2 URL types 47 | 48 | - System 49 | - Custom 50 | 51 | **Note:** You can view these under Manage Catalog -> URL Rewrite Management. 52 | 53 | 54 | ## 2.1 System 55 | 56 | These are urls generated by Magento for products and categories when you save a product/category. 57 | These use the product/category suffix found under System -> Configuration -> Catalog -> Search Engine Optimisations. 58 | 59 | **Example:** 60 | 61 | - id_path = product/1 62 | - request_path = my-sample-product.html 63 | - target_path = catalog/product/view/id/1 64 | - is_system = 1 65 | - product_id = 1 66 | 67 | 68 | ## 2.2 Custom 69 | 70 | These are redirects either manually created in URL rewrite Management or if change the URL of the product/category and select create redirect option. 71 | 72 | - id_path = random_string 73 | - request_path = old-url.html 74 | - target_path = my-sample-product.html 75 | - is_system = 0 76 | - options = RP 77 | 78 | So you will notice there is "RP". This stands for permanent redirect. It can also be "R" for temporary redirect. 79 | 80 | 81 | # 3. How Rewrites/Request work 82 | 83 | So when the front controller is dispatched and before matching the router to a URL it will try and match the URL to category or product and set an alias for standard router to use and also see if the URL type is custom and then redirect the user before the method match is called. 84 | 85 | 86 | Mage_Core_Controller_Varien_Front->dispatch(); 87 | 88 | 89 | **Overview:** 90 | 91 | 1. Calls the rewrite method in Mage_Core_Model_Url_Rewrite_Request 92 | 2. Checks if there is any database rewrites 93 | 4. If the rewrite is a system rewrite (e.g. catalog/product/view/id/1) then it will set an alias in the Request class Zend_Controller_Request_Http 94 | 5. If its custom and is a redirect then it will redirect the user to the target_path 95 | 96 | 97 | ### 3.1. Rewrite Method 98 | 99 | When the Front Controller is being dispatched *Mage_Core_Controller_Varien_Front->dispatch();* it will call the following method before matching the URL with a router. 100 | 101 | $this->_getRequestRewriteController()->rewrite(); 102 | 103 | The rewrite method is called in *Mage_Core_Model_Url_Rewrite_Request*. 104 | 105 | This then calls the method rewriteDb(); 106 | 107 | 108 | ### 3.2 Get target paths 109 | 110 | The method rewriteDb will then do the following: 111 | 112 | 1. Gets request paths which returns an array of paths (/ and no / at the end of the URL) 113 | 2. Loads "request_path" in Mage_Core_Model_Resource_Url_Rewrite->getRequestPathByIdPath($idPath, $store); 114 | 115 | If there is no target_path and the URL is from switching store (__from_store) then Magento will try and load that store and set the target path. 116 | 117 | At this point if there is no target path it will return false and the Default Router will output a 404 page. 118 | 119 | ## 3.3 Set Alias for Request 120 | 121 | At this point the method then sets an Alias which is used by the Standard router to load the correct data. 122 | 123 | 124 | $this->_request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, 125 | $this->_rewrite->getRequestPath()); 126 | 127 | 128 | Request class is Zend_Controller_Request_Http. 129 | 130 | ## 3.4 Redirect 131 | 132 | So before the method then redirects any custom redirects before returning to the Request process. 133 | 134 | This is done in the _processRedirectOptions() method. 135 | 136 | So there are 2 redirect types: 137 | 138 | 1. RP - 301 redirect 139 | 2. R - 302 redirect 140 | 141 | So this method will call _sendRedirectHeaders method and set the redirect header. 142 | 143 | 144 | # 4. Category/Product URL Creation 145 | 146 | 147 | # 4.1 Creating URL's 148 | 149 | 150 | When you save a product for the first time and there is no value then the Request Path use the title and hyphenates it and lowercase it using this method 151 | 152 | Mage_Catalog_Model_Product_Url->formatKey($url); 153 | 154 | 155 | This is the same for the category 156 | 157 | Mage_Catalog_Model_Category_Url->formatKey($url); 158 | 159 | 160 | # 4.2. Configuration Options 161 | 162 | 163 | System -> Configuration -> Catalog -> Search Engine Optimisations 164 | 165 | 1. Product URL Suffix - the suffix for product URLs - default ".html" 166 | 2. Category URL Suffix - the suffix for category URLs - default ".html" 167 | 3. Use Categories Path for Product URLs - Whether to allow category URL's created for a product - default "yes" 168 | 4. Create Permanent Redirect for URLs if URL Key Changed - If Magento should create Permanent redirects when you change a URL 169 | 170 | 171 | System -> Configuration -> Web -> Search Engine Optimisations 172 | 173 | 1. Use Web Server Rewrites - Use mod_alias and remove index.php from URL's. - default = no. 174 | 175 | # 5. Further Reading 176 | 177 | - [http://blog.belvg.com/magento-certified-developer-exam-url-rewrites-part-i.html](http://blog.belvg.com/magento-certified-developer-exam-url-rewrites-part-i.html) 178 | - [http://www.solvingmagento.com/magento-url-rewrites/](http://www.solvingmagento.com/magento-url-rewrites/) 179 | - [http://alanstorm.com/magento_dispatch_rewrites_intro](http://alanstorm.com/magento_dispatch_rewrites_intro) 180 | -------------------------------------------------------------------------------- /3. Rendering/2. Blocks.md: -------------------------------------------------------------------------------- 1 | # Blocks 2 | 3 | ## What are blocks used for in Magento? 4 | To output data 5 | 6 | ## What is the parent block for all Magento blocks? 7 | 8 | Mage_Core_Block_Abstract 9 | 10 | ## Which class does each block that uses a template extend? 11 | 12 | Mage_Core_Block_Template 13 | 14 | 15 | ## In which way does a template block store information about its template file? Does it store an absolute or a relative path to the template? 16 | 17 | Absolute. 18 | 19 | ## What is the role of the Mage_Core_Block_Abstract class? 20 | 21 | - add helper methods 22 | - getChildHtml() to get Child block 23 | - toHtml() to generate output 24 | - \_beforeToHtml() method before its rendered 25 | - \_toHtml() method to allow blocks output HTML 26 | - Cache Blocks 27 | 28 | ## Can any block in Magento use a template file? 29 | Only those which extend from Mage_Core_Block_Template or Mage_Core_Block_Abstract 30 | 31 | ## How does the $this variable work inside the template file? 32 | It references the block class 33 | 34 | ## Is it possible to render a template without a block in Magento? 35 | No. 36 | 37 | ## Is it possible to have a block without a template in Magento? 38 | Yes in theory you could output HTML in \_toHtml() method. 39 | 40 | ## Which class is responsible for creating an instance of the block? 41 | 42 | Mage_Core_Model_Layout 43 | 44 | ## Which class is responsible for figuring out which blocks should be created for certain pages? 45 | 46 | Mage_Core_Model_Layout_Update 47 | 48 | Check out asSimpleXml() method and loadLayout() method in Mage_Core_Model_Layout 49 | 50 | 51 | ## How is the tree of blocks typically rendered? 52 | 53 | From the root downwards through the child HTML. 54 | 55 | ## Is it possible to create an instance of the block and render it on the page without using the Magento layout? 56 | 57 | Mage_Core_Model_Layout->createBlock() method e.g. $this->getLayout()->createBlock('core/template', 'my_block_name'); 58 | 59 | ## Is it possible to create an instance of the block and add it to the current layout manually? 60 | 61 | Yes. 62 | 63 | ## How are a block’s children rendered? Once you added a child to the block, can you expect it will be rendered automatically? 64 | 65 | No it needs to be called by $this->getChildHtml('name'); 66 | 67 | ## What is a difference in rendering process for different types of blocks? 68 | 69 | Mage_Core_Block_Text outputs the text set in the method setText. 70 | Mage_Core_Block_Template outputs the template set in construct or setTemplate method. 71 | Mage_Core_Block_Text_List outputs the child blocks. 72 | 73 | 74 | class Mage_Core_Block_Text_List extends Mage_Core_Block_Text 75 | { 76 | protected function \_toHtml() 77 | { 78 | $this->setText(''); 79 | foreach ($this->getSortedChildren() as $name) { 80 | $block = $this->getLayout()->getBlock($name); 81 | if (!$block) { 82 | Mage::throwException(Mage::helper('core')->\__('Invalid block: %s', $name)); 83 | } 84 | $this->addText($block->toHtml()); 85 | } 86 | return parent::\_toHtml(); 87 | } 88 | } 89 | 90 | 91 | ## How can block output be caught using an observer? 92 | 93 | Mage::dispatchEvent('core_block_abstract_to_html_after',array('block' => $this, 'transport' => self::$\_transportObject)); 94 | $html = self::$\_transportObject->getHtml(); 95 | 96 | 97 | ## What events do Mage_Core_Block_Abstract and Mage_Core_Block_Template fire? 98 | 99 | ### 1. Before/After Layout Object is set 100 | 101 | Mage::dispatchEvent('core_block_abstract_prepare_layout_before', array('block' => $this)); 102 | Mage::dispatchEvent('core_block_abstract_prepare_layout_after', array('block' => $this)); 103 | 104 | ### 2. Before Block is Rendered 105 | 106 | Mage::dispatchEvent('core_block_abstract_to_html_before', array('block' => $this)); 107 | 108 | ### 3. After Block is Rendered before returning HTML 109 | 110 | Mage::dispatchEvent('core_block_abstract_to_html_after', array('block' => $this, 'transport' => self::$\_transportObject)); 111 | 112 | **Note::** $\__transportObject is returned by calling is getHtml() method. 113 | 114 | 115 | ### What is the purpose of each of the following block types: 116 | 117 | - **Mage_Core_Block_Template** - To output a template. 118 | - **Mage_Core_Block_Text_List** - To output an array of child blocks 119 | - **Mage_Core_Block_Text** - To output text 120 | 121 | ### Which block type renders its children automatically? 122 | 123 | Mage_Core_Block_Text_List 124 | 125 | ### Which block type is usually used for a “content” block on Magento pages? 126 | 127 | Mage_Core_Block_Text_List 128 | 129 | ### How can a template’s block instance be accessed inside the template file, and how can other block instances be accessed? 130 | 131 | $this->getChildHtml(); 132 | 133 | ### How can block instances be accessed from the controller? 134 | 135 | $this->getLayout()->getBlock('name'); 136 | 137 | ### How can block instances be accessed inside install scripts or other model class instances? 138 | 139 | Mage::app()->getLayout()->getBlock('name'); 140 | 141 | 142 | ### In which ways can block output be disabled in Magento? 143 | 144 | 145 | 146 | or you could reference the parent block 147 | 148 | 149 | 150 | name 151 | 152 | 153 | 154 | 155 | ### Which method can be overridden to control block output? 156 | 157 | \_toHtml() 158 | \_afterToHtml() 159 | 160 | ### In which method are templates rendered? 161 | 162 | Mage_Core_Block_Abstract->toHtml(); 163 | 164 | # Which classes are responsible for figuring out the absolute path for including the template file? 165 | 166 | Mage_Core_Block_Template->getTemplateFile(); 167 | 168 | 169 | ### Which class performs rendering of the template? 170 | 171 | Mage_Core_Block_Template->fetchView(); 172 | 173 | ### How can output buffering be enabled/disabled when templates are rendered? 174 | 175 | Mage_Core_Model_Layout::setDirectOuput(true) 176 | -------------------------------------------------------------------------------- /1. Basics/2. Configuration/1.Explain how Magento loads and manipulates configuration information.md: -------------------------------------------------------------------------------- 1 | # Explain how Magento loads and manipulates configuration information 2 | 3 | 4 | ## Overview 5 | 6 | When loading a class in Magento this can sometimes be referred to *name class resolution*. 7 | 8 | So we are going to use an example to explain how the class name is resolved in Magento. 9 | 10 | 11 | $order = Mage::getModel('sales/order'); 12 | 13 | 14 | 15 | ## 1. getModel() 16 | 17 | This return the method Mage_Core_Model_Config::getModelInstance() 18 | 19 | 20 | ## 2. getModelInstance($modelClass, array $arguments) 21 | 22 | This gets the class name from the method *getModelClassName* and passes in the arguments when creating the object class. 23 | 24 | 25 | 26 | ## 3. getModelClassName($modelClass) 27 | 28 | This does 2 things: 29 | 30 | - validates the class name 31 | - Gets the class name 32 | 33 | ### 3.1 Validate 34 | 35 | The first thing it does is checks if a forward slash exists in the class name. 36 | 37 | 38 | $modelClass = trim($modelClass); 39 | if (strpos($modelClass, '/')===false) { 40 | return $modelClass; 41 | } 42 | 43 | 44 | ### 3.2 Gets the class name 45 | 46 | It then gets the class name from the method *getGroupedClassName* 47 | 48 | $this->getGroupedClassName('model', $modelClass); 49 | 50 | 51 | ## 4. getGroupedClassName($groupType, $classId, $groupRootNode=null) 52 | 53 | This is main method which figures out the classname from the layout XML also known as *class name resolution*. 54 | 55 | ### 4.1 Parameters 56 | 57 | - **$groupType** is the type e.g. model, block, helper 58 | - **$classId** is the class name e.g. "sales/order" 59 | - **$groupRootNode** is the XML node to search in. By default it will search in global 60 | 61 | 62 | 63 | ### 4.2 config.xml 64 | 65 | Before we go through this method the sales order class config xml looks something like this 66 | 67 | 68 | 69 | 70 | Mage_Sales_Model 71 | 72 | 73 | 74 | 75 | Please take a mental note of the node *sales* and the class *Mage_Sales_Model* 76 | 77 | 78 | ### 4.3 GroupRootNode 79 | 80 | Firstly if there is no GroupRootNode set, we combine "global/" and the groupType e.g. "global/models" or "global/blocks" 81 | 82 | if (empty($groupRootNode)) { 83 | $groupRootNode = 'global/'.$groupType.'s'; 84 | } 85 | 86 | In our example this would be *global/models"*. 87 | 88 | This is the XML node used to resolve the class name. 89 | 90 | 91 | ### 4.4 Group Name 92 | 93 | The next thing it does is figure out the group name. This is the name before the forward slash in your class name. So in our example it would be "sales". 94 | 95 | It explodes the string by "/" and then also assigns the second part of the string to a variable called *$class*. 96 | 97 | 98 | ### 4.5 Checks the cache 99 | 100 | It then checks to see has the class name already being resolved in the cache and if so returns that class name so it does not need to repeat itself. 101 | 102 | if (isset($this->_classNameCache[$groupRootNode][$group][$class])) { 103 | return $this->_classNameCache[$groupRootNode][$group][$class]; 104 | } 105 | 106 | 107 | ### 4.6 Get Config XML 108 | 109 | It then gets the XML for group *(global -> models -> sales)*. 110 | 111 | 112 | $config = $this->_xml->global->{$groupType.'s'}->{$group}; 113 | 114 | 115 | **Note:** Class name for $config is *Mage_Core_Model_Config_Element*. 116 | 117 | 118 | ### 4.7 Check for Rewrite 119 | 120 | It then checks to see if there is a rewrite node exists and if does sets this as the classname. 121 | 122 | 123 | So for example if you rewriting the sales model (first task in Meeting 2 of the Group Guide). Your XML would like the following: 124 | 125 | 126 | 127 | 128 | 129 | 130 | Colin_Two_Model_Rewrite_Sales_Order 131 | 132 | 133 | 134 | 135 | 136 | 137 | The code for getting the rewrite class is the following 138 | 139 | if (isset($config->rewrite->$class)) { 140 | $className = (string)$config->rewrite->$class; 141 | } 142 | 143 | So in the rewrite exercise the $config would be *global -> models -> sales* and the $class would be *order*. 144 | 145 | 146 | ### 4.8 Get the class name 147 | 148 | Finally if there is no rewrite, Magento will do the following: 149 | 150 | #### 4.8.1. Get the classname from the *class* node. 151 | 152 | So in our example, the classname would be Mage_Sales_Model as its set in the ** node. 153 | This gets the class in *Mage_Core_Model_Config_Element->getClassName()*. 154 | 155 | 156 | #### 4.8.2. Use default classname if node does not exists 157 | 158 | So if the node did not exist it creates the classname from the following: 159 | 160 | $className = 'mage_'.$group.'_'.$groupType; 161 | 162 | So if you were calling it from a package outside Mage e.g. Colin_Two then the class name would be *Mage_Two_Model*. 163 | 164 | 165 | #### 4.8.3. Append _$class to the classname. 166 | 167 | Finally it appends the _$class so our classname now would *Mage_Sales_Model_Order* 168 | 169 | **Note:** It should be noted that the function *ucwords* is ran on the class name so if you called Mage::getModel('sales/test_class') the variable $class would Test_Class. 170 | 171 | 172 | ### 4.9 Cache the class name 173 | 174 | This then caches the name as follows and returns the class name. 175 | 176 | $this->_classNameCache[$groupRootNode][$group][$class] = $className 177 | 178 | 179 | # Conclusion 180 | 181 | To run over this briefly again the following happens when Magento is loading a class. 182 | 183 | - Checks if the class name is separated by a forward slash. 184 | - Splits the string into group and class e.g. sales/order, sales is group and class is order. 185 | - Checks to see if the class name is already cached. If so return the class name. 186 | - Checks for a rewrite. 187 | - Otherwise gets the class node (Mage_Sales_Model) and combines it with the class (Mage_Sales_Model_Order). 188 | - Caches the classname and returns the class, 189 | - The autoloader then loads the file and class. 190 | -------------------------------------------------------------------------------- /5. EAV/2. EAV Attributes/2. Describe how to implement the interface of attribute frontend, source, and backend models.md: -------------------------------------------------------------------------------- 1 | # Describe how to implement the interface of attribute frontend, source, and backend models 2 | 3 | 4 | # 1. Frontend 5 | 6 | So lets say for the content attribute we want to add a method called $this->getExcerpt() which got 150 characters we would do the following 7 | 8 | 9 | # 1.1. Update Attribute in Upgrade Script 10 | 11 | 12 | $this->startSetup(); 13 | $helper = Mage::helper("core"); 14 | // Entity Type Code, Attribute Code, Attribute, Value 15 | $this->updateAttribute("colin_eav_blog", "content", "frontend_model", "colin_eav/attribute_frontend_content"); 16 | $this->endSetup(); 17 | 18 | 19 | # 1.2. Frontend Class 20 | 21 | The frontend class must extend from **Mage_Eav_Model_Entity_Attribute_Frontend_Abstract** 22 | 23 | class Colin_EAV_Model_Attribute_Frontend_Content extends Mage_Eav_Model_Entity_Attribute_Frontend_Abstract 24 | { 25 | 26 | public function getExcerpt(Varien_Object $object, $length = 150) 27 | { 28 | return substr($this->getValue($object), 0, (int)$length); 29 | } 30 | 31 | } 32 | 33 | 34 | # 1.3. Get Frontend Model 35 | 36 | 37 | $blog = Mage::getModel("colin_eav/blog")->load(1); 38 | echo Mage::getSingleton('eav/config') 39 | ->getAttribute("colin_eav_blog", 'content') 40 | ->getFrontend() 41 | ->getExcerpt($blog, 10); 42 | 43 | 44 | # 2. Source Model 45 | 46 | These need a method of *toOptionArray()* which return key value. 47 | 48 | public function getOptionArray() 49 | { 50 | return array( 51 | self::STATUS_ENABLED => Mage::helper('catalog')->__('Enabled'), 52 | self::STATUS_DISABLED => Mage::helper('catalog')->__('Disabled') 53 | ); 54 | } 55 | 56 | # 3. Backend Model 57 | 58 | Backend Models extend from *Mage_Eav_Model_Entity_Attribute_Backend_Abstract* class. 59 | 60 | **Information taken from http://www.divisionlab.com/solvingmagento/magento-eav-system/** 61 | 62 | 63 | ### getTable() 64 | Returns the table name (or, more precisely, configuration node pointing to the table name), which stores the attributes data. Think of “skinny” attribute-value tables, for example, customer_entity_varchar, or catalog_product_entity_decimal. 65 | 66 | 67 | ### isStatic() 68 | 69 | Tells if the attribute is static. Static is the default value for attribute field backend_type. Static attribute values are stored in the main entity table (i.e., catalog_product_entity or customer_entity) and not in the “skinny” EAV attribute-value tables. 70 | 71 | 72 | ### getType() 73 | Returns the attribute backend type. They can be varchar, static, int, text, decimal, or datetime. The type defines, in which “skinny” table the EAV entity saves the value of its attributes. The columns of a “skinny” table are: entity_id (references the entity), entity_type_id (references to the ID of the entity’s type: customer, catalog_product etc), attribute_id (pointing to the attribute whose value it is), value (in format corresponding to the attribute’s type: int, decimal, datetime etc). In a case of a multi-store environment where entities can have different values for the same attribute, the store_id column can be used. 74 | 75 | ### getEntityIdField() 76 | Returns the name of a column in EAV attribute tables, where entity_ids are stored. Default name for such column is entity_id; but custom naming is possible – and that is why this function exists. 77 | 78 | ### setValueId($valueId) 79 | Sets the ID of a row containing the entity attribute data. 80 | 81 | ### getValueId() 82 | Returns the ID of a row containing the entity attribute data. 83 | 84 | ### getEntityValueId($entity) 85 | 86 | Entity values can be stored in an attribute backend data model instance. They are packed into a protected field as an array, where keys are entity_ids, and values are the IDs of the rows in the skinny table. This function retrieves the data row ID for the given entity. 87 | 88 | ### setEntityValueId($entity, $valueId) 89 | 90 | Sets the ID of a row containing the attribute data for the given entity. 91 | The following functions implement custom data manipulation for attribute values of the $object variable. The latter can be a customer, customer address, product, or category object 92 | 93 | 94 | ### Load/Save Methods 95 | 96 | 1. afterLoad($object) – processes object attribute data after the object is loaded. 97 | 2. beforeSave($object) – prepares attribute data before saving the object into the database. 98 | 3. afterSave($object) – processes attribute data after the object is saved. 99 | 4. beforeDelete($object) – performs operations on attribute data before the object is deleted. 100 | 5. afterDelete($object) – processes attribute data (deletes it, in most imaginable cases) after the parent object is deleted. 101 | 102 | 103 | # 4. Questions 104 | 105 | ## Which methods have to be implemented in a custom source model (or frontend model or backend model)? 106 | 107 | 1. toOptionArray for Admin 108 | 2. getAllOptions for Frontend 109 | 110 | ## Can adminhtml system configuration source models also be used for EAV attributes? 111 | 112 | See above. 113 | 114 | ## What is the default frontend model (and source and backend model) for EAV attributes? 115 | 116 | Mage_Eav_Model_Entity_Attribute_Frontend_Default 117 | 118 | ## Does every attribute use a source model? 119 | No. 120 | 121 | ## Which classes and methods are related to updating the EAV attribute values in the flat catalog tables? 122 | 123 | Mage::getResourceModel('eav/entity_setup)->updateAttribute() 124 | Mage::getResourceModel('eav/entity_setup)->addAttribute() 125 | 126 | ## What factors allow for attributes to be added to flat catalog tables? 127 | 128 | Source Model 129 | 130 | ## How are store-scoped entity attribute values stored when catalog flat storage is enabled for that entity type? 131 | 132 | catalog_category_flat_store_id 133 | 134 | ## Which frontend, source, and backend models are available in a stock Magento installation? 135 | 136 | ## How do multi-lingual options for attributes work in Magento? 137 | 138 | store_id 139 | 140 | ## How do you get a list of all options for an attribute for a specified store view in addition to the admin scope? 141 | 142 | Mage::getModel('eav/entity_attribute')->load({id})->getSource()->getAllOptions() 143 | -------------------------------------------------------------------------------- /2. Request Flow/1. Application Initialization/1. Describe the steps for application initialization.md: -------------------------------------------------------------------------------- 1 | # Describe the steps for application initialization 2 | 3 | # Overview 4 | 5 | 1. index.php 6 | 2. Mage::run($mageRunCode, $mageRunType); 7 | 3. Mage_Core_Model_App->run(array $options); 8 | 4. Mage_Core_Model_App->baseInit() 9 | 5. Mage_Core_Model_Config->loadBase() 10 | 6. Mage_Core_Model_App->\_initModules(); 11 | 7. Mage_Core_Model_App->\_initCurrentStore($scopeCode, $scopeType); 12 | 8. Dispatches the Front Controller - more information [here](https://github.com/colinmurphy/magento-exam-notes/blob/master/2.%20Request%20Flow/2.%20Front%20Controller/2.%20Describe%20the%20role%20of%20the%20front%20controller.md) 13 | 14 | For a detailed explanation read [http://blog.belvg.com/magento-certified-developer-exam-application-initialization.html](http://blog.belvg.com/magento-certified-developer-exam-application-initialization.html). 15 | 16 | 17 | # 0. Request Flow Image 18 | 19 | Belvg have created an excellent image which covers the whole chapter - [http://blog.belvg.com/wp-content/files/magento_request_flow.jpg](http://blog.belvg.com/wp-content/files/magento_request_flow.jpg) 20 | 21 | 22 | 23 | # 1. index.php 24 | 25 | 26 | 1. Checks PHP Requirements 27 | 2. Checks for Compiler and includes compiler classes 28 | 3. Checks for downloader and if so exits 29 | 4. Checks for maintenance.flag and if exists exits 30 | 5. Includes Mage.php file 31 | 6. Checks for server run_code and run_type 32 | 7. Runs Mage Mage::run($mageRunCode, $mageRunType); 33 | 34 | 35 | ### 1.1. Notes on MAGE_RUN_CODE and MAGE_RUN_TYPE 36 | 37 | **MAGE_RUN_TYPE** 38 | 39 | By default this is "store" if there is no server MAGE_RUN_TYPE set 40 | 41 | - store (store view) 42 | - website (website) 43 | - group (store) 44 | 45 | 46 | **MAGE_RUN_CODE** 47 | 48 | This is the code e.g. base or german and the value is associated to which store/group/website you need to load. 49 | 50 | **Examples:** 51 | 52 | 1. German website 53 | 54 | SetEnv MAGE_RUN_TYPE "website" 55 | SetEnv MAGE_RUN_CODE "german" 56 | 57 | 58 | 2. German Store View/Store 59 | 60 | SetEnv MAGE_RUN_CODE "german" 61 | 62 | 63 | **Note:** These are used further along in the initialization process at *Mage_Core_Model_App->\_initCurrentStore($scopeCode, $scopeType)* 64 | 65 | 66 | # 2. Mage::run($code, $store); 67 | 68 | **Note:** Before we begin looking at this, please note that at the top of the file the autoloader and include paths have been [set](https://github.com/colinmurphy/magento-exam-notes/blob/master/1.%20Basics/1.%20Architecture/6.%20Explain%20class%20naming%20conventions%20and%20their%20relationship%20with%20the%20autoloader.md). 69 | 70 | Overview 71 | 72 | 1. Checks for options (3rd parameter) 73 | 2. Calls app class Mage_Core_Model_App 74 | 3. Sets the application as installed 75 | 4. Sets the config model Mage_Core_Model_Config with the array of options 76 | 5. Calls apps run - Mage_Core_Model_App->run(array $options); 77 | 78 | 79 | ### 2.1 Notes 80 | 81 | Please note that if an option exists config_model then that Config model will be used instead. 82 | I am not sure why you would want to do this. 83 | 84 | 85 | # 3. Mage_Core_Model_App->run(array $options); 86 | 87 | 1. Loads local.xml and config.xml in baseInit() 88 | 2. Checks is request is cached and sets response 89 | 3. Otherwise it loads the modules in \_initModules(); and also runs resource update/install scripts 90 | 4. Loads Area (frontend/admin/install) 91 | 5. Sets the current store from parameters 92 | 6. Runs Data script update (different to resource update scripts) 93 | 7. Calls the front controller 94 | 95 | # 4. Mage_Core_Model_App->baseInit($options) 96 | 97 | 1. Sets the error handler 98 | 2. Initiates the config 99 | 3. Sets the options in the config class 100 | 4. Loads the config.xml and local.xml into Config Class - Mage_Core_Model_Config->loadBase() 101 | 5. Initiates caching 102 | 103 | # 5. Mage_Core_Model_Config->loadBase() 104 | 105 | This merges the XML from under app/etc into the config class. 106 | So basically config.xml and local.xml would be merged in the config class. 107 | 108 | So it does the following: 109 | 110 | - Loads the XML files under app/etc e.g. config.xml and local.xml using *glob* 111 | - Loops through these files 112 | - Clones Mage_Core_Model_Config_Base 113 | - Adds xml from the file to this class 114 | - Merges Mage_Core_Model_Config_Base into Mage_Core_Model_Config 115 | 116 | # 6. Mage_Core_Model_App->\_initModules(); 117 | 118 | So in Mage_Core_Model_App->run() we check if the request is cached and return the cache if it exists. 119 | 120 | Other we call this method and this does the following if the modules are not already cached: 121 | 122 | - Load Modules 123 | - Merges config data from Database 124 | - Runs Resource Install/Update scripts 125 | - Processes and configuration values in the config.xml 126 | - Saves Cache 127 | 128 | ### 6.1 Loading modules 129 | 130 | Mage_Core_Model_Config->loadModules(); 131 | 132 | - Loads modules under app/etc/modules using glob 133 | - Loads modules it depends on 134 | - Merges config.xml into config node of class Mage_Core_Model_Config 135 | - **Important:** Merges back in local.xml file afterwards to prevent overrides 136 | 137 | Then it runs setup updates by checking version numbers of the modules against the database table core_resource. 138 | 139 | ### 6.2 Merges Config data from database 140 | 141 | Mage_Core_Model_App::loadDb() 142 | 143 | ### 6.3 Runs Resource Install/Update scripts 144 | 145 | 146 | Mage_Core_Model_Resource_Setup::applyAllUpdates(); 147 | 148 | 149 | Its important to note the name of the class and method for the exam and that this runs before the data scripts. 150 | Data updates are called in the applyAllDataUpdates() method of the class. 151 | 152 | 153 | # 7. Mage_Core_Model_App->\_initCurrentStore($scopeCode, $scopeType); 154 | 155 | As mentioned earlier these parameters are set at the end of the index.php and are passed through to Mage::run(); 156 | 157 | 158 | # 8. Important Notes 159 | 160 | **Merging Config.xml** 161 | 162 | Magento loads config.xml and local.xml and adds them to the config class. 163 | It loads the modules config.xml and merges them into the config class. 164 | It then loads the local.xml file and re-merges it into the config class to prevent overrides by modules.\ 165 | 166 | **Scripts:** 167 | Resource Scripts are called before Data Scripts and also when the config merges the database config. 168 | --------------------------------------------------------------------------------