Magmi delete attribute value - attributes

How do you delete a attribute value with magmi?
<?hp
$prod[sku] = '1';
$prod[attribute1] = '';
$prod[sku] = '1';
$prod[attribute1] = null;
$prod[sku] = '1';
$prod[attribute1] = false;
?>
I tried these cases and none worked

I would recommend reading the Magmi Empty Values documentation.
Magmi can assign empty values to an attribute, depending on the mode you select. As far as actually unassigning the attribute from the product, doing so would require you to delete the product and reimport it with the correct attribute set. The reason being, attribute associations are tied to attribute sets, which in turn are tied to products. You can only assign a blank or empty value for that attribute without deleting the product.
There are two other ways you could do what you're attempting to do.
Use the Product Deleter plugin to delete the product, then re-import it with the correct attribute values.
Create a custom Magmi plugin that detects the blank attribute values, checks the product in Magento to see if it has that attribute, then deletes it.

Related

Can't modify/remove a field from an ActivityNode using sbt

I created an ActivityNode (an Entry) and I can add custom fields with the
setFields(List<Field> newListField)
fonction.
BUT
I am unable to modify these fields. (In this case I try to modify the value of the field named LIBENTITE)
FieldList list = myEntry.getTextFields();
List<Field> updatedList = new ArrayList<Field>();
//I add each old field in the new list, but I modify the field LIBENTITE
for(Field myField : list){
if(myField.getName().equals("LIBENTITE")){
((TextField)myField).setTextSummary("New value");
}
updatedList.add(myField);
}
myEntry.setFields(updatedList);
activityService.updateActivityNode(myEntry);
This code should replace the old list of fields with the new one, but I can't see any change in the custom field LIBENTITE of myEntry in IBM connections.
So I tried to create a new list of fields, not modifying my field but adding a new one :
for(Field myField:list){
if(!myField.getName().equals("LIBENTITE")){
updatedList.add(myField);
}
}
Field newTextField = new TextField("New Value");
newTextField .setFieldName("LIBENTITE");
updatedList.add(newTextField );
And this code is just adding the new field in myEntry. What I see is that the other custom fields did not change and I have now two custom fields named LIBENTITE, one with the old value and the second with the new value, in myEntry.
So I though that maybe if I clear the old list of Fields, and then I add the new one, it would work.
I tried the two fonctions
myEntry.clearFieldsMap();
and
myEntry.remove("LIBENTITE");
but none of them seems to work, I still can't remove a custom field from myEntry using SBT.
Any suggestions ?
I have two suggestions, as I had (or have) similar problems:
If you want to update an existing text field in an activity node, you have to call node.setField(fld) to update the field in the node object.
Code snippet from my working application, where I'm updating a text field containing a (computed) start time:
ActivityNode node = activityService.getActivityNode(id);
node.setTitle(formatTitle()); // add/update start and end time in title
boolean startFound = false;
// ...
FieldList textfields =node.getTextFields();
Iterator<Field> iterFields = textfields.iterator();
while (iterFields.hasNext()) {
TextField fld = (TextField) iterFields.next();
if (fld.getName().equals(Constants.FIELDNAME_STARTTIME)) {
fld.setTextSummary(this.getStartTimeString()); // NOTE: .setFieldValue does *not* work
node.setField(fld); // write updated field back. This seems to be the only way updating fields works
startFound=true;
}
}
If there is no field with that name, I create a new one (that's the reason I'm using the startFound boolean variable).
I think that the node.setField(fld) should do the trick. If not, there might be a way to sidestep the problem:
You have access to the underlying DOM object which was parsed in. You can use this to tweak the DOM object, which finally will be written back to Connections.
I had to use this as there seems to be another nasty bug in the SBT SDK: If you read in a text field which has no value, and write it back, an error will be thrown. Looks like the DOM object misses some required nodes, so you have to create them yourself to avoid the error.
Some code to demonstrate this:
// ....
} else if (null == fld.getTextSummary()) { // a text field without any contents. Which is BAD!
// there is a bug in the SBT API: if we read a field which has no value
// and try to write the node back (even without touching the field) a NullPointerException
// will be thrown. It seems that there is no value node set for the field. We
// can't set a value with fld.setTextSummary(), the error will still be thrown.
// therefore we have to remove the field, and - optionally - we set a defined "empty" value
// to avoid the problem.
// node.remove(fld.getName()); // remove the field -- this does *not* work! At least not for empty fields
// so we have to do it the hard way: we delete the node of the field in the cached dom structure
String fieldName = fld.getName();
DeferredElementNSImpl fldData = (DeferredElementNSImpl) fld.getDataHandler().getData();
fldData.getParentNode().removeChild(fldData); // remove the field from the cached dom structure, therefore delete it
// and create it again, but with a substitute value
Field newEmptyField = new TextField (Constants.FIELD_TEXTFIELD_EMPTY_VALUE); // create a field with a placeholder value
newEmptyField.setFieldName(fieldName);
node.setField(newEmptyField);
}
Hope that helps.
Just so that post does not stay unanswered I write the answer that was in a comment of the initial question :
"currently, there is no solution to this issue, the TextFields are read-only map. we have the issue recorded on github.com/OpenNTF/SocialSDK/issues/1657"

Can't set Orchard field values unless item already created

I seem to be having a problem with assigning values to fields of a content item with a custom content part and the values not persisting.
I have to create the content item (OrchardServices.ContentManager.Create) first before calling the following code which modifies a field value:
var fields = contentItem.As<MyPart>().Fields;
var imageField = fields.FirstOrDefault(o => o.Name.Equals("Image"));
if (imageField != null)
{
((MediaLibraryPickerField)imageField).Ids = new int[] { imageId };
}
The above code works perfectly when against an item that already exists, but the imageId value is lost if this is done before creating it.
Please note, this is not exclusive to MediaLibraryPickerFields.
I noticed that other people have reported this aswell:
https://orchard.codeplex.com/workitem/18412
Is it simply the case that an item must be created prior to amending it's value field?
This would be a shame, as I'm assigning this fields as part of a large import process and would inhibit performance to create it and then modify the item only to update it again.
As the comments on this issue explain, you do need to call Create. I'm not sure I understand why you think that is an issue however.

Assigning a value to the primary field in code fails

I have a custom entity named eld_timereg. This entity has an attribute named eld_name (which is the primary field). Records are created in a generic handler (after pushing a button in the ribbon). I'm using late binding.
var myService = ...;
var t = new Entity( "eld_timereg" );
t["field1"] = "abc";
.
.
.
t["eld_name"] = GenerateAnUniqueStringCode("ZXC");
// returns something like ZXC-16398-T1VC
return myService.Create(t);
The record is created without any error. Checking the entity in SSMS, the value is blank although it is a required field.
What is happening here?
Found the problem. You put me on the right track James. Thank you for that. The eld_name attribute was overwritten in the plug-in (I forgot). Here it should be filled with some information. This was going wrong and always returned a null.

Magento: getting attributes from an attribute set without a product

I have set an attribute set in my Magento shop which has several binary attributes.
For a pulldown I need a list of ALL the attributes inside this one attribute set, including their internal name and their label. Since this pulldown should appear in places that not necessarily have a product selected I can't go the usual route of "getting the attributes of a product".
How do I go about of getting a list of all the attributes inside my set?
OK, I realised that I missed that you want the whole set of attributes, not just an individual one. Try this:
$productEntityType = Mage::getModel('eav/entity_type')->loadByCode(Mage_Catalog_Model_Product::ENTITY);
$attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection');
$attributesInfo = Mage::getResourceModel('eav/entity_attribute_collection')
->setEntityTypeFilter($productEntityType->getId()) //4 = product entities
->addSetInfo()
->getData();
You'll then need to iterate through the array that is returned with something like:
foreach($attributesInfo as $attribute):
$attribute = Mage::getModel('eav/entity_attribute')->load($attribute['attribute_id']);
echo 'label = '.$attribute->getFrontendLabel().'<br/>';
echo 'code = '.$attribute->getAttributeCode().'<br/><br/>';
endforeach;
Sorry for missing the original point, hope this helps!
Cheers,
JD
In order to get all the attributes in an attribute set, you can use as:
$entityTypeId = Mage::getModel('eav/entity')
                ->setType('catalog_product')
                ->getTypeId();
$attributeSetName   = 'Default'; //Edit with your required Attribute Set Name
$attributeSetId     = Mage::getModel('eav/entity_attribute_set')
                    ->getCollection()
                    ->setEntityTypeFilter($entityTypeId)
                    ->addFieldToFilter('attribute_set_name', $attributeSetName)
                    ->getFirstItem()
                    ->getAttributeSetId();
$attributes = Mage::getModel('catalog/product_attribute_api')->items($attributeSetId);
foreach($attributes as $_attribute){
    print_r($_attribute);
}
Cheers!!
try this snippet, it should give you want you need, except for multi-select attributes.
$attribute = Mage::getModel('eav/config')->getAttribute('catalog_product','attribute_name');
foreach($attribute->getSource()->getAllOptions(true,true) as $option){
$attributeArray[$option['value']] = $option['label'];
}
return $attributeArray;
Hope this helps,
JD

Cascading list boxes, with multi-select

I wound up modifying the source from a publically posted POC: http://datacogs.com/datablogs/archive/2007/08/26/641.aspx, which is a custom field definition for cascading drop downs. The modifications were to allow parent-child list boxes where a user can multiselect for filtering and selecting the values to be written back to a SharePoint list. I got the parent-child cascading behavior working, but the save operation only takes the first value that is selected from the list box. I changed the base type for the custom field control from "SPFieldText" to "SPMultiLineText", along with changing the FLD_TYPES field definition values from:
Text to Note and this did not work. So, I changed the field control base type to "SPFieldMultiChoice" and the FLD_TYPES to "MultiChoice" and still get the same result, which is only the first value that's selected, writing to the SharePoint list.
Does anyone have any idea how to get a custom field with multiple selections to write those multiple selections to a SharePoint list?
Thanks for taking the time to read through my post.
Cheers,
~Peter
I was able to accomplish this by inheriting from SPFieldLookup and overriding its internal handling of AllowMultipleValues:
In your FLDTYPES_*.xml set <ParentType>LookupMulti</ParentType>
In your extension of SPFieldLookup, be sure to override AllowMultipleValues (always true), FieldValueType (probably typeof(SPFieldLookupValueCollection)) and FieldRenderingControl. I also set base.LookupField = "LinkTitleNoMenu", though in retrospect I'm not sure why. :)
In your field editor control's OnSaveChange(), set the field's Mult value to true.
To set Mult, you can either string manipulation on field.SchemaXml:
string s = field.SchemaXml;
if (s.IndexOf(" Mult=", StringComparison.OrdinalIgnoreCase) < 0)
field.SchemaXml = s.Insert(s.IndexOf("/>", StringComparison.Ordinal), " Mult=\"TRUE\" ");
Or use reflection:
var type = field.GetType();
var mi = type.GetMethod("SetFieldBoolValue", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(field, new object[] { "Mult", true });
It's been a while, so I might be forgetting something, but that should be most of it.

Resources