Blog

Setting a php_value in PHP‑FPM

Published: January 29, 2018

Tags:

NOTE: The example used in this post is setting PHP's error_reporting level, which is no longer supported as of PHP 7.0. Regardless approaches documented in this post are still applicable for setting other php_values

Recently I needed to adjust PHP’s error_reporting level.

The goal was to set it to E_ALL & ~E_NOTICE which would silences notices.

The project in question was a Magento deployment, where it’s never advisable to modify core files (e.g. index.php). As such, I Googled “htaccess error_reporting E_ALL & ~E_NOTICE”, with hopes of making the change in the .htaccess file.

Magento 1 Enterprise Random 404s on the Product Detail Page (/catalog/product/view)

Published: January 26, 2018

Tags:

Recently, I received the following email from a client…

Help! My best selling product is 404-ing! We need this resolved ASAP!!!

Ruh-roh :scream:

My first step, of course, was to visit the URL for myself. Indeed, I got a 404.

Next up I added ?no_cache=1 at the end of the URL. This trick will bypass the full page cache in Magento 1 Enterprise, which the site in question was using. I refreshed the page and lo and behold the 404 was gone.

Digging in (after flushing page cache), I ultimately found a bug that can cause cache poisoning with a 404 response on any product details page if session is considered “invalid”.

In this post, let’s look at the issue, and how it can be solved.

Converting Numeric Data to Alphanumeric in PHP with base_convert

Published: January 25, 2018

Tags:

Recently a client came to me with the following request…

We’re planning publish “offer codes” in our print circulars so that customers can search for more details on our website. The offer codes our system generates are long and will be cumbersome for users to enter into the search field on the website. What can we do about this?

The offer codes looked something like this…

I thought about it a little and then a lightbulb went off in my head :bulb:

This could be solved by stripping the “PRE-“ (which was consistent across every offer code) and converting the remaining numeric data to alphanumeric via a base-10 to base-36 conversion. The result would be short alphanumeric codes that looked something like this…

In this post we’ll look at how this can be achieved in PHP.

Magento 2 Enterprise Special Price Confusion

Published: January 24, 2018

Tags:

One of the coolest features in Magento 2 Enterprise (a.k.a Magento Commerce) is Content Staging. Content staging allows store administrators to schedule updates for product attributes, and preview the changes prior to go live including providing a share-able link.

With the introduction of this feature, Magento was faced with a decision…what should be done with pre-existing facilities that already allowed (primitive) scheduling? For example, Special Pricing could already be scheduled via the “Special Price From Date” and “Special Price To Date” attributes.

Ultimately, Magento seems to have decided to attempt to prevent store administrators from using these features at all in favor of scheduled updates. This can be demonstrated both through the source code and documentation.

While this sounds good in theory, in practice it hasn’t worked out so well from what I’ve seen. In this post I’ll discuss my experience and thoughts.

Magento 2 Product EAV Index Failing After Downgrading

Published: January 18, 2018

Tags:

Recently one of my co-workers reported experiencing the following error when running a product eav reindex.

SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1, query was: INSERT INTO `catalog_product_index_eav_idx` SELECT DISTINCT  `pid`.`entity_id`, `pid`.`attribute_id`, `pid`.`store_id`, IFNULL(pis.value, pid.value) AS `value` FROM (SELECT DISTINCT  `s`.`store_id`, `s`.`website_id`, `dd`.`attribute_id`, COALESCE(ds.value, dd.value) AS `value`, `cpe`.`row_id`, `cpe`.`entity_id` FROM `store` AS `s`
 LEFT JOIN `catalog_product_entity_int` AS `dd` ON dd.store_id = 0
 LEFT JOIN `catalog_product_entity_int` AS `ds` ON ds.store_id = s.store_id AND ds.attribute_id = dd.attribute_id AND ds.row_id = dd.row_id
 LEFT JOIN `catalog_product_entity_int` AS `d2d` ON d2d.store_id = 0 AND d2d.row_id = dd.row_id AND d2d.attribute_id = 292
 LEFT JOIN `catalog_product_entity_int` AS `d2s` ON d2s.store_id = s.store_id AND d2s.attribute_id = d2d.attribute_id AND d2s.row_id = d2d.row_id
 LEFT JOIN `catalog_product_entity` AS `cpe` ON cpe.row_id = dd.row_id AND (cpe.created_in <= '1509969103' AND cpe.updated_in > '1509969103') WHERE (s.store_id != 0) AND ((ds.value IS NOT NULL OR dd.value IS NOT NULL)) AND (COALESCE(d2s.value, d2d.value) = 1)) AS `pid`
 LEFT JOIN `catalog_product_entity_int` AS `pis` ON pis.row_id = pid.row_id AND pis.attribute_id = pid.attribute_id AND pis.store_id = pid.store_id WHERE (pid.attribute_id IN('802')) AND (IFNULL(pis.value, pid.value) IS NOT NULL) AND (NOT(pis.value IS NULL AND pis.value_id IS NOT NULL))

The error indicates that catalog_product_index_eav_idx does not match the column list being INSERT-ed…

`pid`.`entity_id`,
`pid`.`attribute_id`,
`pid`.`store_id`,
IFNULL(pis.value, pid.value) AS `value`

I asked my co-worker to check and indeed, catalog_product_index_eav_idx contained an additional column (source_id).

Digging In To Magento 2 Logging

Published: January 15, 2018

Tags:

For better or worse, logging has changed a lot in Magento 2.

Previously the Mage god class defined a static log method through which all logging happened.

// app/Mage.php
public static function log($message, $level = null, $file = '', $forceLog = false)

Now, logging uses a light wrapper on top of Monolog.

There’s already some good information outlining how to do logging in Magento 2, so we won’t focus on that here (well, we will look at it, but only very briefly). Instead, here we’ll dig into the core Magento logging code to understand exactly how logging works in Magento 2 internally.