Tuesday, December 29, 2009

how to get customer address (for MagentoPycho)

Problem:how to get customer address from session?

Possible solution
Here is how you retrieve the primary billing address object:
$customerAddressId = Mage::getSingleton('customer/session')->getCustomer()->getDefaultBilling();
if ($customerAddressId){
$address = Mage::getModel('customer/address')->load($customerAddressId);
}
If you want the address in html format do this:
$customerAddressId = Mage::getSingleton('customer/session')->getCustomer()->getDefaultBilling();
if ($customerAddressId){
$address = Mage::getModel('customer/address')->load($customerAddressId);
$htmlAddress = $address->format('html')
}
if you want specific parts of the address just print it out and see how that part is called
$customerAddressId = Mage::getSingleton('customer/session')->getCustomer()->getDefaultBilling();
if ($customerAddressId){
$address = Mage::getModel('customer/address')->load($customerAddressId);
echo "
"; print_r($address->getData());echo "
"; }
for example if you want the street do this:
$street = $address->getData('street');
It works the same for the rest of the of the address attributes (firstname, lastname, phone, ...)

Exporting reviews (for rpeters83)

Problem: how to export reviews from Magento.
Possible solution:


Here is how you can retrieve all the comments.
Create a new php file on the same level as index.php of Magento. let's call it reviews.php
the content of this file should look like this:
<?php 
$mageFilename = 'app/Mage.php';

require_once $mageFilename;

Varien_Profiler::enable();

Mage::setIsDeveloperMode(true);

ini_set('display_errors', 1);

umask(0);
Mage::app('default');
Mage::register('isSecureArea', 1);

header('Content-Type: text/xml; charset=utf-8');
echo "<?xml version =\"1.0\" encoding =\"UTF-8\"?>\n";
echo "<reviews>\n";
$collection = Mage::getModel('review/review')->getCollection();
foreach ($collection as $item){
$review = Mage::getModel('review/review')->load($item->getId());
echo "\t<review>\n";
echo "\t\t<id>".$review->getId()."</id>\n";
echo "\t\t<created_at>".$review->getCreatedAt()."</created_at>\n";
echo "\t\t<status_id>".$review->getStatusId()."</status_id>\n";
echo "\t\t<store_id>".$review->getStoreId()."</store_id>\n";
echo "\t\t<title>".$review->getTitle()."</title>\n";
echo "\t\t<detail>".$review->getDetail()."</detail>\n";
echo "\t\t<nickname>".$review->getNickname()."</nickname>\n";
echo "\t\t<customer_id>".$review->getCustomerId()."</customer_id>\n";
echo "\t\t<product_id>".$review->getEntityPkValue()."</product_id>\n";
echo "\t\t<stores>".implode(",", $review->getStores())."</stores>\n";
echo "\t</review>\n";
}
echo "</reviews>";
?>
Just call the page in your browser (www.yoursite.com/review.php)
This will export all the reviews in xml format. If you want an other format you can manage from this.
The status id is one of these
APPROVED       = 1;
PENDING        = 2;
NOT_APPROVED   = 3;

I hope this helps.

Monday, December 28, 2009

Switching language and currency when having multiple websitecodes (for sonician)

Problem (and maybe better solutions) found here:
http://www.magentocommerce.com/boards/viewthread/71171/

Hi again
There is a way of running a store view directly.
When you call something like this:
Mage::run('website1', 'website');
the default store view from website1 will run.
Let's say in website1 you have a store view called store_view_1. You can run it like this.
Mage::run('store_view_1');
As for the currency, you can set a default currency for each store view.
For example you can have to identical store views (in English), one with default currency 'EUR' and one 'GBP'.
Let's say the first one is called store_view_eur, and the second one store_view_gbp.
You can run them like this.
if (some condition){
Mage::run('store_view_eur');
}
else{
Mage::run('store_view_gbp');
}
As for the IP location, sorry but I don't think I can help you much there.

Thursday, December 24, 2009

Websitecode, currency, language (for sonician)

Problem:
get through code the current values for website, currency and language.
Hello,
Website:
//for name
Mage::app()->getWebsite()->getName();
//for code
Mage::app()->getWebsite()->getCode();
Currency:
Mage::app()->getStore()->getCurrentCurrencyCode();
Language:
This is a little tricky. You can get the ISO code for the language, because by standards French for France is different from French for Belgium
Mage::app()->getLocale()->getLocale();//will return something like fr_FR, fr_BE or en_US
if you want to go further and see only the language code it's simple
$isoCode = Mage::app()->getLocale()->getLocale();
$parts = explode("_", $isoCode);
$language = $parts[0];
$country = $parts[1];

Currency Rounding (for jjones17)

Problem:
Round the currency to the nearest ten ore (ten cents)

Possible solution:

Here is what you can try.
In lib/Zend/Currency.php, in the $_options member of the class change precision from 2 to 1.
This will have the desired effect but also side effects.
All the other currencies besides Norwegian Krone they will all be rounded in the same way.
All prices will look like this 123.4 instead of 123.40.
In order to avoid the first problem instead of changing the precision you can do a "quick and dirty" job.
in Mage_Directory_Model_Currency class for method formatTxt() add this right at the beginning.
if ($this->getCode() == 'NOK'){//if you need it for an other //currency just replace the code here
$options['precision'] = 1;
}

If you want to avoid the last problem (123.4 instead of 123.40) in the same method formatTxt() add add a 0 to the return value
return Mage::app()->getLocale()->currency($this->getCode())->toCurrency($price, $options)."0";

If you don't mind these 2 side effects than I recommended using the first solution. It's less code.

Wednesday, November 25, 2009

Import Simple Products (for barrmy)

You don't need to import the data directly in the into the tables. My suggestion is to use the models provided by magento (that's why it's a MVC).

Create an product instance like this:

$product = Mage::getModel('catalog/product');

set the data you need
$product->setName('PRODUCT NAME');
$product->setDescription('PRODUCT DESCRIPTION');
and so on.
To add stock to this:
$stock_data=array(
'use_config_manage_stock' => 1,
'qty' => 998,
'min_qty' => 0,
'use_config_min_qty'=>1,
'min_sale_qty' => 0,
'use_config_min_sale_qty'=>1,
'max_sale_qty' => 9999,
'use_config_max_sale_qty'=>1,
'is_qty_decimal' => 0,
'backorders' => 0,
'notify_stock_qty' => 0,
'is_in_stock' => 1
);
$product->setData('stock_data',$stock_data);

If you have more that 1 website you must specify on which website to appear
$product->setWebsiteIds(array(1,2));
To add categories:
$product->setCategoryIds(array(7,10));
Set status
$product->setStatus(1);//1=Enabled; 2=Disabled;
Set visibility
$product->setVisibility(4);//4 = catalog & search.
For photos:
$product->addImageToMediaGallery('path/to/photo', array('image', 'small_image', 'thumbnail'), false, false);

second parameter can be replaced by null for a regular image. You can test the difference :)

After all the attributes are set just call
$product->save();
and Magento will put all the attributes in the right table.
If you want to update a product, do the same but instead of creating an "empty" instance of a product, load one.
$product = Mage::getModel('catalog/product')->load(PRODUCT ID);

This will work if you want to modify the default values. If you want to modify the values for a specific store do this.
$product = Mage::getModel('catalog/product')->setStoreId(STORE ID)->load(PRODUCT ID);
These are the basics. If you want a "fine tuned" product creation you just have to play around with the attributes setData() method.

It's not easy. You need some programming skills, but it can be done.

You can find an update to this post here:
http://marius-strajeru.blogspot.com/2010/05/import-products-update.html

Monday, November 23, 2009

Remove category from navigation. (Linking to non active category? for HyekiM)

This is a response for http://www.magentocommerce.com/boards/viewthread/67559/
For versions >= 1.4 this is included in the core (not this, but something similar)
Problem: Linking to a non-active category. Turned into "removing a category from navigation".
Why don't you trey an other approach. Set the category as active and remove it from the navigation.
If you are using drawItem method from 'Mage_Catalog_Block_Navigation' class to list your categories you can do this. Replace
if (!$category->getIsActive()) {
            return $html;
        }
with
if (!$category->getIsActive() || $category->getId() == YOUR CATEGORY ID) {
            return $html;
        }
This is the quick and dirty way to do it.
The clean way is to add a new 'yes/no' attribute on the category object "Show in Navigation (show_in_navigation)", and you can change the code above to:
if (!$category->getIsActive() || !$category->getShowInNavigation()) {
            return $html;
        }

To add a new attribute to the category do this:
Run this sql script on your database
INSERT INTO `eav_attribute` (`attribute_id`, `entity_type_id`, `attribute_code`, `attribute_model`, `backend_model`, `backend_type`, `backend_table`, `frontend_model`, `frontend_input`, `frontend_label`, `frontend_class`, `source_model`, `is_global`, `is_visible`, `is_required`, `is_user_defined`, `default_value`, `is_searchable`, `is_filterable`, `is_comparable`, `is_visible_on_front`, `is_unique`, `is_configurable`, `apply_to`, `position`, `note`, `is_visible_in_advanced_search`, `is_used_for_price_rules`) VALUES
(NULL, 3, 'is_anchor', NULL, '', 'int', '', '', 'select', 'Show in Navigation', NULL, 'eav/entity_attribute_source_boolean', 1, 1, 0, 0, '', 0, 0, 0, 0, 0, 1, '', 1, '', 0, 1);

The second value to insert (3) is the entity_type id for the category object. You can check if this is correct in this table:eav_entity_type.
Take the entity_type_id for entity_type_code 'catalog_category'.

After you run the sql clear the cache (var/cache).
Now you should have the "Show in Navigation" attribute for each category.

Link customer login to store view? (for Pulse Digital Ltd)

This is a response for http://www.magentocommerce.com/boards/viewthread/67624/
Problem: Limit customers to only one store view.

I don't think you can limit a customer to a single store view, and limit his access only to that store view.
The whole idea of store view is that you have multiple versions (languages or currencies) for the same website.
What you can do is to set up 2 (or more) websites, each one with specific prices and/or products and allow the customer to access only that website.
You can find a tutorial here http://www.magentocommerce.com/knowledge-base/entry/overview-how-multiple-websites-stores-work and in the videos reffered here.
For example you set up mysite.com and mysite.eu. They can be hosted on the same machine and moderated form the same admin panel.
After that you can choose not to share the customer accounts from System->configuration->Customer configuration.
In the "Account Sharing Options" section set "Share Customer Accounts" to "Per Website".

Link to first product in category, dynamically (for marcfalk)

This is a response for http://www.magentocommerce.com/boards/viewthread/67625/
Problem: Create a link to the first(smallest id) in stock product in a category.
This is the code to retrieve the first product in stock with the smallest id:
(Let's assume the category id you want to do it for is $categoryId)
$_category = Mage::getModel('catalog/category')->load($categoryId);
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addCategoryFilter($_category);
$collection->getSelect()->joinLeft(
array('_inventory_table'=>$collection->getResource()->getTable('cataloginventory/stock_item')),
"_inventory_table.product_id = e.entity_id",
array('is_in_stock', 'manage_stock')
);
$collection->addExpressionAttributeToSelect('on_top',
'(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR  ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',
array());
$collection->getSelect()->order('on_top DESC');
$collection->getSelect()->order('entity_id ASC');
$collection->getSelect()->limit('1');
if ($collection->count() > 0){
$_product = Mage::getModel('catalog/product')->setStoreId(Mage::app()->getStore()->getId())->load($collection->getFirstItem()->getId());
}
else{
$_product = Mage::getModel('catalog/product');
}

After that in order to print the product url do this:
<?php if ($_product->getId()) : ?>
<a href="<?php echo $_product->getUrl()?>"> First in stock product in category A  (or <?php echo $_product->getName(); ?>)</a>
<?php endif;?>

In case the category has no products at all the link above will not be displayed.
In case all the products in the category are out of stock the link will point to the product with the smallest id.
if you want in this case not to display the link change the if above into:
<?php if ($_product->getId() && $_product->isSalable()) : ?>

Saturday, November 21, 2009

Show description in the product list page (for Vania)

This is an answer for 
http://www.magentocommerce.com/boards/viewthread/67466/
Problem: Show the product long description on the list page.
Hi Vania. You can use in the list.phtml file this.
$_product->getDescription(); 
[UPDATE] For Magento versions that support WYSIWYG editors this is the correct way to display the description:
<?php echo $this->helper('catalog/output')->productAttribute($_product, $_product->getDescription(), 'description') ?>
[/UPDATE]
but Magento does not load all the attributes on the product listing page. Go to the admin pannel Catalod->Attributes-> Manage Attributes and edit the description attribute. Set "Used in product listing" to "Yes". Save and clear the cache.

How to reset the passwords for all the customers (for Andrew)

This is a response for: http://www.magentocommerce.com/boards/viewthread/67065/
Hi Andrew You can create a new php file.
Let's call it customer.php and place it on the same level as index.php file af Magento. Put this code in the file.
error_reporting(E_ALL | E_STRICT);
$mageFilename = 'app/Mage.php';
if (!file_exists($mageFilename)) {
if (is_dir('downloader')) {
header("Location: downloader");
} else {
echo $mageFilename." was not found";
}
exit;
}
require_once $mageFilename;
Varien_Profiler::enable();
Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
umask(0);
Mage::app('default');
$passwordLength = 10;
$customers = Mage::getModel('customer/customer')->getCollection();
foreach ($customers as $customer){
    //[Update 2012-04-19: thanks Michael]
    $customer->load($customer->getId());
    //[/Update 2012-04-19]
    $customer->setPassword($customer->generatePassword($passwordLength))->save();
    $customer->sendNewAccountEmail();
}
?>


then just call the page in your browser http://mydomain.com/customer.php After you finish delete the customer.php file from your server to avoid running it again.

Friday, November 20, 2009

Add one image to just one product (For John Egg)

Problem: http://www.magentocommerce.com/boards/viewthread/67233/
Add an image to only a single product in the view page:
Possible solution:
Add a new 'yes/no' attribute for the products, lets call it 'use_alternative_image'
Edit the product you want the image for and set the attribute to "Yes";
In the view.phtml file, you just have to do this:

<?php if ($_product->getUseAlternativeImage()) : ?>
 <img src="{Your image src}" />
<?php endif; ?> 



This way you can set this image to one ore more products (or none).

Thursday, November 19, 2009

Just to be safe

Yesterday Nov 19th 2009, my magentocommerce forum account and all 300 posts went down the drain, because of a "human error".
Just to be on the safe side I decided to put all answers here, and just reference them on the forum.