protected override void Created(ConnectorCreateContext context) { // Determine new sequence number var sequence = context.ConnectorContent.As <SequencePart>(); if (sequence == null) { return; } int?finalSequence = null; if (sequence.Sequence > 0) { finalSequence = sequence.Sequence; } if (!finalSequence.HasValue) { var highest = context.SiblingConnectors.ForPart <SequencePart>().Join <SequencePartRecord>().OrderByDescending(s => s.Sequence).Slice(0, 1).FirstOrDefault(); if (highest != null) { finalSequence = highest.Sequence + 1; } } if (!finalSequence.HasValue) { // Default to 1 finalSequence = 1; } // TODO: Allow creating at a different sequence, e.g. if we dropped a content into the middle of a list. Maybe a hidden field on a creator. if (finalSequence.HasValue) { sequence.Sequence = finalSequence.Value; } }
protected IEnumerable <IConnector> CreateConnector(IContent left, IContent right, ConnectorDescriptor ConnectorDef, bool createInverseIfPossible, bool ignorePermissions = false) { // Check sockets var leftSock = left.As <SocketsPart>(); var rightSock = right.As <SocketsPart>(); // TODO: SocketsPart doesn't need any data so we could consider automatically welding it to any content that has valid connectors. It's // very rare that we want a connector type to apply to anything so maybe should disable the wildcard. if (leftSock == null || rightSock == null) { throw new OrchardException(T("Attempted to create connector between non-socket content %0 (%1) and %2 (%3). You must add SocketsPart to content to participate in connections.", left.ContentItem.ContentType, leftSock == null ? "hasn't" : "has", right.ContentItem.ContentType, rightSock == null ? "hasn't" : "has")); } // Build a new item var connector = Services.ContentManager.New <ConnectorPart>(ConnectorDef.Name); // Check security var createContext = new ConnectorCreateContext(left, right, ConnectorDef); createContext.ConnectorContent = connector; createContext.SiblingConnectors = leftSock.Sockets[ConnectorDef.Name].ConnectorQuery; if (!ignorePermissions && !Services.Authorizer.Authorize(Permissions.PublishContent, connector, T("Cannot create connector"))) { return(Enumerable.Empty <IConnector>()); } // Store left and right items connector.LeftContentItemId = left.ContentItem.Id; connector.RightContentItemId = right.ContentItem.Id; // Handle versioning if (left.ContentItem.VersionRecord != null) { connector.LeftContentVersionId = left.ContentItem.VersionRecord.Id; } if (right.ContentItem.VersionRecord != null) { connector.RightContentVersionId = right.ContentItem.VersionRecord.Id; } // Invoke Creating event _connectorHandlers.Value.Invoke(c => c.Creating(createContext), Logger); if (createContext.Cancel) { return(Enumerable.Empty <IConnector>()); } // Create the item and invoke Created Services.ContentManager.Create(connector, ((left.ContentItem.VersionRecord != null)? (left.ContentItem.VersionRecord.Published ? VersionOptions.Published : VersionOptions.Draft) : VersionOptions.Published)); _connectorHandlers.Value.Invoke(c => c.Created(createContext), Logger); IEnumerable <IConnector> returnList = new[] { connector }; if (ConnectorDef.PartDefinition != null) { var settings = ConnectorDef.Settings; // Can we create an inverse? if (createInverseIfPossible && !String.IsNullOrWhiteSpace(settings.InverseConnectorType)) { var inverseDef = DescribeConnector(settings.InverseConnectorType); var inverseContext = new ConnectorCreateContext(right, left, inverseDef); inverseContext.InverseConnectorContent = createContext.ConnectorContent; _connectorHandlers.Value.Invoke(c => c.CreatingInverse(inverseContext), Logger); if (!inverseContext.Cancel) { // Create it var inverseCreate = CreateConnector(right, left, inverseDef, false, ignorePermissions); var inverseFirst = inverseCreate.FirstOrDefault().As <ConnectorPart>(); // Exchange Ids if (inverseFirst != null) { connector.InverseConnector = inverseFirst; inverseFirst.InverseConnector = connector; } returnList = returnList.Concat(inverseCreate); } } } return(returnList.ToArray()); }