PageRenderTime 84ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/CompositeC1/Composite.Workflows/Plugins/Elements/ElementProviders/PageElementProvider/EditPageWorkflow.cs

#
C# | 778 lines | 581 code | 175 blank | 22 comment | 93 complexity | 444a30afb05836e0c6deea1afdd8c3dd MD5 | raw file
Possible License(s): LGPL-2.1
  1. /*
  2. * The contents of this web application are subject to the Mozilla Public License Version
  3. * 1.1 (the "License"); you may not use this web application except in compliance with
  4. * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/.
  5. *
  6. * Software distributed under the License is distributed on an "AS IS" basis,
  7. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  8. * for the specific language governing rights and limitations under the License.
  9. *
  10. * The Original Code is owned by and the Initial Developer of the Original Code is
  11. * Composite A/S (Danish business reg.no. 21744409). All Rights Reserved
  12. *
  13. * Section 11 of the License is EXPRESSLY amended to include a provision stating
  14. * that any dispute, including but not limited to disputes related to the enforcement
  15. * of the License, to which Composite A/S as owner of the Original Code, as Initial
  16. * Developer or in any other role, becomes a part to shall be governed by Danish law
  17. * and be initiated before the Copenhagen City Court ("K�benhavns Byret")
  18. */
  19. using System;
  20. using System.Collections.Generic;
  21. using System.Linq;
  22. using System.Web.UI;
  23. using System.Workflow.Activities;
  24. using System.Workflow.Runtime;
  25. using System.Xml.Linq;
  26. using Composite.C1Console.Actions;
  27. using Composite.C1Console.Events;
  28. using Composite.C1Console.Forms;
  29. using Composite.C1Console.Forms.DataServices;
  30. using Composite.C1Console.Forms.Flows;
  31. using Composite.C1Console.Scheduling;
  32. using Composite.C1Console.Security;
  33. using Composite.C1Console.Trees;
  34. using Composite.C1Console.Users;
  35. using Composite.C1Console.Workflow;
  36. using Composite.C1Console.Workflow.Activities;
  37. using Composite.Core;
  38. using Composite.Core.Collections.Generic;
  39. using Composite.Core.Extensions;
  40. using Composite.Core.Linq;
  41. using Composite.Core.PageTemplates;
  42. using Composite.Core.ResourceSystem;
  43. using Composite.Core.Routing.Foundation.PluginFacades;
  44. using Composite.Core.Types;
  45. using Composite.Core.WebClient.FlowMediators.FormFlowRendering;
  46. using Composite.Core.WebClient.Renderings.Page;
  47. using Composite.Core.Xml;
  48. using Composite.Data;
  49. using Composite.Data.DynamicTypes;
  50. using Composite.Data.GeneratedTypes;
  51. using Composite.Data.ProcessControlled;
  52. using Composite.Data.ProcessControlled.ProcessControllers.GenericPublishProcessController;
  53. using Composite.Data.PublishScheduling;
  54. using Composite.Data.Transactions;
  55. using Composite.Data.Types;
  56. using Composite.Data.Validation;
  57. using Composite.Data.Validation.ClientValidationRules;
  58. namespace Composite.Plugins.Elements.ElementProviders.PageElementProvider
  59. {
  60. [EntityTokenLock]
  61. [AllowPersistingWorkflow(WorkflowPersistingType.Idle)]
  62. public sealed partial class EditPageWorkflow : FormsWorkflow
  63. {
  64. [NonSerialized]
  65. private bool _doPublish;
  66. public EditPageWorkflow()
  67. {
  68. InitializeComponent();
  69. }
  70. private static DataTypeDescriptorFormsHelper CreateDataTypeDescriptorFormsHelper(IPageMetaDataDefinition pageMetaDataDefinition, DataTypeDescriptor dataTypeDescriptor)
  71. {
  72. var bindingPrefix = string.Format("{0}:{1}.{2}", pageMetaDataDefinition.Name, dataTypeDescriptor.Namespace, dataTypeDescriptor.Name);
  73. var helper = new DataTypeDescriptorFormsHelper(dataTypeDescriptor, bindingPrefix);
  74. var generatedTypesHelper = new GeneratedTypesHelper(dataTypeDescriptor);
  75. helper.AddReadOnlyFields(generatedTypesHelper.NotEditableDataFieldDescriptorNames);
  76. helper.FieldGroupLabel = StringResourceSystemFacade.ParseString(pageMetaDataDefinition.Label);
  77. return helper;
  78. }
  79. private List<KeyValuePair<Guid, string>> GetSelectablePageTypes()
  80. {
  81. var selectedPage = GetBinding<IPage>("SelectedPage");
  82. var parentPageId = selectedPage.GetParentId();
  83. IPage parentPage = null;
  84. if (parentPageId != Guid.Empty)
  85. {
  86. parentPage = PageManager.GetPageById(parentPageId);
  87. }
  88. return
  89. parentPage.GetChildPageSelectablePageTypes(selectedPage).
  90. Select(f => new KeyValuePair<Guid, string>(f.Id, f.Name)).
  91. ToList();
  92. }
  93. private List<KeyValuePair<Guid, string>> GetSelectablePageTemplates()
  94. {
  95. var selectedPage = GetBinding<IPage>("SelectedPage");
  96. var allPageTemplates = PageTemplateFacade.GetPageTemplates().ToList();
  97. var templateRestrictions =
  98. DataFacade.GetData<IPageTypePageTemplateRestriction>()
  99. .Where(f => f.PageTypeId == selectedPage.PageTypeId)
  100. .Select(restriction => restriction.PageTemplateId)
  101. .ToList();
  102. IEnumerable<PageTemplateDescriptor> result;
  103. if (templateRestrictions.Any())
  104. {
  105. var allowedTemplatesHash = new HashSet<Guid>(templateRestrictions);
  106. var allowedTemplates =
  107. allPageTemplates
  108. .Where(template => allowedTemplatesHash.Contains(template.Id))
  109. .ToList();
  110. var selectedTemplateId = selectedPage.TemplateId;
  111. var selectedTemplate = allPageTemplates.FirstOrDefault(t => t.Id == selectedTemplateId);
  112. if (selectedTemplate != null
  113. & !allowedTemplates.Any(t => t.Id == selectedTemplateId))
  114. {
  115. allowedTemplates.Add(selectedTemplate);
  116. }
  117. result = allowedTemplates;
  118. }
  119. else
  120. {
  121. result = allPageTemplates;
  122. }
  123. return result
  124. .OrderBy(template => template.Title)
  125. .Select(f => new KeyValuePair<Guid, string>(f.Id, f.Title)).ToList();
  126. }
  127. private void editStateCodeActivity_ExecuteCode(object sender, EventArgs e)
  128. {
  129. if (!PermissionsFacade.GetPermissionsForCurrentUser(EntityToken).Contains(PermissionType.Publish))
  130. {
  131. var formData = WorkflowFacade.GetFormData(InstanceId, true);
  132. if (formData.ExcludedEvents == null)
  133. formData.ExcludedEvents = new List<string>();
  134. formData.ExcludedEvents.Add("SaveAndPublish");
  135. }
  136. IPage selectedPage;
  137. if (!BindingExist("SelectedPage"))
  138. {
  139. selectedPage = GetDataItemFromEntityToken<IPage>();
  140. if (selectedPage.PublicationStatus == GenericPublishProcessController.Published)
  141. {
  142. selectedPage.PublicationStatus = GenericPublishProcessController.Draft;
  143. }
  144. Bindings.Add("SelectedPage", selectedPage);
  145. }
  146. else
  147. {
  148. selectedPage = GetBinding<IPage>("SelectedPage");
  149. }
  150. if (!BindingExist("UrlTitleIsRequired"))
  151. {
  152. var isRootPage = PageManager.GetParentId(selectedPage.Id) == Guid.Empty;
  153. Bindings["UrlTitleIsRequired"] = !isRootPage;
  154. Bindings["IsRootPage"] = isRootPage;
  155. }
  156. IFormMarkupProvider markupProvider = new FormDefinitionFileMarkupProvider(@"\Administrative\EditPage.xml");
  157. XDocument formDocument;
  158. using (var reader = markupProvider.GetReader())
  159. {
  160. formDocument = XDocument.Load(reader);
  161. }
  162. var bindingsXElement = formDocument.Root.Element(DataTypeDescriptorFormsHelper.CmsNamespace + FormKeyTagNames.Bindings);
  163. var layoutXElement = formDocument.Root.Element(DataTypeDescriptorFormsHelper.CmsNamespace + FormKeyTagNames.Layout);
  164. var tabPanelsXElement = layoutXElement.Element(DataTypeDescriptorFormsHelper.MainNamespace + "TabPanels");
  165. IEnumerable<ICompositionContainer> compositionContainers = selectedPage.GetAllowedMetaDataContainers().Evaluate();
  166. var compositionTabs = new Dictionary<Guid, XElement>();
  167. foreach (var compositionContainer in compositionContainers)
  168. {
  169. var element = new XElement(Namespaces.BindingFormsStdUiControls10 + "PlaceHolder");
  170. element.Add(new XAttribute("Label", StringResourceSystemFacade.ParseString(compositionContainer.Label)));
  171. compositionTabs.Add(compositionContainer.Id, element);
  172. }
  173. var clientValidationRules = new Dictionary<string, List<ClientValidationRule>>();
  174. var pageMetaDataDefinitions = selectedPage.GetAllowedMetaDataDefinitions();
  175. foreach (var pageMetaDataDefinition in pageMetaDataDefinitions)
  176. {
  177. var metaDatTypeId = pageMetaDataDefinition.MetaDataTypeId;
  178. var dataTypeDescriptor = DynamicTypeManager.GetDataTypeDescriptor(metaDatTypeId);
  179. Verify.IsNotNull(dataTypeDescriptor, "Failed to get meta data type by id '{0}'. If data type was purposely removed, in order to fix this exception you should remove IPageMetaDataDefinition records that reference this data type.", metaDatTypeId);
  180. var metaDataType = TypeManager.TryGetType(dataTypeDescriptor.TypeManagerTypeName);
  181. Verify.IsNotNull(metaDataType, "Failed to get meta data type '{0}', id: {1}. If it has been removed, references from '{2}' have to be removed as well",
  182. dataTypeDescriptor.TypeManagerTypeName, metaDatTypeId, typeof(IPageMetaDataDefinition).Name);
  183. var helper = CreateDataTypeDescriptorFormsHelper(pageMetaDataDefinition, dataTypeDescriptor);
  184. var metaData = selectedPage.GetMetaData(pageMetaDataDefinition.Name, metaDataType);
  185. if (metaData == null)
  186. {
  187. metaData = DataFacade.BuildNew(metaDataType);
  188. PageMetaDataFacade.AssignMetaDataSpecificValues(metaData, pageMetaDataDefinition.Name, selectedPage);
  189. var localizedData = metaData as ILocalizedControlled;
  190. if (localizedData != null)
  191. {
  192. localizedData.SourceCultureName = UserSettings.ActiveLocaleCultureInfo.Name;
  193. }
  194. var publishControlled = metaData as IPublishControlled;
  195. publishControlled.PublicationStatus = GenericPublishProcessController.Draft;
  196. helper.UpdateWithNewBindings(Bindings);
  197. helper.ObjectToBindings(metaData, Bindings);
  198. }
  199. else
  200. {
  201. helper.UpdateWithBindings(metaData, Bindings);
  202. }
  203. bindingsXElement.Add(helper.BindingXml.Elements());
  204. compositionTabs[pageMetaDataDefinition.MetaDataContainerId].Add(helper.PanelXml);
  205. clientValidationRules.AddDictionary(helper.GetBindingsValidationRules(metaData));
  206. }
  207. var previewTabPanel = tabPanelsXElement.Elements().Last();
  208. foreach (var element in compositionTabs.Values)
  209. {
  210. previewTabPanel.AddBeforeSelf(element);
  211. }
  212. IDictionary<string, string> transitionNames = new Dictionary<string, string>();
  213. transitionNames.Add(GenericPublishProcessController.Draft, StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.DraftTransition"));
  214. transitionNames.Add(GenericPublishProcessController.AwaitingApproval, StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.AwaitingApprovalTransition"));
  215. var username = UserValidationFacade.GetUsername();
  216. var userPermissionDefinitions = PermissionTypeFacade.GetUserPermissionDefinitions(username);
  217. var userGroupPermissionDefinitions = PermissionTypeFacade.GetUserGroupPermissionDefinitions(username);
  218. var currentPermissionTypes = PermissionTypeFacade.GetCurrentPermissionTypes(UserValidationFacade.GetUserToken(), EntityToken, userPermissionDefinitions, userGroupPermissionDefinitions);
  219. foreach (var permissionType in currentPermissionTypes)
  220. {
  221. if (GenericPublishProcessController.AwaitingPublicationActionPermissionType.Contains(permissionType))
  222. {
  223. transitionNames.Add(GenericPublishProcessController.AwaitingPublication, StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.AwaitingPublicationTransition"));
  224. break;
  225. }
  226. }
  227. var contents = DataFacade.GetData<IPagePlaceholderContent>(f => f.PageId == selectedPage.Id).ToList();
  228. var namedXhtmlFragments = contents.ToDictionary(content => content.PlaceHolderId, content => content.Content ?? "");
  229. UpdateBinding("SelectablePageTypeIds", GetSelectablePageTypes());
  230. UpdateBinding("SelectableTemplateIds", GetSelectablePageTemplates());
  231. UpdateBinding("NamedXhtmlFragments", namedXhtmlFragments);
  232. UpdateBinding("StateOptions", transitionNames);
  233. var existingPagePublishSchedule = PublishScheduleHelper.GetPublishSchedule(typeof (IPage),
  234. selectedPage.Id.ToString(),
  235. UserSettings.CultureInfo.Name);
  236. UpdateBinding("PublishDate", existingPagePublishSchedule != null ? existingPagePublishSchedule.PublishDate : (object) null);
  237. var existingPageUnpublishSchedule = PublishScheduleHelper.GetUnpublishSchedule(typeof(IPage),
  238. selectedPage.Id.ToString(),
  239. UserSettings.CultureInfo.Name);
  240. UpdateBinding("UnpublishDate", existingPageUnpublishSchedule != null ? existingPageUnpublishSchedule.UnpublishDate : (object) null);
  241. var formDefinition = formDocument.GetDocumentAsString();
  242. DeliverFormData(
  243. selectedPage.Title,
  244. StandardUiContainerTypes.Document,
  245. formDefinition,
  246. Bindings,
  247. clientValidationRules
  248. );
  249. }
  250. private void newPageTypeSelectedCodeActivity_UpdateView_ExecuteCode(object sender, EventArgs e)
  251. {
  252. RerenderView();
  253. }
  254. private void saveCodeActivity_ExecuteCode(object sender, EventArgs e)
  255. {
  256. var updateTreeRefresher = CreateUpdateTreeRefresher(EntityToken);
  257. var selectedPage = GetBinding<IPage>("SelectedPage");
  258. var originalPage = DataFacade.GetData<IPage>(f => f.Id == selectedPage.Id).SingleOrDefault();
  259. var viewLabelUpdated = originalPage == null
  260. || selectedPage.MenuTitle != originalPage.MenuTitle
  261. || selectedPage.Title != originalPage.Title;
  262. var treeviewRequiresRefreshing = false;
  263. var dataToAdd = new Dictionary<string, IData>();
  264. var dataToUpdate = new Dictionary<string, IData>();
  265. var dataValidated = true;
  266. WorkflowInstance publishWorkflowInstance = null;
  267. WorkflowInstance unpublishWorkflowInstance = null;
  268. try
  269. {
  270. using (var transactionScope = TransactionsFacade.CreateNewScope())
  271. {
  272. dataValidated = PrepareAddUpdateMetaData(selectedPage, dataToAdd, dataToUpdate);
  273. if (dataValidated)
  274. {
  275. PublishControlledHelper.HandlePublishUnpublishWorkflows(selectedPage, UserSettings.ActiveLocaleCultureInfo.Name, PublishDate, UnpublishDate, ref publishWorkflowInstance, ref unpublishWorkflowInstance);
  276. if (selectedPage.PageTypeId != originalPage.PageTypeId)
  277. {
  278. // Adding metadata fields
  279. var oldPageMetaDataDefinitions = originalPage.GetAllowedMetaDataDefinitions().Except(selectedPage.GetAllowedMetaDataDefinitions(), new PageMetaDataDefinitionEqualityComparer());
  280. foreach (var pageMetaDataDefinition in oldPageMetaDataDefinitions)
  281. {
  282. var oldMetaData = selectedPage.GetMetaData(pageMetaDataDefinition.Name, pageMetaDataDefinition.MetaDataTypeId);
  283. if (oldMetaData != null)
  284. {
  285. ProcessControllerFacade.FullDelete(oldMetaData);
  286. }
  287. }
  288. // Adding page folders
  289. var pageTypeDataFolderTypeLinks =
  290. DataFacade.GetData<IPageTypeDataFolderTypeLink>().
  291. Where(f => f.PageTypeId == selectedPage.PageTypeId).
  292. Evaluate().
  293. RemoveDeadLinks();
  294. foreach (var pageTypeDataFolderTypeLink in pageTypeDataFolderTypeLinks)
  295. {
  296. if (selectedPage.GetFolderDefinitionId(pageTypeDataFolderTypeLink.DataTypeId) != Guid.Empty) continue;
  297. selectedPage.AddFolderDefinition(pageTypeDataFolderTypeLink.DataTypeId);
  298. treeviewRequiresRefreshing = true;
  299. }
  300. // Adding applications
  301. var pageTypeTreeLinks =
  302. DataFacade.GetData<IPageTypeTreeLink>().
  303. Where(f => f.PageTypeId == selectedPage.PageTypeId).
  304. Evaluate().
  305. RemoveDeadLinks();
  306. foreach (var pageTypeTreeLink in pageTypeTreeLinks)
  307. {
  308. var tree = TreeFacade.GetTree(pageTypeTreeLink.TreeId);
  309. if (tree.HasAttachmentPoints(selectedPage.GetDataEntityToken())) continue;
  310. TreeFacade.AddPersistedAttachmentPoint(pageTypeTreeLink.TreeId, typeof(IPage), selectedPage.Id);
  311. treeviewRequiresRefreshing = true;
  312. }
  313. }
  314. foreach (var data in dataToAdd.Values)
  315. {
  316. DataFacade.AddNew(data);
  317. }
  318. foreach (var data in dataToUpdate.Values)
  319. {
  320. var publishControlled = data as IPublishControlled;
  321. publishControlled.PublicationStatus = GenericPublishProcessController.Draft;
  322. DataFacade.Update(data);
  323. }
  324. treeviewRequiresRefreshing |= (originalPage.Title != selectedPage.Title) ||
  325. (originalPage.Description != selectedPage.Description) ||
  326. (originalPage.PublicationStatus != selectedPage.PublicationStatus);
  327. // NOTE: updating originalPage object, in order to make XML & SQL provider work in the same way
  328. originalPage.TemplateId = selectedPage.TemplateId;
  329. originalPage.PageTypeId = selectedPage.PageTypeId;
  330. originalPage.Title = selectedPage.Title;
  331. originalPage.MenuTitle = selectedPage.MenuTitle;
  332. originalPage.UrlTitle = selectedPage.UrlTitle;
  333. originalPage.FriendlyUrl = selectedPage.FriendlyUrl;
  334. originalPage.Description = selectedPage.Description;
  335. originalPage.PublicationStatus = selectedPage.PublicationStatus;
  336. originalPage.SourceCultureName = selectedPage.SourceCultureName;
  337. DataFacade.Update(originalPage);
  338. var contentDictionary = GetBinding<Dictionary<string, string>>("NamedXhtmlFragments");
  339. var existingContents = DataFacade.GetData<IPagePlaceholderContent>(f => f.PageId == selectedPage.Id).ToList();
  340. foreach (var existingContent in existingContents)
  341. {
  342. if (contentDictionary.ContainsKey(existingContent.PlaceHolderId))
  343. {
  344. existingContent.Content = contentDictionary[existingContent.PlaceHolderId];
  345. existingContent.PublicationStatus = GenericPublishProcessController.Draft;
  346. DataFacade.Update(existingContent);
  347. }
  348. else
  349. {
  350. DataFacade.Delete(existingContent);
  351. }
  352. }
  353. foreach (var contentDictionaryElement in contentDictionary.Where(f => existingContents.Any(existing => existing.PlaceHolderId == f.Key) == false))
  354. {
  355. var newContent = DataFacade.BuildNew<IPagePlaceholderContent>();
  356. newContent.PageId = selectedPage.Id;
  357. newContent.PlaceHolderId = contentDictionaryElement.Key;
  358. newContent.Content = contentDictionaryElement.Value;
  359. newContent.SourceCultureName = UserSettings.ActiveLocaleCultureInfo.Name;
  360. newContent.PublicationStatus = GenericPublishProcessController.Draft;
  361. DataFacade.AddNew(newContent);
  362. }
  363. }
  364. transactionScope.Complete();
  365. }
  366. if (publishWorkflowInstance != null)
  367. {
  368. publishWorkflowInstance.Start();
  369. WorkflowFacade.RunWorkflow(publishWorkflowInstance);
  370. }
  371. if (unpublishWorkflowInstance != null)
  372. {
  373. unpublishWorkflowInstance.Start();
  374. WorkflowFacade.RunWorkflow(unpublishWorkflowInstance);
  375. }
  376. if (_doPublish)
  377. {
  378. if (publishWorkflowInstance == null || PublishDate < DateTime.Now)
  379. {
  380. var actionToken = new GenericPublishProcessController.PublishActionToken();
  381. var serviceContainer = WorkflowFacade.GetFlowControllerServicesContainer(WorkflowEnvironment.WorkflowInstanceId);
  382. ActionExecutorFacade.Execute(EntityToken, actionToken, serviceContainer);
  383. treeviewRequiresRefreshing = false;
  384. }
  385. else
  386. {
  387. var title = StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.PublishDatePreventPublishTitle");
  388. var message = StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.PublishDatePreventPublish");
  389. ShowMessage(DialogType.Warning, title, message);
  390. }
  391. }
  392. if (treeviewRequiresRefreshing)
  393. {
  394. updateTreeRefresher.PostRefreshMesseges(selectedPage.GetDataEntityToken());
  395. }
  396. UpdateBinding("OldPublicationStatus", selectedPage.PublicationStatus);
  397. if (viewLabelUpdated)
  398. {
  399. RerenderView();
  400. }
  401. }
  402. catch (Exception ex)
  403. {
  404. var mostSpecificException = ex;
  405. while (mostSpecificException.InnerException != null) mostSpecificException = mostSpecificException.InnerException;
  406. ShowMessage(DialogType.Error, "Save failed", string.Format("Save failed: {0}", mostSpecificException.Message));
  407. Log.LogError("Page save", ex);
  408. }
  409. finally
  410. {
  411. SetSaveStatus(dataValidated);
  412. }
  413. }
  414. private bool PrepareAddUpdateMetaData(IPage selectedPage, IDictionary<string, IData> dataToAdd, IDictionary<string, IData> dataToUpdate)
  415. {
  416. var isValid = ValidateBindings();
  417. IEnumerable<IPageMetaDataDefinition> pageMetaDataDefinitions = selectedPage.GetAllowedMetaDataDefinitions().Evaluate();
  418. foreach (var pageMetaDataDefinition in pageMetaDataDefinitions)
  419. {
  420. var dataTypeDescriptor = DynamicTypeManager.GetDataTypeDescriptor(pageMetaDataDefinition.MetaDataTypeId);
  421. var metaDataType = TypeManager.GetType(dataTypeDescriptor.TypeManagerTypeName);
  422. var helper = CreateDataTypeDescriptorFormsHelper(pageMetaDataDefinition, dataTypeDescriptor);
  423. var metaData = selectedPage.GetMetaData(pageMetaDataDefinition.Name, metaDataType);
  424. if (metaData == null)
  425. {
  426. var newData = DataFacade.BuildNew(metaDataType);
  427. PageMetaDataFacade.AssignMetaDataSpecificValues(newData, pageMetaDataDefinition.Name, selectedPage);
  428. var localizedData = newData as ILocalizedControlled;
  429. if (localizedData != null)
  430. {
  431. localizedData.SourceCultureName = UserSettings.ActiveLocaleCultureInfo.Name;
  432. }
  433. if (!BindAndValidate(helper, newData))
  434. {
  435. isValid = false;
  436. }
  437. dataToAdd.Add(helper.BindingNamesPrefix, newData);
  438. }
  439. else
  440. {
  441. if (!BindAndValidate(helper, metaData))
  442. {
  443. isValid = false;
  444. }
  445. dataToUpdate.Add(helper.BindingNamesPrefix, metaData);
  446. }
  447. }
  448. var pageValidationResults = ValidationFacade.Validate(selectedPage);
  449. if (!pageValidationResults.IsValid)
  450. {
  451. isValid = false;
  452. }
  453. foreach (var kvp in dataToAdd.Concat(dataToUpdate))
  454. {
  455. var validationResults = ValidationFacade.Validate(kvp.Value);
  456. if (!validationResults.IsValid)
  457. {
  458. isValid = false;
  459. foreach (var result in validationResults)
  460. {
  461. ShowFieldMessage(DataTypeDescriptorFormsHelper.GetBindingName(kvp.Key, result.Key), result.Message);
  462. }
  463. }
  464. }
  465. return isValid;
  466. }
  467. private DateTime? PublishDate
  468. {
  469. get { return GetBinding<DateTime?>("PublishDate"); }
  470. }
  471. private DateTime? UnpublishDate
  472. {
  473. get { return GetBinding<DateTime?>("UnpublishDate"); }
  474. }
  475. private void editPreviewCodeActivity_ExecuteCode(object sender, EventArgs e)
  476. {
  477. var serviceContainer = WorkflowFacade.GetFlowControllerServicesContainer(WorkflowEnvironment.WorkflowInstanceId);
  478. var webRenderService = serviceContainer.GetService<IFormFlowWebRenderingService>();
  479. try
  480. {
  481. var selectedPage = GetBinding<IPage>("SelectedPage");
  482. var contents = new List<IPagePlaceholderContent>();
  483. var namedXhtmlFragments = GetBinding<Dictionary<string, string>>("NamedXhtmlFragments");
  484. foreach (var placeHolderContent in namedXhtmlFragments)
  485. {
  486. var content = DataFacade.BuildNew<IPagePlaceholderContent>();
  487. content.PageId = selectedPage.Id;
  488. content.PlaceHolderId = placeHolderContent.Key;
  489. content.Content = placeHolderContent.Value;
  490. contents.Add(content);
  491. }
  492. var output = PagePreviewBuilder.RenderPreview(selectedPage, contents);
  493. webRenderService.SetNewPageOutput(new LiteralControl(output));
  494. }
  495. catch (Exception ex)
  496. {
  497. Control errOutput = new LiteralControl("<pre>" + ex + "</pre>");
  498. webRenderService.SetNewPageOutput(errOutput);
  499. }
  500. }
  501. private static void TrimFieldValues(IPage page)
  502. {
  503. page.Title = page.Title.Trim();
  504. page.MenuTitle = page.MenuTitle.Trim();
  505. page.UrlTitle = page.UrlTitle.Trim();
  506. var friendlyURL = page.FriendlyUrl;
  507. page.FriendlyUrl = friendlyURL != null ? friendlyURL.Trim() : null;
  508. }
  509. private bool FieldHasValidLength(string fieldValue, string fieldName, int maximumLength)
  510. {
  511. if (fieldValue.Length <= maximumLength)
  512. {
  513. return true;
  514. }
  515. var bindingName = "SelectedPage." + fieldName;
  516. ShowFieldMessage(bindingName, GetText("EditPage.MaxLength").FormatWith(maximumLength));
  517. return false;
  518. }
  519. private void ValidateSave(object sender, ConditionalEventArgs e)
  520. {
  521. var selectedPage = GetBinding<IPage>("SelectedPage");
  522. selectedPage.MenuTitle = selectedPage.MenuTitle ?? string.Empty;
  523. selectedPage.FriendlyUrl = selectedPage.FriendlyUrl ?? string.Empty;
  524. TrimFieldValues(selectedPage);
  525. if (!FieldHasValidLength(selectedPage.Title, "Title", 255)
  526. || !FieldHasValidLength(selectedPage.MenuTitle, "MenuTitle", 64)
  527. || !FieldHasValidLength(selectedPage.UrlTitle, "UrlTitle", 64)
  528. || !FieldHasValidLength(selectedPage.FriendlyUrl, "FriendlyUrl", 64))
  529. {
  530. e.Result = false;
  531. return;
  532. }
  533. e.Result = true;
  534. var processedUrlTitle = UrlFormattersPluginFacade.FormatUrl(selectedPage.UrlTitle, true);
  535. if (selectedPage.UrlTitle != processedUrlTitle)
  536. {
  537. RerenderView();
  538. selectedPage.UrlTitle = processedUrlTitle;
  539. ShowMessage(DialogType.Message,
  540. GetText("EditPage.UrlTitleFormattedTitle"),
  541. (GetText("EditPage.UrlTitleFormattedMessage") ?? string.Empty).FormatWith(processedUrlTitle));
  542. }
  543. var siblingPageUrlTitles =
  544. (from page in PageServices.GetChildren(selectedPage.GetParentId())
  545. where page.Id != selectedPage.Id
  546. select page.UrlTitle).ToList();
  547. foreach (var siblingUrlTitle in siblingPageUrlTitles)
  548. {
  549. if (siblingUrlTitle.Equals(selectedPage.UrlTitle, StringComparison.InvariantCultureIgnoreCase))
  550. {
  551. ShowFieldMessage("SelectedPage.UrlTitle", "${Composite.Plugins.PageElementProvider, UrlTitleNotUniqueError}");
  552. e.Result = false;
  553. break;
  554. }
  555. }
  556. if (string.IsNullOrEmpty(selectedPage.FriendlyUrl) == false)
  557. {
  558. var usedFriendlyUrls = DataFacade.GetData<IPage>(f => f.FriendlyUrl != null && f.FriendlyUrl != string.Empty && f.Id != selectedPage.Id).Select(f => f.FriendlyUrl).ToList();
  559. if (usedFriendlyUrls.Any(f => f.Equals(selectedPage.FriendlyUrl, StringComparison.InvariantCultureIgnoreCase)))
  560. {
  561. ShowFieldMessage("SelectedPage.FriendlyUrl", "${Composite.Plugins.PageElementProvider, FriendlyUrlNotUniqueError}");
  562. e.Result = false;
  563. }
  564. }
  565. if (string.IsNullOrEmpty(selectedPage.Title))
  566. {
  567. ShowFieldMessage("SelectedPage.Title", "${Composite.Plugins.PageElementProvider, TitleMissingError}");
  568. e.Result = false;
  569. }
  570. var validationResults = ValidationFacade.Validate(selectedPage);
  571. if (!validationResults.IsValid)
  572. {
  573. if (validationResults.Any(f => f.Key == "UrlTitle"))
  574. {
  575. ShowFieldMessage("SelectedPage.UrlTitle", "${Composite.Plugins.PageElementProvider, UrlTitleNotValidError}");
  576. e.Result = false;
  577. }
  578. foreach (var validationResult in validationResults.Where(f => f.Key != "UrlTitle"))
  579. {
  580. ShowFieldMessage("SelectedPage." + validationResult.Key, validationResult.Message);
  581. }
  582. }
  583. if (!ValidateBindings())
  584. {
  585. e.Result = false;
  586. }
  587. }
  588. private static string GetText(string key)
  589. {
  590. return StringResourceSystemFacade.GetString("Composite.Plugins.PageElementProvider", key);
  591. }
  592. private void PageStillExists(object sender, ConditionalEventArgs e)
  593. {
  594. var selectedPage = GetBinding<IPage>("SelectedPage");
  595. var originalPage = DataFacade.GetData<IPage>(f => f.Id == selectedPage.Id).SingleOrDefault();
  596. e.Result = originalPage != null;
  597. }
  598. private void setToPublishCodeActivity_ExecuteCode(object sender, EventArgs e)
  599. {
  600. _doPublish = true;
  601. }
  602. }
  603. }