private GoalProperty <string> CreateCustomEventGoalProperty(string propertyName, string value, byte?comparisonOperatorByte) { GoalProperty <string> eventCategoryProperty = null; var valueColumnName = String.Format("Event{0}", propertyName); var operatorColumnName = String.Format("{0}ComparisonOperator", propertyName); if (value != null) { if (comparisonOperatorByte == null) { throw new Exception(String.Format("{0} value cannot be null when {1} value is not null.", operatorColumnName, valueColumnName)); } if (!GoalUtils.IsValidComparisonOperator((byte)comparisonOperatorByte)) { throw new Exception(String.Format("{0} value {1} is outside of range.", operatorColumnName, comparisonOperatorByte)); } var comparisonOperator = (GoalComparisonOperator)comparisonOperatorByte; if (!GoalUtils.IsValidStringOperator(comparisonOperator)) { throw new Exception(String.Format("Comparison operator value {0} is not supported by {1} goal type.", comparisonOperator.ToString(), GoalType)); } eventCategoryProperty = new GoalProperty <string> { ComparisonOperator = comparisonOperator, PropertyValue = value.Trim() }; } return(eventCategoryProperty); }
// Compares two numeric values using the specified operator public static bool CompareNumericProperty <T>(GoalProperty <T> prop, T value) where T : struct, IComparable { var result = false; var compareToResult = value.CompareTo(prop.PropertyValue); switch (prop.ValueComparisionOperator) { case ValueComparisonOperator.GreaterThan: result = (compareToResult == 1); break; case ValueComparisonOperator.LessThan: result = (compareToResult == -1); break; case ValueComparisonOperator.EqualsTo: result = (compareToResult == 0); break; } return(result); }
public TagToGoalRecordDestinationUrl(IReadOnlyDictionary <string, int> columnMetadata, IList <object> row) : base(columnMetadata, row) { GoalType = GoalType.DestinationUrl; if (_destinationUrlOrdinal == -1) { _destinationUrlOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "DestinationURL"); } if (_comparisonOperatorOrdinal == -1) { _comparisonOperatorOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "DestinationURLOperator"); } var destinationUrl = (string)row[_destinationUrlOrdinal]; var comparisonOperatorByte = (byte)row[_comparisonOperatorOrdinal]; if (!GoalUtils.IsValidComparisonOperator(comparisonOperatorByte)) { throw new Exception(String.Format("DestinationUrl comparison operator value {0} is outside of range.", comparisonOperatorByte)); } var comparisonOperator = (GoalComparisonOperator)comparisonOperatorByte; if (!GoalUtils.IsValidStringOperator(comparisonOperator)) { throw new Exception(String.Format("Comparison operator value {0} is not supported by {1} goal type.", comparisonOperator.ToString(), GoalType)); } DestinationUrlProperty = new GoalProperty <string> { ComparisonOperator = comparisonOperator, PropertyValue = destinationUrl.Trim() }; }
public TagToGoalRecordPagesPerVisit(IReadOnlyDictionary <string, int> columnMetadata, IList <object> row) : base(columnMetadata, row) { GoalType = GoalType.PagesPerVisit; if (_numberOfPagesOrdinal == -1) { _numberOfPagesOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "PageVisitGoal"); } if (_comparisonOperatorOrdinal == -1) { _comparisonOperatorOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "PageVisitOperator"); } var numberOfPages = (short)row[_numberOfPagesOrdinal]; var valueOperatorByte = (byte)row[_comparisonOperatorOrdinal]; if (!GoalUtils.IsValidValueOperator(valueOperatorByte)) { throw new Exception(String.Format("NumberOfPages comparison operator value {0} is outside of range.", valueOperatorByte)); } var valueComparisonOperator = (ValueComparisonOperator)valueOperatorByte; if (!GoalUtils.IsValidNumericOperator(valueComparisonOperator)) { throw new Exception(String.Format("Value operator value {0} is not supported by {1} goal type.", valueComparisonOperator.ToString(), GoalType)); } NumberOfPagesProperty = new GoalProperty <short> { ValueComparisionOperator = valueComparisonOperator, PropertyValue = numberOfPages }; }
// Compares two strings using the specified operator public static bool CompareStringProperty(GoalProperty <string> prop, string value, bool compareUrls = false) { if (prop == null || String.IsNullOrWhiteSpace(prop.PropertyValue) || String.IsNullOrWhiteSpace(value)) { return(false); } var propertyValue = prop.PropertyValue; value = value.Trim(); if ((int)prop.ComparisonOperator == 7) { // Hard coded & int casted because we will soon be dropping Conman + rewriting/merging the Operator enums // 7: Operator value denoting "Contains" eg does the destination url contain the given property value return(value.IndexOf(propertyValue, StringComparison.OrdinalIgnoreCase) != -1); } if (prop.ComparisonOperator == GoalComparisonOperator.RegularExpression) { if (!prop.RegexAssigned) { prop.RegexAssigned = true; var strippedPropertyValue = propertyValue.TrimEnd('\\', '/'); if (strippedPropertyValue.StartsWith("*")) { // One common mistake in the customer defined url regular expression is forgetting to add the '.' before '*'. // So ".*thankyou.html" is correct but "*thankyou.html" will throw exception during new Regex operation. strippedPropertyValue = "." + strippedPropertyValue; } else if (strippedPropertyValue.StartsWith("?")) { // One common mistake in the customer defined url regular expression is forgetting to add the '\' before '?'. // So "\?thankyou.html" is correct but "?thankyou.html" will throw exception during new Regex operation. strippedPropertyValue = @"\" + strippedPropertyValue; } if (strippedPropertyValue.Contains(@"\_")) { // Another common mistake in the customer defined url regular expression is that they use '\_' to represent '_', // while in C# _ is not a escape character. strippedPropertyValue = strippedPropertyValue.Replace(@"\_", @"_"); strippedPropertyValue = strippedPropertyValue.Replace(@"\_", @"\\_"); // We are seeing an "\\_" case and should not replace this one. } try { // Original code first try non-trimmed first then trimmed, which is unnecessary. We can try directly the trimmed. prop.Regex = new Regex(strippedPropertyValue, RegexOptions.IgnoreCase, RegexTimeOut); } catch (ArgumentException) { // TODO: UI needs to validate the regex // DebugStream.WriteLine("Failed to parse regex " + propertyValue); return(false); } } if (prop.Regex != null) { try { return(prop.Regex.IsMatch(value)); } catch (RegexMatchTimeoutException) { DebugStream.WriteLine("Timeout occured for " + propertyValue + " when matching " + value); } } return(false); } var result = false; switch (prop.ComparisonOperator) { case GoalComparisonOperator.EqualsTo: result = String.Equals(value, propertyValue, StringComparison.OrdinalIgnoreCase); break; case GoalComparisonOperator.BeginsWith: result = value.StartsWith(propertyValue, StringComparison.OrdinalIgnoreCase); break; } if (!result && compareUrls) { // If the original strings do not match, try matching pure URLs (without http or www) var strippedPropertyValue = StripHeaders(propertyValue.TrimEnd('/')); var strippedValue = StripHeaders(value.TrimEnd('/')); switch (prop.ComparisonOperator) { case GoalComparisonOperator.EqualsTo: result = String.Equals(strippedValue, strippedPropertyValue, StringComparison.OrdinalIgnoreCase); break; case GoalComparisonOperator.BeginsWith: result = strippedValue.StartsWith(strippedPropertyValue, StringComparison.OrdinalIgnoreCase); break; } } return(result); }
public TagToGoalRecordCustomEvent(Dictionary <string, int> columnMetadata, object[] row) : base(columnMetadata, row) { GoalType = GoalType.CustomEvent; if (_eventCategoryOrdinal == -1) { _eventCategoryOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventCategory"); } if (_categoryComparisonOperatorOrdinal == -1) { _categoryComparisonOperatorOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventCategoryOperator"); } if (_eventNameOrdinal == -1) { _eventNameOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventName"); } if (_nameComparisonOperatorOrdinal == -1) { _nameComparisonOperatorOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventNameOperator"); } if (_eventLabelOrdinal == -1) { _eventLabelOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventLabel"); } if (_labelComparisonOperatorOrdinal == -1) { _labelComparisonOperatorOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventLabelOperator"); } if (_eventValueOrdinal == -1) { _eventValueOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventValue"); } if (_valueComparisonOperatorOrdinal == -1) { _valueComparisonOperatorOrdinal = MapFileUtils.GetColumnOrdinal(columnMetadata, "EventValueOperator"); } var eventCategory = (string)row[_eventCategoryOrdinal]; var categoryComparisonOperatorByte = (byte?)row[_categoryComparisonOperatorOrdinal]; EventCategoryProperty = CreateCustomEventGoalProperty("Category", eventCategory, categoryComparisonOperatorByte); var eventName = (string)row[_eventNameOrdinal]; var nameComparisonOperatorByte = (byte?)row[_nameComparisonOperatorOrdinal]; EventActionProperty = CreateCustomEventGoalProperty("Name", eventName, nameComparisonOperatorByte); var eventLabel = (string)row[_eventLabelOrdinal]; var labelComparisonOperatorByte = (byte?)row[_labelComparisonOperatorOrdinal]; EventLabelProperty = CreateCustomEventGoalProperty("Label", eventLabel, labelComparisonOperatorByte); var eventValue = (double?)row[_eventValueOrdinal]; var valueComparisonOperatorByte = (byte?)row[_valueComparisonOperatorOrdinal]; if (eventValue != null) { if (valueComparisonOperatorByte == null) { throw new Exception("ValueComparisonOperator value cannot be null when EventValue value is not null."); } if (!GoalUtils.IsValidValueOperator((byte)valueComparisonOperatorByte)) { throw new Exception(String.Format("ValueComparisonOperator value {0} is outside of range.", valueComparisonOperatorByte)); } var valueOperator = (ValueComparisonOperator)valueComparisonOperatorByte; if (!GoalUtils.IsValidNumericOperator(valueOperator)) { throw new Exception(String.Format("ValueOperator value {0} is not supported by {1} goal type.", valueOperator.ToString(), GoalType)); } EventValueProperty = new GoalProperty <double> { ValueComparisionOperator = valueOperator, PropertyValue = (double)eventValue }; } }