Magento: UPDATE and DELETE programatically from frontend, not working? - magento

i am trying to update the product from frontend but it does not let me update all the fields of the product,
Here is the code of index controller FOR UPDATING:
public function updateVproductAction(){
if($addvp = $this->getRequest()->getPost())
{
/*********************** Product Update ***************************/
/**
* Get the resource model
*/
$resource = Mage::getSingleton('core/resource');
/**
* Retrieve the write connection
*/
$writeConnection = $resource->getConnection('core_write');
/**
* Retrieve our table name
*/
$table = $resource->getTableName('catalog/product');
/**
* Set the product ID
*/
$productId = $addvp['product']['id'];
/**
* Set the new SKU
* It is assumed that you are hard coding the new SKU in
* If the input is not dynamic, consider using the
* Varien_Db_Select object to insert data
*/
//$newSku = 'new-sku';
$sku = $addvp['product']['sku'];
$name = $addvp['product']['name'];
$description = $addvp['product']['description'];
$short_description = $addvp['product']['short_description'];
$weight = $addvp['product']['weight'];
$news_from_date = $addvp['product']['news_from_date'];
$news_to_date = $addvp['product']['news_to_date'];
$status = $addvp['product']['status'];
$price = $addvp['product']['price'];
$special_price = $addvp['product']['special_price'];
$tax_class_id = $addvp['product']['tax_class_id'];
$meta_title = $addvp['product']['meta_title'];
$meta_keyword = $addvp['product']['meta_keyword'];
$meta_description = $addvp['product']['meta_description'];
$stock_data = array(
'is_in_stock' => 1,
'qty' => $addvp['product']['stock_data']['qty']
);
$query = "UPDATE {$table} SET sku = '{$sku}', name = '{$name}', description = '{$description}', short_description = '{$short_description}', weight = '{$weight}', news_from_date = '{$news_from_date}', news_to_date = '{$news_to_date}', status = '{$status}', price = '{$price}', special_price = '{$special_price}', tax_class_id = '{$tax_class_id}', meta_title = '{$meta_title}', meta_keyword = '{$meta_keyword}', meta_description = '{$meta_description}', stock_data = '{$stock_data}' WHERE entity_id = "
.(int) $productId;
try
{
/**
* Execute the query
*/
$writeConnection->query($query);
echo "successfully updated product with ID: ". $productId ."<br />";
}
catch (Exception $e)
{
echo "Could not update product with ID: ". $productId ."<br />";
}
}
}
Can anyone please help and correct me where i am wrong ?
For Deleting a product i am simply calling this function from Helper :
public function vDeleteproduct($vprod){
//print_r($vprod); exit;
try
{
$product = Mage::getSingleton('catalog/product')->load($vprod);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
//$product = Mage::getModel('catalog/product')->load($vprod)->delete();
echo "successfully deleted product with ID: ". $vprod ."<br />";
}
catch (Exception $e)
{
echo "Could not delete product with ID: ". $vprod ."<br />";
}
return;
}
It too don't work :(
Plz help.

FOR DELETING PRODUCTS :
i have found the answer for this by just giving access to delete from non-admin area (i.e. frontend). And it did the magic for me.
http://inchoo.net/ecommerce/magento/programming-magento/how-to-delete-magento-product-from-frontend-template-code-from-view-files/
Above link helped me to find the solution.

Related

Magento - Mage_Core_Exception: Please select a valid payment method

I create order promatically with below code
function createSaleOrderForMagento()
{
$customer_id = $this->sale_lib->get_customer();
$items = $this->sale_lib->get_cart();
if($customer_id==-1)
{
return;
}
$cust_info = $this->Customer->get_info($customer_id);
$primaryAddress = $cust_info->getPrimaryShippingAddress();
require_once '../app/Mage.php';
Mage::init();
$websiteId = Mage::app()->getWebsite()->getId();
$store = Mage::app()->getStore();
// Start New Sales Order Quote
$storeId=$store->getId();
$quote = Mage::getModel('sales/quote')->setStoreId($storeId);
// Set Sales Order Quote Currency
$baseCurrencyCode = Mage::app()->getStore($storeId)->getBaseCurrencyCode();
$currentCurrencyCode = Mage::app()->getStore($storeId)->getCurrentCurrencyCode();
$quote->setCurrency('VND');
$customer = Mage::getModel('customer/customer')->load($customer_id);
// Assign Customer To Sales Order Quote
$quote->assignCustomer($customer);
// Configure Notification
$quote->setSendCconfirmation(0);
foreach($items as $line=>$item)
{
$product=Mage::getModel('catalog/product')->load($item['item_id']);
$quote->addProduct($product,new Varien_Object(array('qty' => 1)));
}
// Set Sales Order Billing Address
// set Billing Address
$billing = $customer->getDefaultBillingAddress();
$billingAddress = Mage::getModel('sales/order_address')
->setStoreId($storeId)
->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_BILLING)
->setCustomerId($customer->getId())
->setCustomerAddressId($customer->getDefaultBilling())
->setCustomer_address_id($billing->getEntityId())
->setPrefix($billing->getPrefix())
->setFirstname($billing->getFirstname())
->setMiddlename($billing->getMiddlename())
->setLastname($billing->getLastname())
->setSuffix($billing->getSuffix())
->setCompany($billing->getCompany())
->setStreet($billing->getStreet())
->setCity($billing->getCity())
->setCountry_id($billing->getCountryId())
->setRegion($billing->getRegion())
->setRegion_id($billing->getRegionId())
->setPostcode($billing->getPostcode())
->setTelephone($billing->getTelephone())
->setFax($billing->getFax());
$quote->setBillingAddress($billingAddress);
// Set Sales Order Shipping Address
$shipping = $customer->getDefaultShippingAddress();
$shippingAddress = Mage::getModel('sales/order_address')
->setStoreId($storeId)
->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)
->setCustomerId($customer->getId())
->setCustomerAddressId($customer->getDefaultShipping())
->setCustomer_address_id($shipping->getEntityId())
->setPrefix($shipping->getPrefix())
->setFirstname($shipping->getFirstname())
->setMiddlename($shipping->getMiddlename())
->setLastname($shipping->getLastname())
->setSuffix($shipping->getSuffix())
->setCompany($shipping->getCompany())
->setStreet($shipping->getStreet())
->setCity($shipping->getCity())
->setCountry_id($shipping->getCountryId())
->setRegion($shipping->getRegion())
->setRegion_id($shipping->getRegionId())
->setPostcode($shipping->getPostcode())
->setTelephone($shipping->getTelephone())
->setFax($shipping->getFax())->setShippingMethod('freeshipping_freeshipping');
$quote->setShippingAddress($shippingAddress)
->setShipping_method('freeshipping_freeshipping')
->setPaymentMethod('checkmo');
$quote->save();
$quote->getShippingAddress()
->setShippingMethod('freeshipping_freeshipping')
->setCollectShippingRates(true)
->setPaymentMethod('checkmo')
->collectTotals();
$quote->save();
// Create Order From Quote
$service = Mage::getModel('sales/service_quote', $quote);
//var_dump($service);
$service->submitAll();
$increment_id = $service->getOrder()->getRealOrderId();
// Resource Clean-Up
$quote = $customer = $service = null;
// Finished
return $increment_id;
}
But I got an error :
( ! ) Fatal error: Uncaught exception 'Mage_Core_Exception' with
message 'Please select a valid payment method.' in
C:\wamp\www\pmc\app\Mage.php on line 595
( ! ) Mage_Core_Exception: Please select a valid payment method. in C:\wamp\www\pmc\app\Mage.php on line 595
Please help me to solve this problem
If you check the condition of this error outputting, you will see next:
if (!($this->getQuote()->getPayment()->getMethod())) {
Mage::throwException(Mage::helper('sales')->__('Please select a valid payment method.'));
}
Which means that you need to initialize you Mage_Sales_Model_Quote_Payment model and set there your payment method:
$quote->getPayment()->setMethod('checkmo');

Magento Order History Comments: Modify Date

I am creating a script to add orders programmatically in Magento. I need help to change the date of the entries in the Comments History (quote, invoice, shipping, etc.). I can manipulate the date of the order itself (setCreatedAt) and some of the comments related to the creation of the order are correct (e.g. "Sep 29, 2008 8:59:25 AM|Pending Customer Notification Not Applicable"), but I cannot change the date of the comment when I use addStatusHistoryComment...
Here's a snippet of my code:
try {
if(!$order->canInvoice()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
}
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->setCreatedAt('2008-09-23 13:05:20');
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
- >addObject($invoice->getOrder());
$transactionSave->save();
//END Handle Invoice
//START Handle Shipment
$shipment = $order->prepareShipment();
$shipment->setCreatedAt('2008-09-23 14:20:10');
$shipment->register();
$order->setIsInProcess(true);
$order->addStatusHistoryComment('Shipping message goes here...', true);
$shipment->setEmailSent(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
$track = Mage::getModel('sales/order_shipment_track')
->setShipment($shipment)
->setData('title', 'Some tracking no.')
->setData('number', '111222333444')
->setData('carrier_code', 'fedex') //custom, fedex, ups, usps, dhl
->setData('order_id', $shipment->getData('order_id'))
->save();
//END Handle Shipment
}
catch (Mage_Core_Exception $ex) {
echo "Problem creating order invoice and/or shipment: ".$ex."\n";
}
Thanks in advance.
If I understand your question correctly, you just need to do this:
$comments = $order->getStatusHistoryCollection(true);
$comments now contains a collection of all the status history comments, and you can loop over them with whatever sort of criteria you like.
foreach ($comments as $c) {
if ( /* some stuff */ ) {
$c->setData('created_at',$new_date)->save();
}
}
So this is untested, but should work:
You need to create a new method based off addStatusHistoryComment:
/app/code/core/Mage/Sales/Model/Order.php
/*
* Add a comment to order
* Different or default status may be specified
*
* #param string $comment
* #param string $status
* #return Mage_Sales_Model_Order_Status_History
*/
public function addStatusHistoryComment($comment, $status = false)
{
if (false === $status) {
$status = $this->getStatus();
} elseif (true === $status) {
$status = $this->getConfig()->getStateDefaultStatus($this->getState());
} else {
$this->setStatus($status);
}
$history = Mage::getModel('sales/order_status_history')
->setStatus($status)
->setComment($comment)
->setEntityName($this->_historyEntityName);
->setCreatedAt('2008-09-23 14:20:10'); //I added this line
$this->addStatusHistory($history);
return $history;
}
Obviously you either need to rewrite this method, or refactor the code to do the same.

Creating categories and sub-categories in Magento Extension

I am new to Magento Extension Development and wondering which is the best way to create categories and sub-categories from within an extension. The Extension I am working on is synchronizing product-data from an ERP-System. The extension is operating with a System->Configuration Dialog which holds the data for the connection to the server (user/pwd/etc.) Now I am wondering, if it is better to connect via Ajax request or use a Soap call. Ajax seems very slow in this case for about 700 Products. So what do you suggest?
Furthermore, I am a little stuck by creating categories and sub-categories. Is there simple way to do that. I found some stuff on creating a category and then use the ->move() function. Moreover I am wondering if the 'path' of the category is essential on creating sub-categories.
You should use magento models:
Create category with subcategory:
/**
* After installation system has two categories: root one with ID:1 and Default category with ID:2
*/
/** #var $category1 Mage_Catalog_Model_Category */
$category1 = Mage::getModel('catalog/category');
$category1->setName('Category 1')
->setParentId(2)
->setLevel(2)
->setAvailableSortBy('name')
->setDefaultSortBy('name')
->setIsActive(true)
->setPosition(1)
->save();
/** #var $category2 Mage_Catalog_Model_Category */
$category2 = Mage::getModel('catalog/category');
$category2->setName('Category 1.1')
->setParentId($category1->getId()) // set parent category which was created above
->setLevel(3)
->setAvailableSortBy('name')
->setDefaultSortBy('name')
->setIsActive(true)
->setIsAnchor(true)
->setPosition(1)
->save();
public static function addCatalogCategory($item, $id, $storeId = 0) {
/*
* resource for checking category exists
* http://fishpig.co.uk/blog/load-a-category-or-product-by-an-attribute.html
*/
$categories = Mage::getResourceModel('catalog/category_collection');
// Select which fields to load into the category
// * will load all fields but it is possible to pass an array of
// select fields to load
$categories->addAttributeToSelect('*');
// Ensure the category is active
$categories->addAttributeToFilter('is_active', 1);
// Add Name filter
$categories->addAttributeToFilter('name', $item->GROUP_NAME);
// Limit the collection to 1 result
$categories->setCurPage(1)->setPageSize(1);
// Load the collection
$categories->load();
if ($categories->getFirstItem()->getId()) {
$category = $categories->getFirstItem();
return $category->getId();
}
/* get category object model */
$category = Mage::getModel('catalog/category');
$category->setStoreId($storeId);
$data = array();
/* if the node is root */
if (Heliumv_Synchronization_Helper_Data::xml_attribute($item, 'type') == 'root') {
$data['category']['parent'] = 2; // 2 top level id
} else {
/* is node/leaf */
$data['category']['parent'] = $id;
}
$data['general']['path'] = $item->PARENT_ID;
$data['general']['name'] = $item->GROUP_NAME;
$data['general']['meta_title'] = "";
$data['general']['meta_description'] = "";
$data['general']['is_active'] = "1";
$data['general']['url_key'] = "";
$data['general']['display_mode'] = "PRODUCTS";
$data['general']['is_anchor'] = 0;
/* add data to category model */
$category->addData($data['general']);
if (!$category->getId()) {
$parentId = $data['category']['parent'];
if (!$parentId) {
if ($storeId) {
$parentId = Mage::app()->getStore($storeId)->getRootCategoryId();
} else {
$parentId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
}
}
$parentCategory = Mage::getModel('catalog/category')->load($parentId);
$category->setPath($parentCategory->getPath());
}
$category->setAttributeSetId($category->getDefaultAttributeSetId());
try {
$category->save();
return $category->getId();
} catch (Exception $e) {
echo Mage::log($e->getMessage());
}
}
I hope this helps someone. cheers

Magento Product Attribute Get Value

How to get specific product attribute value if i know product ID without loading whole product?
Mage::getResourceModel('catalog/product')->getAttributeRawValue($productId, 'attribute_code', $storeId);
A way that I know of:
$product->getResource()->getAttribute($attribute_code)
->getFrontend()->getValue($product)
you can use
<?php echo $product->getAttributeText('attr_id') ?>
Please see Daniel Kocherga's answer, as it'll work for you in most cases.
In addition to that method to get the attribute's value, you may sometimes want to get the label of a select or multiselect. In that case, I have created this method which I store in a helper class:
/**
* #param int $entityId
* #param int|string|array $attribute atrribute's ids or codes
* #param null|int|Mage_Core_Model_Store $store
*
* #return bool|null|string
* #throws Mage_Core_Exception
*/
public function getAttributeRawLabel($entityId, $attribute, $store=null) {
if (!$store) {
$store = Mage::app()->getStore();
}
$value = (string)Mage::getResourceModel('catalog/product')->getAttributeRawValue($entityId, $attribute, $store);
if (!empty($value)) {
return Mage::getModel('catalog/product')->getResource()->getAttribute($attribute)->getSource()->getOptionText($value);
}
return null;
}
It seems impossible to get value without loading product model. If you take a look at file app/code/core/Mage/Eav/Model/Entity/Attribute/Frontend/Abstract.php you'll see the method
public function getValue(Varien_Object $object)
{
$value = $object->getData($this->getAttribute()->getAttributeCode());
if (in_array($this->getConfigField('input'), array('select','boolean'))) {
$valueOption = $this->getOption($value);
if (!$valueOption) {
$opt = new Mage_Eav_Model_Entity_Attribute_Source_Boolean();
if ($options = $opt->getAllOptions()) {
foreach ($options as $option) {
if ($option['value'] == $value) {
$valueOption = $option['label'];
}
}
}
}
$value = $valueOption;
}
elseif ($this->getConfigField('input')=='multiselect') {
$value = $this->getOption($value);
if (is_array($value)) {
$value = implode(', ', $value);
}
}
return $value;
}
As you can see this method requires loaded object to get data from it (3rd line).
First we must ensure that the desired attribute is loaded, and then output it. Use this:
$product = Mage::getModel('catalog/product')->load('<product_id>', array('<attribute_code>'));
$attributeValue = $product->getResource()->getAttribute('<attribute_code>')->getFrontend()->getValue($product);
Try this
$attribute = $_product->getResource()->getAttribute('custom_attribute_code');
if ($attribute)
{
echo $attribute_value = $attribute ->getFrontend()->getValue($_product);
}
You don't have to load the whole product.
Magentos collections are very powerful and smart.
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('entity_id', $product->getId());
$collection->addAttributeToSelect('manufacturer');
$product = $collection->getFirstItem();
$manufacturer = $product->getAttributeText('manufacturer');
At the moment you call getFirstItem() the query will be executed and the result product is very minimal:
[status] => 1
[entity_id] => 38901
[type_id] => configurable
[attribute_set_id] => 9
[manufacturer] => 492
[manufacturer_value] => JETTE
[is_salable] => 1
[stock_item (Varien_Object)] => Array
(
[is_in_stock] => 1
)
This one works-
echo $_product->getData('ATTRIBUTE_NAME_HERE');
You can get attribute value by following way
$model = Mage::getResourceModel('catalog/product');
$attribute_value = $model->getAttributeRawValue($productId, 'attribute_code', $storeId);
$orderId = 1; // YOUR ORDER ID
$items = $block->getOrderItems($orderId);
foreach ($items as $item) {
$options = $item->getProductOptions();
if (isset($options['options']) && !empty($options['options'])) {
foreach ($options['options'] as $option) {
echo 'Title: ' . $option['label'] . '<br />';
echo 'ID: ' . $option['option_id'] . '<br />';
echo 'Type: ' . $option['option_type'] . '<br />';
echo 'Value: ' . $option['option_value'] . '<br />' . '<br />';
}
}
}
all things you will use to retrieve value product custom option cart order in Magento 2: https://www.mageplaza.com/how-get-value-product-custom-option-cart-order-magento-2.html
You could write a method that would do it directly via sql I suppose.
Would look something like this:
Variables:
$store_id = 1;
$product_id = 1234;
$attribute_code = 'manufacturer';
Query:
SELECT value FROM eav_attribute_option_value WHERE option_id IN (
SELECT option_id FROM eav_attribute_option WHERE FIND_IN_SET(
option_id,
(SELECT value FROM catalog_product_entity_varchar WHERE
entity_id = '$product_id' AND
attribute_id = (SELECT attribute_id FROM eav_attribute WHERE
attribute_code='$attribute_code')
)
) > 0) AND
store_id='$store_id';
You would have to get the value from the correct table based on the attribute's backend_type (field in eav_attribute) though so it takes at least 1 additional query.
If you have an text/textarea attribute named my_attr you can get it by:
product->getMyAttr();

How to get all product from a category including its subcategories in Magento?

I'm looking for a way to retrieve all products from a category includings its subcategories and return me a Product Collection.
I know I can iterate over categories to get ids of product and load them in the view, but I would have liked to get a product collection as it is done currently in most categories/views.
Any ideas?
I've solved this problem by implementing addCategoriesFilter in product collection model, here is the patch. Modified code to be copied to the local pool to allow updates to a newer version.
## -103,6 +103,7 ##
* Allowed filters
* store_id int;
* category_id int;
+ * category_ids array;
* category_is_anchor int;
* visibility array|int;
* website_ids array|int;
## -567,6 +568,21 ##
}
/**
+ * Specify categories filter for product collection
+ *
+ * #param array $categories
+ * #return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
+ */
+ public function addCategoriesFilter(array $categories)
+ {
+ $this->_productLimitationFilters['category_ids'] = $categories;
+
+ ($this->getStoreId() == 0)? $this->_applyZeroStoreProductLimitations() : $this->_applyProductLimitations();
+
+ return $this;
+ }
+
+ /**
* Join minimal price attribute to result
*
* #return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
## -1592,7 +1608,7 ##
$this->_productLimitationJoinPrice();
$filters = $this->_productLimitationFilters;
- if (!isset($filters['category_id']) && !isset($filters['visibility'])) {
+ if (!isset($filters['category_id']) && !isset($filters['category_ids']) && !isset($filters['visibility'])) {
return $this;
}
## -1604,11 +1620,16 ##
$conditions[] = $this->getConnection()
->quoteInto('cat_index.visibility IN(?)', $filters['visibility']);
}
- $conditions[] = $this->getConnection()
- ->quoteInto('cat_index.category_id=?', $filters['category_id']);
- if (isset($filters['category_is_anchor'])) {
+
+ if (!isset($filters['category_ids'])) {
$conditions[] = $this->getConnection()
- ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']);
+ ->quoteInto('cat_index.category_id=?', $filters['category_id']);
+ if (isset($filters['category_is_anchor'])) {
+ $conditions[] = $this->getConnection()
+ ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']);
+ }
+ } else {
+ $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id IN(' . implode(',', $filters['category_ids']) . ')', "");
}
$joinCond = join(' AND ', $conditions);
Usage:
$category = $layer->getCurrentCategory();
$categories = $category->getAllChildren(true);
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->addCategoriesFilter($categories);
You have to set that category to Anchor = Yes in de backend. That way your collection will nculde all the products form his subcategories.
If you wanted to show all products assigned to a category below the root category of a store you could do the following (or replace root category with the one you desire):
$root_category = Mage::getModel('catalog/category')->load(Mage::app()->getStore()->getRootCategoryId());
$all_cat_ids = explode(",", $root_category->getAllChildren());
$collection->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left');
$collection->addAttributeToFilter('category_id', array('in' => $all_cat_ids));
Hope this helps.
Similar to the answer by Matt, but without the "XXX already exists" error.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once 'app/Mage.php';
umask(0);
$app = Mage::app('admin');
$rootCategory = Mage::getModel('catalog/category')->load(17);
$collection = Mage::getResourceModel('catalog/product_collection');
$allCatIds = explode(",", $rootCategory->getAllChildren());
$collection
->getSelect()
->group('entity_id');
$collection
->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
->addAttributeToFilter('category_id', array('in' => $allCatIds));
echo $collection->count();
Sorry for the incomplete answer, but an approach that might work is to look at the category path for the parent (1/2/3) and use a query (on a category collection?) that grabs all descendents of that category (path like 1/2/3%). Then, you could use that to filter a product collection. Maybe someone else can flesh out those details and answer better :)

Resources