diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.controller.js index ea25195ffa..8631b09a45 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.controller.js @@ -73,9 +73,11 @@ } function executeAction(check, index, action) { + check.loading = true; healthCheckResource.executeAction(action) .then(function(response) { check.status[index] = response; + check.loading = false; }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html index ba355c22a2..a50d70211a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/developer/healthcheck.html @@ -82,10 +82,10 @@
- - - - + + + +
@@ -101,7 +101,9 @@
- + + +
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 439cc1aaab..2b5ce44d79 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1352,8 +1352,8 @@ To manage your website, simply open the Umbraco back office and start adding con There was an error, check log for full error: %0%. Total XML: %0%, Total: %1% - Total XML: %0%, Total: %1% - Total XML: %0%, Total published: %1% + Total XML: %0%, Total: %1%, Total invalid %2% + Total XML: %0%, Total published: %1%, Total invalid %2% Certificate validation error: '%0%' Error pinging the URL %0% - '%1%' diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index c2c3417e66..05015116ee 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -1356,8 +1356,8 @@ To manage your website, simply open the Umbraco back office and start adding con There was an error, check log for full error: %0%. Total XML: %0%, Total: %1% - Total XML: %0%, Total: %1% - Total XML: %0%, Total published: %1% + Total XML: %0%, Total: %1%, Total invalid %2% + Total XML: %0%, Total published: %1%, Total invalid %2% Certificate validation error: '%0%' Error pinging the URL %0% - '%1%' diff --git a/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/XmlDataIntegrityHealthCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/XmlDataIntegrityHealthCheck.cs index 5ba16305de..8895e18af9 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/XmlDataIntegrityHealthCheck.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/XmlDataIntegrityHealthCheck.cs @@ -92,46 +92,105 @@ namespace Umbraco.Web.HealthCheck.Checks.DataIntegrity }; } + /// + /// Checks the cmsContentXml table to see if the number of entries for media matches the number of media entities + /// + /// + /// + /// Further to just counting the data integrity, this also checks if the XML stored in the cmsContentXml table contains the correct + /// GUID identifier. In older versions of Umbraco, the GUID is not persisted to the content cache, that will cause problems in newer + /// versions of Umbraco, so the xml table would need a rebuild. + /// private HealthCheckStatus CheckMedia() { var total = _services.MediaService.Count(); var mediaObjectType = Guid.Parse(Constants.ObjectTypes.Media); - var subQuery = new Sql() + + //count entries + var countTotalSubQuery = new Sql() .Select("Count(*)") .From(_sqlSyntax) .InnerJoin(_sqlSyntax) .On(_sqlSyntax, left => left.NodeId, right => right.NodeId) .Where(dto => dto.NodeObjectType == mediaObjectType); - var totalXml = _database.ExecuteScalar(subQuery); + var totalXml = _database.ExecuteScalar(countTotalSubQuery); + //count invalid entries + var countNonGuidQuery = new Sql() + .Select("Count(*)") + .From(_sqlSyntax) + .InnerJoin(_sqlSyntax) + .On(_sqlSyntax, left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == mediaObjectType) + .Where(string.Format("cmsContentXml.{0} NOT LIKE '% key=\"%'", _sqlSyntax.GetQuotedColumnName("xml"))); + var totalNonGuidXml = _database.ExecuteScalar(countNonGuidQuery); + + var hasError = false; var actions = new List(); - if (totalXml != total) - actions.Add(new HealthCheckAction(CheckMediaXmlTableAction, Id)); - - return new HealthCheckStatus(_textService.Localize("healthcheck/xmlDataIntegrityCheckMedia", new[] { totalXml.ToString(), total.ToString() })) + if (totalXml != total || totalNonGuidXml > 0) { - ResultType = totalXml == total ? StatusResultType.Success : StatusResultType.Error, + //if the counts don't match + actions.Add(new HealthCheckAction(CheckMediaXmlTableAction, Id)); + hasError = true; + } + + return new HealthCheckStatus(_textService.Localize("healthcheck/xmlDataIntegrityCheckMedia", + new[] { totalXml.ToString(), total.ToString(), totalNonGuidXml.ToString() })) + { + ResultType = hasError == false + ? StatusResultType.Success + : StatusResultType.Error, Actions = actions }; } + /// + /// Checks the cmsContentXml table to see if the number of entries for content matches the number of published content entities + /// + /// + /// + /// Further to just counting the data integrity, this also checks if the XML stored in the cmsContentXml table contains the correct + /// GUID identifier. In older versions of Umbraco, the GUID is not persisted to the content cache, that will cause problems in newer + /// versions of Umbraco, so the xml table would need a rebuild. + /// private HealthCheckStatus CheckContent() { var total = _services.ContentService.CountPublished(); - var subQuery = new Sql() + var documentObjectType = Guid.Parse(Constants.ObjectTypes.Document); + + //count entires + var countTotalSubQuery = new Sql() .Select("DISTINCT cmsContentXml.nodeId") .From(_sqlSyntax) .InnerJoin(_sqlSyntax) .On(_sqlSyntax, left => left.NodeId, right => right.NodeId); - var totalXml = _database.ExecuteScalar("SELECT COUNT(*) FROM (" + subQuery.SQL + ") as tmp"); + var totalXml = _database.ExecuteScalar("SELECT COUNT(*) FROM (" + countTotalSubQuery.SQL + ") as tmp"); + + //count invalid entries + var countNonGuidQuery = new Sql() + .Select("Count(*)") + .From(_sqlSyntax) + .InnerJoin(_sqlSyntax) + .On(_sqlSyntax, left => left.NodeId, right => right.NodeId) + .Where(dto => dto.NodeObjectType == documentObjectType) + .Where(string.Format("cmsContentXml.{0} NOT LIKE '% key=\"%'", _sqlSyntax.GetQuotedColumnName("xml"))); + var totalNonGuidXml = _database.ExecuteScalar(countNonGuidQuery); + var hasError = false; var actions = new List(); - if (totalXml != total) - actions.Add(new HealthCheckAction(CheckContentXmlTableAction, Id)); - - return new HealthCheckStatus(_textService.Localize("healthcheck/xmlDataIntegrityCheckContent", new[] { totalXml.ToString(), total.ToString() })) + if (totalXml != total || totalNonGuidXml > 0) { - ResultType = totalXml == total ? StatusResultType.Success : StatusResultType.Error, + //if the counts don't match + actions.Add(new HealthCheckAction(CheckContentXmlTableAction, Id)); + hasError = true; + } + + return new HealthCheckStatus(_textService.Localize("healthcheck/xmlDataIntegrityCheckContent", + new[] { totalXml.ToString(), total.ToString(), totalNonGuidXml.ToString() })) + { + ResultType = hasError == false + ? StatusResultType.Success + : StatusResultType.Error, Actions = actions }; }