mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-07-20 08:33:03 +02:00
Issue #1167 : Implement group merge function
* Implement new API function pwg.groups.merge * Generalize the delete group function in admin/include/functions.php * Implement merge action in Group Manager * Add loading state on grouped delete in group manager * Member manager's design fixes
This commit is contained in:
@@ -2454,6 +2454,50 @@ SELECT name
|
||||
return $groupname;
|
||||
}
|
||||
|
||||
function delete_groups($group_ids) {
|
||||
|
||||
$group_id_string = implode(',', $group_ids);
|
||||
|
||||
// destruction of the access linked to the group
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '. GROUP_ACCESS_TABLE .'
|
||||
WHERE group_id IN('. $group_id_string .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// destruction of the users links for this group
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '. USER_GROUP_TABLE .'
|
||||
WHERE group_id IN('. $group_id_string .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$query = '
|
||||
SELECT id, name
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id IN('. $group_id_string .')
|
||||
;';
|
||||
|
||||
$group_list = query2array($query, 'id', 'name');
|
||||
$groupids = array_keys($group_list);
|
||||
|
||||
// destruction of the group
|
||||
$query = '
|
||||
DELETE
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id IN('. $group_id_string .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
trigger_notify('delete_group', $groupids);
|
||||
pwg_activity('group', $groupids, 'delete');
|
||||
|
||||
|
||||
return $group_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username corresponding to the given user identifier if exists.
|
||||
*
|
||||
|
||||
@@ -602,7 +602,7 @@ input:focus + .slider {
|
||||
border:1px solid #3c3c3c;
|
||||
}
|
||||
|
||||
.ValidationUserAssociated{
|
||||
.ValidationUserAssociated, .ValidationUserDissociated{
|
||||
color:#00aa00;
|
||||
background-color:#c2f5c2;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ jQuery(document).ready(function () {
|
||||
newgroup.css("order", -id);
|
||||
newgroup.attr("data-id", id);
|
||||
newgroup.find("#group_name").html(name);
|
||||
newgroup.find(".group_name-editable").val(name);
|
||||
newgroup.find(".Group-checkbox label").attr("for", "Group-Checkbox-selection-" + id);
|
||||
newgroup.find(".Group-checkbox input").attr("id", "Group-Checkbox-selection-" + id);
|
||||
newgroup.find(".input-edit-group-name").attr("placeholder", name);
|
||||
@@ -109,9 +110,9 @@ jQuery(document).ready(function () {
|
||||
newgroup.find(".groupMessage").fadeIn();
|
||||
newgroup.find(".groupMessage").delay(DELAY_FEEDBACK).fadeOut();
|
||||
} else {
|
||||
$("#showAddGroup .groupError").html(str_name_taken);
|
||||
$("#showAddGroup .groupError").fadeIn();
|
||||
$("#showAddGroup .groupError").delay(DELAY_FEEDBACK).fadeOut();
|
||||
$("#addGroupForm .groupError").html(str_name_taken);
|
||||
$("#addGroupForm .groupError").fadeIn();
|
||||
$("#addGroupForm .groupError").delay(DELAY_FEEDBACK).fadeOut();
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
@@ -129,54 +130,14 @@ jQuery(document).ready(function () {
|
||||
setupGroupBox($(this));
|
||||
});
|
||||
});
|
||||
|
||||
var setupGroupBox = function (groupBox) {
|
||||
var id = groupBox.data("id");
|
||||
|
||||
/* Change background color of group block if checked in selection mode */
|
||||
groupBox.find(".Group-checkbox input[type='checkbox']").change(function () {
|
||||
if ($(this).is(":checked")) {
|
||||
groupBox.addClass("OrangeBackground");
|
||||
groupBox.find(".icon-users-1").addClass("OrangeIcon");
|
||||
groupBox.find(".group_number_users").addClass("OrangeFont");
|
||||
|
||||
//Display item selection on selection panel
|
||||
item = $(
|
||||
"<div data-id=" +
|
||||
groupBox.data("id") +
|
||||
">" +
|
||||
"<a class='icon-cancel'></a>" +
|
||||
"<p>" +
|
||||
groupBox.find("#group_name").html() +
|
||||
"</p> </div>"
|
||||
);
|
||||
item.appendTo(".DeleteGroupList");
|
||||
item.find("a").on("click", function () {
|
||||
groupBox.find(".Group-checkbox input").attr("checked", false);
|
||||
groupBox
|
||||
.find(".Group-checkbox input[type='checkbox']")
|
||||
.trigger("change");
|
||||
});
|
||||
updateSelectionPanel();
|
||||
option = $('<option value="'+id+'">'+groupBox.find("#group_name").html()+'</option>')
|
||||
option.appendTo("#MergeOptionsChoices");
|
||||
} else {
|
||||
groupBox.removeClass("OrangeBackground");
|
||||
groupBox.find(".icon-users-1").removeClass("OrangeIcon");
|
||||
groupBox.find(".group_number_users").removeClass("OrangeFont");
|
||||
$(".DeleteGroupList div").each(function () {
|
||||
if ($(this).data("id") == id) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
updateSelectionPanel();
|
||||
$("#MergeOptionsChoices option").each(function () {
|
||||
if ($(this).attr("value") == id) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
toogleSelection(id, groupBox.find(".Group-checkbox input[type='checkbox']").is(":checked"));
|
||||
});
|
||||
groupBox.find(".Group-checkbox input[type='checkbox']").attr("checked", false)
|
||||
|
||||
/* Display the option on the click on "..." */
|
||||
groupBox.find(".group-dropdown-options").click(function GroupOptions() {
|
||||
@@ -186,18 +147,40 @@ var setupGroupBox = function (groupBox) {
|
||||
/* Set the delete action */
|
||||
groupBox.find("#GroupDelete").on("click", function () {
|
||||
$.confirm({
|
||||
title: str_delete+' '+groupBox.find("#group_name").html(),
|
||||
content: str_are_you_sure,
|
||||
title: str_delete.replace("%s",groupBox.find("#group_name").html()),
|
||||
draggable: false,
|
||||
titleClass: "groupDeleteConfirm",
|
||||
theme: "modern",
|
||||
content: "",
|
||||
animation: "zoom",
|
||||
boxWidth: '30%',
|
||||
useBootstrap: false,
|
||||
type: 'red',
|
||||
typeAnimated: true,
|
||||
animateFromElement: false,
|
||||
backgroundDismiss: true,
|
||||
typeAnimated: false,
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: str_yes_delete_confirmation,
|
||||
btnClass: 'btn-red',
|
||||
action: function () {
|
||||
deleteGroup(id);
|
||||
let groupName = groupBox.find(".Group-name-container p").html();
|
||||
deleteGroup(id).then(() => {
|
||||
$.alert({
|
||||
title: str_group_deleted.replace("%s",groupName),
|
||||
icon: 'icon-ok',
|
||||
titleClass: "groupDeleteAlert",
|
||||
theme:"modern",
|
||||
closeIcon: true,
|
||||
content: "",
|
||||
animation: "zoom",
|
||||
boxWidth: '20%',
|
||||
useBootstrap: false,
|
||||
backgroundDismiss: true,
|
||||
animateFromElement: false,
|
||||
typeAnimated: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
@@ -249,28 +232,71 @@ var setupGroupBox = function (groupBox) {
|
||||
|
||||
};
|
||||
|
||||
var toogleSelection = function(group_id, toggle) {
|
||||
groupBox = $("#group-"+group_id);
|
||||
if (toggle) {
|
||||
groupBox.find(".Group-checkbox input").attr("checked", true);
|
||||
groupBox.addClass("OrangeBackground");
|
||||
groupBox.find(".icon-users-1").addClass("OrangeIcon");
|
||||
groupBox.find(".group_number_users").addClass("OrangeFont");
|
||||
|
||||
//Display item selection on selection panel
|
||||
item = $(
|
||||
"<div data-id=" +
|
||||
group_id +
|
||||
">" +
|
||||
"<a class='icon-cancel'></a>" +
|
||||
"<p>" +
|
||||
groupBox.find("#group_name").html() +
|
||||
"</p> </div>"
|
||||
);
|
||||
item.appendTo(".DeleteGroupList");
|
||||
item.find("a").on("click", function () {
|
||||
groupBox.find(".Group-checkbox input").attr("checked", false);
|
||||
toogleSelection(group_id);
|
||||
});
|
||||
updateSelectionPanel();
|
||||
option = $('<option value="'+group_id+'">'+groupBox.find("#group_name").html()+'</option>')
|
||||
option.appendTo("#MergeOptionsChoices");
|
||||
} else {
|
||||
groupBox.find(".Group-checkbox input").attr("checked", false);
|
||||
groupBox.removeClass("OrangeBackground");
|
||||
groupBox.find(".icon-users-1").removeClass("OrangeIcon");
|
||||
groupBox.find(".group_number_users").removeClass("OrangeFont");
|
||||
$(".DeleteGroupList div").each(function () {
|
||||
if ($(this).data("id") == group_id) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
updateSelectionPanel();
|
||||
$("#MergeOptionsChoices option").each(function () {
|
||||
if ($(this).attr("value") == group_id) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* Group Ajax and Display Functions */
|
||||
var deleteGroup = function (id) {
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.groups.delete",
|
||||
type: "POST",
|
||||
data: "group_id=" + id + "&pwg_token=" + pwg_token,
|
||||
success: function (raw_data) {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
$.alert({
|
||||
title: str_group_deleted,
|
||||
content: "",
|
||||
boxWidth: '20%',
|
||||
useBootstrap: false
|
||||
});
|
||||
$("#group-" + id).remove();
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err);
|
||||
},
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.groups.delete",
|
||||
type: "POST",
|
||||
data: "group_id=" + id + "&pwg_token=" + pwg_token,
|
||||
success: function (raw_data) {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
$("#group-" + id).remove();
|
||||
$(".DeleteGroupList div[data-id="+id+"]").remove()
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err);
|
||||
},
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
var renameGroup = function(id, newName) {
|
||||
@@ -338,13 +364,9 @@ var setDefaultGroup = function (id, is_default) {
|
||||
if (data.stat === "ok") {
|
||||
if (is_default) {
|
||||
setupDefaultActions(id,true)
|
||||
//$("#group-" + id).find(".groupMessage").html(str_set_default_state);
|
||||
} else {
|
||||
setupDefaultActions(id,false)
|
||||
//$("#group-" + id).find(".groupMessage").html(str_unset_default_state);
|
||||
}
|
||||
//$("#group-" + id).find(".groupMessage").fadeIn();
|
||||
//$("#group-" + id).find(".groupMessage").delay(DELAY_FEEDBACK).fadeOut();
|
||||
}
|
||||
},
|
||||
error: function (err) {
|
||||
@@ -379,6 +401,7 @@ var setupDefaultActions = function(id, is_default) {
|
||||
-------*/
|
||||
|
||||
$(function () {
|
||||
$("#toggleSelectionMode").attr("checked", false)
|
||||
$("#toggleSelectionMode").click(function () {
|
||||
if ($(this).is(":checked")) {
|
||||
$(".in-selection-mode").show();
|
||||
@@ -478,17 +501,98 @@ var buttonUnavailable = function(button) {
|
||||
button.removeAttr("OnClick");
|
||||
}
|
||||
|
||||
/*-------
|
||||
Merge function on button's pannel
|
||||
-------*/
|
||||
|
||||
$('.ConfirmMergeButton').on("click", function() {
|
||||
let loadState = new TemporaryState();
|
||||
loadState.changeAttribute($('.ConfirmMergeButton'), "style", "pointer-events: none");
|
||||
loadState.changeHTML($('.ConfirmMergeButton'), "<i class='icon-spin6 animate-spin'> </i>");
|
||||
loadState.removeClass($('.ConfirmMergeButton'), "icon-ok");
|
||||
merge_group = [];
|
||||
str_merge_group = "";
|
||||
dest_grp = $("#MergeOptionsChoices").val();
|
||||
|
||||
$(".DeleteGroupList div").each(function () {
|
||||
if (dest_grp != $(this).attr("data-id")) {
|
||||
str_merge_group += "&merge_group_id[]="+$(this).attr("data-id");
|
||||
merge_group.push($(this).attr("data-id"));
|
||||
}
|
||||
})
|
||||
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.groups.merge",
|
||||
type: "POST",
|
||||
data: "destination_group_id=" + dest_grp + str_merge_group + "&pwg_token=" + pwg_token,
|
||||
success: function (raw_data) {
|
||||
loadState.reverse();
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
updateSelectionPanel('Selection');
|
||||
console.log(data);
|
||||
merge_group.forEach(function(id) {
|
||||
($("#group-"+id).fadeOut(complete=function(){
|
||||
$(this).remove();
|
||||
}))
|
||||
})
|
||||
toogleSelection(dest_grp, false)
|
||||
|
||||
$("#group-"+dest_grp + " .group_number_users").html("<i class='icon-spin6 animate-spin'> </i>");
|
||||
jQuery.ajax({
|
||||
url: "ws.php?format=json&method=pwg.users.getList",
|
||||
type: "POST",
|
||||
data: "group_id=" + dest_grp,
|
||||
success: function (raw_data) {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
let number = data.result.users.length;
|
||||
$("#group-"+dest_grp + " .group_number_users").html(
|
||||
number + " " + ((number > 1)? str_members_default:str_member_default)
|
||||
);
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*-------
|
||||
Delete function on button's pannel
|
||||
-------*/
|
||||
|
||||
$('.ConfirmDeleteButton').on("click", function() {
|
||||
let names = [];
|
||||
let promises = [];
|
||||
$('.DeleteGroupList div').each(function () {
|
||||
deleteGroup($(this).data('id'));
|
||||
$(this).remove();
|
||||
let id = $(this).data('id');
|
||||
names.push($("#group-"+id+" #group_name").html());
|
||||
promises.push(deleteGroup(id));
|
||||
});
|
||||
|
||||
let loadState = new TemporaryState;
|
||||
loadState.changeAttribute($('.ConfirmDeleteButton'), "style", "pointer-events: none");
|
||||
loadState.changeHTML($('.ConfirmDeleteButton'), "<i class='icon-spin6 animate-spin'> </i>");
|
||||
loadState.removeClass($('.ConfirmDeleteButton'),"icon-ok");
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
loadState.reverse();
|
||||
updateSelectionPanel("NoSelection");
|
||||
$.alert({
|
||||
title: str_groups_deleted.replace("%s",names.toString()),
|
||||
titleClass: "groupDeleteAlert",
|
||||
theme: "modern",
|
||||
icon: 'icon-ok',
|
||||
closeIcon: true,
|
||||
content: "",
|
||||
animation: "zoom",
|
||||
boxWidth: '20%',
|
||||
useBootstrap: false,
|
||||
backgroundDismiss: true,
|
||||
animateFromElement: false,
|
||||
typeAnimated: false,
|
||||
backgroundDismiss: true,
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
/*-------
|
||||
Manage User Part
|
||||
@@ -505,9 +609,13 @@ var usersInGroup = [];
|
||||
// Max offset of the user container (322 = 6 lines)
|
||||
var maxOffsetUserCont = 322;
|
||||
|
||||
var infoUsers = $("<div class='ValidationUserAssociated'>"
|
||||
var dissociateUserInfo = $("<div class='ValidationUserDissociated'>"
|
||||
+ "<p class='icon-ok'></p>"
|
||||
+ "</div>")
|
||||
+ "</div>").appendTo(".group-name-block").hide();
|
||||
|
||||
var associateUserInfo = $("<div class='ValidationUserAssociated'>"
|
||||
+ "<p class='icon-ok'></p>"
|
||||
+ "</div>");
|
||||
|
||||
// Setup the user research bar
|
||||
$(function() {
|
||||
@@ -625,10 +733,10 @@ var getUserDisplay = function(username, user_id, grp_id) {
|
||||
success: function (raw_data) {
|
||||
data = jQuery.parseJSON(raw_data);
|
||||
if (data.stat === "ok") {
|
||||
infoUsers.remove();
|
||||
infoUsers.insertAfter(userBlock).hide();
|
||||
infoUsers.find("p").html(str_user_dissociated);
|
||||
infoUsers.fadeIn()
|
||||
let str = str_user_dissociated.replace("%s", username)
|
||||
dissociateUserInfo.find("p").html(str);
|
||||
dissociateUserInfo.fadeIn()
|
||||
dissociateUserInfo.delay(DELAY_FEEDBACK).fadeOut()
|
||||
|
||||
userBlock.remove()
|
||||
|
||||
@@ -652,7 +760,7 @@ var getUserDisplay = function(username, user_id, grp_id) {
|
||||
//Update member number function
|
||||
function updateMembernumber(number, grp_id) {
|
||||
$(".GroupContainer[data-id="+grp_id+"] .group_number_users")
|
||||
.html(number + " " + str_member_default);
|
||||
.html(number + " " + ((number > 1)? str_members_default:str_member_default));
|
||||
$(".UserNumberBadge").html(number);
|
||||
$(".AmountOfUsersShown strong:nth-child(2)").html(number)
|
||||
$(".AmountOfUsersShown strong:nth-child(1)").html($(".UsernameBlock").length)
|
||||
@@ -691,10 +799,11 @@ $(".AddUserBlock button").on("click", function () {
|
||||
})
|
||||
let userBlock = getUserDisplay(username, id, grp_id).prependTo(".UsersInGroupList");
|
||||
|
||||
infoUsers.remove();
|
||||
infoUsers.insertAfter(userBlock).hide();
|
||||
infoUsers.find("p").html(str_user_associated);
|
||||
infoUsers.fadeIn()
|
||||
associateUserInfo.remove()
|
||||
associateUserInfo.insertAfter(userBlock);
|
||||
associateUserInfo.find("p").html(str_user_associated);
|
||||
associateUserInfo.fadeIn()
|
||||
associateUserInfo.delay(DELAY_FEEDBACK).fadeOut()
|
||||
|
||||
updateUserSearch();
|
||||
|
||||
@@ -716,7 +825,6 @@ $(".input-user-name").on("input", function() {
|
||||
searchString = $(this).val().toLowerCase();
|
||||
grp_id = $(".UserListPopIn").data("group_id");
|
||||
if (searchString != "") {
|
||||
infoUsers.remove();
|
||||
$(".UsersInGroupListContainer").css("min-height", $(".UsersInGroupListContainer").height())
|
||||
usersInGroup.forEach(function(u) {
|
||||
let isSearched = u.username.toLowerCase().includes(searchString)
|
||||
@@ -739,6 +847,7 @@ $(".input-user-name").on("input", function() {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
$(".AmountOfUsersShown strong:nth-child(1)").html($(".UsernameBlock").length)
|
||||
while ($(".UsersInGroupList").height() > maxOffsetUserCont) {
|
||||
$(".UsernameBlock").last().remove();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
{footer_script}
|
||||
var pwg_token = "{$PWG_TOKEN}";
|
||||
var str_member_default = "{'member'|@translate}"
|
||||
var str_members_default = "{'members'|@translate}"
|
||||
var str_group_created = "{'Group added'|@translate}"
|
||||
var str_renaming_done = "{'Group renamed'|@translate}"
|
||||
var str_name_taken = "{'Name is already taken'|@translate}"
|
||||
var str_group_deleted = "{'Group succesfully deleted'|@translate}"
|
||||
var str_group_deleted = '{'Group "%s" succesfully deleted'|@translate}'
|
||||
var str_groups_deleted = '{'Groups \{%s\} succesfully deleted'|@translate}'
|
||||
var str_set_default = "{'Set as group for new users'|@translate}"
|
||||
var str_unset_default = "{'Unset as group for new users'|@translate}"
|
||||
var str_set_default_state = "{'Group for new users set'|@translate}"
|
||||
var str_unset_default_state = "{'Group for new users unset'|@translate}"
|
||||
var str_delete = "{'Delete'|@translate}"
|
||||
var str_are_you_sure = "{'Are you sure ?'|@translate}"
|
||||
var str_yes_delete_confirmation = "{'Yes, delete it'|@translate}"
|
||||
var str_no_delete_confirmation = "{"No, I've changed my mind"|@translate}"
|
||||
var str_user_associated = "{"User Associated"|@translate}"
|
||||
var str_user_dissociated = "{"User Dissociated"|@translate}"
|
||||
var str_delete = '{'Delete group "%s"?'|@translate}'
|
||||
var str_yes_delete_confirmation = "{'Yes, delete'|@translate}"
|
||||
var str_no_delete_confirmation = "{"No, I have changed my mind"|@translate}"
|
||||
var str_user_associated = "{"User associated"|@translate}"
|
||||
var str_user_dissociated = '{'User "%s" Dissociated from this group'|@translate}'
|
||||
var str_user_list = "{"User List"|@translate}"
|
||||
|
||||
var serverKey = '{$CACHE_KEYS.users}'
|
||||
@@ -122,20 +121,19 @@ var rootUrl = '{$ROOT_URL}'
|
||||
<p>{'Choose which group to merge these groups into'|@translate}</p>
|
||||
<p class="ItalicTextInfo">{'The other groups will be removed'|@translate}</p>
|
||||
<div class="MergeOptionsContainer">
|
||||
<label for="MergeOptionsChoices">{'The other groups will be removed'|@translate}</label>
|
||||
<select id="MergeOptionsChoices"> {* TODO *}
|
||||
<select id="MergeOptionsChoices">
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button class="icon-ok ConfirmMergeButton" onclick="updateSelectionPanel('Selection')">Confirm merge</button>
|
||||
<button class="icon-ok ConfirmMergeButton">Confirm merge</button>
|
||||
<a id="CancelMerge" onclick="updateSelectionPanel('Selection')">Cancel</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="ConfirmGroupAction">
|
||||
<p>You are about to delete <span class="number-Selected">0</span> groups, are you sure?</p>
|
||||
<button class="icon-ok ConfirmDeleteButton" onclick="updateSelectionPanel('Selection')">Yes, delete</button>
|
||||
<a id="CancelDelete" onclick="updateSelectionPanel('Selection')">No, I have changed my mind</a>
|
||||
<button class="icon-ok ConfirmDeleteButton">{'Yes, delete'|@translate}</button>
|
||||
<a id="CancelDelete" onclick="updateSelectionPanel('Selection')">{"No, I have changed my mind"|@translate}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -2044,6 +2044,35 @@ input:checked + .slider:before {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.groupDeleteConfirm, .groupDeleteAlert {
|
||||
padding-bottom: 0 !important;
|
||||
color: #3c3c3c !important;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
.groupDeleteConfirm ~ .jconfirm-content-pane, .groupDeleteAlert ~ .jconfirm-content-pane {
|
||||
height: 0px !important;
|
||||
margin: 0px !important;
|
||||
}
|
||||
|
||||
.groupDeleteConfirm ~ .jconfirm-buttons button {
|
||||
text-transform: none !important;
|
||||
}
|
||||
|
||||
.groupDeleteAlert .jconfirm-icon-c i {
|
||||
color: #0a0 !important;
|
||||
background-color:#c2f5c2 !important;
|
||||
border-radius: 20px;
|
||||
padding: 5px 3px;
|
||||
border-radius: 60px;
|
||||
padding: 2px;
|
||||
font-size: 45px;
|
||||
}
|
||||
|
||||
.groupDeleteAlert .jconfirm-icon-c {
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
/*Group checkbox*/
|
||||
|
||||
.Group-checkbox{
|
||||
@@ -2421,7 +2450,7 @@ input:checked + .slider:before {
|
||||
display:inline-block;
|
||||
font-size:12px;
|
||||
text-align:left;
|
||||
padding:2px;
|
||||
padding: 4px 6px;
|
||||
border-radius:10px;
|
||||
margin-left:-5px;
|
||||
margin-right:10px;
|
||||
@@ -2431,6 +2460,20 @@ input:checked + .slider:before {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.ValidationUserDissociated{
|
||||
display:inline-block;
|
||||
text-align:left;
|
||||
padding: 6px;
|
||||
border-radius: 30px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.ValidationUserDissociated p{
|
||||
margin:0 !important;
|
||||
font-size:12px !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
|
||||
#UserList .FilterUserBlock .AmountOfUsersShown {
|
||||
display:inline-block;
|
||||
|
||||
@@ -632,7 +632,7 @@ input:focus + .slider {
|
||||
border:1px solid #f3f3f3;
|
||||
}
|
||||
|
||||
.ValidationUserAssociated{
|
||||
.ValidationUserAssociated, .ValidationUserDissociated{
|
||||
background-color:#00aa00;
|
||||
color:#c2f5c2;
|
||||
}
|
||||
|
||||
@@ -104,46 +104,9 @@ function ws_groups_delete($params, &$service)
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
$group_id_string = implode(',', $params['group_id']);
|
||||
|
||||
// destruction of the access linked to the group
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '. GROUP_ACCESS_TABLE .'
|
||||
WHERE group_id IN('. $group_id_string .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// destruction of the users links for this group
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '. USER_GROUP_TABLE .'
|
||||
WHERE group_id IN('. $group_id_string .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
$query = '
|
||||
SELECT id, name
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id IN('. $group_id_string .')
|
||||
;';
|
||||
|
||||
$group_list = query2array($query, 'id', 'name');
|
||||
$groupnames = array_values($group_list);
|
||||
$groupids = array_keys($group_list);
|
||||
|
||||
// destruction of the group
|
||||
$query = '
|
||||
DELETE
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id IN('. $group_id_string .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
trigger_notify('delete_group', $groupids);
|
||||
pwg_activity('group', $groupids, 'delete');
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
$groupnames = array_values(delete_groups($params['group_id']));
|
||||
|
||||
invalidate_user_cache();
|
||||
|
||||
return new PwgNamedArray($groupnames, 'group_deleted');
|
||||
@@ -264,6 +227,92 @@ SELECT COUNT(*)
|
||||
return $service->invoke('pwg.groups.getList', array('group_id' => $params['group_id']));
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Merge groups in one other group
|
||||
* @param mixed[] $params
|
||||
* @option int destination_group_id
|
||||
* @option int[] merge_group_id
|
||||
*/
|
||||
function ws_groups_merge($params, &$service) {
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
$all_groups = $params['merge_group_id'];
|
||||
array_push($all_groups, $params['destination_group_id']);
|
||||
|
||||
$all_groups = array_unique($all_groups);
|
||||
$merge_group = array_diff($params['merge_group_id'], array($params['destination_group_id']));
|
||||
|
||||
$query = '
|
||||
SELECT COUNT(*)
|
||||
FROM `'. GROUPS_TABLE .'`
|
||||
WHERE id in ('.implode(',', $all_groups) .')
|
||||
;';
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($count != count($all_groups))
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'All groups does not exist.');
|
||||
}
|
||||
|
||||
$user_in_merge_groups = array();
|
||||
$user_in_dest = array();
|
||||
$user_to_add = array();
|
||||
|
||||
$query = '
|
||||
SELECT DISTINCT(user_id)
|
||||
FROM `'. USER_GROUP_TABLE .'`
|
||||
WHERE
|
||||
group_id in ('.implode(',', $merge_group) .')
|
||||
;';
|
||||
$user_in_merge_groups = query2array($query, null, 'user_id');
|
||||
|
||||
$query = '
|
||||
SELECT user_id
|
||||
FROM `'. USER_GROUP_TABLE .'`
|
||||
WHERE group_id = '.$params['destination_group_id'].'
|
||||
;';
|
||||
|
||||
$user_in_dest = query2array($query, null, 'user_id');;
|
||||
|
||||
|
||||
$user_to_add = array_diff($user_in_merge_groups, $user_in_dest);
|
||||
|
||||
$inserts = array();
|
||||
foreach ($user_to_add as $user)
|
||||
{
|
||||
$inserts[] = array(
|
||||
'group_id' => $params['destination_group_id'],
|
||||
'user_id' => $user,
|
||||
);
|
||||
}
|
||||
|
||||
mass_inserts(
|
||||
USER_GROUP_TABLE,
|
||||
array('group_id', 'user_id'),
|
||||
$inserts,
|
||||
array('ignore'=>true)
|
||||
);
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
invalidate_user_cache();
|
||||
|
||||
pwg_activity('group', $params['destination_group_id'], 'edit');
|
||||
foreach ($user_to_add as $user_id)
|
||||
{
|
||||
pwg_activity('user', $user_id, 'edit');
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
delete_groups($merge_group);
|
||||
|
||||
return $service->invoke('pwg.groups.getList', array('group_id' => $params['destination_group_id']));
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Removes user(s) from a group
|
||||
|
||||
@@ -910,6 +910,21 @@ function ws_addDefaultMethods( $arr )
|
||||
array('admin_only'=>true, 'post_only'=>true)
|
||||
);
|
||||
|
||||
$service->addMethod(
|
||||
'pwg.groups.merge',
|
||||
'ws_groups_merge',
|
||||
array(
|
||||
'destination_group_id' => array('type'=>WS_TYPE_ID,
|
||||
'info'=>'Destination group (is not necessarily part of groups to merge)'),
|
||||
'merge_group_id' => array('flags'=>WS_PARAM_FORCE_ARRAY,
|
||||
'type'=>WS_TYPE_ID),
|
||||
'pwg_token' => array(),
|
||||
),
|
||||
'Merge groups in one other group',
|
||||
$ws_functions_root . 'pwg.groups.php',
|
||||
array('admin_only'=>true, 'post_only'=>true)
|
||||
);
|
||||
|
||||
$service->addMethod(
|
||||
'pwg.users.getList',
|
||||
'ws_users_getList',
|
||||
|
||||
Reference in New Issue
Block a user