Magento Development: Delete Orders, Reset Dashboard

Delete Orders

Found this great extension that does it. I’ve used it on EE 1.12, and from the reviews I gather it works on CE 1.7.0.2 as well. YMMV, use with caution, etc. I can’t imagine installing this in anything other than a development environment.  Seamless Delete Order.

Reset Dashboard Statistics

To remove “Bestsellers” from my dashboard, I add this stored procedure to my development MySQL environments, courtesy of this post at PHP Bugs.

DROP PROCEDURE IF EXISTS reset_dashboard;
delimiter //
CREATE PROCEDURE reset_dashboard()
BEGIN
  TRUNCATE sales_bestsellers_aggregated_daily;
  TRUNCATE sales_bestsellers_aggregated_monthly;
  TRUNCATE sales_bestsellers_aggregated_yearly;
  DELETE FROM report_event WHERE event_type_id IN (SELECT event_type_id FROM report_event_types WHERE event_name IN ('catalog_product_view'));
END //
delimiter ;

The DELETE FROM report_event code I stumbled across shortly after I originally posted this. I found it here at DesignersSandBox.

Magento Image Information via SOAP API

Here’s a little snippet that’ll dump out image information for … well, as written here, every active SKU in your Magento Installation.

The reason for the for loop breaking SKUs down based on the first letter is to keep from blowing up my PHP memory with too many products. Your mileage may vary.

try {
    $proxy = new SoapClient('http://magento.store.url/index.php/api/?wsdl');
    $sid = $proxy->login('username', '********');
}
catch( Exception $e ) {
    echo "Can't establish connection: " . $e->getMessage() . "\n";
    exit(-3);
}
 
for( $cat = 'A', $i=0; $i < 26; $i++, $cat++ ) {     $filter = array(         'status' => array( '='=>'1' ),
        'sku' => array( 'like' => $cat.'%' )
    );
    echo $cat.".";
    try {
        $productList = $proxy->call( $sid, 'product.list', array($filter) );
    }
    catch( Exception $e ) {
        echo "Can't retrieve product listing: " . $e->getMessage() . "\n";
        exit(-4);
    }
    foreach( $productList as $prodInfo ) {
        echo $prodInfo['sku'] . "\t" . $prodInfo['name'] . "\n";
        $media = $proxy->call($sid, 'product_media.list', $prodInfo['sku']);
        print_r($media);
    }
}
exit(0);

Magento Customer Passwords

Recently I had occasion to export some customer data and use it in another system. This way I don’t need 2 different sign-ons for an external CMS.

Magento stores the hashed password with its salt. You can use this code as a guide to checking Magento customer passwords outside (well, inside, too, I guess…) Magento. This is a php command line script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* Substitute appropriate Mage path: */
require_once( "../../app/Mage.php" );
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
 
/* argv[1] is assumed to be the email address in our program
 * argv[2] is the password
 */
$customer = Mage::getModel('customer/customer')->setWebsiteId(Mage::app()->getStore()->getWebsiteId())->loadByEmail($argv[1]);
echo "Customer ID: " . $customer->getId() . "\n";
 
/* Load in the password_hash: */
$hash_in_db = $customer->getPasswordHash();
echo "Hashed password as stored in the database: ". $hash_in_db . "\n";
 
/* The hashed password is stored as:
 *      hash.':'.salt
 * We explode at the ':' such that hash is in element 0, salt is in element 1
 */
$a = explode(':', $hash_in_db);
$hash = $a[0];
$salt = $a[1];
 
/* Generate a hash based on what was passed in at argv[2] */
$password_in = $argv[2];
$computed_password =  md5($salt . $password_in);
 
echo "Database=[$hash]  Computed=[$computed_password]\n\n";
 
/* Well, did it match? */
echo ( $computed_password === $hash ) ? "BOOM-MATCH!\n" : "*bbzzt* nope\n";
exit(0);

Thank you, unexpected[it]!

Magento: “An error occurred while saving the URL rewrite”

Working on a new Magento store, I got this error while rebuilding the Catalog URL Rewrites index:

! An error occurred while saving the URL rewrite

After the usual Google searches, I came across this post, which proved to be the answer to my problem: http://www.magentocommerce.com/boards/main.php/viewthread/198534/#t334426

Turns out there’s a conflict introduced by the installation of the osCommerce Migration Extension. However, the post wasn’t exactly clear on which code to change, so I figured I’d post a little more on the issue.

First, I moved all of the osCommerce code out of app/code/core/Mage and into app/code/local/Mage. I should point out, though, that I had already done that even before I ran into this problem because I ran into several issues with the import process that I was (cautiously) optimistic that I could actually fix, as well as several things that I wanted to change (for example, my import source had categories that contained embedded HTML I wished to strip out – and I had several thousand categories …)

The file we need to edit is Mage/Oscommerce/Model/Mysql4/Catalog/Url.php. In that file, we find the Mage_Oscommerce_Model_Mysql4_Catalog_Url, which extends Mage_Catalog_Model_Resource_Eav_Mysql4_Url:

class Mage_Oscommerce_Model_Mysql4_Catalog_Url extends Mage_Catalog_Model_Resource_Eav_Mysql4_Url
{
    protected function _getCategories($categoryIds, $storeId = null, $path = null)
    {
        $isActiveAttribute = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_category', 'is_active');
        $categories = array();

Basically, all the post wants us to do is short circuit the _getCategories function by returning its parents’ version instead.

class Mage_Oscommerce_Model_Mysql4_Catalog_Url extends Mage_Catalog_Model_Resource_Eav_Mysql4_Url
{
    protected function _getCategories($categoryIds, $storeId = null, $path = null)
    {
        return parent::_getCategories();
 
        $isActiveAttribute = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_category', 'is_active');
        $categories = array();

Note: Please don’t confuse this with a “good, permanent” solution. This is a nice way to be able to continue to refine my import using osCommerce Migration, and be minimally invasive. Once I have this thing working properly, I will simply remove the osCommerce Migration Extension from my site – once I’m live, I won’t need it any more.