Magento Custom Sitemap - php

Magento's default sitemap generation produces an XML file that displays all products, including simple products that are associated with configurable products. I only want the configurable product not the associated simple products, can anyone help me?
In Mage/Sitemap/Model/Sitemap.php the function that generates the XML sitemap is generateXml() and the code block that generates the product urls is:
$changefreq = (string)Mage::getStoreConfig('sitemap/product/changefreq', $storeId);
$priority = (string)Mage::getStoreConfig('sitemap/product/priority', $storeId);
$collection = Mage::getResourceModel('sitemap/catalog_product')->getCollection($storeId);
foreach ($collection as $item) {
$xml = sprintf('<url><loc>%s</loc><lastmod>%s</lastmod><changefreq>%s</changefreq><priority>%.1f</priority></url>',
htmlspecialchars($baseUrl . $item->getUrl()),
$date,
$changefreq,
$priority
);
$io->streamWrite($xml);
}
unset($collection);
I tried using
Mage::getModel('catalog/product')->getCollection();
and changed this line:
htmlspecialchars($baseUrl . $item->getUrl()),
to this line to get it work
htmlspecialchars($item->getProductUrl()),
I get the correct products (without the associated ones), but the urls are like this:
http://www.domain.com/catalog/product/view/id/532/
I want the Url Rewrites, so i changed it to:
$collection = Mage::getModel('catalog/product')->getCollection($storeId)
->addUrlRewrite();
But i still get this:
http://www.domain.com/catalog/product/view/id/532/
Any ideas what's wrong?

you can try with below code.
$product_collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('entity_id', 16)->addUrlRewrite();
echo $product_collection->getFirstItem()->getProductUrl();
or you can load url separately as you already have product collection than try something like this
Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($productId, 'attribute_code', Mage::app()->getStore());

Related

Magento - Get the associated product attributes of an item in the wishlist

In app/code/local/Mage/Catalog/Product/Type/Configurable/Price.php, I am trying to get the attribute values of an associated product within the wishlist. I've attempted several approaches but I can only seem to produce data for the parent product.
Latest attempt
$customer = Mage::getSingleton('customer/session')->getCustomer();
if($customer->getId()) {
$wishlist = Mage::getModel('wishlist/wishlist')->loadByCustomer($customer, true);
$wishListItemCollection = $wishlist->getItemCollection();
foreach ($wishListItemCollection as $wlitem) {
$wishitem = Mage::getModel('catalog/product')->setStoreId($wlitem->getStoreId())->load($wlitem->getProductId());
//echo $wishitem->getId() . '<br>';
if($product->getId() == $wishitem->getId()) { //if the current product id equals the wishlist product id
echo $wishitem->getSku()."</br>";
}
}
}
That only gets me the parent product's sku. What I ultimately want to get is the attribute value for 2 attributes that I added for configurable products (not super attributes) but it seems that $product in Price.php only has the parent product collection.
Other Attempts:
$item_s = Mage::getModel('wishlist/item')->loadWithOptions($product->getId(), 'simple_product')->getOptionsByCode();
$simple_product = $item_s['simple_product']->getData();
$simple_product_id = $simple_product['product_id'];
$sim_product = Mage::getModel('catalog/product')->load($simple_product_id);
print_r($sim_product);
This only resulted in an error on the page.
Also:
$_item = Mage::getModel('catalog/product')->load($product->getId());
//echo $_item->getData('ppuom');
//print_r($_item);
$simpleProduct = $_item->getOptionsByCode()['simple_product']->getItem()->getProduct();
print_r($simpleProduct);
Seems as if you were most of the way there. I've tested this on my Magento site and it worked for me. It's pretty simple actually, you just have to grab the right model for that collection. Also, it seems like you're changing the pricing?!?! Be careful that your wishlist items contain the necessary attributes used in your logic.
$_item = Mage::getModel('catalog/product')->load($product->getId());
$attribute1 = $_item->getData('attribute1_code'); //see admin for attribute code
$attribute2 = $_item->getData('attribute2_code'); //see admin for attribute code
OR
Make changes to your template's wishlist files rather than the pricing logic in the code folder. You'll have access to all the data you need and it won't interfere with the price.php file which is relied on heavily in the cart and other critical areas of the website. The price in the wishlist is recalculated when it's moved to the cart anyway.

Get custom attribute from product in Magento 1.9

I'm trying to fetch some product data based on the products SKU. This is working, but I also need to get a custom added attribute at the same time, named 'sku_supplier'. Is this possible?
This is what I got:
require $_SERVER['DOCUMENT_ROOT'] . "/app/Mage.php";
Mage::app();
$sku = '748547';
$products = Mage::getResourceModel('catalog/product_collection');
$products->addAttributeToSelect('*');
$products->addAttributeToFilter('visibility', array('neq' => 1));
$products->addAttributeToFilter('status', 1);
$products->addAttributeToFilter('sku', $sku);
$products->setCurPage(1)->setPageSize(1);
$products->load();
if ($products->getFirstItem()) {
$product = $products->getFirstItem();
$strProdName = $product->getName();
$strProdSku = $product->getSku();
$strProdSkuSup = $product->getSku_Supplier(); // <= I want to show this
}else{
$addError = 'true';
$addErrorMessage[] = 'Error...';
}
Thanks in advance,
Just remove the underscore:
$strProdSkuSup = $product->getSkuSupplier();
$strProdSkuSup = $product->getData('sku_supplier'); //alternative
Magento translates snake_case into camelCase when you want to use the magic getters; ie. an attribute with the attribute code cool_custom_attribute would translate into coolCustomAttribute, i.e. $product->getCoolCustomAttribute().
Edit:
You might need to load a product model as sometimes I've experienced that not all custom attributes are attached when you pull it out of a collection (intended for performance reasons I guess). Something like:
$_product = Mage::getModel('catalog/product')->load($product->getId());
$strProdSkuSup = $_product->getSkuSupplier();
Also, did you know that there's a dedicated StackExchange site for Magento?
Use this
$strProdSkuSup = $product->getSkuSupplier();
Instead of
$strProdSkuSup = $product->getSku_Supplier();

How to query magento database tables to show categories and products?

I have a PHP website and now the I want to add a shopping cart to my existing php website.
So I am using magento for this.
In the directory of my website I have created a new directory with the name of "shop" and put magento in this directory.
My website is working fine. But on website's home page I want to show categories and products from the magento site so it is not possible to use the magento built-in functions for this as my website's home page is out the magento site.
So I think I should query the magento database tables for this but the magento database tables are so complex so any body who can give me some idea about this problem?
Is there any other way to solve my problem and if the only the query is the solution then how will I query the magento database tables to show categories and products.
Thanks in advance.
I would try something like this:
require 'shop/app/Mage.php';
/* Run magento app */
Mage::app();
function get_categories(){
$category = Mage::getModel(’catalog/category’);
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
$arr = array();
if ($ids){
foreach ($ids as $id){
$cat = Mage::getModel(’catalog/category’);
$cat->load($id);
array_push($arr, $cat);
}
}
return $arr;
}
$categories = get_categories();
foreach($categories as $cat) {
echo "<br />Category: " . $cat->getName();
$collection = $cat->getProductCollection();
foreach ($collection as $item) {
$product = Mage::getModel("catalog/product")->load($item->getId());
echo "<br />Product: " . $product->getName();
}
}
You need not to write complex queries to show some categories in homepage. But instead you can add the below in your homepage (Menu > CMS > Pages > Homepage)
{{block type="catalog/product_list" category_id="3" template="catalog/product/list.phtml"}}
where category_id is the id of the category to be shown. See screenshot to get cat id.

Magento - load only configurable products

I have the following code:
$_productCollection = $this->getLoadedProductCollection();
foreach ($_productCollection as $_product)
{
if ($_product->_data['type_id'] == 'configurable')
{
...
}
}
While it does what it's supposed to do, it greatly slows down page load time. Is it possible to load only configurable products and remove the check for 'configurable'? The store has 12000 products, about 700 are configurable and the rest are child simple products.
I found the following code which returns all configurable products. I need only the products within the current category:
$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('type_id', array('eq' => 'configurable'));
The problem with getLoadedProductCollection() is it's already loaded - the products' data has already been retrieved from the database. Just using the current category's product collection isn't good enough either, that will ignore the "layers" (attribute filters). The trick is to remove the loaded products from the list first.
// First make a copy, otherwise the rest of the page might be affected!
$_productCollection = clone $this->getLoadedProductCollection();
// Unset the current products and filter before loading the next.
$_productCollection->clear()
->addAttributeToFilter('type_id', 'configurable')
->load();
print_r($_productCollection) has it's issues too, you're not just outputting the products but also all details of the resource that is the database connection, and cached values, and the products' individual resources, and so on...
In this case I think you would be happier with:
print_r($_productCollection->toArray())
All those solutions didn't work for me, try this:
$_productCollection1 = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('*')
->addAttributeToFilter('type_id','configurable');
foreach ($_productCollection1 as $product1) {
echo $product1->getName();
...
}
It works but don't know if it's correct (I'm new to Magento). Let me know please.
The way you're doing this requires all products to be loaded before you parse through and filter them. This is probably closer to what you're looking for:
$_productCollection = $this ->getLoadedProductCollection()
->addAttributeToFilter('type_id','configurable');
Try following
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('type_id','configurable');
foreach($collection as $product)
{
}
For loading configurable and simple as well try
$collection->addAttributeToFilter('type_id', array('in' => array('configurable','simple')));
Here is the code for getting only configurable products:
$Config_products = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('type_id','configurable');
Use \Magento\Catalog\Model\ResourceModel\Product\Collection $_productcollection,
public function getConfigProducts() {
$configproducts = $this->_productcollection;
$configproducts->addAttributeToSelect('*');
$configproducts->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
$configproducts->addAttributeToFilter('show_in_price_page', array('eq' => 1));
$configproducts->addAttributeToFilter('type_id', array('eq' => "configurable"));
return $configproducts;
}
If you change Visibility of simple product to "Not Visible Individually", Magento will not load it to display in product list page.

Copy and Paste Category in Magento

I want to copy my first category to a second category in Magento.
What should I do?
Thanks,
Wesley.
By code:
<?php
$category = Mage::getModel('catalog/category')
->load(123); // The ID of the category you want to copy.
$copy = clone $category;
$copy->setId(null) // Remove the ID.
->save();
If you want to do it in a programmatic way you can use the Magento API.
Use:
catalog_category.info - to read a category
catalog_category.create - to create a new one by copying data from existing.
Here are the docs for category API
I wouldn't clone the category object, but rather do something like this (using the Magento API - http://www.magentocommerce.com/wiki/doc/webservices-api/catalog_category ):
get the category which must be copied
$source_category = Mage::getModel('catalog/category')->load($id);
Create a new category using the API
$CategoryApi = new Mage_Catalog_Model_Category_Api();
$parent_id = /* Location for the new category */
$new_category_id = $CategoryApi->create(
$parent_id,
array(
/* Attributes to fill with source category values. */
)
);
Get the source category products and place them in the new category, again with the API.
$products = $CategoryApi->assignedProducts(source_category->getId());
foreach($products as $product)
{
$CategoryApi->assignProduct($product->getId())
}
Above must be done recursively for each subcategory.
Note: Using the API ensures your code will still work when you upgrade the Magento core.
All the replies here were not complete. I did a script that does the total Creating the new category, subcategories and assigning the products to them.
public function run()
{
$categoryId = 123;
// Change this if you want the copy to be under another category than the default
$baseCategoryId = 2;
$category = Mage::getModel('catalog/category')->load($categoryId);
$defaultCategory = Mage::getModel('catalog/category')->load($baseCategoryId);
$this->duplicate($category, $defaultCategory, 1);
}
private function duplicate($categoryToClone, $parentCategory, $level)
{
// This will clone the clild and assign it to the new parent
$newCategory = clone $categoryToClone;
$newCategory->setPath($parentCategory->getPath())
->setParentId($parentCategory->getId())
->setId(null);
// Optional, Only change the new with suffix with "new" for the first
if ($level == 1) {
$newCategory->setUrlKey($categoryToClone->getUrlKey() . '-new')
->setName($categoryToClone->getName() . '(new)');
}
// Assign all products from the cloned category to the new
$newCategory->setPostedProducts($categoryToClone->getProductsPosition());
$newCategory->save();
// Applies the changes to the subcategories infinite levels
$subcategories = $categoryToClone->getChildrenCategories();
if (count($subcategories) > 0) {
foreach ($subcategories as $subcategory) {
$this->duplicate($subcategory, $newCategory, ++$level);
}
}
}
You can't with the admin interface, you need. to create a script with the category api.
Sorry you cannot copy/paste Category directly in Magento Admin panel through the interface, which Catalog Products can offer with the help of "Duplicate" button.
I suppose you will need to write a script fetching the category details by first loading the Category model with the required Category ID.
This forum post contains instructions and code for importing your categories from a CSV file.
Good luck,
JD
I think you want to export products from a specific cat and import it to another one. if it's so use the steps bellow:
login to magento backend
navigate to System -> Import/Export
Create a new advanced profile for your cat
export it
now import it in the same fashion
Sometime we need to copy same products to another category.(Like we have two stores with same category or within same store need to copy the category products to somewhere else)
Adding product from back-end is very time consuming process you can do it by code.
You can create a file in your root directory copy-products.php with the following code to copy product:
<?php
require_once ( "app/Mage.php" );
umask(0);
// Initialize Magento
Mage::app();
$category = Mage::getModel('catalog/category');
$category->load('24'); // Category id you want to copy
$collection = $category->getProductCollection();
$collection->addAttributeToSelect('*');
foreach ($collection as $product) {
$product->getId();// Now get category ids and add a specific category to them and save?
$categories = $product->getCategoryIds();
$categories[] = 29; // Category id you want to add
$product->setCategoryIds($categories);
$product->save();
}
?>

Categories