Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6795afd5c2 | |||
| 9411a22a0d | |||
| 461ce64feb | |||
| 53c251feb5 | |||
| c5a55b17e6 | |||
| fd577afe2c | |||
| f46ef0b006 | |||
| 04f64cd804 | |||
| dc937ec942 | |||
| cefd9e7323 | |||
| 315690e758 | |||
| fb8c519f71 | |||
| 80f172e3fb | |||
| 5eced19816 | |||
| 5df4d3509d | |||
| 4bd263e7bc | |||
| b094bfad29 | |||
| e333f6c628 | |||
| 916bc6badb | |||
| 76ee23b933 | |||
| 2a0cc71d06 | |||
| a2e6da2491 | |||
| ba7d8b0955 | |||
| 7288bcf679 | |||
| ca57b9c5e6 | |||
| 62ce7f6132 | |||
| b1f2c5d93a | |||
| 1ec07aa205 | |||
| 13055ad1f2 | |||
| d5447106a6 | |||
| c5d874464a | |||
| 1cc3b39601 | |||
| c5f4793d11 | |||
| 4175c0530f | |||
| cf97926f26 | |||
| 4b08c3a5c3 | |||
| fbda4fc8d1 | |||
| 312b994537 | |||
| dd1bfe9cbf | |||
| de17b69564 | |||
| 7f44f4a030 | |||
| 422219ab21 | |||
| 9986a3c2c2 | |||
| ce81416368 | |||
| 04e04ae47a | |||
| 0f6e7d26c9 | |||
| 51ceba6fea | |||
| 5dde2efe0d | |||
| fe2b86b681 | |||
| 368fec4ac1 | |||
| 9016147118 | |||
| bee75803f7 | |||
| 7b3f7f4ad4 | |||
| f6c25f29c0 | |||
| 6de3b920eb | |||
| 606abd8ac7 | |||
| 65db5396cf | |||
| 32d5a0a57c | |||
| be1172d604 | |||
| 7cf8cd3518 | |||
| 4cab1c89b4 | |||
| 88fd5a9623 |
@@ -40,6 +40,7 @@ function Get-UmbracoBuildEnv
|
||||
&$nuget install 7-Zip.CommandLine -OutputDirectory $path -Verbosity quiet
|
||||
$dir = ls "$path\7-Zip.CommandLine.*" | sort -property Name -descending | select -first 1
|
||||
$file = ls -path "$dir" -name 7za.exe -recurse
|
||||
$file = ls -path "$dir" -name 7za.exe -recurse | select -first 1 #A select is because there is tools\7za.exe & tools\x64\7za.exe
|
||||
mv "$dir\$file" $sevenZip
|
||||
Remove-Directory $dir
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.7.2")]
|
||||
[assembly: AssemblyInformationalVersion("7.7.2")]
|
||||
[assembly: AssemblyFileVersion("7.7.3")]
|
||||
[assembly: AssemblyInformationalVersion("7.7.3")]
|
||||
@@ -538,24 +538,41 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
internal static bool ContentCacheXmlStoredInCodeGen
|
||||
{
|
||||
get { return ContentCacheXmlStorageLocation == ContentXmlStorage.AspNetTemp; }
|
||||
get { return LocalTempStorageLocation == LocalTempStorage.AspNetTemp; }
|
||||
}
|
||||
|
||||
internal static ContentXmlStorage ContentCacheXmlStorageLocation
|
||||
|
||||
/// <summary>
|
||||
/// This is the location type to store temporary files such as cache files or other localized files for a given machine
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently used for the xml cache file and the plugin cache files
|
||||
/// </remarks>
|
||||
internal static LocalTempStorage LocalTempStorageLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
{
|
||||
//there's a bunch of backwards compat config checks here....
|
||||
|
||||
//This is the current one
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoLocalTempStorage"))
|
||||
{
|
||||
return Enum<LocalTempStorage>.Parse(ConfigurationManager.AppSettings["umbracoLocalTempStorage"]);
|
||||
}
|
||||
|
||||
//This one is old
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLStorage"))
|
||||
{
|
||||
return Enum<ContentXmlStorage>.Parse(ConfigurationManager.AppSettings["umbracoContentXMLStorage"]);
|
||||
}
|
||||
return Enum<LocalTempStorage>.Parse(ConfigurationManager.AppSettings["umbracoContentXMLStorage"]);
|
||||
}
|
||||
|
||||
//This one is older
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLUseLocalTemp"))
|
||||
{
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoContentXMLUseLocalTemp"])
|
||||
? ContentXmlStorage.AspNetTemp
|
||||
: ContentXmlStorage.Default;
|
||||
? LocalTempStorage.AspNetTemp
|
||||
: LocalTempStorage.Default;
|
||||
}
|
||||
return ContentXmlStorage.Default;
|
||||
return LocalTempStorage.Default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
internal enum ContentXmlStorage
|
||||
internal enum LocalTempStorage
|
||||
{
|
||||
Default,
|
||||
AspNetTemp,
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.7.2");
|
||||
private static readonly Version Version = new Version("7.7.3");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -73,19 +73,19 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (GlobalSettings.ContentCacheXmlStorageLocation)
|
||||
switch (GlobalSettings.LocalTempStorageLocation)
|
||||
{
|
||||
case ContentXmlStorage.AspNetTemp:
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco.config");
|
||||
case ContentXmlStorage.EnvironmentTemp:
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1();
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoXml",
|
||||
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData",
|
||||
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path
|
||||
appDomainHash);
|
||||
return Path.Combine(cachePath, "umbraco.config");
|
||||
case ContentXmlStorage.Default:
|
||||
case LocalTempStorage.Default:
|
||||
return IOHelper.ReturnPath("umbracoContentXML", "~/App_Data/umbraco.config");
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class UserGroup : Entity, IUserGroup, IReadOnlyUserGroup
|
||||
public class UserGroup : Entity, IUserGroup, IReadOnlyUserGroup
|
||||
{
|
||||
private int? _startContentId;
|
||||
private int? _startMediaId;
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Compilation;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -15,6 +16,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using umbraco.interfaces;
|
||||
using Umbraco.Core.Configuration;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -39,7 +41,8 @@ namespace Umbraco.Core
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly ProfilingLogger _logger;
|
||||
private readonly string _tempFolder;
|
||||
private readonly Lazy<string> _pluginListFilePath = new Lazy<string>(GetPluginListFilePath);
|
||||
private readonly Lazy<string> _pluginHashFilePath = new Lazy<string>(GetPluginHashFilePath);
|
||||
|
||||
private readonly object _typesLock = new object();
|
||||
private readonly Dictionary<TypeListKey, TypeList> _types = new Dictionary<TypeListKey, TypeList>();
|
||||
@@ -65,14 +68,7 @@ namespace Umbraco.Core
|
||||
_serviceProvider = serviceProvider;
|
||||
_runtimeCache = runtimeCache;
|
||||
_logger = logger;
|
||||
|
||||
// the temp folder where the cache file lives
|
||||
_tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
|
||||
if (Directory.Exists(_tempFolder) == false)
|
||||
Directory.CreateDirectory(_tempFolder);
|
||||
|
||||
var pluginListFile = GetPluginListFilePath();
|
||||
|
||||
|
||||
if (detectChanges)
|
||||
{
|
||||
//first check if the cached hash is string.Empty, if it is then we need
|
||||
@@ -84,7 +80,8 @@ namespace Umbraco.Core
|
||||
// if the hash has changed, clear out the persisted list no matter what, this will force
|
||||
// rescanning of all plugin types including lazy ones.
|
||||
// http://issues.umbraco.org/issue/U4-4789
|
||||
File.Delete(pluginListFile);
|
||||
if(File.Exists(_pluginListFilePath.Value))
|
||||
File.Delete(_pluginListFilePath.Value);
|
||||
|
||||
WriteCachePluginsHash();
|
||||
}
|
||||
@@ -94,7 +91,8 @@ namespace Umbraco.Core
|
||||
// if the hash has changed, clear out the persisted list no matter what, this will force
|
||||
// rescanning of all plugin types including lazy ones.
|
||||
// http://issues.umbraco.org/issue/U4-4789
|
||||
File.Delete(pluginListFile);
|
||||
if (File.Exists(_pluginListFilePath.Value))
|
||||
File.Delete(_pluginListFilePath.Value);
|
||||
|
||||
// always set to true if we're not detecting (generally only for testing)
|
||||
RequiresRescanning = true;
|
||||
@@ -187,11 +185,10 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (_cachedAssembliesHash != null)
|
||||
return _cachedAssembliesHash;
|
||||
|
||||
if (File.Exists(_pluginHashFilePath.Value) == false) return string.Empty;
|
||||
|
||||
var filePath = GetPluginHashFilePath();
|
||||
if (File.Exists(filePath) == false) return string.Empty;
|
||||
|
||||
var hash = File.ReadAllText(filePath, Encoding.UTF8);
|
||||
var hash = File.ReadAllText(_pluginHashFilePath.Value, Encoding.UTF8);
|
||||
|
||||
_cachedAssembliesHash = hash;
|
||||
return _cachedAssembliesHash;
|
||||
@@ -229,9 +226,8 @@ namespace Umbraco.Core
|
||||
/// Writes the assembly hash file.
|
||||
/// </summary>
|
||||
private void WriteCachePluginsHash()
|
||||
{
|
||||
var filePath = GetPluginHashFilePath();
|
||||
File.WriteAllText(filePath, CurrentAssembliesHash.ToString(), Encoding.UTF8);
|
||||
{
|
||||
File.WriteAllText(_pluginHashFilePath.Value, CurrentAssembliesHash, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -274,7 +270,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
return generator.GenerateHash();
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,7 +310,7 @@ namespace Umbraco.Core
|
||||
uniqInfos.Add(fileOrFolder.FullName);
|
||||
generator.AddFileSystemItem(fileOrFolder);
|
||||
}
|
||||
return generator.GenerateHash();
|
||||
return generator.GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,12 +343,11 @@ namespace Umbraco.Core
|
||||
{
|
||||
return ReadCache();
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filePath = GetPluginListFilePath();
|
||||
File.Delete(filePath);
|
||||
File.Delete(_pluginListFilePath.Value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -366,12 +361,11 @@ namespace Umbraco.Core
|
||||
internal Dictionary<Tuple<string, string>, IEnumerable<string>> ReadCache()
|
||||
{
|
||||
var cache = new Dictionary<Tuple<string, string>, IEnumerable<string>>();
|
||||
|
||||
var filePath = GetPluginListFilePath();
|
||||
if (File.Exists(filePath) == false)
|
||||
|
||||
if (File.Exists(_pluginListFilePath.Value) == false)
|
||||
return cache;
|
||||
|
||||
using (var stream = GetFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, ListFileOpenReadTimeout))
|
||||
using (var stream = GetFileStream(_pluginListFilePath.Value, FileMode.Open, FileAccess.Read, FileShare.Read, ListFileOpenReadTimeout))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
while (true)
|
||||
@@ -414,38 +408,86 @@ namespace Umbraco.Core
|
||||
/// <remarks>Generally only used for resetting cache, for example during the install process.</remarks>
|
||||
public void ClearPluginCache()
|
||||
{
|
||||
var path = GetPluginListFilePath();
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
|
||||
path = GetPluginHashFilePath();
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
if (File.Exists(_pluginListFilePath.Value))
|
||||
File.Delete(_pluginListFilePath.Value);
|
||||
|
||||
if (File.Exists(_pluginHashFilePath.Value))
|
||||
File.Delete(_pluginHashFilePath.Value);
|
||||
|
||||
_runtimeCache.ClearCacheItem(CacheKey);
|
||||
}
|
||||
|
||||
private string GetPluginListFilePath()
|
||||
private static string GetPluginListFilePath()
|
||||
{
|
||||
var filename = "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".list";
|
||||
return Path.Combine(_tempFolder, filename);
|
||||
string pluginListFilePath;
|
||||
switch (GlobalSettings.LocalTempStorageLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
pluginListFilePath = Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco-plugins.list");
|
||||
break;
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1();
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData",
|
||||
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path
|
||||
appDomainHash);
|
||||
pluginListFilePath = Path.Combine(cachePath, "umbraco-plugins.list");
|
||||
break;
|
||||
case LocalTempStorage.Default:
|
||||
default:
|
||||
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
|
||||
pluginListFilePath = Path.Combine(tempFolder, "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".list");
|
||||
break;
|
||||
}
|
||||
|
||||
//ensure the folder exists
|
||||
var folder = Path.GetDirectoryName(pluginListFilePath);
|
||||
if (folder == null)
|
||||
throw new InvalidOperationException("The folder could not be determined for the file " + pluginListFilePath);
|
||||
if (Directory.Exists(folder) == false)
|
||||
Directory.CreateDirectory(folder);
|
||||
|
||||
return pluginListFilePath;
|
||||
}
|
||||
|
||||
private string GetPluginHashFilePath()
|
||||
private static string GetPluginHashFilePath()
|
||||
{
|
||||
var filename = "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".hash";
|
||||
return Path.Combine(_tempFolder, filename);
|
||||
string pluginHashFilePath;
|
||||
switch (GlobalSettings.LocalTempStorageLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
pluginHashFilePath = Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco-plugins.hash");
|
||||
break;
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1();
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData",
|
||||
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path
|
||||
appDomainHash);
|
||||
pluginHashFilePath = Path.Combine(cachePath, "umbraco-plugins.hash");
|
||||
break;
|
||||
case LocalTempStorage.Default:
|
||||
default:
|
||||
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
|
||||
pluginHashFilePath = Path.Combine(tempFolder, "umbraco-plugins." + NetworkHelper.FileSafeMachineName + ".hash");
|
||||
break;
|
||||
}
|
||||
|
||||
//ensure the folder exists
|
||||
var folder = Path.GetDirectoryName(pluginHashFilePath);
|
||||
if (folder == null)
|
||||
throw new InvalidOperationException("The folder could not be determined for the file " + pluginHashFilePath);
|
||||
if (Directory.Exists(folder) == false)
|
||||
Directory.CreateDirectory(folder);
|
||||
|
||||
return pluginHashFilePath;
|
||||
}
|
||||
|
||||
internal void WriteCache()
|
||||
{
|
||||
// be absolutely sure
|
||||
if (Directory.Exists(_tempFolder) == false)
|
||||
Directory.CreateDirectory(_tempFolder);
|
||||
|
||||
var filePath = GetPluginListFilePath();
|
||||
|
||||
using (var stream = GetFileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, ListFileOpenWriteTimeout))
|
||||
using (var stream = GetFileStream(_pluginListFilePath.Value, FileMode.Create, FileAccess.Write, FileShare.None, ListFileOpenWriteTimeout))
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
foreach (var typeList in _types.Values)
|
||||
@@ -461,8 +503,7 @@ namespace Umbraco.Core
|
||||
|
||||
internal void UpdateCache()
|
||||
{
|
||||
// note
|
||||
// at the moment we write the cache to disk every time we update it. ideally we defer the writing
|
||||
// TODO: at the moment we write the cache to disk every time we update it. ideally we defer the writing
|
||||
// since all the updates are going to happen in a row when Umbraco starts. that being said, the
|
||||
// file is small enough, so it is not a priority.
|
||||
WriteCache();
|
||||
@@ -475,13 +516,13 @@ namespace Umbraco.Core
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
return new FileStream(path, fileMode, fileAccess, fileShare);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (--attempts == 0)
|
||||
throw;
|
||||
throw;
|
||||
|
||||
LogHelper.Debug<PluginManager>(string.Format("Attempted to get filestream for file {0} failed, {1} attempts left, pausing for {2} milliseconds", path, attempts, pauseMilliseconds));
|
||||
Thread.Sleep(pauseMilliseconds);
|
||||
@@ -691,7 +732,7 @@ namespace Umbraco.Core
|
||||
// else proceed,
|
||||
typeList = new TypeList(baseType, attributeType);
|
||||
|
||||
var scan = RequiresRescanning || File.Exists(GetPluginListFilePath()) == false;
|
||||
var scan = RequiresRescanning || File.Exists(_pluginListFilePath.Value) == false;
|
||||
|
||||
if (scan)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using umbraco.interfaces;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Sync
|
||||
@@ -39,6 +40,7 @@ namespace Umbraco.Core.Sync
|
||||
private bool _syncing;
|
||||
private bool _released;
|
||||
private readonly ProfilingLogger _profilingLogger;
|
||||
private readonly Lazy<string> _distCacheFilePath = new Lazy<string>(GetDistCacheFilePath);
|
||||
|
||||
protected DatabaseServerMessengerOptions Options { get; private set; }
|
||||
protected ApplicationContext ApplicationContext { get { return _appContext; } }
|
||||
@@ -460,10 +462,9 @@ namespace Umbraco.Core.Sync
|
||||
/// </remarks>
|
||||
private void ReadLastSynced()
|
||||
{
|
||||
var path = SyncFilePath;
|
||||
if (File.Exists(path) == false) return;
|
||||
if (File.Exists(_distCacheFilePath.Value) == false) return;
|
||||
|
||||
var content = File.ReadAllText(path);
|
||||
var content = File.ReadAllText(_distCacheFilePath.Value);
|
||||
int last;
|
||||
if (int.TryParse(content, out last))
|
||||
_lastId = last;
|
||||
@@ -478,7 +479,7 @@ namespace Umbraco.Core.Sync
|
||||
/// </remarks>
|
||||
private void SaveLastSynced(int id)
|
||||
{
|
||||
File.WriteAllText(SyncFilePath, id.ToString(CultureInfo.InvariantCulture));
|
||||
File.WriteAllText(_distCacheFilePath.Value, id.ToString(CultureInfo.InvariantCulture));
|
||||
_lastId = id;
|
||||
}
|
||||
|
||||
@@ -498,20 +499,40 @@ namespace Umbraco.Core.Sync
|
||||
+ "/D" + AppDomain.CurrentDomain.Id // eg 22
|
||||
+ "] " + Guid.NewGuid().ToString("N").ToUpper(); // make it truly unique
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sync file path for the local server.
|
||||
/// </summary>
|
||||
/// <returns>The sync file path for the local server.</returns>
|
||||
private static string SyncFilePath
|
||||
private static string GetDistCacheFilePath()
|
||||
{
|
||||
get
|
||||
{
|
||||
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/DistCache/" + NetworkHelper.FileSafeMachineName);
|
||||
if (Directory.Exists(tempFolder) == false)
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
var fileName = HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt";
|
||||
|
||||
return Path.Combine(tempFolder, HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt");
|
||||
string distCacheFilePath;
|
||||
switch (GlobalSettings.LocalTempStorageLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
distCacheFilePath = Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData", fileName);
|
||||
break;
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.ToSHA1();
|
||||
var cachePath = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData",
|
||||
//include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path
|
||||
appDomainHash);
|
||||
distCacheFilePath = Path.Combine(cachePath, fileName);
|
||||
break;
|
||||
case LocalTempStorage.Default:
|
||||
default:
|
||||
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/DistCache");
|
||||
distCacheFilePath = Path.Combine(tempFolder, fileName);
|
||||
break;
|
||||
}
|
||||
|
||||
//ensure the folder exists
|
||||
var folder = Path.GetDirectoryName(distCacheFilePath);
|
||||
if (folder == null)
|
||||
throw new InvalidOperationException("The folder could not be determined for the file " + distCacheFilePath);
|
||||
if (Directory.Exists(folder) == false)
|
||||
Directory.CreateDirectory(folder);
|
||||
|
||||
return distCacheFilePath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
<Compile Include="Configuration\BaseRest\ExtensionElement.cs" />
|
||||
<Compile Include="Configuration\BaseRest\ExtensionElementCollection.cs" />
|
||||
<Compile Include="Configuration\BaseRest\MethodElement.cs" />
|
||||
<Compile Include="Configuration\ContentXmlStorage.cs" />
|
||||
<Compile Include="Configuration\LocalTempStorage.cs" />
|
||||
<Compile Include="Configuration\CoreDebug.cs" />
|
||||
<Compile Include="Configuration\Dashboard\AccessElement.cs" />
|
||||
<Compile Include="Configuration\Dashboard\AccessItem.cs" />
|
||||
|
||||
@@ -20,7 +20,7 @@ using Umbraco.Tests.TestHelpers.Entities;
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentTests : BaseUmbracoConfigurationTest
|
||||
public class ContentTests : BaseUmbracoApplicationTest
|
||||
{
|
||||
[SetUp]
|
||||
public void Init()
|
||||
|
||||
@@ -118,25 +118,12 @@ namespace Umbraco.Tests.TestHelpers
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// By default this returns false which means the plugin manager will not be reset so it doesn't need to re-scan
|
||||
/// all of the assemblies. Inheritors can override this if plugin manager resetting is required, generally needs
|
||||
/// to be set to true if the SetupPluginManager has been overridden.
|
||||
/// </summary>
|
||||
protected virtual bool PluginManagerResetRequired
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inheritors can resset the plugin manager if they choose to on teardown
|
||||
/// </summary>
|
||||
protected virtual void ResetPluginManager()
|
||||
{
|
||||
if (PluginManagerResetRequired)
|
||||
{
|
||||
PluginManager.Current = null;
|
||||
}
|
||||
PluginManager.Current = null;
|
||||
}
|
||||
|
||||
protected virtual CacheHelper CreateCacheHelper()
|
||||
@@ -185,26 +172,23 @@ namespace Umbraco.Tests.TestHelpers
|
||||
/// </summary>
|
||||
protected virtual void SetupPluginManager()
|
||||
{
|
||||
if (PluginManager.Current == null || PluginManagerResetRequired)
|
||||
PluginManager.Current = new PluginManager(
|
||||
new ActivatorServiceProvider(),
|
||||
CacheHelper.RuntimeCache, ProfilingLogger, false)
|
||||
{
|
||||
PluginManager.Current = new PluginManager(
|
||||
new ActivatorServiceProvider(),
|
||||
CacheHelper.RuntimeCache, ProfilingLogger, false)
|
||||
AssembliesToScan = new[]
|
||||
{
|
||||
AssembliesToScan = new[]
|
||||
{
|
||||
Assembly.Load("Umbraco.Core"),
|
||||
Assembly.Load("umbraco"),
|
||||
Assembly.Load("Umbraco.Tests"),
|
||||
Assembly.Load("businesslogic"),
|
||||
Assembly.Load("cms"),
|
||||
Assembly.Load("controls"),
|
||||
Assembly.Load("umbraco.editorControls"),
|
||||
Assembly.Load("umbraco.MacroEngines"),
|
||||
Assembly.Load("umbraco.providers"),
|
||||
}
|
||||
};
|
||||
}
|
||||
Assembly.Load("Umbraco.Core"),
|
||||
Assembly.Load("umbraco"),
|
||||
Assembly.Load("Umbraco.Tests"),
|
||||
Assembly.Load("businesslogic"),
|
||||
Assembly.Load("cms"),
|
||||
Assembly.Load("controls"),
|
||||
Assembly.Load("umbraco.editorControls"),
|
||||
Assembly.Load("umbraco.MacroEngines"),
|
||||
Assembly.Load("umbraco.providers"),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -7,11 +7,12 @@ using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Deploy;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class UdiTests
|
||||
public class UdiTests : BaseUmbracoApplicationTest
|
||||
{
|
||||
[Test]
|
||||
public void StringUdiCtorTest()
|
||||
|
||||
@@ -7,12 +7,22 @@ var app = angular.module("Umbraco.canvasdesigner", ['colorpicker', 'ui.slider',
|
||||
|
||||
.controller("Umbraco.canvasdesignerController", function ($scope, $http, $window, $timeout, $location, dialogService) {
|
||||
|
||||
var isInit = $location.search().init;
|
||||
if (isInit === "true") {
|
||||
//do not continue, this is the first load of this new window, if this is passed in it means it's been
|
||||
//initialized by the content editor and then the content editor will actually re-load this window without
|
||||
//this flag. This is a required trick to get around chrome popup mgr. We don't want to double load preview.aspx
|
||||
//since that will double prepare the preview documents
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.isOpen = false;
|
||||
$scope.frameLoaded = false;
|
||||
$scope.enableCanvasdesigner = 0;
|
||||
$scope.googleFontFamilies = {};
|
||||
$scope.pageId = $location.search().id;
|
||||
$scope.pageUrl = "../dialogs/Preview.aspx?id=" + $location.search().id;
|
||||
var pageId = $location.search().id;
|
||||
$scope.pageId = pageId;
|
||||
$scope.pageUrl = "../dialogs/Preview.aspx?id=" + pageId;
|
||||
$scope.valueAreLoaded = false;
|
||||
$scope.devices = [
|
||||
{ name: "desktop", css: "desktop", icon: "icon-display", title: "Desktop" },
|
||||
|
||||
+2
-2
@@ -208,9 +208,9 @@
|
||||
if (!$scope.busy) {
|
||||
|
||||
// Chromes popup blocker will kick in if a window is opened
|
||||
// outwith the initial scoped request. This trick will fix that.
|
||||
// without the initial scoped request. This trick will fix that.
|
||||
//
|
||||
var previewWindow = $window.open('preview/?id=' + content.id, 'umbpreview');
|
||||
var previewWindow = $window.open('preview/?init=true&id=' + content.id, 'umbpreview');
|
||||
|
||||
// Build the correct path so both /#/ and #/ work.
|
||||
var redirect = Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + '/preview/?id=' + content.id;
|
||||
|
||||
@@ -66,9 +66,13 @@ Use this directive to render an avatar.
|
||||
|
||||
function getNameInitials(name) {
|
||||
if(name) {
|
||||
var initials = name.match(/\b\w/g) || [];
|
||||
initials = ((initials.shift() || '') + (initials.pop() || '')).toUpperCase();
|
||||
return initials;
|
||||
var names = name.split(' '),
|
||||
initials = names[0].substring(0, 1);
|
||||
|
||||
if (names.length > 1) {
|
||||
initials += names[names.length - 1].substring(0, 1);
|
||||
}
|
||||
return initials.toUpperCase();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -261,6 +261,9 @@ input[type="submit"].btn {
|
||||
*padding-top: 1px;
|
||||
*padding-bottom: 1px;
|
||||
}
|
||||
|
||||
// Safari defaults to 1px for input. Ref U4-7721.
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,3 +35,10 @@
|
||||
margin-right: 5px;
|
||||
color: @gray-7;
|
||||
}
|
||||
|
||||
input.umb-breadcrumbs__add-ancestor {
|
||||
height: 25px;
|
||||
margin-top: -2px;
|
||||
margin-left: 3px;
|
||||
width: 100px;
|
||||
}
|
||||
@@ -636,9 +636,19 @@
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.umb-grid .mce-btn button {
|
||||
padding: 8px 6px;
|
||||
line-height: inherit;
|
||||
.umb-grid .mce-btn {
|
||||
button {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
padding-left: 6px;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&:not(.mce-menubtn) {
|
||||
button {
|
||||
padding-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.umb-grid .mce-toolbar {
|
||||
|
||||
@@ -126,21 +126,21 @@ ul.color-picker li a {
|
||||
// Media picker
|
||||
// --------------------------------------------------
|
||||
.umb-mediapicker .add-link {
|
||||
display: inline-block;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
color: @gray-8;
|
||||
border: 2px @gray-8 dashed;
|
||||
line-height: 120px;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
justify-content:center;
|
||||
align-items:center;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
color: @gray-8;
|
||||
border: 2px @gray-8 dashed;
|
||||
text-decoration: none;
|
||||
|
||||
transition: all 150ms ease-in-out;
|
||||
transition: all 150ms ease-in-out;
|
||||
|
||||
&:hover {
|
||||
color: @turquoise-d1;
|
||||
border-color: @turquoise;
|
||||
}
|
||||
&:hover {
|
||||
color: @turquoise-d1;
|
||||
border-color: @turquoise;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-mediapicker .picked-image {
|
||||
@@ -165,6 +165,10 @@ ul.color-picker li a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.umb-mediapicker .add-link-square {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.umb-thumbnails{
|
||||
@@ -207,11 +211,10 @@ ul.color-picker li a {
|
||||
|
||||
.umb-mediapicker .umb-sortable-thumbnails li {
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
margin: 0 5px 0 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
.umb-sortable-thumbnails li:hover a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -219,16 +222,20 @@ ul.color-picker li a {
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails li img {
|
||||
max-width:100%;
|
||||
max-height:100%;
|
||||
margin:auto;
|
||||
display:block;
|
||||
background-image: url(../img/checkered-background.png);
|
||||
max-width:100%;
|
||||
max-height:100%;
|
||||
margin:auto;
|
||||
display:block;
|
||||
background-image: url(../img/checkered-background.png);
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails li img.noScale{
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
.umb-sortable-thumbnails li img.trashed {
|
||||
opacity:0.3;
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails li img.noScale {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails .umb-icon-holder {
|
||||
@@ -254,8 +261,8 @@ ul.color-picker li a {
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__actions {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails .umb-sortable-thumbnails__action {
|
||||
@@ -285,27 +292,27 @@ ul.color-picker li a {
|
||||
// -------------------------------------------------
|
||||
|
||||
.umb-cropper{
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.umb-cropper img, .umb-cropper-gravity img{
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.umb-cropper img {
|
||||
max-width: none;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.umb-cropper .overlay, .umb-cropper-gravity .overlay {
|
||||
top: 0;
|
||||
left: 0;
|
||||
cursor: move;
|
||||
z-index: @zindexCropperOverlay;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
cursor: move;
|
||||
z-index: @zindexCropperOverlay;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.umb-cropper .viewport{
|
||||
@@ -317,43 +324,43 @@ ul.color-picker li a {
|
||||
}
|
||||
|
||||
.umb-cropper-gravity .viewport{
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.umb-cropper .viewport:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: @zindexCropperOverlay - 1;
|
||||
-moz-opacity: .75;
|
||||
opacity: .75;
|
||||
filter: alpha(opacity=7);
|
||||
-webkit-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2);
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: @zindexCropperOverlay - 1;
|
||||
-moz-opacity: .75;
|
||||
opacity: .75;
|
||||
filter: alpha(opacity=7);
|
||||
-webkit-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
.umb-cropper-gravity .overlay{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
background: @turquoise;
|
||||
border: 3px solid @white;
|
||||
opacity: 0.8;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
background: @turquoise;
|
||||
border: 3px solid @white;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.umb-cropper-gravity .overlay i {
|
||||
font-size: 26px;
|
||||
line-height: 26px;
|
||||
opacity: 0.8 !important;
|
||||
font-size: 26px;
|
||||
line-height: 26px;
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
|
||||
.umb-cropper .crop-container {
|
||||
@@ -361,16 +368,16 @@ ul.color-picker li a {
|
||||
}
|
||||
|
||||
.umb-cropper .crop-slider {
|
||||
padding: 10px;
|
||||
border-top: 1px solid @gray-10;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
@media (min-width: 769px) {
|
||||
padding: 10px;
|
||||
border-top: 1px solid @gray-10;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
@media (min-width: 769px) {
|
||||
padding: 10px 50px 10px 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.umb-cropper .crop-slider i {
|
||||
|
||||
+44
-27
@@ -56,6 +56,46 @@ angular.module("umbraco")
|
||||
$scope.target = dialogOptions.currentTarget;
|
||||
}
|
||||
|
||||
function onInit() {
|
||||
if ($scope.startNodeId !== -1) {
|
||||
entityResource.getById($scope.startNodeId, "media")
|
||||
.then(function (ent) {
|
||||
$scope.startNodeId = ent.id;
|
||||
run();
|
||||
});
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
function run() {
|
||||
//default root item
|
||||
if (!$scope.target) {
|
||||
if ($scope.lastOpenedNode && $scope.lastOpenedNode !== -1) {
|
||||
entityResource.getById($scope.lastOpenedNode, "media")
|
||||
.then(ensureWithinStartNode, gotoStartNode);
|
||||
} else {
|
||||
gotoStartNode();
|
||||
}
|
||||
} else {
|
||||
//if a target is specified, go look it up - generally this target will just contain ids not the actual full
|
||||
//media object so we need to look it up
|
||||
var id = $scope.target.udi ? $scope.target.udi : $scope.target.id
|
||||
var altText = $scope.target.altText;
|
||||
mediaResource.getById(id)
|
||||
.then(function (node) {
|
||||
$scope.target = node;
|
||||
if (ensureWithinStartNode(node)) {
|
||||
selectImage(node);
|
||||
$scope.target.url = mediaHelper.resolveFile(node);
|
||||
$scope.target.altText = altText;
|
||||
$scope.openDetailsDialog();
|
||||
}
|
||||
},
|
||||
gotoStartNode);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.upload = function(v) {
|
||||
angular.element(".umb-file-dropzone-directive .file-select").click();
|
||||
};
|
||||
@@ -107,7 +147,7 @@ angular.module("umbraco")
|
||||
|
||||
if (folder.id > 0) {
|
||||
entityResource.getAncestors(folder.id, "media")
|
||||
.then(function(anc) {
|
||||
.then(function(anc) {
|
||||
$scope.path = _.filter(anc,
|
||||
function(f) {
|
||||
return f.path.indexOf($scope.startNodeId) !== -1;
|
||||
@@ -218,32 +258,6 @@ angular.module("umbraco")
|
||||
$scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" });
|
||||
}
|
||||
|
||||
//default root item
|
||||
if (!$scope.target) {
|
||||
if ($scope.lastOpenedNode && $scope.lastOpenedNode !== -1) {
|
||||
entityResource.getById($scope.lastOpenedNode, "media")
|
||||
.then(ensureWithinStartNode, gotoStartNode);
|
||||
} else {
|
||||
gotoStartNode();
|
||||
}
|
||||
} else {
|
||||
//if a target is specified, go look it up - generally this target will just contain ids not the actual full
|
||||
//media object so we need to look it up
|
||||
var id = $scope.target.udi ? $scope.target.udi : $scope.target.id
|
||||
var altText = $scope.target.altText;
|
||||
mediaResource.getById(id)
|
||||
.then(function(node) {
|
||||
$scope.target = node;
|
||||
if (ensureWithinStartNode(node)) {
|
||||
selectImage(node);
|
||||
$scope.target.url = mediaHelper.resolveFile(node);
|
||||
$scope.target.altText = altText;
|
||||
$scope.openDetailsDialog();
|
||||
}
|
||||
},
|
||||
gotoStartNode);
|
||||
}
|
||||
|
||||
$scope.openDetailsDialog = function() {
|
||||
|
||||
$scope.mediaPickerDetailsOverlay = {};
|
||||
@@ -368,4 +382,7 @@ angular.module("umbraco")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onInit();
|
||||
|
||||
});
|
||||
@@ -48,14 +48,14 @@
|
||||
<span class="umb-breadcrumbs__seperator">/</span>
|
||||
</li>
|
||||
|
||||
<li class="umb-breadcrumbs__ancestor" ng-if="!lockedFolder">
|
||||
<li class="umb-breadcrumbs__ancestor" ng-show="!lockedFolder">
|
||||
<a href ng-hide="showFolderInput" ng-click="showFolderInput = true">
|
||||
<i class="icon icon-add small"></i>
|
||||
</a>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
class="input-foldername input-mini inline"
|
||||
class="umb-breadcrumbs__add-ancestor"
|
||||
ng-show="showFolderInput"
|
||||
ng-model="newFolderName"
|
||||
ng-keydown="enterSubmitFolder($event)"
|
||||
|
||||
+8
-4
@@ -1,7 +1,7 @@
|
||||
//this controller simply tells the dialogs service to open a mediaPicker window
|
||||
//with a specified callback, this callback will receive an object with a selection on it
|
||||
|
||||
function contentPickerController($scope, entityResource, editorState, iconHelper, $routeParams, angularHelper, navigationService, $location, miniEditorHelper) {
|
||||
function contentPickerController($scope, entityResource, editorState, iconHelper, $routeParams, angularHelper, navigationService, $location, miniEditorHelper, localizationService) {
|
||||
|
||||
var unsubscribe;
|
||||
|
||||
@@ -154,7 +154,6 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($routeParams.section === "settings" && $routeParams.tree === "documentTypes") {
|
||||
//if the content-picker is being rendered inside the document-type editor, we don't need to process the startnode query
|
||||
dialogOptions.startNodeId = -1;
|
||||
@@ -287,8 +286,12 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
|
||||
entityResource.getUrl(entity.id, entityType).then(function(data){
|
||||
// update url
|
||||
angular.forEach($scope.renderModel, function(item){
|
||||
if(item.id === entity.id) {
|
||||
item.url = data;
|
||||
if (item.id === entity.id) {
|
||||
if (entity.trashed) {
|
||||
item.url = localizationService.dictionary.general_recycleBin;
|
||||
} else {
|
||||
item.url = data;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -330,6 +333,7 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
|
||||
"icon": item.icon,
|
||||
"path": item.path,
|
||||
"url": item.url,
|
||||
"trashed": item.trashed,
|
||||
"published": (item.metaData && item.metaData.IsPublished === false && entityType === "Document") ? false : true
|
||||
// only content supports published/unpublished content so we set everything else to published so the UI looks correct
|
||||
});
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.ContentPickerController" class="umb-editor umb-contentpicker">
|
||||
|
||||
<p ng-if="(renderModel|filter:{trashed:true}).length == 1"><localize key="contentPicker_pickedTrashedItem"></localize></p>
|
||||
<p ng-if="(renderModel|filter:{trashed:true}).length > 1"><localize key="contentPicker_pickedTrashedItems"></localize></p>
|
||||
|
||||
<ng-form name="contentPickerForm">
|
||||
|
||||
<div ui-sortable="sortableOptions" ng-model="renderModel">
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
val-server="value" />
|
||||
|
||||
<span class="help-inline" val-msg-for="textbox" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="textbox" val-toggle-msg="valEmail"><localize key="valiation_invalidEmail">Invalid email</localize></span>
|
||||
<span class="help-inline" val-msg-for="textbox" val-toggle-msg="valEmail"><localize key="validation_invalidEmail">Invalid email</localize></span>
|
||||
<span class="help-inline" val-msg-for="textbox" val-toggle-msg="valServer"></span>
|
||||
</div>
|
||||
|
||||
+39
-17
@@ -1,7 +1,7 @@
|
||||
//this controller simply tells the dialogs service to open a mediaPicker window
|
||||
//with a specified callback, this callback will receive an object with a selection on it
|
||||
angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerController",
|
||||
function ($rootScope, $scope, dialogService, entityResource, mediaResource, mediaHelper, $timeout, userService, $location) {
|
||||
function ($rootScope, $scope, dialogService, entityResource, mediaResource, mediaHelper, $timeout, userService, $location, localizationService) {
|
||||
|
||||
//check the pre-values for multi-picker
|
||||
var multiPicker = $scope.model.config.multiPicker && $scope.model.config.multiPicker !== '0' ? true : false;
|
||||
@@ -26,17 +26,44 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
|
||||
// the mediaResource has server side auth configured for which the user must have
|
||||
// access to the media section, if they don't they'll get auth errors. The entityResource
|
||||
// acts differently in that it allows access if the user has access to any of the apps that
|
||||
// might require it's use. Therefore we need to use the metatData property to get at the thumbnail
|
||||
// might require it's use. Therefore we need to use the metaData property to get at the thumbnail
|
||||
// value.
|
||||
|
||||
entityResource.getByIds(ids, "Media").then(function (medias) {
|
||||
entityResource.getByIds(ids, "Media").then(function(medias) {
|
||||
|
||||
_.each(medias, function (media, i) {
|
||||
// The service only returns item results for ids that exist (deleted items are silently ignored).
|
||||
// This results in the picked items value to be set to contain only ids of picked items that could actually be found.
|
||||
// Since a referenced item could potentially be restored later on, instead of changing the selected values here based
|
||||
// on whether the items exist during a save event - we should keep "placeholder" items for picked items that currently
|
||||
// could not be fetched. This will preserve references and ensure that the state of an item does not differ depending
|
||||
// on whether it is simply resaved or not.
|
||||
// This is done by remapping the int/guid ids into a new array of items, where we create "Deleted item" placeholders
|
||||
// when there is no match for a selected id. This will ensure that the values being set on save, are the same as before.
|
||||
|
||||
medias = _.map(ids,
|
||||
function(id) {
|
||||
var found = _.find(medias,
|
||||
function(m) {
|
||||
return m.udi === id || m.id === id;
|
||||
});
|
||||
if (found) {
|
||||
return found;
|
||||
} else {
|
||||
return {
|
||||
name: localizationService.dictionary.mediaPicker_deletedItem,
|
||||
id: $scope.model.config.idType !== "udi" ? id : null,
|
||||
udi: $scope.model.config.idType === "udi" ? id : null,
|
||||
icon: "icon-picture",
|
||||
thumbnail: null,
|
||||
trashed: true
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
//only show non-trashed items
|
||||
if (media.parentId >= -1) {
|
||||
|
||||
if (!media.thumbnail) {
|
||||
_.each(medias,
|
||||
function(media, i) {
|
||||
// if there is no thumbnail, try getting one if the media is not a placeholder item
|
||||
if (!media.thumbnail && media.id && media.metaData) {
|
||||
media.thumbnail = mediaHelper.resolveFileFromEntity(media, true);
|
||||
}
|
||||
|
||||
@@ -44,12 +71,10 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
|
||||
|
||||
if ($scope.model.config.idType === "udi") {
|
||||
$scope.ids.push(media.udi);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$scope.ids.push(media.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$scope.sync();
|
||||
});
|
||||
@@ -82,8 +107,8 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
|
||||
submit: function(model) {
|
||||
|
||||
_.each(model.selectedImages, function(media, i) {
|
||||
|
||||
if (!media.thumbnail) {
|
||||
// if there is no thumbnail, try getting one if the media is not a placeholder item
|
||||
if (!media.thumbnail && media.id && media.metaData) {
|
||||
media.thumbnail = mediaHelper.resolveFileFromEntity(media, true);
|
||||
}
|
||||
|
||||
@@ -101,10 +126,8 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
|
||||
|
||||
$scope.mediaPickerOverlay.show = false;
|
||||
$scope.mediaPickerOverlay = null;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
$scope.sortableOptions = {
|
||||
@@ -142,5 +165,4 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
|
||||
//update the display val again if it has changed from the server
|
||||
setupViewModel();
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
<div class="umb-editor umb-mediapicker" ng-controller="Umbraco.PropertyEditors.MediaPickerController">
|
||||
|
||||
<ul ui-sortable="sortableOptions" ng-model="images" class="umb-sortable-thumbnails">
|
||||
<li style="width: 120px; height: 100px; overflow: hidden;" ng-repeat="image in images">
|
||||
<p ng-if="(images|filter:{trashed:true}).length == 1"><localize key="mediaPicker_pickedTrashedItem"></localize></p>
|
||||
<p ng-if="(images|filter:{trashed:true}).length > 1"><localize key="mediaPicker_pickedTrashedItems"></localize></p>
|
||||
|
||||
<!-- IMAGE -->
|
||||
<img ng-src="{{image.thumbnail}}" alt="" ng-show="image.thumbnail" title="{{image.name}}" />
|
||||
<div class="flex error">
|
||||
<ul ui-sortable="sortableOptions" ng-model="images" class="umb-sortable-thumbnails">
|
||||
<li style="width: 120px; height: 100px; overflow: hidden;" ng-repeat="image in images">
|
||||
|
||||
<!-- SVG -->
|
||||
<img ng-if="image.metaData.umbracoExtension.Value === 'svg'" ng-src="{{image.metaData.umbracoFile.Value}}" alt="" title="{{image.name}}" />
|
||||
<img ng-if="image.extension === 'svg'" ng-src="{{image.file}}" alt="" />
|
||||
<!-- IMAGE -->
|
||||
<img ng-class="{'trashed': image.trashed}" ng-src="{{image.thumbnail}}" alt="" ng-show="image.thumbnail" title="{{image.trashed ? 'Trashed: ' + image.name : image.name}}" />
|
||||
|
||||
<!-- FILE -->
|
||||
<span class="umb-icon-holder" ng-hide="image.thumbnail || image.metaData.umbracoExtension.Value === 'svg' || image.extension === 'svg'">
|
||||
<i class="icon {{image.icon}} large"></i>
|
||||
<small>{{image.name}}</small>
|
||||
</span>
|
||||
<!-- SVG -->
|
||||
<img ng-class="{'trashed': image.trashed}" ng-if="image.metaData.umbracoExtension.Value === 'svg'" ng-src="{{image.metaData.umbracoFile.Value}}" alt="" title="{{image.trashed ? 'Trashed: ' + image.name : image.name}}" />
|
||||
<img ng-class="{'trashed': image.trashed}" ng-if="image.extension === 'svg'" ng-src="{{image.file}}" alt="" />
|
||||
|
||||
<div class="umb-sortable-thumbnails__actions">
|
||||
<a class="umb-sortable-thumbnails__action" href="" ng-click="goToItem(image)">
|
||||
<i class="icon icon-edit"></i>
|
||||
</a>
|
||||
<a class="umb-sortable-thumbnails__action -red" href="" ng-click="remove($index)">
|
||||
<i class="icon icon-delete"></i>
|
||||
</a>
|
||||
</div>
|
||||
<!-- FILE -->
|
||||
<span class="umb-icon-holder" ng-hide="image.thumbnail || image.metaData.umbracoExtension.Value === 'svg' || image.extension === 'svg'">
|
||||
<i class="icon {{image.icon}} large"></i>
|
||||
<small>{{image.name}}</small>
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<div class="umb-sortable-thumbnails__actions">
|
||||
<a class="umb-sortable-thumbnails__action" href="" ng-click="goToItem(image)">
|
||||
<i class="icon icon-edit"></i>
|
||||
</a>
|
||||
<a class="umb-sortable-thumbnails__action -red" href="" ng-click="remove($index)">
|
||||
<i class="icon icon-delete"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
<ul class="umb-sortable-thumbnails" ng-if="showAdd()">
|
||||
<li style="border: none">
|
||||
<a href="#" class="add-link" ng-click="add()" prevent-default>
|
||||
<i class="icon icon-add large"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<a href="#" class="add-link" ng-click="add()" ng-class="{'add-link-square': images.length === 0}" ng-if="showAdd()" prevent-default>
|
||||
<i class="icon icon-add large"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="mediaPickerOverlay.show"
|
||||
model="mediaPickerOverlay"
|
||||
position="right"
|
||||
view="mediaPickerOverlay.view">
|
||||
</umb-overlay>
|
||||
<umb-overlay
|
||||
ng-if="mediaPickerOverlay.show"
|
||||
model="mediaPickerOverlay"
|
||||
position="right"
|
||||
view="mediaPickerOverlay.view">
|
||||
</umb-overlay>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -76,6 +76,7 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
|
||||
icon.isCustom = false;
|
||||
break;
|
||||
case "styleselect":
|
||||
case "fontsizeselect":
|
||||
icon.name = "icon-list";
|
||||
icon.isCustom = true;
|
||||
break;
|
||||
|
||||
@@ -1027,9 +1027,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>7720</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>7730</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:7720</IISUrl>
|
||||
<IISUrl>http://localhost:7730</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -60,21 +60,29 @@
|
||||
JObject cfg = contentItem.config;
|
||||
|
||||
if(cfg != null)
|
||||
foreach (JProperty property in cfg.Properties()) {
|
||||
attrs.Add(property.Name + "='" + property.Value.ToString() + "'");
|
||||
foreach (JProperty property in cfg.Properties())
|
||||
{
|
||||
var propertyValue = HttpUtility.HtmlAttributeEncode(property.Value.ToString());
|
||||
attrs.Add(property.Name + "=\"" + propertyValue + "\"");
|
||||
}
|
||||
|
||||
|
||||
JObject style = contentItem.styles;
|
||||
|
||||
if (style != null) {
|
||||
var cssVals = new List<string>();
|
||||
foreach (JProperty property in style.Properties())
|
||||
cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
|
||||
if (style != null) {
|
||||
var cssVals = new List<string>();
|
||||
foreach (JProperty property in style.Properties())
|
||||
{
|
||||
var propertyValue = property.Value.ToString();
|
||||
if (string.IsNullOrWhiteSpace(propertyValue) == false)
|
||||
{
|
||||
cssVals.Add(property.Name + ":" + propertyValue + ";");
|
||||
}
|
||||
}
|
||||
|
||||
if (cssVals.Any())
|
||||
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
|
||||
if (cssVals.Any())
|
||||
attrs.Add("style=\"" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "\"");
|
||||
}
|
||||
|
||||
|
||||
return new MvcHtmlString(string.Join(" ", attrs));
|
||||
}
|
||||
}
|
||||
@@ -60,21 +60,29 @@
|
||||
JObject cfg = contentItem.config;
|
||||
|
||||
if(cfg != null)
|
||||
foreach (JProperty property in cfg.Properties()) {
|
||||
attrs.Add(property.Name + "='" + property.Value.ToString() + "'");
|
||||
foreach (JProperty property in cfg.Properties())
|
||||
{
|
||||
var propertyValue = HttpUtility.HtmlAttributeEncode(property.Value.ToString());
|
||||
attrs.Add(property.Name + "=\"" + propertyValue + "\"");
|
||||
}
|
||||
|
||||
|
||||
JObject style = contentItem.styles;
|
||||
|
||||
if (style != null) {
|
||||
var cssVals = new List<string>();
|
||||
foreach (JProperty property in style.Properties())
|
||||
cssVals.Add(property.Name + ":" + property.Value.ToString() + ";");
|
||||
if (style != null) {
|
||||
var cssVals = new List<string>();
|
||||
foreach (JProperty property in style.Properties())
|
||||
{
|
||||
var propertyValue = property.Value.ToString();
|
||||
if (string.IsNullOrWhiteSpace(propertyValue) == false)
|
||||
{
|
||||
cssVals.Add(property.Name + ":" + propertyValue + ";");
|
||||
}
|
||||
}
|
||||
|
||||
if (cssVals.Any())
|
||||
attrs.Add("style='" + string.Join(" ", cssVals) + "'");
|
||||
if (cssVals.Any())
|
||||
attrs.Add("style=\"" + HttpUtility.HtmlAttributeEncode(string.Join(" ", cssVals)) + "\"");
|
||||
}
|
||||
|
||||
|
||||
return new MvcHtmlString(string.Join(" ", attrs));
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
@if (Model.editor.config.markup != null)
|
||||
{
|
||||
string markup = Model.editor.config.markup.ToString();
|
||||
|
||||
markup = markup.Replace("#value#", Model.value.ToString());
|
||||
var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
markup = markup.Replace("#value#", umbracoHelper.ReplaceLineBreaksForHtml(HttpUtility.HtmlEncode(Model.value.ToString())));
|
||||
markup = markup.Replace("#style#", Model.editor.config.style.ToString());
|
||||
|
||||
<text>
|
||||
|
||||
@@ -935,6 +935,15 @@ Mange hilsner fra Umbraco robotten
|
||||
<area alias="colorpicker">
|
||||
<key alias="noColors">Du har ikke konfigureret nogen godkendte farver</key>
|
||||
</area>
|
||||
<area alias="contentPicker">
|
||||
<key alias="pickedTrashedItem">Du har valgt et dokument som er slettet eller lagt i papirkurven</key>
|
||||
<key alias="pickedTrashedItems">Du har valgt dokumenter som er slettede eller lagt i papirkurven</key>
|
||||
</area>
|
||||
<area alias="mediaPicker">
|
||||
<key alias="pickedTrashedItem">Du har valgt et medie som er slettet eller lagt i papirkurven</key>
|
||||
<key alias="pickedTrashedItems">Du har valgt medier som er slettede eller lagt i papirkurven</key>
|
||||
<key alias="deletedItem">Slettet medie</key>
|
||||
</area>
|
||||
<area alias="relatedlinks">
|
||||
<key alias="enterExternal">indtast eksternt link</key>
|
||||
<key alias="chooseInternal">vælg en intern side</key>
|
||||
|
||||
@@ -693,35 +693,35 @@
|
||||
<key alias="databaseFound">Your database has been found and is identified as</key>
|
||||
<key alias="databaseHeader">Database configuration</key>
|
||||
<key alias="databaseInstall">
|
||||
<![CDATA[
|
||||
Press the <strong>install</strong> button to install the Umbraco %0% database
|
||||
<![CDATA[
|
||||
Press the <strong>install</strong> button to install the Umbraco %0% database
|
||||
]]>
|
||||
</key>
|
||||
<key alias="databaseInstallDone"><![CDATA[Umbraco %0% has now been copied to your database. Press <strong>Next</strong> to proceed.]]></key>
|
||||
<key alias="databaseNotFound">
|
||||
<![CDATA[<p>Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.</p>
|
||||
<p>To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file. </p>
|
||||
<p>
|
||||
Click the <strong>retry</strong> button when
|
||||
done.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">
|
||||
<![CDATA[<p>Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.</p>
|
||||
<p>To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file. </p>
|
||||
<p>
|
||||
Click the <strong>retry</strong> button when
|
||||
done.<br /><a href="http://our.umbraco.org/documentation/Using-Umbraco/Config-files/webconfig7" target="_blank">
|
||||
More information on editing web.config here.</a></p>]]>
|
||||
</key>
|
||||
<key alias="databaseText">
|
||||
<![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
|
||||
Please contact your ISP if necessary.
|
||||
<![CDATA[To complete this step, you must know some information regarding your database server ("connection string").<br />
|
||||
Please contact your ISP if necessary.
|
||||
If you're installing on a local machine or server you might need information from your system administrator.]]>
|
||||
</key>
|
||||
<key alias="databaseUpgrade">
|
||||
<![CDATA[
|
||||
<p>
|
||||
Press the <strong>upgrade</strong> button to upgrade your database to Umbraco %0%</p>
|
||||
<p>
|
||||
Don't worry - no content will be deleted and everything will continue working afterwards!
|
||||
</p>
|
||||
<![CDATA[
|
||||
<p>
|
||||
Press the <strong>upgrade</strong> button to upgrade your database to Umbraco %0%</p>
|
||||
<p>
|
||||
Don't worry - no content will be deleted and everything will continue working afterwards!
|
||||
</p>
|
||||
]]>
|
||||
</key>
|
||||
<key alias="databaseUpgradeDone">
|
||||
<![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
|
||||
<![CDATA[Your database has been upgraded to the final version %0%.<br />Press <strong>Next</strong> to
|
||||
proceed. ]]>
|
||||
</key>
|
||||
<key alias="databaseUpToDate"><![CDATA[Your current database is up-to-date!. Click <strong>next</strong> to continue the configuration wizard]]></key>
|
||||
@@ -736,65 +736,65 @@
|
||||
<key alias="permissionsAffectedFoldersMoreInfo">More information on setting up permissions for Umbraco here</key>
|
||||
<key alias="permissionsAffectedFoldersText">You need to grant ASP.NET modify permissions to the following files/folders</key>
|
||||
<key alias="permissionsAlmostPerfect">
|
||||
<![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
|
||||
<![CDATA[<strong>Your permission settings are almost perfect!</strong><br /><br />
|
||||
You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
|
||||
</key>
|
||||
<key alias="permissionsHowtoResolve">How to Resolve</key>
|
||||
<key alias="permissionsHowtoResolveLink">Click here to read the text version</key>
|
||||
<key alias="permissionsHowtoResolveText"><![CDATA[Watch our <strong>video tutorial</strong> on setting up folder permissions for Umbraco or read the text version.]]></key>
|
||||
<key alias="permissionsMaybeAnIssue">
|
||||
<![CDATA[<strong>Your permission settings might be an issue!</strong>
|
||||
<br/><br />
|
||||
<![CDATA[<strong>Your permission settings might be an issue!</strong>
|
||||
<br/><br />
|
||||
You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
|
||||
</key>
|
||||
<key alias="permissionsNotReady">
|
||||
<![CDATA[<strong>Your permission settings are not ready for Umbraco!</strong>
|
||||
<br /><br />
|
||||
<![CDATA[<strong>Your permission settings are not ready for Umbraco!</strong>
|
||||
<br /><br />
|
||||
In order to run Umbraco, you'll need to update your permission settings.]]>
|
||||
</key>
|
||||
<key alias="permissionsPerfect">
|
||||
<![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
|
||||
<![CDATA[<strong>Your permission settings are perfect!</strong><br /><br />
|
||||
You are ready to run Umbraco and install packages!]]>
|
||||
</key>
|
||||
<key alias="permissionsResolveFolderIssues">Resolving folder issue</key>
|
||||
<key alias="permissionsResolveFolderIssuesLink">Follow this link for more information on problems with ASP.NET and creating folders</key>
|
||||
<key alias="permissionsSettingUpPermissions">Setting up folder permissions</key>
|
||||
<key alias="permissionsText">
|
||||
<![CDATA[
|
||||
Umbraco needs write/modify access to certain directories in order to store files like pictures and PDF's.
|
||||
It also stores temporary data (aka: cache) for enhancing the performance of your website.
|
||||
<![CDATA[
|
||||
Umbraco needs write/modify access to certain directories in order to store files like pictures and PDF's.
|
||||
It also stores temporary data (aka: cache) for enhancing the performance of your website.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="runwayFromScratch">I want to start from scratch</key>
|
||||
<key alias="runwayFromScratchText">
|
||||
<![CDATA[
|
||||
Your website is completely empty at the moment, so that's perfect if you want to start from scratch and create your own document types and templates.
|
||||
(<a href="http://Umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">learn how</a>)
|
||||
You can still choose to install Runway later on. Please go to the Developer section and choose Packages.
|
||||
<![CDATA[
|
||||
Your website is completely empty at the moment, so that's perfect if you want to start from scratch and create your own document types and templates.
|
||||
(<a href="http://Umbraco.tv/documentation/videos/for-site-builders/foundation/document-types">learn how</a>)
|
||||
You can still choose to install Runway later on. Please go to the Developer section and choose Packages.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="runwayHeader">You've just set up a clean Umbraco platform. What do you want to do next?</key>
|
||||
<key alias="runwayInstalled">Runway is installed</key>
|
||||
<key alias="runwayInstalledText">
|
||||
<![CDATA[
|
||||
You have the foundation in place. Select what modules you wish to install on top of it.<br />
|
||||
This is our list of recommended modules, check off the ones you would like to install, or view the <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">full list of modules</a>
|
||||
<![CDATA[
|
||||
You have the foundation in place. Select what modules you wish to install on top of it.<br />
|
||||
This is our list of recommended modules, check off the ones you would like to install, or view the <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">full list of modules</a>
|
||||
]]>
|
||||
</key>
|
||||
<key alias="runwayOnlyProUsers">Only recommended for experienced users</key>
|
||||
<key alias="runwaySimpleSite">I want to start with a simple website</key>
|
||||
<key alias="runwaySimpleSiteText">
|
||||
<![CDATA[
|
||||
<p>
|
||||
"Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically,
|
||||
but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However,
|
||||
Runway offers an easy foundation based on best practices to get you started faster than ever.
|
||||
If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages.
|
||||
</p>
|
||||
<small>
|
||||
<em>Included with Runway:</em> Home page, Getting Started page, Installing Modules page.<br />
|
||||
<em>Optional Modules:</em> Top Navigation, Sitemap, Contact, Gallery.
|
||||
</small>
|
||||
<![CDATA[
|
||||
<p>
|
||||
"Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically,
|
||||
but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However,
|
||||
Runway offers an easy foundation based on best practices to get you started faster than ever.
|
||||
If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages.
|
||||
</p>
|
||||
<small>
|
||||
<em>Included with Runway:</em> Home page, Getting Started page, Installing Modules page.<br />
|
||||
<em>Optional Modules:</em> Top Navigation, Sitemap, Contact, Gallery.
|
||||
</small>
|
||||
]]>
|
||||
</key>
|
||||
<key alias="runwayWhatIsRunway">What is Runway</key>
|
||||
@@ -805,24 +805,24 @@
|
||||
<key alias="step5">Step 5/5: Umbraco is ready to get you started</key>
|
||||
<key alias="thankYou">Thank you for choosing Umbraco</key>
|
||||
<key alias="theEndBrowseSite">
|
||||
<![CDATA[<h3>Browse your new site</h3>
|
||||
<![CDATA[<h3>Browse your new site</h3>
|
||||
You installed Runway, so why not see how your new website looks.]]>
|
||||
</key>
|
||||
<key alias="theEndFurtherHelp">
|
||||
<![CDATA[<h3>Further help and information</h3>
|
||||
<![CDATA[<h3>Further help and information</h3>
|
||||
Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]>
|
||||
</key>
|
||||
<key alias="theEndHeader">Umbraco %0% is installed and ready for use</key>
|
||||
<key alias="theEndInstallFailed">
|
||||
<![CDATA[To finish the installation, you'll need to
|
||||
<![CDATA[To finish the installation, you'll need to
|
||||
manually edit the <strong>/web.config file</strong> and update the AppSetting key <strong>UmbracoConfigurationStatus</strong> in the bottom to the value of <strong>'%0%'</strong>.]]>
|
||||
</key>
|
||||
<key alias="theEndInstallSuccess">
|
||||
<![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to Umbraco</strong>,
|
||||
<![CDATA[You can get <strong>started instantly</strong> by clicking the "Launch Umbraco" button below. <br />If you are <strong>new to Umbraco</strong>,
|
||||
you can find plenty of resources on our getting started pages.]]>
|
||||
</key>
|
||||
<key alias="theEndOpenUmbraco">
|
||||
<![CDATA[<h3>Launch Umbraco</h3>
|
||||
<![CDATA[<h3>Launch Umbraco</h3>
|
||||
To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]>
|
||||
</key>
|
||||
<key alias="Unavailable">Connection to database failed.</key>
|
||||
@@ -830,8 +830,8 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="Version4">Umbraco Version 4</key>
|
||||
<key alias="watch">Watch</key>
|
||||
<key alias="welcomeIntro">
|
||||
<![CDATA[This wizard will guide you through the process of configuring <strong>Umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
|
||||
<br /><br />
|
||||
<![CDATA[This wizard will guide you through the process of configuring <strong>Umbraco %0%</strong> for a fresh install or upgrading from version 3.0.
|
||||
<br /><br />
|
||||
Press <strong>"next"</strong> to start the wizard.]]>
|
||||
</key>
|
||||
</area>
|
||||
@@ -889,47 +889,47 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<area alias="notifications">
|
||||
<key alias="editNotifications">Edit your notification for %0%</key>
|
||||
<key alias="mailBody">
|
||||
<![CDATA[
|
||||
Hi %0%
|
||||
|
||||
This is an automated mail to inform you that the task '%1%'
|
||||
has been performed on the page '%2%'
|
||||
by the user '%3%'
|
||||
|
||||
Go to http://%4%/#/content/content/edit/%5% to edit.
|
||||
|
||||
Have a nice day!
|
||||
|
||||
Cheers from the Umbraco robot
|
||||
<![CDATA[
|
||||
Hi %0%
|
||||
|
||||
This is an automated mail to inform you that the task '%1%'
|
||||
has been performed on the page '%2%'
|
||||
by the user '%3%'
|
||||
|
||||
Go to http://%4%/#/content/content/edit/%5% to edit.
|
||||
|
||||
Have a nice day!
|
||||
|
||||
Cheers from the Umbraco robot
|
||||
]]>
|
||||
</key>
|
||||
<key alias="mailBodyHtml">
|
||||
<![CDATA[<p>Hi %0%</p>
|
||||
|
||||
<p>This is an automated mail to inform you that the task <strong>'%1%'</strong>
|
||||
has been performed on the page <a href="http://%4%/#/content/content/edit/%5%"><strong>'%2%'</strong></a>
|
||||
by the user <strong>'%3%'</strong>
|
||||
</p>
|
||||
<div style="margin: 8px 0; padding: 8px; display: block;">
|
||||
<br />
|
||||
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%"> EDIT </a>
|
||||
<br />
|
||||
</div>
|
||||
<p>
|
||||
<h3>Update summary:</h3>
|
||||
<table style="width: 100%;">
|
||||
%6%
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<div style="margin: 8px 0; padding: 8px; display: block;">
|
||||
<br />
|
||||
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%"> EDIT </a>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<p>Have a nice day!<br /><br />
|
||||
Cheers from the Umbraco robot
|
||||
<![CDATA[<p>Hi %0%</p>
|
||||
|
||||
<p>This is an automated mail to inform you that the task <strong>'%1%'</strong>
|
||||
has been performed on the page <a href="http://%4%/#/content/content/edit/%5%"><strong>'%2%'</strong></a>
|
||||
by the user <strong>'%3%'</strong>
|
||||
</p>
|
||||
<div style="margin: 8px 0; padding: 8px; display: block;">
|
||||
<br />
|
||||
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%"> EDIT </a>
|
||||
<br />
|
||||
</div>
|
||||
<p>
|
||||
<h3>Update summary:</h3>
|
||||
<table style="width: 100%;">
|
||||
%6%
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<div style="margin: 8px 0; padding: 8px; display: block;">
|
||||
<br />
|
||||
<a style="color: white; font-weight: bold; background-color: #5372c3; text-decoration : none; margin-right: 20px; border: 8px solid #5372c3; width: 150px;" href="http://%4%/#/content/content/edit/%5%"> EDIT </a>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<p>Have a nice day!<br /><br />
|
||||
Cheers from the Umbraco robot
|
||||
</p>]]>
|
||||
</key>
|
||||
<key alias="mailSubject">[%0%] Notification about %1% performed on %2%</key>
|
||||
@@ -937,9 +937,9 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
</area>
|
||||
<area alias="packager">
|
||||
<key alias="chooseLocalPackageText">
|
||||
<![CDATA[
|
||||
Choose Package from your machine, by clicking the Browse<br />
|
||||
button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension.
|
||||
<![CDATA[
|
||||
Choose Package from your machine, by clicking the Browse<br />
|
||||
button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="dropHere">Drop to upload</key>
|
||||
@@ -982,7 +982,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="packageName">Package name</key>
|
||||
<key alias="packageNoItemsHeader">Package doesn't contain any items</key>
|
||||
<key alias="packageNoItemsText">
|
||||
<![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
|
||||
<![CDATA[This package file doesn't contain any items to uninstall.<br/><br/>
|
||||
You can safely remove this from the system by clicking "uninstall package" below.]]>
|
||||
</key>
|
||||
<key alias="packageNoUpgrades">No upgrades available</key>
|
||||
@@ -994,8 +994,8 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="packageUninstalledText">The package was successfully uninstalled</key>
|
||||
<key alias="packageUninstallHeader">Uninstall package</key>
|
||||
<key alias="packageUninstallText">
|
||||
<![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
|
||||
<span style="color: Red; font-weight: bold;">Notice:</span> any documents, media etc depending on the items you remove, will stop working, and could lead to system instability,
|
||||
<![CDATA[You can unselect items you do not wish to remove, at this time, below. When you click "confirm uninstall" all checked-off items will be removed.<br />
|
||||
<span style="color: Red; font-weight: bold;">Notice:</span> any documents, media etc depending on the items you remove, will stop working, and could lead to system instability,
|
||||
so uninstall with caution. If in doubt, contact the package author.]]>
|
||||
</key>
|
||||
<key alias="packageUpgradeDownload">Download update from the repository</key>
|
||||
@@ -1042,28 +1042,28 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
</area>
|
||||
<area alias="publish">
|
||||
<key alias="contentPublishedFailedAwaitingRelease">
|
||||
<![CDATA[
|
||||
%0% could not be published because the item is scheduled for release.
|
||||
<![CDATA[
|
||||
%0% could not be published because the item is scheduled for release.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="contentPublishedFailedExpired">
|
||||
<![CDATA[
|
||||
%0% could not be published because the item has expired.
|
||||
<![CDATA[
|
||||
%0% could not be published because the item has expired.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="contentPublishedFailedInvalid">
|
||||
<![CDATA[
|
||||
%0% could not be published because these properties: %1% did not pass validation rules.
|
||||
<![CDATA[
|
||||
%0% could not be published because these properties: %1% did not pass validation rules.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="contentPublishedFailedByEvent">
|
||||
<![CDATA[
|
||||
%0% could not be published, a 3rd party add-in cancelled the action.
|
||||
<![CDATA[
|
||||
%0% could not be published, a 3rd party add-in cancelled the action.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="contentPublishedFailedByParent">
|
||||
<![CDATA[
|
||||
%0% can not be published, because a parent page is not published.
|
||||
<![CDATA[
|
||||
%0% can not be published, because a parent page is not published.
|
||||
]]>
|
||||
</key>
|
||||
<key alias="includeUnpublished">Include unpublished subpages</key>
|
||||
@@ -1073,13 +1073,31 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="nodePublishAll">%0% and subpages have been published</key>
|
||||
<key alias="publishAll">Publish %0% and all its subpages</key>
|
||||
<key alias="publishHelp">
|
||||
<![CDATA[Click <em>Publish</em> to publish <strong>%0%</strong> and thereby making its content publicly available.<br/><br />
|
||||
You can publish this page and all its subpages by checking <em>Include unpublished subpages</em> below.
|
||||
<![CDATA[Click <em>Publish</em> to publish <strong>%0%</strong> and thereby making its content publicly available.<br/><br />
|
||||
You can publish this page and all its subpages by checking <em>Include unpublished subpages</em> below.
|
||||
]]>
|
||||
</key>
|
||||
</area>
|
||||
<area alias="colorpicker">
|
||||
<key alias="noColors">You have not configured any approved colours</key>
|
||||
</area>
|
||||
<area alias="contentPicker">
|
||||
<key alias="pickedTrashedItem">You have picked a content item currently deleted or in the recycle bin</key>
|
||||
<key alias="pickedTrashedItems">You have picked content items currently deleted or in the recycle bin</key>
|
||||
</area>
|
||||
<area alias="mediaPicker">
|
||||
<key alias="pickedTrashedItem">You have picked a media item currently deleted or in the recycle bin</key>
|
||||
<key alias="pickedTrashedItems">You have picked media items currently deleted or in the recycle bin</key>
|
||||
<key alias="deletedItem">Deleted item</key>
|
||||
</area>
|
||||
<area alias="contentPicker">
|
||||
<key alias="pickedTrashedItem">You have picked a content item currently deleted or in the recycle bin</key>
|
||||
<key alias="pickedTrashedItems">You have picked content items currently deleted or in the recycle bin</key>
|
||||
</area>
|
||||
<area alias="mediaPicker">
|
||||
<key alias="pickedTrashedItem">You have picked a media item currently deleted or in the recycle bin</key>
|
||||
<key alias="pickedTrashedItems">You have picked media items currently deleted or in the recycle bin</key>
|
||||
<key alias="deletedItem">Deleted item</key>
|
||||
</area>
|
||||
<area alias="relatedlinks">
|
||||
<key alias="enterExternal">enter external link</key>
|
||||
|
||||
@@ -1079,6 +1079,15 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<area alias="colorpicker">
|
||||
<key alias="noColors">You have not configured any approved colors</key>
|
||||
</area>
|
||||
<area alias="contentPicker">
|
||||
<key alias="pickedTrashedItem">You have picked a content item currently deleted or in the recycle bin</key>
|
||||
<key alias="pickedTrashedItems">You have picked content items currently deleted or in the recycle bin</key>
|
||||
</area>
|
||||
<area alias="mediaPicker">
|
||||
<key alias="pickedTrashedItem">You have picked a media item currently deleted or in the recycle bin</key>
|
||||
<key alias="pickedTrashedItems">You have picked media items currently deleted or in the recycle bin</key>
|
||||
<key alias="deletedItem">Deleted item</key>
|
||||
</area>
|
||||
<area alias="relatedlinks">
|
||||
<key alias="enterExternal">enter external link</key>
|
||||
<key alias="chooseInternal">choose internal page</key>
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Web.UI.Umbraco.Dialogs
|
||||
}
|
||||
|
||||
DocumentId = doc.Id;
|
||||
PageName = doc.Name;
|
||||
PageName = Server.HtmlEncode(doc.Name);
|
||||
DocumentPath = doc.Path;
|
||||
|
||||
}
|
||||
|
||||
@@ -643,9 +643,7 @@ namespace Umbraco.Web.Editors
|
||||
ShowMessageForPublishStatus(publishStatus.Result, display);
|
||||
break;
|
||||
}
|
||||
|
||||
UpdatePreviewContext(contentItem.PersistedContent.Id);
|
||||
|
||||
|
||||
//If the item is new and the operation was cancelled, we need to return a different
|
||||
// status code so the UI can handle it since it won't be able to redirect since there
|
||||
// is no Id to redirect to!
|
||||
@@ -875,24 +873,6 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the user is currently in preview mode and if so will update the preview content for this item
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
private void UpdatePreviewContext(int contentId)
|
||||
{
|
||||
var previewId = Request.GetPreviewCookieValue();
|
||||
if (previewId.IsNullOrWhiteSpace()) return;
|
||||
Guid id;
|
||||
if (Guid.TryParse(previewId, out id))
|
||||
{
|
||||
var d = new Document(contentId);
|
||||
var pc = new PreviewContent(UmbracoUser, id, false);
|
||||
pc.PrepareDocument(UmbracoUser, d, true);
|
||||
pc.SavePreviewSet();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps the dto property values to the persisted model
|
||||
/// </summary>
|
||||
|
||||
@@ -599,12 +599,14 @@ namespace Umbraco.Web.Editors
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[EnsureUserPermissionForMedia("folder.ParentId")]
|
||||
public MediaItemDisplay PostAddFolder(EntityBasic folder)
|
||||
|
||||
public MediaItemDisplay PostAddFolder(PostedFolder folder)
|
||||
{
|
||||
var intParentId = GetParentIdAsInt(folder.ParentId, validatePermissions:true);
|
||||
|
||||
var mediaService = ApplicationContext.Services.MediaService;
|
||||
var f = mediaService.CreateMedia(folder.Name, folder.ParentId, Constants.Conventions.MediaTypes.Folder);
|
||||
|
||||
var f = mediaService.CreateMedia(folder.Name, intParentId, Constants.Conventions.MediaTypes.Folder);
|
||||
mediaService.Save(f, Security.CurrentUser.Id);
|
||||
|
||||
return Mapper.Map<IMedia, MediaItemDisplay>(f);
|
||||
@@ -636,66 +638,15 @@ namespace Umbraco.Web.Editors
|
||||
if (result.FileData.Count == 0)
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//get the string json from the request
|
||||
int parentId; bool entityFound; GuidUdi parentUdi;
|
||||
string currentFolderId = result.FormData["currentFolder"];
|
||||
// test for udi
|
||||
if (GuidUdi.TryParse(currentFolderId, out parentUdi))
|
||||
{
|
||||
currentFolderId = parentUdi.Guid.ToString();
|
||||
}
|
||||
|
||||
if (int.TryParse(currentFolderId, out parentId) == false)
|
||||
{
|
||||
// if a guid then try to look up the entity
|
||||
Guid idGuid;
|
||||
if (Guid.TryParse(currentFolderId, out idGuid))
|
||||
{
|
||||
var entity = Services.EntityService.GetByKey(idGuid);
|
||||
if (entity != null)
|
||||
{
|
||||
entityFound = true;
|
||||
parentId = entity.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new EntityNotFoundException(currentFolderId, "The passed id doesn't exist");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Request.CreateValidationErrorResponse("The request was not formatted correctly, the currentFolder is not an integer or Guid");
|
||||
}
|
||||
|
||||
if (entityFound == false)
|
||||
{
|
||||
return Request.CreateValidationErrorResponse("The request was not formatted correctly, the currentFolder is not an integer or Guid");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ensure the user has access to this folder by parent id!
|
||||
if (CheckPermissions(
|
||||
new Dictionary<string, object>(),
|
||||
Security.CurrentUser,
|
||||
Services.MediaService,
|
||||
Services.EntityService,
|
||||
parentId) == false)
|
||||
{
|
||||
return Request.CreateResponse(
|
||||
HttpStatusCode.Forbidden,
|
||||
new SimpleNotificationModel(new Notification(
|
||||
Services.TextService.Localize("speechBubbles/operationFailedHeader"),
|
||||
Services.TextService.Localize("speechBubbles/invalidUserPermissionsText"),
|
||||
SpeechBubbleIcon.Warning)));
|
||||
}
|
||||
|
||||
string currentFolderId = result.FormData["currentFolder"];
|
||||
int parentId = GetParentIdAsInt(currentFolderId, validatePermissions: true);
|
||||
|
||||
var tempFiles = new PostedFiles();
|
||||
var mediaService = ApplicationContext.Services.MediaService;
|
||||
|
||||
|
||||
|
||||
//in case we pass a path with a folder in it, we will create it and upload media to it.
|
||||
if (result.FormData.ContainsKey("path"))
|
||||
{
|
||||
@@ -830,6 +781,69 @@ namespace Umbraco.Web.Editors
|
||||
return Request.CreateResponse(HttpStatusCode.OK, tempFiles);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a parent id which could be a GUID, UDI or an INT, this will resolve the INT
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="validatePermissions">
|
||||
/// If true, this will check if the current user has access to the resolved integer parent id
|
||||
/// and if that check fails an unauthorized exception will occur
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
private int GetParentIdAsInt(string parentId, bool validatePermissions)
|
||||
{
|
||||
int intParentId;
|
||||
GuidUdi parentUdi;
|
||||
|
||||
// test for udi
|
||||
if (GuidUdi.TryParse(parentId, out parentUdi))
|
||||
{
|
||||
parentId = parentUdi.Guid.ToString();
|
||||
}
|
||||
|
||||
//if it's not an INT then we'll check for GUID
|
||||
if (int.TryParse(parentId, out intParentId) == false)
|
||||
{
|
||||
// if a guid then try to look up the entity
|
||||
Guid idGuid;
|
||||
if (Guid.TryParse(parentId, out idGuid))
|
||||
{
|
||||
var entity = Services.EntityService.GetByKey(idGuid);
|
||||
if (entity != null)
|
||||
{
|
||||
intParentId = entity.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new EntityNotFoundException(parentId, "The passed id doesn't exist");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new HttpResponseException(
|
||||
Request.CreateValidationErrorResponse("The request was not formatted correctly, the parentId is not an integer, Guid or UDI"));
|
||||
}
|
||||
}
|
||||
|
||||
//ensure the user has access to this folder by parent id!
|
||||
if (validatePermissions && CheckPermissions(
|
||||
new Dictionary<string, object>(),
|
||||
Security.CurrentUser,
|
||||
Services.MediaService,
|
||||
Services.EntityService,
|
||||
intParentId) == false)
|
||||
{
|
||||
throw new HttpResponseException(Request.CreateResponse(
|
||||
HttpStatusCode.Forbidden,
|
||||
new SimpleNotificationModel(new Notification(
|
||||
Services.TextService.Localize("speechBubbles/operationFailedHeader"),
|
||||
Services.TextService.Localize("speechBubbles/invalidUserPermissionsText"),
|
||||
SpeechBubbleIcon.Warning))));
|
||||
}
|
||||
|
||||
return intParentId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the item can be moved/copied to the new location
|
||||
/// </summary>
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.Validation;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to create a folder with the MediaController
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class PostedFolder
|
||||
{
|
||||
[DataMember(Name = "parentId")]
|
||||
public string ParentId { get; set; }
|
||||
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ using Examine;
|
||||
using Examine.LuceneEngine.Providers;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Mapping;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
@@ -21,7 +20,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
config.CreateMap<UmbracoEntity, EntityBasic>()
|
||||
.ForMember(x => x.Udi, expression => expression.MapFrom(x => Udi.Create(UmbracoObjectTypesExtensions.GetUdiType(x.NodeObjectTypeId), x.Key)))
|
||||
.ForMember(basic => basic.Icon, expression => expression.MapFrom(entity => entity.ContentTypeIcon))
|
||||
.ForMember(dto => dto.Trashed, expression => expression.Ignore())
|
||||
.ForMember(dto => dto.Trashed, expression => expression.MapFrom(x => x.Trashed))
|
||||
.ForMember(x => x.Alias, expression => expression.Ignore())
|
||||
.AfterMap((entity, basic) =>
|
||||
{
|
||||
@@ -98,8 +97,8 @@ namespace Umbraco.Web.Models.Mapping
|
||||
else if (entity.NodeObjectTypeId == Constants.ObjectTypes.TemplateTypeGuid)
|
||||
basic.Icon = "icon-newspaper-alt";
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
config.CreateMap<SearchResult, SearchResultItem>()
|
||||
//default to document icon
|
||||
.ForMember(x => x.Score, expression => expression.MapFrom(result => result.Score))
|
||||
|
||||
@@ -126,8 +126,10 @@ namespace Umbraco.Web.UI
|
||||
{
|
||||
var task = GetTaskForOperation(httpContext, umbracoUser, Operation.Create, nodeType);
|
||||
if (task == null)
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Could not task for operation {0} for node type {1}", Operation.Create, nodeType));
|
||||
{
|
||||
//if no task was found it will use the default task and we cannot validate the application assigned so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
var dialogTask = task as LegacyDialogTask;
|
||||
if (dialogTask != null)
|
||||
@@ -154,8 +156,10 @@ namespace Umbraco.Web.UI
|
||||
{
|
||||
var task = GetTaskForOperation(httpContext, umbracoUser, Operation.Delete, nodeType);
|
||||
if (task == null)
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Could not task for operation {0} for node type {1}", Operation.Delete, nodeType));
|
||||
{
|
||||
//if no task was found it will use the default task and we cannot validate the application assigned so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
var dialogTask = task as LegacyDialogTask;
|
||||
if (dialogTask != null)
|
||||
|
||||
@@ -392,6 +392,7 @@
|
||||
<Compile Include="Models\ContentEditing\MemberTypeSave.cs" />
|
||||
<Compile Include="Models\ContentEditing\Permission.cs" />
|
||||
<Compile Include="Models\ContentEditing\PostedFiles.cs" />
|
||||
<Compile Include="Models\ContentEditing\PostedFolder.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyGroupBasic.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyTypeBasic.cs" />
|
||||
<Compile Include="Models\ContentEditing\SimpleNotificationModel.cs" />
|
||||
|
||||
@@ -46,12 +46,11 @@ namespace Umbraco.Web
|
||||
/// <param name="app"></param>
|
||||
protected virtual void ConfigureMiddleware(IAppBuilder app)
|
||||
{
|
||||
//Ensure owin is configured for Umbraco back office authentication. If you have any front-end OWIN
|
||||
// cookie configuration, this must be declared after it.
|
||||
|
||||
// Configure OWIN for authentication.
|
||||
ConfigureUmbracoAuthentication(app);
|
||||
|
||||
app
|
||||
.UseUmbracoBackOfficeCookieAuthentication(ApplicationContext, PipelineStage.Authenticate)
|
||||
.UseUmbracoBackOfficeExternalCookieAuthentication(ApplicationContext, PipelineStage.Authenticate)
|
||||
.UseUmbracoPreviewAuthentication(ApplicationContext, PipelineStage.Authorize)
|
||||
.UseSignalR()
|
||||
.FinalizeMiddlewareConfiguration();
|
||||
}
|
||||
@@ -68,6 +67,20 @@ namespace Umbraco.Web
|
||||
Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider().AsUmbracoMembershipProvider());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure external/OAuth login providers
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
protected virtual void ConfigureUmbracoAuthentication(IAppBuilder app)
|
||||
{
|
||||
// Ensure owin is configured for Umbraco back office authentication.
|
||||
// Front-end OWIN cookie configuration must be declared after this code.
|
||||
app
|
||||
.UseUmbracoBackOfficeCookieAuthentication(ApplicationContext, PipelineStage.Authenticate)
|
||||
.UseUmbracoBackOfficeExternalCookieAuthentication(ApplicationContext, PipelineStage.Authenticate)
|
||||
.UseUmbracoPreviewAuthentication(ApplicationContext, PipelineStage.Authorize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the middleware has been configured
|
||||
/// </summary>
|
||||
|
||||
@@ -70,10 +70,11 @@ namespace umbraco.presentation.umbraco.dialogs
|
||||
private void import_Click(object sender, EventArgs e)
|
||||
{
|
||||
var xd = new XmlDocument();
|
||||
xd.XmlResolver = null;
|
||||
xd.Load(tempFile.Value);
|
||||
|
||||
var userId = base.getUser().Id;
|
||||
|
||||
|
||||
var element = XElement.Parse(xd.InnerXml);
|
||||
var importContentTypes = ApplicationContext.Current.Services.PackagingService.ImportContentTypes(element, userId);
|
||||
var contentType = importContentTypes.FirstOrDefault();
|
||||
@@ -104,7 +105,8 @@ namespace umbraco.presentation.umbraco.dialogs
|
||||
documentTypeFile.PostedFile.SaveAs(fileName);
|
||||
|
||||
var xd = new XmlDocument();
|
||||
xd.Load(fileName);
|
||||
xd.XmlResolver = null;
|
||||
xd.Load(fileName);
|
||||
dtName.Text = xd.DocumentElement.SelectSingleNode("//DocumentType/Info/Name").FirstChild.Value;
|
||||
dtAlias.Text = xd.DocumentElement.SelectSingleNode("//DocumentType/Info/Alias").FirstChild.Value;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace umbraco.dialogs
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
Button1.Text = ui.Text("update");
|
||||
pane_form.Text = ui.Text("notifications", "editNotifications", node.Text, base.getUser());
|
||||
pane_form.Text = ui.Text("notifications", "editNotifications", Server.HtmlEncode(node.Text), base.getUser());
|
||||
}
|
||||
|
||||
#region Web Form Designer generated code
|
||||
|
||||
Reference in New Issue
Block a user