diff --git a/OurUmbraco/Repository/Controllers/PackageRepositoryController.cs b/OurUmbraco/Repository/Controllers/PackageRepositoryController.cs
index d05dff3c..615e63e4 100644
--- a/OurUmbraco/Repository/Controllers/PackageRepositoryController.cs
+++ b/OurUmbraco/Repository/Controllers/PackageRepositoryController.cs
@@ -9,6 +9,7 @@ using Umbraco.Core.Cache;
using Umbraco.Web.WebApi;
using System.Net.Http;
using System.Net;
+using Umbraco.Core;
namespace OurUmbraco.Repository.Controllers
{
@@ -87,13 +88,26 @@ namespace OurUmbraco.Repository.Controllers
TimeSpan.FromMinutes(1)); //cache for 1 min
}
- public Models.PackageDetails GetDetails(Guid id)
+ ///
+ /// Returns the package details for the package Id passed in and ensures that
+ /// the resulting ZipUrl is the compatible package for the version passed in.
+ ///
+ ///
+ /// The umbraco version requesting the details, if null than the ZipUrl will be the latest package zip
+ ///
+ public PackageDetails GetDetails(Guid id, string version = null)
{
+ System.Version parsed = null;
+ if (version.IsNullOrWhiteSpace() == false)
+ {
+ System.Version.TryParse(version, out parsed);
+ }
+
//return the results, but cache for 1 minute
- var key = string.Format("PackageRepositoryController.GetDetails.{0}", id);
+ var key = string.Format("PackageRepositoryController.GetDetails.{0}.{1}", id, parsed == null ? string.Empty : parsed.ToString(3));
var package = ApplicationContext.ApplicationCache.RuntimeCache.GetCacheItem
(key,
- () => Service.GetDetails(id),
+ () => Service.GetDetails(id, parsed),
TimeSpan.FromMinutes(1)); //cache for 1 min
if (package == null)
@@ -103,5 +117,7 @@ namespace OurUmbraco.Repository.Controllers
return package;
}
+
+
}
}
\ No newline at end of file
diff --git a/OurUmbraco/Repository/Models/Package.cs b/OurUmbraco/Repository/Models/Package.cs
index f0668a09..a94cfc10 100644
--- a/OurUmbraco/Repository/Models/Package.cs
+++ b/OurUmbraco/Repository/Models/Package.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace OurUmbraco.Repository.Models
{
@@ -27,18 +28,13 @@ namespace OurUmbraco.Repository.Models
public string Category { get; set; }
+ ///
+ /// The latest version of this package
+ ///
public string LatestVersion { get; set; }
public PackageOwnerInfo OwnerInfo { get; set; }
-
- ///
- /// This is the minimum Umbraco version that this package supports
- ///
- ///
- /// This could be null if it is a legacy package
- ///
- public string MinimumVersion { get; set; }
-
+
public long Score { get; set; }
}
}
\ No newline at end of file
diff --git a/OurUmbraco/Repository/Models/PackageDetails.cs b/OurUmbraco/Repository/Models/PackageDetails.cs
index 8f85678e..0d695952 100644
--- a/OurUmbraco/Repository/Models/PackageDetails.cs
+++ b/OurUmbraco/Repository/Models/PackageDetails.cs
@@ -24,7 +24,6 @@ namespace OurUmbraco.Repository.Models
this.Name = package.Name;
this.Icon = package.Icon;
this.LatestVersion = package.LatestVersion;
- this.MinimumVersion = package.MinimumVersion;
this.OwnerInfo = package.OwnerInfo;
}
}
@@ -35,6 +34,11 @@ namespace OurUmbraco.Repository.Models
public List Compatibility { get; set; }
+ ///
+ /// A list of all supported/targeted Umbraco versions for all files for this package
+ ///
+ public List TargetedUmbracoVersions { get; set; }
+
public List ExternalSources { get; set; }
public string LicenseName { get; set; }
diff --git a/OurUmbraco/Repository/Services/PackageRepositoryService.cs b/OurUmbraco/Repository/Services/PackageRepositoryService.cs
index f738fd67..67a33da2 100644
--- a/OurUmbraco/Repository/Services/PackageRepositoryService.cs
+++ b/OurUmbraco/Repository/Services/PackageRepositoryService.cs
@@ -145,7 +145,14 @@ namespace OurUmbraco.Repository.Services
};
}
- public PackageDetails GetDetails(Guid id)
+ ///
+ /// Returns the package details for the package Id passed in and ensures that
+ /// the resulting ZipUrl is the compatible package for the version passed in.
+ ///
+ ///
+ /// The umbraco version requesting the details, if null than the ZipUrl will be the latest package zip
+ ///
+ public PackageDetails GetDetails(Guid id, System.Version version)
{
// [LK:2016-06-13@CGRT16] We're using XPath as we experienced issues with query Examine for GUIDs,
// (it might worth but we were up against the clock).
@@ -156,16 +163,14 @@ namespace OurUmbraco.Repository.Services
if (item == null)
return null;
- return MapContentToPackageDetails(item);
+ return MapContentToPackageDetails(item, version);
}
private Models.Package MapContentToPackage(IPublishedContent content)
{
if (content == null)
return null;
-
- var wikiFiles = WikiFile.CurrentFiles(content.Id);
-
+
return new Models.Package
{
Category = content.Parent.Name,
@@ -177,29 +182,76 @@ namespace OurUmbraco.Repository.Services
Name = content.Name,
Icon = GetThumbnailUrl(BASE_URL + content.GetPropertyValue("defaultScreenshotPath", "/css/img/package2.png"), 154, 281),
LatestVersion = content.GetPropertyValue("version"),
- MinimumVersion = GetMinimumVersion(content.GetPropertyValue("file"), wikiFiles.Where(x => x.FileType.InvariantEquals("package"))),
OwnerInfo = GetPackageOwnerInfo(content.GetPropertyValue("owner"), content.GetPropertyValue("openForCollab", false), content.Id),
Url = string.Concat(BASE_URL, content.Url)
};
}
- private PackageDetails MapContentToPackageDetails(IPublishedContent content)
+ private PackageDetails MapContentToPackageDetails(IPublishedContent content, System.Version currentUmbracoVersion)
{
if (content == null)
return null;
-
+
var package = MapContentToPackage(content);
- var packageDetails = new PackageDetails(package);
+
var wikiFiles = WikiFile.CurrentFiles(content.Id);
- packageDetails.Compatibility = GetPackageCompatibility(content);
- packageDetails.NetVersion = content.GetPropertyValue("dotNetVersion");
- packageDetails.LicenseName = content.GetPropertyValue("licenseName");
- packageDetails.LicenseUrl = content.GetPropertyValue("licenseUrl");
- packageDetails.Description = content.GetPropertyValue("description").CleanHtmlAttributes();
- packageDetails.Images = GetPackageImages(wikiFiles.Where(x => x.FileType.InvariantEquals("screenshot")), 154, 281);
- packageDetails.ExternalSources = GetExternalSources(content);
- packageDetails.ZipUrl = string.Concat(BASE_URL, "/FileDownload?id=", content.GetPropertyValue("file"));
+ //TODO: SD: I dunno where these come from or if we care about it?
+ //var deliCompatVersions = Utils.GetProjectCompatibleVersions(content.Id) ?? new List();
+
+ var allPackageFiles = wikiFiles.Where(x => x.FileType.InvariantEquals("package")).ToArray();
+
+ var strictPackageFileVersions = GetAllStrictSupportedPackageVersions(allPackageFiles).ToArray();
+
+ var packageDetails = new PackageDetails(package)
+ {
+ TargetedUmbracoVersions = GetAllFilePackageVersions(allPackageFiles).Select(x => x.ToString(3)).ToList(),
+ Compatibility = GetPackageCompatibility(content),
+ NetVersion = content.GetPropertyValue("dotNetVersion"),
+ LicenseName = content.GetPropertyValue("licenseName"),
+ LicenseUrl = content.GetPropertyValue("licenseUrl"),
+ Description = content.GetPropertyValue("description").CleanHtmlAttributes(),
+ Images = GetPackageImages(wikiFiles.Where(x => x.FileType.InvariantEquals("screenshot")), 154, 281),
+ ExternalSources = GetExternalSources(content)
+ };
+
+ //if no version or not strict version dependencies, return the current release file
+ if (currentUmbracoVersion == null || strictPackageFileVersions.Length == 0)
+ {
+ var currentReleaseFile = content.GetPropertyValue("file");
+ packageDetails.ZipUrl = string.Concat(BASE_URL, "/FileDownload?id=", currentReleaseFile);
+ }
+ else
+ {
+ //order from latest package version and lastest min umb version and start from the top, we want to return the most recent
+ //available package version for the current Umbraco version
+ var packageVersions = strictPackageFileVersions
+ .OrderByDescending(x => x.Item2)
+ .ThenByDescending(x => x.Item3);
+
+ int found = -1;
+ foreach (var pckVersion in packageVersions)
+ {
+ //if this version will work with the umbraco version, then use it
+ if (pckVersion.Item3 >= currentUmbracoVersion)
+ {
+ found = pckVersion.Item1;
+ break;
+ }
+ }
+
+ if (found != -1)
+ {
+ //got one! so use it's id for the file download
+ packageDetails.ZipUrl = string.Concat(BASE_URL, "/FileDownload?id=", found);
+ }
+ else
+ {
+ //not compatible!
+ return null;
+ }
+ }
+
packageDetails.Created = content.CreateDate;
return packageDetails;
@@ -222,29 +274,71 @@ namespace OurUmbraco.Repository.Services
.ToList();
}
- private string GetMinimumVersion(int filePropertyValue, IEnumerable packages)
+ ///
+ /// Based on all of the files that this package go retrieve all targeted Umbraco versions
+ ///
+ ///
+ ///
+ private IEnumerable GetAllFilePackageVersions(IEnumerable packages)
{
- var currentVersion = filePropertyValue;
- var latest = packages.FirstOrDefault(x => x.Id == currentVersion);
+ var allVersions = packages
+ .Select(x => ConvertToVersion(x.Version.Version))
+ .WhereNotNull()
+ .Distinct()
+ .OrderBy(x => x)
+ .ToArray();
- if (latest == null || string.IsNullOrWhiteSpace(latest.Version.Version) || latest.Version.Version.InvariantEquals("nan"))
- return null;
+ return allVersions;
+ }
- if (latest.Version.Version.InvariantStartsWith("v"))
+ ///
+ /// Based on all of the files that this package go retrieve all targeted Umbraco versions
+ ///
+ ///
+ ///
+ /// A tuple: the file Id, the package version, the min umbraco version
+ ///
+ private IEnumerable> GetAllStrictSupportedPackageVersions(IEnumerable packages)
+ {
+ var allVersions = packages
+ .Where(x => x.MinimumVersionStrict.IsNullOrWhiteSpace() == false)
+ .Select(x => Tuple.Create(x.Id, ConvertToVersion(x.Version.Version), ConvertToVersion(x.MinimumVersionStrict)))
+ .Where(x => x.Item2 != null && x.Item3 != null)
+ .ToArray();
+ return allVersions;
+ }
+
+ ///
+ /// Try to convert the string to a real version based on legacy version formats
+ ///
+ ///
+ ///
+ private System.Version ConvertToVersion(string ver)
+ {
+ string normalized = ver;
+ if (ver.InvariantStartsWith("v"))
{
- var legacyFormat = latest.Version.Version;
-
- if (legacyFormat.InvariantStartsWith("v4"))
+ if (ver.InvariantStartsWith("v4"))
{
- return string.Concat(legacyFormat.Replace("v4", "4."), ".0");
+ normalized = string.Concat(ver.Replace("v4", "4."), ".0");
}
else
{
- return string.Join(".", legacyFormat.ToCharArray().Skip(1));
+ normalized = string.Join(".", ver.ToCharArray().Skip(1));
}
}
- return latest.Version.Version;
+ if (normalized.EndsWith(".x"))
+ {
+ normalized = normalized.TrimEnd(".x").EnsureEndsWith(".0");
+ }
+
+ System.Version result;
+ if (System.Version.TryParse(normalized, out result))
+ {
+ return result;
+ }
+ return null;
}
private PackageOwnerInfo GetPackageOwnerInfo(int ownerId, bool openForCollab, int contentId)