kreta/Kreta.Core/Extensions.cs
2024-03-13 00:33:46 +01:00

350 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Kreta.Core.CustomAttributes;
namespace Kreta.Core
{
/// <summary>
/// Extension
/// </summary>
public static class Extensions
{
#region Convert Extensions
/// <summary>
/// Converts to a bool? value to int
/// </summary>
/// <param name="origin">The origin.</param>
/// <returns></returns>
public static int ToNullableInt(this bool? origin) => origin == true ? 1 : 0;
/// <summary>
/// Converts to a bool value to int
/// </summary>
/// <param name="origin">if set to <c>true</c> [origin].</param>
/// <returns></returns>
public static int ToNullableInt(this bool origin) => origin ? 1 : 0;
/// <summary>
/// Converts to a bool? value to int
/// </summary>
/// <param name="origin">The origin.</param>
/// <returns></returns>
public static int ToBit(this bool? origin) => origin.ToNullableInt();
/// <summary>
/// Converts to a bool value to int
/// </summary>
/// <param name="origin">if set to <c>true</c> [origin].</param>
/// <returns></returns>
public static int ToBit(this bool origin) => origin.ToNullableInt();
/// <summary>
/// Converts to a int? value to bool
/// </summary>
/// <param name="origin">The origin.</param>
/// <returns></returns>
public static bool ToBool(this int? origin) => origin == 1;
/// <summary>
/// Converts to a string value to bool
/// </summary>
/// <param name="origin">The origin.</param>
/// <returns></returns>
public static bool ToBool(this string origin) => string.Equals(origin, "T", StringComparison.OrdinalIgnoreCase) || string.Equals(origin, "TRUE", StringComparison.OrdinalIgnoreCase);
/// <summary>
/// Determines whether [is not null and positive] [the specified value].
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static bool IsNotNullAndPositive(this int? value)
{
return value.HasValue && 0 < value;
}
/// <summary>
/// Determines whether [is not null and positive] [the specified value].
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static bool IsNotNullAndPositive(this int value)
{
return 0 < value;
}
/// <summary>
/// Megvizsgálja, hogy az int? lehetséges EntityId-e (nem null és nagyobb mint 0)
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static bool IsEntityId(this int? value)
{
return value.IsNotNullAndPositive();
}
/// <summary>
/// Megvizsgálja, hogy az int lehetséges EntityId-e (nagyobb mint 0)
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static bool IsEntityId(this int value)
{
return 0 < value;
}
public static int? ToNullableInt(this string stringValue)
{
if (int.TryParse(stringValue, out int intValue))
{
return intValue;
}
return null;
}
/// <summary>
/// Converts to a bool? value to bool
/// </summary>
/// <param name="value">The origin.</param>
/// <returns>False when it is null</returns>
public static bool ToBool(this bool? value)
{
return value ?? false;
}
public static string ToSDABoolean(this bool value) => value ? "T" : "F";
public static bool? ToNullableBoolean(this int? value) => value.HasValue ? (value.Value == 1) : (bool?)null;
#endregion
#region Validation Extensions
public static bool IsValidEmail(this string value)
{
//NOTE: A null-t és az üres string-et is validnak vesszük, ha azt szeretnénk, hogy ezek ne legyenek validok, azokat külön kint kell vizsgálni string.IsNullOrWhiteSpace()-vel!
bool result = new EmailAddressExtendedAttribute(true, true).IsValid(value);
return result;
}
public static bool IsValidPhone(this string value)
{
//NOTE: A null-t és az üres string-et is validnak vesszük, ha azt szeretnénk, hogy ezek ne legyenek validok, azokat külön kint kell vizsgálni string.IsNullOrWhiteSpace()-vel!
bool result = new PhoneExtendedAttribute(true, true).IsValid(value);
return result;
}
public static bool Is18EvesElmult(this DateTime szuletesiIdo)
{
bool result = szuletesiIdo.Date.AddYears(18) < DateTime.Today;
return result;
}
#endregion
#region String Extensions
public static string Truncate(this string value, int maxChars)
{
return value.Length <= maxChars ? value : value.Substring(0, maxChars - 3) + "...";
}
public static string RemoveDiacritics(this string text)
{
if (string.IsNullOrWhiteSpace(text))
{
return text;
}
text = text.Normalize(NormalizationForm.FormD);
var chars = text
.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
.ToArray();
return new string(chars).Normalize(NormalizationForm.FormC);
}
public static string ReplaceMultipleSpacesAndTrim(this string text, string defaultValue = null)
{
if (string.IsNullOrWhiteSpace(text))
{
return defaultValue;
}
//NOTE: "\u00A0" = NO-BREAK SPACE
// "\u0009" = CHARACTER TABULATION
// "\u0020" = SPACE
// Replace-elni kell a NO-BREAK SPACE-eket, mert a SPACE-el nem ekvivalens és jöhet be ilyen adat és okozhat problémát.
// Replace-elni kell a CHARACTER TABULATION-öket, mert a SPACE-el nem ekvivalens és jöhet be ilyen adat és okozhat problémát.
// Ezt követően replace-eljük a többszörös szóközöket egyre.
// Ezt követően trim-elünk.
string result = Regex.Replace(text.Replace("\u00A0", "\u0020").Replace("\u0009", "\u0020"), @"\s+", " ").Trim();
if (string.IsNullOrWhiteSpace(result))
{
return defaultValue;
}
return result;
}
public static string RemoveSpecialCharacters(this string text)
=> Regex.Replace(text, @"[ \-'`~!@#$%^&*()_|+=?;:"",.<>{ }[\]\\/]", "");
#endregion
#region Collection Extensions
public static int GetSequenceHashCode<T>(this IReadOnlyCollection<T> sequence)
{
if (sequence == null || sequence.Count == 0)
{
return 0;
}
return sequence.Select(item => item.GetHashCode()).Aggregate((total, nextCode) => total ^ nextCode);
}
public static void RemoveRange<T>(this List<T> self, IEnumerable<T> items)
{
var exceptItems = self.Except(items).ToList();
self.Clear();
self.AddRange(exceptItems);
}
public static bool NotNullAndAny<T>(this IEnumerable<T> enumerable)
{
return enumerable != null && enumerable.Any();
}
/// <summary>
/// A generikus objektumlistában sorba rendezzük az adatokat és beállítjuk a lapozást a bejövő paraméterek alapján reflection-el.
/// </summary>
/// <typeparam name="T">A T bármilyen típus lehet.</typeparam>
/// <param name="itemList">A T típusú objektumlista, amivel dolgozunk. Ha ez az érték null, akkor null-al térünk vissza, hogy ne legyen exception.</param>
/// <param name="orderDictionary">A dictionary, amiben benne van, hogy mely property-k(Key) alapján és milyen irányba(Value) kell rendezni az adatokat. Ha ez az érték null vagy üres, akkor nincs sorbarendezés, hanem az eredeti sorrenddel dolgozunk tovább.</param>
/// <param name="firstItemIndex">A lapozáshoz az első elem indexe. Ha ez az érték null, akkor nincs lapozás és visszaadunk minden elemet.</param>
/// <param name="lastItemIndex">A lapozáshoz az utolsó elem indexe. Ha ez az érték null, akkor nincs lapozás és visszaadunk minden elemet.</param>
/// <returns></returns>
public static List<T> SortingAndPaging<T>(this IEnumerable<T> itemList, Dictionary<string, ListSortDirection> orderDictionary = null, int? firstItemIndex = null, int? lastItemIndex = null)
{
if (itemList == null)
{
return null;
}
List<T> result;
if (orderDictionary != null && orderDictionary.Count > 0)
{
IOrderedEnumerable<T> orderedList = null;
bool isOrderBy = true;
foreach (var orderItem in orderDictionary)
{
PropertyInfo propInfo = typeof(T).GetProperty(orderItem.Key);
if (isOrderBy)
{
orderedList = orderItem.Value == ListSortDirection.Ascending ?
itemList.OrderBy(x => propInfo.GetValue(x, null)) :
itemList.OrderByDescending(x => propInfo.GetValue(x, null));
isOrderBy = false;
}
else
{
orderedList = orderItem.Value == ListSortDirection.Ascending ?
orderedList.ThenBy(x => propInfo.GetValue(x, null)) :
orderedList.ThenByDescending(x => propInfo.GetValue(x, null));
}
}
result = orderedList.ToList();
}
else
{
result = itemList.ToList();
}
if (firstItemIndex.HasValue && lastItemIndex.HasValue)
{
if (firstItemIndex <= lastItemIndex)
{
int pageSize = lastItemIndex.Value - firstItemIndex.Value + 1;
if (pageSize < result.Count)
{
result = result.Skip(firstItemIndex.Value).Take(pageSize).ToList();
}
}
}
return result;
}
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var keys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (keys.Add(keySelector(element)))
{
yield return element;
}
}
}
public static IEnumerable<T> Difference<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
return first.Except(second).Union(second.Except(first));
}
public static void RemoveDictionaryItemByValue(this Dictionary<string, string> self, string value)
{
var valuesList = self.Where(s => s.Value == value).ToList();
valuesList.ForEach(i => self.Remove(i.Key));
}
#endregion
#region Enumeration Extensions
/// <summary>
/// GetAttribute by Type
/// </summary>
/// <typeparam name="T">type of attribute</typeparam>
/// <returns>type of Attribute</returns>
public static T GetAttribute<T>(this System.Enum value) where T : Attribute
{
return (T)value.GetType()
.GetMember(value.ToString())[0].GetCustomAttributes(typeof(T), false)
.FirstOrDefault();
}
/// <summary>
///Get Display Name Attribute
/// </summary>
/// <example> [Display(Name = "xy")]</example>
/// <returns>xy</returns>
public static string ToDisplayName(this System.Enum value) => value.GetAttribute<DisplayAttribute>()?.Name;
#endregion
#region DateTimeExtensions
public static DateTime StartOfTheDay(this DateTime dateTime)
{
return dateTime.Date;
}
public static DateTime EndOfTheDay(this DateTime dateTime)
{
return dateTime.Date.AddDays(1).AddTicks(-1);
}
#endregion DateTimeExtensions
}
}