Hej Guys
I have a rather large problem, I've been tasked with creating a Custom Data Provider for extracting Stock Keeping Units(SKUs) from a SOLR database into sitecore, without actually populating the database with items.
I've created a data provider, which succesfully pulls data from the SOLR database a "creates" the items in sitecore, by using the following code:
public class SkuDataProvider : DataProvider, ISkuDataProvider
{
private readonly string _targetDatabaseName = "master";
private readonly string _idTablePrefix = "Skus";
private readonly ID _skuTemplateId = new ID("{F806B403-BDAF-4C60-959D-E706A82FC1DC}");
private readonly ID _skuRootTemplateId = new ID("{9767BC47-0A95-40E9-A2DE-3766FF241411}");
private readonly IEnumerable<SkuItemInfo> _skus;
public SkuDataProvider(/*IProductPageService productPageService*/)
{
_skus = new MockDataForSkuDataProvider().GetSimpleSkuCollection();
}
public override ItemDefinition GetItemDefinition(ID itemId, CallContext context)
{
Assert.ArgumentNotNull(itemId, "itemID");
// Retrieve the sku id from Sitecore's IDTable
var skuId = GetSkuIdFromIdTable(itemId);
if (!string.IsNullOrEmpty(skuId))
{
// Retrieve the sku data from the skus collection
var sku = _skus.FirstOrDefault(o => o.SkuId == skuId);
if (sku != null)
{
// Ensure the sku item name is valid for the Sitecore content tree
var itemName = ItemUtil.ProposeValidItemName($"{sku.SkuId}_{sku.Name}");
// Return a Sitecore item definition for the sku using the sku template
return new ItemDefinition(itemId, itemName, ID.Parse(_skuTemplateId), ID.Null);
}
}
return null;
}
private string GetSkuIdFromIdTable(ID itemId)
{
var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemId);
if (idTableEntries.Any())
return idTableEntries[0].Key.ToString();
return null;
}
public override IDList GetChildIDs(ItemDefinition parentItem, CallContext context)
{
if (CanProcessParent(parentItem.ID))
{
var itemIdList = new IDList();
foreach (var sku in _skus)
{
var skuId = sku.SkuId;
// Retrieve the Sitecore item ID mapped to his sku
IDTableEntry mappedId = IDTable.GetID(_idTablePrefix, skuId) ??
IDTable.GetNewID(_idTablePrefix, skuId, parentItem.ID);
itemIdList.Add(mappedId.ID);
}
context.DataManager.Database.Caches.DataCache.Clear();
return itemIdList;
}
return base.GetChildIDs(parentItem, context);
}
private bool CanProcessParent(ID id)
{
var item = Factory.GetDatabase(_targetDatabaseName).Items[id];
bool canProcess = item.Paths.IsContentItem && item.TemplateID == _skuRootTemplateId && item.ID == new ID("{F37753A0-BC79-4FF7-B975-A8F142AACD76}");
return canProcess;
}
public override ID GetParentID(ItemDefinition itemDefinition, CallContext context)
{
var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemDefinition.ID);
if (idTableEntries.Any())
{
return idTableEntries.First().ParentID;
}
return base.GetParentID(itemDefinition, context);
}
public override FieldList GetItemFields(ItemDefinition itemDefinition, VersionUri version, CallContext context)
{
var fields = new FieldList();
var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemDefinition.ID);
if (idTableEntries.Any())
{
if (context.DataManager.DataSource.ItemExists(itemDefinition.ID))
{
ReflectionUtil.CallMethod(typeof(ItemCache), CacheManager.GetItemCache(context.DataManager.Database), "RemoveItem", true, true, new object[] { itemDefinition.ID });
}
var template = TemplateManager.GetTemplate(_skuTemplateId, Factory.GetDatabase(_targetDatabaseName));
if (template != null)
{
var skuId = GetSkuIdFromIdTable(itemDefinition.ID);
if (!string.IsNullOrEmpty(skuId))
{
var sku = _skus.FirstOrDefault(o => o.SkuId == skuId);
if (sku != null)
{
foreach (var field in GetDataFields(template))
{
fields.Add(field.ID, GetFieldValue(field, sku));
}
}
}
}
}
return fields;
}
protected virtual IEnumerable<TemplateField> GetDataFields(Template template)
{
return template.GetFields().Where(ItemUtil.IsDataField);
}
private string GetFieldValue(TemplateField field, SkuItemInfo sku)
{
string fieldValue = string.Empty;
switch (field.Name)
{
case "Name":
fieldValue = sku.Name;
break;
case "SkuId":
fieldValue = sku.SkuId;
break;
default:
break;
}
return fieldValue;
}
}
}
The problem emerges when accessing the Sitecore backend, where all items appears below the bucket item in a hierarchly-way.
I've checked that the Root item is set a bucket and that the template used is bucketable. Furthermore when inserting manually in the backend, the item is correctly inserted in the bucket.
Do anyone got an idea for me, on how to fix this issue?
Best Regards Nicolai