Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/multiphp_manager/index.cmb.js
/* global define: false */
define(
'app/services/configService',[
// Libraries
"angular",
// CJT
"cjt/io/api",
"cjt/util/parse",
"cjt/util/locale",
"cjt/io/whm-v1-request",
"cjt/io/whm-v1", // IMPORTANT: Load the driver so its ready
"cjt/services/APIService"
],
function(angular, API, PARSE, LOCALE, APIREQUEST, APIDRIVER) {
"use strict";
// Fetch the current application
var app;
try {
app = angular.module("App"); // For runtime
} catch (e) {
app = angular.module("App", ["cjt2.services.api"]); // Fall-back for unit testing
}
/**
* Set up the account list model's API service.
*/
app.factory("configService", ["$q", "APIService", function($q, APIService) {
/**
* @typedef PoolOption
* @property {Number} trinary_admin_value 0 = admin option does not exist for pool value, 1 = this is php_admin_value, 2 = php_value
* @property {String} base_flag_name name of option being set
* @property {String | Number} value value of option being set
*/
var MultiPHPConfigService = function() {};
MultiPHPConfigService.prototype = new APIService();
/**
* Parse raw data into format usuable to front end
* @method parsePHPFPMData
* @param {Array<PoolOption>} data raw data from backend
* @return {Array<PoolOption>} parsedData parsed data for use by front end
*/
function parsePHPFPMData(data, domain) {
var parsedData = {};
function parseValue(option) {
if (option.value === "on") {
return true;
}
if (option.value === "off") {
return false;
}
if (option.base_flag_name === "pm_max_children" ||
option.base_flag_name === "pm_process_idle_timeout" ||
option.base_flag_name === "pm_max_requests") {
if (!isNaN(parseInt(option.value, 10))) {
return parseInt(option.value, 10);
}
}
if (option.base_flag_name === "error_reporting" || option.base_flag_name === "disable_functions") {
if (typeof option.value !== "string" || option.value.length === 0) {
option.value = [];
} else {
option.value = option.value.split(",");
}
return option.value;
}
if (option.base_flag_name === "doc_root") {
if (typeof option.value !== "string" || !domain) {
option.value = "";
} else {
option.value = option.value.split("[% documentroot %]")[1];
if (option.value.indexOf("/") === 0) {
option.value = option.value.slice(1, option.value.length);
}
}
return option.value;
}
if (option.base_flag_name === "error_log") {
if (typeof option.value !== "string" || !domain) {
option.value = "";
} else {
option.value = option.value.split("/logs/")[1];
}
return option.value;
}
}
data.forEach(function(option) {
parsedData[option.base_flag_name] = {
value: parseValue(option),
admin: option.trinary_admin_value === 1 ? true : option.trinary_admin_value === 2 ? false : 0
};
});
return parsedData;
}
/**
* Encode options for API call
* @method encodePoolOptions
* @param {Array<PoolOption>} poolOptions data in format for front end
* @return {Array<PoolOption>} encodedPoolOptions data encoded for use by API
*/
function encodePoolOptions(poolOptions) {
var encodedPoolOptions = [];
var encodedOption = {};
function encodeValue(option, val) {
if (option === "allow_url_fopen" || option === "log_errors" || option === "short_open_tag") {
if (val) {
val = "on";
} else {
val = "off";
}
return val;
}
if (option === "disable_functions" || option === "error_reporting") {
if (val.length === 0) {
// API only accepts empty string for no funs or errs
val = "";
} else {
val = val.join(",");
}
return val;
}
if (option === "pm_max_children" ||
option === "pm_max_requests" ||
option === "pm_process_idle_timeout") {
return val;
}
if (option === "error_log") {
if (val === "") {
val = "[% homedir %]/logs/[% scrubbed_domain %].php.error.log";
} else {
val = "[% homedir %]/logs/" + val;
}
return val;
}
if (option === "doc_root") {
if (val.indexOf("/") !== 0) {
val = "[% documentroot %]/" + val;
} else {
val = "[% documentroot %]" + val;
}
return val;
}
}
for (var option in poolOptions) {
if (option) {
encodedOption["trinary_admin_value"] = poolOptions[option].admin ? 1 : poolOptions[option].admin === 0 ? poolOptions[option].admin : 2;
encodedOption["base_flag_name"] = option;
encodedOption["value"] = encodeValue(option, poolOptions[option].value);
}
encodedPoolOptions.push(encodedOption);
encodedOption = {};
}
return encodedPoolOptions;
}
angular.extend(MultiPHPConfigService.prototype, {
/**
* Converts the response to our application data structure
* @param {Object} response - Response from API call.
* @returns {Object} Sanitized data structure.
*/
convertResponseToList: function(response) {
var items = [];
if (response.status) {
var data = response.data;
for (var i = 0, length = data.length; i < length; i++) {
var list = data[i];
if (list.hasOwnProperty("php_fpm")) {
list.php_fpm = PARSE.parsePerlBoolean(list.php_fpm);
}
if (list.hasOwnProperty("is_suspended")) {
list.is_suspended = PARSE.parsePerlBoolean(list.is_suspended);
}
if (list.hasOwnProperty("main_domain")) {
list.main_domain = PARSE.parsePerlBoolean(list.main_domain);
}
if (list.hasOwnProperty("version")) {
list.display_php_version = this.transformPhpFormat(list.version);
}
items.push(
list
);
}
var meta = response.meta;
var totalItems = meta.paginate.total_records || data.length;
var totalPages = meta.paginate.total_pages || 1;
return {
items: items,
totalItems: totalItems,
totalPages: totalPages
};
} else {
return {
items: [],
totalItems: 0,
totalPages: 0
};
}
},
/**
* Retrieves a list of installed FPM packages.
* @returns {Promise} - Promise encapsulating the package list.
*/
checkFPMPackages: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "package_manager_list_packages");
apiCall.addArgument("state", "installed");
return this.deferred(apiCall).promise
.then(function(response) {
return response.data;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Set a given PHP version at the system level.
* @param {string} setData - PHP version to set.
* @returns {Promise} - Promise that will fulfill the request.
*/
applySystemSetting: function(setData) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_set_system_default_version");
apiCall.addArgument("version", setData);
var that = this;
return this.deferred(apiCall).promise
.then(function(response) {
return that.convertResponseToList(response);
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Gets the current system-level PHP version.
* @returns {Promise} - Promise that will fulfill the request.
*/
fetchSystemPhp: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_get_system_default_version");
return this.deferred(apiCall).promise
.then(function(response) {
return response.data;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Set a given PHP version to the given list of vhosts.
* @param {string} version - PHP version to apply to the provided vhost list.
* @param {Object[]} vhostList - List of vhosts to which the new PHP needs to be applied.
* @returns {Promise} - Promise that will fulfill the request.
*/
applyDomainSetting: function(version, vhostList) {
var apiCall = new APIREQUEST.Class();
var that = this;
apiCall.initialize("", "php_set_vhost_versions");
apiCall.addArgument("version", version);
if (typeof (vhostList) !== "undefined" && vhostList.length > 0) {
vhostList.forEach(function(vhost, index) {
apiCall.addArgument("vhost-" + index, vhost);
});
}
return this.deferred(apiCall).promise
.then(function(response) {
var results = that.convertResponseToList(response);
return results;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Set PHP FPM to the given list of vhosts.
* @param {number} fpm - PHP FPM, either On(1) or Off(0).
* @param {Object[]} vhostList - List of vhosts.
* @returns {Promise} - Promise that will fulfill the request.
*/
applyDomainFpm: function(fpm, vhostList) {
var apiCall = new APIREQUEST.Class();
var that = this;
apiCall.initialize("", "php_set_vhost_versions");
apiCall.addArgument("php_fpm", fpm);
if (typeof (vhostList) !== "undefined" && vhostList.length > 0) {
vhostList.forEach(function(vhost, index) {
apiCall.addArgument("vhost-" + index, vhost);
});
}
return this.deferred(apiCall).promise
.then(function(response) {
var results = that.convertResponseToList(response);
return results;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Set Pool Options for the given vhost
* @param {Object} account - The account whose options need to be saved.
* @returns {Promise} - Promise that will fulfill the request.
*/
savePoolOption: function(account) {
var apiCall = new APIREQUEST.Class();
var that = this;
apiCall.initialize("", "php_set_vhost_versions");
apiCall.addArgument("php_fpm", 1);
apiCall.addArgument("vhost-0", account.vhost);
apiCall.addArgument("php_fpm_pool_parms", JSON.stringify(account.php_fpm_pool_parms));
return this.deferred(apiCall).promise
.then(function(response) {
var results = that.convertResponseToList(response);
return results;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get a list of accounts along with their default PHP versions for the given search/filter/page criteria.
* @param {object} meta - Optional meta data to control sorting, filtering and paging
* @param {string} meta.sortBy - Name of the field to sort by
* @param {string} meta.sortDirection - asc or desc
* @param {string} meta.sortType - Optional name of the sort rule to apply to the sorting
* @param {string} meta.filterBy - Name of the field to filter by
* @param {string} meta.filterValue - Expression/argument to pass to the compare method.
* @param {string} meta.pageNumber - Page number to fetch.
* @param {string} meta.pageSize - Size of a page, will default to 10 if not provided.
* @return {Promise} - Promise that will fulfill the request.
*/
fetchList: function(meta) {
var apiCall = new APIREQUEST.Class();
var that = this;
apiCall.initialize("", "php_get_vhost_versions");
return this.deferred(apiCall).promise
.then(function(response) {
var results = that.convertResponseToList(response);
return results;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get a list of PHP versions and their associated PHP handlers.
* @returns {Promise} - Promise that will fulfill the request.
*/
fetchVersionHandlerList: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_get_handlers");
var that = this;
return this.deferred(apiCall).promise
.then(function(response) {
return that.convertResponseToList(response);
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get a list of PHP versions.
* @returns {Promise} - Promise that will fulfill the request.
*/
fetchPHPVersions: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_get_installed_versions");
return this.deferred(apiCall).promise
.then(function(response) {
return response.data;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get the domains that are impacted by the given domain's
* PHP settings and/or the system’s default PHP setting
* @param {string} type - "domain" or "system_default"
* @param {string|number} value - The domain name or 1 for system default.
* @returns {Promise} - Promise encapsulating a list of domains.
*/
fetchImpactedDomains: function(type, value) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_get_impacted_domains");
apiCall.addArgument(type, value);
return this.deferred(apiCall).promise;
},
/**
* Applies the provided handler to the provided version
* @param {string} version
* @param {string} handler
* @returns {Promise} - Promise encapsulating a list of domains.
*/
applyVersionHandler: function(version, handler) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_set_handler");
apiCall.addArgument("version", version);
apiCall.addArgument("handler", handler);
return this.deferred(apiCall).promise
.then(function(response) {
return response.status;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Checks to see if a FPM conversion job is currently running
* @returns {Promise} Result of API call.
*/
conversionInProgress: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "is_conversion_in_progress");
return this.deferred(apiCall).promise
.then(function(result) {
return PARSE.parsePerlBoolean(result.data.inProgress);
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Convert all accounts to use PHP-FPM.
* @returns {Promise} Result of API call. Indicates whether
* the batch process has started.
*/
convertAllAccountsToFPM: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "convert_all_domains_to_fpm");
return this.deferred(apiCall).promise
.then(function(response) {
return response.data;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get the current status of PHP-FPM on the system.
* @return {Promise} Result of API call.
*/
fetchFPMStatus: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_get_default_accounts_to_fpm");
return this.deferred(apiCall).promise
.then(function(response) {
return response.data;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get the server PHP FPM environment information.
* @param {string} version
* @param {string} handler
* @returns {Promise} Result of API call.
*/
checkFPMEnvironment: function(version, handler) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "get_fpm_count_and_utilization");
return this.deferred(apiCall).promise
.then(function(response) {
return response.data;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Get all PHP FPM information at once.
* @param {string} version
* @param {string} handler
* @returns {Promise} Promise encapsulating object with all results
*/
getPHPFPMInfo: function(version, handler) {
var promises = {
environment: this.checkFPMEnvironment(version, handler),
status: this.fetchFPMStatus(),
packages: this.checkFPMPackages()
};
return $q.all(promises);
},
/**
* Switch the current status of PHP-FPM on the system.
* @param {number} newStatus - 0 (off) or 1 (on).
* @returns {Promise} Promise encapsulating object with all results
*/
switchSystemFPM: function(newStatus) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_set_default_accounts_to_fpm");
apiCall.addArgument("default_accounts_to_fpm", newStatus);
return this.deferred(apiCall).promise
.then(function(response) {
return true;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Convert the rpm format of PHP version (eg: ea-php56)
* to a user friendly notation (eg: PHP 5.6)
* @param {String}
* @return {String}
*/
friendlyPhpFormat: function(str) {
var newStr = str || "";
var phpVersionRegex = /^\D+-(php)(\d{2,3})$/i;
if (phpVersionRegex.test(str)) {
var stringArr = str.match(phpVersionRegex);
// adds a period before the last digit
var formattedNumber = stringArr[2].replace(/(\d)$/, ".$1");
newStr = "PHP " + formattedNumber;
}
return newStr;
},
/**
* Friendly PHP format with the rpm package
* name included.
* Example: PHP 5.6 (ea-php56)
* @param {String}
* @return {String}
*/
transformPhpFormat: function(str) {
var newStr = str || "";
var phpVersionRegex = /^\D+-(php)(\d{2,3})$/i;
if (phpVersionRegex.test(str)) {
newStr = this.friendlyPhpFormat(str);
newStr = newStr + " (" + str + ")";
}
return newStr;
},
/**
* Parse the values coming back from API.
* @param {Object} clData - The CloudLinux purchase data needed to build the banner.
* @returns {Object} - Return parsed data.
*/
parseCloudLinuxData: function(data) {
data.cl_is_installed = PARSE.parsePerlBoolean(data.cl_is_installed);
data.cl_is_supported = PARSE.parsePerlBoolean(data.cl_is_supported);
data.purchase_cl_data.disable_upgrade = PARSE.parsePerlBoolean(data.purchase_cl_data.disable_upgrade);
data.purchase_cl_data.is_url = PARSE.parsePerlBoolean(data.purchase_cl_data.is_url);
data.purchase_cl_data.server_timeout = PARSE.parsePerlBoolean(data.purchase_cl_data.server_timeout);
return data;
},
/**
* Set CloudLinux information that is needed for a banner.
* @param {Object} clData - The CloudLinux purchase data needed to build the banner.
* @returns {Object} - data needed by the banner.
*/
setCloudLinuxInfo: function(clData) {
var returnData = {};
if (clData) {
var cloudLinuxData = this.parseCloudLinuxData(clData);
var purchaseData = cloudLinuxData.purchase_cl_data;
if (cloudLinuxData.cl_is_supported && !cloudLinuxData.cl_is_installed && !purchaseData.disable_upgrade) {
returnData.showBanner = true;
if (!purchaseData.server_timeout) {
if (purchaseData.is_url) {
returnData.purchaseLink = purchaseData.url;
returnData.actionText = LOCALE.maketext("Upgrade to [asis,CloudLinux]");
returnData.linkTarget = purchaseData.target || "_blank";
} else {
// Create an email link to send to user
var mailSubject = "Upgrade to Cloud Linux"; // Do not localize the stuff that will get emailed to the CL folks
var mailBody = "I am interested in more information on how I can benefit from CloudLinux on my cPanel server."; // Do not localize the stuff that will get emailed to the CL folks
var mailtoText = "mailto:" + encodeURIComponent(purchaseData.email || "") + "?subject=" + encodeURIComponent(mailSubject) + "&body=" + encodeURIComponent(mailBody);
returnData.purchaseLink = mailtoText;
returnData.linkTarget = "_top";
returnData.actionText = LOCALE.maketext("Email Provider");
}
}
}
returnData.data = cloudLinuxData;
}
return returnData;
},
/**
* Fetch system default or domain specific php-fpm settings
* @method getPHPFPMSettings
* @param {String} [domain] Empty parameter for system settings, domain string if domain specific settings
* @return {Promise<Object>} Object of php-fpm keys with their respective values
* @throws {Promise<String>} Error message on failure
*/
getPHPFPMSettings: function(domain) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_fpm_config_get");
apiCall.json = true;
apiCall.addArgument("domain", domain ? domain : "");
return this.deferred(apiCall).promise
.then(function(response) {
return parsePHPFPMData(response.data.config, domain);
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* Submit config pool options for validation or saving
* @method submitPoolOptions
* @param {Object} poolOptions Aray of object describing each pool option and its value
* @param {Boolean} validate A boolean, if true will validate options, if false will save options
* @param {String} [domain] If given the options are saved or validated for given domain, if left empty values are saved/validated as system defaults
* @return {Promise<Boolean>} If true, values saved or validated successfully
* @throws {Promise<String>} Error message on failue
*/
submitPoolOptions: function(poolOptions, validate, domain) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "php_fpm_config_set");
apiCall.json = true;
apiCall.addArgument("validate_only", validate);
apiCall.addArgument("domain", domain ? domain : "");
apiCall.addArgument("config", encodePoolOptions(poolOptions));
return this.deferred(apiCall).promise
.then(function(response) {
return true;
})
.catch(function(error) {
return $q.reject(error);
});
},
/**
* @method getEA4Recommendations
* @return {Promise}
*/
getEA4Recommendations: function() {
var apiCall = new APIREQUEST.Class();
var apiService = new APIService();
apiCall.initialize("", "ea4_recommendations");
var deferred = apiService.deferred(apiCall);
return deferred.promise;
}
});
return new MultiPHPConfigService();
}
]);
});
/*
* templates/multiphp_manager/views/impactedDomainsPopup.js Copyright(c) 2020 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
define(
'app/views/impactedDomainsPopup',[
"angular",
"lodash",
"cjt/util/locale",
"uiBootstrap"
],
function(angular, _, LOCALE) {
// Retrieve the current application
var app = angular.module("App");
var controller = app.controller(
"impactedDomainsPopup",
["$scope", "$uibModalInstance", "data",
function($scope, $uibModalInstance, data) {
$scope.modalData = {};
var vhostInfo = data;
$scope.modalData = vhostInfo;
$scope.closeModal = function() {
$uibModalInstance.close();
};
}
]);
return controller;
}
);
/*
* templates/multiphp_manager/views/poolOptions.js
* Copyright 2022 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
/* eslint no-use-before-define: 0*/
define(
'app/views/poolOptions',[
"angular",
"lodash",
"cjt/util/parse",
"cjt/util/locale",
"uiBootstrap",
"cjt/directives/alertList",
"cjt/services/alertService",
"app/services/configService",
"cjt/directives/validationContainerDirective",
"cjt/directives/validationItemDirective",
"cjt/directives/toggleLabelInfoDirective",
"cjt/directives/loadingPanel",
"cjt/directives/actionButtonDirective",
"cjt/validator/datatype-validators",
"cjt/validator/compare-validators",
"cjt/validator/path-validators",
],
function(angular, _, PARSE, LOCALE) {
"use strict";
var app = angular.module("App");
var controller = app.controller(
"poolOptionsController",
["$q", "$scope", "$anchorScroll", "$rootScope", "alertService", "configService",
function($q, $scope, $anchorScroll, $rootScope, alertService, configService) {
$scope.displayValue = {
selectedDomain: "",
docRootDisplayValue: "",
logDirDisplayValue: "",
reportedErrs: "",
disabledFuncs: "",
displayMode: null,
disabledFuncsPanelOpen: false,
errsReportedPanelOpen: false,
saveReminderDisplayed: false,
saveReminderMessage: LOCALE.maketext("Click [output,em,Save Configuration] to save your changes."),
};
$scope.poolOptions = {};
$scope.poolOptionsCache = {};
$scope.additionalResources = [
{
text: "cPanel Documentation",
link: "https://docs.cpanel.net/",
},
{
text: LOCALE.maketext("Official [asis,PHP] Configuration Documentation"),
link: "https://secure.php.net/manual/en/install.fpm.configuration.php",
},
{
text: "Bottleneck with Child Processes",
link: "https://go.cpanel.net/ApachevsPHP-FPMBottleneckwithChildProcesses",
},
];
/**
* Return default button classes to work with cp-action directive
*
* @scope
* @method getDefaultButtonClasses
*/
$scope.getDefaultButtonClasses = function() {
return "btn btn-default";
};
/**
* Return small default button classes to work with cp-action directive
* @method getSmallDefaultButtonClasses
*/
$scope.getSmallDefaultButtonClasses = function() {
return "btn btn-sm btn-default";
};
/**
* Return default button classes to work with cp-action directive
*
* @scope
* @method getButtonClasses
* @return {String} Default button classes
*/
$scope.getButtonClasses = function() {
return "btn btn-default";
};
/**
* Return primary button classes to work with cp-action directive
*
* @scope
* @method getPrimaryButtonsClasses
* @return {String} Promary button classes
*/
$scope.getPrimaryButtonsClasses = function() {
return "btn btn-sm btn-primary";
};
/**
* Add functions to the disable_functions value list
*
* @scope
* @method addFunctionsToDisable
* @param {Array.<String>} funcs array of functions to validate for disabling
* @param {Object} formVal object representing php-fpm form
* @return {Promise.<Array.<String>> | } if the promise exists it returns an array of strings of validated funcs, if the promise does not exist, the function returns nothing
*/
$scope.addFunctionsToDisable = function(funcs, formVal) {
var funcsPromises = formatAndValidateFunctions(funcs, formVal);
if (!funcsPromises) {
return;
}
$scope.actions.validatingFuncs = true;
return funcsPromises.then(function(validatedFuncs) {
alertService.add({
type: "success",
autoClose: 5000,
message: LOCALE.maketext("You successfully added the “[_1]” function to the list. Click [output,em,Save Configuration] to save your changes.", _.escape(validatedFuncs)),
});
$scope.actions.validatingFuncs = false;
});
};
/**
* Remove functions from disable_functions value list
*
* @scope
* @method removeDisabledFunction
* @param {String} func function to remove from disable_functions value list
* @param {Object} formVal object representing php-fpm form
*/
$scope.removeDisabledFunction = function(func, formVal) {
var commands = $scope.poolOptions.disable_functions.value;
for (var i = 0, len = $scope.poolOptions.disable_functions.value.length; i < len; i++) {
if (func === commands[i]) {
$scope.poolOptions.disable_functions.value.splice(i, 1);
formVal.$setDirty();
return;
}
}
};
/**
* Add errors to error_reporting value list
*
* @scope
* @method addErrsToReport
* @param {Array.<String>} errs array of errors to validate before adding to error_reporting value list
* @param {Object} formVal object representing php-fpm form
* @return {Promise.<Array.<String>>} if the promise exists it returns and array of strings of validated errors, if it does not exist the function return nothing
*/
$scope.addErrsToReport = function(errs, formVal) {
var errsPromises = formatAndValidateErrs(errs, formVal);
if (!errsPromises) {
return;
}
$scope.actions.validatingErrs = true;
return errsPromises.then(function(validatedErrs) {
alertService.add({
type: "success",
autoClose: 5000,
message: LOCALE.maketext("You successfully added the “[_1]” error to the list. Click [output,em,Save Configuration] to save your changes.", _.escape(validatedErrs)),
});
$scope.actions.validatingErrs = false;
});
};
/**
* Remove errors from error_reporting value list
*
* @scope
* @method removeReportedErrs
* @param {String} err error to remove from error_reporting value list
* @param {Object} formVal object representing php-fpm form
*/
$scope.removeReportedErrs = function(err, formVal) {
var errs = $scope.poolOptions.error_reporting.value;
for (var i = 0, len = $scope.poolOptions.error_reporting.value.length; i < len; i++) {
if (err === errs[i]) {
$scope.poolOptions.error_reporting.value.splice(i, 1);
formVal.$setDirty();
return;
}
}
};
/**
* Emit event to return to PHP Version domain list view
*
* @scope
* @method returnToDomainsList
*/
$scope.returnToDomainsList = function() {
$rootScope.$emit("returnToDomainList");
};
/**
* Toggle betwee php_value and php_admin_value for given options
*
* @scope
* @method toggleOverrideVal
* @param {String} overrideVal which pool option is being toggled
* @param {Object} formVal object representing php-fpm form
* @throws {String} error informing developer of invalid value
*/
$scope.toggleOverrideVal = function(overrideVal, formVal) {
formVal.$setDirty();
if (!$scope.displayValue.saveReminderDisplayed) {
alertService.add({
type: "info",
closeable: true,
autoClose: 5000,
message: $scope.displayValue.saveReminderMessage,
});
$scope.displayValue.saveReminderDisplayed = true;
}
switch (overrideVal) {
case "allow_url_fopen":
$scope.poolOptions.allow_url_fopen.admin = !$scope.poolOptions.allow_url_fopen.admin;
break;
case "log_errors":
$scope.poolOptions.log_errors.admin = !$scope.poolOptions.log_errors.admin;
break;
case "short_open_tag":
$scope.poolOptions.short_open_tag.admin = !$scope.poolOptions.short_open_tag.admin;
break;
case "doc_root":
$scope.poolOptions.doc_root.admin = !$scope.poolOptions.doc_root.admin;
break;
case "error_log":
$scope.poolOptions.error_log.admin = !$scope.poolOptions.error_log.admin;
break;
case "disable_functions":
$scope.poolOptions.disable_functions.admin = !$scope.poolOptions.disable_functions.admin;
break;
case "error_reporting":
$scope.poolOptions.error_reporting.admin = !$scope.poolOptions.error_reporting.admin;
break;
default:
throw new Error("DEVELOPER ERROR: invalid override value given");
}
};
/**
* Save new pool options
*
* @scope
* @method savePoolOptions
* @param {Object} formVal object representing php-fpm form
*/
$scope.savePoolOptions = function(formVal) {
return submitPoolOptions($scope.poolOptions, false, $scope.displayValue.selectedDomain, formVal);
};
/**
* Validate new pool options
*
* @scope
* @method validatePoolOptions
*/
$scope.validatePoolOptions = function() {
return submitPoolOptions($scope.poolOptions, true, $scope.displayValue.selectedDomain);
};
/**
* Set the form to pristine
*
* @scope
* @method deactivateSaveActions
* @param {Object} formVal object representing php-fpm form
*/
$scope.deactivateSaveActions = function(formVal) {
formVal.$setPristine();
};
/**
* Reset form to initial state
*
* @scope
* @method resetPoolOptionsForm
* @param {Object} formVal object representing php-fpm form
*/
$scope.resetPoolOptionsForm = function(formVal) {
$scope.poolOptions = $scope.poolOptionsCache;
$scope.poolOptionsCache = angular.copy($scope.poolOptions);
formVal.$setPristine();
};
/**
* Check for duplicate entries in entered list, and existing list. Format each function for validation submission
*
* @method formatAndValidateFunctions
* @param {Array.<String>} funcs functions to format and validate
* @param {Object} formVal object representing php-fpm form
* @return {Array.<Promise>} if functions is a duplicate, return nothing, if it isn't return array of promises from validated functions
*/
function formatAndValidateFunctions(funcs, formVal) {
funcs = funcs.split(",");
funcs = formatListVals(funcs);
var optionForValidation;
var validationPromises = [];
var validationPromise;
for (var i = 0, len = funcs.length; i < len; i++) {
// checks for duplicates within the array entered and returns out of if()
// unless it is the last index of that function
if (funcs.indexOf(funcs[i]) !== -1 && funcs.indexOf(funcs[i], i + 1) !== -1) {
return;
}
// checks for duplicates in already existing function list
if ($scope.poolOptions.disable_functions.value.indexOf(funcs[i]) !== -1) {
var duplicateMessage = LOCALE.maketext("The “[_1]” function already appears on the disabled functions list.", _.escape(funcs[i]));
alertService.add({
type: "warning",
autoClose: 5000,
closeable: true,
message: duplicateMessage,
});
if (len === 1) {
return;
} else {
continue;
}
}
optionForValidation = {
disable_functions: {
value: [],
admin: $scope.poolOptions.disable_functions.admin,
},
};
optionForValidation.disable_functions.value.push(funcs[i]);
validationPromise = validateInlineOption(optionForValidation, true, $scope.displayValue.selectedDomain, formVal);
validationPromises.push(validationPromise);
}
return $q.all(validationPromises);
}
/**
* Check for duplicate entries in entered error list, and existing error list. Format each error for validation submission
*
* @method formatAndValidateErrs
* @param {Array.<String>} errs errors to format and validate
* @param {Object} formVal object representing php-fpm form
* @return {Array.<Promise>} if error is a duplicate, return nothing, if it isn't return array of promises from validated errors
*/
function formatAndValidateErrs(errs, formVal) {
errs = errs.split(",");
errs = formatListVals(errs);
var optionForValidation;
var validationPromises = [];
var validationPromise;
for (var i = 0, len = errs.length; i < len; i++) {
// checks for duplicates within the array entered and returns out of if()
// unless it is the last index of that function
if (errs.indexOf(errs[i]) !== -1 && errs.indexOf(errs[i], i + 1) !== -1) {
return;
}
// checks for duplicates in already existing function list
if ($scope.poolOptions.error_reporting.value.indexOf(errs[i]) !== -1) {
var duplicateMessage = LOCALE.maketext("The “[_1]” error already appears on the errors list.", _.escape(errs[i]));
alertService.add({
type: "warning",
autoClose: 5000,
closeable: true,
message: duplicateMessage,
});
if (len === 1) {
return;
} else {
continue;
}
}
optionForValidation = {
error_reporting: {
value: [],
admin: $scope.poolOptions.error_reporting.admin,
},
};
optionForValidation.error_reporting.value.push(errs[i]);
validationPromise = validateInlineOption(optionForValidation, true, $scope.displayValue.selectedDomain, formVal);
validationPromises.push(validationPromise);
}
return $q.all(validationPromises);
}
/**
* Remove leading and trailing spaces from each value
*
* @method formatListVals
* @param {Array.<String>} vals array of function or error values to format
* @return {Array.<String>} array of parsed error or function values
*/
function formatListVals(vals) {
var parsedVals = [];
function removeSpaceChars(val) {
var endIndex = val.length - 1;
if (val.indexOf(" ") !== 0 && val.indexOf(" ") !== endIndex) {
return val;
}
if (val.indexOf(" ") === 0) {
val = val.slice(1);
}
if (val.indexOf(" ") === endIndex) {
val = val.slice(0, endIndex);
}
return removeSpaceChars(val);
}
vals.forEach(function(val) {
val = removeSpaceChars(val);
parsedVals.push(val);
});
return parsedVals;
}
/**
* Validate options entered into disable_functions or error_reporting
*
* @method validateInlineOption
* @param {Object} poolOption name and value of option to validate
* @param {Boolean} validate boolean always set to true so that option is validated, not saved
* @param {String} [domain] if it exists then it is validating options for that domain, if it does not the options are validated for system config
* @param {[type]} formVal object representing php-fpm form
* @return {String | Promise} on success return value of option validated, on failure return error
*/
function validateInlineOption(poolOption, validate, domain, formVal) {
return configService.submitPoolOptions(poolOption, validate, domain)
.then(function(data) {
if (poolOption.disable_functions) {
$scope.poolOptions.disable_functions.value.push(poolOption.disable_functions.value[0]);
$scope.displayValue.disabledFuncsPanelOpen = true;
$scope.displayValue.disabledFuncs = "";
formVal.$setDirty();
return poolOption.disable_functions.value[0];
} else if (poolOption.error_reporting) {
$scope.displayValue.reportedErrs = "";
$scope.poolOptions.error_reporting.value.push(poolOption.error_reporting.value[0]);
$scope.displayValue.errsReportedPanelOpen = true;
formVal.$setDirty();
return poolOption.error_reporting.value[0];
}
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
});
});
}
/**
* Save or validate PHP-FPM form
*
* @method submitPoolOptions
* @param {Object} poolOptions names and value of pool options to submit
* @param {Boolean} validate if true options are validated, if false options are saved
* @param {String} [domain] if it exists options are saved/validated for individual domain, if it does not options are saved/validated for the system config
* @param {Object} formVal object representing php-fpm form
* @return {Promise}
*/
function submitPoolOptions(poolOptions, validate, domain, formVal) {
return configService.submitPoolOptions(poolOptions, validate, domain)
.then(function(data) {
var successMessage;
if (validate) {
successMessage = LOCALE.maketext("The system successfully validated the [asis,PHP-FPM] configuration.");
} else {
formVal.$setPristine();
$scope.poolOptionsCache = angular.copy(poolOptions);
successMessage = LOCALE.maketext("The system successfully saved the [asis,PHP-FPM] configuration.");
}
alertService.add({
type: "success",
message: successMessage,
autoClose: 5000,
});
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
});
});
}
/**
* Get document root from global value
*
* @method getDocRootValue
* @return {String} document root
*/
function getDocRootValue() {
return PAGE.selectedDomainDocRoot;
}
/**
* Get domain home directory from global value
*
* @method getHomeDirectory
* @return {String} domain home directory
*/
function getHomeDirectory() {
return PAGE.selectedDomainHomeDir;
}
/**
* Get selected domain name from global values
*
* @method getSelectedDomainName
* @return {String} selected domain value
*/
function getSelectedDomainName() {
return PAGE.selectedDomainName;
}
/**
* Get display mode from global values
*
* @method getDisplayMode
* @return {String} display mode
*/
function getDisplayMode() {
return PAGE.poolOptionsDisplayMode;
}
/**
* Parse location of error log for use by front end
*
* @method parseErrorLog
* @param {String} data raw error log location
* @return {String} parsed error log location
*/
function parseErrorLog(data) {
function replacer() {
return "_";
}
function removeLeadingChars(log) {
if (log.indexOf(".") === 0) {
return log;
}
log = log.slice(1);
return removeLeadingChars(log);
}
var scrubbedDomainSplitter = "[% scrubbed_domain %]";
var scrubbedDomain = $scope.displayValue.selectedDomain.replace(/\./, replacer);
var parsedErrorLog;
if (data.error_log.value.indexOf(scrubbedDomainSplitter) !== -1) {
parsedErrorLog = removeLeadingChars(data.error_log.value.split("scrubbed_domain")[1]);
parsedErrorLog = scrubbedDomain + parsedErrorLog;
data.error_log.value = parsedErrorLog;
}
return data;
}
/**
* Get existing pool options
*
* @method getPoolOptions
* @param {String} [domain] if it exists fetch pool options for individual domain, if it doesn't fetch system pool options
*/
function getPoolOptions(domain) {
return configService.getPHPFPMSettings(domain)
.then(function(data) {
if (domain) {
data = parseErrorLog(data);
}
$scope.poolOptions = data;
$scope.poolOptionsCache = angular.copy($scope.poolOptions);
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
});
})
.finally(function() {
scrollToFormTop();
$scope.actions.initialLoading = false;
});
}
/**
* Scroll to top of form
*
* @method scrollToFormTop
*/
function scrollToFormTop() {
$anchorScroll.yOffset = -100;
$anchorScroll("content");
}
/**
* Initialize app
*
* @method init
*/
function init() {
$scope.actions = {
initialLoading: true,
validatingFuncs: false,
validatingErrs: false,
};
$scope.displayValue.displayMode = getDisplayMode() || "default";
if ($scope.displayValue.displayMode === "domain") {
$scope.displayValue.docRootDisplayValue = getDocRootValue() + "/";
$scope.displayValue.logDirDisplayValue = getHomeDirectory() + "/logs/";
$scope.displayValue.selectedDomain = getSelectedDomainName();
getPoolOptions($scope.displayValue.selectedDomain);
} else {
getPoolOptions();
}
}
init();
}]
);
return controller;
}
);
/*
* templates/multiphp_manager/views/phpManagerConfig.js
* Copyright 2022 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
/* eslint no-use-before-define: 0*/
define(
'app/views/phpManagerConfig',[
"angular",
"lodash",
"cjt/util/locale",
"cjt/util/parse",
"cjt/util/table",
"uiBootstrap",
"cjt/directives/alertList",
"cjt/services/alertService",
"cjt/decorators/paginationDecorator",
"cjt/directives/toggleSortDirective",
"cjt/directives/actionButtonDirective",
"app/services/configService",
"app/views/impactedDomainsPopup",
"app/views/poolOptions"
],
function(angular, _, LOCALE, PARSE, Table) {
"use strict";
// Retrieve the current application
var app = angular.module("App");
var controller = app.controller(
"phpManagerController",
["$scope", "$rootScope", "$q", "configService", "$timeout", "$uibModal", "alertService", "PAGE", "$interval",
function($scope, $rootScope, $q, configService, $timeout, $uibModal, alertService, PAGE, $interval) {
$rootScope.$on("returnToDomainList", function() {
$rootScope.editPoolOptionsMode = false;
if (PAGE.poolOptionsDisplayMode) {
delete PAGE.poolOptionsDisplayMode;
}
});
$rootScope.litespeedRunning = PARSE.parsePerlBoolean(PAGE.litespeed_running);
var altRegex = /^alt/;
var eolWarningMsgLastPart = LOCALE.maketext("We recommend that you update to a supported version of [asis,PHP]. [output,url,_1,Learn more about supported versions,target,_2].", "http://php.net/supported-versions.php", "_blank");
$scope.actions = {
initialDataLoading: true,
loadingFPMInfo: false,
fetchingImpactedDomains: false,
settingSystemPHP: false,
fpmConversionRunning: false,
fpmConversionRunningOnLoad: false,
loadingAccountList: false
};
$scope.php = {
versions: [],
versionsInherit: [],
systemDefault: {
version: "",
displayVersion: "",
hasFPMInstalled: false,
showEolMsg: false,
eolWarningMsg: LOCALE.maketext("[output,strong,Warning]: Your system’s [asis,PHP] version has reached [output,acronym,EOL,End Of Life].") + " " + eolWarningMsgLastPart
},
showEolMsg: false,
eolWarningMsg: "",
perDomain: {
selected: ""
},
accountList: [],
compatibleVersions: [],
installedVersion: [],
systemEditView: false,
totalSelectedDomains: 0,
paginationMessage: "",
inheritWarning: LOCALE.maketext("[asis,PHP-FPM] option is disabled when one or more selections contain PHP version of [output,em,inherit]."),
incompatibleWarning: LOCALE.maketext("[asis,PHP-FPM] option is disabled when one or more selections contain PHP version that doesn’t have corresponding [asis,PHP-FPM] package installed."),
noVersions: false,
};
$scope.fpm = {
completePackageData: [],
checkingFPMPackage: false,
fpmPackageNeeded: false,
flag: false,
showMemoryWarning: false,
systemStatus: false,
requiredMemoryAmount: 0,
ea4ReviewLink: "",
fcgiMissing: false,
ea4Went: false,
conversionTimer: null,
conversionTimerInterval: 3000,
convertBuildId: null,
fpmConversionStarted: false,
domainSelection: 0,
missingPackages: [],
fpmWarning: LOCALE.maketext("The [output,em,inherit] option of [asis,PHP] Version is disabled when one or more selections have [asis,PHP-FPM] on.")
};
$scope.applyingPHPVersionTo = [];
var domainTable = new Table();
// Add more pageSizes.
domainTable.meta.pageSizes = _.concat(domainTable.meta.pageSizes, [500, 1000]);
var searchByDomainOrAccount = function(account, searchExpression) {
searchExpression = searchExpression.toLowerCase();
return account.account.toLowerCase().indexOf(searchExpression) !== -1 ||
account.vhost.toLowerCase().indexOf(searchExpression) !== -1 || account.account_owner.toLowerCase().indexOf(searchExpression) !== -1;
};
domainTable.setSearchFunction(searchByDomainOrAccount);
domainTable.setSort("vhost,account,account_owner,version,php_fpm", "asc");
$scope.meta = domainTable.getMetadata();
$scope.getFPMInfo = function() {
return getFPMInfo();
};
$scope.setFPMFlag = function() {
$scope.fpm.flag = false;
return configService.setFPMFlag();
};
$scope.editSystemPHP = function(toEditMode) {
if (toEditMode) {
$scope.php.systemEditView = true;
$scope.impactedDomains = {};
preSelectSystemValue();
processImpactedDomains("system_default", true, $scope.impactedDomains, true);
} else {
$scope.php.systemEditView = false;
}
};
$scope.applySystemPHP = function() {
return setSystemPHPVersion($scope.php.systemDefault.selected);
};
$scope.requiredMemory = function() {
return LOCALE.maketext("Your system requires [format_bytes,_1] of memory to convert the remaining domains to [asis,PHP-FPM].", $scope.fpm.requiredMemoryAmount);
};
$scope.switchSystemFPM = function() {
$scope.fpm.systemStatus = !$scope.fpm.systemStatus;
var status = $scope.fpm.systemStatus ? 1 : 0;
switchSystemFPM(status);
};
$scope.convertAllAccountsToFPM = function() {
return convertAllAccountsToFPM();
};
var addImpactedDomainsTo = function(vhost) {
if (typeof vhost.impactedDomains === "undefined") {
vhost.impactedDomains = {};
}
processImpactedDomains("domain", vhost.vhost, vhost.impactedDomains, vhost.selected);
};
$scope.handleEntireListSelection = function() {
var areAllSelected = domainTable.areAllDisplayedRowsSelected();
if (areAllSelected) {
domainTable.unselectAllDisplayed();
} else {
domainTable.selectAllDisplayed();
}
$scope.php.totalSelectedDomains = domainTable.getTotalRowsSelected();
$scope.php.accountList = domainTable.getList();
};
$scope.handleSingleListSelection = function(vhost) {
addImpactedDomainsTo(vhost);
if (vhost.selected) {
domainTable.selectItem(vhost);
} else {
domainTable.unselectItem(vhost);
}
$scope.php.allRowsSelected = domainTable.areAllDisplayedRowsSelected();
$scope.php.totalSelectedDomains = domainTable.getTotalRowsSelected();
$scope.php.accountList = domainTable.getList();
};
$scope.searchByDomainOrAccount = function() {
domainTable.update();
$scope.php.accountList = domainTable.getList();
$scope.meta = domainTable.getMetadata();
$scope.php.paginationMessage = domainTable.paginationMessage();
};
$scope.areRowsSelected = function() {
var rowsSelected = domainTable.getTotalRowsSelected();
if (rowsSelected === 0) {
return true;
} else {
return false;
}
};
$scope.applyPHPToMultipleAccounts = function() {
var version = $scope.php.perDomain.selected.version;
var vhostList = [];
var domains = domainTable.getSelectedList();
domains.forEach(function(domain) {
vhostList.push(domain.vhost);
});
$scope.php.accountList = domainTable.getList();
return applyPHPVersionToAccounts(version, vhostList);
};
$scope.applyPHPToSingleAccount = function(account) {
if (account.version === "inherit" && account.php_fpm) {
var version = account.display_php_version.split(" ")[2];
var endPoint = version.length - 2;
account.version = version.substr(1, endPoint);
return;
}
var vhostList = [];
vhostList.push(account.vhost);
applyPHPVersionToAccounts(account.version, vhostList);
};
$scope.isAnyDomainInherited = function() {
var accounts = domainTable.getSelectedList();
for (var i = 0, len = accounts.length; i < len; i++) {
if (accounts[i].inherited) {
return true;
}
}
return false;
};
$scope.isAnyDomainFPM = function() {
var accounts = domainTable.getSelectedList();
for (var i = 0, len = accounts.length; i < len; i++) {
if (accounts[i].php_fpm) {
return true;
}
}
return false;
};
$scope.updateTable = function() {
domainTable.update();
$scope.php.accountList = domainTable.getList();
$scope.meta = domainTable.getMetadata();
$scope.php.paginationMessage = domainTable.paginationMessage();
};
$scope.isAnyDomainIncompatible = function() {
var accounts = domainTable.getSelectedList();
var compatibleVersions = [];
$scope.php.compatibleVersions.forEach(function(version) {
version = version.split("-php-fpm")[0];
compatibleVersions.push(version);
});
for (var i = 0, len = accounts.length; i < len; i++) {
if (compatibleVersions.indexOf(accounts[i].version) === -1) {
return true;
}
}
return false;
};
$scope.isDomainVersionIncompatible = function(domainVersion) {
// always return false if domainVersion is "inherit"
if (domainVersion === "inherit") {
return false;
}
var compatibleVersions = [];
$scope.php.compatibleVersions.forEach(function(version) {
version = version.split("-php-fpm")[0];
compatibleVersions.push(version);
});
for (var i = 0, len = compatibleVersions.length; i < len; i++) {
if (domainVersion === compatibleVersions[i]) {
return false;
}
}
return true;
};
$scope.setMultipleDomainFPM = function() {
$scope.actions.applyingFPM = true;
var vhostList = [];
var selectedAccounts = domainTable.getSelectedList();
selectedAccounts.forEach(function(account) {
vhostList.push(account.vhost);
});
return applyDomainFPM($scope.fpm.domainSelection, vhostList);
};
$scope.setSingleDomainFPM = function(domain) {
var domainValue = domain.php_fpm ? 0 : 1;
var vhostList = [];
vhostList.push(domain.vhost);
return applyDomainFPM(domainValue, vhostList);
};
$scope.showAllImpactedDomains = function() {
var modalData = $scope.impactedDomains;
$uibModal.open({
templateUrl: "impactedDomainsPopup.ptt",
controller: "impactedDomainsPopup",
resolve: {
data: function() {
return modalData;
}
}
});
};
$scope.setPoolOptionsDisplayValues = function(vhost) {
PAGE.poolOptionsDisplayMode = "domain";
PAGE.selectedDomainHomeDir = vhost.homedir;
PAGE.selectedDomainDocRoot = vhost.documentroot;
PAGE.selectedDomainName = vhost.vhost;
$rootScope.editPoolOptionsMode = true;
};
var getPHPVersions = function() {
return configService
.fetchPHPVersions()
.then(function(results) {
$scope.php.versions = createPHPDisplayVersions(results);
$scope.php.versionsInherit = createPHPVersionListInherit($scope.php.versions);
})
.catch(function(error) {
// No PHP version error is displayed as callout, so it does not also need to be an alert
if (error.indexOf("“PHP” is not installed on the system") === -1) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "getPHPVersionsError"
});
}
});
};
var getSystemPHP = function() {
return configService.fetchSystemPhp()
.then(function(results) {
$scope.php.systemDefault.version = results.version;
$scope.php.systemDefault.displayVersion = configService.transformPhpFormat(results.version);
})
.catch(function(error) {
// No PHP version error is displayed as callout, so it does not also need to be an alert
if (error.indexOf("“PHP” is not installed on the system") === -1) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "getSystemPHPError"
});
}
});
};
var validatePoolOption = function(input, max) {
var value = parseInt(input, 10);
if (isNaN(value)) {
return false;
} else if (value <= 0) {
return false;
} else if (value > max) {
return false;
}
return true;
};
var savePoolOptions = function(vhost) {
return configService.savePoolOption(vhost)
.then(function(data) {
alertService.add({
type: "success",
message: LOCALE.maketext("The system successfully updated the pool options for the domain “[_1]”.", vhost.vhost),
autoClose: 5000,
id: "poolOptionsSuccessMessage-" + vhost.vhost
});
})
.catch(function(error) {
alertService.add({
type: "danger",
message: LOCALE.maketext("Failed to apply [asis,PHP-FPM] Pool options to the selected domain."),
closeable: true,
id: "poolOptionsError"
});
})
.finally(function() {
getAccountList();
});
};
var applyDomainFPM = function(domainValue, selectedVhostList) {
$scope.actions.applyingFPM = true;
return configService.applyDomainFpm(domainValue, selectedVhostList)
.then(function(data) {
alertService.add({
type: "success",
message: LOCALE.maketext("The system successfully updated the [asis,PHP-FPM] setting."),
autoClose: 5000,
id: "phpFPMSuccessMessage"
});
})
.catch(function(error) {
alertService.add({
type: "danger",
message: _.escape(error),
closeable: true,
id: "domainFPMError"
});
})
.finally(function() {
$scope.actions.applyingFPM = false;
getAccountList();
});
};
var applyPHPVersionToAccounts = function(version, vhostList) {
$scope.actions.applyingPHPVersion = true;
$scope.applyingPHPVersionTo = vhostList.slice();
return configService.applyDomainSetting(version, vhostList)
.then(function(data) {
alertService.add({
type: "success",
message: LOCALE.maketext("The system successfully updated the [asis,PHP] version to “[_1]”.", version),
autoClose: 5000,
id: "phpDomainSuccessMessage"
});
})
.catch(function(error) {
alertService.add({
type: "danger",
message: _.escape(error),
closeable: true,
id: "domainVersionError"
});
})
.finally(function() {
// add a little delay so updating message is easier to read
$timeout(function() {
$scope.actions.applyingPHPVersion = false;
$scope.applyingPHPVersionTo = [];
}, 500);
getAccountList();
});
};
$scope.phpConversionInProgressFor = function(acct) {
return $scope.applyingPHPVersionTo.indexOf(acct) !== -1;
};
$scope.processInProgress = function() {
return $scope.actions.loadingAccountList || $scope.actions.applyingPHPVersion || $scope.actions.applyingFPM || $scope.fpm.fpmConversionStarted;
};
var convertAllAccountsToFPM = function() {
$scope.fpm.fpmConversionStarted = true;
return configService.convertAllAccountsToFPM()
.then(function(data) {
$scope.fpm.convertBuildId = data.build;
return monitorConversionStatus();
})
.catch(function(error) {
if (error === "canceled") {
$scope.fpm.conversionTimer = null;
} else {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "convertAllAccountsError"
});
}
})
.finally(function() {
$scope.fpm.fpmConversionStarted = false;
getAccountList();
});
};
var switchSystemFPM = function(newStatus) {
return configService.switchSystemFPM(newStatus)
.then(function(data) {
fetchFPMSystemStatus();
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "fpmSystemSwitchError"
});
});
};
var fetchFPMSystemStatus = function() {
return configService.fetchFPMStatus()
.then(function(data) {
$scope.fpm.systemStatus = PARSE.parsePerlBoolean(data.default_accounts_to_fpm);
});
};
var monitorConversionStatus = function() {
$scope.fpm.conversionTimer = $interval(function() {
configService.conversionInProgress()
.then(function(inProgress) {
$scope.actions.fpmConversionRunning = inProgress;
if (!inProgress) {
$scope.actions.fpmConversionRunning = false;
$scope.actions.fpmConversionRunningOnLoad = false;
$interval.cancel($scope.fpm.conversionTimer);
}
});
}, $scope.fpm.conversionTimerInterval);
return $scope.fpm.conversionTimer;
};
var setSystemPHPVersion = function(phpVersion) {
$scope.actions.settingSystemPHP = true;
alertService.clear();
return configService.applySystemSetting(phpVersion.version)
.then(function(data) {
if (data !== undefined) {
alertService.add({
type: "success",
message: LOCALE.maketext("The system default [asis,PHP] version has been set to “[_1]”.", phpVersion.displayVersion),
autoClose: 10000,
id: "phpSystemSuccess"
});
$scope.php.systemDefault.version = phpVersion.version;
$scope.php.systemDefault.displayVersion = configService.transformPhpFormat(phpVersion.version);
$scope.php.toggleEolWarning("systemDefault", isPhpEol($scope.php.systemDefault.version));
}
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "phpSystemError"
});
})
.finally(function() {
runFPMPackageCheck($scope.fpm.completePackageData);
$scope.php.systemEditView = false;
$scope.actions.settingSystemPHP = false;
getAccountList();
});
};
var preSelectSystemValue = function() {
for (var i = 0, len = $scope.php.versions.length; i < len; i++) {
if ($scope.php.versions[i].version === $scope.php.systemDefault.version) {
$scope.php.systemDefault.selected = $scope.php.versions[i];
return;
}
}
};
var processImpactedDomains = function(type, value, impactedDomains, selected) {
if (selected) {
// Currently there are only two types: domain (string value), system_default (bool value).
$scope.actions.fetchingImpactedDomains = true;
configService.fetchImpactedDomains(type, value)
.then(function(result) {
var domains = result.data;
if (result.status && domains.length > 0) {
impactedDomains.show = impactedDomains.warn = true;
impactedDomains.showMore = domains.length > 10;
var displayText = ( type === "domain" ) ?
LOCALE.maketext("A change to the “[output,strong,_1]” domain‘s PHP version affects the following domains:", value)
:
LOCALE.maketext("A change to the system default PHP version affects the following domains:");
impactedDomains.text = displayText;
impactedDomains.domains = _.sortBy(domains);
}
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "fetchImpactedDomainsError"
});
impactedDomains.show = impactedDomains.warn = false;
})
.finally(function() {
$scope.actions.fetchingImpactedDomains = false;
$scope.impactedDomains = impactedDomains;
});
} else {
impactedDomains.show = impactedDomains.warn = false;
$scope.impactedDomains = impactedDomains;
}
};
var formatFPMMemoryNeeded = function(fpmData) {
var memoryRequired = fpmData.environment.memory_needed * 1024;
return memoryRequired;
};
var checkFPMSystemStatus = function(fpmData) {
var systemStatus = PARSE.parsePerlBoolean(fpmData.status.default_accounts_to_fpm);
return systemStatus;
};
var checkFPMMemoryWarning = function(fpmData) {
var showMemoryWarning = PARSE.parsePerlBoolean(fpmData.environment.show_warning);
if (showMemoryWarning) {
$scope.fpm.requiredMemoryAmount = formatFPMMemoryNeeded(fpmData);
}
return showMemoryWarning;
};
var createFPMPackageCheckList = function(phpVersions) {
var fpmPackageChecklist = [];
phpVersions.forEach(function(version) {
if (version.version !== "inherit" && !altRegex.test(version.version)) {
fpmPackageChecklist.push(version.version);
}
});
// Add ea-apache24-mod_proxy_fcgi in addition to php versions
fpmPackageChecklist.push("ea-apache24-mod_proxy_fcgi");
return fpmPackageChecklist;
};
var isSystemPHPFPMInstalled = function(fpmPackages, phpSystemDefault) {
phpSystemDefault = phpSystemDefault + "-php-fpm";
for (var i = 0, len = fpmPackages.length; i < len; i++) {
if (phpSystemDefault === fpmPackages[i].package) {
return true;
}
}
return false;
};
var createMissingPackageDisplayVersions = function(fpmPackageChecklist) {
var displayVersions = "";
if (fpmPackageChecklist[0] === "ea-apache24-mod_proxy_fcgi") {
fpmPackageChecklist.shift();
}
fpmPackageChecklist.forEach(function(fpmPackage) {
if (fpmPackage !== "ea-apache24-mod_proxy_fcgi") {
fpmPackage = fpmPackage.split("ea-php");
fpmPackage = fpmPackage[1].split("-php-fpm");
fpmPackage = fpmPackage[0].split("").join(".");
}
displayVersions = displayVersions + fpmPackage + ", ";
});
return displayVersions;
};
var checkCompatibleVersions = function(fpmPackages, fpmPackageChecklist) {
var compatibleVersions = [];
var installedVersions = [];
var extendedPackageChecklist = [];
fpmPackageChecklist.forEach(function(fpmPackage) {
if (fpmPackage !== "ea-apache24-mod_proxy_fcgi") {
fpmPackage = fpmPackage + "-php-fpm";
}
extendedPackageChecklist.push(fpmPackage);
});
for (var i = 0, len = fpmPackages.length; i < len; i++) {
for (var j = 0, length = extendedPackageChecklist.length; j < length; j++) {
if (fpmPackages[i].package === extendedPackageChecklist[j]) {
installedVersions.push(fpmPackages[i].package);
if (fpmPackages[i].package !== "ea-apache24-mod_proxy_fcgi") {
compatibleVersions.push(fpmPackages[i].package);
}
extendedPackageChecklist.splice(extendedPackageChecklist.indexOf(fpmPackages[i].package), 1);
}
}
}
$scope.fpm.missingPackagesDisplay = createMissingPackageDisplayVersions(extendedPackageChecklist);
$scope.php.installedVersion = createMissingPackageDisplayVersions(installedVersions).slice(0, $scope.php.installedVersion.length - 2);
$scope.php.compatibleVersions = compatibleVersions;
$scope.fpm.missingPackages = extendedPackageChecklist;
};
var createQueryLink = function(fpmPackageChecklist) {
var queryString =
_.join(
_.map(fpmPackageChecklist,
function(fpmPkg) {
return "install=" + fpmPkg;
}
), "&"
);
return PAGE.cp_security_token + "/scripts7/EasyApache4/review?" + queryString;
};
var isFcgiMissing = function(fpmMissingPackages) {
if ($scope.fpm.missingPackages.indexOf("ea-apache24-mod_proxy_fcgi") !== -1) {
return true;
} else {
return false;
}
};
var runFPMPackageCheck = function(fpmPackageData) {
$scope.fpm.packageChecklist = createFPMPackageCheckList($scope.php.versions);
$scope.php.systemDefault.hasFPMInstalled = isSystemPHPFPMInstalled(fpmPackageData, $scope.php.systemDefault.version);
// fpm.packageChecklist turns into fpm.missingPackages here
checkCompatibleVersions(fpmPackageData, $scope.fpm.packageChecklist);
if ($scope.fpm.missingPackages.length) {
$scope.fpm.ea4ReviewLink = createQueryLink($scope.fpm.missingPackages);
}
$scope.fpm.fcgiMissing = isFcgiMissing($scope.fpm.missingPackages);
};
var getFPMInfo = function() {
$scope.actions.loadingFPMInfo = true;
return configService.getPHPFPMInfo()
.then(function(data) {
$scope.fpm.completePackageData = data.packages;
$scope.fpm.systemStatus = checkFPMSystemStatus(data);
$scope.fpm.showMemoryWarning = checkFPMMemoryWarning(data);
runFPMPackageCheck(data.packages);
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "fetchFPMInfoError"
});
})
.finally(function() {
$scope.actions.loadingFPMInfo = false;
});
};
var createPHPDisplayVersions = function(phpVersions) {
var versionObj;
var versions = [];
phpVersions.forEach(function(version) {
versionObj = {};
versionObj["version"] = version;
versionObj["displayVersion"] = configService.transformPhpFormat(version);
versions.push(versionObj);
});
return versions;
};
var labelInheritedAccounts = function(phpAccountList) {
phpAccountList.forEach(function(account) {
if ( typeof account.phpversion_source !== "undefined" ) {
var type = "", value = "";
if ( typeof account.phpversion_source.domain !== "undefined" ) {
type = "domain";
value = account.phpversion_source.domain;
} else if (typeof account.phpversion_source.system_default !== "undefined") {
type = "system_default";
value = LOCALE.maketext("System Default");
}
if ((type === "domain" && value !== account.vhost) ||
type === "system_default") {
account.version = "inherit";
account.displayVersion = "inherit (" + $scope.php.systemDefault.version + ")";
account.inherited = true;
account.inheritedInfo = LOCALE.maketext("This domain inherits its [asis,PHP] version “[output,em,_1]” from: [output,strong,_2]", account.display_php_version, value);
}
}
});
return phpAccountList;
};
var labelUnavailableAccounts = function(phpAccountList) {
var phpVersions = [];
$scope.php.versions.forEach(function(version) {
phpVersions.push(version.version);
});
phpAccountList.forEach(function(account) {
if (account.version === "inherit") {
account.isUnavailableVersion = false;
} else if (phpVersions.indexOf(account.version) === -1) {
account.isUnavailableVersion = true;
account.isUnavailableVersionMessage = LOCALE.maketext("The domain ‘[_1]’ uses a PHP version, ‘[_2]’, that no longer exists in the system. You must select a new PHP version for this domain.", account.vhost, account.version);
} else {
account.isUnavailableVersion = false;
}
});
return phpAccountList;
};
var createAccountTable = function(phpAccountList) {
phpAccountList = labelInheritedAccounts(phpAccountList);
phpAccountList = labelUnavailableAccounts(phpAccountList);
domainTable.load(phpAccountList);
domainTable.update();
$scope.meta = domainTable.getMetadata();
$scope.php.accountList = domainTable.getList();
$scope.php.paginationMessage = domainTable.paginationMessage();
};
var createPHPVersionListInherit = function(phpVersionList) {
var clonedList = phpVersionList.slice();
clonedList.push({
version: "inherit",
displayVersion: "inherit"
});
return clonedList;
};
var preSelectPerDomainValue = function() {
for (var i = 0, len = $scope.php.versionsInherit.length; i < len; i++) {
if ($scope.php.versionsInherit[i].version === $scope.php.systemDefault.version) {
$scope.php.perDomain.selected = $scope.php.versionsInherit[i];
return;
}
}
};
var setInitialPHPFPMData = function() {
if (PAGE.php_versions.data) {
$scope.actions.fpmConversionRunning = $scope.actions.fpmConversionRunningOnLoad = PARSE.parsePerlBoolean(PAGE.fpm_conversion_in_progress);
$scope.php.noVersions = false;
} else {
$scope.php.noPHPVersionsError = PAGE.php_versions.metadata.reason;
$scope.php.noVersions = true;
}
if ($scope.actions.fpmConversionRunning) {
monitorConversionStatus();
}
};
var getAccountList = function() {
$scope.actions.loadingAccountList = true;
clearTable();
return configService.fetchList()
.then(function(data) {
createAccountTable(data.items);
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "fetchTableListError"
});
})
.finally(function() {
$scope.php.allRowsSelected = false;
$scope.actions.loadingAccountList = false;
});
};
var clearTable = function() {
domainTable.clear();
$scope.php.totalSelectedDomains = 0;
};
var clearPoolOptionsDisplaySettings = function() {
$rootScope.editPoolOptionsMode = false;
if (PAGE.poolOptionsDisplayMode) {
delete PAGE.poolOptionsDisplayMode;
}
};
var isPhpEol = function(phpVer) {
return _.includes($scope.php.eolPhps, phpVer);
};
$scope.php.eolWarningClass = function(type) {
var cssClass = "";
switch (type) {
case "systemDefault":
if ($scope.php.systemDefault.showEolMsg) {
cssClass = "system eol-warning";
}
break;
default:
cssClass = "";
}
return cssClass;
};
$scope.php.toggleEolWarning = function(type, show) {
switch (type) {
case "systemDefault":
$scope.php.systemDefault.showEolMsg = show;
break;
}
if (show) {
$scope.php.eolWarningClass(type);
} else {
$scope.php.eolWarningClass();
}
};
var setPhpEolData = function() {
var eolPhps = [];
if ($scope.php.versions.length > 0) {
return configService.getEA4Recommendations()
.then(function(result) {
if (result && typeof result.data !== "undefined") {
var keys = _.filter(_.keys(result.data), function(key) {
return (/^ea-php\d{2}$/.test(key));
});
// Extract only the keys for the installed PHPs.
keys = _.sortBy(_.intersection(keys, _.map($scope.php.versions, "version")));
_.each(keys, function(key) {
_.each(result.data[key], function(reco) {
if (_.includes(reco.filter, "eol")) {
eolPhps.push(key);
}
});
});
if (eolPhps.length > 0) {
$scope.php.eolPhps = eolPhps;
var displayEolPhps = _.map(eolPhps, function(php) {
return configService.friendlyPhpFormat(php);
});
var eolWarningMsg = LOCALE.maketext("[output,strong,Warning]: The [asis,PHP] [numerate,_2,version,versions] [list_and,_1] [numerate,_2,has,have] reached [output,acronym,EOL,End Of Life].", displayEolPhps, eolPhps.length) + " " + eolWarningMsgLastPart;
$scope.php.showEolMsg = true;
$scope.php.eolWarningMsg = eolWarningMsg;
}
}
})
.catch(function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
id: "recommendationsError"
});
});
}
};
var init = function() {
// ===No API calls===
clearPoolOptionsDisplaySettings();
$scope.clData = PAGE.cl_data;
$scope.clBannerText = LOCALE.maketext("[output,strong,cPanel] provides the most recent stable versions of PHP. If you require legacy versions of PHP, such as PHP [list_and,_3], [asis,CloudLinux] provides hardened and secured [asis,PHP] versions that are patched against all known vulnerabilities. To learn more about [asis,CloudLinux] Advanced PHP Features, please read [output,url,_1,Hardened PHP versions on CloudLinux,target,_2].", "https://go.cpanel.net/cloudlinuxhardenedphp", "_blank", [4.4, 5.1, 5.2, 5.3]);
setInitialPHPFPMData();
// ===API calls===
var promises = {
info: getFPMInfo(),
versions: getPHPVersions(),
system: getSystemPHP()
};
$q.all(promises)
.then(function(data) {
setPhpEolData();
preSelectPerDomainValue();
return getAccountList();
})
.finally(function(data) {
$timeout(function() {
// $scope.php.systemDefault.eolWarningMsg = systemEolWarningMsg;
$scope.php.toggleEolWarning("systemDefault", isPhpEol($scope.php.systemDefault.version));
}, 0);
$scope.actions.initialDataLoading = false;
});
};
init();
}
]);
return controller;
}
);
/*
* templates/multiphp_manager/views/phpHandlers.js Copyright(c) 2020 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
define(
'app/views/phpHandlers',[
"angular",
"lodash",
"cjt/util/locale",
"uiBootstrap",
"cjt/directives/alertList",
"cjt/services/alertService",
"app/services/configService"
],
function(angular, _, LOCALE) {
// Retrieve the current application
var app = angular.module("App");
var controller = app.controller(
"phpHandlers",
["$scope", "$location", "$routeParams", "$timeout", "$filter", "configService", "spinnerAPI", "alertService", "growl", "growlMessages", "$anchorScroll", "PAGE",
function($scope, $location, $routeParams, $timeout, $filter, configService, spinnerAPI, alertService, growl, growlMessages, $anchorScroll, PAGE) {
// Setup data structures for the view
$scope.loadingVersionsList = false;
$scope.phpVersionsEmpty = true;
$scope.meta = {
// Sort settings
sortReverse: false,
sortBy: "version",
sortDirection: "asc"
};
var orderBy = $filter("orderBy");
$scope.sortList = function() {
// sort the filtered list
if ($scope.meta.sortDirection !== "" && $scope.meta.sortBy !== "") {
$scope.phpVersionHandlerList = orderBy($scope.phpVersionHandlerList, $scope.meta.sortBy, $scope.meta.sortDirection === "asc" ? true : false);
}
};
$scope.editPhpHandler = function(itemToEdit) {
// set that record's editView = true;
itemToEdit.editView = true;
};
var clearConflictView = function(item) {
item.conflicts = [];
item.showAlert = false;
};
var applyListToTable = function(resultList) {
var versionList = resultList.items;
$scope.phpVersionHandlerList = versionList.map(function(item) {
item.editView = false;
item.conflicts = []; // Records all the conflicts that happen when a handler is changed.
item.showAlert = false; // Used when conflicts/warnings need to be shown
item.originalHandler = item.current_handler; // Used to decide when to show/hide warning.
return item;
});
};
$scope.cancelHandlerEdit = function(item) {
item.editView = false;
item.current_handler = item.originalHandler;
clearConflictView(item);
};
/**
* Fetch the list of PHP versions with their associated handlers.
* @return {Promise} Promise that will result in the list being loaded with the PHP versions with handlers.
*/
$scope.fetchVersionHandlerList = function() {
$scope.loadingVersionsList = true;
return configService
.fetchVersionHandlerList()
.then(function(results) {
applyListToTable(results);
$scope.lsApiInstalled = _.includes(_.uniq(
_.flatten(
_.map($scope.phpVersionHandlerList, "available_handlers")
)
), "lsapi");
}, function(error) {
// failure
growl.error(error);
})
.then(function() {
$scope.loadingVersionsList = false;
});
};
// Apply the new PHP version setting of a selected user
$scope.applyVersionHandler = function(item) {
growlMessages.destroyAllMessages();
clearConflictView(item);
return configService.applyVersionHandler(item.version, item.current_handler)
.then(
function(success) {
if (success) {
growl.success(LOCALE.maketext("Successfully applied the “[_1]” [asis,PHP] handler to the “[_2]” package.", item.current_handler, item.version));
item.originalHandler = item.current_handler;
item.editView = false;
}
})
.catch(function(error) {
growl.error(_.escape(error));
});
};
$scope.warnUser = function(versionHandler, originalHandler) {
if ( versionHandler.current_handler !== originalHandler ) {
versionHandler.showAlert = true;
} else {
versionHandler.showAlert = false;
}
};
$scope.$on("$viewContentLoaded", function() {
growlMessages.destroyAllMessages();
$scope.fetchVersionHandlerList();
$scope.clData = PAGE.cl_data;
$scope.clBannerText = LOCALE.maketext("To utilize the [asis,LSAPI] handler’s full functionality and performance benefits, upgrade your system to [asis,CloudLinux]. To learn more about this feature, please read [output,url,_1,CloudLinux - Mod_lsapi Feature,target,_2].", "https://go.cpanel.net/CL-lsapi", "blank");
});
}
]);
return controller;
}
);
/*
* templates/multiphp_manager/views/conversion.js Copyright(c) 2020 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
define(
'app/views/conversion',[
"angular",
"lodash",
"cjt/util/locale",
"uiBootstrap"
],
function(angular, _, LOCALE) {
// Retrieve the current application
var app = angular.module("App");
var controller = app.controller(
"conversion",
["$scope", "$sce", "$routeParams",
function($scope, $sce, $routeParams) {
$scope.buildId = $routeParams.buildId;
// Create iframe to load the tailing cgi script
$scope.tailingUrl = CPANEL.security_token + "/cgi/process_tail.cgi?process=ConvertToFPM&build_id=" + $scope.buildId;
$scope.tailingUrl = $sce.trustAsResourceUrl($scope.tailingUrl);
}
]);
return controller;
}
);
/*
# templates/multiphp_manager/directives/cloudLinuxBanner.js Copyright 2022 cPanel, L.L.C.
# All rights reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
define(
'app/directives/cloudLinuxBanner',[
"angular",
"cjt/core",
"cjt/util/locale",
"cjt/util/parse",
"app/services/configService"
],
function(angular, CJT, LOCALE, PARSE) {
"use strict";
// Retrieve the current application
var app = angular.module("whm.multiphpManager.cloudLinuxBanner", []);
/**
* This is a directive that renders CloudLinux banner where it is needed.
*
* Basic usage in a template:
* <cloud-linux-banner id-prefix="someIdPrefix"
cl-data = clDataObjectFromApi
banner-text="clBannerTextFromView">
* </cloud-linux-banner>
*/
app.directive("cloudLinuxBanner",
["configService",
function(configService) {
var TEMPLATE_PATH = "directives/cloudLinuxBanner.ptt";
var RELATIVE_PATH = "templates/multiphp_manager/" + TEMPLATE_PATH;
var checkToHideUpgradeOption = function(data) {
var purchaseData = data.purchase_cl_data;
return (purchaseData.server_timeout ||
(purchaseData.error_msg && purchaseData.error_msg !== ""));
};
var ddo = {
replace: true,
restrict: "E",
templateUrl: CJT.config.debug ? CJT.buildFullPath(RELATIVE_PATH) : TEMPLATE_PATH,
scope: {
idPrefix: "@",
clData: "=",
bannerText: "="
},
link: function postLink(scope, element, attrs) {
var scopeData = configService.setCloudLinuxInfo(scope.clData);
scope.data = scopeData.data;
scope.linkTarget = scopeData.linkTarget;
scope.purchaseLink = scopeData.purchaseLink;
scope.showBanner = scopeData.showBanner;
scope.actionText = scopeData.actionText;
scope.hideUpgradeOption = checkToHideUpgradeOption(scope.data);
}
};
return ddo;
}
]
);
}
);
/*
* templates/multiphp_manager/directives/nonStringSelect.js Copyright(c) 2020 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false */
define(
'app/directives/nonStringSelect',[
"angular",
],
function(angular) {
// Retrieve the current application
var app = angular.module("App");
var controller = app.directive("convertToNumber", function() {
return {
require: "ngModel",
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
return parseInt(val, 10);
});
ngModel.$formatters.push(function(val) {
return "" + val;
});
}
};
});
return controller;
}
);
/*
* templates/multiphp_manager/index.js Copyright(c) 2020 cPanel, L.L.C.
* All rights reserved.
* copyright@cpanel.net http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global require, define, PAGE */
define(
'app/index',[
"angular",
"jquery",
"lodash",
"cjt/core",
"cjt/modules",
"ngRoute",
"uiBootstrap"
],
function(angular, $, _, CJT) {
return function() {
// First create the application
angular.module("App", [
"cjt2.config.whm.configProvider", // This needs to load first
"ngRoute",
"ui.bootstrap",
"cjt2.whm",
"whm.multiphpManager.cloudLinuxBanner"
]);
// Then load the application dependencies
var app = require(
[
"cjt/bootstrap",
// Application Modules
"app/views/phpManagerConfig",
"app/views/phpHandlers",
"app/views/conversion",
"app/directives/cloudLinuxBanner",
"app/views/poolOptions",
"app/directives/nonStringSelect",
"cjt/directives/actionButtonDirective",
"cjt/directives/pageSizeDirective",
"cjt/decorators/paginationDecorator",
"cjt/directives/searchDirective",
"cjt/directives/toggleSortDirective"
], function(BOOTSTRAP) {
var app = angular.module("App");
app.value("PAGE", PAGE);
app.firstLoad = {
phpAccountList: true
};
// Setup Routing
app.config(["$routeProvider", "growlProvider", "$animateProvider",
function($routeProvider, growlProvider, $animateProvider) {
// This prevents performance issues
// when the queue gets large.
// cf. https://docs.angularjs.org/guide/animations#which-directives-support-animations-
$animateProvider.classNameFilter(/INeverWantThisToAnimate/);
// Setup the routes
$routeProvider.when("/config", {
controller: "phpManagerController",
templateUrl: CJT.buildFullPath("multiphp_manager/views/phpManagerConfig.ptt"),
reloadOnSearch: false
})
.when("/handlers", {
controller: "phpHandlers",
templateUrl: CJT.buildFullPath("multiphp_manager/views/phpHandlers.ptt"),
reloadOnSearch: false
})
.when("/conversion", {
controller: "conversion",
templateUrl: CJT.buildFullPath("multiphp_manager/views/conversion.ptt"),
reloadOnSearch: false
})
.when("/poolOptions", {
controller: "poolOptionsController",
templateUrl: CJT.buildFullPath("multiphp_manager/views/poolOptions.ptt"),
reloadOnSearch: false
})
.otherwise({
"redirectTo": "/config"
});
}
]);
app.run(["$rootScope", "$location", function($rootScope, $location) {
$("#content").show();
// register listener to watch route changes
$rootScope.$on("$routeChangeStart", function() {
$rootScope.currentRoute = $location.path();
});
}]);
BOOTSTRAP(document);
});
return app;
};
}
);
Back to Directory
File Manager