2024-08-21 10:09:17 -04:00
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
2024-08-21 06:17:23 -04:00
using System.Globalization ;
2024-08-21 10:09:17 -04:00
using System.Linq ;
2024-08-21 06:17:23 -04:00
using System.Net ;
using System.Text.RegularExpressions ;
using Nop.Core.Infrastructure ;
2024-08-21 10:09:17 -04:00
namespace Nop.Core
2024-08-21 06:17:23 -04:00
{
2024-08-21 10:09:17 -04:00
/// <summary>
/// Represents a common helper
/// </summary>
public partial class CommonHelper
{
#region Fields
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
//we use EmailValidator from FluentValidation. So let's keep them sync - https://github.com/JeremySkinner/FluentValidation/blob/master/src/FluentValidation/Validators/EmailValidator.cs
private const string EMAIL_EXPRESSION = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-||_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+([a-z]+|\d|-|\.{0,1}|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])?([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$" ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
private static readonly Regex _emailRegex ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
#endregion
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
#region Ctor
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
static CommonHelper ( )
2024-08-21 06:17:23 -04:00
{
2024-08-21 10:09:17 -04:00
_emailRegex = new Regex ( EMAIL_EXPRESSION , RegexOptions . IgnoreCase ) ;
2024-08-21 06:17:23 -04:00
}
2024-08-21 10:09:17 -04:00
#endregion
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
#region Methods
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Ensures the subscriber email or throw.
/// </summary>
/// <param name="email">The email.</param>
/// <returns></returns>
public static string EnsureSubscriberEmailOrThrow ( string email )
{
var output = EnsureNotNull ( email ) ;
output = output . Trim ( ) ;
output = EnsureMaximumLength ( output , 255 ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
if ( ! IsValidEmail ( output ) )
{
throw new NopException ( "Email is not valid." ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
return output ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Verifies that a string is in valid e-mail format
/// </summary>
/// <param name="email">Email to verify</param>
/// <returns>true if the string is a valid e-mail address and false if it's not</returns>
public static bool IsValidEmail ( string email )
{
if ( string . IsNullOrEmpty ( email ) )
return false ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
email = email . Trim ( ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
return _emailRegex . IsMatch ( email ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Verifies that string is an valid IP-Address
/// </summary>
/// <param name="ipAddress">IPAddress to verify</param>
/// <returns>true if the string is a valid IpAddress and false if it's not</returns>
public static bool IsValidIpAddress ( string ipAddress )
{
return IPAddress . TryParse ( ipAddress , out var _ ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Generate random digit code
/// </summary>
/// <param name="length">Length</param>
/// <returns>Result string</returns>
public static string GenerateRandomDigitCode ( int length )
{
using var random = new SecureRandomNumberGenerator ( ) ;
var str = string . Empty ;
for ( var i = 0 ; i < length ; i + + )
str = string . Concat ( str , random . Next ( 10 ) . ToString ( ) ) ;
return str ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Returns an random integer number within a specified rage
/// </summary>
/// <param name="min">Minimum number</param>
/// <param name="max">Maximum number</param>
/// <returns>Result</returns>
public static int GenerateRandomInteger ( int min = 0 , int max = int . MaxValue )
2024-08-21 06:17:23 -04:00
{
2024-08-21 10:09:17 -04:00
using var random = new SecureRandomNumberGenerator ( ) ;
return random . Next ( min , max ) ;
2024-08-21 06:17:23 -04:00
}
2024-08-21 10:09:17 -04:00
/// <summary>
/// Ensure that a string doesn't exceed maximum allowed length
/// </summary>
/// <param name="str">Input string</param>
/// <param name="maxLength">Maximum length</param>
/// <param name="postfix">A string to add to the end if the original string was shorten</param>
/// <returns>Input string if its length is OK; otherwise, truncated input string</returns>
public static string EnsureMaximumLength ( string str , int maxLength , string postfix = null )
{
if ( string . IsNullOrEmpty ( str ) )
return str ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
if ( str . Length < = maxLength )
return str ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
var pLen = postfix ? . Length ? ? 0 ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
var result = str [ 0. . ( maxLength - pLen ) ] ;
if ( ! string . IsNullOrEmpty ( postfix ) )
{
result + = postfix ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
return result ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Ensures that a string only contains numeric values
/// </summary>
/// <param name="str">Input string</param>
/// <returns>Input string with only numeric values, empty string if input is null/empty</returns>
public static string EnsureNumericOnly ( string str )
{
return string . IsNullOrEmpty ( str ) ? string . Empty : new string ( str . Where ( char . IsDigit ) . ToArray ( ) ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Ensure that a string is not null
/// </summary>
/// <param name="str">Input string</param>
/// <returns>Result</returns>
public static string EnsureNotNull ( string str )
{
return str ? ? string . Empty ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Indicates whether the specified strings are null or empty strings
/// </summary>
/// <param name="stringsToValidate">Array of strings to validate</param>
/// <returns>Boolean</returns>
public static bool AreNullOrEmpty ( params string [ ] stringsToValidate )
{
return stringsToValidate . Any ( string . IsNullOrEmpty ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Compare two arrays
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="a1">Array 1</param>
/// <param name="a2">Array 2</param>
/// <returns>Result</returns>
public static bool ArraysEqual < T > ( T [ ] a1 , T [ ] a2 )
{
//also see Enumerable.SequenceEqual(a1, a2);
if ( ReferenceEquals ( a1 , a2 ) )
return true ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
if ( a1 = = null | | a2 = = null )
return false ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
if ( a1 . Length ! = a2 . Length )
return false ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
var comparer = EqualityComparer < T > . Default ;
return ! a1 . Where ( ( t , i ) = > ! comparer . Equals ( t , a2 [ i ] ) ) . Any ( ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Sets a property on an object to a value.
/// </summary>
/// <param name="instance">The object whose property to set.</param>
/// <param name="propertyName">The name of the property to set.</param>
/// <param name="value">The value to set the property to.</param>
public static void SetProperty ( object instance , string propertyName , object value )
{
if ( instance = = null )
throw new ArgumentNullException ( nameof ( instance ) ) ;
if ( propertyName = = null )
throw new ArgumentNullException ( nameof ( propertyName ) ) ;
var instanceType = instance . GetType ( ) ;
var pi = instanceType . GetProperty ( propertyName ) ;
if ( pi = = null )
throw new NopException ( "No property '{0}' found on the instance of type '{1}'." , propertyName , instanceType ) ;
if ( ! pi . CanWrite )
throw new NopException ( "The property '{0}' on the instance of type '{1}' does not have a setter." , propertyName , instanceType ) ;
if ( value ! = null & & ! value . GetType ( ) . IsAssignableFrom ( pi . PropertyType ) )
value = To ( value , pi . PropertyType ) ;
pi . SetValue ( instance , value , Array . Empty < object > ( ) ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Converts a value to a destination type.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <param name="destinationType">The type to convert the value to.</param>
/// <returns>The converted value.</returns>
public static object To ( object value , Type destinationType )
{
return To ( value , destinationType , CultureInfo . InvariantCulture ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Converts a value to a destination type.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <param name="destinationType">The type to convert the value to.</param>
/// <param name="culture">Culture</param>
/// <returns>The converted value.</returns>
public static object To ( object value , Type destinationType , CultureInfo culture )
{
if ( value = = null )
return null ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
var sourceType = value . GetType ( ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
var destinationConverter = TypeDescriptor . GetConverter ( destinationType ) ;
if ( destinationConverter . CanConvertFrom ( value . GetType ( ) ) )
return destinationConverter . ConvertFrom ( null , culture , value ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
var sourceConverter = TypeDescriptor . GetConverter ( sourceType ) ;
if ( sourceConverter . CanConvertTo ( destinationType ) )
return sourceConverter . ConvertTo ( null , culture , value , destinationType ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
if ( destinationType . IsEnum & & value is int )
return Enum . ToObject ( destinationType , ( int ) value ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
if ( ! destinationType . IsInstanceOfType ( value ) )
return Convert . ChangeType ( value , destinationType , culture ) ;
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
return value ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Converts a value to a destination type.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <typeparam name="T">The type to convert the value to.</typeparam>
/// <returns>The converted value.</returns>
public static T To < T > ( object value )
{
//return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
return ( T ) To ( value , typeof ( T ) ) ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Convert enum for front-end
/// </summary>
/// <param name="str">Input string</param>
/// <returns>Converted string</returns>
public static string ConvertEnum ( string str )
{
if ( string . IsNullOrEmpty ( str ) )
return string . Empty ;
var result = string . Empty ;
foreach ( var c in str )
if ( c . ToString ( ) ! = c . ToString ( ) . ToLowerInvariant ( ) )
result + = " " + c . ToString ( ) ;
else
result + = c . ToString ( ) ;
//ensure no spaces (e.g. when the first letter is upper case)
result = result . TrimStart ( ) ;
return result ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Get difference in years
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public static int GetDifferenceInYears ( DateTime startDate , DateTime endDate )
{
//source: http://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-in-c
//this assumes you are looking for the western idea of age and not using East Asian reckoning.
var age = endDate . Year - startDate . Year ;
if ( startDate > endDate . AddYears ( - age ) )
age - - ;
return age ;
}
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Get DateTime to the specified year, month, and day using the conventions of the current thread culture
/// </summary>
/// <param name="year">The year</param>
/// <param name="month">The month</param>
/// <param name="day">The day</param>
/// <returns>An instance of the Nullable<System.DateTime></returns>
public static DateTime ? ParseDate ( int? year , int? month , int? day )
2024-08-21 06:17:23 -04:00
{
2024-08-21 10:09:17 -04:00
if ( ! year . HasValue | | ! month . HasValue | | ! day . HasValue )
return null ;
DateTime ? date = null ;
try
{
date = new DateTime ( year . Value , month . Value , day . Value , CultureInfo . CurrentCulture . Calendar ) ;
}
catch { }
return date ;
2024-08-21 06:17:23 -04:00
}
2024-08-21 10:09:17 -04:00
#endregion
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
#region Properties
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
/// <summary>
/// Gets or sets the default file provider
/// </summary>
public static INopFileProvider DefaultFileProvider { get ; set ; }
2024-08-21 06:17:23 -04:00
2024-08-21 10:09:17 -04:00
#endregion
}
}