Viewing File: /usr/local/cpanel/base/frontend/jupiter/multiphp_ini_editor/views/basicMode.js
/*
* multiphp_ini_editor/views/basicMode.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, PAGE: true */
define(
[
"angular",
"lodash",
"cjt/util/locale",
"uiBootstrap",
"cjt/directives/alertList",
"cjt/directives/spinnerDirective",
"cjt/decorators/growlDecorator",
"cjt/services/alertService",
"app/services/configService",
"cjt/directives/actionButtonDirective"
],
function(angular, _, LOCALE) {
// Retrieve the current application
var app = angular.module("App");
var controller = app.controller(
"basicMode",
["$scope", "$location", "configService", "$routeParams", "$timeout", "spinnerAPI", "alertService", "growl",
function($scope, $location, configService, $routeParams, $timeout, spinnerAPI, alertService, growl) {
// Setup data structures for the view
var iniUserPaths = []; // This will contain all data about INI paths.
var alreadyInformed = false;
var infoGrowlHandle;
$scope.noIniPaths = true;
$scope.txtInFirstOption = LOCALE.maketext("[comment,used for highlight in select option]-- Not Available --[comment,used for highlight in select option]");
$scope.selectedIniPath = { type: "", name: "" };
// This is strip down version of 'iniUserPaths' which only contains
// type & name attributes to display in the dropdown.
$scope.iniPathNames = [];
$scope.loadingDirectiveList = false;
$scope.showEmptyMessage = false;
$scope.knobLabel = "\u00a0";
var resetForm = function() {
// Reset the directive list to empty.
$scope.directiveList = [];
$scope.showEmptyMessage = false;
};
$scope.loadDirectives = function() {
// Destroy all growls before attempting to submit something.
alertService.clear();
if ($scope.selectedIniPath.type) {
spinnerAPI.start("loadingSpinner");
var selectedIni = $scope.selectedIniPath;
$scope.loadingDirectiveList = true;
alreadyInformed = false;
var pathInfo = getIniPathInfo($scope.selectedIniPath);
// construct the path to php.ini
if (pathInfo.type === "home") {
pathInfo.inifullpath = pathInfo.homedir + "/" + pathInfo.path;
} else if (pathInfo.type === "vhost") {
pathInfo.inifullpath = pathInfo.documentroot + "/" + pathInfo.path;
}
$scope.currentIniPathInfo = pathInfo;
return configService
// 'name' variable contains vhost value for all ini paths of type:'vhost'.
.fetchBasicList(selectedIni.type, selectedIni.name)
.then(function(data) {
if (typeof (data.directives) !== "undefined" && data.directives.length > 0 ) {
var directiveData = data.directives;
// If the handler is not suPHP make sure to hide the directives
// that can be edited only by the system.
return configService.getHandlerForDomain(selectedIni.type, selectedIni.name)
.then(function(data) {
if (data.php_handler !== "suphp") {
directiveData = _.filter(directiveData, function(dir) {
return dir.php_ini_mode !== "PHP_INI_SYSTEM";
});
}
// Map the localized string for the directives' defaults
// to show them with the directive values.
$scope.directiveList = directiveData.map(function(item) {
item.toggleValue = ( item.value === "On" ) ? true : false;
var defaultPhpValue = item.default_value;
if ( typeof item.cpanel_default !== "undefined" && item.cpanel_default !== null ) {
defaultPhpValue = item.cpanel_default;
}
if ( item.type === "boolean" ) {
defaultPhpValue = item.default_value === "1" ?
LOCALE.maketext("Enabled") : LOCALE.maketext("Disabled");
}
item.default_text = LOCALE.maketext("[asis,PHP] Default: [output,class,_1,defaultValue]", defaultPhpValue);
return item;
});
}, function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
replace: false,
group: "multiphpIniEditor"
});
});
}
}, function(error) {
alertService.add({
type: "danger",
message: error,
closeable: true,
replace: false,
group: "multiphpIniEditor"
});
})
.then(function() {
$scope.loadingDirectiveList = false;
spinnerAPI.stop("loadingSpinner");
})
.finally(function() {
spinnerAPI.stop("loadingSpinner");
$scope.showEmptyMessage = $scope.selectedIniPath !== "" && $scope.directiveList.length <= 0;
}
);
} else {
resetForm();
}
};
var informUser = function() {
if (!alreadyInformed) {
alreadyInformed = true;
// TODO: Replace this info growl with alert service.
growl.info(LOCALE.maketext("You must click “[_1]” to apply the new changes.", LOCALE.maketext("Apply")),
{
ttl: -1,
onopen: function() {
infoGrowlHandle = this;
}
}
);
}
};
$scope.toggle_status = function(directive) {
if (directive.value === "On") {
directive.value = "Off";
directive.toggleValue = false;
} else {
directive.value = "On";
directive.toggleValue = true;
}
informUser();
};
$scope.directiveTextChange = function(directive) {
informUser();
var type = directive.type;
var text = directive.value || "";
var valid = true;
var valMsg = "";
if (type === "integer") {
// Do the integer thing.
var E_FLAG = "[~!]?\\s*E_(?:(?:(?:CORE_|COMPILE_|USER_)?(?:ERROR|WARNING))|(?:USER_)?(?:NOTICE|DEPRECATED)|PARSE|STRICT|RECOVERABLE_ERROR|ALL)";
var E_OPER = "[&|^]";
var intRegex = new RegExp("^\\s*" + E_FLAG + "(?:\\s*" + E_OPER + "\\s*" + E_FLAG + ")*$");
if (/^-?\d+[kmg]?$/i.test(text) || intRegex.test(text)) {
valid = true;
} else {
valid = false;
valMsg = LOCALE.maketext("You must provide either an integer value, a [output,url,_1,shorthand byte,target,blank,title,shorthand byte documentation], or a [output,url,_2,predefined constant,target,blank,title,predefined constant documentation].", "http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes", "http://php.net/manual/en/errorfunc.constants.php");
}
} else if (type === "float") {
if (/^-?\d+(?:\.\d*)?$/.test(text)) {
valid = true;
} else {
valid = false;
valMsg = LOCALE.maketext("You must provide a valid float value.");
}
}
$scope.basicModeForm["txt" + directive.key].$setValidity("pattern", valid);
directive.validationMsg = valMsg;
};
$scope.disableApply = function() {
return ($scope.noIniPaths || !$scope.selectedIniPath.type || !$scope.basicModeForm.$valid);
};
$scope.requiredValidation = function(directive) {
return (directive.type !== "string" && directive.type !== "boolean");
};
$scope.applyPhpSettings = function() {
if ($scope.basicModeForm.$valid) {
// Destroy all growls before attempting to submit something.
alertService.clear();
alreadyInformed = false;
if ( typeof infoGrowlHandle !== "undefined" ) {
infoGrowlHandle.destroy();
}
return configService.applySettings($scope.selectedIniPath.type, $scope.selectedIniPath.name, $scope.directiveList)
.then(
function(data) {
if (data !== undefined) {
alertService.add({
type: "success",
message: LOCALE.maketext("Successfully applied the settings."),
closeable: true,
replace: false,
autoClose: 10000,
group: "multiphpIniEditor"
});
}
}, function(error) {
// The error returned already is encoded in the backend response.
// CJT2/uapi.js->find_messages() again applies escape() to the text.
// This is causing issue EA-3862. Removing escape() in uapi.js may break any existing stuff.
// So applying a hack here specific to this API.
alertService.add({
type: "danger",
message: _.unescape(error),
closeable: true,
replace: false,
group: "multiphpIniEditor"
});
});
}
};
var getIniPathInfo = function(shortPathInfo) {
// filter the required path info from iniUserPaths
var pathInfo = _.find(iniUserPaths, function(path) {
// There can be only one record of type 'home'
if (shortPathInfo.type === "home" && path.type === "home") {
return true;
} else if (shortPathInfo.type === "vhost" && shortPathInfo.name === path.vhost) {
return true;
}
});
return pathInfo;
};
var setIniPathDropdown = function(iniList) {
// iniList is sent to the function when the
// dropdown is bound the first time.
if (iniList.length > 0) {
iniUserPaths = iniList;
var mainDomainName;
// Map the object: { type, name } to the iniPathNames array, filtering out the home directory item
// and primary domain item. They will be added to the top of the list later.
_.each(iniList, function(iniPath) {
if (iniPath.type !== "home" && !iniPath.main_domain) {
$scope.iniPathNames.push({ type: iniPath.type, name: iniPath.vhost });
} else if (iniPath.main_domain) {
// Save the Primary Domain name
mainDomainName = iniPath.vhost;
}
});
// Sort the resultant $scope.iniPathNames
$scope.iniPathNames = _.sortBy($scope.iniPathNames, "name");
// Push the Home Directory & Primary Domain entries on top of the list.
$scope.iniPathNames.unshift({ type: "vhost", name: mainDomainName });
$scope.iniPathNames.unshift({ type: "home", name: "Home Directory" });
}
if ($scope.iniPathNames.length > 0) {
$scope.noIniPaths = false;
$scope.txtInFirstOption = LOCALE.maketext("[comment,used for highlight in select option]-- Select a location --[comment,used for highlight in select option]");
}
};
$scope.$on("$viewContentLoaded", function() {
// Destroy all growls before attempting to submit something.
alertService.clear();
var phpIniData = PAGE.php_ini_data;
$scope.localeIsRTL = PAGE.locale_is_RTL ? true : false;
if (!phpIniData.status && phpIniData.errors.length > 0) {
// Handle errors
var errors = phpIniData.errors;
errors.forEach(function(error) {
alertService.add({
type: "danger",
message: error,
replace: false,
closeable: true,
group: "multiphpIniEditor"
});
});
} else {
// Bind PHP INI Files specific to dropdown
setIniPathDropdown(phpIniData.data.paths);
}
});
}
]);
return controller;
}
);
Back to Directory
File Manager