diff options
Diffstat (limited to '')
-rw-r--r-- | admin/batch_manager_global.php | 8 | ||||
-rw-r--r-- | admin/include/configuration_watermark_process.inc.php | 35 | ||||
-rw-r--r-- | admin/include/functions.php | 119 | ||||
-rw-r--r-- | admin/themes/default/template/permalinks.tpl | 9 | ||||
-rw-r--r-- | admin/themes/default/template/rating_user.tpl | 19 | ||||
-rw-r--r-- | admin/themes/default/template/user_list.tpl | 72 |
6 files changed, 216 insertions, 46 deletions
diff --git a/admin/batch_manager_global.php b/admin/batch_manager_global.php index 1d5cb747d..332f3f7a7 100644 --- a/admin/batch_manager_global.php +++ b/admin/batch_manager_global.php @@ -123,6 +123,8 @@ DELETE { if (isset($_POST['del_tags']) and count($_POST['del_tags']) > 0) { + $taglist_before = get_image_tag_ids($collection); + $query = ' DELETE FROM '.IMAGE_TAG_TABLE.' @@ -130,7 +132,11 @@ DELETE AND tag_id IN ('.implode(',', $_POST['del_tags']).') ;'; pwg_query($query); - + + $taglist_after = get_image_tag_ids($collection); + $images_to_update = compare_image_tag_lists($taglist_before, $taglist_after); + update_images_lastmodified($images_to_update); + if (isset($_SESSION['bulk_manager_filter']['tags']) && count(array_intersect($_SESSION['bulk_manager_filter']['tags'], $_POST['del_tags']))) { diff --git a/admin/include/configuration_watermark_process.inc.php b/admin/include/configuration_watermark_process.inc.php index bc1451791..0e07380a7 100644 --- a/admin/include/configuration_watermark_process.inc.php +++ b/admin/include/configuration_watermark_process.inc.php @@ -26,6 +26,21 @@ if( !defined("PHPWG_ROOT_PATH") ) die ("Hacking attempt!"); } +function get_watermark_filename($list, $candidate, $step = 0) +{ + global $change_name; + $change_name = $candidate; + if ($step != 0) + { + $change_name .= '-'.$step; + } + if (in_array($change_name, $list)) + { + return get_watermark_filename($list, $candidate, $step+1); + } + return $change_name.'.png'; +} + $errors = array(); $pwatermark = $_POST['w']; @@ -45,8 +60,22 @@ if (isset($_FILES['watermarkImage']) and !empty($_FILES['watermarkImage']['tmp_n $upload_dir = PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks'; if (mkgetdir($upload_dir, MKGETDIR_DEFAULT&~MKGETDIR_DIE_ON_ERROR)) { - $new_name = get_filename_wo_extension($_FILES['watermarkImage']['name']).'.png'; - $file_path = $upload_dir.'/'.$new_name; + // file name may include exotic chars like single quote, we need a safe name + $new_name = str2url(get_filename_wo_extension($_FILES['watermarkImage']['name'])); + + // we need existing watermarks to avoid overwritting one + $watermark_files = array(); + if ( ($glob=glob(PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks/*.png')) !== false) + { + foreach ($glob as $file) + { + $watermark_files[] = get_filename_wo_extension( + substr($file, strlen(PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks/')) + ); + } + } + + $file_path = $upload_dir.'/'.get_watermark_filename($watermark_files, $new_name); if (move_uploaded_file($_FILES['watermarkImage']['tmp_name'], $file_path)) { @@ -183,4 +212,4 @@ else $template->assign('watermark', $pwatermark); $template->assign('ferrors', $errors); } -?>
\ No newline at end of file +?> diff --git a/admin/include/functions.php b/admin/include/functions.php index 9a827d1d6..030e7fa31 100644 --- a/admin/include/functions.php +++ b/admin/include/functions.php @@ -1519,6 +1519,8 @@ function add_tags($tags, $images) return; } + $taglist_before = get_image_tag_ids($images); + // we can't insert twice the same {image_id,tag_id} so we must first // delete lines we'll insert later $query = ' @@ -1545,6 +1547,11 @@ DELETE array_keys($inserts[0]), $inserts ); + + $taglist_after = get_image_tag_ids($images); + $images_to_update = compare_image_tag_lists($taglist_before, $taglist_after); + update_images_lastmodified($images_to_update); + invalidate_user_cache_nb_tags(); } @@ -1565,6 +1572,15 @@ function delete_tags($tag_ids) return false; } + // we need the list of impacted images, to update their lastmodified + $query = ' +SELECT + image_id + FROM '.IMAGE_TAG_TABLE.' + WHERE tag_id IN ('.implode(',', $tag_ids).') +;'; + $image_ids = query2array($query, null, 'image_id'); + $query = ' DELETE FROM '.IMAGE_TAG_TABLE.' @@ -1579,6 +1595,7 @@ DELETE ;'; pwg_query($query); + update_images_lastmodified($image_ids); invalidate_user_cache_nb_tags(); } @@ -1662,6 +1679,9 @@ function set_tags_of($tags_of) { if (count($tags_of) > 0) { + $taglist_before = get_image_tag_ids(array_keys($tags_of)); + global $logger; $logger->debug('taglist_before', $taglist_before); + $query = ' DELETE FROM '.IMAGE_TAG_TABLE.' @@ -1691,11 +1711,83 @@ DELETE ); } + $taglist_after = get_image_tag_ids(array_keys($tags_of)); + global $logger; $logger->debug('taglist_after', $taglist_after); + $images_to_update = compare_image_tag_lists($taglist_before, $taglist_after); + global $logger; $logger->debug('$images_to_update', $images_to_update); + + update_images_lastmodified($images_to_update); invalidate_user_cache_nb_tags(); } } /** + * Get list of tag ids for each image. Returns an empty list if the image has + * no tags. + * + * @since 2.9 + * @param array $image_ids + * @return associative array, image_id => list of tag ids + */ +function get_image_tag_ids($image_ids) +{ + if (!is_array($image_ids) and is_int($image_ids)) + { + $images_ids = array($image_ids); + } + + if (count($image_ids) == 0) + { + return array(); + } + + $query = ' +SELECT + image_id, + tag_id + FROM '.IMAGE_TAG_TABLE.' + WHERE image_id IN ('.implode(',', $image_ids).') +;'; + + $tags_of = array_fill_keys($image_ids, array()); + $image_tags = query2array($query); + foreach ($image_tags as $image_tag) + { + $tags_of[ $image_tag['image_id'] ][] = $image_tag['tag_id']; + } + + return $tags_of; +} + +/** + * Compare the list of tags, for each image. Returns image_ids where tag list has changed. + * + * @since 2.9 + * @param array $taglist_before - for each image_id (key), list of tag ids + * @param array $taglist_after - for each image_id (key), list of tag ids + * @return array - image_ids where the list has changed + */ +function compare_image_tag_lists($taglist_before, $taglist_after) +{ + $images_to_update = array(); + + foreach ($taglist_after as $image_id => $list_after) + { + sort($list_after); + + $list_before = isset($taglist_before[$image_id]) ? $taglist_before[$image_id] : array(); + sort($list_before); + + if ($list_after != $list_before) + { + $images_to_update[] = $image_id; + } + } + + return $images_to_update; +} + +/** * Associate a list of images to a list of categories. * The function will not duplicate links and will preserve ranks. * @@ -2887,3 +2979,30 @@ function save_images_order($category_id, $images) ); mass_updates(IMAGE_CATEGORY_TABLE, $fields, $datas); } + +/** + * Force update on images.lastmodified column. Useful when modifying the tag + * list. + * + * @since 2.9 + * @param array $image_ids + */ +function update_images_lastmodified($image_ids) +{ + if (!is_array($image_ids) and is_int($image_ids)) + { + $images_ids = array($image_ids); + } + + if (count($image_ids) == 0) + { + return; + } + + $query = ' +UPDATE '.IMAGES_TABLE.' + SET lastmodified = NOW() + WHERE id IN ('.implode(',', $image_ids).') +;'; + pwg_query($query); +} diff --git a/admin/themes/default/template/permalinks.tpl b/admin/themes/default/template/permalinks.tpl index 8ec0f3a6d..15857e3ea 100644 --- a/admin/themes/default/template/permalinks.tpl +++ b/admin/themes/default/template/permalinks.tpl @@ -20,6 +20,13 @@ form fieldset p.actionButtons {margin-bottom:0} </style> {/literal} +{html_style} +[name="permalink"] { + width : 100%; + max-width : 600px; +} +{/html_style} + <div class="titrePage"> <h2>{'Permalinks'|@translate}</h2> </div> @@ -96,4 +103,4 @@ form fieldset p.actionButtons {margin-bottom:0} </tr> {/foreach} </table> -</fieldset>
\ No newline at end of file +</fieldset> diff --git a/admin/themes/default/template/rating_user.tpl b/admin/themes/default/template/rating_user.tpl index bc2b29ad6..e1493832a 100644 --- a/admin/themes/default/template/rating_user.tpl +++ b/admin/themes/default/template/rating_user.tpl @@ -65,14 +65,14 @@ body .ui-tooltip { {combine_script id='core.scripts' load='async' path='themes/default/js/scripts.js'} {combine_script id='jquery.geoip' load='async' path='admin/themes/default/js/jquery.geoip.js'} {footer_script} -var oTable = jQuery('#rateTable').dataTable({ - sDom : '<"dtBar"filp>rt<"dtBar"ilp>', - iDisplayLength: 100, - aLengthMenu: [ [25, 50, 100, 500, -1], [25, 50, 100, 500, "All"]], - aaSorting: [], //[[1,'desc']], - bAutoWidth: false, - bSortClasses: false, - aoColumnDefs: [ +jQuery('#rateTable').dataTable({ + dom : '<"dtBar"filp>rt<"dtBar"ilp>', + pageLength: 100, + lengthMenu: [ [25, 50, 100, 500, -1], [25, 50, 100, 500, "All"]], + sorting: [], //[[1,'desc']], + autoWidth: false, + sortClasses: false, + columnDefs: [ { aTargets: ["dtc_user"], sType: "string", @@ -108,6 +108,7 @@ var oTable = jQuery('#rateTable').dataTable({ ] }); +var oTable = jQuery('#rateTable').DataTable(); function uidFromCell(cell){ var tr = cell; @@ -135,7 +136,7 @@ $(document).ready( function(){ onFailure: function(num, text) { tr.stop(); tr.fadeTo(0,1); alert(num + " " + text); }, onSuccess: function(result){ if (result) - oTable.fnDeleteRow(tr[0]); + oTable.row(tr[0]).remove().draw(); else alert(result); } diff --git a/admin/themes/default/template/user_list.tpl b/admin/themes/default/template/user_list.tpl index dedf59cf6..c25ae0df6 100644 --- a/admin/themes/default/template/user_list.tpl +++ b/admin/themes/default/template/user_list.tpl @@ -76,7 +76,7 @@ jQuery(document).ready(function() { jQuery("#addUserForm .loading").show(); }, success:function(data) { - oTable.fnDraw(); + oTable.draw(); jQuery("#addUserForm .loading").hide(); var data = jQuery.parseJSON(data); @@ -172,7 +172,7 @@ jQuery(document).ready(function() { /* Formating function for row details */ function fnFormatDetails(oTable, nTr) { - var userId = oTable.fnGetData(nTr)[0]; + var userId = oTable.api().row(nTr).data()[0]; console.log("userId = "+userId); var sOut = null; @@ -567,7 +567,7 @@ jQuery(document).on('click', '.close-user-details', function(e) { title:"{/literal}{'Edit user'|translate}{literal}", href:".user_form_popin", onClosed: function() { - oTable.fnDraw(); + oTable.draw(); } }); @@ -578,10 +578,10 @@ jQuery(document).on('click', '.close-user-details', function(e) { /* first column must be prefixed with the open/close icon */ var aoColumns = [ { - 'bVisible':false + visible:false }, { - "mRender": function(data, type, full) { + render: function(data, type, full) { return '<label><input type="checkbox" data-user_id="'+full[0]+'"> '+data+'</label> <a title="{/literal}{'Open user details'|translate|escape:'javascript'}{literal}" class="icon-pencil openUserDetails">{/literal}{'edit'|translate}{literal}</a>'; } } @@ -592,35 +592,36 @@ jQuery(document).on('click', '.close-user-details', function(e) { } var oTable = jQuery('#userList').dataTable({ - "iDisplayLength": 10, - "bDeferRender": true, - "bProcessing": true, - "bServerSide": true, - "sServerMethod": "POST", - "sAjaxSource": "admin/user_list_backend.php", - "oLanguage": { - "sProcessing": "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}", - "sLengthMenu": sprintf("{/literal}{'Show %s users'|translate|escape:'javascript'}{literal}", '_MENU_'), - "sZeroRecords": "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}", - "sInfo": sprintf("{/literal}{'Showing %s to %s of %s users'|translate|escape:'javascript'}{literal}", '_START_', '_END_', '_TOTAL_'), - "sInfoEmpty": "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}", - "sInfoFiltered": sprintf("{/literal}{'(filtered from %s total users)'|translate|escape:'javascript'}{literal}", '_MAX_'), - "sSearch": '<span class="icon-search"></span>'+"{/literal}{'Search'|translate|escape:'javascript'}{literal}", - "sLoadingRecords": "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}", - "oPaginate": { - "sFirst": "{/literal}{'First'|translate|escape:'javascript'}{literal}", - "sPrevious": '← '+"{/literal}{'Previous'|translate|escape:'javascript'}{literal}", - "sNext": "{/literal}{'Next'|translate|escape:'javascript'}{literal}"+' →', - "sLast": "{/literal}{'Last'|translate|escape:'javascript'}{literal}", + pageLength: 10, + deferRender: true, + processing: true, + serverSide: true, + serverMethod: "POST", + ajaxSource: "admin/user_list_backend.php", + pagingType: "simple", + language: { + processing: "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}", + lengthMenu: sprintf("{/literal}{'Show %s users'|translate|escape:'javascript'}{literal}", '_MENU_'), + zeroRecords: "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}", + info: sprintf("{/literal}{'Showing %s to %s of %s users'|translate|escape:'javascript'}{literal}", '_START_', '_END_', '_TOTAL_'), + infoEmpty: "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}", + infoFiltered: sprintf("{/literal}{'(filtered from %s total users)'|translate|escape:'javascript'}{literal}", '_MAX_'), + search: '<span class="icon-search"></span>'+"{/literal}{'Search'|translate|escape:'javascript'}{literal}", + loadingRecords: "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}", + paginate: { + first: "{/literal}{'First'|translate|escape:'javascript'}{literal}", + previous: '← '+"{/literal}{'Previous'|translate|escape:'javascript'}{literal}", + next: "{/literal}{'Next'|translate|escape:'javascript'}{literal}"+' →', + last: "{/literal}{'Last'|translate|escape:'javascript'}{literal}", } }, - "fnDrawCallback": function( oSettings ) { + "drawCallback": function( oSettings ) { jQuery("#userList input[type=checkbox]").each(function() { var user_id = jQuery(this).data("user_id"); jQuery(this).prop('checked', (selection.indexOf(user_id) != -1)); }); }, - "aoColumns": aoColumns + columns: aoColumns }); /** @@ -807,7 +808,7 @@ jQuery(document).on('click', '.close-user-details', function(e) { jQuery("#applyActionLoading").show(); }, success:function(data) { - oTable.fnDraw(); + oTable.draw(); jQuery("#applyActionLoading").hide(); jQuery("#applyActionBlock .infos").show(); @@ -840,11 +841,18 @@ jQuery(document).on('click', '.close-user-details', function(e) { .dataTables_wrapper, .dataTables_info {clear:none;} table.dataTable {clear:right;padding-top:10px;} .dataTable td img {margin-bottom: -6px;margin-left: -6px;} -.paginate_enabled_previous, .paginate_enabled_previous:hover, .paginate_disabled_previous, .paginate_enabled_next, .paginate_enabled_next:hover, .paginate_disabled_next {background:none;} -.paginate_enabled_previous, .paginate_enabled_next {color:#005E89 !important;} -.paginate_enabled_previous:hover, .paginate_enabled_next:hover {color:#D54E21 !important; text-decoration:underline !important;} -.paginate_disabled_next, .paginate_enabled_next {padding-right:3px;} +.paginate_button, .paginate_button:hover {background:none !important;} +.dataTables_wrapper .dataTables_paginate .paginate_button {color:#005E89 !important;} +.dataTables_wrapper .dataTables_paginate .paginate_button:hover {color:#D54E21 !important; text-decoration:underline !important; border-color:transparent;} + +.paginate_button.next {padding-right:3px !important;} + +table.dataTable tbody th, +table.dataTable tbody td { + padding: 3px 5px; +} + .bulkAction {margin-top:10px;} #addUserForm p {margin-left:0;} #applyActionBlock .actionButtons {margin-left:0;} |