PageRenderTime 51ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Libraries/Nop.Services/Installation/SqlFileInstallationService.cs

http://nopcommerce.codeplex.com
C# | 316 lines | 253 code | 57 blank | 6 comment | 20 complexity | 009fcebb3db467c622cf8a3b29b3ed07 MD5 | raw file
Possible License(s): LGPL-2.1
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Xml;
  8. using Nop.Core;
  9. using Nop.Core.Configuration;
  10. using Nop.Core.Data;
  11. using Nop.Core.Domain;
  12. using Nop.Core.Domain.Blogs;
  13. using Nop.Core.Domain.Catalog;
  14. using Nop.Core.Domain.Cms;
  15. using Nop.Core.Domain.Common;
  16. using Nop.Core.Domain.Customers;
  17. using Nop.Core.Domain.Directory;
  18. using Nop.Core.Domain.Discounts;
  19. using Nop.Core.Domain.Forums;
  20. using Nop.Core.Domain.Localization;
  21. using Nop.Core.Domain.Logging;
  22. using Nop.Core.Domain.Media;
  23. using Nop.Core.Domain.Messages;
  24. using Nop.Core.Domain.News;
  25. using Nop.Core.Domain.Orders;
  26. using Nop.Core.Domain.Payments;
  27. using Nop.Core.Domain.Polls;
  28. using Nop.Core.Domain.Security;
  29. using Nop.Core.Domain.Shipping;
  30. using Nop.Core.Domain.Tasks;
  31. using Nop.Core.Domain.Tax;
  32. using Nop.Core.Domain.Topics;
  33. using Nop.Core.Infrastructure;
  34. using Nop.Core.IO;
  35. using Nop.Data;
  36. using Nop.Services.Common;
  37. using Nop.Services.Customers;
  38. using Nop.Services.Helpers;
  39. using Nop.Services.Media;
  40. using Nop.Services.Localization;
  41. using Nop.Services.Seo;
  42. using Nop.Core.Domain.Seo;
  43. namespace Nop.Services.Installation
  44. {
  45. public partial class SqlFileInstallationService : IInstallationService
  46. {
  47. #region Fields
  48. private readonly IRepository<Language> _languageRepository;
  49. private readonly IRepository<Customer> _customerRepository;
  50. private readonly IDataProvider _dataProvider;
  51. private readonly IDbContext _dbContext;
  52. private readonly IWebHelper _webHelper;
  53. #endregion
  54. #region Ctor
  55. public SqlFileInstallationService(IRepository<Language> languageRepository,
  56. IRepository<Customer> customerRepository,
  57. IDataProvider dataProvider,
  58. IDbContext dbContext,
  59. IWebHelper webHelper)
  60. {
  61. this._languageRepository = languageRepository;
  62. this._customerRepository = customerRepository;
  63. this._dataProvider = dataProvider;
  64. this._dbContext = dbContext;
  65. this._webHelper = webHelper;
  66. }
  67. #endregion
  68. #region Classes
  69. private class LocaleStringResourceParent : LocaleStringResource
  70. {
  71. public LocaleStringResourceParent(XmlNode localStringResource, string nameSpace = "")
  72. {
  73. Namespace = nameSpace;
  74. var resNameAttribute = localStringResource.Attributes["Name"];
  75. var resValueNode = localStringResource.SelectSingleNode("Value");
  76. if (resNameAttribute == null)
  77. {
  78. throw new NopException("All language resources must have an attribute Name=\"Value\".");
  79. }
  80. var resName = resNameAttribute.Value.Trim();
  81. if (string.IsNullOrEmpty(resName))
  82. {
  83. throw new NopException("All languages resource attributes 'Name' must have a value.'");
  84. }
  85. ResourceName = resName;
  86. if (resValueNode == null || string.IsNullOrEmpty(resValueNode.InnerText.Trim()))
  87. {
  88. IsPersistable = false;
  89. }
  90. else
  91. {
  92. IsPersistable = true;
  93. ResourceValue = resValueNode.InnerText.Trim();
  94. }
  95. foreach (XmlNode childResource in localStringResource.SelectNodes("Children/LocaleResource"))
  96. {
  97. ChildLocaleStringResources.Add(new LocaleStringResourceParent(childResource, NameWithNamespace));
  98. }
  99. }
  100. public string Namespace { get; set; }
  101. public IList<LocaleStringResourceParent> ChildLocaleStringResources = new List<LocaleStringResourceParent>();
  102. public bool IsPersistable { get; set; }
  103. public string NameWithNamespace
  104. {
  105. get
  106. {
  107. var newNamespace = Namespace;
  108. if (!string.IsNullOrEmpty(newNamespace))
  109. {
  110. newNamespace += ".";
  111. }
  112. return newNamespace + ResourceName;
  113. }
  114. }
  115. }
  116. private class ComparisonComparer<T> : IComparer<T>, IComparer
  117. {
  118. private readonly Comparison<T> _comparison;
  119. public ComparisonComparer(Comparison<T> comparison)
  120. {
  121. _comparison = comparison;
  122. }
  123. public int Compare(T x, T y)
  124. {
  125. return _comparison(x, y);
  126. }
  127. public int Compare(object o1, object o2)
  128. {
  129. return _comparison((T)o1, (T)o2);
  130. }
  131. }
  132. #endregion
  133. #region Utilities
  134. private void RecursivelyWriteResource(LocaleStringResourceParent resource, XmlWriter writer)
  135. {
  136. //The value isn't actually used, but the name is used to create a namespace.
  137. if (resource.IsPersistable)
  138. {
  139. writer.WriteStartElement("LocaleResource", "");
  140. writer.WriteStartAttribute("Name", "");
  141. writer.WriteString(resource.NameWithNamespace);
  142. writer.WriteEndAttribute();
  143. writer.WriteStartElement("Value", "");
  144. writer.WriteString(resource.ResourceValue);
  145. writer.WriteEndElement();
  146. writer.WriteEndElement();
  147. }
  148. foreach (var child in resource.ChildLocaleStringResources)
  149. {
  150. RecursivelyWriteResource(child, writer);
  151. }
  152. }
  153. private void RecursivelySortChildrenResource(LocaleStringResourceParent resource)
  154. {
  155. ArrayList.Adapter((IList)resource.ChildLocaleStringResources).Sort(new ComparisonComparer<LocaleStringResourceParent>((x1, x2) => x1.ResourceName.CompareTo(x2.ResourceName)));
  156. foreach (var child in resource.ChildLocaleStringResources)
  157. {
  158. RecursivelySortChildrenResource(child);
  159. }
  160. }
  161. protected virtual void InstallLocaleResources()
  162. {
  163. //'English' language
  164. var language = _languageRepository.Table.Single(l => l.Name == "English");
  165. //save resoureces
  166. foreach (var filePath in System.IO.Directory.EnumerateFiles(_webHelper.MapPath("~/App_Data/Localization/"), "*.nopres.xml", SearchOption.TopDirectoryOnly))
  167. {
  168. #region Parse resource files (with <Children> elements)
  169. //read and parse original file with resources (with <Children> elements)
  170. var originalXmlDocument = new XmlDocument();
  171. originalXmlDocument.Load(filePath);
  172. var resources = new List<LocaleStringResourceParent>();
  173. foreach (XmlNode resNode in originalXmlDocument.SelectNodes(@"//Language/LocaleResource"))
  174. resources.Add(new LocaleStringResourceParent(resNode));
  175. resources.Sort((x1, x2) => x1.ResourceName.CompareTo(x2.ResourceName));
  176. foreach (var resource in resources)
  177. RecursivelySortChildrenResource(resource);
  178. var sb = new StringBuilder();
  179. var writer = XmlWriter.Create(sb);
  180. writer.WriteStartDocument();
  181. writer.WriteStartElement("Language", "");
  182. writer.WriteStartAttribute("Name", "");
  183. writer.WriteString(originalXmlDocument.SelectSingleNode(@"//Language").Attributes["Name"].InnerText.Trim());
  184. writer.WriteEndAttribute();
  185. foreach (var resource in resources)
  186. RecursivelyWriteResource(resource, writer);
  187. writer.WriteEndElement();
  188. writer.WriteEndDocument();
  189. writer.Flush();
  190. var parsedXml = sb.ToString();
  191. #endregion
  192. //now we have a parsed XML file (the same structure as exported language packs)
  193. //let's save resources
  194. var localizationService = EngineContext.Current.Resolve<ILocalizationService>();
  195. localizationService.ImportResourcesFromXml(language, parsedXml);
  196. }
  197. }
  198. protected virtual void UpdateDefaultCustomer(string defaultUserEmail, string defaultUserPassword)
  199. {
  200. var adminUser = _customerRepository.Table.Single(x => !x.IsSystemAccount);
  201. if (adminUser == null)
  202. throw new Exception("Admin user cannot be loaded");
  203. adminUser.CustomerGuid = Guid.NewGuid();
  204. adminUser.Email = defaultUserEmail;
  205. adminUser.Username = defaultUserEmail;
  206. _customerRepository.Update(adminUser);
  207. var customerRegistrationService = EngineContext.Current.Resolve<ICustomerRegistrationService>();
  208. customerRegistrationService.ChangePassword(new ChangePasswordRequest(defaultUserEmail, false,
  209. PasswordFormat.Hashed, defaultUserPassword));
  210. }
  211. protected virtual void ExecuteSqlFile(string path)
  212. {
  213. var statements = new List<string>();
  214. using (var stream = File.OpenRead(path))
  215. using (var reader = new StreamReader(stream))
  216. {
  217. string statement = "";
  218. while ((statement = ReadNextStatementFromStream(reader)) != null)
  219. statements.Add(statement);
  220. }
  221. foreach (string stmt in statements)
  222. _dbContext.ExecuteSqlCommand(stmt);
  223. }
  224. protected virtual string ReadNextStatementFromStream(StreamReader reader)
  225. {
  226. var sb = new StringBuilder();
  227. string lineOfText = "";
  228. while (true)
  229. {
  230. lineOfText = reader.ReadLine();
  231. if (lineOfText == null)
  232. {
  233. if (sb.Length > 0)
  234. return sb.ToString();
  235. else
  236. return null;
  237. }
  238. if (lineOfText.TrimEnd().ToUpper() == "GO")
  239. break;
  240. sb.Append(lineOfText + Environment.NewLine);
  241. }
  242. return sb.ToString();
  243. }
  244. #endregion
  245. #region Methods
  246. public virtual void InstallData(string defaultUserEmail,
  247. string defaultUserPassword, bool installSampleData = true)
  248. {
  249. ExecuteSqlFile(_webHelper.MapPath("~/App_Data/Install/create_required_data.sql"));
  250. InstallLocaleResources();
  251. UpdateDefaultCustomer(defaultUserEmail, defaultUserPassword);
  252. if (installSampleData)
  253. {
  254. ExecuteSqlFile(_webHelper.MapPath("~/App_Data/Install/create_sample_data.sql"));
  255. }
  256. }
  257. #endregion
  258. }
  259. }