<commit_before>using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Web.Http;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
using Language = Our.Umbraco.Vorto.Models.Language;

namespace Our.Umbraco.Vorto.Web.Controllers
{
	[PluginController("VortoApi")]
	public class VortoApiController : UmbracoAuthorizedJsonController
	{
		public IEnumerable<object> GetNonVortoDataTypes()
		{
			return Services.DataTypeService.GetAllDataTypeDefinitions()
				.Where(x => x.PropertyEditorAlias != "Our.Umbraco.Vorto")
				.OrderBy(x => x.SortOrder)
				.Select(x => new
				{
					guid = x.Key,
					name = x.Name,
					propertyEditorAlias = x.PropertyEditorAlias
				});
		}

		public object GetDataTypeById(Guid id)
		{
			var dtd = Services.DataTypeService.GetDataTypeDefinitionById(id);
			return FormatDataType(dtd);
		}

		public object GetDataTypeByAlias(string contentType, string contentTypeAlias, string propertyAlias)
		{
            IContentTypeComposition ct = null;
            
		    switch (contentType)
            {
                case "member":
                    ct = Services.MemberTypeService.Get(contentTypeAlias);
                    break;
                case "content":
                    ct = Services.ContentTypeService.GetContentType(contentTypeAlias);
		            break;
                case "media":
                    ct = Services.ContentTypeService.GetMediaType(contentTypeAlias);
		            break;
		    }

		    if (ct == null)
		        return null;

			var prop = ct.CompositionPropertyTypes.SingleOrDefault(x => x.Alias == propertyAlias);
			if (prop == null)
				return null;

			var dtd = Services.DataTypeService.GetDataTypeDefinitionById(prop.DataTypeDefinitionId);
			return FormatDataType(dtd);
		}

		protected object FormatDataType(IDataTypeDefinition dtd)
		{
			if (dtd == null)
				throw new HttpResponseException(HttpStatusCode.NotFound);

			var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);

			// Force converter before passing prevalues to view
			var preValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id);
			var convertedPreValues = propEditor.PreValueEditor.ConvertDbToEditor(propEditor.DefaultPreValues,
				preValues);

			return new
			{
				guid = dtd.Key,
				propertyEditorAlias = dtd.PropertyEditorAlias,
				preValues = convertedPreValues,
				view = propEditor.ValueEditor.View
			};
		}

        public IEnumerable<object> GetLanguages(string section, int id, int parentId, Guid dtdGuid)
		{
            var dtd = Services.DataTypeService.GetDataTypeDefinitionById(dtdGuid);
		    if (dtd == null) return Enumerable.Empty<object>();

			var preValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id).PreValuesAsDictionary;
			var languageSource = preValues.ContainsKey("languageSource") ? preValues["languageSource"].Value : "";
			var primaryLanguage = preValues.ContainsKey("primaryLanguage") ? preValues["primaryLanguage"].Value : "";

			var languages = new List<Language>();

			if (languageSource == "inuse")
			{
				var xpath = preValues.ContainsKey("xpath") ? preValues["xpath"].Value : "";

				// Grab languages by xpath (only if in content section)
                if (!string.IsNullOrWhiteSpace(xpath) && section == "content")
				{
					xpath = xpath.Replace("$currentPage",
						string.Format("//*[@id={0} and @isDoc]", id)).Replace("$parentPage",
							string.Format("//*[@id={0} and @isDoc]", parentId)).Replace("$ancestorOrSelf",
								string.Format("//*[@id={0} and @isDoc]", id != 0 ? id : parentId));

					// Lookup language nodes
					var nodeIds = uQuery.GetNodesByXPath(xpath).Select(x => x.Id).ToArray();
					if (nodeIds.Any())
					{
						var db = ApplicationContext.Current.DatabaseContext.Database;
						languages.AddRange(db.Query<string>(
							string.Format(
								"SELECT DISTINCT [languageISOCode] FROM [umbracoLanguage] JOIN [umbracoDomains] ON [umbracoDomains].[domainDefaultLanguage] = [umbracoLanguage].[id] WHERE [umbracoDomains].[domainRootStructureID] in ({0})",
								string.Join(",", nodeIds)))
							.Select(CultureInfo.GetCultureInfo)
							.Select(x => new Language
							{
								IsoCode = x.Name,
								Name = x.DisplayName,
								NativeName = x.NativeName,
                                IsRightToLeft = x.TextInfo.IsRightToLeft
							}));
					}
				}
				else
				{<commit_msg>Fix issue accessing in-use, XPath defined languages on unpublished nodes<commit_after>using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Web.Http;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
using Language = Our.Umbraco.Vorto.Models.Language;

namespace Our.Umbraco.Vorto.Web.Controllers
{
	[PluginController("VortoApi")]
	public class VortoApiController : UmbracoAuthorizedJsonController
	{
		public IEnumerable<object> GetNonVortoDataTypes()
		{
			return Services.DataTypeService.GetAllDataTypeDefinitions()
				.Where(x => x.PropertyEditorAlias != "Our.Umbraco.Vorto")
				.OrderBy(x => x.SortOrder)
				.Select(x => new
				{
					guid = x.Key,
					name = x.Name,
					propertyEditorAlias = x.PropertyEditorAlias
				});
		}

		public object GetDataTypeById(Guid id)
		{
			var dtd = Services.DataTypeService.GetDataTypeDefinitionById(id);
			return FormatDataType(dtd);
		}

		public object GetDataTypeByAlias(string contentType, string contentTypeAlias, string propertyAlias)
		{
            IContentTypeComposition ct = null;
            
		    switch (contentType)
            {
                case "member":
                    ct = Services.MemberTypeService.Get(contentTypeAlias);
                    break;
                case "content":
                    ct = Services.ContentTypeService.GetContentType(contentTypeAlias);
		            break;
                case "media":
                    ct = Services.ContentTypeService.GetMediaType(contentTypeAlias);
		            break;
		    }

		    if (ct == null)
		        return null;

			var prop = ct.CompositionPropertyTypes.SingleOrDefault(x => x.Alias == propertyAlias);
			if (prop == null)
				return null;

			var dtd = Services.DataTypeService.GetDataTypeDefinitionById(prop.DataTypeDefinitionId);
			return FormatDataType(dtd);
		}

		protected object FormatDataType(IDataTypeDefinition dtd)
		{
			if (dtd == null)
				throw new HttpResponseException(HttpStatusCode.NotFound);

			var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);

			// Force converter before passing prevalues to view
			var preValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id);
			var convertedPreValues = propEditor.PreValueEditor.ConvertDbToEditor(propEditor.DefaultPreValues,
				preValues);

			return new
			{
				guid = dtd.Key,
				propertyEditorAlias = dtd.PropertyEditorAlias,
				preValues = convertedPreValues,
				view = propEditor.ValueEditor.View
			};
		}

        public IEnumerable<object> GetLanguages(string section, int id, int parentId, Guid dtdGuid)
		{
            var dtd = Services.DataTypeService.GetDataTypeDefinitionById(dtdGuid);
		    if (dtd == null) return Enumerable.Empty<object>();

			var preValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id).PreValuesAsDictionary;
			var languageSource = preValues.ContainsKey("languageSource") ? preValues["languageSource"].Value : "";
			var primaryLanguage = preValues.ContainsKey("primaryLanguage") ? preValues["primaryLanguage"].Value : "";

			var languages = new List<Language>();

			if (languageSource == "inuse")
			{
                var currentNode = id != 0 ? ApplicationContext.Services.ContentService.GetById(id) : null;

                //trying to add/publish a home node, so no "in use" languages have been defined/are accessible - display all installed in the interim
                var canAccessInUseLanguages = (currentNode == null || !currentNode.Published) && parentId == -1;

                var xpath = preValues.ContainsKey("xpath") ? preValues["xpath"].Value : "";

                // Grab languages by xpath (only if in content section)
                if (canAccessInUseLanguages && !string.IsNullOrWhiteSpace(xpath) && section == "content")
                {
                    xpath = xpath.Replace("$currentPage",
                        string.Format("//*[@id={0} and @isDoc]", id)).Replace("$parentPage",
                            string.Format("//*[@id={0} and @isDoc]", parentId)).Replace("$ancestorOrSelf",
                                string.Format("//*[@id={0} and @isDoc]", currentNode != null && currentNode.Published ? id : parentId));

                    // Lookup language nodes
                    var nodeIds = uQuery.GetNodesByXPath(xpath).Select(x => x.Id).ToArray();
                    if (nodeIds.Any())
                    {
                        var db = ApplicationContext.Current.DatabaseContext.Database;
                        languages.AddRange(db.Query<string>(
                            string.Format(
                                "SELECT DISTINCT [languageISOCode] FROM [umbracoLanguage] JOIN [umbracoDomains] ON [umbracoDomains].[domainDefaultLanguage] = [umbracoLanguage].[id] WHERE [umbracoDomains].[domainRootStructureID] in ({0})",
                                string.Join(",", nodeIds)))
                            .Select(CultureInfo.GetCultureInfo)
                            .Select(x => new Language
                            {
                                IsoCode = x.Name,
                                Name = x.DisplayName,
                                NativeName = x.NativeName,
                                IsRightToLeft = x.TextInfo.IsRightToLeft
                            }));
                    }
                }
                else
				{
{'fraction_non_alphanumeric': 0.1059726458722818, 'fraction_numerical': 0.001082357571583194, 'mean_word_length': 2.648241206030151, 'pattern_counts': {'":': 6, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '826064', 'n_tokens_mistral': 3232, 'n_tokens_neox': 2785, 'n_words': 567}