|
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
-
- /**
- * @api
- */
- define([
- 'jquery',
- 'underscore',
- 'ko',
- 'Magento_Customer/js/section-config',
- 'mage/url',
- 'mage/storage',
- 'jquery/jquery-storageapi'
- ], function ($, _, ko, sectionConfig, url) {
- 'use strict';
-
- var options = {},
- storage,
- storageInvalidation,
- invalidateCacheBySessionTimeOut,
- invalidateCacheByCloseCookieSession,
- dataProvider,
- buffer,
- customerData,
- deferred = $.Deferred();
-
- url.setBaseUrl(window.BASE_URL);
- options.sectionLoadUrl = url.build('customer/section/load');
-
- /**
- * @param {Object} invalidateOptions
- */
- invalidateCacheBySessionTimeOut = function (invalidateOptions) {
- var date;
-
- if (new Date($.localStorage.get('mage-cache-timeout')) < new Date()) {
- storage.removeAll();
- }
- date = new Date(Date.now() + parseInt(invalidateOptions.cookieLifeTime, 10) * 1000);
- $.localStorage.set('mage-cache-timeout', date);
- };
-
- /**
- * Invalidate Cache By Close Cookie Session
- */
- invalidateCacheByCloseCookieSession = function () {
- if (!$.cookieStorage.isSet('mage-cache-sessid')) {
- storage.removeAll();
- }
-
- $.cookieStorage.set('mage-cache-sessid', true);
- };
-
- dataProvider = {
-
- /**
- * @param {Object} sectionNames
- * @return {Object}
- */
- getFromStorage: function (sectionNames) {
- var result = {};
-
- _.each(sectionNames, function (sectionName) {
- result[sectionName] = storage.get(sectionName);
- });
-
- return result;
- },
-
- /**
- * @param {Object} sectionNames
- * @param {Boolean} forceNewSectionTimestamp
- * @return {*}
- */
- getFromServer: function (sectionNames, forceNewSectionTimestamp) {
- var parameters;
-
- sectionNames = sectionConfig.filterClientSideSections(sectionNames);
- parameters = _.isArray(sectionNames) && sectionNames.indexOf('*') < 0 ? {
- sections: sectionNames.join(',')
- } : [];
- parameters['force_new_section_timestamp'] = forceNewSectionTimestamp;
-
- return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) {
- throw new Error(jqXHR);
- });
- }
- };
-
- /**
- * @param {Function} target
- * @param {String} sectionName
- * @return {*}
- */
- ko.extenders.disposableCustomerData = function (target, sectionName) {
- var sectionDataIds, newSectionDataIds = {};
-
- target.subscribe(function () {
- setTimeout(function () {
- storage.remove(sectionName);
- sectionDataIds = $.cookieStorage.get('section_data_ids') || {};
- _.each(sectionDataIds, function (data, name) {
- if (name !== sectionName) {
- newSectionDataIds[name] = data;
- }
- });
- $.cookieStorage.set('section_data_ids', newSectionDataIds);
- }, 3000);
- });
-
- return target;
- };
-
- buffer = {
- data: {},
-
- /**
- * @param {String} sectionName
- */
- bind: function (sectionName) {
- this.data[sectionName] = ko.observable({});
- },
-
- /**
- * @param {String} sectionName
- * @return {Object}
- */
- get: function (sectionName) {
- if (!this.data[sectionName]) {
- this.bind(sectionName);
- }
-
- return this.data[sectionName];
- },
-
- /**
- * @return {Array}
- */
- keys: function () {
- return _.keys(this.data);
- },
-
- /**
- * @param {String} sectionName
- * @param {Object} sectionData
- */
- notify: function (sectionName, sectionData) {
- if (!this.data[sectionName]) {
- this.bind(sectionName);
- }
- this.data[sectionName](sectionData);
- },
-
- /**
- * @param {Object} sections
- */
- update: function (sections) {
- var sectionId = 0,
- sectionDataIds = $.cookieStorage.get('section_data_ids') || {};
-
- _.each(sections, function (sectionData, sectionName) {
- sectionId = sectionData['data_id'];
- sectionDataIds[sectionName] = sectionId;
- storage.set(sectionName, sectionData);
- storageInvalidation.remove(sectionName);
- buffer.notify(sectionName, sectionData);
- });
- $.cookieStorage.set('section_data_ids', sectionDataIds);
- },
-
- /**
- * @param {Object} sections
- */
- remove: function (sections) {
- _.each(sections, function (sectionName) {
- storage.remove(sectionName);
-
- if (!sectionConfig.isClientSideSection(sectionName)) {
- storageInvalidation.set(sectionName, true);
- }
- });
- }
- };
-
- customerData = {
-
- /**
- * Customer data initialization
- */
- init: function () {
- var expiredSectionNames = this.getExpiredSectionNames();
-
- if (expiredSectionNames.length > 0) {
- _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {
- buffer.notify(sectionName, sectionData);
- });
- this.reload(expiredSectionNames, false);
- } else {
- _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {
- buffer.notify(sectionName, sectionData);
- });
-
- if (!_.isEmpty(storageInvalidation.keys())) {
- this.reload(storageInvalidation.keys(), false);
- }
- }
-
- if (!_.isEmpty($.cookieStorage.get('section_data_clean'))) {
- this.reload(sectionConfig.getSectionNames(), true);
- $.cookieStorage.set('section_data_clean', '');
- }
- },
-
- /**
- * Storage init
- */
- initStorage: function () {
- $.cookieStorage.setConf({
- path: '/',
- expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000)
- });
- storage = $.initNamespaceStorage('mage-cache-storage').localStorage;
- storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;
- },
-
- /**
- * Retrieve the list of sections that has expired since last page reload.
- *
- * Sections can expire due to lifetime constraints or due to inconsistent storage information
- * (validated by cookie data).
- *
- * @return {Array}
- */
- getExpiredSectionNames: function () {
- var expiredSectionNames = [],
- cookieSectionTimestamps = $.cookieStorage.get('section_data_ids') || {},
- sectionLifetime = options.expirableSectionLifetime * 60,
- currentTimestamp = Math.floor(Date.now() / 1000),
- sectionData;
-
- // process sections that can expire due to lifetime constraints
- _.each(options.expirableSectionNames, function (sectionName) {
- sectionData = storage.get(sectionName);
-
- if (typeof sectionData === 'object' && sectionData['data_id'] + sectionLifetime <= currentTimestamp) {
- expiredSectionNames.push(sectionName);
- }
- });
-
- // process sections that can expire due to storage information inconsistency
- _.each(cookieSectionTimestamps, function (cookieSectionTimestamp, sectionName) {
- sectionData = storage.get(sectionName);
-
- if (typeof sectionData === 'undefined' ||
- typeof sectionData === 'object' &&
- cookieSectionTimestamp !== sectionData['data_id']
- ) {
- expiredSectionNames.push(sectionName);
- }
- });
-
- //remove expired section names of previously installed/enable modules
- expiredSectionNames = _.intersection(expiredSectionNames, sectionConfig.getSectionNames());
-
- return _.uniq(expiredSectionNames);
- },
-
- /**
- * Check if some sections have to be reloaded.
- *
- * @deprecated Use getExpiredSectionNames instead.
- *
- * @return {Boolean}
- */
- needReload: function () {
- var expiredSectionNames = this.getExpiredSectionNames();
-
- return expiredSectionNames.length > 0;
- },
-
- /**
- * Retrieve the list of expired keys.
- *
- * @deprecated Use getExpiredSectionNames instead.
- *
- * @return {Array}
- */
- getExpiredKeys: function () {
- return this.getExpiredSectionNames();
- },
-
- /**
- * @param {String} sectionName
- * @return {*}
- */
- get: function (sectionName) {
- return buffer.get(sectionName);
- },
-
- /**
- * @param {String} sectionName
- * @param {Object} sectionData
- */
- set: function (sectionName, sectionData) {
- var data = {};
-
- data[sectionName] = sectionData;
- buffer.update(data);
- },
-
- /**
- * Avoid using this function directly 'cause of possible performance drawbacks.
- * Each customer section reload brings new non-cached ajax request.
- *
- * @param {Array} sectionNames
- * @param {Boolean} forceNewSectionTimestamp
- * @return {*}
- */
- reload: function (sectionNames, forceNewSectionTimestamp) {
- return dataProvider.getFromServer(sectionNames, forceNewSectionTimestamp).done(function (sections) {
- $(document).trigger('customer-data-reload', [sectionNames]);
- buffer.update(sections);
- });
- },
-
- /**
- * @param {Array} sectionNames
- */
- invalidate: function (sectionNames) {
- var sectionDataIds,
- sectionsNamesForInvalidation;
-
- sectionsNamesForInvalidation = _.contains(sectionNames, '*') ? sectionConfig.getSectionNames() :
- sectionNames;
-
- $(document).trigger('customer-data-invalidate', [sectionsNamesForInvalidation]);
- buffer.remove(sectionsNamesForInvalidation);
- sectionDataIds = $.cookieStorage.get('section_data_ids') || {};
-
- // Invalidate section in cookie (increase version of section with 1000)
- _.each(sectionsNamesForInvalidation, function (sectionName) {
- if (!sectionConfig.isClientSideSection(sectionName)) {
- sectionDataIds[sectionName] += 1000;
- }
- });
- $.cookieStorage.set('section_data_ids', sectionDataIds);
- },
-
- /**
- * Checks if customer data is initialized.
- *
- * @returns {jQuery.Deferred}
- */
- getInitCustomerData: function () {
- return deferred.promise();
- },
-
- /**
- * Reload sections on ajax complete
- *
- * @param {Object} jsonResponse
- * @param {Object} settings
- */
- onAjaxComplete: function (jsonResponse, settings) {
- var sections,
- redirects;
-
- if (settings.type.match(/post|put|delete/i)) {
- sections = sectionConfig.getAffectedSections(settings.url);
-
- if (sections && sections.length) {
- this.invalidate(sections);
- redirects = ['redirect', 'backUrl'];
-
- if (_.isObject(jsonResponse) && !_.isEmpty(_.pick(jsonResponse, redirects))) { //eslint-disable-line
- return;
- }
- this.reload(sections, true);
- }
- }
- },
-
- /**
- * @param {Object} settings
- * @constructor
- */
- 'Magento_Customer/js/customer-data': function (settings) {
- options = settings;
- customerData.initStorage();
- invalidateCacheBySessionTimeOut(settings);
- invalidateCacheByCloseCookieSession();
- customerData.init();
- deferred.resolve();
- }
- };
-
- /**
- * Events listener
- */
- $(document).on('ajaxComplete', function (event, xhr, settings) {
- customerData.onAjaxComplete(xhr.responseJSON, settings);
- });
-
- /**
- * Events listener
- */
- $(document).on('submit', function (event) {
- var sections;
-
- if (event.target.method.match(/post|put|delete/i)) {
- sections = sectionConfig.getAffectedSections(event.target.action);
-
- if (sections) {
- customerData.invalidate(sections);
- }
- }
- });
-
- return customerData;
- });
|