/*
* Copyright 2015 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This controller handles the notification when a page is published, the live preview and the preview
*/
Ext.define(
'Ametys.plugins.web.page.controller.LivePageController', {
extend: 'Ametys.web.controller.WebButtonController',
/**
* @property {String[]} [_pageIds=[]] List of identifiers of pages concerned by the action of the controller
* @private
*/
/**
* @property {Boolean} _isContentTarget True if the target message concerns a Content
* @private
*/
constructor: function(config)
{
this._pageIds = [];
this._isContentTarget = false;
this.callParent(arguments);
// FIXME zoneChanged ? typeChanged ?
Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
Ametys.message.MessageBus.on(Ametys.message.Message.WORKFLOW_CHANGED, this._onModified, this);
},
/**
* @private
* Listener for modified or workflow changed messages
* Will update the state of the buttons effectively upon the current selection.
* @param {Ametys.message.Message} message the message.
*/
_onModified: function (message)
{
if (this.updateTargetsInCurrentSelectionTargets(message) || message.getTargets(Ametys.message.MessageTarget.CONTENT).length > 0)
{
this._isContentTarget = message.getTargets(Ametys.message.MessageTarget.CONTENT).length > 0;
this.refresh();
}
},
/**
* Get the matching targets that match set link page conditions
* @return {Ametys.message.MessageTarget[]} targets filling all conditions.
*/
getAllRightPageTargets: function ()
{
var matchingTargets = this.getMatchingTargets();
var me = this;
return Ext.Array.filter (matchingTargets, function (target) {
return Ext.Array.contains(me._pageIds, target.getParameters().id)
});
},
updateState: function()
{
this._getStatus(this.getMatchingTargets());
},
/**
* @private
* Get the status
* @param targets The page targets
*/
_getStatus: function(targets)
{
this._calculateStatus(targets, this._getStatusCb);
},
/**
* @private
* Compute the status of the current page.
* Done from client-side if the modified target is a page, done from server-side if the modified target is a content
* @param {Ametys.message.Targets[]} targets The matching page targets
* @param {Function} callback The callback function to invoked after status was updated
*/
_calculateStatus: function(targets, callback)
{
var result = {
"invalid-pages": [],
"allright-pages": [],
"invalid-page": [],
"invalid-hierarchy": []
};
var me = this;
if (me._isContentTarget)
{
// When target message is a content a call to server side is needed to update the page status
var remainingPagesCounter = targets.length;
Ext.Array.each(targets, function(matchingTarget){
var pageId = matchingTarget.getParameters().id;
Ametys.web.page.PageDAO.getPage(pageId, function(page){
me._updatePageStatus(matchingTarget, page, result);
remainingPagesCounter--;
if (remainingPagesCounter == 0)
{
callback.apply(me, [result]);
}
});
});
}
else
{
// Update status from page target (done from client-side only)
Ext.Array.each(targets, function(matchingTarget){
var parameters = matchingTarget.getParameters();
if (parameters && parameters.page)
{
me._updatePageStatus(matchingTarget, parameters.page, result);
}
});
callback.apply(me, [result]);
}
},
/**
* @protected
* Update the page status
* @param {Ametys.message.MessageTarget} matchingTarget The matching page target
* @param {Ametys.web.page.Page} page The page associated to this target (should be up-to-date)
* @param {Object} result The status result to be updated
*/
_updatePageStatus: function(matchingTarget, page, result)
{
var error = false;
if (!this.hasRightOnAny([matchingTarget]))
{
var i18nStr = this.getConfig("noright-page-description");
var description = Ext.String.format(i18nStr, page.getTitle());
var pageParam = this._getPageDefaultParameters(page);
pageParam["description"] = description;
result["noright-pages"].push(pageParam);
error = true;
}
var validPage = page.getIsPageValid();
if (!validPage)
{
var i18nStr = this.getConfig("invalid-page-description");
var description = Ext.String.format(i18nStr, page.getTitle());
var pageParam = this._getPageDefaultParameters(page);
pageParam["description"] = description;
result["invalid-pages"].push(pageParam);
error = true;
}
else if (validPage && !page.getIsLiveHierarchyValid())
{
var i18nStr = this.getConfig("invalid-hierarchy-description");
var description = Ext.String.format(i18nStr, page.getTitle());
var pageParam = this._getPageDefaultParameters(page);
pageParam["description"] = description;
result["invalid-hierarchy"].push(pageParam);
error = true;
}
if (!error)
{
var i18nStr = this.getConfig("allright-page-description");
var description = Ext.String.format(i18nStr, page.getTitle());
var contentParam = this._getPageDefaultParameters(page);
contentParam["description"] = description;
result["allright-pages"].push(contentParam);
}
},
/**
* create a json object representing a page
* @private
* @param {Ametys.web.page.Page} page The page to analyse
* @return {Object} containing id and title
*/
_getPageDefaultParameters : function(page)
{
var pageParams = {};
pageParams["id"] = page.getId();
pageParams["title"] = page.getTitle();
return pageParams;
},
/**
* Callback for the button reloading process
* @param {Object} params the server's response
* @param {Object[]} params.allright-pages the allright pages
* @param {Object[]} params.invalid-hierarchy the pages having an invalid hierarchy
* @param {Object[]} params.invalid-pages the invalid pages
*/
_getStatusCb: function(params)
{
var allRightPages = params['allright-pages'];
if (allRightPages.length > 0)
{
for (var i=0; i < allRightPages.length; i++)
{
this._pageIds.push(allRightPages[i].id);
}
this.enable();
}
else
{
this.disable();
}
this._updateTooltipDescription(this.getInitialConfig('default-description'), params);
},
/**
* @protected
* Update the tooltip description according state of the current selection
* @param description The initial description. Can be empty.
* @param params The JSON result received
*/
_updateTooltipDescription: function (description, params)
{
description = this._handlingMultiple(description, "noright", params['noright-pages']);
description = this._handlingMultiple(description, "invalid-page", params['invalid-pages']);
description = this._handlingMultiple(description, "invalid-hierarchy", params['invalid-hierarchy']);
description = this._handlingMultiple(description, 'allright-page', params['allright-pages']);
this.setDescription (description);
},
/**
* Generates the tooltip to set
* @param {String} description the description where to add text in html
* @param {String} paramPrefix the parameter prefix
* @param {Object} pages the pages
*/
_handlingMultiple: function(description, paramPrefix, pages)
{
if (pages && pages.length > 0)
{
if (description != "")
{
description += "<br/><br/>";
}
description += this.getInitialConfig(paramPrefix + "-start-description");
for (var i=0; i < pages.length; i++)
{
if (i != 0)
{
description += ", ";
}
description += pages[i].description;
}
description += this.getInitialConfig()[paramPrefix + "-end-description"];
}
return description;
}
}
);