Adds logging to the package installer for debugging. Updates DisposableTimer to pass delegates for logging for tracing/info.
Fixes PluginManager cache file handling. Ensures cache file is written with the correct TypeResolutionKind. Have added a check to ensure the file is replaced if a legacy file is found. Added a check to the PluginManager to load from scanning if the cache item is not found in the file, this fixes all install issues with the type finding in 4.11. Added new batch file to reset an umbraco install to vanilla (not 100% complete yet)
This commit is contained in:
98
build/RevertToCleanInstall.bat
Normal file
98
build/RevertToCleanInstall.bat
Normal file
@@ -0,0 +1,98 @@
|
||||
@ECHO OFF
|
||||
|
||||
:choice
|
||||
set /P c=WARNING! Are you sure you want to continue, this will remove all package files, view files, sqlce database, etc... Press 'Y' to auto-remove all files/folders, 'N' to cancel or 'C' to prompt for each folder removal?
|
||||
if /I "%c%" EQU "C" goto :prompt
|
||||
if /I "%c%" EQU "Y" goto :auto
|
||||
if /I "%c%" EQU "N" goto :exit
|
||||
goto :choice
|
||||
|
||||
|
||||
:prompt
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Removing sqlce database
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Umbraco.sdf
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*
|
||||
|
||||
echo Removing log files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Logs\*.*
|
||||
|
||||
echo Removing xslt files
|
||||
del ..\src\Umbraco.Web.UI\Xslt\*.*
|
||||
|
||||
echo Removing user control files
|
||||
del ..\src\Umbraco.Web.UI\UserControls\*.*
|
||||
|
||||
echo Removing view files
|
||||
del ..\src\Umbraco.Web.UI\Views\*.*
|
||||
|
||||
echo Removing razor files
|
||||
del ..\src\Umbraco.Web.UI\MacroScripts\*.*
|
||||
|
||||
echo Removing media files
|
||||
del ..\src\Umbraco.Web.UI\Media\*.*
|
||||
|
||||
echo Removing script files
|
||||
del ..\src\Umbraco.Web.UI\Scripts\*.*
|
||||
|
||||
echo Removing css files
|
||||
del ..\src\Umbraco.Web.UI\Css\*.*
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:auto
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Removing sqlce database
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Umbraco.sdf
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*) DO DEL %%A
|
||||
|
||||
echo Removing log files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\Logs\*.*) DO DEL %%A
|
||||
|
||||
echo Removing xslt files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Xslt\*.*) DO DEL %%A
|
||||
|
||||
echo Removing user control files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\UserControls\*.*) DO DEL %%A
|
||||
|
||||
echo Removing view files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Views\*.*) DO DEL %%A
|
||||
|
||||
echo Removing razor files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\MacroScripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing media files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Media\*.*) DO DEL %%A
|
||||
|
||||
echo Removing script files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Scripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing css files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Css\*.*) DO DEL %%A
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:exit
|
||||
exit
|
||||
@@ -41,6 +41,17 @@ namespace Umbraco.Core
|
||||
return new DisposableTimer(callback);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
|
||||
@@ -68,6 +68,14 @@ namespace Umbraco.Core
|
||||
Directory.CreateDirectory(_tempFolder);
|
||||
}
|
||||
|
||||
//this is a check for legacy changes, before we didn't store the TypeResolutionKind in the file which was a mistake,
|
||||
//so we need to detect if the old file is there without this attribute, if it is then we delete it
|
||||
if (DetectLegacyPluginListFile())
|
||||
{
|
||||
var filePath = GetPluginListFilePath();
|
||||
File.Delete(filePath);
|
||||
}
|
||||
|
||||
if (detectCodeChanges)
|
||||
{
|
||||
//first check if the cached hash is 0, if it is then we ne
|
||||
@@ -120,6 +128,7 @@ namespace Umbraco.Core
|
||||
|
||||
#region Hash checking methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a bool if the assemblies in the /bin have changed since they were last hashed.
|
||||
/// </summary>
|
||||
@@ -228,9 +237,9 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal Attempt<IEnumerable<string>> TryGetCachedPluginsFromFile<T>()
|
||||
internal Attempt<IEnumerable<string>> TryGetCachedPluginsFromFile<T>(TypeResolutionKind resolutionType)
|
||||
{
|
||||
var filePath = Path.Combine(_tempFolder, "umbraco-plugins.list");
|
||||
var filePath = GetPluginListFilePath();
|
||||
if (!File.Exists(filePath))
|
||||
return Attempt<IEnumerable<string>>.False;
|
||||
|
||||
@@ -257,9 +266,12 @@ namespace Umbraco.Core
|
||||
var typeElement = xml.Root.Elements()
|
||||
.SingleOrDefault(x =>
|
||||
x.Name.LocalName == "baseType"
|
||||
&& ((string) x.Attribute("type")) == typeof (T).FullName);
|
||||
&& ((string) x.Attribute("type")) == typeof (T).FullName
|
||||
&& ((string) x.Attribute("resolutionType")) == resolutionType.ToString());
|
||||
|
||||
//return false but specify this exception type so we can detect it
|
||||
if (typeElement == null)
|
||||
return Attempt<IEnumerable<string>>.False;
|
||||
return new Attempt<IEnumerable<string>>(new CachedPluginNotFoundInFile());
|
||||
|
||||
//return success
|
||||
return new Attempt<IEnumerable<string>>(
|
||||
@@ -267,10 +279,52 @@ namespace Umbraco.Core
|
||||
typeElement.Elements("add")
|
||||
.Select(x => (string) x.Attribute("type")));
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
//if the file is corrupted, etc... return false
|
||||
return Attempt<IEnumerable<string>>.False;
|
||||
return new Attempt<IEnumerable<string>>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPluginListFilePath()
|
||||
{
|
||||
return Path.Combine(_tempFolder, "umbraco-plugins.list");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will return true if the plugin list file is a legacy one
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This method exists purely due to an error in 4.11. We were writing the plugin list file without the
|
||||
/// type resolution kind which will have caused some problems. Now we detect this legacy file and if it is detected
|
||||
/// we remove it so it can be recreated properly.
|
||||
/// </remarks>
|
||||
internal bool DetectLegacyPluginListFile()
|
||||
{
|
||||
var filePath = GetPluginListFilePath();
|
||||
if (!File.Exists(filePath))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var xml = XDocument.Load(filePath);
|
||||
if (xml.Root == null)
|
||||
return false;
|
||||
|
||||
var typeElement = xml.Root.Elements()
|
||||
.FirstOrDefault(x => x.Name.LocalName == "baseType");
|
||||
|
||||
if (typeElement == null)
|
||||
return false;
|
||||
|
||||
//now check if the typeElement is missing the resolutionType attribute
|
||||
return typeElement.Attributes().All(x => x.Name.LocalName != "resolutionType");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//if the file is corrupted, etc... return true so it is removed
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +333,8 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="typesFound"></param>
|
||||
/// <remarks>
|
||||
///<param name="resolutionType"> </param>
|
||||
///<remarks>
|
||||
/// THIS METHOD IS NOT THREAD SAFE
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
@@ -292,9 +347,9 @@ namespace Umbraco.Core
|
||||
/// </plugins>
|
||||
/// ]]>
|
||||
/// </example>
|
||||
internal void UpdateCachedPluginsFile<T>(IEnumerable<Type> typesFound)
|
||||
internal void UpdateCachedPluginsFile<T>(IEnumerable<Type> typesFound, TypeResolutionKind resolutionType)
|
||||
{
|
||||
var filePath = Path.Combine(_tempFolder, "umbraco-plugins.list");
|
||||
var filePath = GetPluginListFilePath();
|
||||
XDocument xml;
|
||||
try
|
||||
{
|
||||
@@ -316,11 +371,15 @@ namespace Umbraco.Core
|
||||
var typeElement = xml.Root.Elements()
|
||||
.SingleOrDefault(x =>
|
||||
x.Name.LocalName == "baseType"
|
||||
&& ((string)x.Attribute("type")) == typeof(T).FullName);
|
||||
&& ((string)x.Attribute("type")) == typeof(T).FullName
|
||||
&& ((string)x.Attribute("resolutionType")) == resolutionType.ToString());
|
||||
|
||||
if (typeElement == null)
|
||||
{
|
||||
//create the type element
|
||||
typeElement = new XElement("baseType", new XAttribute("type", typeof(T).FullName));
|
||||
typeElement = new XElement("baseType",
|
||||
new XAttribute("type", typeof(T).FullName),
|
||||
new XAttribute("resolutionType", resolutionType.ToString()));
|
||||
//then add it to the root
|
||||
xml.Root.Add(typeElement);
|
||||
}
|
||||
@@ -486,9 +545,11 @@ namespace Umbraco.Core
|
||||
{
|
||||
using (var readLock = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
var typesFound = new List<Type>();
|
||||
|
||||
using (DisposableTimer.TraceDuration<PluginManager>(
|
||||
String.Format("Starting resolution types of {0}", typeof(T).FullName),
|
||||
String.Format("Completed resolution of types of {0}", typeof(T).FullName)))
|
||||
() => String.Format("Starting resolution types of {0}", typeof(T).FullName),
|
||||
() => String.Format("Completed resolution of types of {0}, found {1}", typeof(T).FullName, typesFound.Count)))
|
||||
{
|
||||
//check if the TypeList already exists, if so return it, if not we'll create it
|
||||
var typeList = _types.SingleOrDefault(x => x.IsTypeList<T>(resolutionType));
|
||||
@@ -501,14 +562,26 @@ namespace Umbraco.Core
|
||||
typeList = new TypeList<T>(resolutionType);
|
||||
|
||||
//we first need to look into our cache file (this has nothing to do with the 'cacheResult' parameter which caches in memory).
|
||||
if (!HaveAssembliesChanged)
|
||||
//if assemblies have not changed and the cache file actually exists, then proceed to try to lookup by the cache file.
|
||||
if (!HaveAssembliesChanged && File.Exists(GetPluginListFilePath()))
|
||||
{
|
||||
var fileCacheResult = TryGetCachedPluginsFromFile<T>(resolutionType);
|
||||
|
||||
//here we need to identify if the CachedPluginNotFoundInFile was the exception, if it was then we need to re-scan
|
||||
//in some cases the plugin will not have been scanned for on application startup, but the assemblies haven't changed
|
||||
//so in this instance there will never be a result.
|
||||
if (fileCacheResult.Error != null && fileCacheResult.Error is CachedPluginNotFoundInFile)
|
||||
{
|
||||
//we don't have a cache for this so proceed to look them up by scanning
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, resolutionType, finder);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileCacheResult = TryGetCachedPluginsFromFile<T>();
|
||||
if (fileCacheResult.Success)
|
||||
{
|
||||
var successfullyLoadedFromCache = true;
|
||||
//we have a previous cache for this so we don't need to scan we just load what has been found in the file
|
||||
foreach(var t in fileCacheResult.Result)
|
||||
foreach (var t in fileCacheResult.Result)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -522,14 +595,14 @@ namespace Umbraco.Core
|
||||
//if there are any exceptions loading types, we have to exist, this should never happen so
|
||||
//we will need to revert to scanning for types.
|
||||
successfullyLoadedFromCache = false;
|
||||
LogHelper.Error<PluginManager>("Could not load a cached plugin type: " + t + " now reverting to re-scanning assemblies for the base type: " + typeof (T).FullName, ex);
|
||||
LogHelper.Error<PluginManager>("Could not load a cached plugin type: " + t + " now reverting to re-scanning assemblies for the base type: " + typeof(T).FullName, ex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!successfullyLoadedFromCache )
|
||||
if (!successfullyLoadedFromCache)
|
||||
{
|
||||
//we need to manually load by scanning if loading from the file was not successful.
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, finder);
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, resolutionType, finder);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -537,10 +610,11 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//we don't have a cache for this so proceed to look them up by scanning
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, finder);
|
||||
LoadViaScanningAndUpdateCacheFile<T>(typeList, resolutionType, finder);
|
||||
}
|
||||
|
||||
//only add the cache if we are to cache the results
|
||||
@@ -550,8 +624,10 @@ namespace Umbraco.Core
|
||||
_types.Add(typeList);
|
||||
}
|
||||
}
|
||||
return typeList.GetTypes();
|
||||
typesFound = typeList.GetTypes().ToList();
|
||||
}
|
||||
|
||||
return typesFound;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,18 +636,19 @@ namespace Umbraco.Core
|
||||
/// Once the results are loaded, we update the cached type xml file
|
||||
/// </summary>
|
||||
/// <param name="typeList"></param>
|
||||
/// <param name="resolutionKind"> </param>
|
||||
/// <param name="finder"></param>
|
||||
/// <remarks>
|
||||
/// THIS METHODS IS NOT THREAD SAFE
|
||||
/// </remarks>
|
||||
private void LoadViaScanningAndUpdateCacheFile<T>(TypeList typeList, Func<IEnumerable<Type>> finder)
|
||||
private void LoadViaScanningAndUpdateCacheFile<T>(TypeList typeList, TypeResolutionKind resolutionKind, Func<IEnumerable<Type>> finder)
|
||||
{
|
||||
//we don't have a cache for this so proceed to look them up by scanning
|
||||
foreach (var t in finder())
|
||||
{
|
||||
typeList.AddType(t);
|
||||
}
|
||||
UpdateCachedPluginsFile<T>(typeList.GetTypes());
|
||||
UpdateCachedPluginsFile<T>(typeList.GetTypes(), resolutionKind);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -683,6 +760,16 @@ namespace Umbraco.Core
|
||||
return _types;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class is used simply to determine that a plugin was not found in the cache plugin list with the specified
|
||||
/// TypeResolutionKind.
|
||||
/// </summary>
|
||||
internal class CachedPluginNotFoundInFile : Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Web.Compilation;
|
||||
using NUnit.Framework;
|
||||
using SqlCE4Umbraco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using umbraco;
|
||||
@@ -148,6 +149,34 @@ namespace Umbraco.Tests
|
||||
// Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds);
|
||||
//}
|
||||
|
||||
[Test]
|
||||
public void Detect_Legacy_Plugin_File_List()
|
||||
{
|
||||
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
|
||||
var manager = new PluginManager(false);
|
||||
var filePath = Path.Combine(tempFolder, "umbraco-plugins.list");
|
||||
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<plugins>
|
||||
<baseType type=""umbraco.interfaces.ICacheRefresher"">
|
||||
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
|
||||
</baseType>
|
||||
</plugins>");
|
||||
|
||||
Assert.IsTrue(manager.DetectLegacyPluginListFile());
|
||||
|
||||
File.Delete(filePath);
|
||||
|
||||
//now create a valid one
|
||||
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<plugins>
|
||||
<baseType type=""umbraco.interfaces.ICacheRefresher"" resolutionType=""FindAllTypes"">
|
||||
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
|
||||
</baseType>
|
||||
</plugins>");
|
||||
|
||||
Assert.IsFalse(manager.DetectLegacyPluginListFile());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Create_Cached_Plugin_File()
|
||||
{
|
||||
@@ -155,10 +184,15 @@ namespace Umbraco.Tests
|
||||
|
||||
var manager = new PluginManager(false);
|
||||
//yes this is silly, none of these types inherit from string, but this is just to test the xml file format
|
||||
manager.UpdateCachedPluginsFile<string>(types);
|
||||
manager.UpdateCachedPluginsFile<string>(types, PluginManager.TypeResolutionKind.FindAllTypes);
|
||||
|
||||
var plugins = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAllTypes);
|
||||
var diffType = manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAttributedTypes);
|
||||
|
||||
var plugins = manager.TryGetCachedPluginsFromFile<string>();
|
||||
Assert.IsTrue(plugins.Success);
|
||||
//this will be false since there is no cache of that type resolution kind
|
||||
Assert.IsFalse(diffType.Success);
|
||||
|
||||
Assert.AreEqual(3, plugins.Result.Count());
|
||||
var shouldContain = types.Select(x => x.AssemblyQualifiedName);
|
||||
//ensure they are all found
|
||||
@@ -206,11 +240,11 @@ namespace Umbraco.Tests
|
||||
var hash3 = PluginManager.GetAssembliesHash(list3);
|
||||
|
||||
//Assert
|
||||
|
||||
//both should be the same since we only create the hash based on the unique folder of the list passed in, yet
|
||||
//all files will exist in those folders still
|
||||
Assert.AreEqual(hash1, hash2);
|
||||
Assert.AreNotEqual(hash1, hash2);
|
||||
Assert.AreNotEqual(hash1, hash3);
|
||||
Assert.AreNotEqual(hash2, hash3);
|
||||
|
||||
Assert.AreEqual(hash1, PluginManager.GetAssembliesHash(list1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -13,7 +13,8 @@ using ICSharpCode.SharpZipLib;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
|
||||
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using umbraco.cms.businesslogic.propertytype;
|
||||
using umbraco.BusinessLogic;
|
||||
@@ -153,6 +154,10 @@ namespace umbraco.cms.businesslogic.packager
|
||||
/// <param name="InputFile">Filename of the umbracopackage</param>
|
||||
/// <returns></returns>
|
||||
public string Import(string InputFile)
|
||||
{
|
||||
using (DisposableTimer.DebugDuration<Installer>(
|
||||
() => "Importing package file " + InputFile,
|
||||
() => "Package file " + InputFile + "imported"))
|
||||
{
|
||||
string tempDir = "";
|
||||
if (File.Exists(IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile)))
|
||||
@@ -178,6 +183,7 @@ namespace umbraco.cms.businesslogic.packager
|
||||
throw new Exception("Error - file not found. Could find file named '" + IOHelper.MapPath(SystemDirectories.Data + Path.DirectorySeparatorChar + InputFile) + "'");
|
||||
return tempDir;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int CreateManifest(string tempDir, string guid, string repoGuid) {
|
||||
@@ -220,8 +226,12 @@ namespace umbraco.cms.businesslogic.packager
|
||||
return insPack.Data.Id;
|
||||
}
|
||||
|
||||
public void InstallFiles(int packageId, string tempDir) {
|
||||
|
||||
public void InstallFiles(int packageId, string tempDir)
|
||||
{
|
||||
using (DisposableTimer.DebugDuration<Installer>(
|
||||
() => "Installing package files for package id " + packageId + " into temp folder " + tempDir,
|
||||
() => "Package file installation complete for package id " + packageId))
|
||||
{
|
||||
//retrieve the manifest to continue installation
|
||||
packager.InstalledPackage insPack = packager.InstalledPackage.GetById(packageId);
|
||||
|
||||
@@ -229,9 +239,11 @@ namespace umbraco.cms.businesslogic.packager
|
||||
//string virtualBasePath = System.Web.HttpContext.Current.Request.ApplicationPath;
|
||||
string basePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
|
||||
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//file")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//file"))
|
||||
{
|
||||
//we enclose the whole file-moving to ensure that the entire installer doesn't crash
|
||||
try {
|
||||
try
|
||||
{
|
||||
String destPath = getFileName(basePath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")));
|
||||
String sourceFile = getFileName(tempDir, xmlHelper.GetNodeValue(n.SelectSingleNode("guid")));
|
||||
String destFile = getFileName(destPath, xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
|
||||
@@ -248,38 +260,49 @@ namespace umbraco.cms.businesslogic.packager
|
||||
|
||||
//PPH log file install
|
||||
insPack.Data.Files.Add(xmlHelper.GetNodeValue(n.SelectSingleNode("orgPath")) + "/" + xmlHelper.GetNodeValue(n.SelectSingleNode("orgName")));
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Add(LogTypes.Error, -1, "Package install error: " + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
insPack.Save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void InstallBusinessLogic(int packageId, string tempDir) {
|
||||
|
||||
using (DisposableTimer.DebugDuration<Installer>(
|
||||
() => "Installing business logic for package id " + packageId + " into temp folder " + tempDir,
|
||||
() => "Package business logic installation complete for package id " + packageId))
|
||||
{
|
||||
//retrieve the manifest to continue installation
|
||||
packager.InstalledPackage insPack = packager.InstalledPackage.GetById(packageId);
|
||||
bool saveNeeded = false;
|
||||
|
||||
//Install DataTypes
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//DataType")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//DataType"))
|
||||
{
|
||||
cms.businesslogic.datatype.DataTypeDefinition newDtd = cms.businesslogic.datatype.DataTypeDefinition.Import(n);
|
||||
|
||||
if (newDtd != null) {
|
||||
if (newDtd != null)
|
||||
{
|
||||
insPack.Data.DataTypes.Add(newDtd.Id.ToString());
|
||||
saveNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (saveNeeded) {insPack.Save(); saveNeeded = false;}
|
||||
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
|
||||
|
||||
//Install languages
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//Language")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//Language"))
|
||||
{
|
||||
language.Language newLang = language.Language.Import(n);
|
||||
|
||||
if (newLang != null) {
|
||||
if (newLang != null)
|
||||
{
|
||||
insPack.Data.Languages.Add(newLang.id.ToString());
|
||||
saveNeeded = true;
|
||||
}
|
||||
@@ -288,10 +311,12 @@ namespace umbraco.cms.businesslogic.packager
|
||||
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
|
||||
|
||||
//Install dictionary items
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("./DictionaryItems/DictionaryItem")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("./DictionaryItems/DictionaryItem"))
|
||||
{
|
||||
Dictionary.DictionaryItem newDi = Dictionary.DictionaryItem.Import(n);
|
||||
|
||||
if (newDi != null) {
|
||||
if (newDi != null)
|
||||
{
|
||||
insPack.Data.DictionaryItems.Add(newDi.id.ToString());
|
||||
saveNeeded = true;
|
||||
}
|
||||
@@ -300,10 +325,12 @@ namespace umbraco.cms.businesslogic.packager
|
||||
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
|
||||
|
||||
// Install macros
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//macro")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("//macro"))
|
||||
{
|
||||
cms.businesslogic.macro.Macro m = cms.businesslogic.macro.Macro.Import(n);
|
||||
|
||||
if (m != null) {
|
||||
if (m != null)
|
||||
{
|
||||
insPack.Data.Macros.Add(m.Id.ToString());
|
||||
saveNeeded = true;
|
||||
}
|
||||
@@ -313,15 +340,18 @@ namespace umbraco.cms.businesslogic.packager
|
||||
|
||||
// Get current user, with a fallback
|
||||
User u = new User(0);
|
||||
if (!string.IsNullOrEmpty(BasePages.UmbracoEnsuredPage.umbracoUserContextID)) {
|
||||
if (BasePages.UmbracoEnsuredPage.ValidateUserContextID(BasePages.UmbracoEnsuredPage.umbracoUserContextID)) {
|
||||
if (!string.IsNullOrEmpty(BasePages.UmbracoEnsuredPage.umbracoUserContextID))
|
||||
{
|
||||
if (BasePages.UmbracoEnsuredPage.ValidateUserContextID(BasePages.UmbracoEnsuredPage.umbracoUserContextID))
|
||||
{
|
||||
u = User.GetCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add Templates
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template"))
|
||||
{
|
||||
var t = Template.Import(n, u);
|
||||
|
||||
insPack.Data.Templates.Add(t.Id.ToString());
|
||||
@@ -336,12 +366,15 @@ namespace umbraco.cms.businesslogic.packager
|
||||
// in the database, but this is also duplicating the saving of the design content since the above Template.Import
|
||||
// already does this. I've left this for now because I'm not sure the reprocussions of removing it but seems there
|
||||
// is a lot of excess database calls happening here.
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Templates/Template"))
|
||||
{
|
||||
string master = xmlHelper.GetNodeValue(n.SelectSingleNode("Master"));
|
||||
template.Template t = template.Template.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Alias")));
|
||||
if (master.Trim() != "") {
|
||||
if (master.Trim() != "")
|
||||
{
|
||||
template.Template masterTemplate = template.Template.GetByAlias(master);
|
||||
if (masterTemplate != null) {
|
||||
if (masterTemplate != null)
|
||||
{
|
||||
t.MasterTemplate = template.Template.GetByAlias(master).Id;
|
||||
//SD: This appears to always just save an empty template because the design isn't set yet
|
||||
// this fixes an issue now that we have MVC because if there is an empty template and MVC is
|
||||
@@ -355,14 +388,16 @@ namespace umbraco.cms.businesslogic.packager
|
||||
}
|
||||
}
|
||||
// Master templates can only be generated when their master is known
|
||||
if (UmbracoSettings.UseAspNetMasterPages) {
|
||||
if (UmbracoSettings.UseAspNetMasterPages)
|
||||
{
|
||||
t.ImportDesign(xmlHelper.GetNodeValue(n.SelectSingleNode("Design")));
|
||||
t.SaveMasterPageFile(t.Design);
|
||||
}
|
||||
}
|
||||
|
||||
// Add documenttypes
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType"))
|
||||
{
|
||||
ImportDocumentType(n, u, false);
|
||||
saveNeeded = true;
|
||||
}
|
||||
@@ -371,13 +406,16 @@ namespace umbraco.cms.businesslogic.packager
|
||||
|
||||
|
||||
// Add documenttype structure
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("DocumentTypes/DocumentType"))
|
||||
{
|
||||
DocumentType dt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(n.SelectSingleNode("Info/Alias")));
|
||||
if (dt != null) {
|
||||
if (dt != null)
|
||||
{
|
||||
ArrayList allowed = new ArrayList();
|
||||
foreach (XmlNode structure in n.SelectNodes("Structure/DocumentType")) {
|
||||
foreach (XmlNode structure in n.SelectNodes("Structure/DocumentType"))
|
||||
{
|
||||
DocumentType dtt = DocumentType.GetByAlias(xmlHelper.GetNodeValue(structure));
|
||||
if(dtt != null)
|
||||
if (dtt != null)
|
||||
allowed.Add(dtt.Id);
|
||||
}
|
||||
|
||||
@@ -395,7 +433,8 @@ namespace umbraco.cms.businesslogic.packager
|
||||
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
|
||||
|
||||
// Stylesheets
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Stylesheets/Stylesheet")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Stylesheets/Stylesheet"))
|
||||
{
|
||||
StyleSheet s = StyleSheet.Import(n, u);
|
||||
|
||||
insPack.Data.Stylesheets.Add(s.Id.ToString());
|
||||
@@ -405,22 +444,29 @@ namespace umbraco.cms.businesslogic.packager
|
||||
if (saveNeeded) { insPack.Save(); saveNeeded = false; }
|
||||
|
||||
// Documents
|
||||
foreach (XmlElement n in _packageConfig.DocumentElement.SelectNodes("Documents/DocumentSet [@importMode = 'root']/*")) {
|
||||
foreach (XmlElement n in _packageConfig.DocumentElement.SelectNodes("Documents/DocumentSet [@importMode = 'root']/*"))
|
||||
{
|
||||
insPack.Data.ContentNodeId = cms.businesslogic.web.Document.Import(-1, u, n).ToString();
|
||||
}
|
||||
|
||||
//Package Actions
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action")) {
|
||||
foreach (XmlNode n in _packageConfig.DocumentElement.SelectNodes("Actions/Action"))
|
||||
{
|
||||
|
||||
if (n.Attributes["undo"] == null || n.Attributes["undo"].Value == "true") {
|
||||
if (n.Attributes["undo"] == null || n.Attributes["undo"].Value == "true")
|
||||
{
|
||||
insPack.Data.Actions += n.OuterXml;
|
||||
Log.Add(LogTypes.Debug, -1, HttpUtility.HtmlEncode(n.OuterXml));
|
||||
}
|
||||
|
||||
if (n.Attributes["runat"] != null && n.Attributes["runat"].Value == "install") {
|
||||
try {
|
||||
if (n.Attributes["runat"] != null && n.Attributes["runat"].Value == "install")
|
||||
{
|
||||
try
|
||||
{
|
||||
packager.PackageAction.RunPackageAction(insPack.Data.Name, n.Attributes["alias"].Value, n);
|
||||
} catch {
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -433,6 +479,7 @@ namespace umbraco.cms.businesslogic.packager
|
||||
|
||||
insPack.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void InstallCleanUp(int packageId, string tempDir) {
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{2849E9D4
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\Build.bat = ..\build\Build.bat
|
||||
..\build\Build.proj = ..\build\Build.proj
|
||||
..\build\RevertToCleanInstall.bat = ..\build\RevertToCleanInstall.bat
|
||||
umbraco.presentation.targets = umbraco.presentation.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
||||
Reference in New Issue
Block a user