Subscribe To RSS Feed


Mike D's SharpBlog

Just another Sharpdot weblog

Archive for the ‘magento’ Category

Magento: Import Multiple Images or Remove Images durring Batch Import

- Tuesday, March 2nd, 2010 -

This article will detail how to adjust the Magento Batch Import (Dataflow) to allow uploading multiple gallery images, and also how to add a way to remove all images during Import/Update.

These are the accompaning files: (Please reference this file if you have any quetion about the code examples below. The WYSIWYG editor was messing things up. mainly “&’s” and “empty()’s” )
1. Full Code Example

First we are going to have to modify the the adapter used to save/update products during the import process. The file used is located here: “/app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php“. Since we are going to be modifying this file we should extend it so we don’t change any core files. There are plenty of articles that detail how to extend/customize Magento files so I will not go into it.

First lets tackle adding multiple gallery images. These are images that appear on the products detail page below the main image. We will be making all our edits in the Product.php file mentioned in the previous paragraph. Find the SaveRow method. In this method find the code where Magento saves the products images(should be similar to the following code and around line 630).

        $imageData = array();
        foreach ($this->_imageFields as $field) {
            if (!empty($importData[$field]) && $importData[$field] != 'no_selection') {
                if (!isset($imageData[$importData[$field]])) {
                    $imageData[$importData[$field]] = array();
                }
                $imageData[$importData[$field]][] = $field;
            }
        }

        foreach ($imageData as $file => $fields) {
            try {
                $product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . $file, $fields);
            }
            catch (Exception $e) {}
        }

First thing we will do is change the addImageToMediaGallery so that when it saves the image it is not excluded(saves you from having to re-edit the products after import to make the images appear.).


        foreach ($imageData as $file => $fields) {
            try {
            	// changed to not mark imported images as 'excluded' - see http://www.magentocommerce.com/boards/viewthread/6971/P15/ and http://www.magentocommerce.com/boards/viewthread/40007/
                //$product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . $file, $fields);
                $product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . $file, $fields, false, false);
            }
            catch (Exception $e) {}
        }

Now we can add the code to import multiple gallery images. Just below the code above add this new code:

            //Now add each gallery image.
        if (!empty($importData['gallimg'])) {
			//$importData['gallimg'] should be a list of images to import seperated by ";"
			$images = explode(";", $importData['gallimg']);
			foreach($images as $image){
				//Don't add field for gallimg's
				try {
					//made second param null so it is not added as the main image, small or thumb. just added to the gallery
					$product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . trim($image), NULL, false, false);
				}
				catch (Exception $e) {}

			}
        }

In order to use this new code you need to add a new column to your import spreadsheet. Label the column “gallimg”. This needs to be a list of the images you want to import separated by a “;”.
Now that was not too hard was it?

Now we can address removing images during the import/update process. In order to remove all the images you will need to continue modifying the saveRow method. Add the following code just above the code we previously edited.

        //MRD added to remove all images for product before uploading new images
        if(isset($importData['remove_all_images']) && $importData['remove_all_images']=="yes" ){
	        //check if gallery attribute exists then remove all images if it exists
	        //Get products gallery attribute
	        $attributes = $product->getTypeInstance()->getSetAttributes();
        	if (isset($attributes['media_gallery'])) {
				$gallery = $attributes['media_gallery'];
				//Get the images
				$galleryData = $product->getMediaGallery();
				foreach($galleryData['images'] as $image){
				//If image exists
			    	if ($gallery->getBackend()->getImage($product, $image['file'])) {
			            $gallery->getBackend()->removeImage($product, $image['file']);
			        }
				}
			}
			#$gallery->clearMediaAttribute($product, array('image','small_image','thumbnail'));
        }
        //END Remove Images

To utilize the code we just created you will need to add the “remove_all_images” column to your spreadsheet and set the value to “yes”.

This was written using Magento version 1.2.1 so your files could be slightly different, but should still work if you follow the instruction. If you have any problems please leave a productive comment and I will see how I can help.

Posted in PHP, magento | 19 Comments »

Magento: Customer Desired Delivery Date Module

- Monday, February 22nd, 2010 -

This Magento Module allows you to add a date picker to the checkout process, which the customer can use to input a desired delivery date. There is minimal setup required. You will need to add the supplied code to your template pages in order to display the date-picker on the checkout process and add one line of code to the admin template. As soon as I find a convenient way to add the necessary block to the template files with out having to modify the template files I will remove the manual part of the Module.

Here is a link to the modules page: Delivery Date Plugin

To Add to email templates: (provided by Magento user: mrgniarf)
You can modify yourtheme/yourdesign/template/email/order/items.phtml and before :

<table cellspacing="0" cellpadding="0" border="0" width="100%" style="border:1px solid #bebcb7;background:#f8f7f5">
    <thead>
        <tr>
            <th align="left" bgcolor="#d9e5ee">__('Sku') ?></th>
            <th align="left" bgcolor="#d9e5ee">__('Item') ?></th>
            <th align="right" bgcolor="#d9e5ee">__('Subtotal') ?></th>
            <th align="center" bgcolor="#d9e5ee">__('Qty') ?></th>
        </tr>
    </thead>

Add:

<table cellspacing="0" cellpadding="0" border="0" width="100%">
    <thead>
        <tr>
            <th align="left" width="100%" bgcolor="#d9e5ee">__('Desired Arrival Date') ?></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td valign="top" style="padding:7px 9px 9px 9px;border:1px solid #bebcb7;border-top:0;background:#f8f7f5">
                helper('deliverydate')->getFormatedDeliveryDate($_order->getShippingArrivalDate()); ?>
            </td>
        </tr>
    </tbody>
</table>
<br>

Tags: , ,
Posted in magento | 28 Comments »

Magento Error: You cannot define a correlation name … more than once.

- Thursday, February 4th, 2010 -

This will be a short post about an error I ran into when messing around with the Magento “Toolbar” that is displayed for search results and on category pages. I decided that i needed to extend the toolbar block in-order to achieve some custom functionality that a client needed. Then I noticed that when I sorted by price I got the following error “You cannot define a correlation name ‘_price_order_table’ more than once“.  In my case I had extended the setCollection function.

My problem(Error) began because I was calling the parent method then was setting the order on the collection again, and Magento did not like it.

     public function setCollection($collection)
    {
        parent::setCollection($collection);
        //The next three lines were what were causing the problem.
        //Because setOrder was called in the parent function it threw the error when it was called again.
        #if ($this->getCurrentOrder()) {
        #    $this->getCollection()->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
        #}
        //Custom code went here
        return $this;
    }

Posted in PHP, magento | No Comments »

Magento: Can’t edit/add Categories

- Wednesday, October 28th, 2009 -

I recently ran into a problem with not being able to edit or even add a new category on a Magento site. I was upgrading a site and was working on the Development installation. I had changed the site name from something like “localsite.com” to “localsiteUpgrade.com”.

All of the sudden I could not edit categories. The problem is that when I viewed the site it showed as “localsiteupgrade.com” the “U” in Upgrade got converted to “u” lowercase. This difference in the base url set in magento and the url in the browser was causing SID to appear in the url. This was breaking ajax urls like the ones used to edit categories. to fix the issue I just had to set the base site url to “localsiteupdate.com” like it was showing in the browser address bar. Durring my research I ran accross other posts showing how to use htaccess files to make sure that visitors were redirected to the proper url.

Hope this saves someone else some time!

Posted in magento | 3 Comments »

Magento: Problems/Errors after upgrade to 1.3.x with the Flat Catalog

- Friday, October 23rd, 2009 -

I recently decided to upgrade a Magento Site from version 1.2.1 to version 1.3.2.4 and the upgrade went smoothly, so I thought. When trying to enable the new caching features(Flat products and Categories) added in ver 1.3, I was unable to build the flat catalog for the categories and products. I kept getting “Flat Catalog Category rebuild error”. This was very disappointing as this was a major reason to do the upgrade.

Well not to fear, the problem was that the hosting company I used when installing Magento did not allow the “innodb” storage engine. This meant that the tables were using the  MyISAM  storage engine instead. This was the root of the problem. Keep reading to get the solution.

Luckily the Magento Team has released a Database Repair Tool. (Download here)
If you need to use the Database Repair Tool Through trial and error I found it is MUCH better to run it before updating versions. If you do it after updating(“to just fix the flat catalog error”) I have ran into other errors I believe to have been caused by updating a site with a corrupted database.
The instructions are easy to follow and worked perfectly, but here is the gist of things. You create a fresh install of Magento(same version as your site). You put the repair tool script in the web root and fill in the connection info for the damaged database and the fresh installation database. Then the script fixes broken foreign keys, storage engine types, etc.

After running the repair tool I was able to build the Flat catalog categories and products tables.
Problem Solved.

Posted in PHP, Sql, magento | No Comments »

Transfering Magento Database

- Wednesday, April 8th, 2009 -

*Note: The Best way to migrate the database is to do it command line, using mysqldump.

I have Had a few problems when transferring a Magento database. Usually when pushing a development site to Production. Importing the database sometimes throws foreign key constraint errors. What I have found is that if you use phpmyadmin to export the database you need to check the box next to disable foreign key checks. Then you can import this database with out getting the constraint errors. Exporting the database through Magento’s built in functionality does this automatically.

The next issue I have run into is that( I believe, but don’t quote me ) mysql versions prior to 4.1 don’t automatically add the commands to allow inserting primary keys with an id of 0. This will cause Magento to throw an error. The way I have found to fix this is by manually editing a few db entries to set them to an id of 0. The tables I found that need to be edited are: core_store, core_website, core_store_group, and customer_group. I believe it will allays be the last entry that needs to be set to zero, but if in doubt compare it against the old database.

Hope this helps someone else, and let me know of any other work-arrounds to this issue.

Tags: ,
Posted in magento | 2 Comments »

Magento: Getting product attributes values and labels

- Monday, April 6th, 2009 -

I have found that it is very useful to be able to get attributes from the system and use them in places other than a products category page. I always forget the exact syntax to use so, this is going to be my unofficial cheat sheet.

This is how to get a drop down lists options. I don’t think it will work for a mulit-select attribute. I stick the value/label pairs into an array to use how I please.

$attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 'attribute_id');
foreach ( $attribute->getSource()->getAllOptions(true, true) as $option){
$attrubuteArray[$option['value']] = $option['label'];
}

I had a trickier time getting values for a multi-select attribute. I don’t think that this is the best method, but it is one that worked for me. First the multi-select attribute must be set to be used in the advanced search. You can set this in the manage attributes area.

$attributes = Mage::getModel('catalogsearch/advanced')->getAttributes();
$attributeArray=array();
foreach($attributes as $a){
if($a->getAttributeCode() == 'desired_attribute_code'){
foreach($a->getSource()->getAllOptions(false) as $option){
$attributeArray[$option['value']] = $option['label'];
}
}
}

If you only need to retrieve a value for a product you can try this way

//Referenced from /app/code/core/Mage/Eav/Model/Config/php @ line 443
$_product->getResource()->getAttribute('club_type')->getFrontend()->getValue($_product)

I added this code snip it below to possibly answer a question that was posted. The code below will get an attribure collection. Set {entityType} to 4 to get attributes for products. You can remove the “setCodeFilters” line if you want to get all the attributes. To get anything really useful you will probably need to get the resulting attribute ids and do someting with them, like use them in a filter for the products collection or something.

//
$attributesInfo = Mage::getResourceModel('eav/entity_attribute_collection')
->setEntityTypeFilter({entityType})
->setCodeFilter($attributes)
->addSetInfo()
->getData();

Entity Type Id’s
$entityType is an integer id for what type of entity the attribute is associated to. If you look at the “eav_attribute” table you will see that each attribute has an entity_type_id.
1 = Customer Entity
2 = Shipping Entity (I believe)
3 = Category Entity
4 = Product Entity

The Following code was added to answer a question in the replies:
To make a product attribute avaliable when getting a product collection(such as on a category page or search results page) you can add some code the a config.xml file that instructs Magento to load allways the attribute when a product collection is loaded.

How to add an  attribute to be loaded whenever a product collection is loaded:
This can go in any config.xml file. I would recommend putting it in a custom module rather than one from the core code. Just replace “attribute_name” with the attribute code of the attribute you are trying to add.

<frontend>
<product>
<collection>
<attributes>
<attribute_name/>
</attributes>
</collection>
</product>
</frontend>

Tags:
Posted in magento | 32 Comments »

Magento: error message – Notice: Undefined index: 0 app/code/core/Mage/Core/Model/Mysql4/Config.php on line 92

- Tuesday, March 17th, 2009 -

The Quick resolution to this problem it to move the database command line, and not use phpmyadmin. If you just need to fix your database keep reading.

I was moving a installation to a production server and was getting this error message: Notice: Undefined index: 0 in app/code/core/Mage/Core/Model/Mysql4/Config.php on line 92. It took alot of searching to figure out the problem, but here is what I found. When Magento installs it sets store and website ids in the database. When transferring the database the new database did not like having an id of 0 for the admin part of the site, so it made it have an id of 2. This is what my problem was. To fix it I went into the core_store and core_website Tables and gave the admin site an id of 0. It looks like this may only affect certain versions of magento(Earlier versions). Hope this helps someone else.

P.S. I also got foreign_key_constraint errors when importing my database. To solve this disable foreign key check when you export your database. Then when you need to change the core_store and core_website id’s you will probably need to surround your sql with the following code:

set foreign_key_checks=0;
//SQL to update ids
SET FOREIGN_KEY_CHECKS=1;

Tags: , ,
Posted in magento | 35 Comments »

Magento: Adding a static block to a view file (AKA: phtml file)

- Wednesday, March 11th, 2009 -

In magetnto you can add static blocks that you have created to pages using the layout xml files and adding code there. There is plenty of documentation on this method, but what if you want to call the static block from a view (view files generally end in .phtml). Well this is how I have been able to do it.

Just call

<?php
     echo  $this->getLayout()->createBlock('cms/block')->setBlockId('contacts_text')->toHtml() ;
?>

or

<?php
 echo $this->getLayout()->createBlock('catalog/product_list_related')->setTemplate('catalog/product/list/related.phtml')->toHtml() ;
?>

Where setBlockId is the identifier you set up in the static block.

Tags:
Posted in magento | 15 Comments »

Magento: Error – SimpleXMLElement::addAttribute() Attribute already exists

- Tuesday, March 10th, 2009 -

Warning: SimpleXMLElement::addAttribute() [simplexmlelement.addattribute]: Attribute already exists.

This Magento Error Message was giving me the hardest time. It seems to occur when you have a mis-match in your layout files.

What happend to me was I hard coded the newsletter into a page. In the newsletter layour file It was instructed to put the newsletter in the page also. This meant that it was included in the page more than once. That is why the error is thrown. Check your layout files to get a better grip on the problem.

I need to give thanks to Branko Ajzele for his post. It helped me realize what the problem was.

Tags: ,
Posted in magento | 3 Comments »