Some code recipes and useful scripts.

Later Ctrl + ↑

Log Debug Backtrace in Magento 2

$obj = \Magento\Framework\App\ObjectManager::getInstance();
$fileHandler = $obj->create(\Magento\Framework\Logger\Handler\Base::class, ['fileName' => 'var/log/debug.log']);
$logger = $obj->create(\Monolog\Logger::class, [
                'name' => 'save',
                'handlers' => ['file' => $fileHandler],
                'processors' => ['process_id' => $obj->get(\Monolog\Processor\ProcessIdProcessor::class)]
            ]);
$logger->info(var_export(\Magento\Framework\Debug::backtrace(1, 0, 1), 1));

Result could be found in var/log/debug.log

 No comments   2018   debug   log   magento 2

Delete product duplicate images

The following solutions helps to find duplicate image file for each product and to remove it.
Create file delete.php in Magento base directory, put the following code into the file.

<?php
include('app/Mage.php');
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
ob_implicit_flush(1);

$mediaApi  = Mage::getModel("catalog/product_attribute_media_api");
$_products = Mage::getModel('catalog/product')->getCollection();
$i         = 0;
$total     = count($_products);
$count     = 0;
foreach ($_products as $_prod) {
    $_product   = Mage::getModel('catalog/product')->load($_prod->getId());
    $_md5Values = array();

    //protected base image
    $baseImage = $_product->getImage();
    if ($baseImage != 'no_selection') {
        $filePath = Mage::getBaseDir('media') . '/catalog/product' . $baseImage;
        if (file_exists($filePath)) {
            $_md5Values[] = md5(file_get_contents($filePath));
        }
    }

    $i++;
    echo "processing product $i of $total " . PHP_EOL;

    // Loop through product images
    $_images = $_product->getMediaGalleryImages();
    if ($_images) {
        foreach ($_images as $_image) {
            //protected base image
            if ($_image->getFile() == $baseImage) {
                continue;
            }

            $filePath = Mage::getBaseDir('media') . '/catalog/product' . $_image->getFile();
            if (!file_exists($filePath)) {
                continue;
            }
            $md5 = md5(file_get_contents($filePath));
            if (in_array($md5, $_md5Values)) {
                $mediaApi->remove($_product->getId(), $_image->getFile());
                echo 'removed duplicate image from ' . $_product->getSku() . PHP_EOL;
                $count++;
            } else {
                $_md5Values[] = $md5;
            }
        }
    }
}

To launch the script just launch in terminal

>php delete.php

Or visit

http://YourWebsiteURL/delete.php

from your browser.

Thanks to Aadil for a solution.

 1 comment   2016   gallery   images   product

Hide all categories without products and show categories with products

Reindex category products index at first and then execute following sql-script.

UPDATE `catalog_category_entity_int` AS `status`
INNER JOIN `eav_attribute` AS `attr` ON `attr`.`attribute_code` = 'is_active'
AND `attr`.`entity_type_id` = 3
AND `status`.`attribute_id` = `attr`.`attribute_id`
SET `status`.`value` = IF((SELECT COUNT(`index`.`product_id`)
	FROM `catalog_category_product_index` AS `index`
	WHERE `index`.`category_id` = `status`.`entity_id` GROUP BY `index`.`category_id`) > 0, 1, 0)
WHERE `status`.`store_id` = 0
 No comments   2016   category   product   sql

Check Product Is New

Magento has two attributes “Set Product As New From Date” and “Set Product As New To Date” to set a product as new. If both fields are empty the product is not new. If only “Set Product As New To Date” is set, the product will be marked as “new” from current time until “Set Product As New To Date”. And If you set only “Set Product As New From Date” attribute the product will be marked as new from that date until forever. But how to check is product “new” currently?

Unfortunately Magento doesn’t have special method for this. But in Mage_Core_Model_Locale model there is a method called isStoreDateInInterval($store, $dateFrom, $dateTo) which checks is current date in two passed dates interval. But we need additional validation two dates are not empty, otherwise that method will return true. So we can create such method in some helper class:

<?php
public function isProductNew(Mage_Catalog_Model_Product $product)
{
    $newsFromDate = $product->getNewsFromDate();
    $newsToDate   = $product->getNewsToDate();
    if (!$newsFromDate && !$newsToDate) {
        return false;
    }
    return Mage::app()->getLocale()
            ->isStoreDateInInterval($product->getStoreId(), $newsFromDate, $newsToDate);
}
 1 comment   2015   date   locale   new   product

Add Admin User Via MySQL

If you don’t have access to store’s admin panel, but you have access to a database, you can easily add new Magento admin panel user via MySQL script.

Before you launch the next script, please, be sure your password is 8 symbols length and has at least 1 digit.

LOCK TABLES `admin_role` WRITE , `admin_user` WRITE;
 
SET @SALT = "mr";
SET @PASS = CONCAT(MD5(CONCAT( @SALT , "password") ), CONCAT(":", @SALT ));
SELECT @EXTRA := MAX(extra) FROM admin_user WHERE extra IS NOT NULL;
 
INSERT INTO `admin_user` (firstname,lastname,email,username,password,created,lognum,reload_acl_flag,is_active,extra,rp_token_created_at) 
VALUES ('First name','Last name','email@example.com','username',@PASS,NOW(),0,0,1,@EXTRA,NOW());
 
INSERT INTO `admin_role` (parent_id,tree_level,sort_order,role_type,user_id,role_name) 
VALUES (1,2,0,'U',(SELECT user_id FROM admin_user WHERE username = 'username'),'First name');
 
UNLOCK TABLES;

Make Simple Products of Configurable “Not Visible Individually”

If you wan’t automatically make all simple products which are configurable options of configurable products to be hidden in catalog, you have to change their visibility to “Not Visible Individually”.

Next SQL-query will help you with that task.

UPDATE
`catalog_product_entity_int`
SET 
`value` = 1
WHERE
`attribute_id`=(SELECT `attribute_id` FROM `eav_attribute` WHERE `attribute_code` = 'visibility')
AND
`entity_id` IN (SELECT `product_id` FROM `catalog_product_super_link`);

Change Customers Email Domains

Sometimes you need to work with a production’s DB dump on a staging or on a dev server. To avoid emails be sent to real customers you should replace their email addresses with safe values. We will use Mailinator service which receives all emails and allows to access them if you know full email address.

Just execute this SQL-query in your DB

UPDATE `customer_entity`
SET `email` = CONCAT(
	SUBSTRING(`email`, 1, locate('@', `email`)),
	'mailinator.com'
);

If you need to left your organization domain email addresses unchanged, just add such condition:

UPDATE `customer_entity`
SET `email` = CONCAT(
	SUBSTRING(`email`, 1, locate('@', `email`)),
	'mailinator.com'
)
WHERE  SUBSTRING(`email`, locate('@', `email`) + 1) != 'my-organization.com';

Change Magento Product Images File Type

For instance, we need to convert all .gif to .jpg

Execute next commands in terminal

> cd /vaw/www/media/catalog/product/
> for i in $(find $(pwd) -name \*.gif -print); do convert $i $(echo $i.jpg | sed s/.gif//g); done
> rm -r cache/

Then, run these SQL-statements in DB

UPDATE `catalog_product_entity_varchar`
SET `value` = REPLACE(`value`, '.gif', '.jpg') 
WHERE `attribute_id` IN 
    (SELECT `attribute_id` FROM `eav_attribute`
        WHERE `attribute_code` IN ('image', 'small_image', 'thumbnail') AND `entity_type_id` = 4
    )
; 
UPDATE `catalog_product_entity_media_gallery`
SET `value` = REPLACE(`value`, '.gif', '.jpg');
 No comments   2015   images   media   product