How to Compress Images with Jpegoptim

Jpegoptim is a utility to optimize/compress JPEG files. You can compress JPG format image losslessly with it, or you can set a maximum quality factor to compress the images into even smaller files.

Install Jpegoptim in Ubuntu or CentOS

Ubuntu

Run the commands below to update the package list and install jpegoptim on Ubuntu.

You can check if the installation is successful by running command below to check the version.

Centos

Run the command below to update the package list and install jpegoptim on Centos.

If you are running into an error saying “no package available”, make sure you have repo epel installed and enabled because jpegoptim is a part of epel on Centos.
You can use the command below to list all the enabled repos:

If you don’t see the epel repo in the list, try the command below to enable it.

or install it

Now let’s see some common use cases below:

Losslessly Compress a Single Image

Compress Quality to 80% for all Images in a Folder

Compress Quality to 60% for all Images in a Folder That are larger than 500kb

If you will need a detailed user manual, here is a link https://www.systutorials.com/docs/linux/man/1-jpegoptim/

Magento 2 Update Product Attributes for All Products in a Certain Category

Update Product Attributes in Bulk Using Product Grid

Magento 2 gives you the ability to update product attributes in bulk. Just go to the product grid at back-end(Catalog > Products), and you can select multiple products for which you want to update the product attribute value. Then from the action drop-down menu(upper left), select “Update Attributes”. You will be brought to a product edit page, instead of updating a single product, this time you are updating for all products you have selected. Change the value of product attribute by clicking on “Change” checkbox right below the attribute you would like to update, then the attribute will become enable to accepts your updates. When you are done editing, click on save button, all products will be updated with new attribute value.

You can even apply attribute filters, e.g. availability, qty, product type, etc.

Magento 2 Update Product Attributes for All Products in a Certain Category

However Magento 2 does not allow you to search product by categories in the product grid, you are reading this post because you want to update product attributes for all products in a certain category, for example you want to disable all products in one category.

Below is a simple PHP script to do that:

  • $categoryId is the Id of the category
  • attribue_code is the attribute code(string)
  • $value is the attribute value, in the script above, I was updating a YES/NO attribute, 1 = YES, 0 = NO

Replace $categoryId, $value, attribue_code for your needs, then run the script from CLI, or directly execute it in your browser.

Magento 2 Different Ways to Load Products

How do you load product by product ID in Magento2?

Using Repository to Load Products – Recommanded

Using Factroy to Load Products

The reason to use ProductRepository’s instead of a ProductFatory’s to load the product is because the former is of a higher level than the latter.

SO, you should use the API layer whenever possible, because:

  • Api/Data layer is used in the Web Api, as well
  • models can – and probably will – be refactored at some point; Api/Data/Product will not.
  • To get a product in your classes, you need to inject either a concrete factory (ProductFactory) or an interface (ProductRepository). I don’t think you want your module to rely on anything but an interface. Hence I disagree with this type of injection.

Using Collection to Load Products

If you need to load multiple products, you should use prodcut collections.

Using Product Mode to Load Products – Deprecated

How To Install Redis and Configure Multiple Redis Server on Centos 7

What is Redis

You are reading this post, I assume you already have a bit idea what is Redis. But just a short introduction: Redis is an open source in-memory database. It supports basic data type like strings as well as advanced data structures like lists and hashes.Redis is very simple to setup and use. Below is simple instruction on how to install and configure Redis on CentOS 7.

Redis official documentation here

Installation

Run the command below to stall Redis server on Centos.

If you are running into an error saying “no package available”, make sure you have repo epel installed and enabled because redis is a part of epel on Centos.
You can use the command below to list all the enabled repos:

If you don’t see the epel repo in the list, try the command below to enable it.

or install it

Start the Redis Server

Now you can start Redis server and enable to auto-start on system reboot by using the commands below.

By default, Redis server listens on 6379 port, and you can run commands below to check if it is alive.

Install and Run Multiple Instance of Redis on Centos

Sometimes you will need multiple Redis instances, for example I was configuring a server for Magento 2 hosting, and I need 1 server for page cache, 1 for config cache, 1 for session storage.

You can run multiple Redis instances on different ports. By default Redis is installed under /var/lib/redis. This is considered as the work space for the default Redis insane. Memory dump is stored here. You will see a file named dump.rdb if there is any data dumped from memory.

First, to setup another Redis instance, we will need to duplicate the directory for a new instance. You can do so by running the commands below:

Second, we will need to create a separate configuration file. The default config file is /etc/redis.conf

And update configuration in the file to let the new instance run on different ports.

Lines need to be updated:

As you can see above, this time we are using port 6380 to host the new instance.
Then create separate service file for Centos.

Lines need to be updated in the new service file

Now it is time to start the new instance and enable to auto-start on system reboot just like what we did when we install the first instance.

Check the status or our second instance:

Now we have 2 Redis servers running separately on porst 6379 and 6380.

Can Your Store Customer’s Credit Card in Magento

The question of whether you can store credit card information within Magento comes up a lot. The answer to this question is unfortunately not very clear when looking for an answer elsewhere including on the Magento website. To clarify the answer to this question, there are a few things that need to be understood including the PCI-DSS, PA-DSS compliance and the difference between them.

What is PCI-DDS?

PCI-DSS is the compliancy of your entire online environment which includes your systems, practices, software, etc. This is the standard that is required to be able to process on-site payments. A software application can never be “PCI compliant” by itself. Magento IS PCI-DSS compliant when the rules of PCI-DSS are followed which include:

  • Build and Maintain a Secure Network
  • Protect Cardholder Data
  • Maintain a Vulnerability Management Program
  • Implement Strong Access Control Measures
  • Regularly Monitor and Test Networks
  • Maintain an Information Security Policy

What is PA-DDS?

PA-DSS is a standard for *software applications* dealing with payment processing. PA-DSS was designed to provide the definitive data standard for software vendors that develop payment applications which can store cardholder data securely and prevent them from storing prohibited cardholder data (full mag stripes, CVV2 info, pin numbers, etc).

PCI-DSS and PA-DSS Compliance

PCI DSS standards apply to each merchant who accepts payment via credit cards. There are various rules regarding the securing of credit card information depending on whether you record it on paper, in a computer, or both, and physical security rules also apply if you have credit card terminals.

PA-DSS is the certification being required for commercial applications that process credit cards. This requirement is on the software developers, not the merchants.

An application can be PA-DSS compliant, but the environment may or may not be PCI compliant.

By using a 3rd party plugin or merchant whose software and system IS PA-DSS compliant that can store cardholder data on external systems (Magento Payment Bridge included), it removes the PA-DSS requirement from Magento itself and allows you to be PCI-DSS compliant. This of course holds true if and only if all of the systems and networks this cardholder data traverse are protected. In other words, let’s say that your Magento store isn’t storing cardholder data, but is instead using a PA-DSS compliant third party. Let’s then say that the connection between your Magento store and the third-party is not encrypted or you have debugging enabled for the payment gateway. In such cases, you would NOT be PCI compliant.

Is Magento PA-DDS Compliant

Magento by itself is NOT a PA-DSS certified application. To reiterate, Magento does have the built in ability to store cardholder data in its own database, but you will never be PA-DSS compliant in doing so which prevents you from being PCI-DSS compliant. The Magento application (at any level: CE, PE, EE) has not been PA-DSS certified. Remember, PA-DSS applies to software only, and not the infrastructure. Storing cardholder data in a non-PA-DSS compliant application like Magento will invalidate PCI compliance.

If you do want to store credit card data for any time frame, even if for only a few minutes, you must use either Payment Bridge or a 3rd party plugin / service which is PA-DSS compliant and stores the cardholder information on their servers for later retrieval. In addition to this, the entire flow of cardholder data must be secured. This means all debugging must be off and the connections carrying cardholder information must use some form of SSL/TLS.

Mageno PCI Compliance

Magento Enterprise Edition

Magento Secure Payment Bridge is the easiest way to make your Magento website PCI compliant. The solution is separate from the Enterprise platform, so you don’t need a full website to be compliant. Therefore, you can easily update your ecommerce store without affecting the compliance of Bridge.

The solution stores credit card data and sends a token to the Magento instance. The token makes your system secure, as payment bridge credentials are not enough for getting access to customer data. In case of threats related to your payment bridge, you just need to setup a new instance and get new credentials. Thus, credit card information will remain secure.

Despite the Secure Payment Bridge application meets the above PCI requirements, it is not enough to make your Magento website absolutely secure, since the app must be installed in a PCI DSS compliant environment.

Magento Community Edition
Unfortunately, Secure Payment Bridge is not compatible with this edition. But there are several ways to make your Magento website PCI compliant:

You can use a third party payment methods, for example PayPal express, Authorize.net, etc.

If you choose this option you won’t have to be PCI compliant yourself, because you don’t have to store credit card information on your server. In this case you have to consider that your customers will be redirected to the site of the payment processor and will have to leave your website, which might be inconvenient and interrupt the buying process.

Magento’s Saved Credit Card Option

Again, let me first start off with the fact that this is not a PCI-compliant solution. It’s not ideal. I’d say that this is for emergencies only. And it might even be too risky for your company.

Magento Store Credit Card Option

But if a payment gateway goes down completely, and you’re not able to take orders, my recommendation is to do a temporary bypass and turn on the Saved Credit Card Option.

Then, you can use a virtual terminal or other means to manually run the credit card for each order later.

Normally, the saved credit card option is something we use just for testing. It’s not as secure as using a payment gateway. It most likely goes against your merchant agreement that you signed.

But if a payment gateway like Authorize.net is down, my recommendation is to turn this on, save the credit card numbers on the site, and then run them when you are able.

You’ll want to then later remove the stored credit cards from the server, so that you can mitigate any risk of storing credit cards.

Magento Products Not Showing in Category

After working with Magento for two years, sometimes, I still find I can be surprised by it.
Why a product is not showing on the category page, I don’t how many times I have been ask this question.
Below it is a workflow I summarized we can follow to do troubleshooting.

Magento Products Not Showing in Category

Only one specific product is not showing on the category page.

If on your Magento category page, only one specific product is now showing up, other products are fine. We should consider it is something with the product itself.

Let’s do a product configuration checklist:

1. Check if the product is enabled.

2. Check if the product Visibility is set to ‘Catalog, Search’ or ‘Catalog’.

3. Check if the Stock Availability in Inventory tab is set to ‘In Stock’.

4. In Inventory Tab, ‘Qty’ should > 0, if ‘Manage Stock’ is set to Yes. If ‘Manage Stock’ is set to No, then ‘Qty’ filed doesn’t matter.

5. In the Categories Tab, the product should be assigned to the target category.

6. If you have multiple store / storeview setup, make sure the correct website is checked in the Website tab.

7. Are you using Full Page Cache? If so, try flushing the Full Page Cache.

After going through the checklist above, clear all Magento cache, preform a re-index, and then check again.

One specific category page is empty with no product, other categories load products with no issue.

First, still do the check list above, just in case all the products in the category have been misconfigured.

But be noticed, in Magento, if you go to a category page where there is 0 products assigned, you are likely to see a message like “There are no products matching the selection.”, see the screenshot below.

If you are not seeing this message, make sure the empty category page is a ‘real category page’, you are not being redirected to an empty CMS pages or anywhere else.

Also, check the ‘Display Mode’ of the category. Magento will only render the product list/grid on the category page if you select ‘Products only’ or ‘Static block and products’.

Clear Magento cache, and re-index.

All Category pages are empty, no product is showing on any category page.

In this case, you probably want to test if you can reach product detail pages.

If Product Pages cannot be reached.

This tells that Magento didn’t not find any products at all.
First of all, let’s still go through the product configuration checklist above. Sometimes, people import all products at once using csv file or other import tools, they may misconfigure some fields for all products.

After making sure product data is correct. we can now say, most likely it is an issue caused by multi-store/store view environment.
Go to System –> Manage Stores, click the store you are configuring(not website, not store view either). Please check whether your products are under the ‘Root Category’ here.

You should also try the below procedure:
Go to product grid at back-end, select all products, and then use the bulk update function at upper right. Set the Website again for all products. This is because sometimes people found product-website association is broken after they renamed their store or store view.

Clear Magento cache,and re-index, same.

If Product Pages can be reached, but no products on category page.

If you have reached here, and the issue is still not fixed, No worries. From my experience, there should be some errors in coding. First check product not showing is not caused by any CSS problems on your category page.
More likely, check if there is any error in the Catalog module, or if any 3rd-party extension overrides Catalog Module poorly.

Some possible overrides to cause the issue:

Catalog/Block/Product/List.php

Search the function getLoadedProductCollection  among all 3rd part modules for possible overrides.

Also the template files:

Catalog/Product/list.phtml
Catalog/Category/view.phtml

I hope your problem can be solved after reading this post.

 

How to Reinstall a Magento Module

Sometimes, we need troubleshooting an installed Magento Module, which you know should work perfectly, but in your case, it is not.

Doing a reinstall seems to be an option. If you installed the module using Magento connect, it is straightforward, everything can be handled via Magento back-end. However, if we installed the module manually, you will find not easy to do so.

Re-upload and Overwrite All Module Files

Replacing all files from the module may resolve the issue in the case that the issue was caused by corrupted or missing files. However, this will do nothing to the database. The existing tables and records in the database will not be updated.

Run the Database Install Script

In case something wrong with your database, e.g. dependent tables were not created in the initial install process.
We want the database install script of your module to run another time.
In order to do so, we will need to delete the setup record for your module in the database. Find the setup record in the core_resource table, it should look like yourmodule_setup(see the example below). Delete it with the SQL statement below, or use phpMyAdmin.

Magento core_resource table

Delete Statement:

When Magento scans file system, and find this module. Without having a setup record in the core_resource table, Magento will treat it as a new module and then run the database setup script.

However, you may also consider deleting all the dependent tables of that plugin in the database before trying re-run the script. Because the script usually uses CREATE TABLE IF NOT EXISTS statement. So it only creates the tables if it doesn’t exist before.

Clean Module Configuration

Last, if you have gone through the two steps above, and still no luck. You may try resetting the configuration of the module saved in Magento too.
These configuration usually store in the core_config table. To find all records belong to the module, open the system.xml file of your module(etc/system.xml) and match the fields defined here with records in core_config table. See an example below

Field ‘Active’ defined in system.xml

Magento module system.xml

Record ‘mailchimp/general/active’ in core_config table

Magento core_config table

Delete all records that added by this module, and the re-do the first two steps. Then you have completed the module reinstall.

 

How to send email programmatically with email template in Magento 1

Sending email programmaticallyis a very common need when you are developing a Magento site or a Magento extension. With the API provided, it is quit easy.  Let’s go over a couple essential steps when we send email programmatically in Magento.

Step 1. Load the Email Template Module

Step 2. Load a Email Template from File or Database

If we have a email template saved as a file in app/locale directory, use the code below to load it.

If you create a email template via Magento back-end and saved it to the database, you can use the code below.

Step 3. Prepare the Variables Used in the Email Template

Prepare the variable array. These variables will be used in the email template. Below is an example, where we retrieved the customer name and email from context, and then store them in an array which will be passed to the email template.

Step 4. Prepare for Sender info

Since we are using email template, subject is already set in the template. Next we will need to provide the sender information. Use the code below to set sender name and sender email.

You can also load the sender info from a previous saved config in the database, e.g. code below loads name and email from general contact which you can manage from Magento backend.

Step 5. Set Recipient and Send

The lasts step is set the recipient of the email, and then send it!

This approach uses an existing email template whether it is created from Magento back-end, or stored as a template. In my future posts, we will also discuss how to create an email template programmatically upon sending an email, or send emails using queue.

 

How to Config Cron Jobs in Magento

Cron Jobs support is a key feature offered by Magento. From sending order confirmation emails to validating special price. Multiple core functionalities of Magento are built on the top of Cron Jobs. So configure Cron Jobs correctly is crucial to the success of your online store.

How to Config Cron Jobs in Magento

By default, Magento comes with Cron Jobs features. There are also 3rd party extensions like Aoe_Scheduler, which offers more advanced Cron Jobs management and optimization. We are not talking about those extensions here. Instead, this post will go through the setup process of the default Cron Jobs function offered by Magento itself.

Configure Magento Cron Jobs from Command Line

If you are familiar with Linux environment and Linux Cron Jobs, it may be pretty straightforward to add the Cron Jobs Magento required from Command Line.

Just log into your server, and then switch to the Magento file system user, using SU command, and then using Crontab -e command to open the Cron Jobs editor.

After entering the command above, pressing ESC quits from insert mode to normal mode, and then enter :wq to save, quite easy, right?

Configure Magento Cron Jobs using CPanel

If you are not very familiar with Linux commands, no worries! Most of the hosting solutions have CPanel ready for you. Just log in your Cpanel account, search for Cron, and then go to Cron Jobs

Cpanel-cron

It also offers some useful presets of Cron Jobs options, such as execute your Cron Jobs once per minute, or once per 5 minutes, etc …

Cpanel Cron Job Configuration

Last, in the Command box, enter  sh /path_to_Magento_root/cron.sh

Then we are done!

How often should you run Cron Jobs for Magento?

Whether you use command line or CPanel to set up Magento Cron Jobs, you will need to set the frequency of Cron Jobs execution. You may find different answers to how often you should run Cron Jobs after searching on the Internet. My development team and I personally would like to use 3 mins or 5 mins as an interval to run the Cron Jobs for Magento.

Execute Cron Jobs every 3 mins:

Execute Cron Jobs every 5 mins:

But I have seen people using 1 min, 10 min.

Magento Cron Jobs Settings in Back-end

Last, let’s take a look at some Cron Jobs Settings in Magento Backend.

Go to System -> Configuration

From the left Menu, Find Advanced -> System -> Cron (Scheduled Tasks)

You will see couple options we have here:

Magento Cron Job Configuration

Schedule ahead for: Cron Jobs tasks will be generated for this amount of time ahead.
In the example, if a Cron Jobs task is scheduled at 15:15, it will not be generated and then added to Cron_schedule before 15:00

Missed if not run within: if Cron Jobs is executed within setup minutes after the task was scheduled, it will be executed. Otherwise, it will be marked as ‘missed ’in Cron_schedule table.

History cleanup every: Magento will clean up history not more than setup amount of minutes.

Success history lifetime: successfully executed tasks will be stored in Cron_schedule table for this amount of minutes.

Failure history lifetime: Tasks that have status ‘error’ and ‘missed’ will be stored in Cron_schedule table for this amount of minutes.

How to Find and Remove Hanging Cron Jobs in Magento

Recently, one of our Magento client reported that their website stopped sending out order confirmation. However, invoice and shipment emails seemed to work with no issue. After an investigation, we discovered their site has caused a hanging Cron Jobs.

How to Find and Remove Hanging Cron Jobs in Magento

Starting from version 1.9.1, order confirmation emails are not sent directly during checkout, instead, they are queued in Magento, and then send out later by execution of Cron Jobs. A hanging Cron Job will cause email send stopped.

Check if Magento Cron Jobs is Hanging

Log into the server and run the following command:

As the screenshot below, you can see a couple lines of outputs

Magento Hanging Cron Jobs

The first line is the Cron daemon process running on this server.

The second line shows the command we just ran.

The third and fourth lines are Magento Cron Jobs that are currently being executed.

Furthermore, take a look at the second column from the right, that is the execution time of the process. Magento Cron Jobs usually runs real quick. So if it is caught by our ps command, and showing a long execution time, I would say if it is longer than 30 mins,  then it is possibly hanging.

Kill Hanging Cron Job

Now find the pid(second column) of the hanging process ending with ‘-mdefault’, in our case above, which is 10231, kill the process with the command below.

Make sure replace  10231 with the pid showing on your console, and you may run the ps aufx | grep cron command again to confirm the hanging Cron Job is killed.  Your Magento Cron Job should resume momentarily.

Usually, following the procedure above will resolve the hanging Cron Job for Magent, but if the Cron Job is still not working normally, or becomes hanging again. I suggest:, First check if you have your Magento Cron Job setup correctly. Check this post if you are not sure how to configure Magento Cron Job.

You can also try doing a truncate (delete all records) for table cron_schedule, and then run the commands again, see if new Cron Job tasks are populated in the cron_schedule table. Additionally, identifying the Cron Job task that is hanging with RUNNING status in the cron_schedule table may help you locate the module which is causing the hanging Cron Job.