2016-04-18 22 views
2

Hej JungsAusstellungsstück im Kübel mit Sitecores Data Provider

ich ein ziemlich großes Problem haben, ich habe mit dem Erstellen eines Custom Data Provider für das Extrahieren Vorratshaltung Units (SKUs) von einer SOLR Datenbank in Sitecores beauftragt, ohne die Datenbank tatsächlich mit Elementen zu füllen.

ich einen Datenprovider erstellt haben, die erfolgreich Daten aus der Datenbank SOLR zieht ein die Elemente in Sitecore, indem Sie den folgenden Code „erzeugt“:

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; 
     } 
    } 
} 

Das Problem tritt beim Zugriff auf das Backend Sitecores , in dem alle Elemente hierarchisch unter dem Bucket-Element angezeigt werden.

Ich habe überprüft, dass das Root-Element einen Bucket gesetzt ist und dass die verwendete Vorlage bucketfähig ist. Außerdem wird beim manuellen Einfügen in das Backend das Objekt korrekt in den Bucket eingefügt.

Hat jemand eine Idee für mich, wie man dieses Problem beheben kann?

Mit freundlichen Grüßen Nicolai

Antwort

1

Sie müssen sich die Is Bucketable Flagge auf den Standardwerten der Vorlage Element anstelle der Vorlage Artikel setzen.

Auch die Art und Weise, wie Elemente "bucket" werden, erfolgt über Ereignisse, wenn das Element erstellt oder gespeichert wird. Sitecore erstellt dann die Bucket-Ordner, in denen die Elemente gespeichert werden. In Ihrem Fall müssen Sie, da Sie virtuelle Elemente haben, ihren Pfad über den Datenprovider behandeln.

Wenn Sie nur möchten, dass sie auf die gleiche Weise wie in einem Standard-Bucket ausgeblendet werden, würde ich vorschlagen, einen Bucket-Ordner unter Ihrem SKU-Stammordner zu erstellen und diesen Artikel als übergeordnetes Element für alle virtuellen Artikel zu verwenden. Auf diese Weise wird der Bucket-Ordner von Sitecore ausgeblendet und Sie erhalten dieselbe Ansicht wie bei einem Standard-Bucket.

Dies ist die Vorlage zu verwenden: für Bucket Folder Template

+0

Mein Fehler nicht in meinem Beitrag zu klären, aber es wird auf Standardwerte gesetzt. :) Aber ich werde den Eimer Ordner Idee versuchen! – MrNantir

+1

Es scheint, dass ich den gewünschten Effekt erzielt habe. Vielen Dank für eine schnelle und einfache Antwort :) – MrNantir

+0

Wie würden Sie den Artikelpfad für virtuelle Artikel im Datenprovider behandeln? – user1501050