Tips to Grow eCommerce Business in 2018

Do you own an eCommerce business? Are you wondering how to improve it this year? If so, then you already know what a struggle it can be to expand in this industry. With so much competition, you might be at a loss trying to figure out where to start.

That’s why we’ve created this article, which will provide you with only the best tips for eCommerce success. Before we start, though, here’s a short table of content so that you know what’s ahead.

Table of contents:

What Else to Do To Grow eCommerce Business in 2018: Keeping up with the Times
eCommerce Site Personalization: Making Every Experience Unique
Building Your Brand is Still Important in 2018: Branding for Best Results
Video Content For Success: How Diverse Content Shapes Your Brand
Gather the Best Team: Developing the Team That Will Lead You
Try New ECommerce Email Marketing Strategy: Emails and Your Future
Summary

What Else to Do To Grow eCommerce Business in 2018

Now that you’re familiar with the goal of this article, we can move on to how you can build your eCommerce Business Strategy. Overall, it’s essential that you keep up with new technologies and features because this will help you to stay ahead of your competition. If you’re using tricks that they aren’t, you’re going to generate more leads in the end!

eCommerce Site Personalization

Website personalization is one of the most impactful ways for you to increase your conversions. There are many more benefits of personalization in eCommerce which we’ll talk about a little more.

With website personalization, you can determine the overall dynamic of your website. When your pages are more interactive, it makes it easier for potential customers to navigate through your site and, therefore, they’re more likely to stay loyal to you rather than another company.

Offers are a great way to personalize your website as well because you can completely customize the product so that you’re providing an offer like no other. You can introduce time limits to get your customers buying right away, and you can edit the look of the off announcement banner.

You can introduce pop-ups to your website if you want to optimize your conversions completely. In doing this, you’ll personalize the offer and the content of the pop-up so that it’s unique to your customers. There are a few different pop-ups that you can introduce to your site: including on-click, timed, scroll, etc.

Building Your Brand in 2018

You might think that once your brand is established, you don’t have to continue with new strategies or to develop your current one anymore. This isn’t true. You have to continuously build your brand so that it stands out and so that it’s memorable.

Now, how do you build your brand? You need to establish a voice in the branding process. We don’t mean that you have to include voice clips; instead, your brand should speak for itself. Everything from the color palette of your site to the font, to the photography, should give your visitors the same vibe.

To do this, you have to find out how to set yourself apart from the competition. You don’t want the same page layouts or fonts as everyone else. If you have a brand that needs to make a profound statement, you might consider bold fonts.

To build your brand, you also need to exploit the best parts of your business. Instead of only focusing on what needs to be worked on, you should identify what’s great about your business and advertise.

Let’s say you’re in an industry that has a hard time shipping quickly. You should find a way to ship within two days. People will have deadlines and events, so you need to be ahead of the game and make sure they get their items on time. Overall, customers will notice what sets you apart from everyone, and that’s what will attract them to your eCommerce business.

Video Content For Success

Video content is increasingly popular. That’s because we live in a digital world, and people don’t want to read as many long descriptions. Because of this, the companies which have video content are also the ones with the highest conversions.

If you have a clothing store, for example, you should consider including shopping hauls; wherein, popular YouTube channels buy hundreds of dollars of clothing to showcase and review the items. If you see that someone had many followers and liked your clothing, you can ask them to include the content on your site.

Companies tend to rank higher in Google when they have diverse content on their pages. You’re going to have more visitors if you have pictures, videos, and articles rather than just articles. As always, make sure your videos are branded with links that lead back to your main page because this will always bring visitors back to you.

Gather the Best Team

Building the best time can be a difficult task. This doesn’t just involve developing the right dedicated team for your company, but also for the development of your website, applications, etc. and for the store’s support.

All of these things will determine how well your store runs. If you have a team that doesn’t work efficiently, you’ll spend more time to set up right organization strategy. This will slow down you from getting the most sales results and, therefore, your company can’t expand fully.

When you build your team, you have to think in the long-term. These are people who will represent your business, and you have to find out whether they’ll be with for the next few years or more.

Try New eCommerce Email Marketing Strategy

Email marketing is underrated. This is because prices for advertising continue to increase. As they do, email marketing will become your main method of advertising and will be one of the features that provides you with the most leads.

Building your email list is the best way to get people to keep coming back to your site. Since you already have data on them, you’ll be able to target specific customers based on their past spending and search history.

Some claim that you should be getting almost a third of your overall revenue from email marketing. If you’re not getting that much, then you might want to consider increasing your email marketing importance.

Best Magento 2 GDPR Extensions Free & Premium in 2019

GDPR means General Data Protection Regulation. It is a piece of legislation involving information gathering and use. Since GDPR became law, every EU website is required to follow specific requirements in the collection of personal information. Companies out of compliance are subject to heavy penalties. Therefore, it’s essential for all eCommerce websites to include extensions and strategies to honor these regulations. In this piece, we’ll explore the best extensions to meet GDPR requirements for Magento® eCommerce platforms.

GDPR Overview

The GDPR came into force in May of this year. It addresses how information is collected by processors and controllers. Controllers are the companies and individuals that collect information. Processors are company workers and representatives. The aim of the GDPR is to protect data for all EU residents and citizens. If companies offer services and goods in the EU, they are obligated to follow GDPR law, even if they are foreign-based. If your website uses an EU language, accepts payments in Euros, or mentions EU clients, then regulations require it to act within GDPR law.

There are three main elements to the GDPR. Protection of personal data, protection of people’s rights and freedom regarding information gathering, and restrictions regarding the sharing and use of this information. Information which can identify a person qualifies as personal data. Regulations also require data collection details to be made transparent in the Privacy Policy of your website.

GDPR Regulation

GDPR aims to create awareness about and offer control over how information is collected and used. The goal is to simplify information collection and management. GDPR is oriented around seven principles:

  1. Processing: Information processing should be done with transparency, legally and fairly.
  2. Limitation of Purpose: Information can only be gathered for legitimate, precise, specific purposes and processed only for those purposes.
  3. Minimization: No information should be gathered beyond the stated purposes. As little data as possible should be collected to fulfill this purpose.
  4. Accuracy: All inaccurate information should be updated or removed immediately upon discovery.
  5. Limitation of Storage: Personal information should be removed once it has fulfilled the company’s stated goals.
  6. Confidentiality and Integrity: Information should be used only in legal and authorized fashions and protected from exposure to other parties.
  7. Accountability: Persons and companies responsible for processing and collecting information are accountable for any damage, destruction, or loss related to illegal or unauthorized information handling.

As per GDPR, information which can be used as an identifier is personal data. Names, ID numbers, online identifiers, locations, and other information which can be used to identify a specific person all fall under this category. GDPR makes allowances for technological innovation and changes in information gathering methods. It covers information collected automatically or gathered manually for filing systems.

GDPR also addresses sensitive information. This category includes genetic and biometric data. Philosophical views, religious views, and political views also fall under the heading of sensitive personal information. Sensitive data is protected under extra safeguards. Data protected with a pseudonym or key-code is regarded as personal data, if it can be connected with the individual, indirectly or directly.

Information is only regarded as personal if it “relates to” or concerns a specific person. Consider informational content, processing purpose, and potential impact. Inaccurate information can be regarded as personal data, but anonymized information is exempt from GDPR regulation. Data regarding the deceased, companies or public authorities are also exempt. On the other hand, information about employees, company directors, sole traders, and partners is protected under GDPR.

What Are GDPR Requirements?

Before gathering personal information, a company must establish a valid reason for its collection. The GDPR established six valid reasons, or lawful bases, which justify information gathering and processing. These are:

  1. Consent: A person can permit to process certain data for a stated goal.
  2. Contract: Specific information can be necessary to establish contract legitimacy.
  3. Legal Obligation: Legal compliance can legitimately require the processing of certain data.
  4. Vital Interests: Information can be gathered to protect life.
  5. Public Task: Specific information may be gathered to help officials to act in the public interest according to the scope of their position.
  6. Legitimate Interests: The legitimate interests of your company or a third party may require the gathering and processing of specific information.

These are the six legitimate purposes which justify data gathering and use. Should your goals change, information can be used for the new goals only if they are compatible with the previous ones. After defining a lawful basis, each website must explicitly state what information is collected and how it is used. This must be clarified in a site’s Cookie and Privacy statements.

How to Make Your Website GDPR Compliant

To ensure your company complies with GDPR standards, you must understand GDPR principles. Think about the content of the data you collect. If the sensitive personal information is gathered, read up on the additional conditions that apply to this specific type of data. You must also prepare all documentation to ensure that information is being collected according to a valid legal basis. Finally, all EU customers should be informed of the data gathered, the reason for gathering it, and the processing details.

The principles listed above are the core of GDPR. They are not ironclad laws. Instead, they lay out the intentions of data protection regulations. Websites are compliant when they act by these principles. Any infringements upon these basic principles will result in severe fines.

GDPR requires data to be processed legally, transparently, and fairly. To establish GDPR requirements, first, find your lawful basis for information gathering and processing. This gives you validity for the handling of information. Be open, honest, and clear regarding the information and its uses. Do not mislead the customer, and ensure that the data isn’t used detrimentally. Finally, follow GDPR standards and any other relevant regulations. This includes ensuring the information is not processed in any way that constitutes:

  • Confidence breaches;
  • Exceeding your legal powers or exercising them improperly;
  • Copyright infringements;
  • Contract breaches;
  • Breaches of industry-specific regulations; or
  • Breaches of the Human Rights Act of 1998.

Documentation

Extensive documentation is needed to demonstrate that you are prepared. To be compliant, you must be able to produce a set of documents upon demand. The documents required by the GDPR are as follows:

  • Subject Access Request Forms and Procedures
  • Retention and Erasure Policy & Schedule
  • Records of Processing Activities (where applicable)
  • Records of Consent from Data Subjects or Parental/Guardian Consent
  • Processor Agreements (where applicable)
  • Procedures for Subject Access Requests
  • Procedures for Non-EU Data Transfers & Documented Safeguarding Measures
  • Procedures for Data Breaches & Notifications
  • Procedures & Notifications for Subject Rights
  • Privacy Notice with Article 13/14 Information Disclosures
  • Documented Technical & Organisational Measures for Processing Security
  • Data Protection Policy
  • Data Protection Officer Appointment, Duties & Notifications (where applicable)
  • Data Protection Officer Appointment, Duties & Notifications (where applicable)

There are several additional forms which extend beyond mandatory requirements. These forms constitute best practice and show dedication to GDPR:

  • Access Request Response Templates – These templates ensure compliant and consistent SAR responses.
  • Information Audit – Record details of gathered information.
  • Internal Audit & Review Policy & Procedures – First, establish GDPR policies and compliance measures and procedures. Review, audit and assess regularly. Adjust and adapt as necessary to maintain compliance.
  • Privacy Notice Register – Keep Privacy Notice records. Make sure details like purpose, and last revision date are accessible.
  • Staff Training Program –Training methods and policies, evaluations and assessments, any other relevant details.

Assigning Roles

GDPR requires you to assign roles for information processing and gathering. GDPR defines two key roles: processor and controller. Controllers define the goal of information collection and handling. Processors are entities working for a controller, dealing with information records or processing data. For companies employing over 250 individuals processing information from more than 5000 subjects, GDPR regulation requires a Data Protection Officer responsible for compliance.

Legislations relate specifically to each role, so each individual involved in information handling should understand their role. Processors must keep records of information processing and gathering. They are held liable if this information is breached. Controllers are not exempt from these obligations. They are legally obligated to ensure that processors act in compliance. All organizational activities within the EU are subject to these regulations.

Notifying Customers

Transparency is a key principle for GDPR. Your customers should be made fully aware of any information gathered, your reason for gathering it, and how it is processed. Inform the customer of the lawful basis for collecting data. Include written Cookie policies and Privacy policies which fully detail your information collection and usage practices.

Set Up Extension

There are several extensions which help to ensure GDPR compliant data collection. Each extension offers features which allow you to customize your data collection and processing practices and procedures. The sections below explore the features and pricing of each extension in further detail.

GDPR Magento 2 Extensions for eCommerce Stores

GDPR eCommerce can be complicated for companies both within and outside the EU. GDPR extensions ensure that your Magento eCommerce platform complies with GDPR. They help to bring all aspects of your business operation into alignment with current regulations.

GDPR Compliance Manager from OnTap

OnTap manager keeps tabs of all customer data. It also gives your customers access to their data and request erasure. Here are key features offered by OnTap:

  • Offers Subject Access Requests to Customers.
  • Provides a Compliance dashboard.
  • Gives customers comprehensive access to information.
  • Handles the deletion of data through Magento.
  • Offers a workflow which tracks external system data deletion and shows external data sources.
  • Informs you of obligations and notifies you of breaches.
  • Installation is fast and easy. Installation services are offered in more complicated cases.

OnTap’s compliance manager retails at £199. It offers free installation and a 30-day money back guarantee. Free 90-day support is included in the purchase, with the option of 180-day support for £79.60 or 360-day support for £199 pounds.

GDPR Extension for Magento 2 from Amasty

Amasty’s GDPR extension for Magento 2 collects user consent for information gathering and handling. It manages privacy issues and creates privacy policies, adapting them to your operating region or creating several for different regions. It also provides policy updates for new regulations. This extension lets you:

  • Reach GDPR EU regulation;
  • Add Privacy Policy check box to relevant pages;
  • Collect user consent on relevant pages;
  • Establish and update privacy policies;
  • Handle necessary documents;
  • Let customers anonymize or download profile data and request deletion;
  • Export customer lists according to consent;
  • Obtain consent through email and manage consent via a grid;
  • and Update customers on Privacy Policy changes via email.

Amasty Magento 2 GDPR extension retails for £199. Installation costs £59, however, Amasty offers a year of free support.

GDPR Extension for Magento 2 by Aheadworks

Aheadworks offers yet another GDPR extension with impressive features and at a competitive price. These are a few features this extension offers:

  • Automatic deletion for accounts linked to abandoned carts or incomplete orders
  • Complete Base Management for Customers
  • Full customer access and means to request data deletion
  • Email-driven customer verification
  • Means to delete user information
  • Means to export customer lists based on lack of consent
  • Means to export data access and data removal requests
  • Monitoring systems for customer removal requests
  • Tracking systems for customers by consent or lack of consent
  • Tracking systems for data access requests
  • Means to request consents
  • Regular automated updates for information protection policies

Just as with the OnTap and Amasty extensions, the AheadWorks GDPR extension for Magento 2 retails for £199. It comes with a 45-day money-back guarantee and 90 days of free support. This offer also includes free installation and free updates for life.

GDPR Magento Compliance Extension from Magebit

Magebit is a full-service provider of GDPR tool and all other eCommerce web platform solutions. They offer a free open source GDPR extension. Magebit also has a track record of bringing online stores into compliance with GDPR. They offer 24/7 service if you need your site brought into compliance urgently. Magebit also offers a free GDPR requirement checklist so that you can evaluate what your site needs.

Magebit tailors its services to your site, so they don’t give a single price for all web platforms. Magebit ensures that:

  • You have a comprehensive list of all personal data, the sources, the uses, where it is shared, and how long it is kept.
  • You have a detailed analysis of where personal data is stored and how information flows between these locations.
  • The privacy policy is accessible to the public and details all processes relevant to personal data.
  • The privacy policy includes a lawful basis in compliance with GDPR regulations and a clearly stated policy of use.
  • You have a Data Protection Officer with all required documentation.
  • Your decision makers and staff are aware of data protection and GDPR guidelines.
  • Policies are in place for reporting breaches in data.
  • You have a detailed list of sub-processors and contracts to cover data sharing under GDPR guidelines.
  • Your customers can access, update, halt processing, or request deletions of data.
  • Your system automatically deletes any data which is no longer in use.

These are just a few of the features that Magebit offers. It is a great tool to make your store GDPR-ready.

Prepare Your Store According to GDPR Requirements

GDPR requirements list is a major feature of current eCommerce web platforms operating within the EU. Given the extensive regulations, it can be challenging to meet all current requirements. However, with the extensions and information above, you can easily adapt to GDPR and keep your company on top of the game.

Meet Magento UK 2018 Summary

It was a couple of weeks ago, but to refresh memories of those who were there and those of you who wanted to know about such or similar events we’ve prepared our short recap of this event.

What Is Interesting About Meet Magento UK?

We have attended the Meet Magento® UK on June 13th, 2018 at The Mermaid Theatre in London. Let’s start with the venue: It had two halls: main – for the business topics and the other for technical discussions.

Meet Magento UK 2018 at The Mermaid Theatre in London

Meet Magento UK 2018 at The Mermaid Theatre in London

The MMUK18 has gathered 400 visitors from almost all around the world. There were two tracks: for merchants and technicians. Merchant track has been dedicated to investors expectations in the future of eCommerce and Magento obviously. Also, a big talk was devoted to ideas to help you plan, execute, and analyze research for your online store.

We’ve got some important insights from Peter Sheldon on Adobe and Magento future and benefits that it will bring for their joint solution. Mainly it could be the Cloud platform with unique personalization features.

Also, he spoke about a customer’s journey and all the opportunities that brands have to create to improve the user experience. There was a great example of Tesla to show that experience is differentiated brands which will stand with a time.

There were more topics about innovation in eCommerce, research and each panel had a unique case that helped to understand each subject in practice.

The technical track was covered up questions about PWA, DevOps and Magento Page Builder. PWA was the hottest trend, and there were a lot of discussions around how it would be implemented, but also other topics were interesting for developers and merchants to think about having new features in future.

Meet Magento UK 2018 Summary

Magento 2 Extensions for Personalized User Experience

Are you interested in the world of eCommerce? Have you heard of Magento® 2 extensions and Magento’s customization before? If so, you’re not the only one. Magento is one of the best-known platforms for eCommerce websites and companies. That’s because it provides a unique experience for everyone and increases conversions, leads, revenue, etc.

That said, how does Magento affect user experience and why are people so likely to convert to this eCommerce giant? In our below guide, you can read about customizable options in Magento 2.

Magento Personalization Features

Before we get into detail, you should know about Magento 2 product personalization and the benefits of using this platform for both you and your customers.

Customer Oriented Content

You can increase your conversions by creating content that targets your customers. By doing this, you can make every shopping experience unique. This happens when extensions collect data about your customers based on their search history, location, interests, and more.

If you’re looking for the best Magento 2 extension to use for this feature, you should try Fresh Relevance. By creating a unique experience for your customers, the extension provides you with more loyal customers. In short, people are more likely to stick with you if they feel valued by you.

How Does Fresh Relevance Allow You to Customize Experiences?

All you have to do is get used to the extension’s useful toolset. You can do this through either email or web content with the use of online profiling. Here is a short list of Fresh Relevance features:

  • Recommendations for products
  • Online profiling
  • Personalizing content
  • Integrates emails

Product Content

Product personalization is a sure way of making your customers happy. It’s one of Magento’s strengths because it provides the best recommendations out there. Magento chooses its recommendations based on purchase history, online habits, customer profiles, pricing, and several other factors.

As such, product recommendations are tailored to suit the habits of individuals and not groups of people.

Additional Magento Store Functionality for Better UX

For those who want to know more about specific features of Magento 2 to improve user experience, you can read about brand selection, instant checkout, and much more!

Shop by Brand Section

You need to make sure that the layout of your eCommerce website is as convenient as possible for your customers and potential buyers. This means you have to think like a customer when you’re going through your site. The brand section is one of the most important parts of any eCommerce website. It provides a variety for people who are looking for more than just a general selection of the topic they’re trying to buy in.

If, for example, you have a clothing retail website, you might want to add brands like “Calvin Klein to the sidebars so that those who are looking for something specific can find what they wish to conveniently.

Instant Checkout

Instant checkout benefits any eCommerce website, and it just so happens that Magento 2 users can have it all that much easier.
A smooth process ensures conversions. This remains true for checkouts and transaction processing. You shouldn’t try to complicate it too much because you can deal with abandoned carts afterward.

Magento personalization has greatly improved their checkout process, making it smoother and faster for everyone involved. Magento 2 offers One Step checkout, which has been proven to be 40% faster than previous ones.

Advanced Search and Navigation

Easy navigation is the secret to a successful business. Magento 2 allows you to make your navigation direct and simple. Its various navigation settings enable customers to choose from a limited number of categories that will later guide them until the final product is shown.

A great example of one of these extensions is Mega Menu, which has been endorsed by many in the eCommerce industry and IX experts.

AI Personalization

The use of personalization AI can help with the overall unique customer experience for each of your customers. This is done through automated email personalization; wherein, recommendations can be made on past customer experience.

Not only this, but this AI has pricing that might appeal to you because it only charges around 4% of the revenue that’s generated by the AI personalization. In comparison, hiring physical individuals to spread the word about your company will cost considerably more!

AI is evolving in the world of eCommerce because it can pose as your clients’ personal shoppers. This is done through the Chloe extension for Magento 2 stores. It can help them through the entire shopping process so that they have help right away.

8 Elements to Include into Your Magento eCommerce Design

In the decade since its launch, Magento® has become the leading eCommerce platform. The reason for its success is that Magento is flexible and user-friendly. It’s packed with features, highly customizable, and easy to both use and scale. It is an ideal platform for business owners who seek innovative ways to engage with their clients. Magento is effective for small business and large ones. Its scalability helps growing business to reach global proportions. Let’s have a look at some of the design elements to include in your Magento eCommerce design.

What to Design at Your Magento Store

The main key to a successful design is to understand your customers. What do they want? How can you best meet their needs? You also want your site to be user-friendly and engaging. Try to present users with products and services they will want or need. Include calls-to-action and opportunities for the customer to interact with the site.

Here are eight elements which will improve the success of any Magento eCommerce design:

1. Customer Name Field

One of the best ways to connect with people is to use their name. When someone uses our name, we become more open and more willing to engage. This also applies to the relationship between businesses and their customers. Many early designers overlook this element of eCommerce design.

Customers are more comfortable sharing their names than more sensitive information. You can gather names easily by using contact forms or pre-purchase opt-in forms. With a name, you can personalize the customer experience.

2. Related Products

One key to successful eCommerce design is to present your customers with related products. Previous searches can be used to personalize the customer experience. Related products are the most viewed elements on eCommerce websites. They draw attention and increase conversion rates.

Most people won’t want to spend much time searching. The goal is to make it easy for each customer to find things that they are interested in. Try to make your most in-demand products highly visible and place them on the homepage.

3. Product Collections

Product collections are lists of products focused on specific topics. They will dramatically increase sales for your Magento store. Product collections increase your search rankings. This means that prospective customers will be able to find your site more easily. They also let you showcase the best selling products or offer personalized product recommendations. Try to keep these collections updated. New products and deals will raise customer engagement and keep your customers coming back to the site.

4. Rating and Reviews

Ratings and reviews are excellent for building trust. The eCommerce website is like any business. It is a relationship between the owners and managers, and the customers. Cultivating this relationship means making the customer feel comfortable about their purchase.

People often use feedback and recommendations to inform their decisions. Ratings and reviews offer the customer confidence. They make your eCommerce website more trustworthy and more successful. You can gather reviews by requesting feedback in follow-up emails. An alternative is to offer bonuses or discounts to users that provide reviews.

5. Different Fill-Out Forms

Building a relationship also involves offering clients an opportunity to engage with the site and the business. You can do this by including fill-out forms in your design. Feedback forms will give your customer a voice while also gathering reviews.

Rating forms are also an excellent addition, as they are comfortable and quick for the customer. You can also use a form to gather customer contact details! With these details, you can personalize customer outreach and increase engagement. Remember that all information should be collected under GDPR law. Also, make sure to inform customers of the information you gather and how it will be used.

6. Call-to-Action Buttons

Call-to-action buttons can funnel the site experience towards products your customers will like. The Magento 2 design guide offers several tips on how to include call-to-action buttons in your site. It is a designer’s guide to the development of Magento eCommerce web platforms. It explores many elements of design in detail. CTA’s can be tricky design elements, but they can exponentially increase conversions. More than 90% of those who visit your site will read CTA’s. It’s important that they are visible and that they speak to the target audience. With a well-crafted landing site, the CTA will be the last step between customer and conversion.

7. Wish Lists

Magento website design also makes it easy to create personalized wish lists. Browsing customers often see products that catch their interest but need time to consider before they buy. Later, they may find the product on a different site or forget about it altogether. With wish lists, you can maintain customer interest in your products. They also make it more likely that they will buy them from your site.

If you have gotten customer contact details, then you can send follow-up emails. Tactful reminders and notifications of deals or price changes can result in easy conversions. Remember that most of the site’s appeal will be visible. You can raise conversion rates even more by making your wish lists visually appealing.

8. Sharing Products

Product sharing is a powerful element for eCommerce platforms. It’s made easy with Magento store design. By sharing products, customers can receive encouragement from friends or help others to find your site. Many eCommerce platforms overlook this feature.

Yet it can raise interest, make your site more engaging, and increase conversion. Sharing can be made more accessible with URL shorteners. Eye-catching buttons are excellent for product sharing. They let customers share without having to copy and paste. You can also provide buttons that allow your customer to share products on social media.

Magento 1.x End of Life is June 2020 (Updated)

Friends, now read carefully, especially those, who owns the online store based on Magento®. A little bird told us (Twitter, to be exact) that a new Age of Magento was nearby. Yes, Magento 2 has all the chances to become the next strong foundation for your super-powerful online store. So you should start considering it as a new eCommerce tool right now.

Magento Tweet. Support Update for Magento 1.x is June 2020
June 2020.
Remember this time. It is when official Magento 1.x support will stop. And Magento 2 continues to conquer the market.

What does this mean for you?

  • You should keep up to date because it will be the complete renewal of the eCommerce market: the new version is a future of technology, as always.
  • The official updates stop. Therefore, the risk of vulnerabilities in the system grows many times in case you use not an updated Magento version. Your website security requires much attention.
  • Magento community works on new extensions for Magento 2. Gradually, the number of modern solutions compatible with the Magento 1.x website will be not enough for your needs, while the number of Magento 2 extensions will increase on a daily basis.
  • You can now check the exact support dates for Open Source and Community (Enterprise) editions and plan when it is better to upgrade your store.

The main ideas you may come up with are the following:

  • If you’re planning to get the eCommerce project developed, you should choose Magento 2 instead of Magento 1.x;
  • If you already have the Magento 1.x based eCommerce business, you can start migrating it to Magento 2.

The questions are: “Why?” and “What are the pros and difficulties you can meet?”

Let’s make it clear.

According to BuiltWith, almost 20% of Magento based websites use Magento 2.x (68,207 websites). That means a significant number of eCommerce business owners have already made their choice on the side of Magento 2.x. Is it the right decision? Let’s consider the pros and other details.

That means most of the eCommerce business owners have already made their choice on the side of Magento 2.x. Is it the right decision? Let’s consider the pros and other details.

The Pros of Migration to Magento 2

Though Magento 2 is not fully-equipped with many useful features that were presented in Magento 1, it’s still much more flexible. There are some features you’ll discover when working with Magento 2:

Increased Flexibility of Magento 2

Magento 2 is super-flexible and extendable when it comes to customization. It includes a lot of features. It’s all because of Magento 2 improved architecture and modular code base that broadens the limits for fast and efficient project development.

Better Management of Magento 2

Now administration of the online store is also more flexible. You can:

  • include links to images and videos to your products;
  • work with the orders better, because you can see the various types of data related to the orders on the Dashboard, (such as lifetime sales, average orders, etc);
  • keep up with analytics (learn about best customers and sellers, view tax rates and quantities);
  • upload new products easily;
  • enjoy the user-friendly interface.

title=”The Benefits of Magento Commerce 2.2 for B2B Business” link=”https://web4pro.net/blog-news/the-benefits-of-magento-commerce-2-2-for-b2b-business/”

Magento 2 API

The huge advantage is that Magento 2 comes with a Rest and SOAP-based API, unlike Magento 1.x. Magento API is a functionality that allows the web developers to integrate Magento with the other third-party services. While Magento 1.x came with a SOAP and XML-RPC based API, it was more difficult to perform integrations: it required the separate configuration of access rights for each user’s role. REST and SOAP had a different business logic. Now, in Magento 2, REST and SOAP business logic is equivalent, and the Magento 2 REST API allows the browsers based access to API calls.

Updating Magento 2 with Composer

It could be a useful feature when you are going to update Magento 2 version. The steps you should make are the following:

  • choose the version you need to upgrade via composer upgrade;
  • run the relevant command;
  • upgrade the database (don’t forget to backup).

Migration to Magento 2: Pitfalls

As you can see, Magento 2 is quite a powerful and even a cool tool. But also, we can’t miss a fly in the ointment. The technical and hosting requirements are very high for Magento 2. Here are some of the most important of them.

Magento 2 Technical Requirements

  • RAM 2GB
  • PHP 5.6
  • MySQL 5.6

Also, if talk about hosting, SSL security certificate is required for HTTPS. SSH access is required for hosting anyway, otherwise, it will be impossible to install new extensions, themes etc.

You can look through the full list of technical requirements here.

The next thing is the cost. It’s not cheap to move from Magento 1.x to Magento 2 if your online store is complicated enough. Additionally, Magento 2 doesn’t support Magento 1 themes. These facts are not very pleasant, right? But we have good news for you: migration to Magento 2 is an easy-going process with an experienced team of Magento developers.

How to Migrate from Magento 1 to Magento 2 and Why?

We, at WEB4PRO, have already completed a lot of Magento 2 based projects. Most of the project involved the task to migrate from Magento 1.x. Of course, this process could be challenging, but we have a lot of experience and effective solutions to perform it at the highest level.

Also, there are several good ready-made modules for migration from Magento 1 to Magento 2. So, it’s possible for sure! Now you are aware of the things that will happen in a year, and you can be completely ready for these changes.

Must-Have Magento 2 B2B Extensions in 2019

Any business owner knows the importance of creating the ultimate user experience. Of course, this is often a challenge when you don’t have the right tools at your disposal. That’s where Magento® comes into play. With Magento 2 B2B extensions, you can increase your sales, leads, and conversions by introducing extensions for pricing, account management, product reorders, and multichannel integration.

Features of Magento 2 B2B for Enterprises

Before we get into specific extensions, here’s a list of Magento 2 B2B features.

Price for Magento 2 B2B

The price options for Magento B2B extension might be the one thing that will determine whether you decide to go with this tool. There are plenty of options on the market, after all, so what makes Magento so special?

Magento B2B provides you with the option of only showing prices to your merchants. This means that if guests want to see prices, they’ll have to become merchants with your online store. This increases conversions and traffic by insisting that people delve deeper into your business to see prices. Beyond this, you can add a custom message for when customers add items to their carts.

Account Management for B2B

Magento B2B extension allows you to develop and absorb more customer information before they become part of your eCommerce site. You should also note that you can add extra fields to your customer registration page to tailor specific information to your store. If you need to know how they heard of you, what their interests are, their annual salary, etc., you can include this from the very beginning.

The benefit of having these extra fields is that you can learn more about your client base; thereby, also allowing you to tailor products, ads, emails, etc., toward each client. There are a few other features of Magento’s B2B Account Management; including, sending emails to accept or reject potential customers, send emails to admins, etc.

Magento 2 Reorder for B2B

Quite simply, reorder function allows customers to save essential time. This B2B extension has a section available called “My reorder product”; wherein, they can look over all of their previous orders to choose the ones they want to reorder. By saving your customers time, you’re ensuring that you care about them providing qualitative service and give them the necessary option to purchase something they like.

Multichannel Integrations in Magento 2 Commerce

Magento B2B offers eCommerce businesses a variety of multichannel integrations. The purpose of these tools and extensions is to provide your store with a greater reach.

Some extensions will ensure that you’re connected to an Amazon or eBay store, while others will connect you to social media platforms. By opening accounts throughout the internet, different customers will be able to find your store, and you’ll see greater conversions.

Top Magento 2 Extensions

Now that you know about Magento’s various B2B features let’s move on to the best B2B extensions.

M2E Pro Amazon and eBay Integration

Let’s begin with the M2E Pro Amazon and eBay integration. A major plus to this extension is that it’s free for those of you who have the enterprise edition.

This extension ensures that you don’t need to use the cloud to back up any files or to share data; instead, everything can be accessed from your Magento 2 interface. While this might not seem like a big deal on the surface, it affects the overall internet security of your sites.

Since you won’t be using the cloud, you don’t have to worry about the security concerns that come with it. Since you’re only operating out of one interface, you have to check the security of that interface; thereby, cutting costs and threats in half.

Multi-User Account Extension for Magento 2 by Creative Minds

This extension allows for customers to create sub-user accounts rather than having to stick with a single one. This extension costs around $200 for the community edition and $400 for the enterprise edition.

Some might find it unnecessary to have a multi-user account, but the major benefit of this is that each sub-user account will have different permissions. You should be aware, though, that sub-user account may have to send their cart for approval depending on their different permissions.

Improved Layered Navigation by Amasty

Improved layered navigation is important unlike any other because it makes the overall design of your eCommerce site more accessible; thereby, allowing customers to browse more freely. This layered navigation provides you with the opportunity to add filters to your menus and for customers to narrow down their desired products.

Here are a few more benefits to using improved layered navigation: no page loading time, better navigation, reviews, custom URLs that can be made to be SEO-friendly, etc.
You should be aware that this extension is quite pricey. Sitting at $639 for the enterprise edition, you’ll find that this is well worth it.

Connect POS by SmartOSC

This free Magento 2 B2B module connects your physical location to your virtual store. That means your data, stock, and other information will be updated in real-time. You don’t have two different product and customer lists; instead, you can keep everything organized within the same platform. This extension allows you to accept orders, payments, deliveries, and more!

Fastly CDN

Fastly is a free marketplace extension that works with a cloud to provide you with increased security and delivery. This will benefit you and your online store because as you customer experience improves, so will your conversions and purchases do.

Remember, the happier your customers are, the more likely they are to return! This tool provides your customers with only the most accurate information.

Reorder Product List by BSS Commerce

Similar to one of the other commerce extensions Magento 2 on this list, reorder product list allows your customers to reorder the products that they want and need. The list that is shown to them provides them with all of the information they need to reorder the products: product image, price, the number of items in stock, etc.

It costs $80, and it could be one of the less expensive features on your list. All your customers have to do is log into their accounts and click on the My reorder product section of the website.

Virtual Reality in Retail: Growing the Potential

The growth of Virtual reality in retail has exploded in recent years. The impact of this technological development on the gaming industry is clear. Perhaps more surprising is the dramatic impact it is having on commerce. Commerce is steadily evolving. The only way to stay competitive is to bring virtual and augmented reality into the business.

With VR and AR, customers can interface with products on a whole new level. Many retail stores are using AR to gamify the customer experience. VR makes shopping more entertaining, engaging, and educational. These technologies are reshaping how we operate as consumers.

The Growth of Virtual Reality in eCommerce

Businesses that rely only on electronic transactions face some disadvantages. Their stores can be open day and night and need no store permits, maintenance, or leasing. Despite this, they still face a lower conversion rate than physical stores. More than ¾ of online shoppers leave a site before finalizing their sale. A recent Retail Dive Consumer Survey found that 62% of consumers prefer physical stores to e-shops. With eCommerce, consumers experience a “touch-feel gap.” Before, online shoppers had to base their decisions upon product descriptions and 2D images. This is limited exposure to the product. It leaves customers without the trust they get from traditional brick-and-mortar shops.

Customers have access to a broader range of products that would be available in physical shops. VR systems can also make product suggestions based on previous selections, streamlining customer experience based on personal preferences. With VR, users can create and customize product combinations. This immersive VR retail experience provides an engaging, distraction-free shopping atmosphere. Best of all, users can shop from anywhere in the world.

Virtual Reality Shopping Experience

VR can make online stores more like physical shops and help to bridge the “trust gap.” Providers in the eCommerce industry rely on current innovation and technology to stay competitive. Virtual reality and Augmented reality are the height of this new technology.

Lowe’s is one company at the forefront of the virtual revolution. The Lowe’s Holoroom is a virtual feature that allows customers to visualize home improvement projects. Users can design and customize the interior of any room in their home with a tablet. After they design the room, they can view it in the Holoroom with a VR headset. Once the design is finalized, customers are given a Google Cardboard VR headset which can link to any smartphone.

Virtual Reality Fashion

Virtual reality has been big in the world of fashion. Charlotte Tilbury created a sensation with the first ever VR perfume ad. Tommy Hilfiger and other brands are offering another immersive fashion experience. These fashion retailers use VR to give customers a virtual runway experience. This brings more customers into physical shops and heightens interest in their products. As we can see, there are countless ways that VR can enhance the retail fashion experience.

NYT VR

The New York Times brought Virtual reality into journalism when it launched Daily 360 VR News. It is accessible through NYTimes.com and mobile and VR apps. This app was massively well received. More than 700 users shared their personal virtual experience via Instagram. The average viewing time was 14.7 minutes, and 92% of videos were viewed in Cardboard mode. An added benefit to this approach is that the experience is compelling even without a Cardboard viewer. This makes it more accessible to those that haven’t caught up with the trend.

Dior

Dior is another company providing an innovative virtual experience. Rather than offering a traditional runway show, Dior has created a backstage virtual experience. Users can go behind the scenes at a fashion show and observe a professional makeup artist at work, getting cosmetic tips and techniques. Dior teamed with DigitasLBi Labs in France to create a proprietary VR headset, Dior Eyes. The brand has introduced this technology to select stores worldwide in June.

How to Use Augmented Reality in eCommerce?

Augmented Reality is simpler than VR and more accessible with current technology. This technology shows users an image of the world around them, but with virtual elements added to it. Rather than creating an entire immersive world, Augmented reality is used to enhance existing reality.

Augmented Commerce

AR is already being used to enhance the traditional retail experience in many ways. Major clothing retailers offer AR fitting rooms. Customers can try virtual makeup, accessories, clothing, and hairstyles before making a selection. This offers customers “try before you buy” appeal, as well as a bit of engagement and fun. Many retailers use AR to increase product visualization. Customers can get extra information about products with these systems. AR can also provide customers with promotions, contests, and targeted product selection. Let’s see who is implementing AR to attract customers and expand the business.

IKEA Solution

IKEA is another company that has taken advantage of the VR/AR revolution. On the Virtual Reality level, VR pop-up booths allow customers to browse a digital showroom. Users can explore furniture combinations and virtual design rooms. They can also explore different wall colors, fabrics, color schemes, and light levels. IKEA has featured this virtual experience in-store in Berlin and pop-up booths in Kuwait, Morocco, and Jordan. These are intended to enhance customer engagement and boost foot traffic to their physical shops. The Kuwait IKEA store has seen a 19% increase in foot traffic since the installation.

Alibaba VR Shopping

Alibaba is another retailer on top of the VR trend. Alibaba offers inexpensive ($0.15) Cardboard VR viewers which pair with any smartphone. These give access to a virtual mall with thousands of products. One benefit of this approach is that the VR mall can feature products without physical stores at a customer’s location. This allows retailers to reach a wider audience. Users can make real-time purchases with a look using AliPay. Customers can also use the VR interface to pick up objects and examine them with a 360-degree view. Alibaba has used this technology to gamify shopping. Customers receive virtual promotions and contests available only to AR users.

Sephora’s Augmented Reality

Sephora has become yet another leader in the AR world. They offer iPhone-accessible technology that allows users to test makeup digitally. Sephora’s Visual Arts App uses real-time facial recognition software to allow customers to try out a wide range of cosmetics. Visual Arts transforms an iPhone or iPad into an AR mirror that shows the effect of cosmetic products. It also offers product recommendations and makeup tutorials.

Product Visualization

Product visualization is one huge benefit of VR for eCommerce. It helps to boost marketing, improve brand recognition, and grow the business itself. VR is the new generation of product visualization. With it, customers can explore the interior of a device, design the interior of their home, or showcase their merchandise for a client. Let’s have a look at some companies who have implemented it with great success.

eBay

eBay has taken an innovative step into the realm of VR commerce. They have paired with Myer to create the first immersive VR department store app. This app lets users view an extensive selection of products from anywhere in the world. It also offers smart product recommendation. The app observes your choices and adapts future recommendations to your preference. It works with Samsung’s Gear VR. However, eBay has made it accessible to those without an expensive viewer. They offer Google Cardboard viewers called “shopticals” which can be paired with any smartphone. eBay has given out more than 20,000 free shopticals to customers, making their virtual store more accessible. To top it off, shopticals sell for $0.15, so customers face little to no barrier by hardware.

ARkit Apple

Another recent development in AR is Apple’s recent release of ARkit Apple. This software development tool allows developers to make AR apps for iPads and iPhones. These apps can allow users to place virtual objects in the physical world and interact with them by looking at them in the device display. The app works with Apple’s visual odometry sensors to track the orientation and relative position of the device. With a new tool, it is easier than ever to create AR technologies which are accessible to anyone with an iPhone or iPad.

Are AR and VR Thing for the Future?

The growth of Virtual reality has been steadily increasing. There is no doubt that this technology will become mainstream soon. AR/VR technology attracts more customers into the store. It provides greater immersion for shoppers and makes brands available to a wider customer base. In the coming years, anyone trying to sell without virtual technology will be at a less advantage.

Hardware is the largest challenge currently faced by Virtual and Augmented reality. Though the industry is estimated at 4$ billion by the end of 2018, only about 5% of North Americans own VR viewers. This trend is likely to change in the coming years. Virtual reality headsets and technology are now more popular than tablets. Experts expect the virtual technology market to reach 143$ billion within the next two years.

Perhaps Jeff Booth said it best: “Interaction leads to immersion, and immersion leads to conversion.” In a digital market, brands that offer the most interaction will see the highest payoff. The takeaway? Virtual and augmented technology will be to the next generation what smartphones have been to this one. The wise retailer will explore the best ways to make use of VR and AR in their business.

Resolving Magento 2 Extension Conflict Between Amasty_Shopby and Amasty_Scroll

Magento® 2 developers usually try to choose extensions from a single creator so no conflicts arise between them. But what should you do if a conflict still arises where it shouldn’t? Today we will consider this situation as we have experienced it. We will show how to resolve Magento 2 extension conflict between two Amasty modules. Navigate using the list below:

Suppose there’s a site on Magento 2. It should support the AJAX filtration and infinite scrolling on products listing using AJAX (henceforth referred to as Infinite Scroll).

Amasty Modules Chosen

We chose extensions from Amasty to implement both functionalities: Improved Layered Navigation (Amasty_Shopby) and Infinite Scroll (Amasty_Scroll). We chose these extensions from the same developer on the basis of minimizing conflicts between them, since they affect the same pages: product listings.

Magento Extension Conflict Issues

When testing the site, a problem was identified in the listing. The Amasty Ajax Scroll extension places the following block in the footer:

<div class="amscroll-navbar" id="amscroll-navbar" style="background: #3A4F62;"><span class="amscroll-navbar-text">PAGE <span id="amscroll-navbar-current">1</span> of 15</span><a class="amscroll-navbar-link"></a></div>

This block has a fixed position and lets users know how many pages of products were loaded. If the category or search result returns only one page, the block shouldn’t be shown.

If the aforementioned situation occurred when a filter was applied using AJAX (for example, if a customer wanted to browse only products that are the color black and the results fit on just one page), then this block remained in the browser window, which confused users.

This had to be fixed, and we set out analyzing the code of both modules. Both modules for calling and processing Ajax requests implement jQuery widgets. jQuery widgets are Javascript objects with Function() type. The modules are synchronized in the following way.

mage.amScrollScript widget from Amasty_Scroll has the following constructor:

_create: function (options) {
    var self = this;
    $(document).on( "amscroll_refresh", function() {
        self._initialize();//run jQuery(document).trigger('amscroll_refresh');
    });
    this._initialize();
}

In Amasty_Shopby extension widgets, the”amscroll_refresh” event is called when processing AJAX response, but in Amasty_Scroll this event is processed by reinitialization of the whole widget.

So why doesn’t deleting the block from the footer take place when processing this event?

We got the answer to this question after carrying out the analysis of _initialize() method and the widget code.

_initialize: function () {
    this.next_data_cache = "";
    this.pagesLoaded = [];
    this._initPagesCount();
    this.disabled = 1;
    var isValidConfiguration = this._validate();
    if (!isValidConfiguration) {
        return;
    }
    this.disabled = 0;
    this.type = this.options['actionMode'];
    this._preloadPages();
    this._hideToolbars();
    var self = this;
    $(window).scroll(function() {
        self._initPaginator();
    });
    setTimeout(function(){
        self._initPaginator();
    }, 7000);
    this._initProgressBar();
},
….
_validate: function () {
    if(!this.options['product_container']
        || $(this.options['product_container']).length === 0
    ){
        console.log('Please specify "Products Group" Dom selector in module settings.');
        return false;
    }
    if (this.pagesCount <= 1) {
        return false;
    }
    return true;
},
...
_initProgressBar: function () {
    if (this.options['progressbar'] && this.options['progressbar']['enabled'] == '1') {
        var progressbar = jQuery('<div/>', {
            class: 'amscroll-navbar',
            id   : 'amscroll-navbar',
            style: this.options['progressbar']['styles']
        });
        var text = this.options['progressbarText'];
        text = text.replace('%1', '<span id="amscroll-navbar-current">'   this.currentPage   '</span>');
        text = text.replace('%2', this.pagesCount);
        progressbar.append('<span class="amscroll-navbar-text">'   text   '</span>');
        var linkElement = jQuery('<a/>', {
            class: 'amscroll-navbar-link'
        });
        linkElement.click(function(){
            $('body, html').animate({
                scrollTop: 0
            }, 300);
        });
        progressbar.append(linkElement);
        $("body").append(progressbar);
    }
}<

As you can see, the _initProgressBar method generates the aforementioned block and is called from the _initialize() method. However, _initProgressBar will not be called if the number of pages is equal to 1. This is verified in the _validate() method. The code for deleting the block created when applying an Ajax filter from Amasty_Shopby was not provided in the mage.amScrollScript widget. Amasty must correct this mistake.

Solving Amasty Module Conflicts in Magento 2

Mixin should be used for customizing Magento 2 jQuery widgets without rewriting the original widgets. We will declare it in the requirejs-config.js module file.

var config = {
    config:{
            mixins:{
                "Amasty_Scroll/js/amscroll":{
                    "Web4pro_Ajax/js/amscroll":true,
            }
        }
    },
...
}

Then we implement the mixin. We think it should be done as follows:

define([
    "jquery"
], function ($){
    return function (widget) {
        widget.prototype._initialize =function(){
                this.next_data_cache = "";
                this.pagesLoaded = [];
                this._initPagesCount();
                this.disabled = 1;
                var isValidConfiguration = this._validate();
                if (!isValidConfiguration) {
                    $('.amscroll-navbar').each(function(){
                        this.parentElement.removeChild(this);
                    })
                    return;
                }
                this.disabled = 0;
                this.type = this.options['actionMode'];
                this._preloadPages();
                this._hideToolbars();
                var self = this;
                $(window).scroll(function() {
                    self._initPaginator();
                });
                setTimeout(function(){
                    self._initPaginator();
                }, 7000);
                this._initProgressBar();
            };
    }
});

If the number of pages is equal to 1, all blocks with the amscroll-navbar class will be deleted from the DOM page. But this mixin won’t work, since the widget always has the NULL value. This is because Amasty implemented the mage.amScrollScript widget based on jQuery standards, not Magento 2 standards. If the widget was implemented based on Magento 2 standards, it would return a self-pointer using:

return $.mage.amScrollScript;

This is not seen in the code of the mage.amScrollScript widget. But a solution to this problem does exist, and it looks as follows:

define([
    "jquery"
], function ($){
    return function (widget) {
        $.mage.amScrollScript.prototype._initialize =function(){
                this.next_data_cache = "";
                this.pagesLoaded = [];
                this._initPagesCount();
                this.disabled = 1;
                var isValidConfiguration = this._validate();
                if (!isValidConfiguration) {
                    $('.amscroll-navbar').each(function(){
                        this.parentElement.removeChild(this);
                    })
                    return;
                }
                this.disabled = 0;
                this.type = this.options['actionMode'];
                this._preloadPages();
                this._hideToolbars();
                var self = this;
                $(window).scroll(function() {
                    self._initPaginator();
                });
                setTimeout(function(){
                    self._initPaginator();
                }, 7000);
                this._initProgressBar();
            };
    }

This alteration successfully deletes the block with the page number from the DOM page when it’s needed.

Magento 2 Issues: Detected and Solved

Magento® 2 claims to be one of the best eCommerce solutions on the market, as far as the company decided to stop the support of the first Magento version. But what about the changes? Is Magento still powerful or even became much better?

Well, opinions differ. Someone will tell you that Magento 2 is the best eCommerce platform they have ever worked with. Someone will say with a pinch of salt that this platform lacks lots of available functionalities, and its new architecture is odd. Both sides are right partly.

We are here to reveal some technical Magento 2 issues. We’ll discuss how you can cope with them as our team has already done. Sit back, make a cup of tea, and run PhpStorm.

Let’s take control of Magento 2 code together!

Table of Contents

Magento 2 Configuration Issues

Before we start criticizing Magento 2, we should admit that it’s still very flexible and powerful. As it has the new architecture, it calls for new approaches in web development. For example, some customization features that were included out-of-box in the first version now are not available. So we, web developers, need to come up with creative ideas and implement customizations in Magento 2 admin panel ourselves. Let’s look into some of them we’ve already faced.

Navigate to the issue:

Displaying Swatch Attribute of Dropdown Type in Magento 2.2
Configuring Adding Items to Admin Panel Menu in Magento 2.2.0
Displaying the Shopping Cart Content on the Customer View Page in Magento 2 CE
Dealing with Ineffective addAttribute() Method for Customizing Product Listings

Displaying Swatch Attribute of Dropdown Type in Magento 2.2

Problem: We detected the issue with displaying swatch attribute of drop-down type on the product listing page in Magento 2.2. It happens when the attribute of this type configures the configurable product. The issue arises because Magento\Swatches\Block\Product\Renderer\Listing\Configurable block will be output if only the product contains swatch attributes.

  protected function _toHtml()
    {
        $output = '';
        if ($this->isProductHasSwatchAttribute()) {
            $output = parent::_toHtml();
        }

        return $output;
    }

Check the solution

1. Redefine Magento_Swatches::product/listing/renderer.phtml template and set “onlySwatches” option to “false”. It will allow for displaying the swatch attribute of drop-down type on the product listing page.

2. Using frontend/di.xml, redefine SwatchAttributesProvider for Magento\Swatches\Block\Product\Renderer\Listing\Configurable block:

<type name="Magento\Swatches\Block\Product\Renderer\Listing\Configurable">
        <arguments>
            <argument name="swatchAttributesProvider" xsi:type="object">Web4pro\ExtendedSwatch\Model\SwatchAttributesProvider</argument>
        </arguments>
    </type>

3. In Web4pro\ExtendedSwatch\Model\SwatchAttributesProvider class, implement provide() method. In this method, in case the product has no swatch attributes, an additional check for the other  configurable attribute availability will run:

/**
     * @param Product $product
     * @return bool
     */
    public function provide(Product $product)
    {
        $result = parent::provide($product);
        if (empty($result)) {
            $attributes = $this->typeConfigurable->getConfigurableAttributes($product)->getItems();
            $result = count($attributes) > 0;
        };
        return $result;
    }

This approach helps to avoid changes in the whole Magento\Swatches\Block\Product\Renderer\Listing\Configurable class.

Configuring Adding Items to Admin Panel Menu in Magento 2.2.0

Problem: In Magento 2, you can configure adding items to the admin panel menu. In a nutshell, you can add items depending on specific configurations or modules. Here is how it looks like:

<menu>
   <add id="Web4pro_Extended::invoice" title="Invoices" module="Web4pro_Extended" sortOrder="20"
        parent="”
action="web4pro_extended/invoice/index"
        resource="Web4pro_Extended::invoice"
        dependsOnConfig="web4pro_extended/general_settings/enable"
        dependsOnModule=””
/>
</menu>

So that, dependsOnConfig sets the dependency on the configuration, and
dependsOnModule sets dependency on the module. But in Magento 2.2.0, this functionality doesn’t work.

Solution: Implement afterRead() plugin for \Magento\Backend\Model\Menu\Config\Reade class and run necessary checks in this method.

Displaying the Shopping Cart Content on the Customer View Page in Magento 2 CE

Problem: In Magento 2 Commerce, the content of the user’s shopping cart is not displayed on the customer view page.

Check the solution

We can provide the display of a customer shopping cart the following way. First, we should add the separate tab on the customer view page. Let’s implement customer_index_edit.xml layout file in the module. It should have the following content.

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_form">
            <block class="Web4pro\Login\Block\Cart" name="shopping_cart" />
        </referenceBlock>
    </body>
</page>

And a block class:

class Cart extends TabWrapper implements TabInterface {

    /**
     * Core registry
     *
     * @var Registry
     */
    protected $coreRegistry = null;

    /**
     * @var bool
     */
    protected $isAjaxLoaded = true;

    /**
     * Constructor
     *
     * @param Context $context
     * @param Registry $registry
     * @param array $data
     */
    public function __construct(Context $context, Registry $registry, array $data = [])
    {
        $this->coreRegistry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * @inheritdoc
     */
    public function canShowTab()
    {
        return $this->coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
    }

    /**
     * Return Tab label
     *
     * @return \Magento\Framework\Phrase
     */
    public function getTabLabel()
    {
        return __('Manage Shopping Cart');
    }

    /**
     * Return URL link to Tab content
     *
     * @return string
     */
    public function getTabUrl()
    {
        return $this->getUrl('customer/*/carts', ['_current' => true]);
    }
}

These actions will help you to add Manage Shopping Cart tab on the Customer View Page and allow loading its content with AJAX. Then implement customer_index_edit.xml layout file with the content:

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <referenceContainer name="root">
        <block class="Magento\Catalog\Block\Adminhtml\Product\Composite\Configure" name="customer.carts.product.configure" before="admin.customer.carts"/>
    </referenceContainer>
</layout>

This code is used to provide the administrator with an ability to reconfigure the products with options in the shopping cart.

Dealing with Ineffective addAttribute() Method for Customizing Product Listings

Problem: When customizing Magento, you often need to add a custom product attribute to a product listing. With Magento 1, you do this by using the addAttribute method of the Mage_Catalog_Block_Product_List class. Its equivalent in Magento 2 to add product custom attribute, use \Magento\Catalog\Block\Product\ListProduct\, inherited this method, and its implementation is simple enough.

public function addAttribute($code)
{
    $this->_getProductCollection()->addAttributeToSelect($code);
    return $this;
}

In Magento 1, the primary way of customizing outputs was to insert your code blocks using layout. Its only shortcoming was that if using flat index tables for a collection of products on the frontend, the required field could be unavailable if the attribute visibility was not set in the product listing.

In Magento 2.0 and Magento 2.1, you could continue using this method, but it’s strongly discouraged starting with version 2.2.

Check the solution

As you can see below, this method requests a collection of products using _getProductCollection and adds the $code attribute to the request. But the implementation of this method changed entirely in Magento 2.2. It looks as follows.

protected function _getProductCollection()
{
    if ($this->_productCollection === null) {
        $this->_productCollection = $this->initializeProductCollection();
    }
    return $this->_productCollection;
}

InitializeProductCollection() method will appear. Let’s look at its implementation.

private function initializeProductCollection()
{
    $layer = $this->getLayer();
    /* @var $layer \Magento\Catalog\Model\Layer */
    if ($this->getShowRootCategory()) {
        $this->setCategoryId($this->_storeManager->getStore()->getRootCategoryId());
    }
    // if this is a product view page
    if ($this->_coreRegistry->registry('product')) {
        // get collection of categories this product is associated with
        $categories = $this->_coreRegistry->registry('product')
            ->getCategoryCollection()->setPage(1, 1)
            ->load();
        // if the product is associated with any category
        if ($categories->count()) {
            // show products from this category
            $this->setCategoryId(current($categories->getIterator())->getId());
        }
    }
    $origCategory = null;
    if ($this->getCategoryId()) {
        try {
            $category = $this->categoryRepository->get($this->getCategoryId());
        } catch (NoSuchEntityException $e) {
            $category = null;
        }
        if ($category) {
            $origCategory = $layer->getCurrentCategory();
            $layer->setCurrentCategory($category);
        }
    }
    $collection = $layer->getProductCollection();
    $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());
    if ($origCategory) {
        $layer->setCurrentCategory($origCategory);
    }
    $toolbar = $this->getToolbarBlock();
    $this->configureToolbar($toolbar, $collection);
    $this->_eventManager->dispatch(
        'catalog_block_product_list_collection',
        ['collection' => $collection]
    );
    return $collection;
}

This doesn’t seem out of the ordinary. But we can observe that the catalog_block_product_list_collection event is dispatched. Dispatching this event loads the collection and several additional entities to it, such as aggregated information about user reviews and the other.

In this case, the collection is loaded, but layered navigation filters, for example, cannot be applied to it, and the filter blocks themselves won’t be displayed on the frontend. Of course, the attribute will not be added to select, since the collection is already loaded. The method has become not only useless but quite harmful.

Why didn’t Magento declare it deprecated in version 2.2?

Problem: Our theory is that Magento left it for the case when a product collection is not taken from the $layer object but is set to the block by the setCollection method. This doesn’t happen on category pages or regular search pages, but at the moment it’s still on advanced search pages. However, the advanced search wasn’t prevalent on the majority of live Magento 1 sites, and it’s practically not used at all on Magento 2. Note that this problem didn’t exist until version 2.2 since the event mentioned above was dispatched in the block’s _beforeToHteml method, and this didn’t cause any problems.

We will now examine alternative solutions that we can apply in Magento 2.2.

Check the solution

First, you need to set the visibility options on the product listing to the required product attributes for display. This will be sufficient to load the attribute both when using an EAV collection or a Flat. Another method, which will only work when using an EAV product collection on the frontend, is to set a plugin for classes Magento\Catalog\Model\Layer\Category\CollectionFilter and Magento\Catalog\Model\Layer\Search\CollectionFilter.

The first plugin will work for the category page, and the second will work for the search results page. The beforeFilter method must be implemented in the plugin, and its input parameters will be the product collection and current category (an empty object for search pages). You can carry out any operations with the collection that do not require its download. Of course, if you use a flat product collection, an attribute for which no input parameter was set on the listing will not be in the collection. But more complex cases are possible.

Suppose the product has two attributes: name and seo_product_name. On the listing, you must enter the seo_product_name as the name, if it is not empty. Otherwise, enter the name. Also, you must resort by name to account for entering the product name on the listing. To do this, we implement the plugin mentioned above in the following way.

public function beforeFilter($model,$collection,$category){
    if(!$collection->isEnabledFlat()){
        $collection->addExpressionAttributeToSelect('seo_name',
            'IF({{seo_product_name}} is NULL,{{name}},{{seo_product_name}}',
            array('name','seo_product_name'));
    }else{
        $collection->getSelect()->columns(array('seo_name'=>'IF(seo_product_name is NULL,name,seo_product_name)'));
    }
    return array($collection,$category);
}

    $toolbar = $this->getToolbarBlock();
    $this->configureToolbar($toolbar, $collection);
    $this->_eventManager->dispatch(
        'catalog_block_product_list_collection',
        ['collection' => $collection]
    );
    return $collection;

As you can see, we have added the seo_name field in the query result, allowing for both EAV collections or Flat. Now you need to change sorting by name to sorting by added field.

This is not difficult since Magento 2 uses a collection of the Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection class in both search listings and category listings. Sometimes, when using various third-party modules, the collection could be replaced. For example, with the installed Amasty_Shopby module the collection class will be Amasty\Shopby\Model\ResourceModel\Fulltext\Collection. In any case, the plugin that will implement two methods must be set to the collection class:

public function beforeSetOrder($subject,$field,$direction){
     if($field == 'name'){
        $field = 'seo_name';
    }
    return array($field,$direction);
}
public function beforeAddAttributeToSort($collection,$attribute,$dir){
    if($attribute == 'seo_name'){
        $collection->getSelect()->order($attribute.' '.$dir);
    }
    return array($attribute,$dir);
}

Outputting the attribute on the product listing page is outside the scope of this article. I will say that this can be done by transferring the list.phtml template to the theme and customizing the template further, or by changing the template in the module.

If someone should decide to use the advanced search, then you can customize the collection for them the same way, only using the plugin in the Magento\CatalogSearch\Model\Advanced class. You will need to implement the beforePrepareProductCollection($model,$collection) method in this plugin, in which you will be able to carry out any available operation with the collection besides loading it. True, you will have to keep in mind that advanced search uses the collection Magento\Catalog\Model\ResourceModel\Product\Collection.

Plugins for it should only be set on the scope frontend so as not to break the administrator panel, and they should be set accounting for the use of the collection in cart and checkout functionalities, as well as in other places where it can be used. You may also need to obtain additional information about the environment to ensure that the advanced search product collection is being used. We will not examine this matter in detail in this article since advanced search is rarely used on live sites.

Now let’s move on to the next section with migration issues.

Migration is quite essential since you won’t lose your previous data and analytics and start with the new version of the store keeping everything that you were working on before. Use our navigation plan below and find the answer that you need.

Problems of Migrating Data from Magento 1 to Magento 2

When switching from the first Magento to the second, the issue arises of transferring already existing data from Magento 1 to Magento 2. The data storage format in a Magento 2 database is different from the storage format in Magento 1. Also, the storage format can differ slightly across different versions of Magento 2. We will be examining problems encountered during migration and ways to solve them.

Tool: UberTheme Migration Tool

UberTheme has implemented a special tool for transferring the built-in entities of Magento 1 to Magento 2, which is called the UberTheme Migration Tool. This tool is a Magento 2 module, which has a part implemented using Yii, including a graphic web interface and data-transfer functionality.

This part is located in the module’s lib directory and during installation will be transferred to the pub/ub_tool directory. Initial versions of this expansion used an SQLite database to store temporary data, but later versions create the particular tables right in the Magento database. This allows for the transferring from Magento 1 to Magento 2 the information about:

  • sites, stores, and store views (except configuration parameters);
  • EAV entities and attributes, attribute sets, etc.;
  • categories and products;
  • users, including saved addresses;
  • users’ carts, orders placed, payments, invoices, deliveries, and returns, as well as pricing rules for carts and aggregated information about purchases (for reporting);
  • core entities (reviews, wishlists).

Process: working with UberTheme Migration Tool

To work with this module, you must configure the Magento 2 database in the pub/ub-tool/protected/config/db.php file and open the module page in the admin panel. There, you can configure access to the Magento 1 database and the specifics of migration at various stages.

After initiating migration, you can address discrepancies at any stage. It is especially pertinent to information about users or orders.

When the data storage format is changed by a Magento 2 version update, UberTheme Migration Tool updates, too. For example, before Magento 2.2, options for products in orders were stored as a serialized array. This information is stored in JSON starting with version 2.2.

Requirements: You must use the version of the UberTheme Migration Tool that is compatible with your version of Magento 2 (for Magento 2.2, this is UberTheme Migration Tool version 3.1.2). Even so, problems could arise, which are examined below.

Navigate to the issue:

Migration of Magento Using Composer and Set up 2.2 Version
Migration with Ubertheme Migration Tool 3.1.2 and Magento 2.1
Rollback of Changes in the Magento 2 Database After Migration
Migration When It Is Combined with the Merging of Different Sites
Migration of Configurable Products with Custom Attributes
Merging Sites on the Same Host
Migration in a Local Environment with Transfer to Stage or Pre-Production Using Git
Problems with Categories in the Database When Migration Errors Occur

Migration of Magento from an Earlier Version Using Composer and Set up 2.2 Version Using Migration Tool 3.1.2.

Problem: Options for a product in an order may be incorrectly copied during migration (for example, in JSON instead of as a serialized array). This causes the pages for viewing orders in the admin panel to crash.

Cause: During the update, only the version of the core, and not the variable “version,” was updated in the composer.json file.

Check the solution

Solution: The UberTheme Migration Tool determines the M2 version from the variable “version” in the composer.json file, as you can see by the method in the UbMigrate class.

The variable must be updated.

public static function getM2Version()
{
    $version = '';
    $composerFile = Yii::app()->basePath . "/../../../composer.json";
    if (file_exists($composerFile)) {
        $data = @file_get_contents($composerFile);
        $data = json_decode($data);
        if (isset($data->version)) {
            $version = trim($data->version);
        }
    }
    return $version;
}

Migration with UberTheme Migration Tool 3.1.2 and Magento 2.1

Problem: Existing users’ carts may be broken.

Cause: During migration, product options info_buyRequest are serialized into JSON without checking the Magento 2 version. It is a mistake on the part of UberTheme developers.

Check the solution

private function _convertQuoteItemOptionCodeValue($productId2, &$optCode, &$optValue, $keepProductId)
{
    //convert to Magento 2 code and value
    if ($optCode == 'info_buyRequest') {
        $buyRequest = unserialize($optValue);
        //simple
        if (!$keepProductId AND isset($buyRequest['product']) AND $buyRequest['product']) {
            $buyRequest['product'] = UBMigrate::getM2EntityId(5, 'catalog_product_entity', $buyRequest['product']);
        }
        //bundle
        if (!$keepProductId AND isset($buyRequest['bundle_option']) AND $buyRequest['bundle_option']) {
            $bundleOption = [];
            $bundleOptionQty = [];
            foreach ($buyRequest['bundle_option'] as $optionId => $selectionId) {
                $optionId2 = UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_option', $optionId);
                if (is_array($selectionId)) {
                    foreach ($selectionId as $key => $sltId) {
                        if ($sltId) {
                            $bundleOption[$optionId2][$key] =  UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_selection', $sltId);
                        }
                    }
                } else {
                    if ($selectionId) {
                        $bundleOption[$optionId2] = UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_selection', $selectionId);
                    }
                    if (isset($buyRequest['bundle_option_qty'][$optionId])) {
                        $bundleOptionQty[$optionId2] = $buyRequest['bundle_option_qty'][$optionId];
                    }
                }
            }
            $buyRequest['bundle_option'] = $bundleOption;
            $buyRequest['bundle_option_qty'] = $bundleOptionQty;
        }
        //downloadable
        if (!$keepProductId AND isset($buyRequest['links']) AND $buyRequest['links']) {
            $links2 = [];
            foreach ($buyRequest['links'] as $key => $linkId) {
                $links2[$key] = UBMigrate::getM2EntityId('5_product_download', 'downloadable_link', $linkId);
            }
            $buyRequest['links'] = $links2;
        }
        //configurable
        if (isset($buyRequest['super_attribute']) AND $buyRequest['super_attribute']) {
            $superAttribute = [];
            foreach ($buyRequest['super_attribute'] as $attributeId => $attributeOptionId) {
                $attributeId2 = isset($mappingAttributes[$attributeId]) ? $mappingAttributes[$attributeId] : null;
                $superAttribute[$attributeId2] = UBMigrate::getM2EntityId('3_attribute_option', 'eav_attribute_option', $attributeOptionId);
            }
            $buyRequest['super_attribute'] = $superAttribute;
        }
        //virtual
        if (!$keepProductId AND isset($buyRequest['options']) AND $buyRequest['options']) {
            $options2 = [];
            foreach ($buyRequest['options'] as $productOptionId => $value) {
                if (is_numeric($productOptionId)) {
                    $productOptionId2 = UBMigrate::getM2EntityId('5_product_option', 'catalog_product_option', $productOptionId);
                    $options2[$productOptionId2] = $value;
                } else {
                    $options2[$productOptionId] = $value;
                }
            }
            //re-update
            $buyRequest['options'] = $options2;
        }
        //re-update value
        //$optValue = serialize($buyRequest);
        $optValue = UBMigrate::encodeJson($buyRequest); // this was changed from Magento ver.2.2.0
    } elseif ($optCode == 'attributes') {
        $values = unserialize($optValue);
        foreach ($values as $attributeId => $attributeOptionId) {
            $attributeId2 = isset($mappingAttributes[$attributeId]) ? $mappingAttributes[$attributeId] : null;
            $values[$attributeId2] = UBMigrate::getM2EntityId('3_attribute_option', 'eav_attribute_option', $attributeOptionId);
        }
        //$optValue = serialize($values);
        $optValue = UBMigrate::encodeJson($values); // this was changed from Magento ver.2.2.0
    } elseif (substr($optCode, 0, 12) == 'product_qty_') {
        $optCode = "product_qty_{$productId2}";
    } elseif ($optCode == 'simple_product') {
        $optValue = $productId2;
    } elseif ($optCode == 'parent_product_id') {
        $optValue = (!$keepProductId) ? UBMigrate::getM2EntityId(5, 'catalog_product_entity', $optValue) : $optValue;
    } elseif (substr($optCode, 0, 14) == 'selection_qty_') {
        $selectionId = substr($optCode, 14);
        if (is_numeric($selectionId)) {
            $selectionId = (!$keepProductId) ? UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_selection', $selectionId) : $selectionId;
            $optCode = "selection_qty_{$selectionId}";
        }
    } elseif (!$keepProductId AND $optCode == 'bundle_identity') {
        $values = explode('_', $optValue);
        $values[0] = $productId2;
        foreach ($values as $key => $value) {
            if ($value AND ($key % 2 == 1)) {
                $values[$key] = UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_selection', $value);
            }
        }
        $optValue = implode('_', $values);
    } elseif ($optCode == 'bundle_option_ids') {
        $values = unserialize($optValue);
        foreach ($values as $key => $bundleOptionId) {
            $bundleOptionId = (!$keepProductId) ? UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_option', $bundleOptionId) : $bundleOptionId;
            $values[$key] = $bundleOptionId;
        }
        //$optValue = serialize($values);
        $optValue = UBMigrate::encodeJson($values); // this was changed from Magento ver.2.2.0
    } elseif ($optCode == 'bundle_selection_ids') {
        $values = unserialize($optValue);
        foreach ($values as $key => $bundleSelectionId) {
            if ($bundleSelectionId) {
                $bundleSelectionId = (!$keepProductId) ? UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_selection', $bundleSelectionId) : $bundleSelectionId;
                $values[$key] = $bundleSelectionId;
            }
        }
        //$optValue = serialize($values);
        $optValue = UBMigrate::encodeJson($values); // this was changed from Magento ver.2.2.0
    } elseif (!$keepProductId AND $optCode == 'selection_id') {
        if ($optValue) {
            $optValue = UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_selection', $optValue);
        }
    } elseif ($optCode == 'bundle_selection_attributes') {
        $values = unserialize($optValue);
        if (isset($values['option_id']) AND $values['option_id']) {
            $values['option_id'] = (!$keepProductId) ? UBMigrate::getM2EntityId('5_product_option', 'catalog_product_bundle_option', $values['option_id']) : $values['option_id'];
        }
        //$optValue = serialize($values);
        $optValue = UBMigrate::encodeJson($values); // this was changed from Magento ver.2.2.0
    } elseif ($optCode == 'downloadable_link_ids') {
        $values = explode(',', $optValue);
        if ($values) {
            foreach ($values as $key => $value) {
                if (is_numeric($value)) {
                    $values[$key] = (!$keepProductId) ? UBMigrate::getM2EntityId('5_product_download', 'downloadable_link', $value) : $value;
                }
            }
            //$optValue = implode(',', $values);
            $optValue = UBMigrate::encodeJson($values); // this was changed from Magento ver.2.2.0
        }
    } elseif ($optCode == 'option_ids') {
        $values = preg_split('/,\s*/', $optValue);
        if ($values) {
            foreach ($values as $key => $value) {
                if (is_numeric($value)) {
                    $values[$key] = (!$keepProductId) ? UBMigrate::getM2EntityId('5_product_option', 'catalog_product_option', $value) : $value;
                }
            }
            //$optValue = implode(',', $values);
            $optValue = UBMigrate::encodeJson($values); // this was changed from Magento ver.2.2.0
        }
    } elseif (!$keepProductId AND substr($optCode, 0, 7) == 'option_') {
        $productOptionId = (int)substr($optCode, 7);
        $optCode = "option_" . UBMigrate::getM2EntityId('5_product_option', 'catalog_product_option', $productOptionId);
        if (is_numeric($optValue)) {
            $optValue = UBMigrate::getM2EntityId('5_product_option', 'catalog_product_option_type_price', $optValue);
        }
    }
    return true;
}

Rollback of Changes in the Magento 2 Database After Migration

Problem: In some cases, dependent entities (for example, product attributes) are incorrectly assigned, or you can get the 500 internal server error during migration requests.

Solution: contents of the directory pub/ub-tool/protected/runtime/cache must be deleted. The cache of dependencies is stored in this directory.

Migration When It Is Combined with the Merging of Different Sites

Problem: Attributes will be incorrectly assigned if data has been migrated from site A and you would like to migrate data from site B on the same Magento 2 host, but the websites are different.

Solution: not only must the cache be cleared, but the Ubertheme tables in Magento 2 must also be cleared, so that the entities from site B do not get mixed up with the objects from site A due to overlapping numeric identifiers in tables.

However, there are several issues with dependencies that UberTheme migration module cannot solve.

Migration of Configurable Products with Custom Attributes

Problem: Magento 1 has configurable products with the custom attribute default_product_id. By default, it stores the identifier of the product option. During migration, the value of this attribute will be transferred “as is,” but the identifiers of the products in the Magento 2 database will be different. This leads to inconsistencies in the data.

Solution: Dependencies between products of the form SKU=>SKU must be exported from the Magento 1 database to a CSV file, and then imported using the Magento 2 API.

Merging Sites on the Same Host

Problem: Products on sites A and B have identical SKU but different attribute values. For example, suppose site A is a retail store, while site B is wholesale, and the prices for the same products differ on sites A and B. In this case, the prices are specified in Magento 1 for the default site. In this instance, after migrating data from site A, migration from site B will cause product attributes, including price, to be overwritten.

Solution: The scope of the price attribute must first be set in the website value in the Magento 2 configuration, by using a standard export to export product prices to a CSV file after migrating from site A. Then they must be imported using a standard import. To do this, we re-write the code for the default store view of site A using a standard import.

Limitations of the UberTheme Migration Tool

The UberTheme Migration Tool cannot transfer:

  • custom entities;
  • images from the media directory of Magento 1 to pub/media in Magento 2;
  • static pages and blocks.

These elements will have to be transferred manually.

UberTheme can transfer custom attributes of EAV entities.

If it’s a category, user, or user address, then to implement the output of a custom attribute in the admin panel, you will need to implement the corresponding changes in the UI component.

If the attribute has a custom backend, frontend, or source module, then the developer is required to implement the corresponding attributes in Magento 2 and write them into the metadata attributes, so their logic is not violated.

Migration in a Local Environment with Transfer to Stage or Pre-Production Using Git

Problem: Yii classes don’t support the standards of Magento 2, but if they are located in the module directory, Magento will try to include them in the di compilation, which will result in a bin/magento setup:di:compile command error.

Solution: Since the part based on Yii will be copied to pub/ub_tool when it is installed or updated, to successfully transfer it, it needs to be added to the repository before the command bin/magento setup:upgrade is executed.

If the part based on Yii is transferred to pub/ub_tool, there will be no issues.

Saving Categories in the Database When Migration Errors Occur

Problem: In the event of migration errors, categories in the database could be cut off from the tree. It means that there could be identifiers for categories that do not exist in the “path” field of the catalog_category_entity table when being transferred to the category. These non-existent categories aren’t displayed in the category tree in the admin panel, but they can break the standard import of products.

Solution: These categories must be removed from the catalog_category_entity table, and the problem will be solved.

In general, the best method for transferring data from Magento 1 to Magento 2 doesn’t currently exist, though there will be a need for it until Magento 1 becomes a thing of the past. Remember to keep up with updates and choose the UberTheme version that’s compatible with your current version of Magento 2. Also, be prepared for the fact that after migration you may have to reconcile some errors in the data.

Next, we move into the topic on how to work with Magento 2 using UI components.

Issues Related to UI Components in Magento 2

There is a new feature in Magento 2 used for output on both admin and frontend parts. This feature is the UI Component. Magento 2 UI Component has browser part and the server-side part that generates data by using the special object. This object is called Data Provider. Often this object’s class extends from \Magento\Ui\DataProvider\AbstractDataProvider as it should support Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface. The browser part is a JavaScript knockout component and template, that is downloaded asynchronously after the page has been downloaded. Then JavaScript will bind data to template elements by using knockout javascript framework.

UI components are used in most admin pages from the core, sidebar mini cart. Some elements on the cart page and checkout are also implemented with their use. We can define Magento UI Component with XML. They can be customized simpler than blocks, but developers should know, how to do that. Often developers without experience in use and customization of UI Components have difficulties with customizing some grid, product edit form or customer edit form in admin. Below, we will examine the most common questions and how to solve them.

Navigate to the issue:

Displaying an Image from a UI Grid Column in the Administrator Panel
Custom Product Attribute Renderer on the Product Editing Page
Adding UI Element After Outputting Shipping Methods

Displaying an Image from a UI Grid Column in the Administrator Panel

Problem: We need to display the image from the UI Grid column in the admin panel.

Check the solution

Solution: An image from a UI Grid column can be displayed in the following way. The XML field of the UI component must be described using the specific UI component and class.

The class must be implemented.

<column name="image" class="Web4pro\Socialprofile\Ui\Component\Listing\Column\Thumbnail">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/thumbnail</item>
            <item name="sortable" xsi:type="boolean">false</item>
            <item name="altField" xsi:type="string">title</item>
            <item name="has_preview" xsi:type="string">1</item>
            <item name="label" xsi:type="string" translate="true">Thumbnail</item>
        </item>
    </argument>
</column>

class Thumbnail extends \Magento\Ui\Component\Listing\Columns\Column {

   public function prepareDataSource(array $dataSource)
    {
        if(isset($dataSource['data']['items'])) {
            $fieldName = $this->getData('name');
            foreach($dataSource['data']['items'] as &$item) {

               $item[$fieldName . '_src'] = $item['instagram_link'];
                $item[$fieldName . '_alt'] = '';
                $item[$fieldName . '_link'] = '';
                $item[$fieldName . '_orig_src'] = $item['instagram_link'];
            }
        }
       return $dataSource;
    }
}

As you can see, the prepareDataSource() method should return an array whose elements contain non-empty fields with the keys $fieldName.’_src’ and $fieldName.’_orig_src’.

$fieldName.’_alt’ can be set to be non-empty to set the image’s alt attribute.

Custom Product Attribute Renderer on the Product Editing Page

Problem: Suppose there is a product attribute of the type Multiselect, each option of which is associated with a particular image that should be shown after the attribute (on the right) when you hover over an option in the element.

Check the solution

Solution: In Magento 2, a modifier must be implemented to do this, in which the UI component that implements this functionality is described:

di.xml (create only in the adminhtml section)

<?xml version="1.0" ?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="instagram_link" xsi:type="array">
                    <item name="class" xsi:type="string">Web4pro\Socialprofile\Ui\DataProvider\Product\Form\Modifier\Link</item>
                    <item name="sortOrder" xsi:type="number">160</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Modifier class:

class Link extends \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier
{

   protected $arrayManager;
   protected $opts;

   public function __construct(\Magento\Framework\Stdlib\ArrayManager $arrayManager,
                                \Web4pro\Socialprofile\Model\Link $opts)
    {
        $this->arrayManager = $arrayManager;
        $this->opts = $opts;
    }

   /**

* @param array $data
* @return array
*/
public function modifyData(array $data)

{
       return $data;
    }

   /**

* @param array $meta
* @return array
*/
public function modifyMeta(array $meta){

       $fieldCode = 'instagram_link'; //your custom attribute code

$elementPath = $this->arrayManager->findPath($fieldCode, $meta, null, 'children');

       $containerPath = $this->arrayManager->findPath(static::CONTAINER_PREFIX . $fieldCode, $meta, null, 'children');
        if (!$elementPath) {
            return $meta;
        }

       $meta = $this->arrayManager->merge(
            $containerPath,
            $meta,
            [
                'children'  => [
                    $fieldCode.'_img' => [
                        'arguments' => [
                            'data' => [
                                'config' => [
                                    'component' => 'Web4pro_Socialprofile/js/product_links',
                                    'componentType' => 'component',
                                    'disableLabel'  => true,
                                    'multiple'      => false,
                                    'options'       => $this->getOptions()
                                ],
                            ],
                        ],
                    ]
                ]
            ]
        );
        $meta=$this->arrayManager->merge($elementPath,$meta,
            ['arguments'=>
                ['data'=>
                    ['config'=>
                        ['service'=>
                            [ 'template'      => 'Web4pro_Socialprofile/image.html']
                        ]
                    ]
                ]
            ]);
        return $meta;
    }

We put the UI component template in service.template of the element $fieldCode, not in $fieldCode.’_img’. That’s because the contents of the template will be uploaded to the same <div> where the element is located, not outputted after it on the following line, since the template /vendor/magento/module-ui/view/base/element/web/templates/form/field.html is responsible for outputting form elements, with the following form

<div class="admin__field"
     visible="visible"
     css="$data.additionalClasses"
     attr="'data-index': index">
    <label class="admin__field-label" if="$data.label" visible="$data.labelVisible" attr="for: uid">
        <span text="label" attr="'data-config-scope': $data.scopeLabel"/>
    </label>
    <div class="admin__field-control"
         css="'_with-tooltip': $data.tooltip, '_with-reset': $data.showFallbackReset && $data.isDifferedFromDefault">
        <render args="elementTmpl" ifnot="hasAddons()"/>

       <div class="admin__control-addon" if="hasAddons()">
            <render args="elementTmpl"/>
           <label class="admin__addon-prefix" if="$data.addbefore" attr="for: uid">
                <span text="addbefore"/>
            </label>
            <label class="admin__addon-suffix" if="$data.addafter" attr="for: uid">
                <span text="addafter"/>
            </label>
        </div>

       <render args="tooltipTpl" if="$data.tooltip"/>
       <render args="fallbackResetTpl" if="$data.showFallbackReset && $data.isDifferedFromDefault"/>

       <label class="admin__field-error" if="error" attr="for: uid" text="error"/>
       <div class="admin__field-note" if="$data.notice" attr="id: noticeId">
            <span text="notice"/>
        </div>

       <div class="admin__additional-info" if="$data.additionalInfo" html="$data.additionalInfo"></div>
       <render args="$data.service.template" if="$data.hasService()"/>
    </div>
</div>

The template image.html looks the following way:

<img id="instagram_img"/>

The file product_links.js looks as follows.

define(['jquery','uiComponent','jquery/ui'],function($,Component){

   return Component.extend({
        initialize: function () {
            this._super();
            var self = this;
            $(document).on('mouseenter',this.options.element,function(){self.changeOption(this)});
        },
       changeOption:function(opt){
            for(var i in this.options){
                if(parseInt(i)&&this.options[i].value==opt.value){
                    var img=$('#instagram_img');
                    img[0].src = this.options[i]['image'];
                }
            }
        }

   });
});

It’s critical that the component must be initiated before the form element is uploaded. Therefore, the event handler must be attached in precisely this way.

Adding the UI Element After Outputting Shipping Methods

Problem: Additional UI elements must be added after the standard output of shipping methods on one-page checkout.

Check the solution

Solution:

1. Define the checkout_index_index.xml layout file in its module.
2. Add a child element to the shippingAdditional element, which, in turn, will be a component, the value of which should be recorded in a JS file. Example:

<item name="component" xsi:type="string">JohnnySk_Additional/js/view/shipping/newmail/form</item>

This the full example of a custom layout file:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="config" xsi:type="array">
                                                        <item name="shippingMethodNewMailItemTemplate" xsi:type="string">Beautywave_NewMail/shipping-address/shipping-method-item</item>
                                                        <item name="shippingMethodListTemplate" xsi:type="string">Beautywave_NewMail/shipping-address/shipping-method-list</item>
                                                    </item>
                                                    <!-- Add additional shipping component -->
                                                    <item name="children" xsi:type="array">
                                                        <item name="shippingAdditional" xsi:type="array">
                                                            <item name="component" xsi:type="string">uiComponent</item>
                                                            <item name="displayArea" xsi:type="string">shippingAdditional</item>
                                                            <item name="children" xsi:type="array">
                                                                <item name="newmail_carrier_form" xsi:type="array">
                                                                    <item name="component" xsi:type="string">JohnnySk_Additional/js/view/shipping/newmail/form</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

3. Define the JS file of our UI element (we see the path to it in the example above):

JohnnySk_Additional/js/view/shipping/newmail/form

Sample JS file:

/** * Created by JohnnySk. Don't touch this if you don't understand what's going on here ;)
 */
define([    'jquery',
    'ko',
    'uiComponent',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/shipping-service',
    'mage/translate'
], function ($, ko, Component, quote, shippingService, t) {
    'use strict';
    return Component.extend({
        defaults: { template: 'JohnnySk_Additional/shipping/newmail/form'
 },
    initialize: function (config) {
            this.someObsarvableItems    = ko.observableArray();
           this.selectedObsarvableItem = ko.observable();console.log('JohnnySk was here!!!');            this._super();
        }
    });
});

This code is for reference only; from here, you should implement the logic you need for your purposes. The dependencies in the component are also just random; you can include any dependencies you wish here (the first parameter of the defined functionality).

Bonus: How to Create an Alias for Console Commands

Problem: Linux console is slow when running Magento 2

Check the solution

Solution: A convenient way to speed up the Linux console is to use aliases (creating other names for console commands or sequences of commands):

To quickly switch between versions of PHP:

alias m2tom1="sudo a2dismod php7.1&&sudo a2enmod php5.6&&sudo service apache2 restart"
alias m1tom2="sudo a2dismod php5.6&&sudo a2enmod php7.1&&sudo service apache2 restart"

Assigning commands to change permissions:

alias m2perm="sudo find . -type d -exec chmod 775 {} \; && sudo find . -type f -exec chmod 664 {} \; && sudo chmod u x bin/magento"

Full permissions:

alias m2pall="sudo chmod -R 777 ."

Magento 2 console commands:

alias m2="bin/magento"
alias m2 s:u="m2 setup:upgrade"
alias m2 c:f="m2 cache:flush"
alias m2 i:r="m2 indexer:reindex"
alias m2 c:f="m2 setup:static-content:deploy"

To save commands, they must be written to the file ~/.bashrc

Magento 2 issues we discussed are just a part of all the things that you can face. What conclusions can we make? What does all this mean for us? For web developers, Magento 2 is still a powerful tool. But it requires additional technical knowledge, new creative approaches, and learning a lot of skills from scratch regarding the platform’s changed architecture. Also, we should keep in mind that first of all, Magento 2 is a tool. We, Magento developers, and its large community are the masters who can make this product better day by day. For businesses, Magento 2 is a complex solution that allows them to extend and change their online stores flexibly.