personacontent-8.x-2.x-dev/js/personacontent.rules.js

js/personacontent.rules.js
(function (Drupal, $, drupalSettings, once) {

  'use strict';

  /**
   * Creates class to validate Personalization Rules.
   */
  var personaContentClass = function (options) {

    /**
     * Can access this.method
     * inside other methods using
     * root.method()
     */
    var root = this;
    var segment_i_valid = -1;
    var segment_id = -1;
    var pathCurrent = '';
    var key = '';

    /**
     * Debug encapsulation for debugging regions.
     */
    this.consoleLog = function () {
      if (typeof drupalSettings.personacontent !== undefined) {
        if (typeof drupalSettings.personacontent.screen_debug_html !== undefined) {
          if (drupalSettings.personacontent.screen_debug_html == 1) {
            console.log.apply(null, arguments);
          }
        }
      }
    }

    /**
     * Returns a valid segment i found.
     */
    this.segmentValidGet = function () {
      if (segment_i_valid > 0) {
        return segment_i_valid;
      }

      return false;
    }

    /**
     * Returns a valid segment i found.
     */
    this.segmentValidIdGet = function () {
      if (segment_id > 0) {
        return segment_id;
      }

      return false;
    }

    /**
     * Constructor
     */
    this.construct = function (options) {
      $.extend(vars, options);
    };

    /**
     * Init function.
     */
    this.init = function () {
      if (typeof drupalSettings.personacontent === undefined) {
        return false;
      }

      if (typeof drupalSettings.personacontent.segments === undefined) {
        return false;
      }

      var segment_i = -1;
      var segments = drupalSettings.personacontent.segments.slice(0);

      // Check for cache.
      pathCurrent = root.getUrlPath();
      key = 'personacontent--html--2--' + pathCurrent;
      var segment_cache = localStorage.getItem(key);

      if (false && segment_cache != null) {
        segment_cache = JSON.parse(segment_cache);
        var now = Math.round(new Date().getTime() / 1000);

        if (parseInt(segment_cache.expire, 10) >= now) {
          root.markSegmentHtml(segment_cache.i);
          return true;
        }
      }

      // No cache.
      root.segmentProcess(segments, segment_i);
    }

    /**
     * Saves the found valid segment.
     */
    this.segmentValidFound = function (segment_i) {
      var segment = drupalSettings.personacontent.segments[segment_i];
      root.segment_i_valid = segment_i;

      // Store in cache the choosen segment.
      var expire = Math.round(new Date().getTime() / 1000) + 3600;
      var cache = JSON.stringify({'i': segment_i, 'expire': expire});
      localStorage.setItem(key, cache);

      root.markSegmentHtml(segment_i);

      return true;
    }

    /**
     * Marks personacontent segment at html tag.
     */
    this.markSegmentHtml = function (segment_i) {
      segment_i_valid = segment_i;
      var segmentValid = drupalSettings.personacontent.segments[segment_i];
      segment_id = segmentValid.id;
      $('html').addClass('personacontent-segment-' + segmentValid.id);
      $('html').attr('personacontent-segment', segmentValid.id);

      window.personaAnalytics.log(segmentValid.title);

      window.personaDebug.markSegmentWinner(segmentValid);

      Drupal.attachBehaviors();
    }

    /**
     * Process segments in queued mode.
     */
    this.segmentProcess = function (segments, segment_i) {
      segment_i++;

      // Process first segment available in array of segments.
      var segment = segments.shift();
      var segmentL = JSON.parse(JSON.stringify(segment));

      // If no rules, then this segment is valid already.
      segment.rules_count = parseInt(segment.rules.length, 10);
      if (segment.rules_count == 0) {
        window.personaDebug.markRuleWinner({'title': 'segment-without-rules'});
        return root.segmentValidFound(segment_i);
      }

      // Process the segment item.
      segment.rules_validation = [];

      // Process.
      root.segmentProcessRules(segment, segments, segment_i);
    }

    /**
     * Process one segment out of the region.
     */
    this.segmentProcessRules = function (segment, segments, segment_i) {
      // Process first rule available in array of rules.
      var rule = segment.rules.shift();
      var ruleL = JSON.parse(JSON.stringify(rule));

      switch (rule.type) {
        // Url comparisons.
        case 'url:current':
          root.validateUrlCurrent(rule, segment, segments, segment_i);
          break;

        case 'url:referer':
          root.validateUrlReferer(rule, segment, segments, segment_i);
          break;

        case 'url:history':
          root.validateUrlHistory(rule, segment, segments, segment_i);
          break;

        case 'event:click':
          root.validateEvent(rule, segment, segments, segment_i);
          break;

        case 'location:city':
        case 'location:state':
        case 'location:region':
        case 'location:country':
        case 'location:zipcodes':
          root.validateLocation(rule, segment, segments, segment_i);
          break;

        default:
          // Verify if there are more rules to validate.
          var result = false;
          segment.rules_validation.push(result);

          if (parseInt(segment.rules.length) > 0) {
            root.segmentProcessRules(segment, segments, segment_i);
          }
          else {
            root.segmentProcessRulesResult(segment, segments, segment_i, ruleL);
          }
          break;
      }
    }

    /**
     * Validates a current url rule.
     */
    this.validateUrlCurrent = function (rule, segment, segments, segment_i) {
      var ruleL = JSON.parse(JSON.stringify(rule));
      var path = root.getUrlPath();
      var result = root.validateUrlOperator(rule, path);
      segment.rules_validation.push(result);

      // Verify if there are more rules to validate.
      if (parseInt(segment.rules.length) > 0) {
        root.segmentProcessRules(segment, segments, segment_i);
      }
      else {
        // Evaluate rules_matches.
        root.segmentProcessRulesResult(segment, segments, segment_i, ruleL);
      }
    }

    /**
     * Validates a referer url rule.
     */
    this.validateUrlReferer = function (rule, segment, segments, segment_i) {
      var ruleL = JSON.parse(JSON.stringify(rule));
      var path = root.getUrlRefererPath();
      var result = root.validateUrlOperator(rule, path);
      segment.rules_validation.push(result);

      // Verify if there are more rules to validate.
      if (parseInt(segment.rules.length) > 0) {
        root.segmentProcessRules(segment, segments, segment_i);
      }
      else {
        root.segmentProcessRulesResult(segment, segments, segment_i, ruleL);
      }
    }

    /**
     * Validates a history url rule.
     */
    this.validateUrlHistory = function (rule, segment, segments, segment_i) {
      var ruleL = JSON.parse(JSON.stringify(rule));
      // Get History.
      var result = window.personaHistory.searchRule(rule);
      segment.rules_validation.push(result);

      // Verify if there are more rules to validate.
      if (parseInt(segment.rules.length) > 0) {
        root.segmentProcessRules(segment, segments, segment_i);
      }
      else {
        root.segmentProcessRulesResult(segment, segments, segment_i, ruleL);
      }
    }

    /**
     * Validates an Event.
     */
    this.validateEvent = function (rule, segment, segments, segment_i) {
      var ruleL = JSON.parse(JSON.stringify(rule));
      // Get events.
      var result = window.personaEvents.searchRule(rule);
      segment.rules_validation.push(result);

      // Verify if there are more rules to validate.
      if (parseInt(segment.rules.length) > 0) {
        root.segmentProcessRules(segment, segments, segment_i);
      }
      else {
        root.segmentProcessRulesResult(segment, segments, segment_i, ruleL);
      }
    }

    /**
     * Get the current url path.
     */
    this.getUrlPath = function () {
      var path = window.location.pathname;
      var query = window.location.search;
      //var fragment = window.location.hash;
      //return path + query + fragment;

      return path + query;
    }

    /**
     * Get the referer url path.
     */
    this.getUrlRefererPath = function () {
      var referer = document.referrer;
      if (referer.length > 0) {
        var path = referer.match(/\/\/.*?\/(.*?)\/?(\?.*)?$/)[1];
        var matches = path.match(/^\/?(.*)/);

        return matches[1];
      }

      return '';
    }

    /**
     * Validates a path apply to the operator rule.
     */
    this.validateLocationOperator = function (args) {
      var rule = args.rule;
      var string = root.getFirstValue(rule.values);
      var path = args.location;

      switch (rule.operator) {
        case 'starts':
          return path.startsWith(string);

        case 'ends':
          return path.endsWith(string);

        case 'contains':
          return path.includes(string);
      }

      return false;
    }

    /**
     * Validates a path apply to the operator rule.
     */
    this.validateUrlOperator = function (rule, path) {
      var string = root.getFirstValue(rule.values);

      switch (rule.operator) {
        case 'starts':
          return path.startsWith(string);

        case 'ends':
          return path.endsWith(string);

        case 'contains':
          return path.includes(string);
      }

      return false;
    }

    /**
     * Get first value out of the values textarea.
     */
    this.getFirstValue = function (values) {
      var string = values + '';
      string = string.split("\n");
      string = string[0];
      return string;
    }

    /**
     * Save Location at cache.
     */
    this.cacheLocation = function (latlng, location) {
      // Store in cache the choosen segment.
      var expire = Math.round(new Date().getTime() / 1000) + 3600;
      var location_cache = {
        'lat': latlng.lat,
        'lng': latlng.lng,
        'location': location,
        'expire': expire
      };

      localStorage.setItem('personacontent--location', JSON.stringify(location_cache));
    }

    /**
     * Get current location and caches it.
     */
    this.locationGet = function (args, successCallback, failCallback) {
      var location;
      args.valid = false;

      // Look at cache.
      var location_cache = localStorage.getItem('personacontent--location');
      if (typeof location_cache != undefined && location_cache != null) {
        location_cache = JSON.parse(location_cache);
        var now = Math.round(new Date().getTime() / 1000);

        if (parseInt(location_cache.expire, 10) >= now) {
          // True Statement.
          args.location = location_cache.location;

          // True statement.
          if (successCallback(args)) {
            args.valid = true;
            failCallback(args);
          }
          else {
            failCallback(args);
          }
          return;
        }
      }

      // Get current location.
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
          var latlng = {
            lat: position.coords.latitude,
            lng: position.coords.longitude
          };

          var geocoder = new google.maps.Geocoder;
          geocoder.geocode({'location': latlng}, function (results, status) {
            if (status === 'OK') {
              if (results[1]) {
                location = results[1];

                // Save to cache.
                root.cacheLocation(latlng, location.formatted_address);
                args.location = location.formatted_address;

                // True statement.
                if (successCallback(args)) {
                  args.valid = true;
                  failCallback(args);
                }
                else {
                  failCallback(args);
                }
              }
              else {
                // False statement.
                failCallback(args);
              }
            }
            else {
              // False statement.
              failCallback(args);
            }
          });
        }, function () {
          // False statement.
          failCallback(args);
        });
      }
      else {
        // False statement.
        failCallback(args);
      }
    }

    /**
     * Validates Location Rule.
     */
    this.validateLocation = function (rule, segment, segments, segment_i) {
      // Load Args.
      var args = {
        'rule': rule,
        'segment': segment,
        'segments': segments,
        'segment_i': segment_i
      };

      root.locationGet(args, root.validateLocationOperator, root.validateLocationNext);
    }

    /**
     * When validating Location proceeds to the next rule.
     */
    this.validateLocationNext = function (args) {
      var valid = args.valid;
      var segment = args.segment;
      var segments = args.segments;
      var segment_i = args.segment_i;
      var ruleL = JSON.parse(JSON.stringify(args.rule));

      segment.rules_validation.push(valid);

      // Verify if there are more rules to validate.
      if (parseInt(segment.rules.length) > 0) {
        root.segmentProcessRules(segment, segments, segment_i);
      }
      else {
        root.segmentProcessRulesResult(segment, segments, segment_i, ruleL);
      }
    }

    /**
     * Evaluate all rules results after validating all rules.
     */
    this.segmentProcessRulesResult = function (segment, segments, segment_i, ruleL) {
      // Evaluate rules_matches.
      var valid = true;

      $(segment.rules_validation).each(function (i, result) {
        if (result) {
          // If we need only one rule to apply, escape each().
          if (segment.rules_matches == 'any') {
            valid = true;
            return false;
          }
          else if (segment.rules_matches == 'none') {
            valid = false;
            return false;
          }
        }
        else {
          valid = false;

          // If all rules needs to apply and one fails, escape each().
          if (segment.rules_matches == 'all') {
            return false;
          }
        }
      });

      if (valid) {
        window.personaDebug.markRuleWinner(ruleL);
        root.segmentValidFound(segment_i);
      }
      else if (segments.length > 0) {
        root.segmentProcess(segments, segment_i);
      }
    }

  }

  window.personaContent = new personaContentClass();

})(Drupal, jQuery, drupalSettings, once);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc