Setting up Magento 2.2.3 on Valet+ (requires MacOS)
Wondering what is Valet+? It is a development environment for MacOS. If you have previously used Vagrant and/or Docker, I think you would just love Valet+. Valet+ is very easy yet fast development environment, as it doesn’t require you to edit /etc/hosts, vhosts, mysql, etc.. For more information on Valet+ and how it differs with Valet, please read this: https://github.com/weprovide/valet-plus/blob/master/readme.md
Let me know in comments section which one you prefer out of these 3?
Okay so let’s come to topic and start preparing to install Valet and Magento.
1.) Install Homebrew if you do not have it already on your Mac
2.) Let’s install PHP 7.1
brew install homebrew/php/php71
If you already have php70, you can unlink it before running above command:
brew unlink php70
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | Kalpeshs-MBP:~ kalpesh$ brew install php71 Updating Homebrew... ==> Installing php71 from homebrew/php ==> Installing dependencies for homebrew/php/php71: libpng, freetype, gettext, icu4c, jpeg, libtool, unixodbc, readline ==> Installing homebrew/php/php71 dependency: libpng ==> Downloading https://downloads.sourceforge.net/libpng/libpng-1.6.34.tar.xz ==> Downloading from https://downloads.sourceforge.net/project/libpng/libpng16/1.6.34/libpng-1.6.34.tar.xz ######################################################################## 100.0% ==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/libpng/1.6.34 ==> make ==> make test ==> make install 🍺 /usr/local/Cellar/libpng/1.6.34: 26 files, 1.2MB, built in 2 minutes 22 seconds ==> Installing homebrew/php/php71 dependency: freetype ==> Downloading https://downloads.sourceforge.net/project/freetype/freetype2/2.9/freetype-2.9.tar.bz2 ==> Downloading from https://svwh.dl.sourceforge.net/project/freetype/freetype2/2.9/freetype-2.9.tar.bz2 ######################################################################## 100.0% ==> ./configure --prefix=/usr/local/Cellar/freetype/2.9 --without-harfbuzz ==> make ==> make install 🍺 /usr/local/Cellar/freetype/2.9: 60 files, 2.7MB, built in 1 minute 53 seconds ==> Installing homebrew/php/php71 dependency: gettext ==> Downloading https://homebrew.bintray.com/bottles/gettext-0.19.8.1.yosemite.bottle.tar.gz ######################################################################## 100.0% ==> Pouring gettext-0.19.8.1.yosemite.bottle.tar.gz ==> Caveats This formula is keg-only, which means it was not symlinked into /usr/local, because macOS provides the BSD gettext library & some software gets confused if both are in the library path. If you need to have this software first in your PATH run: echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> ~/.bash_profile For compilers to find this software you may need to set: LDFLAGS: -L/usr/local/opt/gettext/lib CPPFLAGS: -I/usr/local/opt/gettext/include ==> Summary 🍺 /usr/local/Cellar/gettext/0.19.8.1: 1,934 files, 17.0MB ==> Installing homebrew/php/php71 dependency: icu4c ==> Downloading https://ssl.icu-project.org/files/icu4c/60.2/icu4c-60_2-src.tgz ######################################################################## 100.0% ==> ./configure --prefix=/usr/local/Cellar/icu4c/60.2 --disable-samples --disable-tests --enable-static --with-library-bits=64 ==> make ==> make install ==> Caveats This formula is keg-only, which means it was not symlinked into /usr/local, because macOS provides libicucore.dylib (but nothing else). If you need to have this software first in your PATH run: echo 'export PATH="/usr/local/opt/icu4c/bin:$PATH"' >> ~/.bash_profile echo 'export PATH="/usr/local/opt/icu4c/sbin:$PATH"' >> ~/.bash_profile For compilers to find this software you may need to set: LDFLAGS: -L/usr/local/opt/icu4c/lib CPPFLAGS: -I/usr/local/opt/icu4c/include For pkg-config to find this software you may need to set: PKG_CONFIG_PATH: /usr/local/opt/icu4c/lib/pkgconfig ==> Summary 🍺 /usr/local/Cellar/icu4c/60.2: 249 files, 67.2MB, built in 9 minutes 15 seconds ==> Installing homebrew/php/php71 dependency: jpeg ==> Downloading http://www.ijg.org/files/jpegsrc.v9c.tar.gz ######################################################################## 100.0% ==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/jpeg/9c ==> make install 🍺 /usr/local/Cellar/jpeg/9c: 21 files, 736.3KB, built in 1 minute 30 seconds ==> Installing homebrew/php/php71 dependency: libtool ==> Downloading https://homebrew.bintray.com/bottles/libtool-2.4.6_1.yosemite.bottle.tar.gz ######################################################################## 100.0% ==> Pouring libtool-2.4.6_1.yosemite.bottle.tar.gz ==> Caveats In order to prevent conflicts with Apple's own libtool we have prepended a "g" so, you have instead: glibtool and glibtoolize. ==> Summary 🍺 /usr/local/Cellar/libtool/2.4.6_1: 70 files, 3.7MB ==> Installing homebrew/php/php71 dependency: unixodbc ==> Downloading http://www.unixodbc.org/unixODBC-2.3.5.tar.gz ######################################################################## 100.0% ==> ./configure --prefix=/usr/local/Cellar/unixodbc/2.3.5_1 --sysconfdir=/usr/local/etc --enable-static --enable-gui=no ==> make install 🍺 /usr/local/Cellar/unixodbc/2.3.5_1: 41 files, 1.9MB, built in 4 minutes 22 seconds ==> Installing homebrew/php/php71 dependency: readline ==> Downloading https://homebrew.bintray.com/bottles/readline-7.0.3_1.yosemite.bottle.tar.gz ######################################################################## 100.0% ==> Pouring readline-7.0.3_1.yosemite.bottle.tar.gz ==> Caveats This formula is keg-only, which means it was not symlinked into /usr/local, because macOS provides the BSD libedit library, which shadows libreadline. In order to prevent conflicts when programs look for libreadline we are defaulting this GNU Readline installation to keg-only.. For compilers to find this software you may need to set: LDFLAGS: -L/usr/local/opt/readline/lib CPPFLAGS: -I/usr/local/opt/readline/include ==> Summary 🍺 /usr/local/Cellar/readline/7.0.3_1: 46 files, 1.5MB ==> Installing homebrew/php/php71 ==> Downloading https://php.net/get/php-7.1.14.tar.bz2/from/this/mirror ==> Downloading from https://secure.php.net/get/php-7.1.14.tar.bz2/from/this/mirror ######################################################################## 100.0% ==> ./configure --prefix=/usr/local/Cellar/php71/7.1.14_25 --localstatedir=/usr/local/var --sysconfdir=/usr/local/etc/php/7.1 --with-config-file-path=/usr/local/etc/php/7 ==> make ==> make install ==> Caveats The php.ini file can be found in: /usr/local/etc/php/7.1/php.ini ✩✩✩✩ Extensions ✩✩✩✩ If you are having issues with custom extension compiling, ensure that you are using the brew version, by placing /usr/local/bin before /usr/sbin in your PATH: PATH="/usr/local/bin:$PATH" PHP71 Extensions will always be compiled against this PHP. Please install them using --without-homebrew-php to enable compiling against system PHP. ✩✩✩✩ PHP CLI ✩✩✩✩ If you wish to swap the PHP you use on the command line, you should add the following to ~/.bashrc, ~/.zshrc, ~/.profile or your shell's equivalent configuration file: export PATH="$(brew --prefix homebrew/php/php71)/bin:$PATH" ✩✩✩✩ FPM ✩✩✩✩ To launch php-fpm on startup: mkdir -p ~/Library/LaunchAgents cp /usr/local/opt/php71/homebrew.mxcl.php71.plist ~/Library/LaunchAgents/ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.php71.plist The control script is located at /usr/local/opt/php71/sbin/php71-fpm OS X 10.8 and newer come with php-fpm pre-installed, to ensure you are using the brew version you need to make sure /usr/local/sbin is before /usr/sbin in your PATH: PATH="/usr/local/sbin:$PATH" You may also need to edit the plist to use the correct "UserName". Please note that the plist was called 'homebrew-php.josegonzalez.php71.plist' in old versions of this formula. With the release of macOS Sierra the Apache module is now not built by default. If you want to build it on your system you have to install php with the --with-httpd option. See brew options php71 for more details. By 31st March 2018 we will deprecate and archive the PHP tap. Some of the formulae will be migrated to homebrew-core. For more details, see https://github.com/Homebrew/homebrew-php/issues/4721 To have launchd start homebrew/php/php71 now and restart at login: brew services start homebrew/php/php71 ==> Summary 🍺 /usr/local/Cellar/php71/7.1.14_25: 345 files, 39.9MB, built in 11 minutes 5 seconds |
3.) Install Composer
brew install homebrew/php/composer
4.) Finally install Valet+
composer global require weprovide/valet-plus
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Kalpeshs-MBP:valet kalpesh$ composer global require weprovide/valet-plus Changed current directory to /Users/kalpesh/.composer Using version ^1.0 for weprovide/valet-plus ./composer.json has been created Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 15 installs, 0 updates, 0 removals - Installing tightenco/collect (v5.4.33): Downloading (100%) - Installing symfony/process (v3.4.6): Downloading (100%) - Installing nategood/httpful (0.2.20): Downloading (100%) - Installing psr/container (1.0.0): Downloading (100%) - Installing container-interop/container-interop (1.2.0): Downloading (100%) - Installing php-di/invoker (1.3.3): Downloading (100%) - Installing psr/log (1.0.2): Downloading (100%) - Installing symfony/debug (v4.0.6): Downloading (100%) - Installing symfony/polyfill-mbstring (v1.7.0): Downloading (100%) - Installing symfony/console (v3.4.6): Downloading (100%) - Installing mnapoli/silly (1.5.1): Downloading (100%) - Installing psr/simple-cache (1.0.1): Downloading (100%) - Installing illuminate/contracts (v5.6.12): Downloading (100%) - Installing illuminate/container (v5.6.12): Downloading (100%) - Installing weprovide/valet-plus (1.0.11): Downloading (100%) symfony/console suggests installing symfony/event-dispatcher () symfony/console suggests installing symfony/lock () Writing lock file Generating autoload files |
5.) Add export PATH in your .bash_profile
vi ~/.bash_profile
and add below line on top (after PATH line if you have one already)
export PATH=”$PATH:$HOME/.composer/vendor/bin”
to reflect our current changes in the current terminal tab session, run:
Magento 2 upgrade from 2.0.* to latest version using composer via CLI
In this post I will show you how to upgrade Magento 2.0.5 (2.0.*) to 2.1.6 which is latest CE version as of today. We will do it using composer via server command-line interface. It is recommended to take code and DB backup and do this upgrade on your development/stage server first.
Magento 2 comes with Web Setup Wizard (under Admin > System) where you can upgrade from admin panel itself, but for some reason it was always failing for me at Readiness Check’s Component Dependency check.
Step 1.) Edit the composer.json which should be located at the root of your store. Change version and magento/product-community-edition from 2.0.* (whatever you have currently) to 2.1.6 or any latest version you wish to upgrade to. Also change sample data versions from 100.0.* to 100.1.*
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | { "name": "magento/project-community-edition", "description": "eCommerce Platform for Growth (Community Edition)", "type": "project", "version": "2.1.6", "require": { "magento/product-community-edition": "2.1.6", "composer/composer": "@alpha", "magento/module-bundle-sample-data": "100.1.*", "magento/module-theme-sample-data": "100.1.*", "magento/module-widget-sample-data": "100.1.*", "magento/module-catalog-sample-data": "100.1.*", "magento/module-customer-sample-data": "100.1.*", "magento/module-cms-sample-data": "100.1.*", "magento/module-tax-sample-data": "100.1.*", "magento/module-review-sample-data": "100.1.*", "magento/module-catalog-rule-sample-data": "100.1.*", "magento/module-sales-rule-sample-data": "100.1.*", "magento/module-sales-sample-data": "100.1.*", "magento/module-grouped-product-sample-data": "100.1.*", "magento/module-downloadable-sample-data": "100.1.*", "magento/module-msrp-sample-data": "100.1.*", "magento/module-configurable-sample-data": "100.1.*", "magento/module-product-links-sample-data": "100.1.*", "magento/module-wishlist-sample-data": "100.1.*", "magento/module-swatches-sample-data": "100.1.*", "magento/sample-data-media": "100.1.*", "magento/module-offline-shipping-sample-data": "100.1.*" },... |
Step 2.) composer update (Run this command on the server/terminal. You may need to create GitHub OAuth token to pass the rate limit. Login to your Github account (or create one) and head to Developer Settings > Personal access tokens and generate new token with full control of private repositories.)
Continue reading »
Magento 2 events observer list
Below is a list of all the events dispatched that you can observe in your Magento 2 web store.
Magento 2 Events Observer list:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | 'adminhtml_cache_flush_all' 'adminhtml_cache_flush_system' 'backend_auth_user_login_success', ['user' => $this->getCredentialStorage()] 'backend_auth_user_login_failed', ['user_name' => $username, 'exception' => $e] 'backend_auth_user_login_failed', ['user_name' => $username, 'exception' => $e] 'adminhtml_store_edit_form_prepare_form', ['block' => $this] 'adminhtml_block_html_before', ['block' => $this] 'backend_block_widget_grid_prepare_grid_before', ['grid' => $this, 'collection' => $this->getCollection()] 'theme_save_after' 'store_group_save', ['group' => $groupModel] 'store_delete', ['store' => $model] 'adminhtml_cache_flush_system' 'clean_media_cache_after' 'clean_static_files_cache_after' 'adminhtml_cache_flush_all' 'clean_catalog_images_cache_after' 'sales_quote_item_qty_set_after', ['item' => $this] 'sales_quote_item_set_product', ['product' => $product, 'quote_item' => $this] 'sales_quote_collect_totals_before', ['quote' => $quote] 'sales_quote_collect_totals_after', ['quote' => $quote] 'sales_quote_address_collect_totals_before', [ 'sales_quote_address_collect_totals_after', [ $this->_eventPrefix . '_import_data_before', [$this->_eventObject => $this, 'input' => $data] 'sales_convert_quote_to_order', ['order' => $order, 'quote' => $object->getQuote()] 'items_additional_data', ['item' => $item] 'checkout_submit_before', ['quote' => $quote] 'checkout_submit_all_after', ['order' => $order, 'quote' => $quote] 'sales_model_service_quote_submit_before', [ 'sales_model_service_quote_submit_success', [ 'sales_model_service_quote_submit_failure', [ 'prepare_catalog_product_collection_prices', ['collection' => $productCollection, 'store_id' => $this->getStoreId()] 'sales_quote_item_collection_products_after_load', ['collection' => $productCollection] $this->_eventPrefix . '_load_after', [$this->_eventObject => $this] 'sales_quote_remove_item', ['quote_item' => $item] 'sales_quote_add_item', ['quote_item' => $item] 'sales_quote_product_add_after', ['items' => $items] $this->_eventPrefix . '_merge_before', [$this->_eventObject => $this, 'source' => $quote] $this->_eventPrefix . '_merge_after', [$this->_eventObject => $this, 'source' => $quote] 'salesrule_validator_process', [ 'sales_quote_address_discount_item', $eventArgs 'sales_quote_address_discount_item', $eventArgs 'salesrule_rule_get_coupon_types', ['transport' => $transport] 'salesrule_rule_condition_combine', ['additional' => $additional] 'adminhtml_promo_quote_edit_tab_main_prepare_form', ['form' => $form] 'adminhtml_promo_quote_edit_tab_coupons_form_prepare_form', ['form' => $form] 'adminhtml_block_salesrule_actions_prepareform', ['form' => $form] 'adminhtml_block_promo_widget_chooser_prepare_collection', ['collection' => $collection] 'adminhtml_controller_salesrule_prepare_save', ['request' => $this->getRequest()] 'clean_cache_by_tags', ['object' => $this->cacheContext] 'paypal_express_place_order_success', [ 'catalog_product_validate_variations_before', ['product' => $parentProduct, 'variations' => $products] 'rss_catalog_review_collection_select', ['collection' => $collection] 'review_review_collection_load_before', ['collection' => $this] 'rating_rating_collection_load_before', ['collection' => $this] 'review_controller_product_init_before', ['controller_action' => $this] 'review_controller_product_init', ['product' => $product] 'review_controller_product_init_after', ['product' => $product, 'controller_action' => $this] 'wishlist_item_collection_products_after_load', ['product_collection' => $productCollection] 'wishlist_add_item', ['item' => $item] 'wishlist_product_add_after', ['items' => $items] 'rss_wishlist_xml_callback', $args 'product_option_renderer_init', ['block' => $this] 'wishlist_add_product', ['wishlist' => $wishlist, 'product' => $product, 'item' => $result] 'wishlist_share', ['wishlist' => $wishlist] 'wishlist_update_item', ['wishlist' => $wishlist, 'product' => $product, 'item' => $wishlist->getItem($id)] 'wishlist_items_renewed' 'catalog_product_prepare_index_select', [ 'prepare_catalog_product_collection_prices', ['collection' => $selections, 'store_id' => $product->getStoreId()] 'catalog_product_get_final_price', ['product' => $product, 'qty' => $qty] 'catalog_product_get_final_price', ['product' => $product, 'qty' => $bundleQty] 'catalog_product_option_price_configuration_after', ['configObj' => $configObj] 'catalog_product_get_final_price', ['product' => $product, 'qty' => $this->bundleProduct->getQty()] $this->_eventPrefix . '_move_before', $eventParams $this->_eventPrefix . '_move_after', $eventParams 'category_move', $eventParams 'catalog_category_change_products', ['category' => $category, 'product_ids' => $productIds] $this->_eventPrefix . '_load_before', [$this->_eventObject => $this] $this->_eventPrefix . '_load_after', [$this->_eventObject => $this] $this->_eventPrefix . '_add_is_active_filter', [$this->_eventObject => $this] 'catalog_category_tree_init_inactive_category_ids', ['tree' => $this] 'catalog_category_flat_loadnodes_before', ['select' => $select] 'catalog_category_tree_init_inactive_category_ids', ['tree' => $this] $this->_eventPrefix . '_load_before', [$this->_eventObject => $this] $this->_eventPrefix . '_load_after', [$this->_eventObject => $this] $this->_eventPrefix . '_add_is_active_filter', [$this->_eventObject => $this] 'catalog_product_delete_after_done', ['product' => $object] 'prepare_catalog_product_index_select', [ 'catalog_prepare_price_select', $eventArgs 'catalog_product_collection_load_after', ['collection' => $this] 'catalog_product_collection_before_add_count_to_categories', ['collection' => $this] 'catalog_product_collection_apply_limitations_after', ['collection' => $this] 'catalog_product_compare_item_collection_clear' $this->_eventPrefix . '_validate_before', $this->_getEventData() $this->_eventPrefix . '_validate_after', $this->_getEventData() 'catalog_product_is_salable_before', ['product' => $this] 'catalog_product_is_salable_after', ['product' => $this, 'salable' => $object] $eventName, ['transport' => $transport, 'buy_request' => $buyRequest, 'product' => $product] 'catalog_product_get_final_price', ['product' => $product, 'qty' => $qty] 'catalog_product_attribute_update_before', ['attributes_data' => &$attrData, 'product_ids' => &$productIds, 'store_id' => &$storeId] 'adminhtml_product_attribute_types', ['response' => $response] 'rss_catalog_notify_stock_collection_select', ['collection' => $collection] 'clean_cache_by_tags', ['object' => $this->cacheContext] 'adminhtml_catalog_category_tabs', ['tabs' => $this] 'adminhtml_catalog_category_edit_prepare_form', ['form' => $form] 'adminhtml_catalog_category_tree_is_moveable', ['options' => $options] 'adminhtml_catalog_category_tree_can_add_root_category', ['category' => $this->getCategory(), 'options' => $options, 'store' => $this->getStore()->getId()] 'adminhtml_catalog_category_tree_can_add_sub_category', ['category' => $this->getCategory(), 'options' => $options, 'store' => $this->getStore()->getId()] 'adminhtml_catalog_product_grid_prepare_massaction', ['block' => $this] 'catalog_product_gallery_prepare_layout', ['block' => $this] 'product_attribute_grid_build', ['grid' => $this] 'adminhtml_catalog_product_attribute_set_toolbar_main_html_before', ['block' => $this] 'adminhtml_catalog_product_attribute_set_main_html_before', ['block' => $this] 'adminhtml_catalog_product_edit_prepare_form', ['form' => $form] 'adminhtml_catalog_product_edit_element_types', ['response' => $response] 'adminhtml_product_attribute_types', ['response' => $response] 'product_attribute_form_build_main_tab', ['form' => $form] 'product_attribute_form_build_front_tab', ['form' => $form] 'adminhtml_catalog_product_attribute_edit_frontend_prepare_form', ['form' => $form, 'attribute' => $attributeObject] 'product_attribute_form_build', ['form' => $form] 'adminhtml_catalog_product_form_prepare_excluded_field_list', ['object' => $this] 'adminhtml_catalog_product_edit_tab_attributes_create_html_before', ['block' => $this] 'adminhtml_catalog_product_edit_prepare_form', ['form' => $form, 'layout' => $this->getLayout()] 'adminhtml_catalog_product_edit_element_types', ['response' => $response] 'shortcut_buttons_container', [ 'catalog_product_view_config', ['response_object' => $responseObject] 'catalog_product_upsell', ['product' => $product, 'collection' => $this->_itemCollection, 'limit' => null] 'catalog_block_product_list_collection', ['collection' => $this->_getProductCollection()] 'catalog_product_option_price_configuration_after', ['configObj' => $configObj] 'catalog_block_product_status_display', ['status' => $statusInfo] 'rss_catalog_category_xml_callback', ['product' => $product] 'rss_catalog_new_xml_callback', ['row' => $item->getData(), 'product' => $item 'rss_catalog_special_xml_callback', ['row' => $item->getData(), 'product' => $item 'catalog_category_prepare_save', ['category' => $category, 'request' => $this->getRequest()] 'category_prepare_ajax_response', ['response' => $eventResponse, 'controller' => $this] 'catalog_controller_category_delete', ['category' => $category] 'catalog_product_to_website_change', ['products' => $productIds] 'controller_action_catalog_product_save_entity_after', ['controller' => $this] 'catalog_product_edit_action', ['product' => $product] 'catalog_product_new_action', ['product' => $product] 'catalog_product_gallery_upload_image_after', ['result' => $result, 'action' => $this] 'catalog_controller_category_init_after', ['category' => $category, 'controller_action' => $this] 'catalog_product_compare_remove_product', ['product' => $item] 'catalog_product_compare_add_product', ['product' => $product] 'catalog_controller_product_init_before', ['controller_action' => $controller, 'params' => $params] 'catalog_controller_product_init_after', ['product' => $product, 'controller_action' => $controller] 'catalog_controller_product_view', ['product' => $product] 'assign_theme_to_stores_after', ['stores' => $stores, 'scope' => $scope, 'theme' => $theme] 'page_block_html_topmenu_gethtml_before', ['menu' => $this->_menu, 'block' => $this] 'page_block_html_topmenu_gethtml_after', ['menu' => $this->_menu, 'transportObject' => $transportObject] 'gift_options_prepare_items', ['items' => $entityItems] 'adminhtml_cache_refresh_type' 'depersonalize_clear_session' 'customer_session_init', ['customer_session' => $this] 'customer_login', ['customer' => $customer] 'customer_data_object_login', ['customer' => $this->getCustomerDataObject()] 'customer_data_object_login', ['customer' => $customer] 'customer_logout', ['customer' => $this->getCustomer()] 'customer_customer_authenticated', ['model' => $this, 'password' => $password] 'customer_validate', ['customer' => $this, 'transport' => $transport] 'customer_customer_authenticated', ['model' => $customerModel, 'password' => $password] 'customer_data_object_login', ['customer' => $customer] 'customer_save_after_data_object', ['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $customer] 'visitor_init', ['visitor' => $this] 'visitor_activity_save', ['visitor' => $this] 'customer_address_format', ['type' => $formatType, 'address' => $this] 'adminhtml_block_html_before', ['block' => $this] 'customer_register_success', ['account_controller' => $this, 'customer' => $customer] 'adminhtml_customer_prepare_save', ['customer' => $customer, 'request' => $request] 'adminhtml_customer_save_after', ['customer' => $customer, 'request' => $request] 'catalog_product_prepare_index_select', [ 'on_view_report', ['report' => 'search'] 'sales_prepare_amount_expression', ['collection' => $this, 'expression_object' => $expressionTransferObject] 'adminhtml_widget_grid_filter_collection', ['collection' => $this->getCollection(), 'filter_values' => $this->_filterValues] 'clean_cache_after_reindex', ['object' => $this->context] 'checkout_type_multishipping_set_shipping_items', ['quote' => $quote] 'checkout_type_multishipping_create_orders_single', ['order' => $order, 'address' => $address, 'quote' => $this->getQuote()] 'checkout_submit_all_after', ['orders' => $orders, 'quote' => $this->getQuote()] 'checkout_multishipping_refund_all', ['orders' => $orders] 'multishipping_checkout_controller_success_action', ['order_ids' => $ids] 'checkout_controller_multishipping_shipping_post', ['request' => $this->getRequest(), 'quote' => $this->_getCheckout()->getQuote()] 'persistent_session_expired' 'adminhtml_cms_page_edit_tab_main_prepare_form', ['form' => $form] 'adminhtml_cms_page_edit_tab_design_prepare_form', ['form' => $form] 'adminhtml_cms_page_edit_tab_content_prepare_form', ['form' => $form] 'adminhtml_cms_page_edit_tab_meta_prepare_form', ['form' => $form] 'cms_controller_router_match_before', ['router' => $this, 'condition' => $condition] 'cms_page_prepare_save', ['page' => $model, 'request' => $this->getRequest()] 'adminhtml_cmspage_on_delete', ['title' => $title, 'status' => 'success'] 'adminhtml_cmspage_on_delete', ['title' => $title, 'status' => 'fail'] 'cms_page_render', ['page' => $this->_page, 'controller_action' => $action] 'cms_wysiwyg_images_static_urls_allowed', ['result' => $checkResult, 'store_id' => $this->_storeId] 'sales_order_place_before', ['order' => $this] 'sales_order_place_after', ['order' => $this] 'order_cancel_after', ['order' => $this] 'sales_convert_order_to_quote', ['order' => $order, 'quote' => $quote] 'sales_convert_order_item_to_quote_item', ['order_item' => $orderItem, 'quote_item' => $item] 'checkout_submit_all_after', ['order' => $order, 'quote' => $quote] 'sales_order_status_unassign', [ 'email_invoice_comment_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_invoice_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_order_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_shipment_comment_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_shipment_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_creditmemo_comment_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_creditmemo_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'email_order_comment_set_template_vars_before', ['sender' => $this, 'transport' => $transport] 'sales_order_item_cancel', ['item' => $this] 'sales_order_payment_place_start', ['payment' => $this] 'sales_order_payment_place_end', ['payment' => $this] 'sales_order_payment_pay', ['payment' => $this, 'invoice' => $invoice] 'sales_order_payment_cancel_invoice', ['payment' => $this, 'invoice' => $invoice] 'sales_order_payment_void', ['payment' => $this, 'invoice' => $document] 'sales_order_payment_refund', ['payment' => $this, 'creditmemo' => $creditmemo] 'sales_order_payment_cancel_creditmemo', ['payment' => $this, 'creditmemo' => $creditmemo] 'sales_order_payment_cancel', ['payment' => $this] 'sales_order_invoice_pay', [$this->_eventObject => $this] 'sales_order_invoice_cancel', [$this->_eventObject => $this] 'sales_order_invoice_register', [$this->_eventObject => $this, 'order' => $order] $this->_eventPrefix . '_html_txn_id', $this->_getEventData() 'sales_order_payment_capture', ['payment' => $payment, 'invoice' => $invoice] 'customer_address_format', ['type' => $formatType, 'address' => $address] $this->_eventPrefix . '_set_sales_order', ['collection' => $this, $this->_eventObject => $this, 'order' => $order] $this->_eventPrefix . '_load_after', [$this->_eventObject => $this] 'sales_sale_collection_query_before', ['collection' => $this] $object->getEventPrefix() . '_save_attribute_before', [ $object->getEventPrefix() . '_save_attribute_after', [ 'sales_order_state_change_before', ['order' => $this, 'transport' => $transport] 'sales_order_creditmemo_cancel', ['creditmemo' => $creditmemo] 'sales_order_creditmemo_refund', ['creditmemo' => $creditmemo] $this->_eventPrefix . '_sales_email_general_async_sending_' . $state, $this->_eventPrefix . '_dev_grid_async_indexing_' . $state, 'rss_order_new_collection_select', ['collection' => $collection] 'adminhtml_customer_orders_add_action_renderer', ['renderer' => $this, 'row' => $row] 'adminhtml_sales_order_creditmemo_register_before', ['creditmemo' => $creditmemo, 'input' => $this->getCreditmemo()] 'adminhtml_sales_order_create_process_data_before', $eventData 'admin_sales_order_address_update', [ 'tax_rate_data_fetch', ['request' => $request, 'sender' => $this] 'tax_settings_change_after' 'adminhtml_cache_refresh_type', ['type' => 'block_html'] 'checkout_type_onepage_save_order_after', ['order' => $order, 'quote' => $this->getQuote()] 'checkout_submit_all_after', [ 'custom_quote_process', ['checkout_session' => $this] 'checkout_quote_init', ['quote' => $quote] 'load_customer_quote_before', ['checkout_session' => $this] 'checkout_quote_destroy', ['quote' => $this->getQuote()] 'restore_quote', ['order' => $order, 'quote' => $quote] 'checkout_cart_product_add_after', ['quote_item' => $result, 'product' => $product] 'checkout_cart_update_items_before', ['cart' => $this, 'info' => $infoDataObject] 'checkout_cart_update_items_after', ['cart' => $this, 'info' => $infoDataObject] 'checkout_cart_save_before', ['cart' => $this] 'checkout_cart_save_after', ['cart' => $this] 'checkout_cart_product_update_after', ['quote_item' => $result, 'product' => $product] 'shortcut_buttons_container', [ 'checkout_cart_add_product_complete', ['product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()] 'checkout_cart_update_item_complete', ['item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse()] 'checkout_onepage_controller_success_action', ['order_ids' => [$session->getLastOrderId()]] 'checkout_controller_onepage_saveOrder', [ 'checkout_allow_guest', ['quote' => $quote, 'store' => $store, 'result' => $result] 'controller_action_nocookies', ['action' => $this, 'redirect' => $redirect] 'eav_collection_abstract_load_before', ['collection' => $this] 'adminhtml_block_eav_attribute_edit_form_init', ['form' => $this->getForm()] 'sendfriend_product', ['product' => $product] 'catalog_product_import_bunch_delete_after', ['adapter' => $this, 'bunch' => $bunch] 'catalog_product_import_finish_before', ['adapter' => $this] 'catalog_product_import_bunch_save_after', ['adapter' => $this, 'bunch' => $bunch] 'admin_user_authenticate_before', ['username' => $username, 'user' => $this] 'admin_user_authenticate_after', ['username' => $username, 'password' => $password, 'user' => $this, 'result' => $result] 'permissions_role_html_before', ['block' => $this] 'admin_permissions_role_prepare_save', ['object' => $role, 'request' => $this->getRequest()] 'store_address_format', ['type' => $type, 'store_info' => $storeInfo] 'swatch_gallery_upload_image_after', ['result' => $result, 'action' => $this] 'payment_method_is_active', [ 'payment_method_assign_data_' . $this->getCode(), [ 'payment_cart_collect_items_and_amounts', ['cart' => $this] 'payment_form_block_to_html_before', ['block' => $this] 'catelogsearch_searchable_attributes_load_after', ['engine' => $this->engine, 'attributes' => $attributes] 'catelogsearch_searchable_attributes_load_after', ['engine' => $this->engine, 'attributes' => $attributes] 'catalogsearch_reset_search_result' 'checkout_directpost_placeOrder', [ 'clean_cache_by_tags', ['object' => $this] 'adminhtml_promo_catalog_edit_tab_main_prepare_form', ['form' => $form] 'adminhtml_controller_catalogrule_prepare_save', ['request' => $this->getRequest()] "admin_system_config_changed_section_{$this->getSection()}", ['website' => $this->getWebsite(), 'store' => $this->getStore()] 'adminhtml_system_config_advanced_disableoutput_render_before', ['modules' => $dispatchResult] 'admin_system_config_changed_section_currency_before_reinit', ['website' => $this->_websiteId, 'store' => $this->_storeId] 'admin_system_config_changed_section_currency', ['website' => $this->_websiteId, 'store' => $this->_storeId] |
Magento 2 hello world module in 2 mins!
Create Magento 2 hello world module in 2 minutes!
To create a simple custom module in Magento2 which will give an output on frontend website from your module, follow below steps:
Change to app/code directory where all the Magento2 module lives. Notice there are no codepools (core, community, local) under this directory like it used to be in Magento 1.x
1 | cd app/code |
Create your company name directory
1 | mkdir Hello |
Create you module name directory
1 | mkdir Hello/World |
Create etc directory to hold module config file
1 | mkdir Hello/World/etc |
module.xml file is required only to hold module name and it’s version
1 | vi Hello/World/etc/module.xml |
1 2 3 4 | <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Hello_World" setup_version="0.1.0" />
</config> |
Register your module, this is required in all the modules. Only thing you will change is your module name (Hello_World)
1 | vi Hello/World/registration.php |
1 2 3 4 5 6 | <?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Hello_World',
__DIR__
); |
Create frontend directory under etc to define frontend routes. We are creating this because we want to output something on frontend website.
1 | mkdir Hello/World/etc/frontend |
routes.xml is used to give your module a front name. Only thing you will be interested is
1 | vi Hello/World/etc/frontend/routes.xml |
1 2 3 4 5 6 7 8 | <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
<router id="standard">
<route id="first" frontName="first">
<module name="Hello_World" />
</route>
</router>
</config> |
Create Controller directory to hold your module’s controller files
1 | mkdir Hello/World/Controller |
Create your controller directory, this will become part of the url after frontName
1 | mkdir Hello/World/Controller/Hello |
Create controller file, notice there is no controller action in Magento2 Controller. This will again become part of the url and will call execute() method of the class.
1 | vi Hello/World/Controller/Hello/World.php |
1 2 3 4 5 6 7 8 9 | <?php
namespace Hello\World\Controller\Hello;
class World extends \Magento\Framework\App\Action\Action
{
public function execute()
{
echo 'Hello world!';
}
} |
Change directory to reach Magento 2 root directory
1 | cd ../../ |
Enable your module, so an entry will go to app/etc/config.php file and cache will be cleared
1 | bin/magento module:enable Hello_World |
This will add your module with it’s current version to DB table setup_module, without running this command you won’t see the changes of newly created module.
1 | bin/magento setup:upgrade |
Check your module in browser: http://www.yourwebsite.com/first/hello/world. If you have done everything correct, it should output “Hello world!”
Magento 2 – Security Bug in Customer Address section (Resolved)
Magento 2 had a serious security bug where a website user can view and edit any customer’s address very easily. I reported this issue to Magento 2 team and they quickly fixed it and rolled it out in new beta version. All the beta versions up to 0.42.0-beta11 were affected, and from 0.74.0-beta1 it is fixed (I have not tested it yet).
Details about the bug and progress: https://github.com/magento/magento2/issues/1107
If you are using the affected Magento 2 versions for online demo or development please upgrade it. Though people use fake address in Demo stores, it is likely that some of them could have used their real address and details which can be accessible by anyone who knows about this bug.
Welcome to my Blog
Certifications
Honor
Recognition
Contributions
Categories
- Apache (2)
- ChatGPT (1)
- Domain name (2)
- eCommerce (2)
- htaccess (1)
- Humor (3)
- Instagram API (1)
- jQuery (4)
- JSON (1)
- Linux (10)
- Magento (142)
- Magento admin (58)
- Magento Certification (5)
- Magento error (13)
- Magento frontend (68)
- Magento Imagine (2)
- Magento Interview (5)
- Magento Master (2)
- Magento2 (10)
- Mobile (1)
- MySQL (7)
- OpenAI (1)
- OroCRM (2)
- Performance (2)
- PHP (8)
- Prototype JS (3)
- Security (4)
- Wordpress (3)
- XML (2)