Magento Product Insert Function - magento

I need to add a custom option to all products as they get saved. For that I need to find the function that inserts the products into the database, which I'm not able to find.
Please, any help would be appreciated.
thanx

$client = new SoapClient('http://www.magentolocal.it/api/?wsdl');
$session = $client->login('productloader', '1234567890');
$sku = "123456";
$attrs['name'] = "Template #1";
$attrs['description'] = "This is the first template.";
$attrs['short_description'] = "This is the short description of the template";
$attrs['websites'] = array('1');
$attrs['price'] = "11.53";
$attrs['categories'] = array('35');
$attrs['images'] = array()
$result = $client->call($session, 'catalog_product.create', array('simple', '63', $sku, $attrs));
echo $result;
$client->endSession($session);

Magento's EAV system is pretty strung out among several files, so you won't find a single function that accomplishes what you want. If you did go looking for it, and changed it, you would also be changing the same save method that mostly every other object in Magento uses, which is probably not what you want.
To do what you want, try setting up an observer/listener on the events that catalog products use when saving, namely catalog_product_save_before or catalog_product_save_after. That way, you don't have to hack the framework.
Hope that helps!
Thanks,
Joe

How about http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_product#catalog_product.create?

Related

How can I sort a loaded product collection in Magento?

I want to sort a product collection that is already loaded by
$_productCollection = $this->getLoadedProductCollection();
The default sort in admin Magento is Style attribute
I want to sort first by Style, then by color and then by name.
I've try
$_productCollection->setOrder(array('style', 'color','name'), asc);
and also
$_productCollection->addAttributeToSort('color', Varien_Data_Collection::SORT_ORDER_ASC);
$_productCollection->addAttributeToSort('name', Varien_Data_Collection::SORT_ORDER_ASC);
but is not working.
The default sort is working good. Can someone please help?
You can do it this way:
$_productCollection = $this->getLoadedProductCollection();
$_productCollection->clear();
$_productCollection->addAttributeToSort('color', Varien_Data_Collection::SORT_ORDER_ASC);
foreach ($_productCollection as $product) {
// ...
}
This way the collection is forced to be reloaded and then your custom sorting is applied.
You can also take clone of the loaded collection and then modify the query as you want.
// clone of the current collection.Better way of modifying the colection
$_productCollection = clone $this->getLoadedProductCollection();
// unset the cuurent coolection and append your custom filter.
$_productCollection->clear()
->addAttributeToFilter('color', Varien_Data_Collection::SORT_ORDER_ASC)
->load();
Nothing here or elsewhere worked for me. No matter what I tried it would just not sort on /Magento_Catalog/templates/product/list.phtml using 'getLoadedProductCollection()'. Also had a weird issue where products would disappear after clearing cache, until a reindex was done. No idea what was going on there, something was not right.
So I got it to work in the hacky way below (Yes I know it's not 'best practice' to use object manager but it was the only thing that worked!!)
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$categoryId = 2;
$category = $_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
$productCollection = $_objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$_productCollection = $productCollection->create()
->addAttributeToSelect('*')
->setOrder('position', 'ASC')
->addCategoryFilter($category)->load();
If you have products in a collection that need more advanced sorting/oordering you can move the products to an assoc array which is much easier to sort/order as you like. Once the order is as you like you can add them back by first clearing your collection with $collection-removeAllItems() and then iterate your array as $product and move each product back to the collection with $collection->addItem($product);
I used this when I wanted a sticky that was not touched by different ordering/sorting.
You can use setOrder on collection to sort any collection data like below :
$_productCollection->setOrder('id','DESC');
Where id can be replace with your column name, & second parameter can be DESC & ASC as per your requirement.
Have it working in v2.3.7 using the following
$_productCollection = $block->getLoadedProductCollection();
$_productCollection->getSelect()->reset(Zend_Db_Select::ORDER);
$_productCollection->setOrder('price', 'ASC');

Programmatically modify related products in magento

I'm trying to programmatically manipulate the product relations in a Magento store.
From what I've read, setRelatedLinkData should be the way to go.
As I simple test, I'm just trying to replace a products related products with nothing (i.e. an empty array), however it's not working - the product in question is still showing the related product in the backend.
The test code I'm working with is:
$product = Mage::getModel('catalog/product')->load($product->getId());
$linkData = array();
print_r($linkData);
$product->setRelatedLinkData($linkData);
echo "Save\n";
$r = $product->save();
As mentioned above however the product still has a related product when I reload it in the backend.
NOTE: I don't only want to remove related products, eventually I want to be able to add new ones as well, so a DELTE FROM... SQL query isn't what I am looking for. However if I can't get it to work to remove products, then it's certainly not going to work to add them, so one step at a time :-)
The quickest way I can think of is to use the Link Resource:
app/code/core/Mage/Catalog/Model/Resource/Product/Link.php saveProductLinks
// sample code
$product = Mage::getModel('catalog/product')->load(147);
$linkData = array();
Mage::getResourceModel('catalog/product_link')->saveProductLinks(
$product, $linkData, Mage_Catalog_Model_Product_Link::LINK_TYPE_RELATED
);
and if you want to assign products use the same code but provide this as $linkData:
$linkData = array(
'145' => array('position' => 1),
'146' => array('position' => 2)
);

Which way is better to load models in magento?

I don't know if i am asking that right.I need to load a product, change some values and save it. My question is which way is the appropriate to do it.Currently i am using that way:
$id = Mage::getModel('catalog/product')->getIdBySku($sku);
$product = Mage::getModel('catalog/product')->load($id);
1) In general it works fine even with 40K products.But i read that this way is leading to memory leak? Also for that solution i read that if i disable the reindex functionality i can improve the process time.
2) If i use another way and load it as a collection and then apply some filters, ex addFieldToFilter('sku',$the_product_i_want)
would be better?
When i say better i mean: 1)the magento way, 2)time efficient 3)not doing something that i don't need to do.
Each time you call the following code snippet Mage::getModel('catalog/product') Magento will create a new model object in the memory. And that will lead to memory wastage. You can do as follows.
$model = Mage::getModel('catalog/product');
$id = $model->getIdBySku($sku);
$product = $model->load($id);
At the same time if you have the product object you can use the following code.
$collection = Mage::getModel('catalog/product')->getCollection();
$product = $collection->addFieldToFilter('sku',$the_product_i_want);

Magento getProductUrl() is not returning the right url (random?)

I am using Magento 1.5.0.1 and the getProductUrl() function used in the cross sell and up sell blocks on the product page is throwing up different URL formats.
Either the correct url like:
/laptop-bag.html
Or the wrong one (well it works, but of course its not the rewrite URL):
/catalog/product/view/id/825/s/laptop-bag/category/16/
Sometimes both cross sell and up sell blocks return the correct URL, sometimes both use the longer version, and in some cases, one uses the correct and the other uses the long version??
Any ideas why this is happening?
I have already run a magento database repair, reindexed, and refreshes / flushed all caches.
Try $product->getUrlPath() instead of $product->getProductUrl()
UPDATE: As per below comment by #jordan314, Magento recommends to EE customers:
The url_path attribute is no longer used as of 1.13 but is still available for backward-compatibility, and Magento will not assign a value to it for new products, so it's not recommended to continue using it. Perhaps you could try using $product->getProductUrl() instead.
The incorrect url is generated because it can't find the rewritten url.
Maybe it is caused because incorrect store_id.
eg:
$id = 290;
Mage::app()->setCurrentStore('default');
echo "store_id: ".Mage::app()->getStore()->getId()."<br>";
$url = Mage::helper('catalog/product')->getProductUrl($id);
echo $url."<br>";
//change store id
Mage::app()->setCurrentStore('admin');
echo "store_id: ".Mage::app()->getStore()->getId()."<br>";
$url = Mage::helper('catalog/product')->getProductUrl($id);
echo $url."<br>";
result:
store_id: 1
http://local.com/surestep-pro-diabetic-test-strips-50-strips-professional-care.html
store_id: 0
https://local.com/index.php/catalog/product/view/id/290/s/surestep-pro-diabetic-test-strips-50-strips-professional-care/
The correct url rewrite can be found in table named core_url_rewrite (including the information about the store_id)
If it found match value in core_url_rewrite, it will generate 'the correct url' else it will concat the product_id + url key + category_id
$routePath = 'catalog/product/view';
$routeParams['id'] = $product->getId();
$routeParams['s'] = $product->getUrlKey();
if ($categoryId) {
$routeParams['category'] = $categoryId;
}
Try add this when you're getting your collection
$collection->addUrlRewrite();
It has helped me.
$id = 10;
Mage::app()->setCurrentStore('admin');
$url = Mage::helper('catalog/product')->getProductUrl($id);

Programmatically ship and comment single item of an order in Magento

I know there is a way to programmatically invoice, ship, and set state on an order (http://www.magentocommerce.com/boards/viewthread/74072/), but I actually need to drill down even deeper to the item level of an order. We have a situation where, depending on item type, two different items can be processed in two different locations (from the same order). I can go into the Magento back-end and "ship" one item without "shipping" the other and append comments to that one item, but I'm looking for a way to do this programmatically. Thank you in advance for your help!
Update:
Here is the code I ended up using to accomplish this:
$client = new SoapClient('http://somesite.domain/magento/index.php/api/?wsdl');
$session = $client->login('username', 'password');
function extract_item_id($items, $sku ){
foreach($items as $item ){
if ($item["sku"]==$sku) {
return $item["item_id"];
}
}
}
$orderNum = "200000052";
$oderInfo = $client->call($session, "sales_order.info", $orderNum );
$item_id = extract_item_id($oderInfo["items"], "someSKU") ;
$itemsQty = array( $item_id => "1" );
$shipment = array(
$orderNum,
$itemsQty,
"Comment associated with item shipped.",
true,
true
);
var_dump($shipment);
$nship = $client->call($session, 'sales_order_shipment.create', $shipment);
I've never done it, but it looks like the SOAP API supports creating individual shipment items. That'd be the first thing I'd check.
If that doesn't work, I'd examine the source code the the Magento admin and reverse engineer what its doing with to create a single item shipment. Specifically, start tracing at the saveAction of the admin's Shipment Controller
app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php
The order/shipment/invoice section of Magento codebase is one of the most volatile/iterative sections, with the core objects/methods/dependencies changing subtly between versions. Finding one "right" answer for this will prove difficult, if not impossible.

Resources