diff --git a/admin/include/add_core_tabs.inc.php b/admin/include/add_core_tabs.inc.php index 7b0146fd8..74cae9ca3 100644 --- a/admin/include/add_core_tabs.inc.php +++ b/admin/include/add_core_tabs.inc.php @@ -35,6 +35,12 @@ function add_core_tabs($sheets, $tab_id) $sheets['permalinks'] = array('caption' => ''.l10n('Permalinks'), 'url' => $my_base_url.'permalinks'); $sheets['search'] = array('caption' => ''.l10n('Search'), 'url' => $my_base_url.'cat_search'); break; + + case 'users': + global $my_base_url; + $sheets['user_list'] = array('caption' => ''.l10n('User list'), 'url' => $my_base_url.'user_list'); + $sheets['user_activity'] = array('caption' => ''.l10n('Activity'), 'url' => $my_base_url.'user_activity'); + break; case 'batch_manager': global $manager_link; diff --git a/admin/include/user_tabs.inc.php b/admin/include/user_tabs.inc.php new file mode 100644 index 000000000..b83b9b50f --- /dev/null +++ b/admin/include/user_tabs.inc.php @@ -0,0 +1,18 @@ +set_id('users'); +$tabsheet->select($page['tab']); +$tabsheet->assign(); + +?> \ No newline at end of file diff --git a/admin/themes/default/template/user_activity.tpl b/admin/themes/default/template/user_activity.tpl new file mode 100644 index 000000000..1432228f9 --- /dev/null +++ b/admin/themes/default/template/user_activity.tpl @@ -0,0 +1,907 @@ +{include file='include/colorbox.inc.tpl'} +{combine_script id='common' load='footer' path='admin/themes/default/js/common.js'} + +{combine_script id='jquery.selectize' load='footer' path='themes/default/js/plugins/selectize.min.js'} +{combine_css id='jquery.selectize' path="themes/default/js/plugins/selectize.{$themeconf.colorscheme}.css"} + +{combine_script id='LocalStorageCache' load='footer' path='admin/themes/default/js/LocalStorageCache.js'} +{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {* order 10 is required, see issue 1080 *} +{footer_script} +{* *} +var usersCache = new UsersCache({ + serverKey: '{$CACHE_KEYS.users}', + serverId: '{$CACHE_KEYS._hash}', + rootUrl: '{$ROOT_URL}' +}); + +usersCache.selectize(jQuery('[data-selectize=users]')); + +jQuery(".cancel-icon").click(function() { + jQuery(".user-selecter")[0].selectize.setValue(null); + return false; +}); + +const color_icons = ["icon-red", "icon-blue", "icon-yellow", "icon-purple", "icon-green"]; + +{*<-- Translation keys -->*} + +var actionType_add = "{'add'|translate}"; +var actionType_delete = "{'deletion'|translate}"; +var actionType_move = "{'move'|translate}"; +var actionType_edit = "{'edit'|translate}"; +var actionType_log = "{'log'|translate}"; + +{* Album keys *} + +var actionInfos_album_added = "{'%d album added'|translate}"; +var actionInfos_album_deleted = "{'%d album deleted'|translate}"; +var actionInfos_album_edited = "{'%d album edited'|translate}"; +var actionInfos_album_moved = "{'%d album moved'|translate}"; + +var actionInfos_albums_added = "{'%d albums added'|translate}"; +var actionInfos_albums_deleted = "{'%d albums deleted'|translate}"; +var actionInfos_albums_edited = "{'%d albums edited'|translate}"; +var actionInfos_albums_moved = "{'%d albums moved'|translate}"; + +{* User keys *} + +var actionInfos_user_added = "{'%d user added'|translate}"; +var actionInfos_user_deleted = "{'%d user deleted'|translate}"; +var actionInfos_user_edited = "{'%d user edited'|translate}"; +var actionInfos_user_logged_in = "{'%d user logged in'|translate}"; +var actionInfos_user_logged_out = "{'%d user logged out'|translate}"; + +var actionInfos_users_added = "{'%d users added'|translate}"; +var actionInfos_users_deleted = "{'%d users deleted'|translate}"; +var actionInfos_users_edited = "{'%d users edited'|translate}"; +var actionInfos_users_logged_in = "{'%d users logged in'|translate}"; +var actionInfos_users_logged_out = "{'%d users logged out'|translate}"; + +{* Photo keys *} + +var actionInfos_photo_added = "{'%d photo added'|translate}"; +var actionInfos_photo_deleted = "{'%d photo deleted'|translate}"; +var actionInfos_photo_edited = "{'%d photo edited'|translate}"; +var actionInfos_photo_moved = "{'%d photo moved'|translate}"; + +var actionInfos_photos_added = "{'%d photos added'|translate}"; +var actionInfos_photos_deleted = "{'%d photos deleted'|translate}"; +var actionInfos_photos_edited = "{'%d photos edited'|translate}"; +var actionInfos_photos_moved = "{'%d photos moved'|translate}"; + +{* Group keys *} + +var actionInfos_group_added = "{'%d group added'|translate}"; +var actionInfos_group_deleted = "{'%d group deleted'|translate}"; +var actionInfos_group_edited = "{'%d group edited'|translate}"; +var actionInfos_group_moved = "{'%d group moved'|translate}"; + +var actionInfos_groups_added = "{'%d groups added'|translate}"; +var actionInfos_groups_deleted = "{'%d groups deleted'|translate}"; +var actionInfos_groups_edited = "{'%d groups edited'|translate}"; +var actionInfos_groups_moved = "{'%d groups moved'|translate}"; + +{* Tags keys *} + +var actionInfos_tag_added = "{'%d tag added'|translate}"; +var actionInfos_tag_deleted = "{'%d tag deleted'|translate}"; +var actionInfos_tag_edited = "{'%d tag edited'|translate}"; +var actionInfos_tag_moved = "{'%d tag moved'|translate}"; + +var actionInfos_tags_added = "{'%d tags added'|translate}"; +var actionInfos_tags_deleted = "{'%d tags deleted'|translate}"; +var actionInfos_tags_edited = "{'%d tags edited'|translate}"; +var actionInfos_tags_moved = "{'%d tags moved'|translate}"; + +{*<-- Getting and Displaying Activities -->*} + +get_user_activity(); + +function get_user_activity() { + $.ajax({ + url: "ws.php?format=json&method=pwg.activity.getList", + type: "POST", + dataType: "json", + data: { + a: 1, + b: 2 + }, + success: (data) => { + /* console log to help debug */ + {* console.log(data); *} + + setCreationDate(data.result[data.result.length-1].date, data.result[0].date); + $(".loading").hide(); + + data.result.forEach(line => { + lineConstructor(line); + }); + displayLine(data); + }, + error: (e) => { + console.log("ajax call failed"); + console.log(e); + } + + }) +} + +function lineConstructor(line) { + let newLine = $("#-1").clone(); + + newLine.removeClass("hide"); + + /* console log to help debug */ + {* console.log(line); *} + newLine.attr("id", line.id); + + var final_albumInfos; + + {* Determines wich string need to be placed in the line constructed *} + + if (line.counter > 1) { + // pluriel + switch (line.action) { + case "edit": + newLine.find(".action-type").addClass("icon-blue"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-pencil"); + + newLine.find(".action-name").html(actionType_edit); + switch (line.object) { + case "user": + final_albumInfos = actionInfos_users_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-user-1"); + + break; + case "album": + final_albumInfos = actionInfos_albums_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_groups_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photos_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tags_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + break; + + case "add": + newLine.find(".action-type").addClass("icon-green"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-plus"); + + newLine.find(".action-name").html(actionType_add); + switch (line.object) { + case "user": + final_albumInfos = actionInfos_users_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-user-1"); + + break; + case "album": + final_albumInfos = actionInfos_albums_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_groups_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photos_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tags_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + break; + + case "delete": + newLine.find(".action-type").addClass("icon-red"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-trash-1"); + + newLine.find(".action-name").html(actionType_delete); + switch (line.object) { + case "user": + final_albumInfos = actionInfos_users_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-user-1"); + + break; + case "album": + final_albumInfos = actionInfos_albums_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_groups_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photos_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tags_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + break; + + case "move": + newLine.find(".action-type").addClass("icon-yellow"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-move"); + + newLine.find(".action-name").html(actionType_move); + switch (line.object) { + case "album": + final_albumInfos = actionInfos_albums_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_groups_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photos_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tags_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + break; + + case "login": + newLine.find(".action-type").addClass("icon-purple"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-key"); + newLine.find(".action-section").addClass("icon-user-1"); + + newLine.find(".action-name").html(actionType_log); + + console.log("userS Logged in"); + final_albumInfos = actionInfos_users_logged_in.replace('%d', line.counter); + + break; + + case "logout": + newLine.find(".action-type").addClass("icon-purple"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-key"); + newLine.find(".action-section").addClass("icon-user-1"); + + newLine.find(".action-name").html(actionType_log); + + console.log("userS Logged in"); + final_albumInfos = actionInfos_users_logged_out.replace('%d', line.counter); + + break; + + default: + newLine.find(".action-type").addClass("icon-purple"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + break; + } + } else { + // singulier + switch (line.action) { + case "edit": + newLine.find(".action-type").addClass("icon-blue"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-pencil"); + + newLine.find(".action-name").html(actionType_edit); + switch (line.object) { + case "user": + final_albumInfos = actionInfos_user_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-user-1"); + + break; + case "album": + final_albumInfos = actionInfos_album_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_group_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photo_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tag_edited.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + + break; + case "add": + newLine.find(".action-type").addClass("icon-green"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-plus"); + + newLine.find(".action-name").html(actionType_add); + switch (line.object) { + case "user": + final_albumInfos = actionInfos_user_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-user-1"); + + break; + case "album": + final_albumInfos = actionInfos_album_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_group_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photo_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tag_added.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + + break; + } + + break; + case "delete": + newLine.find(".action-type").addClass("icon-red"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-trash-1"); + + newLine.find(".action-name").html(actionType_delete); + switch (line.object) { + case "user": + final_albumInfos = actionInfos_user_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-user-1"); + + break; + case "album": + final_albumInfos = actionInfos_album_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_group_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photo_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tag_deleted.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + break; + case "move": + newLine.find(".action-type").addClass("icon-yellow"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-move"); + + newLine.find(".action-name").html(actionType_move); + switch (line.object) { + case "album": + final_albumInfos = actionInfos_album_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-folder-open"); + + break; + case "group": + final_albumInfos = actionInfos_group_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-users-1"); + + break; + case "photo": + final_albumInfos = actionInfos_photo_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-picture"); + + break; + case "tag": + final_albumInfos = actionInfos_tag_moved.replace('%d', line.counter); + newLine.find(".action-section").addClass("icon-tags"); + + break; + default: + final_albumInfos = line.counter + " " +line.object + " " + line.action; + break; + } + + break; + case "login": + newLine.find(".action-type").addClass("icon-purple"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-key"); + newLine.find(".action-section").addClass("icon-user-1"); + + newLine.find(".action-name").html(actionType_log); + + final_albumInfos = actionInfos_user_logged_in.replace('%d', line.counter); + + break; + case "logout": + newLine.find(".action-type").addClass("icon-purple"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + newLine.find(".action-icon").addClass("icon-key"); + newLine.find(".action-section").addClass("icon-user-1"); + + newLine.find(".action-name").html(actionType_log); + + final_albumInfos = actionInfos_user_logged_out.replace('%d', line.counter); + + break; + + default: + newLine.find(".action-type").addClass("icon-purple"); + newLine.find(".user-pic").addClass(color_icons[line.user_id % 5]); + break; + } + } + + newLine.find(".action-infos-test").html(final_albumInfos); + + /* Action_section */ + newLine.find(".nb_items").html(line.counter); + + /* Date_section */ + newLine.find(".date-day").html(line.date); + newLine.find(".date-hour").html(line.hour); + + /* User _Section */ + newLine.find(".user-pic").html(get_initials(line.username)); + newLine.find(".user-name").html(line.username); + + /* Detail_section */ + newLine.find(".detail-item-1").html(line.ip_address); + newLine.find(".detail-item-1").attr("title", "IP"); + + if (line.detailsType == "script") { + newLine.find(".detail-item-2").html(line.details.script); + newLine.find(".detail-item-2").attr('title', 'Script'); + } else if (line.detailsType == "method") { + newLine.find(".detail-item-2").html(line.details.method); + newLine.find(".detail-item-2").attr('title', 'API Method'); + } + + if (line.details.agent) { + newLine.find(".detail-item-3").html(line.details.agent); + newLine.find(".detail-item-3").attr('title', line.details.agent); + } else { + newLine.find(".detail-item-3").remove(); + } + + displayLine(newLine); +} + +function displayLine(line) { + $(".tab").append(line); +} + +function get_initials(username) { + let words = username.toUpperCase().split(" "); + let res = words[0][0]; + + if (words.length > 1 && words[1][0] !== undefined ) { + res += words[1][0]; + } + return res; +} + +function filterUsers(username) { + let lines = $(".line"); + + showAllLines() + let resultLines = []; + + for (let index = 1; index < lines.length; index++) { + + if (username != lines[index].children[2].children[1].innerHTML) { + $("#" + lines[index].id).hide(); + } else { + resultLines.push(lines[index].getElementsByClassName("date-day")[0].textContent) + } + } + setCreationDate((!resultLines[resultLines.length-1]) ? "{'N/A'|translate}" : resultLines[resultLines.length-1], (!resultLines[0]) ? "{'N/A'|translate}" : resultLines[0]) +} + +function showAllLines() { + let lines = $(".line"); + for (let index = 1; index < lines.length; index++) { + $("#" + lines[index].id).show(); + } + + $("#-1").hide(); +} + +function setCreationDate(startDate, endDate) { + $(".start-date").html(startDate) + + $(".end-date").html(endDate) +} + +$(document).ready(function () { + + $('select').on('change', function (user) { + try { + filterUsers($(".selectize-input .item")[0].innerHTML); + } catch (error) { + showAllLines(); + let lines = $(".line"); + let resultLines = []; + for (let index = 1; index < lines.length; index++) { + resultLines.push(lines[index].getElementsByClassName("date-day")[0].textContent) + } + setCreationDate((!resultLines[resultLines.length-1]) ? "-" : resultLines[resultLines.length-1], (!resultLines[0]) ? "-" : resultLines[0]) + } + }); +}); + +{/footer_script} + +
+ +
+
+ {'Selected user'|translate} + + + + + +
+
+ {'Activity time from'|translate} + + + + {'to'|translate} + + + +
+ + + +
+ + + +
+
+ {'Action'|translate} +
+ +
+ {'Date'|translate} +
+ +
+ {'User'|translate} +
+ +
+ {'Details'|translate} +
+
+ + +
+
+ +
+
+
+
+ + Edit +
+
+ T +
+
+ +
+ + 1 Janvier 1970 + a 00:00 +
+ +
+
+
+
+ Username +
+
+ +
+
+ detail 1 +
+
+ detail 2 +
+
+ detail 3 +
+
+
+
+
+ + \ No newline at end of file diff --git a/admin/themes/default/theme.css b/admin/themes/default/theme.css index 7d0605cd5..2b06d0d7e 100644 --- a/admin/themes/default/theme.css +++ b/admin/themes/default/theme.css @@ -5120,3 +5120,82 @@ color:#FF7B00; .user-property-input.user-property-input-password:hover { background-color: #f0f0f0; } + +/* Activity Tab in user manager */ + +.select-user { + background: #fafafa; + height: 50%; + + display: flex; + align-items: center; + + padding: 0 20px; + + box-shadow: 0px 2px 4px #00000024; + border-radius: 5px; +} + +.start-date, +.end-date { + padding: 5px 10px; + background: #eaeaea; + border-radius: 50px; + margin: 5px; + white-space: nowrap; +} + +.acivity-time-text { + font-size: 13px; + font-weight: bold; +} + +.line { + background: #fafafa; + box-shadow: 0px 2px 4px #00000024; + + display: flex; + flex-direction: row; + + height: 40px; + + align-items: center; + + margin-bottom: 10px; +} + +.line .detail-item { + background: #f0f0f0f0; + margin: 0 10px 0 0; + padding: 3px 6px; + border-radius: 20px; + + max-width: 120px; + + text-align: center; + + overflow: hidden; + text-overflow: ellipsis; + cursor: default; + + white-space: nowrap; +} + +.download_csv { + margin-left: auto; + height: 25px; + width: 30px; + background: #dddddd; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + color:black; + cursor: pointer; + border-radius: 5px; +} + +.download_csv:hover { + background: #aaaaaa; + color: black; +} diff --git a/admin/themes/roma/theme.css b/admin/themes/roma/theme.css index 3fda20363..4969cd94a 100644 --- a/admin/themes/roma/theme.css +++ b/admin/themes/roma/theme.css @@ -1327,3 +1327,89 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; .cache-lastCalculated-value, .cache-lastCalculated-text, .cache-size-text, .picture-deletion-size, #label-delete-size-checkbox { color: #c1c1c1; } + +/* Activity Tab in user manager */ + +.select-user { + background: #555555; + height: 50%; + + display: flex; + align-items: center; + + padding: 0 20px; + + box-shadow: 0px 2px 4px #00000024; + border-radius: 5px; +} + +.select-user-title { + color: #bbbbbb; +} + +.start-date, +.end-date { + padding: 5px 10px; + background: #555555; + border-radius: 50px; + margin: 5px; + color: #bbbbbb; +} + +.acivity-time-text { + font-size: 13px; + font-weight: bold; + color: #bbbbbb; +} + +.line { + background: #333333; + box-shadow: 0px 2px 4px #00000024; + + display: flex; + flex-direction: row; + + height: 40px; + + align-items: center; + + margin-bottom: 10px; + color: #bbbbbb; +} + +.line .detail-item { + background: #555555; + margin: 0 10px 0 0; + padding: 3px 6px; + border-radius: 20px; + + min-width: 50px; + max-width: 150px; + + text-align: center; + + overflow: hidden; + text-overflow: ellipsis; + cursor: default; + + white-space: nowrap; +} + +.download_csv { + margin-left: auto; + height: 25px; + width: 30px; + background: #555555; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + color:#b8b8b8; + cursor: pointer; + border-radius: 5px; +} + +.download_csv:hover { + background: #777777; + color: #dddddd; +} diff --git a/admin/user_activity.php b/admin/user_activity.php new file mode 100644 index 000000000..cd70e4f12 --- /dev/null +++ b/admin/user_activity.php @@ -0,0 +1,39 @@ +set_filename('user_activity', 'user_activity.tpl'); +$template->assign('ADMIN_PAGE_TITLE', l10n('User Activity logs')); + +// +-----------------------------------------------------------------------+ +// | sending html code | +// +-----------------------------------------------------------------------+ +$template->assign_var_from_handle('ADMIN_CONTENT', 'user_activity'); + +?> \ No newline at end of file diff --git a/admin/user_list.php b/admin/user_list.php index a1da5d6d5..21c68af52 100644 --- a/admin/user_list.php +++ b/admin/user_list.php @@ -16,14 +16,8 @@ check_input_parameter('group', $_GET, false, PATTERN_ID); // | tabs | // +-----------------------------------------------------------------------+ -include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php'); - -$my_base_url = get_root_url().'admin.php?page='; - -$tabsheet = new tabsheet(); -$tabsheet->set_id('users'); -$tabsheet->select('user_list'); -$tabsheet->assign(); +$page['tab'] = 'user_list'; +include(PHPWG_ROOT_PATH.'admin/include/user_tabs.inc.php'); // +-----------------------------------------------------------------------+ // | groups list | diff --git a/include/ws_functions/pwg.php b/include/ws_functions/pwg.php index 7aa7a47a8..e304fd5ea 100644 --- a/include/ws_functions/pwg.php +++ b/include/ws_functions/pwg.php @@ -341,4 +341,143 @@ function ws_session_getStatus($params, &$service) return $res; } +/** + * API method + * Returns lines of users activity + */ + +function ws_getActivityList($param, &$service) { + + /* Test Lantency */ + // sleep(1); + + $output_lines = array(); + $current_key = ''; + + $query = ' + SELECT + activity_id, + performed_by, + object, action, + session_idx, + ip_address, + occured_on, + details, + username + FROM piwigo_activity, + piwigo_users + WHERE piwigo_activity.performed_by = piwigo_users.id + ORDER BY activity_id DESC; + '; + + $line_id = 0; + $result = pwg_query($query); + while ($row = pwg_db_fetch_assoc($result)) + { + $row['details'] = str_replace('`groups`', 'groups', $row['details']); + $row['details'] = str_replace('`rank`', 'rank', $row['details']); + $details = unserialize($row['details']); + + if (isset($details['method'])) + { + $detailsType = 'method'; + } + if (isset($details['script'])) + { + $detailsType = 'script'; + } + + $line_key = $row['session_idx'].'~'.$row['object'].'~'.$row['action'].'~'; // idx~photo~add + + if ($line_key === $current_key) + { + // j'incrémente le counter de la ligne précédente + $output_lines[count($output_lines)-1]['counter']++; + } + else + { + list($date, $hour) = explode(' ', $row['occured_on']); + // New line + $output_lines[] = array( + 'id' => $line_id, + 'object' => $row['object'], + 'action' => $row['action'], + 'ip_address' => $row['ip_address'], + 'date' => format_date($date), + 'hour' => $hour, + 'username' => $row['username'], + 'user_id' => $row['performed_by'], + 'detailsType' => $detailsType, + 'details' => $details, + 'counter' => 1, + ); + + $current_key = $line_key; + $line_id++; + } + } + + return $output_lines; +} + +/** + * API method + * Returns lines of users activity + */ + +function ws_activity_downloadLog($param, &$service) { + + $output_lines = array(); + + $query = ' + SELECT + activity_id, + performed_by, + object, + object_id, + action, + ip_address, + occured_on, + details, + username + FROM piwigo_activity, + piwigo_users + WHERE piwigo_activity.performed_by = piwigo_users.id + ORDER BY activity_id DESC; + '; + + $result = pwg_query($query); + array_push($output_lines, ['User', 'ID_User', 'Object', 'Object_ID', 'Action', 'Date', 'Hour', 'IP_Address', 'Details']); + while ($row = pwg_db_fetch_assoc($result)) + { + $row['details'] = str_replace('`groups`', 'groups', $row['details']); + $row['details'] = str_replace('`rank`', 'rank', $row['details']); + + list($date, $hour) = explode(' ', $row['occured_on']); + + $output_lines[] = array( + 'username' => $row['username'], + 'user_id' => $row['performed_by'], + 'object' => $row['object'], + 'object_id' => $row['object_id'], + 'action' => $row['action'], + 'date' => $date, + 'hour' => $hour, + 'ip_address' => $row['ip_address'], + 'details' => $row['details'], + ); + $line_id++; + } + + header('Content-type: application/csv'); + header('Content-Disposition: attachment; filename='.date('YmdGis').'piwigo_activity_log.csv'); + header("Content-Transfer-Encoding: UTF-8"); + + $f = fopen('php://output', 'w'); + foreach ($output_lines as $line) { + fputcsv($f, $line, ";"); + } + fclose($f); +} + ?> \ No newline at end of file diff --git a/language/en_UK/admin.lang.php b/language/en_UK/admin.lang.php index 9f49d28e4..315e99c6f 100644 --- a/language/en_UK/admin.lang.php +++ b/language/en_UK/admin.lang.php @@ -1172,3 +1172,53 @@ $lang['Cache size'] = "Cache size"; $lang['calculated'] = "calculated"; $lang['months ago'] = "months ago"; $lang['Delete these sizes'] = 'Delete these sizes'; +$lang['Activity'] = 'Activity'; +$lang['Selected user'] = 'Selected user'; +$lang['Activity time from'] = 'Activity time from'; +$lang['to'] = 'à'; +$lang['add'] = 'add'; +$lang['deletion'] = 'deletion'; +$lang['move'] = 'move'; +$lang['edit'] = 'edit'; +$lang['log'] = 'log'; +$lang['%d album added'] = '%d album added'; +$lang['%d album deleted'] = '%d album deleted'; +$lang['%d album edited'] = '%d album edited'; +$lang['%d albums added'] = '%d albums added'; +$lang['%d albums deleted'] = '%d albums deleted'; +$lang['%d albums edited'] = '%d albums edited'; +$lang['%d user added'] = '%d user added'; +$lang['%d user deleted'] = '%d user deleted'; +$lang['%d user edited'] = '%d user edited'; +$lang['%d user logged in'] = '%d user logged in'; +$lang['%d user logged out'] = '%d user logged out'; +$lang['%d users added'] = '%d users added'; +$lang['%d users deleted'] = '%d users deleted'; +$lang['%d users edited'] = '%d users edited'; +$lang['%d users logged in'] = '%d users logged in'; +$lang['%d users logged out'] = '%d users logged out'; +$lang['%d photo added'] = '%d photo added'; +$lang['%d photo deleted'] = '%d photo deleted'; +$lang['%d photo edited'] = '%d photo edited'; +$lang['%d photo moved'] = '%d photo moved'; +$lang['%d photos added'] = '%d photos added'; +$lang['%d photos deleted'] = '%d photos deleted'; +$lang['%d photos edited'] = '%d photos edited'; +$lang['%d photos moved'] = '%d photos moved'; +$lang['%d group added'] = '%d groupe added'; +$lang['%d group deleted'] = '%d group deleted'; +$lang['%d group edited'] = '%d group edited'; +$lang['%d group moved'] = '%d group moved'; +$lang['%d groups added'] = '%d groups added'; +$lang['%d groups deleted'] = '%d groups deleted'; +$lang['%d groups edited'] = '%d groups edited'; +$lang['%d groups moved'] = '%d groups moved'; +$lang['%d tag added'] = '%d tag added'; +$lang['%d tag deleted'] = '%d tag deleted'; +$lang['%d tag edited'] = '%d tag edited'; +$lang['%d tag moved'] = '%d tag déplacé'; +$lang['%d tags added'] = '%d tags added'; +$lang['%d tags deleted'] = '%d tags deleted'; +$lang['%d tags edited'] = '%d tags edited'; +$lang['%d tags moved'] = '%d tags moved'; +$lang['Download all activities'] = 'Download all activities'; \ No newline at end of file diff --git a/language/fr_FR/admin.lang.php b/language/fr_FR/admin.lang.php index 8f6de73c8..19a775fea 100644 --- a/language/fr_FR/admin.lang.php +++ b/language/fr_FR/admin.lang.php @@ -1174,3 +1174,53 @@ $lang['Cache size'] = "Taille du cache"; $lang['calculated'] = "calculé il y a"; $lang['months ago'] = "mois"; $lang['Delete these sizes'] = 'Supprimer les tailles'; +$lang['Activity'] = 'Activité'; +$lang['Selected user'] = 'Utilisateur sélectionné'; +$lang['Activity time from'] = 'Période d\'activité de'; +$lang['to'] = 'à'; +$lang['add'] = 'ajout'; +$lang['deletion'] = 'suppression'; +$lang['move'] = 'déplacement'; +$lang['edit'] = 'édition'; +$lang['log'] = 'connexion'; +$lang['%d album added'] = '%d album ajouté'; +$lang['%d album deleted'] = '%d album supprimé'; +$lang['%d album edited'] = '%d album édité'; +$lang['%d albums added'] = '%d albums ajoutés'; +$lang['%d albums deleted'] = '%d albums supprimés'; +$lang['%d albums edited'] = '%d albums édité'; +$lang['%d user added'] = '%d utilisateur ajouté'; +$lang['%d user deleted'] = '%d utilisateur suppprimé'; +$lang['%d user edited'] = '%d utilisateur édité'; +$lang['%d user logged in'] = '%d utilisateur connecté'; +$lang['%d user logged out'] = '%d utilisateur déconnecté'; +$lang['%d users added'] = '%d utilisateurs ajoutés'; +$lang['%d users deleted'] = '%d utilisateurs supprimés'; +$lang['%d users edited'] = '%d utilisateurs édités'; +$lang['%d users logged in'] = '%d utilisateurs connectés'; +$lang['%d users logged out'] = '%d utilisateurs déconnectés'; +$lang['%d photo added'] = '%d photo ajoutée'; +$lang['%d photo deleted'] = '%d photo supprimée'; +$lang['%d photo edited'] = '%d photo éditée'; +$lang['%d photo moved'] = '%d photo déplacée'; +$lang['%d photos added'] = '%d photos ajoutées'; +$lang['%d photos deleted'] = '%d photos supprimées'; +$lang['%d photos edited'] = '%d photos éditées'; +$lang['%d photos moved'] = '%d photos déplacées'; +$lang['%d group added'] = '%d groupe ajouté'; +$lang['%d group deleted'] = '%d groupe supprimé'; +$lang['%d group edited'] = '%d groupe édité'; +$lang['%d group moved'] = '%d groupe déplacé'; +$lang['%d groups added'] = '%d groupes ajoutés'; +$lang['%d groups deleted'] = '%d groupes supprimés'; +$lang['%d groups edited'] = '%d groupes édités'; +$lang['%d groups moved'] = '%d groupes déplacés'; +$lang['%d tag added'] = '%d tag ajouté'; +$lang['%d tag deleted'] = '%d tag supprimé'; +$lang['%d tag edited'] = '%d tag édité'; +$lang['%d tag moved'] = '%d tag déplacé'; +$lang['%d tags added'] = '%d tags ajoutés'; +$lang['%d tags deleted'] = '%d tags supprimés'; +$lang['%d tags edited'] = '%d tags édités'; +$lang['%d tags moved'] = '%d tags déplacés'; +$lang['Download all activities'] = 'Télécharger toutes les activités'; \ No newline at end of file diff --git a/ws.php b/ws.php index 601fdae6b..c6deb2533 100644 --- a/ws.php +++ b/ws.php @@ -128,6 +128,24 @@ function ws_addDefaultMethods( $arr ) array('admin_only'=>true) ); + $service->addMethod( + 'pwg.activity.getList', + 'ws_getActivityList', + null, + 'Returns general informations.', + $ws_functions_root . 'pwg.php', + array('admin_only'=>true) + ); + + $service->addMethod( + 'pwg.activity.downloadLog', + 'ws_activity_downloadLog', + null, + 'Returns general informations.', + $ws_functions_root . 'pwg.php', + array('admin_only'=>true) + ); + $service->addMethod( 'pwg.caddie.add', 'ws_caddie_add',