Initial push or quick actions in alias table

master
andryyy 2017-04-26 23:38:18 +02:00
parent a03b36e0c3
commit 5586bd2bb5
7 changed files with 504 additions and 327 deletions

View File

@ -17,3 +17,16 @@ table.footable>tbody>tr.footable-empty>td {
display:block; display:block;
padding: 10px; padding: 10px;
} }
.mass-each-action {
font-style: italic;
padding: 0 3px 0 3px;
user-select: none;
}
.mass-actions {
user-select: none;
padding:10px;
}
.mass-select-all {
cursor:pointer;
color:grey;
}

View File

@ -50,3 +50,8 @@ pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-s
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
} }
/* Fix modal moving content left */
body.modal-open {
overflow: inherit;
padding-right: inherit !important;
}

View File

@ -3308,29 +3308,20 @@ function mailbox_edit_alias_domain($postarray) {
); );
} }
function mailbox_edit_alias($postarray) { function mailbox_edit_alias($postarray) {
// Array elements // We can edit multiple addresses at once, but only set one "goto" and/or "active" attribute for all
// address string // address string or array containing strings | email | required
// goto string (separated by " ", "," ";" "\n") - email address or domain // goto string | separated by " ", "," ";" "\n", email or domain | optional
// active int // active set (active) or unset (inactive)
global $lang; global $lang;
global $pdo; global $pdo;
$address = $postarray['address']; if (!is_array($postarray['address'])) {
$domain = idn_to_ascii(substr(strstr($address, '@'), 1)); $address_array = array();
$local_part = strstr($address, '@', true); $address_array[] = $postarray['address'];
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
} }
if (empty($postarray['goto'])) { else {
$_SESSION['return'] = array( $address_array = $postarray['address'];
'type' => 'danger',
'msg' => sprintf($lang['danger']['goto_empty'])
);
return false;
} }
if (isset($postarray['goto']) || !empty($postarray['goto'])) {
$gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto'])); $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
foreach ($gotos as &$goto) { foreach ($gotos as &$goto) {
if (empty($goto)) { if (empty($goto)) {
@ -3353,7 +3344,18 @@ function mailbox_edit_alias($postarray) {
} }
$gotos = array_filter($gotos); $gotos = array_filter($gotos);
$goto = implode(",", $gotos); $goto = implode(",", $gotos);
}
isset($postarray['active']) ? $active = '1' : $active = '0'; isset($postarray['active']) ? $active = '1' : $active = '0';
foreach ($address_array as $address) {
$domain = idn_to_ascii(substr(strstr($address, '@'), 1));
$local_part = strstr($address, '@', true);
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) { if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
$_SESSION['return'] = array( $_SESSION['return'] = array(
'type' => 'danger', 'type' => 'danger',
@ -3361,8 +3363,8 @@ function mailbox_edit_alias($postarray) {
); );
return false; return false;
} }
try { try {
if (isset($goto) && !empty($goto)) {
$stmt = $pdo->prepare("UPDATE `alias` SET $stmt = $pdo->prepare("UPDATE `alias` SET
`goto` = :goto, `goto` = :goto,
`active`= :active `active`= :active
@ -3372,10 +3374,16 @@ function mailbox_edit_alias($postarray) {
':active' => $active, ':active' => $active,
':address' => $address ':address' => $address
)); ));
$_SESSION['return'] = array( }
'type' => 'success', else {
'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address)) $stmt = $pdo->prepare("UPDATE `alias` SET
); `active`= :active
WHERE `address` = :address");
$stmt->execute(array(
':active' => $active,
':address' => $address
));
}
} }
catch (PDOException $e) { catch (PDOException $e) {
$_SESSION['return'] = array( $_SESSION['return'] = array(
@ -3384,6 +3392,11 @@ function mailbox_edit_alias($postarray) {
); );
return false; return false;
} }
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars(implode(', ', $address_array)))
);
} }
function mailbox_edit_domain($postarray) { function mailbox_edit_domain($postarray) {
// Array elements // Array elements
@ -4527,9 +4540,17 @@ function mailbox_delete_domain($postarray) {
return true; return true;
} }
function mailbox_delete_alias($postarray) { function mailbox_delete_alias($postarray) {
// $postarray['address'] can be a single element or an array
global $lang; global $lang;
global $pdo; global $pdo;
$address = $postarray['address']; if (!is_array($postarray['address'])) {
$address_array = array();
$address_array[] = $postarray['address'];
}
else {
$address_array = $postarray['address'];
}
foreach ($address_array as $address) {
$local_part = strstr($address, '@', true); $local_part = strstr($address, '@', true);
$domain = mailbox_get_alias_details($address)['domain']; $domain = mailbox_get_alias_details($address)['domain'];
try { try {
@ -4565,10 +4586,11 @@ function mailbox_delete_alias($postarray) {
'msg' => 'MySQL: '.$e 'msg' => 'MySQL: '.$e
); );
return false; return false;
}
} }
$_SESSION['return'] = array( $_SESSION['return'] = array(
'type' => 'success', 'type' => 'success',
'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars($address)) 'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars(implode(', ', $address_array)))
); );
} }

View File

@ -15,7 +15,7 @@ $(document).ready(function() {
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
url: '/api/v1/domain/all', url: '/api/v1/get/domain/all',
jsonp: false, jsonp: false,
error: function () { error: function () {
alert('Cannot draw domain table'); alert('Cannot draw domain table');
@ -78,7 +78,7 @@ $(document).ready(function() {
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
url: '/api/v1/mailbox/all', url: '/api/v1/get/mailbox/all',
jsonp: false, jsonp: false,
error: function () { error: function () {
alert('Cannot draw mailbox table'); alert('Cannot draw mailbox table');
@ -146,7 +146,7 @@ $(document).ready(function() {
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
url: '/api/v1/resource/all', url: '/api/v1/get/resource/all',
jsonp: false, jsonp: false,
error: function () { error: function () {
alert('Cannot draw resource table'); alert('Cannot draw resource table');
@ -188,7 +188,7 @@ $(document).ready(function() {
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
url: '/api/v1/alias-domain/all', url: '/api/v1/get/alias-domain/all',
jsonp: false, jsonp: false,
error: function () { error: function () {
alert('Cannot draw alias domain table'); alert('Cannot draw alias domain table');
@ -228,7 +228,7 @@ $(document).ready(function() {
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
url: '/api/v1/alias/all', url: '/api/v1/get/alias/all',
jsonp: false, jsonp: false,
error: function () { error: function () {
alert('Cannot draw alias table'); alert('Cannot draw alias table');
@ -239,6 +239,7 @@ $(document).ready(function() {
'<a href="/edit.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' + '<a href="/edit.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
'<a href="/delete.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' + '<a href="/delete.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
'</div>'; '</div>';
item.chkbox = '<input type="checkbox" class="alias_item" name="sel_aliases" value="' + item.address + '" />';
if (item.is_catch_all == 1) { if (item.is_catch_all == 1) {
item.address = '<div class="label label-default">Catch-All</div> ' + item.address; item.address = '<div class="label label-default">Catch-All</div> ' + item.address;
} }
@ -246,8 +247,9 @@ $(document).ready(function() {
item.domain = "↳ " + item.domain + " (" + item.in_primary_domain + ")"; item.domain = "↳ " + item.domain + " (" + item.in_primary_domain + ")";
} }
}); });
$('#alias_table').footable({ ft_aliases = FooTable.init("#alias_table", {
"columns": [ "columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
{"sorted": true,"name":"address","title":lang.alias,"style":{"width":"250px"}}, {"sorted": true,"name":"address","title":lang.alias,"style":{"width":"250px"}},
{"name":"goto","title":lang.target_address}, {"name":"goto","title":lang.target_address},
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"}, {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
@ -269,6 +271,68 @@ $(document).ready(function() {
"sorting": { "sorting": {
"enabled": true "enabled": true
} }
}, function aliases_table_hook() {
var selected_aliases = {};
$('input[name=sel_aliases]').change(function() {
selected_aliases = {};
$('input[name=sel_aliases]:checked').each(function(i) {
selected_aliases[i] = ($(this).val());
});
});
$("#select_all_aliases").click(function(e) {
e.preventDefault();
var alias_chkbxs = $("input[name=sel_aliases]");
alias_chkbxs.prop("checked", !alias_chkbxs.prop("checked")).change();
});
$("#activate_selected_alias").click(function(e) {
e.preventDefault();
if (Object.keys(selected_aliases).length !== 0) {
$.ajax({
type: "POST",
dataType: "json",
data: { "address": JSON.stringify(selected_aliases), "active": "1" },
url: '/api/v1/edit/alias/post',
jsonp: false,
complete: function (data) {
location.reload();
}
});
}
});
$("#deactivate_selected_alias").click(function(e) {
e.preventDefault();
if (Object.keys(selected_aliases).length !== 0) {
$.ajax({
type: "POST",
dataType: "json",
data: { "address": JSON.stringify(selected_aliases), "active": "0" },
url: '/api/v1/edit/alias/post',
jsonp: false,
complete: function (data) {
location.reload();
}
});
}
});
$("#delete_selected_alias").click(function(e) {
e.preventDefault();
if (Object.keys(selected_aliases).length !== 0) {
$.ajax({
type: "POST",
dataType: "json",
data: { "address": JSON.stringify(selected_aliases) },
url: '/api/v1/delete/alias/post',
jsonp: false,
complete: function (data) {
location.reload();
}
});
}
});
$("tr").on('click',function(event) {
var checkbox = $(this).find(':checkbox');
checkbox.trigger('click');
});
}); });
} }
}); });

View File

@ -2,10 +2,17 @@
require_once 'inc/prerequisites.inc.php'; require_once 'inc/prerequisites.inc.php';
error_reporting(E_ALL); error_reporting(E_ALL);
if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_username'])) { if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_username'])) {
if (isset($_GET['action']) && isset($_GET['object'])) { if (isset($_GET['action']) && isset($_GET['cat'])) {
$category = filter_input(INPUT_GET, 'cat', FILTER_SANITIZE_STRING);
$action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING); $action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING);
if (isset($_GET['object'])) {
$object = filter_input(INPUT_GET, 'object', FILTER_SANITIZE_STRING); $object = filter_input(INPUT_GET, 'object', FILTER_SANITIZE_STRING);
}
switch ($action) { switch ($action) {
case "get":
switch ($category) {
case "domain": case "domain":
switch ($object) { switch ($object) {
case "all": case "all":
@ -239,5 +246,63 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo '{}'; echo '{}';
break; break;
} }
break;
case "delete":
switch ($category) {
case "alias":
if (isset($_POST['address'])) {
$address = json_decode($_POST['address'], true);
if (is_array($address)) {
if (mailbox_delete_alias(array('address' => $address)) === false) {
echo json_encode(array(
'type' => 'error',
'message' => 'Deletion of item failed'
));
exit();
}
echo json_encode(array(
'type' => 'success',
'message' => 'Task completed'
));
}
}
else {
echo json_encode(array(
'type' => 'error',
'message' => 'Cannot find address array in post data'
));
}
break;
}
break;
case "edit":
switch ($category) {
case "alias":
if (isset($_POST['address']) && isset($_POST['active'])) {
$address = json_decode($_POST['address'], true);
if (is_array($address)) {
if (mailbox_edit_alias(array('address' => $address, 'active' => ($_POST['active'] == "1") ? $active = 1 : null)) === false) {
echo json_encode(array(
'type' => 'error',
'message' => 'Edit item failed'
));
exit();
}
echo json_encode(array(
'type' => 'success',
'message' => 'Task completed'
));
}
}
else {
echo json_encode(array(
'type' => 'error',
'message' => 'Cannot find address array in post data'
));
}
break;
}
break;
}
} }
} }

View File

@ -40,7 +40,7 @@ $lang['danger']['alias_goto_identical'] = "Alias and goto address must not be id
$lang['danger']['aliasd_targetd_identical'] = "Alias domain must not be equal to target domain"; $lang['danger']['aliasd_targetd_identical'] = "Alias domain must not be equal to target domain";
$lang['danger']['maxquota_empty'] = 'Max. quota per mailbox must not be 0.'; $lang['danger']['maxquota_empty'] = 'Max. quota per mailbox must not be 0.';
$lang['success']['alias_added'] = "Alias address/es has/have been added"; $lang['success']['alias_added'] = "Alias address/es has/have been added";
$lang['success']['alias_modified'] = "Changes to alias have been saved"; $lang['success']['alias_modified'] = "Changes to alias/es %s have been saved";
$lang['success']['aliasd_modified'] = "Changes to alias domain have been saved"; $lang['success']['aliasd_modified'] = "Changes to alias domain have been saved";
$lang['success']['mailbox_modified'] = "Changes to mailbox %s have been saved"; $lang['success']['mailbox_modified'] = "Changes to mailbox %s have been saved";
$lang['success']['resource_modified'] = "Changes to mailbox %s have been saved"; $lang['success']['resource_modified'] = "Changes to mailbox %s have been saved";
@ -79,7 +79,7 @@ $lang['danger']['mailbox_quota_left_exceeded'] = "Not enough space left (space l
$lang['success']['mailbox_added'] = "Mailbox %s has been added"; $lang['success']['mailbox_added'] = "Mailbox %s has been added";
$lang['success']['resource_added'] = "Resource %s has been added"; $lang['success']['resource_added'] = "Resource %s has been added";
$lang['success']['domain_removed'] = "Domain %s has been removed"; $lang['success']['domain_removed'] = "Domain %s has been removed";
$lang['success']['alias_removed'] = "Alias-Adresse %s has been removed"; $lang['success']['alias_removed'] = "Alias %s has been removed";
$lang['success']['alias_domain_removed'] = "Alias domain %s has been removed"; $lang['success']['alias_domain_removed'] = "Alias domain %s has been removed";
$lang['success']['domain_admin_removed'] = "Domain administrator %s has been removed"; $lang['success']['domain_admin_removed'] = "Domain administrator %s has been removed";
$lang['success']['mailbox_removed'] = "Mailbox %s has been removed"; $lang['success']['mailbox_removed'] = "Mailbox %s has been removed";

View File

@ -89,6 +89,14 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table id="alias_table" class="table table-striped"></table> <table id="alias_table" class="table table-striped"></table>
<div class="mass-actions">
<span id="select_all_aliases" class="mass-select-all">Toggle all</span>
<br /><span>(
<a id="delete_selected_alias" href="#" class="mass-each-action">delete</a> |
<a id="activate_selected_alias" href="#" class="mass-each-action">activate</a> |
<a id="deactivate_selected_alias" href="#" class="mass-each-action">deactivate</a>)
</span>
</div>
</div> </div>
<span class="footer-add-item"><a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a></span> </div> <span class="footer-add-item"><a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a></span> </div>
</div> </div>