Hotfix

The current hotfix version is 4.1.2.3.

Unifi can be patched between releases by using a special Script Include called hotfix. If you find a bug in Unifi we may issue an update to hotfix so you can get the features you need without having to upgrade.

Upgrading

When upgrading Unifi, you can revert to the latest version of hotfix included in the upgrade. We reset hotfix with each release when the fixes become part of the main application.

Patching

We occasionally release a hotfix when minor issues are found. Simply replace the script in the hotfix Script Include with the one shown below and you will instantly have access to the fixes.

These hotfixes will be shipped as real fixes with the next version of Unifi, so make sure you have the correct hotfix for your version.

/**
 * Executes a child function corresponding to the object's type property.
 * The object is passed to the child function so methods and properties can be overridden.
 *
 * @param  {Object} obj The full class object to be patched.
 */
function hotfix(obj) {
  var type = typeof obj === 'function' ? obj.prototype.type : obj.type;
  if (type && typeof hotfix[type] === 'function') {
    hotfix[type](obj);
  }
}

hotfix.version = '4.1.2.3';

hotfix.Dataset = function (Dataset) {
  Dataset.prototype.getExportFieldMap = function getExportFieldMap(message) {
    return Field.getForMessage(message || this.getProcessMessage()).reduce(function (map, field) {
      // UN-1354 allow dataset exports to use legacy field maps
      var script = String(field.getElement('field_map').source_to_stage);
      var source = /\$stage.\$\[field.property\]\s*=/g.test(script) ? 'property' : 'element';
      if (field.getElement('outbound') == true && field.getElement('active') == true) {
        map.push({
          source: field.getValue(source),
          target: field.getValue('property')
        });
      }
      return map;
    }, []);
  };
};

hotfix.DataSetProcessor = function(DataSetProcessor) {
  DataSetProcessor.prototype._executeQueue = function _executeQueue(callback) {
    // UN-1410 fix dataset cleanup processing
    var user_callback = callback;
    var event;
    if (this.event && this.event.name == 'x_snd_eb.dataset.cleanup') {
      event = {};
      for (var field in this.event) {
        if (!this.event.isValidField(field)) continue;
        event[field] = this.event[field].nil() ? '' : this.event.getValue(field);
      }
      this.event = event;
      callback = function callback(gr, index) {
        user_callback(gr, index);
        event.parm1 = gr.sys_id + '';
      };
    }
    var rows = this._execute(callback);
    if (this.event) {
      // UN-1410 revert changes made in UN-1299
      if (rows == this.limit) {
        ws_console.info('Event ' + this.event.name + ' processed the maximum ' + this.limit + ' records. Auto queueing next event.');
        this.queueNext(this.event, this.current);
      } else {
        ws_console.info('Event ' + this.event.name + ' processed less than the maximum ' + this.limit + ' records. Processing complete.');
      }
    } else {
      ws_console.warn('Cannot auto queue additional processing; event not found.');
    }
    return rows;
  };
};

hotfix.Integration = function (Integration) {
  Integration.repair = function repair(integration_id) {
    var details = [];
    var gr = new GlideRecord('x_snd_eb_integration');
    if (gr.get(integration_id)) {
      var dsp = new DataSetProcessor('x_snd_eb_transaction');
      dsp.setQuery('sys_created_on<=' + new GlideDateTime() + '^integration=' + integration_id + '^transaction_stateINTimed Out,Error^message.type!=Heartbeat');
      dsp.setTrackerInterval(5);
      dsp.onUpdateTracker(function (result) {
        result.details = details;
      });
      dsp.execute(function (gr, i) {
        var new_transaction = Transaction.replay(gr);
        // UN-1413 fix integration repair
        if (new_transaction) {
          details.push(new_transaction.getDisplayValue() + ' ' +
                       new_transaction.getDisplayValue('message'));
        } else {
          details.push(ws_console.error('Unable to replay %0.', [gr.getDisplayValue()]));
        }
      });
    }
  };
};

hotfix.system = function (system) {
  system.getDocumentationLink = function getDocumentationLink(path) {
    // UN-1414 fix Integration Diagnostic links
    if (path == '/release/hotfixes') path = '/install/installation/hotfixes';
    if (path == '/release/global-utility') path = '/install/installation/global-utility';
    // get rid of the patch version
    var version = system.getApplicationVersion('minor');
    var url = "https://docs.sharelogic.com/unifi";
    return url + (version ? '/v/' + version : '') + (path || '');
  };
};

hotfix.RestHelper = function (RestHelper) {
  // UN-1434 fix HttpRequest unable to identify message name from request
  RestHelper.prototype.isStringContentType = function isStringContentType(type) {
    if (!type) return true;
    type += '';
    if (type.indexOf('application/json') == 0) return true;
    if (type.indexOf('application/xml') == 0) return true;
    if (type.indexOf('text/xml') == 0) return true;
    return false;
  };
  RestHelper.prototype._getRequestBody = function _getRequestBody(request, method, is_stream) {
    try {
      if (is_stream) {
        return request.body.dataStream;
      } else if (method != 'GET') {
        if (this.isStringContentType(request.headers['content-type'])) {
          return request.body.dataString;
        } else {
          return this._getRequestBodyFromStream(request);
        }
      }
    } catch (e) {
      ws_console.debug('Failed to get request body: ' + e);
    }
    return '';
  };
};

Last updated