using System; using System.Collections.Generic; using System.Linq; using System.Web.UI; using System.Web.UI.WebControls; using umbraco.cms.businesslogic.datatype; // DefaultData using umbraco.cms.businesslogic.property; // Property using umbraco.cms.businesslogic.relation; // RelationType using umbraco.interfaces; // IDataEditor using UmbracoContent = umbraco.cms.businesslogic.Content; // UmbracoContent defined here so as to differentiate with System.Web.UI.WebControls.Content namespace umbraco.editorControls.PickerRelations { /// /// /// public class PickerRelationsDataEditor : CompositeControl, IDataEditor { /// /// value stored by a datatype instance /// private IData data; /// /// configuration options for this datatype, as defined by the PreValueEditor /// private PickerRelationsOptions options; /// /// Literal used to render status (Enabled || Disabled) /// this datatype is only enabled and active if it can find the property alias on the current node (as defined in PreValueEditor) and /// the relation type parent object type (or child if reverse index used) matches the object type of the current node which this datatype is on /// private Literal statusLiteral = new Literal(); private Literal jsLiteral = new Literal(); /// /// Gets a value indicating whether this is an RTE - this Property expected by Umbraco /// public virtual bool TreatAsRichTextEditor { get { return false; } } /// /// Gets a value indicating whether the label should be shown when editing - this Property exected by Umbraco /// public virtual bool ShowLabel { get { return true; } } /// /// Gets the DataEditor - Property expected by Umbraco /// public Control Editor { get { return this; } } /// /// Gets the id of the current (content || media || member) node on which this datatype is a property /// private int CurrentContentId { get { return ((umbraco.cms.businesslogic.datatype.DefaultData)this.data).NodeId; } } /// /// Gets the UmbracoObjectType on which this datatype is a property of /// private uQuery.UmbracoObjectType CurrentContextObjectType { get { return uQuery.GetUmbracoObjectType( uQuery.SqlHelper.ExecuteScalar( "SELECT nodeObjectType FROM umbracoNode WHERE id = @id", uQuery.SqlHelper.CreateParameter("@id", this.CurrentContentId))); } } /////// NOT CURRENTLY USED, BUT MIGHT BE USEFUL TO MARK BIDIRECTIONAL RELATIONS /////// /////// string to identify a particular instance of this datatype /////// ////private string InstanceIdentifier ////{ //// get //// { //// Property pickerRelationsProperty = new Property(((DefaultData)this.data).PropertyId); //// return "[" + pickerRelationsProperty.PropertyType.Id.ToString() + "]"; //// } ////} /// /// Initializes a new instance of PickerRelationsDataEditor /// /// data stored by this instance of this datatype (not currently used) /// configuration options for this datatype as set by the PreValueEditor internal PickerRelationsDataEditor(IData data, PickerRelationsOptions options) { this.data = data; this.options = options; } /// /// Creates the child controls /// protected override void CreateChildControls() { this.statusLiteral.ID = "pickerRelations"; this.Controls.Add(this.statusLiteral); // displays if this datatype is valid in this context, and if so, which pickerProperty and relationtype it wires up this.Controls.Add(this.jsLiteral); } /// /// /// /// protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.EnsureChildControls(); this.statusLiteral.Text = ""; try { this.statusLiteral.Text += "Mapping: " + this.GetMappingDetails(); } catch(Exception ex) { this.statusLiteral.Text += "Error: " + ex.Message; } this.statusLiteral.Text += ""; if (this.options.HideDataEditor) { this.jsLiteral.Text = @" "; } } /// /// Called by Umbraco when saving the node, this datatype doens't do anythign here, but with an event handler instead, /// as needs to know the saved values of a sibling pickerProperty /// public void Save() { } /// /// returns a string "Property '[propertyAlias]' with RelationType '[relationTypeName]" /// /// private string GetMappingDetails() { string mappingDetails = string.Empty; UmbracoContent currentContentNode = new UmbracoContent(this.CurrentContentId); Property pickerProperty = currentContentNode.getProperty(this.options.PropertyAlias); if (pickerProperty != null) { RelationType relationType = new RelationType(this.options.RelationTypeId); // Does it still exist ? TODO: check if (this.IsContextUmbracoObjectTypeValid(this.CurrentContextObjectType, relationType)) { mappingDetails = "Property '" + pickerProperty.PropertyType.Name + "' with " + "Relation Type '" + relationType.Name + "'"; if(this.options.ReverseIndexing) { mappingDetails += " (Reverse Index)"; } } else { throw new Exception("Conflict with this Content Object Type and that expected by the Relation Type '" + relationType.Name + "'"); } } else { throw new Exception("Can't find a Property with the Alias '" + this.options.PropertyAlias + "'"); } return mappingDetails; } /// /// returns the UmbracoObjectType associated as defined by the supplied relation type, and if reverse indexing has been enabled /// /// associated RealationType /// public uQuery.UmbracoObjectType GetPickerUmbracoObjectType(RelationType relationType) { uQuery.UmbracoObjectType pickerUmbracoObjectType = uQuery.UmbracoObjectType.Unknown; if (!relationType.Dual && this.options.ReverseIndexing) { pickerUmbracoObjectType = relationType.GetParentUmbracoObjectType(); } else { pickerUmbracoObjectType = relationType.GetChildUmbracoObjectType(); } return pickerUmbracoObjectType; } /// /// Check to see if the content id side of the relation type is valid (doesn't check the node picker id side) /// /// Type of the content object (content/ media or member) /// Type of the relation. /// /// true if [is content object type valid] [the specified content object type]; otherwise, false. /// public bool IsContextUmbracoObjectTypeValid(uQuery.UmbracoObjectType contextUmbracoObjectType, RelationType relationType) { bool isContextObjectTypeValid = false; if (!relationType.Dual && this.options.ReverseIndexing) { // expects the current context to be the child in the relation if (contextUmbracoObjectType == relationType.GetChildUmbracoObjectType()) { isContextObjectTypeValid = true; } } else { // expects the current context to be the parent in the relation if (contextUmbracoObjectType == relationType.GetParentUmbracoObjectType()) { isContextObjectTypeValid = true; } } return isContextObjectTypeValid; } ///// ///// Insted of rendering the current name of this property, use a consistant label ///// ///// //protected override void Render(HtmlTextWriter writer) //{ // writer.WriteLine("
MultiNode Relations
"); // writer.WriteLine("
"); // base.Render(writer); // writer.WriteLine("
"); //} } }