aboutsummaryrefslogtreecommitdiffstats
path: root/admin
diff options
context:
space:
mode:
Diffstat (limited to 'admin')
-rw-r--r--admin/batch_manager_global.php8
-rw-r--r--admin/include/configuration_watermark_process.inc.php35
-rw-r--r--admin/include/functions.php119
-rw-r--r--admin/themes/default/template/permalinks.tpl9
-rw-r--r--admin/themes/default/template/rating_user.tpl19
-rw-r--r--admin/themes/default/template/user_list.tpl72
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;}