How to update the attribute options programmatically in Magento? - php

I want to update/add the options of a drop down attribute in Magento though code (programmatically). I have found how to add attribute options, but how can I update the option values.
Example:
Suppose the attribute is 'manufacturer'. I have added three options man1, man2, man3. Now through my custom code I want to change the label of man1 to man11 and man2 to man22. How can I achieve that?
Thanks.

Well, I found a solution myself. See complete details here.
//Get the eav attribute model
$attr_model = Mage::getModel('catalog/resource_eav_attribute');
//Load the particular attribute by id
//Here 73 is the id of 'manufacturer' attribute
$attr_model->load(73);
//Create an array to store the attribute data
$data = array();
//Create options array
$values = array(
//15 is the option_id of the option in 'eav_attribute_option_value' table
15 => array(
0 => 'Apple' //0 is current store id, Apple is the new label for the option
),
16 => array(
0 => 'HTC'
),
17 => array(
0 => 'Microsoft'
),
);
//Add the option values to the data
$data['option']['value'] = $values;
//Add data to our attribute model
$attr_model->addData($data);
//Save the updated model
try {
$attr_model->save();
$session = Mage::getSingleton('adminhtml/session');
$session->addSuccess(
Mage::helper('catalog')->__('The product attribute has been saved.'));
/**
* Clear translation cache because attribute labels are stored in translation
*/
Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
$session->setAttributeData(false);
return;
} catch (Exception $e) {
$session->addError($e->getMessage());
$session->setAttributeData($data);
return;
}

You might want to try extending the AttributeController located at app\code\core\Mage\Adminhtml\controllers\Catalog\Product\AttributeController.php and override the saveAction() method to suit your needs.

Related

Codeigniter - input data save in multiple arrays and db table

I've an existing form which is passing the input data to the model in an array format. $postdata has all the data from the view and sending to model.
Controller:
$inquiry_id = $this->input->post('inquiry_id');
$postdata = $this->input->post();
$this->load->model('Design_model');
$this->Design_model->insertdata($postdata,$inquiry_id);
Model:
function insertdata($data = array(), $inquiry_id){
$sql = $this->db->query("select * from design where inquiry_id='".$inquiry_id."'");
if($sql->num_rows() == 0){
$sql_query = $this->db->insert('design', $data);
}
else{
$this->db->where('inquiry_id', $inquiry_id);
$this->db->update('design', $data);
}
}
Above is working fine. Now, I'd like to add few fields in the view and save in a different database table. Need to exclude the new field values from $postdata array getting saved. Need to find the best approach to do this. I can start with some name for all the new fields, so that we can add any filter if available to exclude from the $postdata.
You can use elements() function from Array helper.
$array = array(
'id' => 101,
'title' => 'example',
'desc' => 'something',
'unwanted' => 'bla bla'
);
$filtered_array = elements(array('id','title','desc'),$array); //you can use this directly to the post data
$this->Design_model->insertdata($filtered_array,$inquiry_id);
You can use array_merge() or array_push() functions to add new fields to the array.
Let's say you have following data
$postdata = array("name"=>"xyz",
"email"=>"xyz#gmail.com",
"age"=>"40",
"gender"=>"Male",
"occupation"=>"Engineer"
);
Of which first 3 records are from old fields and last 2 are from new fields as you saying.
You need to find last index of first set i.e. '3' Now you can do this.
$firstDb = array_splice($postdata,0,3); //here 3 is index we are using to get first 3 records from $postdata
$secondDb = array_slice($postdata,0,3); //here 3 is index we are using to get records from position 3 from $postdata
Output:
$firstDb = array("name"=>"xyz","email"=>"xyz#gmail.com","age"=>"40");
$secondDb = array("gender"=>"Male","occupation"=>"Engineer");
Now you can insert you records as you wish to. Happy coding

Podio API: how to set a value for an empty field with podio-php wrapper?

I'm trying to set a field value via API using podio-php. If the field was already not empty, the following snippet made according to the manual works fine:
$item = PodioItem::get_basic( $item_id );
$field = $item->fields["field-name"];
$field->values = "2"; // let's say we have a number filed
$item->save(); // $field->save() also works
But if the field was empty, a warning Creating default object from empty value occures on save. No errors, no changes in the item. This is true for different types of fields. I assume, a field-object should be created from scratch, but didn't managed to find an info on this for different field types.
So, please, how to correctly set a value with podio-php when the field is empty? Thanks.
I had the Same Problem and found this Gem..
PodioItem::update(210606, array('fields' => array(
"title" => "The API documentation is much more funny",
"business_value" => array('value' => 20000, "currency" => "EUR"),
"due_date" => array('start' => "2011-05-06 11:27:20", "end" => "2012-04-30
10:44:20"),
));
I modified it so I can update individual fields. But this will update the field without that stupid error.
$FieldsArray = [];
$FieldsArray['encounter-status'] = "Draft";
$item = PodioItem::update($itemID, array('fields' => $FieldsArray));
May be there is a simplier way, but here is a workaround I've found. If the field was not empty, we just assign the new value. But if the field was empty, we need to create a new field object of the corresponding type (see the list below) with the same name as the existing field and add it to the field collection. The old empty field will be replaced with the new one.
In this example we will set the number field:
$field_name = "field-name";
$new_value = 999;
$item = PodioItem::get_basic( $item_id );
$field = $item->fields[$field_name];
if ( count($field->values) ){ // if the field is not empty
$field->values = $new_value;
} else { // if the field is empty
$new_field = new PodioNumberItemField($field_name); // new field with the same(!) name
$new_field->values = $new_value;
$item->fields[] = $new_field; // the new field will replace the exsisting (empty) one
}
$item->save();
Constructors for other field objects types (found in models/PodioItemField.php):
PodioTextItemField
PodioEmbedItemField
PodioLocationItemField
PodioDateItemField
PodioContactItemField
PodioAppItemField
PodioCategoryItemField
PodioImageItemField
PodioFileItemField
PodioNumberItemField
PodioProgressItemField
PodioDurationItemField
PodioCalculationItemField
PodioMoneyItemField
PodioPhoneItemField
PodioEmailItemField

Codeigniter cart can't insert data

I'm trying to add some data to a codeigniter (HMVC codeigniter) chopping cart and display it, i'm using this method in the main cart controller:
function add_to_cart(){
$this->load->library('cart');
// Get data
$userID = $this->input->post('userID');
$eventID = $this->input->post('eventID');
$tickedID = $this->input->post('tickedID');
// Get ticket data
$this->load->module('ticket');
$ticket_query = $this->ticket->get_where($tickedID);
//echo $this->session->all_userdata();
foreach($ticket_query->result() as $ticket_data){
$ticketPrice = $ticket_data->price;
$ticketCategory = $ticket_data->category;
}
//echo 'tickedID: '.$tickedID.' price: '.$ticketPrice.' category: '.$ticketCategory;
// Add item to cart
$data_items = array(
'id' => $tickedID,
'qty' => 1,
'price' => $ticketPrice,
'category' => $ticketCategory,
'options' => array()
);
$this->cart->insert($data_items);
$cart = $this->cart->contents();
echo '<pre>';
echo print_r($cart);
echo '</pre>';
}
Basically i'm getting the userID, eventID and tickedID variables from the session, then I run a query to get the ticked with the specific id. I run through the results of the query and get the $thicketPrice and $ticketCategory variables from it. Then I attempt to set the variables in $data_items to insert in the cart itself. FInally I attempt to echo the contents of the care and all I get is an empty array.
The session, database and cart libraries are all autoloaded and the sessions are using the database, they have the ci_sessions table. THe sessions also have an ecrypted key, what is wrong?
Some attention for successful cart insert:
'price' > 0
'name' (or similar field) better not in unicode
You need a name index as it's mandatory.
id - Each product in your store must have a unique identifier. Typically this will be an "sku" or other such identifier.
qty - The quantity being purchased.
price - The price of the item.
name - The name of the item.
options - Any additional attributes that are needed to identify the product. These must be passed via an array.
Important: The first four array indexes above (id, qty, price, and name) are required. If you omit any of them the data will not be saved to the cart. The fifth index (options) is optional. It is intended to be used in cases where your product has options associated with it. Use an array for options, as shown above.
From http://ellislab.com/codeigniter/user-guide/libraries/cart.html
So, something like this then:
$data_items = array(
'id' => $tickedID,
'qty' => 1,
'price' => $ticketPrice,
'name' => $someName,
'options' => array('category'=>$ticketCategory)
);

How to access custom options of a product in magento from observer event

I have 2 custom option text fields associated with a product called Location To and Location From,
I have set up a Module that has an Observer for checkout_cart_add_product_complete with a method called getLocationCoords, how would I get access to these two fields from the event object that passed to my method.
I need these 2 fields so I can reverse geocode them which I think I will be able to do myself.
Once I get the 2 sets of coordinates how would I go about storing them with the product so I would be able to see them associated with the product when an order is paced?
=======================
edit addded ============================
What i have tried so far
public function getLocationCoords(Varien_Event_Observer $observer)
{
// Retrieve the product being updated from the event observer
$product = $observer->getEvent()->getProduct();
// Write a new line to var/log/product-updates.log
$name = $product->getName();
$sku = $product->getSku();
Mage::log(
"{$name} ({$sku}) updated",
null,
'product-updates.log'
);
foreach ($product->getOptions() as $o) {
$type = "Custom Option TYPE: " . $o->getType();
$title = "Custom Option TITLE: " . $o->getTitle();
Mage::log(
"{$type} ({$title}) custom option {$o}",
null,
'product-updates.log'
);
}
}
It all works except getting the values of the custom options, i will try the answer below and see where i get
when i print out the var dump of the option object this is what i get
2012-12-11T15:19:45+00:00 DEBUG (7): array (
'option_id' => '1',
'product_id' => '1',
'type' => 'field',
'is_require' => '1',
'max_characters' => '0',
'sort_order' => '0',
'default_title' => 'Location To',
'title' => 'Location To',
'default_price' => '0.0000',
'default_price_type' => 'fixed',
'price' => '0.0000',
'price_type' => 'fixed',
)
there is no value to the object
There is also this event
$eventName = sprintf('catalog_product_type_prepare_%s_options', $processMode);
Mage::dispatchEvent($eventName, array(
'transport' => $transport,
'buy_request' => $buyRequest,
'product' => $product
));
With processMode either full or lite. The buy_request should have your details and you can then add a new option on the product
$product->addCustomOption('my_option','my_value');
Not tested but do let us know how you are getting on.
I believe that by the time that event is dispatched you will need to access the sales quote object from the cart session, which smells bad to me. Try the checkout_cart_product_add_after [link] event and get access to the quote item as follows:
public function geoConversion ($obs)
{
$item = $obs->getQuoteItem();
/* #var $item Mage_Sales_Model_Quote_Item */
//I believe the custom options will be in here, not sure
$buyRequest = $item->getBuyRequest();
// your logic
}
I haven't checked this, but it's a bit better an event to use. However, there are lots of considerations when customizing the add to cart process (admin-created orders and updates of existing cart items for example), so test, test, test. Also, there is another event which may be useful/more appropriate: sales_quote_product_add_after [link].
Further, this behavior could also be achieved by giving these products a custom type model based on - or by observing events dispatched in - Mage_Catalog_Model_Product_Type_Abstract.
It's dizzying.
I was able to get to get access to quote item and from that i was able to access the values of the custom attributes. I had two options and after some debugging i realised my options were being called option_1 and option_2 , from that i was able to get the value and set them to my variables.
public function getLocationCoords(Varien_Event_Observer $observer)
{
$item = $observer->getQuoteItem();
$locationFrom = '';
$locationTo = '';
foreach ($item->getOptions() as $o) {
if($o['code'] == 'option_2'){
$locationFrom = $o['value'];
}
if($o['code'] == 'option_1'){
$locationTo = $o['value'];
}
}
Mage::log("the location from = ".$locationFrom);
Mage::log("the location to = ".$locationTo);
}

Magento adding new options to a drop down attribute

Hello Im currently writing a product syncronisation script for magento. I know how to add a new product with a given attribute set. However one of the atributes i am using is a size field. When a new size is encounterd I want to add this option to the attribute, I am wondering how to do this please?
Here is a script to add new option to attribute from Product View or Block:
$attributeInfo = Mage::getResourceModel('eav/entity_attribute_collection')
->setCodeFilter(YOUR_ATTRIBUTE_CODE)
->getFirstItem();
$options = $attributeInfo->getSource()->getAllOptions(false);
$_optionArr = array(
'value' => array(),
'order' => array(),
'delete' => array()
);
foreach ($options as $option) {
$_optionArr['value'][$option['value']] = array($option['label']);
}
$_optionArr['value']['option_1'] = array(NAME_OF_OUR_NEW_OPTION);
$attribute->setOption($_optionArr);
$attribute->save();
...
Put a file ie: test-attribute.php in your Magento root.
<?php
// Include and start Magento
require_once dirname(__FILE__).'/app/Mage.php';
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
// Load attribute model and load attribute by attribute code
$model = Mage::getModel('catalog/resource_eav_attribute')->load('some_dropdown_attribute', 'attribute_code');
// Get existing options
$options = $model->getSource()->getAllOptions(false);
// Get the count to start at
$count = count($options) + 1;
// Prepare array
$data = array(
'option' => array(
'value' => array(),
'order' => array()
)
);
// You can loop here and increment $count for multiple options
$key = 'option_'.$count;
$data['option']['value'][$key] = array('Test '.$count);
$data['option']['order'][$key] = 0;
// Add array to save
$model->addData($data);
// Save
$model->save();
Should create a new option called Test X on the attribute. Tested on Magento Enterprise 1.11.2
After doing some more looking around I finaly found out how to do it. Then I found a extension to xml-api that extends api to support operations such as one i wanted to do.
The extension i used was MagentoeXtended

Categories