Orchard custom workflow

I've created a custom module in Orchard that creates a new part, type and custom activity, but I'm afraid of the last part of what I need to do to create a copy of all content items associated with a specific parent.

For example, when someone creates a "Trade Show" (a new type from my module), different subpages (destinations, vendor maps, etc.) can be generated from it, since the client is running one show at a time. What I need to do when they create a new exhibit, I want to get the last previous show (which I am doing through _contentManager.HqlQuery().ForType("TradeShow").ForVersion(VersionOptions.Latest).ForVersion(VersionOptions.Published).List().Last()

(positive, which is not the most efficient way, but it works and the number of entries will be ~ 10 after five years), then find all these children the pages that match this old show and copy them into the new content items They should be a copy because sometimes they might have to link to parts with old shows or might change, etc. All the usual reasons.

How do I find all content items that link to the previous show in the Activity? Here is my complete class for Activity:

using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.Autoroute.Services;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Projections.Models;
using Orchard.Projections.Services;
using Orchard.Workflows.Models;
using Orchard.Workflows.Services;
using Orchard.Workflows.Activities;

namespace Orchard.Web.Modules.TradeShows.Activities
{
public class TradeShowPublishedActivity : Task
{
    private readonly IContentManager _contentManager;
    private readonly IAutorouteService _autorouteService;
    private readonly IProjectionManager _projectionManager;

    public TradeShowPublishedActivity(IContentManager contentManager, IAutorouteService autorouteService, IProjectionManager projectionManager)
    {
        _contentManager = contentManager;
        _autorouteService = autorouteService;
        _projectionManager = projectionManager;

        T = NullLocalizer.Instance;
    }

    public Localizer T { get; set; }

    public override LocalizedString Category
    {
        get { return T("Flow"); }
    }

    public override LocalizedString Description
    {
        get { return T("Handles the automatic creation of content pages for the new show."); }
    } 

    public override string Name
    {
        get { return "TradeShowPublished"; }
    }

    public override string Form
    {
        get { return null; }
    }

    public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext)
    {
        yield return T("Done");
    }

    public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext)
    {
        var priorShow = _contentManager.HqlQuery().ForType("TradeShow").ForVersion(VersionOptions.Latest).ForVersion(VersionOptions.Published).List().Last();
        var tradeShowPart = priorShow.Parts.Where(p => p.PartDefinition.Name == "TradeShowContentPart").Single();

        //new show alias
        //workflowContext.Content.ContentItem.As<Orchard.Autoroute.Models.AutoroutePart>().DisplayAlias

        yield return T("Done");
    }
}

      

}

My file Migrations.cs

sets the part used for child pages to link to the parent show:

ContentDefinitionManager.AlterPartDefinition("AssociatedTradeShowPart", builder => builder.WithField("Trade Show", cfg => cfg.OfType("ContentPickerField")
                                                                                                                                  .WithDisplayName("Trade Show")
                                                                                                                                  .WithSetting("ContentPickerFieldSettings.Attachable", "true")
                                                                                                                                  .WithSetting("ContentPickerFieldSettings.Description", "Select the trade show this item is for.")
                                                                                                                                  .WithSetting("ContentPickerFieldSettings.Required", "true")
                                                                                                                                  .WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", "TradeShow")
                                                                                                                                  .WithSetting("ContentPickerFieldSettings.Multiple", "false")
                                                                                                                                  .WithSetting("ContentPickerFieldSettings.ShowContentTab", "true")));

      

Then my child pages (only one, but more) are created like this:

ContentDefinitionManager.AlterTypeDefinition("ShowDirections", cfg => cfg.DisplayedAs("Show Directions")
                                                                                 .WithPart("AutoroutePart", builder => builder.WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                                                                                                                               .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false")
                                                                                                                               .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'international-trade-show'}]")
                                                                                                                               .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
                                                                                 .WithPart("CommonPart", builder => builder.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
                                                                                 .WithPart("PublishLaterPart")
                                                                                 .WithPart("TitlePart")
                                                                                 .WithPart("AssociatedTradeShowPart") /* allows linking to parent show */
                                                                                 .WithPart("ContainablePart", builder => builder.WithSetting("ContainablePartSettings.ShowContainerPicker", "true"))
                                                                                 .WithPart("BodyPart"));

      

+3


source to share


1 answer


So, you have a Trade Show content item, the next step is to find all the parts with ContentPickerField and then filter the list down to those where the field contains your show ID.

        var items = _contentManager.Query().List().ToList() // Select all content items
            .Select(p => (p.Parts 
                // Select all parts on content items
            .Where(f => f.Fields.Where(d => 
                d.FieldDefinition.Name == typeof(ContentPickerField).Name && 
                // See if any of the fields are ContentPickerFields
                (d as ContentPickerField).Ids.ToList().Contains(priorShow.Id)).Any()))); 
                   // That field contains the Id of the show

      



This can get expensive depending on the number of content items in your database.

0


source







All Articles