17 using System.Collections;
18 using System.Collections.Generic;
21 using erminas.SmartAPI.CMS.Converter;
22 using erminas.SmartAPI.CMS.Project.ContentClasses.Elements;
23 using erminas.SmartAPI.CMS.Project.Folder;
24 using erminas.SmartAPI.CMS.Project.Keywords;
25 using erminas.SmartAPI.CMS.Project.Pages;
26 using erminas.SmartAPI.CMS.ServerManagement;
27 using erminas.SmartAPI.Exceptions;
28 using erminas.SmartAPI.Utils;
29 using erminas.SmartAPI.Utils.CachedCollections;
31 namespace erminas.SmartAPI.CMS.Project.ContentClasses
45 void CopyElementsToContentClass(
IContentClass targetCC, params
string[] elementNames);
52 void CopyToProject(
IProject project, Guid targetFolderGuid);
57 string DescriptionInCurrentDisplayLanguage {
get;
set; }
66 ICollection<IPage>
Pages {
get; }
73 bool IsAvailableViaTheShortcutMenuInSmartEdit {
get;
set; }
76 bool IsChangingHeadlineEffectiveForAllLanguageVariants {
get;
set; }
78 bool IsKeywordRequired {
get;
set; }
80 bool IsNotRelevantForGlobalContentWorkflow {
get;
set; }
114 internal class ContentClass : PartialRedDotProjectObject, IContentClass
116 internal ContentClass(
IProject project, XmlElement xmlElement) : base(project, xmlElement)
122 internal ContentClass(IProject project, Guid guid) : base(project, guid)
139 var query = GetSaveString(_readWriteWrapper.MergedElement);
140 Project.ExecuteRQL(query,
RqlType.SessionKeyInProject);
148 public void CopyElementsToContentClass(IContentClass targetCC, params
string[] elementNames)
150 if (elementNames == null || elementNames.Length == 0)
155 var createdElements =
new Dictionary<string, IContentClassElement>();
158 var assign =
new AttributeAssignment();
159 foreach (var languageVariant
in Project.LanguageVariants)
161 ILanguageVariant targetLanguageVariant =
162 targetCC.Project.LanguageVariants[languageVariant.Abbreviation];
163 foreach (var curElementName
in elementNames)
166 languageVariant.Select();
167 var curSourceContentClassElement = Elements[curElementName];
168 if (createdElements.TryGetValue(curElementName, out curTargetContentClassElement))
170 targetLanguageVariant.Select();
171 assign.AssignAllRedDotAttributesForLanguage(curSourceContentClassElement,
172 curTargetContentClassElement,
173 targetLanguageVariant.Abbreviation);
178 targetLanguageVariant.Select();
179 curTargetContentClassElement = curSourceContentClassElement.CopyToContentClass(targetCC);
180 createdElements.Add(curElementName, curTargetContentClassElement);
192 public void CopyToProject(IProject project, Guid targetFolderGuid)
194 ContentClass targetCC = CreateCopyInProject(project, targetFolderGuid);
196 CopyProjectVariantAssignmentToCC(targetCC);
198 CopyAttributesToCC(targetCC);
200 CopyAllElementsToCC(targetCC);
202 CopyPreassignedKeywordsToCC(targetCC);
205 private void CopyProjectVariantAssignmentToCC(ContentClass targetCC)
211 ProjectVariantAssignments.ToLookup(
212 assignment => targetCC.TemplateVariants[assignment.TemplateVariant.Name],
213 assignment =>
new ProjectVariantAssignmentSettings() { ProjectVariant = targetCC.Project.ProjectVariants[assignment.ProjectVariant.Name], IsPublishing = assignment.IsPublishing, IsNotUsingTidy = assignment.IsNotUsingTidy, TemplateVariant = targetCC.TemplateVariants[assignment.TemplateVariant.Name] });
214 targetCC.ProjectVariantAssignments.Assign(x);
222 const string DELETE_CC =
@"<TEMPLATE action=""delete"" guid=""{0}""/>";
223 XmlDocument xmlDoc = Project.ExecuteRQL(
string.Format(DELETE_CC, Guid.ToRQLString()));
224 var
template = (XmlElement) xmlDoc.GetElementsByTagName(
"TEMPLATE")[0];
226 if (
template == null || !
template.TryGetGuid(out guid) || guid != Guid)
228 var msgNode = (XmlElement) xmlDoc.GetElementsByTagName(
"MESSAGE")[0];
229 string msg =
"could not delete content class: " + ToString();
232 msg +=
"; Reason: " + msgNode.GetAttributeValue(
"value");
241 [RedDot(
"description")]
242 public string DescriptionInCurrentDisplayLanguage
244 get {
return GetAttributeValue<string>(); }
245 set { SetAttributeValue(value); }
253 public IContentClassEditableAreaSettings EditableAreaSettings {
get;
private set; }
255 public IContentClassElements Elements {
get;
private set; }
257 public ICollection<IPage>
Pages
259 get {
return Project.
Pages.Search(x => x.ContentClass =
this).ToList(); }
265 [RedDot(
"folderguid", ConverterType = typeof (ContentClassFolderConverter), Description =
"Content Class Folder"
269 get {
return GetAttributeValue<IContentClassFolder>(); }
272 [RedDot(
"selectinnewpage")]
273 public bool IsAvailableViaTheShortcutMenuInSmartEdit
275 get {
return GetAttributeValue<bool>(); }
276 set { SetAttributeValue(value); }
279 [VersionIsGreaterThanOrEqual(9, 0, 0, 41, VersionName =
"Version 9 Hotfix 5")]
280 [RedDot(
"adoptheadlinetoalllanguages")]
281 public bool IsChangingHeadlineEffectiveForAllLanguageVariants
285 VersionVerifier.EnsureVersion(Project.Session);
286 return GetAttributeValue<bool>();
290 VersionVerifier.EnsureVersion(Project.Session);
291 SetAttributeValue(value);
295 [RedDot(
"keywordrequired")]
296 public bool IsKeywordRequired
298 get {
return GetAttributeValue<bool>(); }
299 set { SetAttributeValue(value); }
302 [RedDot(
"ignoreglobalworkflow")]
303 public bool IsNotRelevantForGlobalContentWorkflow
305 get {
return GetAttributeValue<bool>(); }
306 set { SetAttributeValue(value); }
309 public IPageDefinitions PageDefinitions {
get;
private set; }
314 public IPreassignedKeywords PreassignedKeywords {
get;
private set; }
319 [RedDot(
"praefixguid", ConverterType = typeof (SyllableConverter))]
320 public ISyllable Prefix
322 get {
return GetAttributeValue<ISyllable>(); }
325 public IProjectVariantAssignments ProjectVariantAssignments {
get;
private set; }
327 [RedDot(
"requiredcategory", ConverterType = typeof (CategoryConverter))]
330 get {
return GetAttributeValue<ICategory>(); }
333 EnsureInitialization();
334 if (value != null && !IsKeywordRequired)
336 IsKeywordRequired =
true;
339 SetAttributeValue(value ?? ArbitraryCategory.INSTANCE);
346 [RedDot(
"suffixguid", ConverterType = typeof (SyllableConverter))]
347 public ISyllable Suffix
349 get {
return GetAttributeValue<ISyllable>(); }
352 public ITemplateVariants TemplateVariants {
get;
private set; }
354 public override string ToString()
356 return Name +
" (" + Guid.ToRQLString() +
")";
362 public IContentClassVersions Versions {
get;
private set; }
364 protected override void LoadWholeObject()
368 protected override XmlElement RetrieveWholeObject()
370 const string LOAD_CC =
@"<PROJECT><TEMPLATE action=""load"" guid=""{0}""/></PROJECT>";
371 XmlDocument xmlDoc = Project.ExecuteRQL(
string.Format(LOAD_CC, Guid.ToRQLString()));
372 XmlNodeList xmlNodes = xmlDoc.GetElementsByTagName(
"TEMPLATE");
373 if (xmlNodes.Count != 1)
375 throw new ArgumentException(String.Format(
"Could not find content class with guid {0}.",
376 Guid.ToRQLString()));
378 return (XmlElement) xmlNodes[0];
381 private void AddProjectVariants(IProject project, XmlElement
template)
383 XmlElement projectVariants =
template.AddElement(
"PROJECTVARIANTS");
384 projectVariants.AddAttribute(
"action",
"assign");
385 foreach (IProjectVariant curVariant
in Project.ProjectVariants)
387 XmlElement projectVariant = projectVariants.AddElement(
"PROJECTVARIANT");
388 IProjectVariant otherVariant;
389 if (!project.ProjectVariants.TryGetByName(curVariant.Name, out otherVariant))
392 string.Format(
"Could not find project variant {0} in project {1}",
393 curVariant.Name, project.Name));
395 projectVariant.AddAttribute(
"guid", otherVariant.Guid.ToRQLString());
399 private void AddTemplateDescriptions(IProject project, XmlElement
template)
401 XmlElement templateDescriptions =
template.AddElement(
"TEMPLATEDESCRIPTIONS");
402 foreach (ILanguageVariant languageVariant
in project.LanguageVariants)
404 XmlElement templateDescription = templateDescriptions.AddElement(
"TEMPLATEDESCRIPTION");
405 templateDescription.AddAttribute(
"dialoglanguageid", languageVariant.Abbreviation);
406 templateDescription.AddAttribute(
"name", Name);
407 if (!
string.IsNullOrEmpty(DescriptionInCurrentDisplayLanguage))
409 templateDescription.AddAttribute(
"description", DescriptionInCurrentDisplayLanguage);
414 private void AddTemplateVariants(XmlElement
template)
416 XmlDocument ownerDocument =
template.OwnerDocument;
418 XmlElement templateVariants =
template.AddElement(
"TEMPLATEVARIANTS");
419 foreach (ITemplateVariant curTemplateVariant
in TemplateVariants)
421 XmlElement templateVariant = templateVariants.AddElement(
"TEMPLATEVARIANT");
422 templateVariant.AddAttribute(
"name", curTemplateVariant.Name);
424 XmlText textNode = ownerDocument.CreateTextNode(curTemplateVariant.Data);
426 templateVariant.AppendChild(textNode);
430 private void CopyAllElementsToCC(IContentClass targetCC)
432 CopyElementsToContentClass(targetCC, Elements.Select(element => element.Name).ToArray());
435 private void CopyAttributesToCC(IContentClass targetCC)
437 var assignment =
new AttributeAssignment();
438 assignment.AssignAllLanguageIndependentRedDotAttributes(EditableAreaSettings, targetCC.EditableAreaSettings);
440 targetCC.EditableAreaSettings.Commit();
444 assignment.AssignAllLanguageIndependentRedDotAttributes(
this, targetCC);
445 }
catch (AttributeChangeException e)
449 "Unable to assign attribute {0} in content class {1} of project {2} to content class {3} of project {4}",
450 e.AttributeName, Name, Project.Name, targetCC.Name,
451 targetCC.Project.Name), e);
456 private void CopyPreassignedKeywordsToCC(IContentClass targetCC)
460 List<IKeyword> keywordsToAssign =
461 PreassignedKeywords.Select(
462 x => targetCC.Project.Categories.GetByName(x.Category.Name).Keywords.GetByName(x.Name)).ToList();
463 targetCC.PreassignedKeywords.Set(keywordsToAssign);
464 }
catch (Exception e)
467 string.Format(
"Could not copy preassigned keywords for content class {0}",
472 private ContentClass CreateContentClass(IProject project, XmlElement
template)
474 XmlDocument creationResultNode = project.ExecuteRQL(
template.NodeToString());
475 XmlNode guidTextNode = creationResultNode.FirstChild;
477 if (guidTextNode == null || guidTextNode.NodeType != XmlNodeType.Element || guidTextNode.FirstChild == null ||
478 !Guid.TryParse(guidTextNode.FirstChild.Value.Trim(), out newCCGuid))
481 string.Format(
"Could not create content class '{0}'", Name));
484 var targetCC =
new ContentClass(project, newCCGuid);
488 private ContentClass CreateCopyInProject(IProject project, Guid targetFolderGuid)
493 throw new ArgumentException(
"no such content class folder '" + targetFolderGuid.ToRQLString() +
494 "' in project " + Name);
497 var xmlDoc =
new XmlDocument();
498 XmlElement
template = CreateTemplateXmlElement(xmlDoc, folder);
500 AddTemplateDescriptions(project,
template);
502 AddTemplateVariants(
template);
506 return CreateContentClass(project,
template);
509 private static XmlElement CreateTemplateXmlElement(XmlDocument xmlDoc,
IContentClassFolder folder)
511 XmlElement
template = xmlDoc.AddElement(
"TEMPLATE");
512 template.AddAttribute(
"action",
"addnew");
513 template.AddAttribute(
"folderguid", folder.
Guid.ToRQLString());
519 Versions =
new ContentClassVersions(
this,
Caching.Enabled);
520 PreassignedKeywords =
new PreassignedKeywords(
this,
Caching.Enabled);
521 PageDefinitions =
new PageDefinitions(
this,
Caching.Enabled);
522 TemplateVariants =
new TemplateVariants(
this,
Caching.Enabled);
523 Elements =
new ContentClassElements(
this,
Caching.Enabled);
524 ProjectVariantAssignments =
new ProjectVariantAssignments(
this,
Caching.Enabled);
525 EditableAreaSettings =
new CCEditableAreaSettings(
this);
531 internal class ContentClassVersion : RedDotProjectObject, IContentClassVersion
533 private DateTime? _date;
537 internal ContentClassVersion(IContentClass parent, XmlElement xmlElement) : base(parent.Project, xmlElement)
539 ContentClass = parent;
542 public IContentClass ContentClass {
get;
private set; }
554 get {
return _date ?? (_date = XmlElement.GetOADate()).GetValueOrDefault(); }
560 public string DescriptionInCurrentDisplayLanguage
562 get {
return XmlElement.GetAttributeValue(
"description"); }
567 get {
return _folder ?? (_folder = Project.ContentClassFolders.GetByGuid(XmlElement.GetGuid(
"folderguid"))); }
578 string userGuid = XmlElement.GetAttributeValue(
"userguid");
579 return string.IsNullOrEmpty(userGuid)
586 public string Username
588 get {
return XmlElement.GetAttributeValue(
"username"); }
594 ILanguageDependentXmlBasedObject
601 AutomaticallyCreated = 1,