August 07, 2020

cm-mini

Thinking Magento

Magento 1.9.3.5 - Magento 2.3.5

Those of us who been waiting for a Magento 2, which would rival Magento 1, have run out of time. However it would appear that Magento 2.3.5 is that lifeline we've been looking for.

After leaving it to others to pull their hair out over such minor things (I lost most of mine pulling out hair over Magento 1 issues), I can now say that migrating to Magento 2.3.5 from 1.9.3.5 is going to be the right decision.

The PCI compliance issue was a step too far for most people, so it was the cliff edge that most people needed. There are only 11 days to get and you will need a parachute, if you haven't got one yet, you'd sure hope you have a good Magento developer to pull you up

Migrating to Magento 2 - Orphan Record ID

We've all been there. You run the Magento 2 migration tool and your 5000 year old Magento 2 database returns [ERROR]: Foreign key (FK_CATALOG_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID) constraint fails on source database. Orphan records id or some other similar message about there being orphaned rows in the database. Here's a cheatsheet for getting rid of most of those entries quickly.

INTEGRITY CHECK FIXES

DELETE FROM `sales_flat_order_item` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_order_item`.`order_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_flat_order_payment` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_order_payment`.`parent_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_flat_order_status_history` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_order_status_history`.`parent_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_flat_order_address` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_order_address`.`parent_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_order_tax_item` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order_item` WHERE `sales_order_tax_item`.`item_id` = `sales_flat_order_item`.`item_id`);


DELETE FROM `sales_flat_shipment` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_shipment`.`order_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_flat_shipment_item` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_shipment` WHERE `sales_flat_shipment_item`.`parent_id` = `sales_flat_shipment`.`entity_id`);
DELETE FROM `sales_flat_shipment_comment` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_shipment` WHERE `sales_flat_shipment_comment`.`parent_id` = `sales_flat_shipment`.`entity_id`);
DELETE FROM `sales_flat_shipment_track` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_shipment` WHERE `sales_flat_shipment_track`.`parent_id` = `sales_flat_shipment`.`entity_id`);

DELETE FROM `sales_flat_invoice` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_invoice`.`order_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_flat_invoice_item` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_invoice` WHERE `sales_flat_invoice_item`.`parent_id` = `sales_flat_invoice`.`entity_id`);
DELETE FROM `sales_flat_invoice_comment` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_invoice` WHERE `sales_flat_invoice_comment`.`parent_id` = `sales_flat_invoice`.`entity_id`);
DELETE FROM `sales_flat_invoice_grid` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_invoice` WHERE `sales_flat_invoice_grid`.`entity_id` = `sales_flat_invoice`.`entity_id`);


DELETE FROM `sales_flat_creditmemo` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_order` WHERE `sales_flat_creditmemo`.`order_id` = `sales_flat_order`.`entity_id`);
DELETE FROM `sales_flat_creditmemo_item` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_creditmemo` WHERE `sales_flat_creditmemo_item`.`parent_id` = `sales_flat_creditmemo`.`entity_id`);
DELETE FROM `sales_flat_creditmemo_comment` WHERE NOT EXISTS (SELECT 1 FROM `sales_flat_creditmemo` WHERE `sales_flat_creditmemo_comment`.`parent_id` = `sales_flat_creditmemo`.`entity_id`);


DELETE FROM `catalog_eav_attribute` WHERE NOT EXISTS (SELECT 1 FROM `eav_attribute` WHERE `catalog_eav_attribute`.`attribute_id` = `eav_attribute`.`attribute_id`);
DELETE FROM `catalog_product_entity_int` WHERE NOT EXISTS (SELECT 1 FROM `eav_attribute` WHERE `catalog_product_entity_int`.`attribute_id` = `eav_attribute`.`attribute_id`);
DELETE FROM `eav_entity_attribute` WHERE NOT EXISTS (SELECT 1 FROM `eav_attribute` WHERE `eav_entity_attribute`.`attribute_id` = `eav_attribute`.`attribute_id`);

DELETE FROM `cataloginventory_stock_item` WHERE NOT EXISTS (SELECT 1 FROM `catalog_product_entity` WHERE `cataloginventory_stock_item`.`product_id` = `catalog_product_entity`.`entity_id`);

DELETE FROM `catalog_category_entity_int` WHERE NOT EXISTS (SELECT 1 FROM `catalog_category_entity` WHERE `catalog_category_entity_int`.`entity_id` = `catalog_category_entity_int`.`entity_id`);

DELETE FROM `catalog_category_entity_text` WHERE NOT EXISTS (SELECT 1 FROM `catalog_category_entity` WHERE `catalog_category_entity`.`entity_id` = `catalog_category_entity_text`.`entity_id`);

DELETE FROM `eav_attribute_group` WHERE NOT EXISTS (SELECT 1 FROM `eav_attribute_set` WHERE `eav_attribute_set`.`attribute_set_id` = `eav_attribute_group`.`attribute_set_id`);

DELETE FROM `eav_entity_attribute` WHERE NOT EXISTS (SELECT 1 FROM `eav_attribute` WHERE `eav_attribute`.`attribute_set_id` = `eav_entity_attribute`.`attribute_id`);

DELETE FROM `report_viewed_product_index` WHERE NOT EXISTS (SELECT 1 FROM `catalog_product_entity` WHERE `catalog_product_entity`.`entity_id` = `report_viewed_product_index`.`product_id`);

DELETE FROM `catalog_category_entity_varchar` WHERE NOT EXISTS (SELECT 1 FROM `catalog_category_entity` WHERE `catalog_category_entity`.`entity_id` = `catalog_category_entity_varchar`.`entity_id`);

 

Magento 2 - The Elephant We Try To Ignore

To this day, we still can't get our heads around the choice to develop an entirely different, more complicated version of Magento and we have been trying to keep an open mind.

But it's there, this great big elephant standing just a few feet away from us, telling us that we should either jump on or be trampled on.

We've been onboard with Magento since the very very early days of 07 / 08.

The great versions stand out to me as the stable ones (Once you tweaked them), 1.3.2.4, 1.7.0.2 & 1.9.2.4. 

From 1.3 to 1.4 it was a great leap and caused many headaches as the database structure for sales orders took on a whole new structure. As a live database took 8 hours to very very slowly migrate all the sales data into the new 1.4 tables.

On a personal level, these migrations took their toll, until you find the corner stone versions of Magento that you're happy with and then everyone in the client list gets an update to that rock of a version.

The learning curve is much much much much smaller these days for Magento 1. A mistake can be fixed pretty quickly and it's only the patches that sometimes cause the headaches, but for the most part they are stable.

 

Magento 2, we're not prepared to go in on the ground level this time around. We're not as young as we once were and the overheads are much much greater, we now have families and we're still not convinced it's what's needed to survive.

A lot of opinion pieces we've read are all about scaring people into jumping to Magento 2, the security is what you'll see written down regularly.
But these people don't seem to understand it was the community that helped develop and bug find Magento 1 into the fine piece it is today. It is regular human beings who are out there bug finding and figuring out patches. That doesn't just end when there is a community behind you. (Some of that community did get lost in the archives of the old forum)

We say that Magento 1 shouldn't just roll over and play dead. An MS Excel / Word or Photoshop user is never forced to give up their skill base because the program has been redeveloped so that they can no longer use it and must find alternative software. (Some will say, apples / pears), but is it? You can class yourself as an experienced photoshop user and quickly perform bread and butter jobs to financially keep you going. But now, as Magento Developers we are told it's either do or die. Is that what is left of the community?

As for the elephant, perhaps it will change course before it tramples us to death.

-- forum member elfling --

Magento Enterprise - Full Page Cache & Messages / Notices

Just a quick one about Magento Enterprise Full Page Cache.

Recently I noticed that the Enterprise PageCache wasn't hole punching notifications to the customer, so it would just reload the page without displaying the notice. But if the customer went on to do something else, such as a search, then the notice would appear. "This product is not available in the requested quantities"

So taking a look at the theme, I had a quick look to check for the issue.

In the catalog/view.phtml on the product page, is the following to get the message block

<div id="messages_product_view"><?php echo $this->getMessagesBlock()->getGroupedHtml() ?></div>

and after checking through a more recent version of Enterprises theme files I notice a difference and updated it to the following

<div id="messages_product_view"><?php echo $this->getMessagesBlock()->setEscapeMessageFlag(true)->toHtml() ?></div>

Now messages are displayed to the customer without being cached.

Update Product URL's Programmatically with 301 redirect

Recently I needed to update the URL's of existing products, without losing the 301 redirects. There are ways of course of doing this with extensions and uploading CSV's to extensions, however I decided to take a different route and update the URL's programmatically. 

Created a PHP file and placed it in root, in this case we can call it URL_UPDATER.php and added the following code. Set the ID's that you would like update to avoid overloading your database. Job don.

<?php 

require_once 'app/Mage.php';
Mage::app();
umask(0);
/*Set store to be admin so that you the URL change affects global*/
Mage::app()->setCurrentStore('0');

/*Build collection of products*/
$collection = Mage::getResourceModel('catalog/product_collection');

/*Set the product ID range of products you would like to adjust 7157 - 7357*/
$collection->addFieldToFilter('entity_id', array('gt' => 7156));
$collection->addFieldToFilter('entity_id', array('lt' => 7358));
$collection->getAllIds();

foreach($collection as $id) {

/*Get the ID of the product to load*/
$load = $id['entity_id'];

/*Load the product*/
$_product = Mage::getModel('catalog/product')->load($load);

/*New URL based on product name*/
$new_url = Mage::getModel('catalog/product_url')->formatUrlKey($_product->getName());

// save rewrites history for old to new url redirect
$_product->setData('save_rewrites_history', true);

// set new url
$_product->setUrlKey($new_url);

// set new url path
$_product->setUrlPath($new_url);

// save the product
$_product->save();

}

Page 1 of 9