Magento


Magento Error Warning: mcrypt_generic_deinit(): Could not terminate encryption specifier

I ran into the below error today while working with Magento 1 and registering a customer during checkout.

[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "NOTICE: PHP message: PHP Fatal error:  Uncaught exception 'Exception' with message 'Warning: mcrypt_generic_deinit(): Could not terminate encryption specifier  in /var/www/myproject/htdocs/lib/Varien/Crypt/Mcrypt.php on line 135' in /var/www/myproject/htdocs/app/code/core/Mage/Core/functions.php:245"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "Stack trace:"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "#0 [internal function]: mageCoreErrorHandler(2, 'mcrypt_generic_...', '/var/www/myproject...', 135, Array)"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "#1 /var/www/myproject/htdocs/lib/Varien/Crypt/Mcrypt.php(135): mcrypt_generic_deinit(Resource id #180)"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "#2 /var/www/myproject/htdocs/lib/Varien/Crypt/Mcrypt.php(54): Varien_Crypt_Mcrypt->_reset()"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "#3 [internal function]: Varien_Crypt_Mcrypt->destruct()"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "#4 {main}"
[10-Apr-2018 13:49:47] WARNING: [pool www] child 1731 said into stderr: "  thrown in /var/www/myproject/htdocs/app/code/core/Mage/Core/functions.php on line 245"

The problem is the encryption key in app/etc/local.xml was empty. Add one to solve the problem.


A faceted navigation that’s optimal for both site visitors and SEO

A project of mine suffers from over categorization as described here https://baymard.com/blog/ecommerce-over-categorization . There are too many sub categories, many of which contain just a product or two, that silo the visitor into a cumbersome experience. Imagine you visited a site and viewed their TV’s and you looked at their category for 40″ TVs. But then, you decided to view other TV’s, so you viewed the 42″ category, and then the 46″ category. The same would happen if you wanted to shop TV’s by brand, type, or another feature. It would take a long time to browse all available TV’s with the features that are valuable to you! This is an example of over categorization. Instead the categories should be turned into a TV’s category with a variety of available facets (filters) that can be applied together.

Aside from a good information architecture, site speed is important. An ajax based navigation, such as this one https://www.lacrossetechnology.com/products/weather/weather-stations provides a great user experience because only the products will reload when a filter is applied. An entire page reload when a filter changes is not necessary, which improves performance.

While an ajax based navigation is great for visitors, it’s terrible for search engine optimization because:

  1. The filters (facets) and combinations of filters won’t have unique meta content or in page descriptions like the previous sub categories did. With the previous over categorization there was a separate category for “Sony TV’s” that had a unique URL, page title and meta data, and a unique in page description. This is extremely important for SEO and is lost when switching to a general TV’s category with a brand filter (Sony).

    Solution –
    I was happy to find this Amasty extension https://amasty.com/improved-navigation-ajax-layered-navigation.html solves the problem. Try out the filtering on this demo http://improved-navigation-1910.demo.amasty.com/improved-navigation-1910/women/dresses-skirts/dresses-long.html . Notice I’ve linked you directly to the category page with a few filters applied; the combination of filters produces a unique URL without a query string (dresses-long.html) that is built in the same order every time for consistency. Additionally, this unique set of filters will dynamically change the page’s meta description, heading, and show/hide cms blocks of your choosing. You get the best of both worlds here – ajax driven navigation for the user and unique page content for the search engine. The downside it is takes a fair amount of configuration, but it’s worth it. This is especially important if we’re rearranging site categories and changing unnecessary sub categories, which have link juice, info filters.

  2. The filters (facets) and combinations of filters won’t get indexed by search engines like the previous sub categories did. Take the TV’s category for example – there will be one URL for TV’s that your ecommerce solution, such as Magento, will include in the Google sitemap. If you want to link the visitor directly to Sony TV’s it’s possible but with an ugly URL that won’t be included in the google sitemap by default. This URL will be in the form of a query string like tvs.html?brand=sony&size=46, which are not preferred by search engines.

    Solution –
    Build or buy functionality that will add URL’s of your choosing to the google sitemap. Again Amasty to the rescue with this module that allows you to add URL’s of your choosing https://amasty.com/magento-xml-google-sitemap.html .

I found these related articles helpful
https://moz.com/ugc/guide-to-ecommerce-facets-filters-and-categories
https://moz.com/blog/building-faceted-navigation-that-doesnt-suck
https://www.practicalecommerce.com/SEO-When-Product-Facets-and-Filters-Fail


Clean out Magento test data before launch

Before launching a site to production, or if it’s creating a copy of the website and database for development and testing purposes, you may need to clear out all customer and order information. Kudos to Geoff Jackson for this solution https://www.designhaven.co.uk/2014/08/cleanly-delete-orders-sales-customer-data-magento/ . I’ve used this a few times now and want to include it here for easy reference.

SET FOREIGN_KEY_CHECKS=0;
 
#This may NOT be necessary FOR you, but it was FOR me
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ALLOW_INVALID_DATES';
 
##############################
# SALES RELATED TABLES
##############################
TRUNCATE `sales_flat_creditmemo`;
TRUNCATE `sales_flat_creditmemo_comment`;
TRUNCATE `sales_flat_creditmemo_grid`;
TRUNCATE `sales_flat_creditmemo_item`;
TRUNCATE `sales_flat_invoice`;
TRUNCATE `sales_flat_invoice_comment`;
TRUNCATE `sales_flat_invoice_grid`;
TRUNCATE `sales_flat_invoice_item`;
TRUNCATE `sales_flat_order`;
TRUNCATE `sales_flat_order_address`;
TRUNCATE `sales_flat_order_grid`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sales_flat_order_payment`;
TRUNCATE `sales_flat_order_status_history`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_quote_payment`;
TRUNCATE `sales_flat_quote_shipping_rate`;
TRUNCATE `sales_flat_shipment`;
TRUNCATE `sales_flat_shipment_comment`;
TRUNCATE `sales_flat_shipment_grid`;
TRUNCATE `sales_flat_shipment_item`;
TRUNCATE `sales_flat_shipment_track`;
TRUNCATE `sales_invoiced_aggregated`;
TRUNCATE `sales_invoiced_aggregated_order`;
TRUNCATE `log_quote`;
 
ALTER TABLE `sales_flat_creditmemo_comment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_creditmemo_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_creditmemo_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_comment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_status_history` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_shipping_rate` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_comment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_track` AUTO_INCREMENT=1;
ALTER TABLE `sales_invoiced_aggregated` AUTO_INCREMENT=1;
ALTER TABLE `sales_invoiced_aggregated_order` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
 
#########################################
# DOWNLOADABLE PURCHASED
#########################################
TRUNCATE `downloadable_link_purchased`;
TRUNCATE `downloadable_link_purchased_item`;
 
ALTER TABLE `downloadable_link_purchased` AUTO_INCREMENT=1;
ALTER TABLE `downloadable_link_purchased_item` AUTO_INCREMENT=1;
 
#########################################
# RESET ID COUNTERS
#########################################
TRUNCATE `eav_entity_store`;
ALTER TABLE  `eav_entity_store` AUTO_INCREMENT=1;
 
 
##############################
# CUSTOMER RELATED TABLES
##############################
TRUNCATE `customer_address_entity`;
TRUNCATE `customer_address_entity_datetime`;
TRUNCATE `customer_address_entity_decimal`;
TRUNCATE `customer_address_entity_int`;
TRUNCATE `customer_address_entity_text`;
TRUNCATE `customer_address_entity_varchar`;
TRUNCATE `customer_entity`;
TRUNCATE `customer_entity_datetime`;
TRUNCATE `customer_entity_decimal`;
TRUNCATE `customer_entity_int`;
TRUNCATE `customer_entity_text`;
TRUNCATE `customer_entity_varchar`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `tag_properties`;
TRUNCATE `wishlist`;
TRUNCATE `log_customer`;
 
ALTER TABLE `customer_address_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `tag_properties` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_customer` AUTO_INCREMENT=1;
 
 
##############################
# ADDITIONAL LOGS
##############################
TRUNCATE `log_url`;
TRUNCATE `log_url_info`;
TRUNCATE `log_visitor`;
TRUNCATE `log_visitor_info`;
TRUNCATE `report_event`;
TRUNCATE `report_viewed_product_index`;
TRUNCATE `sendfriend_log`;
TRUNCATE `log_summary`;
 
ALTER TABLE `log_url` AUTO_INCREMENT=1;
ALTER TABLE `log_url_info` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;
ALTER TABLE `report_viewed_product_index` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `log_summary` AUTO_INCREMENT=1;
 
SET FOREIGN_KEY_CHECKS=1;

Magento dev site redirects to live site 1

When taking a copy of a production site and installing it on a dev server, you’ll need to do a few things for the application to load the dev server and not redirect to the live site.
1. Change the site_url entries in the core_config_data table to match your dev site’s url
2. Delete everything in the magentoroot/var directory
3. Update the app/etc/local.xml file to point at your local database
4. This is the one that usually stumps me for a bit… ensure the magentoroot/var directory’s permissions are opened up (777 the var directory). If this is not done, Magento will write your Magento temporary and cache to the system temp and you magically be redirected to the live site.


Simple Magento Deployment Script

Here is a quick bash script I created to do a magento deployment. This assumes your magento code is managed by git and you have n98-magerun v1.100 or greater installed on the server. Run this in your project root like “bash deploy.sh mybranchname;” .

#!/bin/bash
 
echo "fetching new branches";
git fetch;
 
echo "creating maintenance file";
touch maintenance.flag;
 
echo "checking out" $1;
git checkout $1;
 
echo "clearing cache";
n98-magerun cache:flush;
 
echo "clearing JS and CSS cache";
n98-magerun media:cache:jscss:clear;
 
echo "running installers";
n98-magerun sys:setup:run;
 
echo "removing maintenance file";
rm maintenance.flag;
 
echo "done";