aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--admin.php1
-rw-r--r--admin/element_set_global.php134
-rw-r--r--admin/element_set_unit.php34
-rw-r--r--admin/include/functions.php196
-rw-r--r--admin/include/functions_metadata.php34
-rw-r--r--admin/picture_modify.php31
-rw-r--r--admin/site_update.php53
-rw-r--r--admin/tags.php265
-rw-r--r--include/category_default.inc.php2
-rw-r--r--include/common.inc.php1
-rw-r--r--include/config_default.inc.php13
-rw-r--r--include/constants.php2
-rw-r--r--include/functions.inc.php33
-rw-r--r--include/functions_html.inc.php53
-rw-r--r--include/functions_search.inc.php68
-rw-r--r--include/functions_tag.inc.php218
-rw-r--r--include/functions_url.inc.php34
-rw-r--r--include/functions_user.inc.php1
-rw-r--r--include/section_init.inc.php117
-rw-r--r--index.php80
-rw-r--r--install/db/19-database.php151
-rw-r--r--install/phpwebgallery_structure.sql31
-rw-r--r--language/en_UK.iso-8859-1/admin.lang.php111
-rw-r--r--language/en_UK.iso-8859-1/common.lang.php27
-rw-r--r--language/fr_FR.iso-8859-1/admin.lang.php110
-rw-r--r--language/fr_FR.iso-8859-1/common.lang.php27
-rw-r--r--picture.php48
-rw-r--r--search.php18
-rw-r--r--search_rules.php28
-rw-r--r--tags.php120
-rw-r--r--template/yoga/admin.tpl1
-rw-r--r--template/yoga/admin/element_set_global.tpl16
-rw-r--r--template/yoga/admin/element_set_unit.tpl4
-rw-r--r--template/yoga/admin/picture_modify.tpl5
-rw-r--r--template/yoga/admin/tags.tpl55
-rw-r--r--template/yoga/content.css1
-rw-r--r--template/yoga/default-layout.css9
-rw-r--r--template/yoga/icon/add_tag.pngbin0 -> 59 bytes
-rw-r--r--template/yoga/index.tpl17
-rw-r--r--template/yoga/menubar.css9
-rw-r--r--template/yoga/picture.tpl4
-rw-r--r--template/yoga/search.tpl10
-rw-r--r--template/yoga/search_rules.tpl12
-rw-r--r--template/yoga/tags.tpl17
44 files changed, 1848 insertions, 353 deletions
diff --git a/admin.php b/admin.php
index fa9a23cc0..6617dfadc 100644
--- a/admin.php
+++ b/admin.php
@@ -92,6 +92,7 @@ $template->assign_vars(
'U_COMMENTS'=> $link_start.'comments',
'U_RATING'=> $link_start.'rating',
'U_CADDIE'=> $link_start.'element_set&cat=caddie',
+ 'U_TAGS'=> $link_start.'tags',
'U_THUMBNAILS'=> $link_start.'thumbnail',
'U_USERS'=> $link_start.'user_list',
'U_GROUPS'=> $link_start.'group_list',
diff --git a/admin/element_set_global.php b/admin/element_set_global.php
index 61ef2d6ee..f4b8aae2b 100644
--- a/admin/element_set_global.php
+++ b/admin/element_set_global.php
@@ -44,40 +44,6 @@ include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
check_status(ACCESS_ADMINISTRATOR);
// +-----------------------------------------------------------------------+
-// | functions |
-// +-----------------------------------------------------------------------+
-
-/**
- * returns the list of uniq keywords among given elements
- *
- * @param array element_ids
- */
-function get_elements_keywords($element_ids)
-{
- if (0 == count($element_ids))
- {
- return array();
- }
-
- $keywords = array();
-
- $query = '
-SELECT keywords
- FROM '.IMAGES_TABLE.'
- WHERE id IN ('.implode(',', $element_ids).')
-;';
- $result = pwg_query($query);
- while ($row = mysql_fetch_array($result))
- {
- if (isset($row['keywords']) and !empty($row['keywords']))
- {
- $keywords = array_merge($keywords, explode(',', $row['keywords']));
- }
- }
- return array_unique($keywords);
-}
-
-// +-----------------------------------------------------------------------+
// | global mode form submission |
// +-----------------------------------------------------------------------+
@@ -111,6 +77,22 @@ if (isset($_POST['submit']))
}
}
+ if (isset($_POST['add_tags']) and count($collection) > 0)
+ {
+ add_tags($_POST['add_tags'], $collection);
+ }
+
+ if (isset($_POST['del_tags']) and count($collection) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', $collection).')
+ AND tag_id IN ('.implode(',', $_POST['del_tags']).')
+;';
+ pwg_query($query);
+ }
+
if ($_POST['associate'] != 0 and count($collection) > 0)
{
$datas = array();
@@ -192,11 +174,6 @@ DELETE
$datas = array();
$dbfields = array('primary' => array('id'), 'update' => array());
- if (!empty($_POST['add_keywords']) or $_POST['remove_keyword'] != '0')
- {
- array_push($dbfields['update'], 'keywords');
- }
-
$formfields = array('author', 'name', 'date_creation');
foreach ($formfields as $formfield)
{
@@ -210,7 +187,7 @@ DELETE
if (count($dbfields['update']) > 0 and count($collection) > 0)
{
$query = '
-SELECT id, keywords
+SELECT id
FROM '.IMAGES_TABLE.'
WHERE id IN ('.implode(',', $collection).')
;';
@@ -221,44 +198,6 @@ SELECT id, keywords
$data = array();
$data['id'] = $row['id'];
- if (!empty($_POST['add_keywords']))
- {
- $data['keywords'] =
- implode(
- ',',
- array_unique(
- array_merge(
- get_keywords(empty($row['keywords']) ? '' : $row['keywords']),
- get_keywords($_POST['add_keywords'])
- )
- )
- );
- }
-
- if ($_POST['remove_keyword'] != '0')
- {
- if (!isset($data['keywords']))
- {
- $data['keywords'] = empty($row['keywords']) ? '' : $row['keywords'];
- }
-
- $data['keywords'] =
- implode(
- ',',
- array_unique(
- array_diff(
- get_keywords($data['keywords']),
- array($_POST['remove_keyword'])
- )
- )
- );
-
- if ($data['keywords'] == '')
- {
- unset($data['keywords']);
- }
- }
-
if ('set' == $_POST['author_action'])
{
$data['author'] = $_POST['author'];
@@ -384,25 +323,36 @@ SELECT DISTINCT(category_id) AS id, c.name, uppercats, global_rank
display_select_cat_wrapper($query, array(), $blockname, true);
}
-$blockname = 'remove_keyword_option';
-
-$template->assign_block_vars(
- $blockname,
- array('VALUE'=> 0,
- 'OPTION' => '------------'
- ));
+// add tags
+$template->assign_vars(
+ array(
+ 'ADD_TAG_SELECTION' => get_html_tag_selection(get_all_tags(), 'add_tags'),
+ )
+ );
-$keywords = get_elements_keywords($page['cat_elements_id']);
+// remove tags
+$query = '
+SELECT tag_id, name, url_name, count(*) counter
+ FROM '.IMAGE_TAG_TABLE.'
+ INNER JOIN '.TAGS_TABLE.' ON tag_id = id
+ WHERE image_id IN ('.implode(',', $page['cat_elements_id']).')
+ GROUP BY tag_id
+ ORDER BY name ASC
+;';
+$result = pwg_query($query);
-foreach ($keywords as $keyword)
+$tags = array();
+while($row = mysql_fetch_array($result))
{
- $template->assign_block_vars(
- $blockname,
- array('VALUE'=> $keyword,
- 'OPTION' => $keyword
- ));
+ array_push($tags, $row);
}
+$template->assign_vars(
+ array(
+ 'DEL_TAG_SELECTION' => get_html_tag_selection($tags, 'del_tags'),
+ )
+ );
+
// creation date
$day =
empty($_POST['date_creation_day']) ? date('j') : $_POST['date_creation_day'];
diff --git a/admin/element_set_unit.php b/admin/element_set_unit.php
index c43522894..f6800f399 100644
--- a/admin/element_set_unit.php
+++ b/admin/element_set_unit.php
@@ -103,25 +103,21 @@ SELECT id, date_creation
{
$data{'date_creation'} = $row['date_creation'];
}
+
+ array_push($datas, $data);
- $keywords = get_keywords($_POST['keywords-'.$row['id']]);
- if (count($keywords) > 0)
- {
- $data{'keywords'} = implode(',', $keywords);
- }
- else
+ // tags management
+ if (isset($_POST[ 'tags-'.$row['id'] ]))
{
- $data{'keywords'} = '';
+ set_tags($_POST[ 'tags-'.$row['id'] ], $row['id']);
}
-
- array_push($datas, $data);
}
mass_updates(
IMAGES_TABLE,
array(
'primary' => array('id'),
- 'update' => array('name','author','comment','date_creation','keywords')
+ 'update' => array('name','author','comment','date_creation')
),
$datas
);
@@ -192,11 +188,13 @@ if (count($page['cat_elements_id']) > 0)
);
$template->assign_vars(array('NAV_BAR' => $nav_bar));
+ // tags
+ $all_tags = get_all_tags();
$element_ids = array();
$query = '
-SELECT id,path,tn_ext,name,date_creation,comment,keywords,author,file
+SELECT id,path,tn_ext,name,date_creation,comment,author,file
FROM '.IMAGES_TABLE.'
WHERE id IN ('.implode(',', $page['cat_elements_id']).')
'.$conf['order_by'].'
@@ -210,6 +208,13 @@ SELECT id,path,tn_ext,name,date_creation,comment,keywords,author,file
array_push($element_ids, $row['id']);
$src = get_thumbnail_src($row['path'], @$row['tn_ext']);
+
+ $query = '
+SELECT tag_id
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id = '.$row['id'].'
+;';
+ $selected_tags = array_from_query($query, 'tag_id');
// creation date
if (!empty($row['date_creation']))
@@ -237,7 +242,12 @@ SELECT id,path,tn_ext,name,date_creation,comment,keywords,author,file
'AUTHOR' => @$row['author'],
'DESCRIPTION' => @$row['comment'],
'DATE_CREATION_YEAR' => $year,
- 'KEYWORDS' => @$row['keywords']
+
+ 'TAG_SELECTION' => get_html_tag_selection(
+ $all_tags,
+ 'tags-'.$row['id'],
+ $selected_tags
+ ),
)
);
diff --git a/admin/include/functions.php b/admin/include/functions.php
index dc477f6d1..3a8c6b506 100644
--- a/admin/include/functions.php
+++ b/admin/include/functions.php
@@ -269,6 +269,14 @@ DELETE FROM '.IMAGE_CATEGORY_TABLE.'
;';
pwg_query($query);
+ // destruction of the links between images and tags
+ $query = '
+DELETE FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+ pwg_query($query);
+
// destruction of the favorites associated with the picture
$query = '
DELETE FROM '.FAVORITES_TABLE.'
@@ -577,25 +585,6 @@ function date_convert_back( $date )
}
/**
- * returns an array with relevant keywords found in the given string.
- *
- * Keywords must be separated by comma or space characters.
- *
- * @param string keywords_string
- * @return array
- */
-function get_keywords($keywords_string)
-{
- return
- array_unique(
- preg_split(
- '/[\s,]+/',
- $keywords_string
- )
- );
-}
-
-/**
* returns an array containing sub-directories which can be a category,
* recursive by default
*
@@ -2094,6 +2083,173 @@ UPDATE
}
/**
+ * Set tags to an image. Warning: given tags are all tags associated to the
+ * image, not additionnal tags.
+ *
+ * @param array tag ids
+ * @param int image id
+ * @return void
+ */
+function set_tags($tags, $image_id)
+{
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id = '.$image_id.'
+;';
+ pwg_query($query);
+
+ if (count($tags) > 0)
+ {
+ $inserts = array();
+ foreach ($tags as $tag_id)
+ {
+ array_push(
+ $inserts,
+ array(
+ 'tag_id' => $tag_id,
+ 'image_id' => $image_id
+ )
+ );
+ }
+ mass_inserts(
+ IMAGE_TAG_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+ }
+}
+
+/**
+ * Add new tags to a set of images.
+ *
+ * @param array tag ids
+ * @param array image ids
+ * @return void
+ */
+function add_tags($tags, $images)
+{
+ if (count($tags) == 0 or count($tags) == 0)
+ {
+ return;
+ }
+
+ // we can't insert twice the same {image_id,tag_id} so we must first
+ // delete lines we'll insert later
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', $images).')
+ AND tag_id IN ('.implode(',', $tags).')
+;';
+ pwg_query($query);
+
+ $inserts = array();
+ foreach ($images as $image_id)
+ {
+ foreach ($tags as $tag_id)
+ {
+ array_push(
+ $inserts,
+ array(
+ 'image_id' => $image_id,
+ 'tag_id' => $tag_id,
+ )
+ );
+ }
+ }
+ mass_inserts(
+ IMAGE_TAG_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+}
+
+function tag_id_from_tag_name($tag_name)
+{
+ global $page;
+
+ if (isset($page['tag_id_from_tag_name_cache'][$tag_name]))
+ {
+ return $page['tag_id_from_tag_name_cache'][$tag_name];
+ }
+
+ if (function_exists('mysql_real_escape_string'))
+ {
+ $tag_name = mysql_real_escape_string($tag_name);
+ }
+ else
+ {
+ $tag_name = mysql_escape_string($tag_name);
+ }
+
+ // does the tag already exist?
+ $query = '
+SELECT id
+ FROM '.TAGS_TABLE.'
+ WHERE name = \''.$tag_name.'\'
+;';
+ $existing_tags = array_from_query($query, 'id');
+
+ if (count($existing_tags) == 0)
+ {
+ mass_inserts(
+ TAGS_TABLE,
+ array('name', 'url_name'),
+ array(
+ array(
+ 'name' => $tag_name,
+ 'url_name' => str2url($tag_name),
+ )
+ )
+ );
+
+ $page['tag_id_from_tag_name_cache'][$tag_name] = mysql_insert_id();
+ }
+ else
+ {
+ $page['tag_id_from_tag_name_cache'][$tag_name] = $existing_tags[0];
+ }
+
+ return $page['tag_id_from_tag_name_cache'][$tag_name];
+}
+
+function set_tags_of($tags_of)
+{
+ if (count($tags_of) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', array_keys($tags_of)).')
+;';
+ pwg_query($query);
+
+ $inserts = array();
+
+ foreach ($tags_of as $image_id => $tag_ids)
+ {
+ foreach ($tag_ids as $tag_id)
+ {
+ array_push(
+ $inserts,
+ array(
+ 'image_id' => $image_id,
+ 'tag_id' => $tag_id,
+ )
+ );
+ }
+ }
+
+ mass_inserts(
+ IMAGE_TAG_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+ }
+}
+
+/**
* Do maintenance on all PWG tables
*
* @return nono
@@ -2143,6 +2299,4 @@ function do_maintenance_all_tables()
pwg_query($query);
}
-
-
?>
diff --git a/admin/include/functions_metadata.php b/admin/include/functions_metadata.php
index 337019b2e..21897c2cd 100644
--- a/admin/include/functions_metadata.php
+++ b/admin/include/functions_metadata.php
@@ -50,10 +50,7 @@ function get_sync_iptc_data($file)
if (isset($iptc['keywords']))
{
- // keywords separator is the comma, nothing else. Allowed characters in
- // keywords : [A-Za-z0-9], "-" and "_". All other characters will be
- // considered as separators
- $iptc['keywords'] = preg_replace('/[^\w-]+/', ',', $iptc['keywords']);
+ // keywords separator is the comma
$iptc['keywords'] = preg_replace('/^,+|,+$/', '', $iptc['keywords']);
}
@@ -90,6 +87,7 @@ function update_metadata($files)
}
$datas = array();
+ $tags_of = array();
foreach ($files as $id => $file)
{
@@ -123,7 +121,25 @@ function update_metadata($files)
{
foreach (array_keys($iptc) as $key)
{
- $data[$key] = addslashes($iptc[$key]);
+ if ($key == 'keywords' or $key == 'tags')
+ {
+ if (!isset($tags_of[$id]))
+ {
+ $tags_of[$id] = array();
+ }
+
+ foreach (explode(',', $iptc[$key]) as $tag_name)
+ {
+ array_push(
+ $tags_of[$id],
+ tag_id_from_tag_name($tag_name)
+ );
+ }
+ }
+ else
+ {
+ $data[$key] = addslashes($iptc[$key]);
+ }
}
}
}
@@ -157,7 +173,10 @@ function update_metadata($files)
$update_fields =
array_merge(
$update_fields,
- array_keys($conf['use_iptc_mapping'])
+ array_diff(
+ array_keys($conf['use_iptc_mapping']),
+ array('tags', 'keywords')
+ )
);
}
@@ -166,8 +185,11 @@ function update_metadata($files)
'primary' => array('id'),
'update' => array_unique($update_fields)
);
+ echo '<pre>'; print_r($datas); echo '</pre>';
mass_updates(IMAGES_TABLE, $fields, $datas);
}
+
+ set_tags_of(tags_of);
}
/**
diff --git a/admin/picture_modify.php b/admin/picture_modify.php
index be7497a07..83bf09a23 100644
--- a/admin/picture_modify.php
+++ b/admin/picture_modify.php
@@ -100,16 +100,6 @@ if (isset($_POST['submit']) and count($page['errors']) == 0)
}
}
- $keywords = get_keywords($_POST['keywords']);
- if (count($keywords) > 0)
- {
- $data{'keywords'} = implode(',', $keywords);
- }
- else
- {
- $data{'keywords'} = '';
- }
-
mass_updates(
IMAGES_TABLE,
array(
@@ -119,6 +109,11 @@ if (isset($_POST['submit']) and count($page['errors']) == 0)
array($data)
);
+ set_tags(
+ isset($_POST['tags']) ? $_POST['tags'] : array(),
+ $_GET['image_id']
+ );
+
array_push($page['infos'], l10n('Picture informations updated'));
}
// associate the element to other categories than its storage category
@@ -215,6 +210,14 @@ $row = mysql_fetch_array(pwg_query($query));
$storage_category_id = $row['category_id'];
$image_file = $row['file'];
+// tags
+$query = '
+SELECT tag_id
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id = '.$_GET['image_id'].'
+;';
+$selected_tags = array_from_query($query, 'tag_id');
+
// Navigation path
$date = isset($_POST['date_creation']) && empty($page['errors'])
@@ -257,9 +260,11 @@ $template->assign_vars(
'CREATION_DATE' => $date,
- 'KEYWORDS' =>
- isset($_POST['keywords']) ?
- stripslashes($_POST['keywords']) : @$row['keywords'],
+ 'TAG_SELECTION' => get_html_tag_selection(
+ get_all_tags(),
+ 'tags',
+ $selected_tags
+ ),
'DESCRIPTION' =>
isset($_POST['description']) ?
diff --git a/admin/site_update.php b/admin/site_update.php
index b68ce2b28..c7c31106c 100644
--- a/admin/site_update.php
+++ b/admin/site_update.php
@@ -715,6 +715,7 @@ if (isset($_POST['submit']) and preg_match('/^metadata/', $_POST['sync'])
$start = get_moment();
$datas = array();
+ $tags_of = array();
foreach ( $files as $id=>$file )
{
$data = $site_reader->get_element_update_attributes($file);
@@ -723,23 +724,55 @@ if (isset($_POST['submit']) and preg_match('/^metadata/', $_POST['sync'])
$data['date_metadata_update'] = CURRENT_DATE;
$data['id']=$id;
array_push($datas, $data);
+
+ foreach (array('keywords', 'tags') as $key)
+ {
+ if (isset($data[$key]))
+ {
+ if (!isset($tags_of[$id]))
+ {
+ $tags_of[$id] = array();
+ }
+
+ foreach (explode(',', $data[$key]) as $tag_name)
+ {
+ array_push(
+ $tags_of[$id],
+ tag_id_from_tag_name($tag_name)
+ );
+ }
+ }
+ }
}
else
{
array_push($errors, array('path' => $file, 'type' => 'PWG-ERROR-NO-FS'));
}
}
- $update_fields = $site_reader->get_update_attributes();
- $update_fields = array_merge($update_fields, array('date_metadata_update'));
- $fields =
- array(
- 'primary' => array('id'),
- 'update' => array_unique($update_fields)
- );
- //print_r($datas);
- if (!$simulate and count($datas)>0 )
+
+ if (!$simulate)
{
- mass_updates(IMAGES_TABLE, $fields, $datas);
+ if (count($datas) > 0)
+ {
+ mass_updates(
+ IMAGES_TABLE,
+ // fields
+ array(
+ 'primary' => array('id'),
+ 'update' => array_unique(
+ array_merge(
+ array_diff(
+ $site_reader->get_update_attributes(),
+ // keywords and tags fields are managed separately
+ array('keywords', 'tags')
+ ),
+ array('date_metadata_update'))
+ )
+ ),
+ $datas
+ );
+ }
+ set_tags_of($tags_of);
}
echo '<!-- metadata update : ';
diff --git a/admin/tags.php b/admin/tags.php
new file mode 100644
index 000000000..7ff29727c
--- /dev/null
+++ b/admin/tags.php
@@ -0,0 +1,265 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | branch : BSF (Best So Far)
+// | file : $RCSfile$
+// | last update : $Date: 2006-03-09 23:46:28 +0100 (jeu, 09 mar 2006) $
+// | last modifier : $Author: rub $
+// | revision : $Revision: 1072 $
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify |
+// | it under the terms of the GNU General Public License as published by |
+// | the Free Software Foundation |
+// | |
+// | This program is distributed in the hope that it will be useful, but |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
+// | General Public License for more details. |
+// | |
+// | You should have received a copy of the GNU General Public License |
+// | along with this program; if not, write to the Free Software |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA. |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+ die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | edit tags |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']))
+{
+ $query = '
+SELECT name
+ FROM '.TAGS_TABLE.'
+;';
+ $existing_names = array_from_query($query, 'name');
+
+
+ $current_name_of = array();
+ $query = '
+SELECT id, name
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.$_POST['edit_list'].')
+;';
+ $result = pwg_query($query);
+ while ($row = mysql_fetch_array($result))
+ {
+ $current_name_of[ $row['id'] ] = $row['name'];
+ }
+
+ $updates = array();
+ // we must not rename tag with an already existing name
+ foreach (explode(',', $_POST['edit_list']) as $tag_id)
+ {
+ if (function_exists('mysql_real_escape_string'))
+ {
+ $tag_name = mysql_real_escape_string($_POST['tag_name-'.$tag_id]);
+ }
+ else
+ {
+ $tag_name = mysql_escape_string($_POST['tag_name-'.$tag_id]);
+ }
+
+ if ($tag_name != $current_name_of[$tag_id])
+ {
+ if (in_array($tag_name, $existing_names))
+ {
+ array_push(
+ $page['errors'],
+ sprintf(
+ l10n('Tag "%s" already exist'),
+ $tag_name
+ )
+ );
+ }
+ else if (!empty($tag_name))
+ {
+ array_push(
+ $updates,
+ array(
+ 'id' => $tag_id,
+ 'name' => $tag_name,
+ 'url_name' => str2url($tag_name),
+ )
+ );
+ }
+ }
+ }
+ mass_updates(
+ TAGS_TABLE,
+ array(
+ 'primary' => array('id'),
+ 'update' => array('name', 'url_name'),
+ ),
+ $updates
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | delete tags |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['delete']) and isset($_POST['tags']))
+{
+ $query = '
+SELECT name
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.implode(',', $_POST['tags']).')
+;';
+ $tag_names = array_from_query($query, 'name');
+
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE tag_id IN ('.implode(',', $_POST['tags']).')
+;';
+ pwg_query($query);
+
+ $query = '
+DELETE
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.implode(',', $_POST['tags']).')
+;';
+ pwg_query($query);
+
+ array_push(
+ $page['infos'],
+ sprintf(
+ l10n('The %d following tags were deleted : %s'),
+ count($tag_names),
+ implode(', ', $tag_names)
+ )
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | add a tag |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['add_tag']) and !empty($_POST['add_tag']))
+{
+ if (function_exists('mysql_real_escape_string'))
+ {
+ $tag_name = mysql_real_escape_string($_POST['add_tag']);
+ }
+ else
+ {
+ $tag_name = mysql_escape_string($_POST['add_tag']);
+ }
+
+ // does the tag already exist?
+ $query = '
+SELECT id
+ FROM '.TAGS_TABLE.'
+ WHERE name = \''.$tag_name.'\'
+;';
+ $existing_tags = array_from_query($query, 'id');
+
+ if (count($existing_tags) == 0)
+ {
+ mass_inserts(
+ TAGS_TABLE,
+ array('name', 'url_name'),
+ array(
+ array(
+ 'name' => $tag_name,
+ 'url_name' => str2url($tag_name),
+ )
+ )
+ );
+
+ array_push(
+ $page['infos'],
+ sprintf(
+ l10n('Tag "%s" was added'),
+ $tag_name
+ )
+ );
+ }
+ else
+ {
+ array_push(
+ $page['errors'],
+ sprintf(
+ l10n('Tag "%s" already exist'),
+ $tag_name
+ )
+ );
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('tags' => 'admin/tags.tpl'));
+
+$template->assign_vars(
+ array(
+ 'F_ACTION' => PHPWG_ROOT_PATH.'admin.php?page=tags'
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | form creation |
+// +-----------------------------------------------------------------------+
+
+$template->assign_vars(
+ array(
+ 'TAG_SELECTION' => get_html_tag_selection(
+ get_all_tags(),
+ 'tags'
+ ),
+ )
+ );
+
+if (isset($_POST['edit']) and isset($_POST['tags']))
+{
+ $template->assign_block_vars(
+ 'edit_tags',
+ array(
+ 'LIST' => implode(',', $_POST['tags']),
+ )
+ );
+
+ $query = '
+SELECT id, name
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.implode(',', $_POST['tags']).')
+;';
+ $result = pwg_query($query);
+ while ($row = mysql_fetch_array($result))
+ {
+ $name_of[ $row['id'] ] = $row['name'];
+ }
+
+ foreach ($_POST['tags'] as $tag_id)
+ {
+ $template->assign_block_vars(
+ 'edit_tags.tag',
+ array(
+ 'ID' => $tag_id,
+ 'NAME' => $name_of[$tag_id],
+ )
+ );
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'tags');
+
+?>
diff --git a/include/category_default.inc.php b/include/category_default.inc.php
index 31d40ed90..6c909647a 100644
--- a/include/category_default.inc.php
+++ b/include/category_default.inc.php
@@ -79,7 +79,7 @@ foreach ($pictures as $row)
{
$thumbnail_title .= ' : '.$row['filesize'].' KB';
}
-
+
// link on picture.php page
$url = duplicate_picture_url(
array(
diff --git a/include/common.inc.php b/include/common.inc.php
index 42697353e..f66d1ee7f 100644
--- a/include/common.inc.php
+++ b/include/common.inc.php
@@ -148,6 +148,7 @@ SELECT id
if (count(array_diff($existing, $applied)) > 0)
{
ob_start();// buffer output so that cookies work
+
echo
'<p>'
.'Some database upgrades are missing, '
diff --git a/include/config_default.inc.php b/include/config_default.inc.php
index 3675f2ed6..57a4520c3 100644
--- a/include/config_default.inc.php
+++ b/include/config_default.inc.php
@@ -439,6 +439,18 @@ $conf['picture_url_style'] = 'id';
$conf['php_extension_in_urls'] = true;
// +-----------------------------------------------------------------------+
+// | tags |
+// +-----------------------------------------------------------------------+
+
+// full_tag_cloud_items_number: number of tags to show in the full tag
+// cloud. Only the most represented tags will be shown
+$conf['full_tag_cloud_items_number'] = 200;
+
+// tags_levels: number of levels to use for display. Each level is bind to a
+// CSS class tagLevelX.
+$conf['tags_levels'] = 10;
+
+// +-----------------------------------------------------------------------+
// | Notification by mail |
// +-----------------------------------------------------------------------+
@@ -455,5 +467,4 @@ $conf['nbm_list_all_enabled_users_to_send'] = false;
// Max mails sended on one pass
$conf['nbm_max_mails_send'] = 35;
-
?>
diff --git a/include/constants.php b/include/constants.php
index 089e3b65d..02b352cc3 100644
--- a/include/constants.php
+++ b/include/constants.php
@@ -70,4 +70,6 @@ define('UPGRADE_TABLE', $prefixeTable.'upgrade');
define('SEARCH_TABLE', $prefixeTable.'search');
define('USER_MAIL_NOTIFICATION_TABLE', $prefixeTable.'user_mail_notification');
define('CATEGORIES_LINK_TABLE', $prefixeTable.'categories_link');
+define('TAGS_TABLE', $prefixeTable.'tags');
+define('IMAGE_TAG_TABLE', $prefixeTable.'image_tag');
?>
diff --git a/include/functions.inc.php b/include/functions.inc.php
index 981da55c4..d8b86743f 100644
--- a/include/functions.inc.php
+++ b/include/functions.inc.php
@@ -31,6 +31,7 @@ include_once( PHPWG_ROOT_PATH .'include/functions_category.inc.php' );
include_once( PHPWG_ROOT_PATH .'include/functions_xml.inc.php' );
include_once( PHPWG_ROOT_PATH .'include/functions_group.inc.php' );
include_once( PHPWG_ROOT_PATH .'include/functions_html.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_tag.inc.php' );
include_once( PHPWG_ROOT_PATH .'include/functions_url.inc.php' );
//----------------------------------------------------------- generic functions
@@ -267,6 +268,35 @@ function get_picture_size( $original_width, $original_height,
$picture_size[1] = $height;
return $picture_size;
}
+
+/**
+ * simplify a string to insert it into an URL
+ *
+ * based on str2url function from Dotclear
+ *
+ * @param string
+ * @return string
+ */
+function str2url($str)
+{
+ $str = strtr(
+ $str,
+ 'ÀÁÂÃÄÅàáâãäåÇçÒÓÔÕÖØòóôõöøÈÉÊËèéêëÌÍÎÏìíîïÙÚÛÜùúûü¾ÝÿýÑñ',
+ 'AAAAAAaaaaaaCcOOOOOOooooooEEEEeeeeIIIIiiiiUUUUuuuuYYyyNn'
+ );
+
+ $str = str_replace('Æ', 'AE', $str);
+ $str = str_replace('æ', 'ae', $str);
+ $str = str_replace('¼', 'OE', $str);
+ $str = str_replace('½', 'oe', $str);
+
+ $str = preg_replace('/[^a-z0-9_\s\'\:\/\[\]-]/','',strtolower($str));
+ $str = preg_replace('/[\s\'\:\/\[\]-]+/',' ',trim($str));
+ $res = str_replace(' ','_',$str);
+
+ return $res;
+}
+
//-------------------------------------------- PhpWebGallery specific functions
/**
@@ -829,5 +859,4 @@ function get_available_upgrade_ids()
return $available_upgrade_ids;
}
-
-?> \ No newline at end of file
+?>
diff --git a/include/functions_html.inc.php b/include/functions_html.inc.php
index 7e7df7c41..13c3dc206 100644
--- a/include/functions_html.inc.php
+++ b/include/functions_html.inc.php
@@ -5,7 +5,6 @@
// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
// +-----------------------------------------------------------------------+
// | branch : BSF (Best So Far)
-// | file : $Id$
// | last update : $Date$
// | last modifier : $Author$
// | revision : $Revision$
@@ -495,6 +494,56 @@ function get_cat_display_name_from_id($cat_id,
}
/**
+ * Returns an HTML list of tags. It can be a multi select field or a list of
+ * checkboxes.
+ *
+ * @param string HTML field name
+ * @param array selected tag ids
+ * @return array
+ */
+function get_html_tag_selection(
+ $tags,
+ $fieldname,
+ $selecteds = array(),
+ $forbidden_categories = null
+ )
+{
+ global $conf;
+
+ $output = '<ul class="tagSelection">';
+ foreach ($tags as $tag)
+ {
+ $output.=
+ '<li>'
+ .'<label>'
+ .'<input type="checkbox" name="'.$fieldname.'[]"'
+ .' value="'.$tag['tag_id'].'"'
+ ;
+
+ if (in_array($tag['tag_id'], $selecteds))
+ {
+ $output.= ' checked="checked"';
+ }
+
+ $output.=
+ ' />'
+ .' '.$tag['name']
+ .'</label>'
+ .'</li>'
+ ."\n"
+ ;
+ }
+ $output.= '</ul>';
+
+ return $output;
+}
+
+function name_compare($a, $b)
+{
+ return strcmp($a['name'], $b['name']);
+}
+
+/**
* exits the current script (either exit or redirect)
*/
function access_denied()
@@ -519,4 +568,4 @@ function access_denied()
redirect($login_url);
}
}
-?> \ No newline at end of file
+?>
diff --git a/include/functions_search.inc.php b/include/functions_search.inc.php
index 2ca87969e..7e55160c8 100644
--- a/include/functions_search.inc.php
+++ b/include/functions_search.inc.php
@@ -84,7 +84,7 @@ function get_sql_search_clause($search_id)
// construction
$clauses = array();
- foreach (array('file','name','comment','keywords','author') as $textfield)
+ foreach (array('file','name','comment','author') as $textfield)
{
if (isset($search['fields'][$textfield]))
{
@@ -109,7 +109,7 @@ function get_sql_search_clause($search_id)
if (isset($search['fields']['allwords']))
{
- $fields = array('file', 'name', 'comment', 'keywords', 'author');
+ $fields = array('file', 'name', 'comment', 'author');
// in the OR mode, request bust be :
// ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
// OR (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
@@ -208,12 +208,68 @@ function get_sql_search_clause($search_id)
$search_clause = $where_separator;
- if (isset($forbidden))
+ return $search_clause;
+}
+
+/**
+ * returns the list of items corresponding to the search id
+ *
+ * @param int search id
+ * @return array
+ */
+function get_search_items($search_id)
+{
+ $items = array();
+
+ $search_clause = get_sql_search_clause($search_id);
+
+ if (!empty($search_clause))
{
- $search_clause.= "\n AND ".$forbidden;
+ $query = '
+SELECT DISTINCT(id)
+ FROM '.IMAGES_TABLE.'
+ INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+ WHERE '.$search_clause.'
+;';
+ $items = array_from_query($query, 'id');
}
- return $search_clause;
-}
+ $search = get_search_array($search_id);
+ if (isset($search['fields']['tags']))
+ {
+ $tag_items = get_image_ids_for_tags(
+ $search['fields']['tags']['words'],
+ $search['fields']['tags']['mode']
+ );
+
+ switch ($search['mode'])
+ {
+ case 'AND':
+ {
+ if (empty($search_clause))
+ {
+ $items = $tag_items;
+ }
+ else
+ {
+ $items = array_intersect($items, $tag_items);
+ }
+ break;
+ }
+ case 'OR':
+ {
+ $items = array_unique(
+ array_merge(
+ $items,
+ $tag_items
+ )
+ );
+ break;
+ }
+ }
+ }
+
+ return $items;
+}
?> \ No newline at end of file
diff --git a/include/functions_tag.inc.php b/include/functions_tag.inc.php
new file mode 100644
index 000000000..5dd4884f4
--- /dev/null
+++ b/include/functions_tag.inc.php
@@ -0,0 +1,218 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2006 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | branch : BSF (Best So Far)
+// | file : $RCSfile$
+// | last update : $Date: 2006-03-16 23:58:16 +0100 (jeu, 16 mar 2006) $
+// | last modifier : $Author: rub $
+// | revision : $Revision: 1085 $
+// | revision : $Revision: 1085 $
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify |
+// | it under the terms of the GNU General Public License as published by |
+// | the Free Software Foundation |
+// | |
+// | This program is distributed in the hope that it will be useful, but |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
+// | General Public License for more details. |
+// | |
+// | You should have received a copy of the GNU General Public License |
+// | along with this program; if not, write to the Free Software |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA. |
+// +-----------------------------------------------------------------------+
+
+
+/**
+ * Tags available. Each return tag is represented as an array with its id,
+ * its name, its weight (count), its url name. Tags are not sorted.
+ *
+ * The returned list can be a subset of all existing tags due to
+ * permissions, only if a list of forbidden categories is provided
+ *
+ * @param array forbidden categories
+ * @return array
+ */
+function get_available_tags($forbidden_categories = null)
+{
+ // we can find top fatter tags among reachable images
+ $tags_query = '
+SELECT tag_id, name, url_name, count(*) counter
+ FROM '.IMAGE_TAG_TABLE.'
+ INNER JOIN '.TAGS_TABLE.' ON tag_id = id';
+
+ if (!is_null($forbidden_categories))
+ {
+ // first we need all reachable image ids
+ $images_query = '
+SELECT DISTINCT image_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id NOT IN ('.implode(',', $forbidden_categories).')
+;';
+ $image_ids = array_from_query($images_query, 'image_id');
+
+ $tags_query.= '
+ WHERE image_id IN ('.
+ wordwrap(
+ implode(', ', $image_ids),
+ 80,
+ "\n"
+ ).')';
+ }
+
+ $tags_query.= '
+ GROUP BY tag_id
+;';
+
+ $result = pwg_query($tags_query);
+
+ $tags = array();
+
+ while ($row = mysql_fetch_array($result))
+ {
+ array_push($tags, $row);
+ }
+
+ return $tags;
+}
+
+/**
+ * All tags, even tags associated to no image.
+ *
+ * @return array
+ */
+function get_all_tags()
+{
+ $query = '
+SELECT id AS tag_id, name, url_name
+ FROM '.TAGS_TABLE.'
+ ORDER BY name
+;';
+ $result = pwg_query($query);
+
+ $tags = array();
+
+ while ($row = mysql_fetch_array($result))
+ {
+ array_push($tags, $row);
+ }
+
+ return $tags;
+}
+
+/**
+ * Giving a set of tags with a counter for each one, calculate the display
+ * level of each tag.
+ *
+ * The level of each tag depends on the average count of tags. This
+ * calcylation method avoid having very different levels for tags having
+ * nearly the same count when set are small.
+ *
+ * @param array tags
+ * @return array
+ */
+function add_level_to_tags($tags)
+{
+ global $conf;
+
+ if (count($tags) == 0)
+ {
+ return $tags;
+ }
+
+ $total_count = 0;
+
+ foreach ($tags as $tag)
+ {
+ $total_count+= $tag['counter'];
+ }
+
+ // average count of available tags will determine the level of each tag
+ $tag_average_count = $total_count / count($tags);
+
+ // tag levels threshold calculation: a tag with an average rate must have
+ // the middle level.
+ for ($i = 1; $i < $conf['tags_levels']; $i++)
+ {
+ $threshold_of_level[$i] =
+ 2 * $i * $tag_average_count / $conf['tags_levels'];
+ }
+
+ // display sorted tags
+ foreach (array_keys($tags) as $k)
+ {
+ $tags[$k]['level'] = 1;
+
+ // based on threshold, determine current tag level
+ for ($i = $conf['tags_levels'] - 1; $i >= 1; $i--)
+ {
+ if ($tags[$k]['counter'] > $threshold_of_level[$i])
+ {
+ $tags[$k]['level'] = $i + 1;
+ break;
+ }
+ }
+ }
+
+ return $tags;
+}
+
+/**
+ * return the list of image ids corresponding to given tags. AND & OR mode
+ * supported.
+ *
+ * @param array tag ids
+ * @param string mode
+ * @return array
+ */
+function get_image_ids_for_tags($tag_ids, $mode = 'AND')
+{
+ switch ($mode)
+ {
+ case 'AND':
+ {
+ // strategy is to list images associated to each tag
+ $tag_images = array();
+
+ foreach ($tag_ids as $tag_id)
+ {
+ $query = '
+SELECT image_id
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE tag_id = '.$tag_id.'
+;';
+ $tag_images[$tag_id] = array_from_query($query, 'image_id');
+ }
+
+ // then we calculate the intersection, the images that are associated to
+ // every tags
+ $items = array_shift($tag_images);
+ foreach ($tag_images as $images)
+ {
+ $items = array_intersect($items, $images);
+ }
+
+ return array_unique($items);
+ break;
+ }
+ case 'OR':
+ {
+ $query = '
+SELECT DISTINCT image_id
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE tag_id IN ('.implode(',', $tag_ids).')
+;';
+ return array_from_query($query, 'image_id');
+ break;
+ }
+ default:
+ {
+ die('get_image_ids_for_tags: unknown mode, only AND & OR are supported');
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/include/functions_url.inc.php b/include/functions_url.inc.php
index 0e0583872..a50f789c8 100644
--- a/include/functions_url.inc.php
+++ b/include/functions_url.inc.php
@@ -258,23 +258,18 @@ function make_section_in_URL($params)
{
$section_string = '';
- if (!isset($params['section']))
+ $section_of = array(
+ 'category' => 'categories',
+ 'tags' => 'tags',
+ 'list' => 'list',
+ 'search' => 'search',
+ );
+
+ foreach ($section_of as $param => $section)
{
- if (isset($params['category']))
- {
- $params['section'] = 'categories';
- }
- else if (isset($params['tags']))
- {
- $params['section'] = 'tags';
- }
- else if (isset($params['list']))
- {
- $params['section'] = 'list';
- }
- else if (isset($params['search']))
+ if (isset($params[$param]))
{
- $params['section'] = 'search';
+ $params['section'] = $section;
}
}
@@ -289,7 +284,7 @@ function make_section_in_URL($params)
{
if (!isset($params['category']))
{
- //$section_string.= '/categories';
+ $section_string.= '/categories';
}
else
{
@@ -309,7 +304,12 @@ function make_section_in_URL($params)
foreach ($params['tags'] as $tag)
{
- $section_string.= '/'.$tag;
+ $section_string.= '/'.$tag['id'];
+
+ if (isset($tag['url_name']))
+ {
+ $section_string.= '-'.$tag['url_name'];
+ }
}
break;
diff --git a/include/functions_user.inc.php b/include/functions_user.inc.php
index cfa4d53aa..c5efa98ad 100644
--- a/include/functions_user.inc.php
+++ b/include/functions_user.inc.php
@@ -633,5 +633,4 @@ function is_adviser()
return ($user['adviser'] == 'true');
}
-
?> \ No newline at end of file
diff --git a/include/section_init.inc.php b/include/section_init.inc.php
index cc7c074c2..e2ed07b42 100644
--- a/include/section_init.inc.php
+++ b/include/section_init.inc.php
@@ -145,15 +145,11 @@ else if (0 === strpos($tokens[$next_token], 'tag'))
$page['tags'] = array();
$next_token++;
+ $i = $next_token;
- for ($i = $next_token; ; $i++)
+ while (isset($tokens[$i]))
{
- if (!isset($tokens[$i]))
- {
- break;
- }
-
- preg_match('/^(\d+)/', $tokens[$i], $matches);
+ preg_match('/^(\d+)(?:-(.*))?/', $tokens[$i], $matches);
if (!isset($matches[1]))
{
if (0 == count($page['tags']))
@@ -165,7 +161,16 @@ else if (0 === strpos($tokens[$next_token], 'tag'))
break;
}
}
- array_push($page['tags'], $matches[1]);
+
+ array_push(
+ $page['tags'],
+ array(
+ 'id' => $matches[1],
+ 'url_name' => isset($matches[2]) ? $matches[2] : '',
+ )
+ );
+
+ $i++;
}
$next_token = $i;
@@ -225,13 +230,10 @@ else if ('list' == $tokens[$next_token])
$next_token++;
}
-for ($i = $next_token; ; $i++)
-{
- if (!isset($tokens[$i]))
- {
- break;
- }
+$i = $next_token;
+while (isset($tokens[$i]))
+{
if (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
{
$page['start'] = $matches[1];
@@ -240,9 +242,12 @@ for ($i = $next_token; ; $i++)
if (preg_match('/^posted|created/', $tokens[$i] ))
{
$chronology_tokens = explode('-', $tokens[$i] );
+
$page['chronology_field'] = $chronology_tokens[0];
+
array_shift($chronology_tokens);
$page['chronology_style'] = $chronology_tokens[0];
+
array_shift($chronology_tokens);
if ( count($chronology_tokens)>0 )
{
@@ -255,6 +260,8 @@ for ($i = $next_token; ; $i++)
$page['chronology_date'] = $chronology_tokens;
}
}
+
+ $i++;
}
@@ -338,19 +345,97 @@ else
$forbidden = ' 1 = 1';
}
// +-----------------------------------------------------------------------+
+// | tags section |
+// +-----------------------------------------------------------------------+
+ if ($page['section'] == 'tags')
+ {
+ $page['tag_ids'] = array();
+ foreach ($page['tags'] as $tag)
+ {
+ array_push($page['tag_ids'], $tag['id']);
+ }
+
+ $items = get_image_ids_for_tags($page['tag_ids']);
+
+ // permissions depends on category, so to only keep images that are
+ // reachable to the connected user, we need to check category
+ // associations
+ if (!empty($user['forbidden_categories']))
+ {
+ $query = '
+SELECT image_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id IN ('.implode(',', $items).')
+ AND '.$forbidden.'
+;';
+ $items = array_unique(
+ array_from_query($query, 'image_id')
+ );
+ }
+
+ // tag names
+ $query = '
+SELECT name, url_name, id
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.implode(',', $page['tag_ids']).')
+;';
+ $result = pwg_query($query);
+ $tag_infos = array();
+
+ while ($row = mysql_fetch_array($result))
+ {
+ $tag_infos[ $row['id'] ]['name'] = $row['name'];
+ $tag_infos[ $row['id'] ]['url_name'] = $row['url_name'];
+ }
+
+ $title = count($page['tags']) > 1 ? l10n('Tags') : l10n('Tag');
+ $title.= ' ';
+
+ $tag_num = 1;
+ foreach ($page['tag_ids'] as $tag_id)
+ {
+ $title.=
+ ($tag_num++ > 1 ? ' + ' : '')
+ .'<a href="'
+ .make_index_url(
+ array(
+ 'tags' => array(
+ array(
+ 'id' => $tag_id,
+ 'url_name' => $tag_infos[$tag_id]['url_name'],
+ ),
+ )
+ )
+ )
+ .'">'
+ .$tag_infos[$tag_id]['name']
+ .'</a>';
+ }
+
+ $page = array_merge(
+ $page,
+ array(
+ 'title' => $title,
+ 'items' => array_values($items),
+ 'thumbnails_include' => 'include/category_default.inc.php',
+ )
+ );
+ }
+// +-----------------------------------------------------------------------+
// | search section |
// +-----------------------------------------------------------------------+
if ($page['section'] == 'search')
{
include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
+
$query = '
SELECT DISTINCT(id)
FROM '.IMAGES_TABLE.'
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
- WHERE '.get_sql_search_clause($page['search']).'
+ WHERE id IN ('.implode(',', get_search_items($page['search'])).')
AND '.$forbidden.'
'.$conf['order_by'].'
-;';
+;';
$page = array_merge(
$page,
diff --git a/index.php b/index.php
index 3bb03d4bd..784832623 100644
--- a/index.php
+++ b/index.php
@@ -221,6 +221,76 @@ if (count($conf['links']) > 0)
);
}
}
+//------------------------------------------------------------------------ tags
+if ('tags' == $page['section'])
+{
+ $template->assign_block_vars('tags', array());
+
+ // display tags associated to currently tagged items, less current tags
+ $query = '
+SELECT tag_id, name, url_name, count(*) counter
+ FROM '.IMAGE_TAG_TABLE.'
+ INNER JOIN '.TAGS_TABLE.' ON tag_id = id
+ WHERE image_id IN ('.implode(',', $items).')
+ AND tag_id NOT IN ('.implode(',', $page['tag_ids']).')
+ GROUP BY tag_id
+ ORDER BY name ASC
+;';
+ $result = pwg_query($query);
+
+ $tags = array();
+
+ while($row = mysql_fetch_array($result))
+ {
+ array_push($tags, $row);
+ }
+
+ $tags = add_level_to_tags($tags);
+
+ foreach ($tags as $tag)
+ {
+ $template->assign_block_vars(
+ 'tags.tag',
+ array(
+ 'URL_ADD' => make_index_URL(
+ array(
+ 'tags' => array_merge(
+ $page['tags'],
+ array(
+ array(
+ 'id' => $tag['tag_id'],
+ 'url_name' => $tag['url_name'],
+ ),
+ )
+ )
+ )
+ ),
+
+ 'URL' => make_index_URL(
+ array(
+ 'tags' => array(
+ array(
+ 'id' => $tag['tag_id'],
+ 'url_name' => $tag['url_name'],
+ ),
+ )
+ )
+ ),
+
+ 'NAME' => $tag['name'],
+
+ 'TITLE' => l10n('See pictures linked to this tag only'),
+
+ 'TITLE_ADD' => sprintf(
+ l10n('%d pictures are also linked to current tags'),
+ $tag['counter']
+ ),
+
+ 'CLASS' => 'tagLevel'.$tag['level']
+ )
+ );
+ }
+}
//---------------------------------------------------------- special categories
// favorites categories
if ( !$user['is_the_guest'] )
@@ -332,6 +402,16 @@ else
}
}
+// tags link
+$template->assign_block_vars(
+ 'summary',
+ array(
+ 'TITLE' => l10n('See available tags'),
+ 'NAME' => l10n('Tags'),
+ 'U_SUMMARY'=> get_root_url().'tags.php',
+ )
+ );
+
// search link
$template->assign_block_vars(
'summary',
diff --git a/install/db/19-database.php b/install/db/19-database.php
new file mode 100644
index 000000000..035aff95a
--- /dev/null
+++ b/install/db/19-database.php
@@ -0,0 +1,151 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | branch : BSF (Best So Far)
+// | file : $RCSfile$
+// | last update : $Date: 2005-09-21 00:04:57 +0200 (mer, 21 sep 2005) $
+// | last modifier : $Author: plg $
+// | revision : $Revision: 870 $
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify |
+// | it under the terms of the GNU General Public License as published by |
+// | the Free Software Foundation |
+// | |
+// | This program is distributed in the hope that it will be useful, but |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
+// | General Public License for more details. |
+// | |
+// | You should have received a copy of the GNU General Public License |
+// | along with this program; if not, write to the Free Software |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA. |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+ die('Hacking attempt!');
+}
+
+$upgrade_description = '#images.keywords moved to new table #tags';
+
+// +-----------------------------------------------------------------------+
+// | New tables |
+// +-----------------------------------------------------------------------+
+
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'tags (
+ id smallint(5) UNSIGNED NOT NULL auto_increment,
+ name varchar(255) BINARY NOT NULL,
+ url_name varchar(255) BINARY NOT NULL,
+ PRIMARY KEY (id)
+) TYPE=MyISAM
+;';
+pwg_query($query);
+
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'image_tag (
+ image_id mediumint(8) UNSIGNED NOT NULL,
+ tag_id smallint(5) UNSIGNED NOT NULL,
+ PRIMARY KEY (image_id,tag_id)
+) TYPE=MyISAM
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// | Move keywords to tags |
+// +-----------------------------------------------------------------------+
+
+// each tag label is associated to a numeric identifier
+$tag_id = array();
+// to each tag id (key) a list of image ids (value) is associated
+$tag_images = array();
+
+$current_id = 1;
+
+$query = '
+SELECT id, keywords
+ FROM '.PREFIX_TABLE.'images
+ WHERE keywords IS NOT NULL
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+ foreach(preg_split('/[,]+/', $row['keywords']) as $keyword)
+ {
+ if (!isset($tag_id[$keyword]))
+ {
+ $tag_id[$keyword] = $current_id++;
+ }
+
+ if (!isset($tag_images[ $tag_id[$keyword] ]))
+ {
+ $tag_images[ $tag_id[$keyword] ] = array();
+ }
+
+ array_push($tag_images[ $tag_id[$keyword] ], $row['id']);
+ }
+}
+
+$datas = array();
+foreach ($tag_id as $tag_name => $tag_id)
+{
+ array_push(
+ $datas,
+ array(
+ 'id' => $tag_id,
+ 'name' => $tag_name,
+ 'url_name' => str2url($tag_name),
+ )
+ );
+}
+mass_inserts(
+ PREFIX_TABLE.'tags',
+ array_keys($datas[0]),
+ $datas
+ );
+
+$datas = array();
+foreach ($tag_images as $tag_id => $images)
+{
+ foreach (array_unique($images) as $image_id)
+ {
+ array_push(
+ $datas,
+ array(
+ 'tag_id' => $tag_id,
+ 'image_id' => $image_id,
+ )
+ );
+ }
+}
+
+mass_inserts(
+ PREFIX_TABLE.'image_tag',
+ array_keys($datas[0]),
+ $datas
+ );
+
+// +-----------------------------------------------------------------------+
+// | Delete images.keywords |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'images DROP COLUMN keywords
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// | End notification |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'tags created and filled'."\n"
+.'Table '.PREFIX_TABLE.'image_tag created and filled'."\n"
+.'Column '.PREFIX_TABLE.'images.keywords dropped'."\n"
+;
+?>
diff --git a/install/phpwebgallery_structure.sql b/install/phpwebgallery_structure.sql
index 4c682d738..db614f40d 100644
--- a/install/phpwebgallery_structure.sql
+++ b/install/phpwebgallery_structure.sql
@@ -1,5 +1,4 @@
-- MySQL dump 9.11
--- MySQL dump 9.11
--
-- Host: localhost Database: pwg-bsf
-- ------------------------------------------------------
@@ -146,6 +145,17 @@ CREATE TABLE `phpwebgallery_image_category` (
) TYPE=MyISAM;
--
+-- Table structure for table `phpwebgallery_image_tag`
+--
+
+DROP TABLE IF EXISTS `phpwebgallery_image_tag`;
+CREATE TABLE `phpwebgallery_image_tag` (
+ `image_id` mediumint(8) unsigned NOT NULL default '0',
+ `tag_id` smallint(5) unsigned NOT NULL default '0',
+ PRIMARY KEY (`image_id`,`tag_id`)
+) TYPE=MyISAM;
+
+--
-- Table structure for table `phpwebgallery_images`
--
@@ -163,8 +173,6 @@ CREATE TABLE `phpwebgallery_images` (
`filesize` mediumint(9) unsigned default NULL,
`width` smallint(9) unsigned default NULL,
`height` smallint(9) unsigned default NULL,
- `keywords` varchar(255) default NULL,
- `storage_category_id` smallint(5) unsigned default NULL,
`representative_ext` varchar(4) default NULL,
`date_metadata_update` date default NULL,
`average_rate` float(5,2) unsigned default NULL,
@@ -172,7 +180,6 @@ CREATE TABLE `phpwebgallery_images` (
`path` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `images_i2` (`date_available`),
- KEY `images_i1` (`storage_category_id`),
KEY `images_i3` (`average_rate`),
KEY `images_i4` (`hit`),
KEY `images_i5` (`date_creation`)
@@ -229,6 +236,18 @@ CREATE TABLE `phpwebgallery_sites` (
) TYPE=MyISAM;
--
+-- Table structure for table `phpwebgallery_tags`
+--
+
+DROP TABLE IF EXISTS `phpwebgallery_tags`;
+CREATE TABLE `phpwebgallery_tags` (
+ `id` smallint(5) unsigned NOT NULL auto_increment,
+ `name` varchar(255) binary NOT NULL default '',
+ `url_name` varchar(255) binary NOT NULL default '',
+ PRIMARY KEY (`id`)
+) TYPE=MyISAM;
+
+--
-- Table structure for table `phpwebgallery_upgrade`
--
@@ -260,7 +279,7 @@ CREATE TABLE `phpwebgallery_user_cache` (
`user_id` smallint(5) NOT NULL default '0',
`need_update` enum('true','false') NOT NULL default 'true',
`forbidden_categories` text,
- `nb_total_images` mediumint(8) unsigned,
+ `nb_total_images` mediumint(8) unsigned default NULL,
PRIMARY KEY (`user_id`)
) TYPE=MyISAM;
@@ -296,7 +315,7 @@ CREATE TABLE `phpwebgallery_user_infos` (
`user_id` smallint(5) NOT NULL default '0',
`nb_image_line` tinyint(1) unsigned NOT NULL default '5',
`nb_line_page` tinyint(3) unsigned NOT NULL default '3',
- `status` enum('webmaster', 'admin', 'normal', 'generic', 'guest') NOT NULL default 'guest',
+ `status` enum('webmaster','admin','normal','generic','guest') NOT NULL default 'guest',
`adviser` enum('true','false') NOT NULL default 'false',
`language` varchar(50) NOT NULL default 'english',
`maxwidth` smallint(6) default NULL,
diff --git a/language/en_UK.iso-8859-1/admin.lang.php b/language/en_UK.iso-8859-1/admin.lang.php
index 81b1aeb20..abfd89a85 100644
--- a/language/en_UK.iso-8859-1/admin.lang.php
+++ b/language/en_UK.iso-8859-1/admin.lang.php
@@ -40,6 +40,7 @@ $lang['%d waiting pictures rejected'] = '%d waiting pictures rejected';
$lang['%d waiting pictures validated'] = '%d waiting pictures validated';
$lang['A new version of PhpWebGallery is available.'] = 'A new version of PhpWebGallery is available.';
$lang['Actions'] = 'Actions';
+$lang['Add a tag'] = 'Add a tag';
$lang['Add a user'] = 'Add a user';
$lang['Add group'] = 'Add group';
$lang['Add selected elements to caddie'] = 'Add selected elements to caddie';
@@ -58,8 +59,10 @@ $lang['Check for upgrade'] = 'Check for upgrade';
$lang['Comments for all'] = 'Comments for all';
$lang['Controversy'] = 'Controversy';
$lang['Creation date'] = 'Creation date';
+$lang['Current name'] = 'Current name';
$lang['Database'] = 'Database';
$lang['Delete Representant'] = 'Delete Representant';
+$lang['Delete selected tags'] = 'Delete selected tags';
$lang['Delete selected users'] = 'Delete selected users';
$lang['Deletions'] = 'Deletions';
$lang['Deny selected groups'] = 'Deny selected groups';
@@ -69,6 +72,8 @@ $lang['Display options'] = 'Display options';
$lang['Dissociated'] = 'Dissociated';
$lang['Does not represent'] = 'Does not represent';
$lang['Edit all picture informations'] = 'Edit all picture informations';
+$lang['Edit selected tags'] = 'Edit selected tags';
+$lang['Edit tags'] = 'Edit tags';
$lang['Elements'] = 'Elements';
$lang['Empty caddie'] = 'Empty caddie';
$lang['Environment'] = 'Environment';
@@ -91,6 +96,7 @@ $lang['Maintenance'] = 'Maintenance';
$lang['Manage permissions for a category'] = 'Manage permissions for a category';
$lang['Manage permissions for group "%s"'] = 'Manage permissions for group "%s"';
$lang['Manage permissions for user "%s"'] = 'Manage permissions for user "%s"';
+$lang['Manage tags'] = 'Manage tags';
$lang['Maximum height of the pictures'] = 'Maximum height of the pictures';
$lang['Maximum width of the pictures'] = 'Maximum width of the pictures';
$lang['Members'] = 'Members';
@@ -98,7 +104,9 @@ $lang['Metadata synchronized from file'] = 'Metadata synchronized from file';
$lang['Move categories'] = 'Move categories';
$lang['Move'] = 'Move';
$lang['Name'] = 'Name';
+$lang['New name'] = 'New name';
$lang['New parent category'] = 'New parent category';
+$lang['New tag'] = 'New tag';
$lang['No'] = 'No';
$lang['Number of comments per page'] = 'Number of comments per page';
$lang['Number of images per row'] = 'Number of images per row';
@@ -111,6 +119,7 @@ $lang['Options'] = 'Options';
$lang['Order alphanumerically'] = 'Order alphanumerically';
$lang['Order by'] = 'Order by';
$lang['Other private categories'] = 'Other private categories';
+$lang['Page banner'] = 'Page banner';
$lang['Parent category'] = 'Parent category';
$lang['Path'] = 'Path';
$lang['Permission denied'] = 'Permission denied';
@@ -118,7 +127,6 @@ $lang['Permission granted thanks to a group'] = 'Permission granted thanks to a
$lang['Permission granted'] = 'Permission granted';
$lang['PhpWebGallery Administration'] = 'PhpWebGallery Administration';
$lang['PhpWebGallery version'] = 'PhpWebGallery version';
-$lang['Page banner'] = 'Page banner';
$lang['Picture informations updated'] = 'Picture informations updated';
$lang['Position'] = 'Position';
$lang['Preferences'] = 'Preferences';
@@ -146,6 +154,7 @@ $lang['Status'] = 'Status';
$lang['Storage category'] = 'Storage category';
$lang['Submit'] = 'Submit';
$lang['Sum of rates'] = 'Sum of rates';
+$lang['Tag selection'] = 'Tag selection';
$lang['Take selected elements out of caddie'] = 'Take selected elements out of caddie';
$lang['Unable to check for upgrade since allow_url_fopen is disabled.'] = 'Unable to check for upgrade since allow_url_fopen is disabled.';
$lang['User comments validation'] = 'User comments validation';
@@ -162,12 +171,9 @@ $lang['You are running the latest version of PhpWebGallery.'] = 'You are running
$lang['You cannot move a category in its own sub category'] = 'You cannot move a category in its own sub category';
$lang['You need to confirm deletion'] = 'You need to confirm deletion';
$lang['actions'] = 'Actions';
-$lang['properties'] = 'Properties';
-$lang['is_high_enabled'] = 'High definition';
-$lang['is_high_disabled'] = '';
-$lang['enabled_high'] = 'High definition enabled';
-$lang['adviser'] = 'Adviser';
$lang['add keywords'] = 'add keywords';
+$lang['add tags'] = 'add tags';
+$lang['adviser'] = 'Adviser';
$lang['associate to category'] = 'associate to category';
$lang['associate to group'] = 'associate to group';
$lang['author'] = 'author';
@@ -208,6 +214,7 @@ $lang['editcat_uploadable'] = 'Authorize upload';
$lang['elements per line'] = 'elements per line';
$lang['elements per page'] = 'elements per page';
$lang['elements'] = 'elements';
+$lang['enabled_high'] = 'High definition enabled';
$lang['file'] = 'file';
$lang['filesize'] = 'filesize';
$lang['first element added on %s'] = 'first element added on %s';
@@ -224,6 +231,8 @@ $lang['group_id URL parameter is missing'] = 'group_id URL parameter is missing'
$lang['groups'] = 'Groups';
$lang['history'] = 'History';
$lang['instructions'] = 'Instructions';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'High definition';
$lang['jump to category'] = 'jump to category';
$lang['jump to image'] = 'jump to image';
$lang['jump to'] = 'jump to';
@@ -239,62 +248,62 @@ $lang['metadata_exif'] = 'EXIF';
$lang['metadata_iptc'] = 'IPTC';
$lang['name'] = 'name';
$lang['nbm_break_list_user'] = 'List of users to send mail is limited to %d. Others users are not listed.';
-$lang['nbm_nbm_break_send_mail'] = 'Sent mail is limited to %d send by pass. Others mails are skipped.';
-$lang['nbm_msg_no_mail_to_send'] = '%d mails were not sent.';
-$lang['nbm_msg_n_mails_sent'] = '%d mails were sent.';
-$lang['nbm_msg_error_sending_email_to'] = 'Error when sending email to %s [%s].';
-$lang['nbm_msg_mail_sent_to'] = 'Mail sent to %s [%s].';
-$lang['nbm_object_news'] = 'New elements added';
-$lang['nbm_object_subcribe'] = 'Subcribe of notification by mail';
-$lang['nbm_object_unsubcribe'] = 'Unsubcribe of notification by mail';
+$lang['nbm_col_check_user_send_mail'] = 'To send ?';
+$lang['nbm_col_last_send'] = 'Last send';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'User';
+$lang['nbm_complementary_mail_content'] = 'Complementary mail content';
+$lang['nbm_content_byebye'] = 'See you soon';
+$lang['nbm_content_goto'] = 'Go to %s %s.';
$lang['nbm_content_hello'] = 'Hello %s';
-$lang['nbm_content_new_elements_between'] = 'New elements were added between %s and %s';
$lang['nbm_content_new_elements'] = 'New elements were added on %s';
-$lang['nbm_content_goto'] = 'Go to %s %s.';
+$lang['nbm_content_new_elements_between'] = 'New elements were added between %s and %s';
$lang['nbm_content_subscribe_by_admin'] = 'You are subcribed by webmaster for the notification by mail';
-$lang['nbm_content_unsubscribe_by_admin'] = 'You are unsubcribed by webmaster for the notification by mail';
$lang['nbm_content_subscribe_by_himself'] = 'You are subcribed for the notification by mail';
-$lang['nbm_content_unsubscribe_by_himself'] = 'You are unsubcribed for the notification by mail';
-$lang['nbm_content_byebye'] = 'See you soon';
-$lang['nbm_content_unsubscribe_link'] = 'To unsubscribe, click on %s .';
$lang['nbm_content_subscribe_link'] = 'To subscribe, click on %s .';
$lang['nbm_content_subscribe_unsubscribe_contact'] = 'On problems or questions, send a message to %s.';
+$lang['nbm_content_unsubscribe_by_admin'] = 'You are unsubcribed by webmaster for the notification by mail';
+$lang['nbm_content_unsubscribe_by_himself'] = 'You are unsubcribed for the notification by mail';
+$lang['nbm_content_unsubscribe_link'] = 'To unsubscribe, click on %s .';
+$lang['nbm_info_send_mail_as'] = 'With blank value, gallery title will be used';
+$lang['nbm_item_notification'] = 'Notification';
+$lang['nbm_msg_error_sending_email_to'] = 'Error when sending email to %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Mail sent to %s [%s].';
+$lang['nbm_msg_n_mails_sent'] = '%d mails were sent.';
+$lang['nbm_msg_no_mail_to_send'] = '%d mails were not sent.';
+$lang['nbm_nbm_break_send_mail'] = 'Sent mail is limited to %d send by pass. Others mails are skipped.';
$lang['nbm_no_mail_to_send'] = 'No mail to send.';
+$lang['nbm_no_user_available_to_send_L1'] = 'No user are available in order to send mail.';
+$lang['nbm_no_user_available_to_send_L2'] = 'A user is available, if the are news elements to notify';
$lang['nbm_no_user_to send_notifications_by_mail'] = 'No user to send notifications by mail.';
-$lang['nbm_send_mail_to_users'] = 'Send mail to users';
-$lang['nbm_user_x_added'] = 'User %s [%s] added.';
-$lang['nbm_item_notification'] = 'Notification';
+$lang['nbm_object_news'] = 'New elements added';
+$lang['nbm_object_subcribe'] = 'Subcribe of notification by mail';
+$lang['nbm_object_unsubcribe'] = 'Unsubcribe of notification by mail';
$lang['nbm_param_mode'] = 'Parameter';
-$lang['nbm_subscribe_mode'] = 'Subscribe';
-$lang['nbm_send_mode'] = 'Send';
-$lang['nbm_title_param'] = 'Parameters';
-$lang['nbm_updated_param_count'] = '%d parameters are updated.';
-$lang['nbm_send_mail_as'] = 'Send mail as';
-$lang['nbm_info_send_mail_as'] = 'With blank value, gallery title will be used';
+$lang['nbm_send_check_all'] = 'Check All';
+$lang['nbm_send_complementary_mail_content'] = 'Complementary mail content';
$lang['nbm_send_detailed_content'] = 'Send detailed content';
-$lang['nbm_complementary_mail_content'] = 'Complementary mail content';
-$lang['nbm_title_subscribe'] = 'Subscribe/unscribe users';
-$lang['nbm_warning_subscribe_unsubcribe'] = 'Warning, subscribe or unscribe send mails to users';
-$lang['nbm_subscribe_col'] = 'Subscribed';
-$lang['nbm_unsubscribe_col'] = 'Unsubcribed';
-$lang['nbm_no_user_available_to_send_L1'] = 'No user are available in order to send mail.';
-$lang['nbm_no_user_available_to_send_L2'] = 'A user is available, if the are news elements to notify';
-$lang['nbm_title_send'] = 'Select sendings';
-$lang['nbm_col_user'] = 'User';
-$lang['nbm_col_mail'] = 'email';
-$lang['nbm_col_last_send'] = 'Last send';
-$lang['nbm_col_check_user_send_mail'] = 'To send ?';
+$lang['nbm_send_mail_as'] = 'Send mail as';
+$lang['nbm_send_mail_to_users'] = 'Send mail to users';
+$lang['nbm_send_mode'] = 'Send';
$lang['nbm_send_options'] = 'Options';
-$lang['nbm_send_complementary_mail_content'] = 'Complementary mail content';
$lang['nbm_send_submit'] = 'Send';
-$lang['nbm_send_check_all'] = 'Check All';
$lang['nbm_send_uncheck_all'] = 'Uncheck All';
-$lang['nbm_user_change_enabled_true'] = 'User %s [%s] added to subscribe list.';
+$lang['nbm_subscribe_col'] = 'Subscribed';
+$lang['nbm_subscribe_mode'] = 'Subscribe';
+$lang['nbm_title_param'] = 'Parameters';
+$lang['nbm_title_send'] = 'Select sendings';
+$lang['nbm_title_subscribe'] = 'Subscribe/unscribe users';
+$lang['nbm_unsubscribe_col'] = 'Unsubcribed';
+$lang['nbm_updated_param_count'] = '%d parameters are updated.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d user(s) are not updated.';
$lang['nbm_user_change_enabled_false'] = 'User %s [%s] removed of subscribe list.';
-$lang['nbm_user_not_change_enabled_true'] = 'User %s [%s] not added to subscribe list.';
-$lang['nbm_user_not_change_enabled_false'] = 'User %s [%s] not removed of subscribe list.';
+$lang['nbm_user_change_enabled_true'] = 'User %s [%s] added to subscribe list.';
$lang['nbm_user_change_enabled_updated_data_count'] = '%d user(s) are updated.';
-$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d user(s) are not updated.';
+$lang['nbm_user_not_change_enabled_false'] = 'User %s [%s] not removed of subscribe list.';
+$lang['nbm_user_not_change_enabled_true'] = 'User %s [%s] not added to subscribe list.';
+$lang['nbm_user_x_added'] = 'User %s [%s] added.';
+$lang['nbm_warning_subscribe_unsubcribe'] = 'Warning, subscribe or unscribe send mails to users';
$lang['no_write_access'] = 'no write access';
$lang['order_by'] = 'order by';
$lang['path'] = 'path';
@@ -303,10 +312,10 @@ $lang['permuser_info'] = 'Only private categories are listed. Private/Public cat
$lang['permuser_only_private'] = 'Only private categories are shown';
$lang['pictures'] = 'pictures';
$lang['private'] = 'private';
+$lang['properties'] = 'Properties';
$lang['public'] = 'public';
$lang['purge history'] = 'purge history';
$lang['purge never used notification feeds'] = 'purge never used notification feeds';
-$lang['repair and optimize database'] = 'repair and optimize database';
$lang['purge sessions'] = 'purge sessions';
$lang['randomly represented'] = 'randomly represented';
$lang['registration_date'] = 'registration date';
@@ -322,6 +331,8 @@ $lang['remote_site_test'] = 'test';
$lang['remote_site_test_hint'] = 'test this remote site';
$lang['remote_site_uncorrect_url'] = 'Remote site url must start by http or https and must only contain characters among "/", "a-zA-Z0-9", "-" or "_"';
$lang['remove keyword'] = 'remove keyword';
+$lang['remove tags'] = 'remove tags';
+$lang['repair and optimize database'] = 'repair and optimize database';
$lang['selection'] = 'selection';
$lang['set to'] = 'set to';
$lang['singly represented'] = 'singly represented';
@@ -442,11 +453,11 @@ $lang['user_delete'] = 'Delete user';
$lang['user_delete_hint'] = 'Click here to delete this user. Warning! This operation cannot be undone!';
$lang['user_id URL parameter is missing'] = 'user_id URL parameter is missing';
$lang['user_status'] = 'User status';
-$lang['user_status_webmaster'] = 'Webmaster';
$lang['user_status_admin'] = 'Administrator';
-$lang['user_status_normal'] = 'User';
$lang['user_status_generic'] = 'Generic';
$lang['user_status_guest'] = 'Guest';
+$lang['user_status_normal'] = 'User';
+$lang['user_status_webmaster'] = 'Webmaster';
$lang['username'] = 'username';
$lang['users'] = 'Users';
$lang['visitors'] = 'Visitors';
diff --git a/language/en_UK.iso-8859-1/common.lang.php b/language/en_UK.iso-8859-1/common.lang.php
index abe3bc29b..5fffbff9a 100644
--- a/language/en_UK.iso-8859-1/common.lang.php
+++ b/language/en_UK.iso-8859-1/common.lang.php
@@ -39,9 +39,14 @@ $lang['%d comments to validate'] = '%d comments to validate';
$lang['%d new comments'] = '%d new comments';
$lang['%d new elements'] = '%d new elements';
$lang['%d new users'] = '%d new users';
+$lang['%d pictures are also linked to current tags'] = '%d pictures are also linked to current tags';
$lang['%d waiting elements'] = '%d waiting elements';
$lang['About'] = 'About';
+$lang['All tags must match'] = 'All tags must match';
+$lang['All tags'] = 'All tags';
+$lang['Any tag'] = 'Any tag';
$lang['At least one listed rule must be satisfied.'] = 'At least one listed rule must be satisfied.';
+$lang['At least one tag must match'] = 'At least one tag must match';
$lang['Author'] = 'Author';
$lang['Average rate'] = 'Average rate';
$lang['Categories'] = 'Categories';
@@ -62,8 +67,8 @@ $lang['Email address is missing'] = 'Email address is missing';
$lang['Email address'] = 'Email address';
$lang['Enter your personnal informations'] = 'Enter your personnal informations';
$lang['Error sending email'] = 'Error sending email';
-$lang['File'] = 'File';
$lang['File name'] = 'File name';
+$lang['File'] = 'File';
$lang['Filesize'] = 'Filesize';
$lang['Filter and display'] = 'Filter and display';
$lang['Filter'] = 'Filter';
@@ -91,21 +96,26 @@ $lang['Post date'] = 'Post date';
$lang['Posted on'] = 'Posted on';
$lang['Profile'] = 'Profile';
$lang['Quick connect'] = 'Quick connect';
-$lang['Rate'] = 'Rate';
$lang['RSS feed'] = 'RSS feed';
+$lang['Rate'] = 'Rate';
$lang['Register'] = 'Register';
$lang['Registration'] = 'Registration';
+$lang['Related tags'] = 'Related tags';
$lang['Reset'] = 'Reset';
$lang['Retrieve password'] = 'Retrieve password';
$lang['Search rules'] = 'Search rules';
+$lang['Search tags'] = 'Search tags';
$lang['Search'] = 'Search';
+$lang['See available tags'] = 'See available tags';
+$lang['See pictures linked to this tag only'] = 'See pictures linked to this tag only';
$lang['Send new password'] = 'Send new password';
$lang['Since'] = 'Since';
$lang['Sort by'] = 'Sort by';
$lang['Sort order'] = 'Sort order';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.';
$lang['Unknown feed identifier'] = 'Unknown feed identifier';
-$lang['nbm_unknown_identifier'] = 'Unknown identifier';
$lang['User comments'] = 'User comments';
$lang['Username'] = 'Username';
$lang['Visits'] = 'Visits';
@@ -117,6 +127,7 @@ $lang['add to caddie'] = 'add to caddie';
$lang['add_favorites_alt'] = 'Add to favorites';
$lang['add_favorites_hint'] = 'Add this picture to your favorites';
$lang['admin'] = 'Administration';
+$lang['adviser_mode_enabled'] = 'Adviser mode enabled';
$lang['all'] = 'all';
$lang['all_categories'] = 'all categories';
$lang['already_rated'] = 'You\'ve already rated this item';
@@ -135,8 +146,8 @@ $lang['calendar_any'] = 'All';
$lang['calendar_hint'] = 'displays each day with pictures, month per month';
$lang['calendar_picture_hint'] = 'displays pictures added on ';
$lang['calendar_view'] = 'View';
-$lang['chronology_monthly_list'] = 'Monthly list';
$lang['chronology_monthly_calendar'] = 'Monthly calendar';
+$lang['chronology_monthly_list'] = 'Monthly list';
$lang['chronology_weekly_list'] = 'Weekly list';
$lang['click_to_redirect'] = 'Click here if your browser does not automatically forward you';
$lang['comment date'] = 'comment date';
@@ -211,8 +222,8 @@ $lang['maxheight'] = 'Maximum height of the pictures';
$lang['maxheight_error'] = 'Maximum height must be a number superior to 50';
$lang['maxwidth'] = 'Maximum width of the pictures';
$lang['maxwidth_error'] = 'Maximum width must be a number superior to 50';
-$lang['mode_normal_hint'] = 'return to normal view mode';
$lang['mode_created_hint'] = 'displays a calendar by creation date';
+$lang['mode_normal_hint'] = 'return to normal view mode';
$lang['mode_posted_hint'] = 'displays a calendar by date posted';
$lang['month'][10] = 'October';
$lang['month'][11] = 'November';
@@ -228,10 +239,11 @@ $lang['month'][8] = 'August';
$lang['month'][9] = 'September';
$lang['most_visited_cat'] = 'Most visited';
$lang['most_visited_cat_hint'] = 'displays most visited pictures';
-$lang['nb_image_per_row'] = 'Number of images per row';
$lang['nb_image_line_error'] = 'The number of images per row must be a not null scalar';
-$lang['nb_row_per_page'] = 'Number of rows per page';
+$lang['nb_image_per_row'] = 'Number of images per row';
$lang['nb_line_page_error'] = 'The number of rows per page must be a not null scalar';
+$lang['nb_row_per_page'] = 'Number of rows per page';
+$lang['nbm_unknown_identifier'] = 'Unknown identifier';
$lang['never_rated'] = 'You\'ve never rated this item';
$lang['new_password'] = 'New password';
$lang['new_password_hint'] = 'You only have to give a password if you wish to change it.';
@@ -332,5 +344,4 @@ $lang['upload_username'] = 'Username';
$lang['useful when password forgotten'] = 'useful when password forgotten';
$lang['w_month'] = 'Month';
$lang['yes'] = 'Yes';
-$lang['adviser_mode_enabled'] = 'Adviser mode enabled';
?>
diff --git a/language/fr_FR.iso-8859-1/admin.lang.php b/language/fr_FR.iso-8859-1/admin.lang.php
index 69a7c3523..114f1b07f 100644
--- a/language/fr_FR.iso-8859-1/admin.lang.php
+++ b/language/fr_FR.iso-8859-1/admin.lang.php
@@ -25,6 +25,7 @@
// | USA. |
// +-----------------------------------------------------------------------+
+
$lang['%d categories including %d physical and %d virtual'] = '%d catégories dont %d physiques et %d virtuelles';
$lang['%d categories moved'] = '%d catégories déplacées';
$lang['%d comments'] = '%d commentaires utilisateur';
@@ -40,6 +41,7 @@ $lang['%d waiting pictures rejected'] = '%d images en attente rejetées';
$lang['%d waiting pictures validated'] = '%d images en attente validées';
$lang['A new version of PhpWebGallery is available.'] = 'Une nouvelle version de PhpWebGallery est disponible.';
$lang['Actions'] = 'Actions';
+$lang['Add a tag'] = 'Ajouter un tag';
$lang['Add a user'] = 'Ajouter un utilisateur';
$lang['Add group'] = 'Ajouter un groupe';
$lang['Add selected elements to caddie'] = 'Ajouter les éléments sélectionnés au panier';
@@ -58,8 +60,10 @@ $lang['Check for upgrade'] = 'Dernière version ?';
$lang['Comments for all'] = 'Commentaires utilisateur pour tous';
$lang['Controversy'] = 'Controverse';
$lang['Creation date'] = 'Date de création';
+$lang['Current name'] = 'Nom courant';
$lang['Database'] = 'Base de données';
$lang['Delete Representant'] = 'Supprimer le représentant';
+$lang['Delete selected tags'] = 'Supprimer les tags sélectionnés';
$lang['Delete selected users'] = 'Supprimer les utilisateurs sélectionnés';
$lang['Deletions'] = 'Suppressions';
$lang['Deny selected groups'] = 'Interdire l\'accès aux groupes sélectionnés';
@@ -69,6 +73,8 @@ $lang['Display options'] = 'Options d\'affichage';
$lang['Dissociated'] = 'Dissociée de';
$lang['Does not represent'] = 'Ne représente pas';
$lang['Edit all picture informations'] = 'Modifier toutes les informations liées à cette image';
+$lang['Edit selected tags'] = 'Editer les tags sélectionnés';
+$lang['Edit tags'] = 'Editer les tags';
$lang['Elements'] = 'Éléments';
$lang['Empty caddie'] = 'Vider le panier';
$lang['Environment'] = 'Environnement';
@@ -91,6 +97,7 @@ $lang['Maintenance'] = 'Maintenance';
$lang['Manage permissions for a category'] = 'Gérer les permissions pour une catégorie';
$lang['Manage permissions for group "%s"'] = 'Gérer les permissions pour le groupe "%s"';
$lang['Manage permissions for user "%s"'] = 'Gérer les permissions pour l\'utilisateur "%s"';
+$lang['Manage tags'] = 'Gérer les tags';
$lang['Maximum height of the pictures'] = 'Hauteur maximum des images';
$lang['Maximum width of the pictures'] = 'Largeur maximum des images';
$lang['Members'] = 'Membres';
@@ -98,7 +105,9 @@ $lang['Metadata synchronized from file'] = 'Meta-données synchronisées à partir
$lang['Move categories'] = 'Déplacer les catégories';
$lang['Move'] = 'Déplacer';
$lang['Name'] = 'Nom';
+$lang['New name'] = 'Nouveau nom';
$lang['New parent category'] = 'Nouvelle catégorie parente';
+$lang['New tag'] = 'Nouveau tag';
$lang['No'] = 'Non';
$lang['Number of comments per page'] = 'Nombre de commentaires utilisateur par page';
$lang['Number of images per row'] = 'Nombre de miniatures par ligne';
@@ -146,6 +155,7 @@ $lang['Status'] = 'Statut';
$lang['Storage category'] = 'Catégorie de stockage';
$lang['Submit'] = 'Valider';
$lang['Sum of rates'] = 'Somme des notes';
+$lang['Tag selection'] = 'Sélection de tags';
$lang['Take selected elements out of caddie'] = 'Sortir les éléments sélectionnés du panier';
$lang['Unable to check for upgrade since allow_url_fopen is disabled.'] = 'Impossible de connaître la dernière version cat la fonction allow_url_fopen est désactivée.';
$lang['User comments validation'] = 'Validation des commentaires utilisateur';
@@ -162,12 +172,9 @@ $lang['You are running the latest version of PhpWebGallery.'] = 'Vous utilisez l
$lang['You cannot move a category in its own sub category'] = 'Vous ne pouvez pas déplacer une catégorie dans sa propre sous-catégorie';
$lang['You need to confirm deletion'] = 'Vous devez confirmer la suppression';
$lang['actions'] = 'Actions';
-$lang['properties'] = 'Propriétés';
-$lang['is_high_enabled'] = 'Haute définition';
-$lang['is_high_disabled'] = '';
-$lang['enabled_high'] = 'Haute définition actif';
-$lang['adviser'] = 'Conseiller';
$lang['add keywords'] = 'ajouter des mots-clef';
+$lang['add tags'] = 'ajouter les tags';
+$lang['adviser'] = 'Conseiller';
$lang['associate to category'] = 'associer à la catégorie';
$lang['associate to group'] = 'associer au groupe';
$lang['author'] = 'auteur';
@@ -208,6 +215,7 @@ $lang['editcat_uploadable'] = 'Autoriser l\'ajout d\'images';
$lang['elements per line'] = 'éléments par ligne';
$lang['elements per page'] = 'éléments par page';
$lang['elements'] = 'éléments';
+$lang['enabled_high'] = 'Haute définition actif';
$lang['file'] = 'fichier';
$lang['filesize'] = 'poids';
$lang['first element added on %s'] = 'premier élément ajouté le %s';
@@ -224,6 +232,8 @@ $lang['group_id URL parameter is missing'] = 'Le paramètre d\'URL "group_id" est
$lang['groups'] = 'Groupes';
$lang['history'] = 'Historique';
$lang['instructions'] = 'Instructions';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Haute définition';
$lang['jump to category'] = 'se rendre dans la catégorie';
$lang['jump to image'] = 'se rendre à l\'image';
$lang['jump to'] = 's\'y rendre';
@@ -239,62 +249,62 @@ $lang['metadata_exif'] = 'EXIF';
$lang['metadata_iptc'] = 'IPTC';
$lang['name'] = 'nom';
$lang['nbm_break_list_user'] = 'La liste des utilisateurs pour l\'envoi est limitéé à %d. Les autres utilisateurs ne sont pas listés.';
-$lang['nbm_nbm_break_send_mail'] = 'Les mails envoyés sont limités à %d envois d\'une seule passe. Les autres envois de mail ont été ignorés.';
-$lang['nbm_msg_no_mail_to_send'] = '%s mails n\'ont pas été envoyés.';
-$lang['nbm_msg_n_mails_sent'] = '%s mails ont été envoyés.';
-$lang['nbm_msg_error_sending_email_to'] = 'Erreur lors de l\'envoi du mail à %s [%s].';
-$lang['nbm_msg_mail_sent_to'] = 'Mail envoyé à %s [%s].';
-$lang['nbm_object_news'] = 'Nouveaux éléments ajoutés';
-$lang['nbm_object_subcribe'] = 'Inscription à la notification par mail';
-$lang['nbm_object_unsubcribe'] = 'Désinscription à la notification par mail';
+$lang['nbm_col_check_user_send_mail'] = 'A envoyer ?';
+$lang['nbm_col_last_send'] = 'Dernier envoi';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Utilisateur';
+$lang['nbm_complementary_mail_content'] = 'Contenu complémentaire au mail';
+$lang['nbm_content_byebye'] = 'A bientôt';
+$lang['nbm_content_goto'] = 'Rendez-vous sur %s %s.';
$lang['nbm_content_hello'] = 'Bonjour %s';
-$lang['nbm_content_new_elements_between'] = 'Des nouveaux éléments ont été ajoutés entre le %s et le %s';
$lang['nbm_content_new_elements'] = 'Des nouveaux éléments ont été ajoutés le %s';
-$lang['nbm_content_goto'] = 'Rendez-vous sur %s %s.';
+$lang['nbm_content_new_elements_between'] = 'Des nouveaux éléments ont été ajoutés entre le %s et le %s';
$lang['nbm_content_subscribe_by_admin'] = 'Vous venez d\'être inscrit par le webmestre du site pour revevoir la notification par mail.';
-$lang['nbm_content_unsubscribe_by_admin'] = 'Vous venez d\'être désinscrit par le webmestre du site pour revevoir la notification par mail.';
$lang['nbm_content_subscribe_by_himself'] = 'Vous venez de vous inscrire pour revevoir la notification par mail.';
-$lang['nbm_content_unsubscribe_by_himself'] = 'Vous venez de vous désinscrire pour revevoir la notification par mail.';
-$lang['nbm_content_byebye'] = 'A bientôt';
-$lang['nbm_content_unsubscribe_link'] = 'Pour vous désinscrire, cliquez sur %s .';
$lang['nbm_content_subscribe_link'] = 'Pour vous inscrire, cliquez sur %s .';
$lang['nbm_content_subscribe_unsubscribe_contact'] = 'En cas de problèmes ou de questions, envoyer un mail à %s.';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Vous venez d\'être désinscrit par le webmestre du site pour revevoir la notification par mail.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Vous venez de vous désinscrire pour revevoir la notification par mail.';
+$lang['nbm_content_unsubscribe_link'] = 'Pour vous désinscrire, cliquez sur %s .';
+$lang['nbm_info_send_mail_as'] = 'Sans valeur, le titre de la galerie sera utilisé';
+$lang['nbm_item_notification'] = 'Notification';
+$lang['nbm_msg_error_sending_email_to'] = 'Erreur lors de l\'envoi du mail à %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Mail envoyé à %s [%s].';
+$lang['nbm_msg_n_mails_sent'] = '%s mails ont été envoyés.';
+$lang['nbm_msg_no_mail_to_send'] = '%s mails n\'ont pas été envoyés.';
+$lang['nbm_nbm_break_send_mail'] = 'Les mails envoyés sont limités à %d envois d\'une seule passe. Les autres envois de mail ont été ignorés.';
$lang['nbm_no_mail_to_send'] = 'Pas de mail à envoyer.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Il n\'y a pas d\'utilisateur à notifier par mail.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Un utilisateur est à notifier si de nouveaux éléments sont disponibles pour cet utilisateur.';
$lang['nbm_no_user_to send_notifications_by_mail'] = 'Pas d\'utilisateur pour envoyer des notifications par mails.';
-$lang['nbm_send_mail_to_users'] = 'Envoi de mail aux utilisateurs';
-$lang['nbm_user_x_added'] = 'Utilisateur %s [%s] ajouté.';
-$lang['nbm_item_notification'] = 'Notification';
+$lang['nbm_object_news'] = 'Nouveaux éléments ajoutés';
+$lang['nbm_object_subcribe'] = 'Inscription à la notification par mail';
+$lang['nbm_object_unsubcribe'] = 'Désinscription à la notification par mail';
$lang['nbm_param_mode'] = 'Paramètrage';
-$lang['nbm_subscribe_mode'] = 'Inscription';
-$lang['nbm_send_mode'] = 'Envoi';
-$lang['nbm_title_param'] = 'Paramètres';
-$lang['nbm_updated_param_count'] = '%d paramètres ont été mis à jour.';
-$lang['nbm_send_mail_as'] = 'Envoyer le mail en tant que';
-$lang['nbm_info_send_mail_as'] = 'Sans valeur, le titre de la galerie sera utilisé';
+$lang['nbm_send_check_all'] = 'Tout cocher';
+$lang['nbm_send_complementary_mail_content'] = 'Contenu complémentaire du mail';
$lang['nbm_send_detailed_content'] = 'Envoi d\'un contenu détaillé';
-$lang['nbm_complementary_mail_content'] = 'Contenu complémentaire au mail';
-$lang['nbm_title_subscribe'] = 'Inscrire/desinscrire les utilisateurs';
-$lang['nbm_warning_subscribe_unsubcribe'] = 'Attention, l\'inscription ou la desincription entraine l\'envoi de mails aux utilisateurs concernés';
-$lang['nbm_subscribe_col'] = 'Inscrits';
-$lang['nbm_unsubscribe_col'] = 'Non Inscrits';
-$lang['nbm_no_user_available_to_send_L1'] = 'Il n\'y a pas d\'utilisateur à notifier par mail.';
-$lang['nbm_no_user_available_to_send_L2'] = 'Un utilisateur est à notifier si de nouveaux éléments sont disponibles pour cet utilisateur.';
-$lang['nbm_title_send'] = 'Sélection des envois';
-$lang['nbm_col_user'] = 'Utilisateur';
-$lang['nbm_col_mail'] = 'email';
-$lang['nbm_col_last_send'] = 'Dernier envoi';
-$lang['nbm_col_check_user_send_mail'] = 'A envoyer ?';
+$lang['nbm_send_mail_as'] = 'Envoyer le mail en tant que';
+$lang['nbm_send_mail_to_users'] = 'Envoi de mail aux utilisateurs';
+$lang['nbm_send_mode'] = 'Envoi';
$lang['nbm_send_options'] = 'Options';
-$lang['nbm_send_complementary_mail_content'] = 'Contenu complémentaire du mail';
$lang['nbm_send_submit'] = 'Envoyer';
-$lang['nbm_send_check_all'] = 'Tout cocher';
$lang['nbm_send_uncheck_all'] = 'Tout décocher';
-$lang['nbm_user_change_enabled_true'] = 'L\'utilisateur %s [%s] a été ajouté à la liste des inscrits.';
+$lang['nbm_subscribe_col'] = 'Inscrits';
+$lang['nbm_subscribe_mode'] = 'Inscription';
+$lang['nbm_title_param'] = 'Paramètres';
+$lang['nbm_title_send'] = 'Sélection des envois';
+$lang['nbm_title_subscribe'] = 'Inscrire/desinscrire les utilisateurs';
+$lang['nbm_unsubscribe_col'] = 'Non Inscrits';
+$lang['nbm_updated_param_count'] = '%d paramètres ont été mis à jour.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d utilisateurs n\'ont pas été mis à jour.';
$lang['nbm_user_change_enabled_false'] = 'L\'utilisateur %s [%s] a été supprimé de la liste des inscrits.';
-$lang['nbm_user_not_change_enabled_true'] = 'L\'utilisateur %s [%s] n\'a pas été ajouté à la liste des inscrits.';
-$lang['nbm_user_not_change_enabled_false'] = 'L\'utilisateur %s [%s] n\'a pas été supprimé de la liste des inscrits.';
+$lang['nbm_user_change_enabled_true'] = 'L\'utilisateur %s [%s] a été ajouté à la liste des inscrits.';
$lang['nbm_user_change_enabled_updated_data_count'] = '%d utilisateurs ont été mis à jour.';
-$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d utilisateurs n\'ont pas été mis à jour.';
+$lang['nbm_user_not_change_enabled_false'] = 'L\'utilisateur %s [%s] n\'a pas été supprimé de la liste des inscrits.';
+$lang['nbm_user_not_change_enabled_true'] = 'L\'utilisateur %s [%s] n\'a pas été ajouté à la liste des inscrits.';
+$lang['nbm_user_x_added'] = 'Utilisateur %s [%s] ajouté.';
+$lang['nbm_warning_subscribe_unsubcribe'] = 'Attention, l\'inscription ou la desincription entraine l\'envoi de mails aux utilisateurs concernés';
$lang['no_write_access'] = 'pas d\'accès en écriture';
$lang['order_by'] = 'trier selon';
$lang['path'] = 'chemin';
@@ -303,10 +313,10 @@ $lang['permuser_info'] = 'Seules les catégories privées sont listées.';
$lang['permuser_only_private'] = 'Seules les catégories privées sont listées.';
$lang['pictures'] = 'images';
$lang['private'] = 'privée';
+$lang['properties'] = 'Propriétés';
$lang['public'] = 'publique';
$lang['purge history'] = 'purger l\'historique';
$lang['purge never used notification feeds'] = 'purger les flux de notification jamais utilisés';
-$lang['repair and optimize database'] = 'réparer et optimiser la base de données';
$lang['purge sessions'] = 'purger les sessions';
$lang['randomly represented'] = 'représentant au hasard';
$lang['registration_date'] = 'date d\'enregistrement';
@@ -322,6 +332,8 @@ $lang['remote_site_test'] = 'tester';
$lang['remote_site_test_hint'] = 'tester ce site distant';
$lang['remote_site_uncorrect_url'] = 'L\'URL d\'un site distant doit commencer par "http" ou "https" et ne doit contenir des caractères que parmi "/", "a-zA-Z0-9", "-" ou "_"';
$lang['remove keyword'] = 'supprimer mot-clef';
+$lang['remove tags'] = 'supprimer les tags';
+$lang['repair and optimize database'] = 'réparer et optimiser la base de données';
$lang['selection'] = 'sélection';
$lang['set to'] = 'changer en';
$lang['singly represented'] = 'représentant fixe';
@@ -442,11 +454,11 @@ $lang['user_delete'] = 'Supprimer utilisateur';
$lang['user_delete_hint'] = 'Cliquer ici pour supprimer cet utilisateur. Attention : cette opération ne peut pas être annulée !';
$lang['user_id URL parameter is missing'] = 'le paramètre d\'URL "user_id" manque';
$lang['user_status'] = 'Statut de l\'utilisateur';
-$lang['user_status_webmaster'] = 'Webmestre';
$lang['user_status_admin'] = 'Administrateur';
-$lang['user_status_normal'] = 'Visiteur';
$lang['user_status_generic'] = 'Générique';
$lang['user_status_guest'] = 'Invité';
+$lang['user_status_normal'] = 'Visiteur';
+$lang['user_status_webmaster'] = 'Webmestre';
$lang['username'] = 'nom utilisateur';
$lang['users'] = 'Utilisateurs';
$lang['visitors'] = 'Visiteurs';
diff --git a/language/fr_FR.iso-8859-1/common.lang.php b/language/fr_FR.iso-8859-1/common.lang.php
index 5a4ea1ac4..45e00ad2c 100644
--- a/language/fr_FR.iso-8859-1/common.lang.php
+++ b/language/fr_FR.iso-8859-1/common.lang.php
@@ -39,8 +39,13 @@ $lang['%d comments to validate'] = '%d commentaires utilisateur à valider';
$lang['%d new comments'] = '%d nouveaux commentaires utilisateur';
$lang['%d new elements'] = '%d nouveaux éléments';
$lang['%d new users'] = '%d nouveaux utilisateurs';
+$lang['%d pictures are also linked to current tags'] = '%d images sont également liées aux tags courants';
$lang['About'] = 'À propos';
+$lang['All tags must match'] = 'Tous les tags doivent correspondre';
+$lang['All tags'] = 'Tous les tags';
+$lang['Any tag'] = 'N\'importe quel tag';
$lang['At least one listed rule must be satisfied.'] = 'Au moins un des critères doit être satisfait.';
+$lang['At least one tag must match'] = 'Au moins un tag doit correspondre';
$lang['Author'] = 'Auteur';
$lang['Average rate'] = 'Note moyenne';
$lang['Categories'] = 'Catégories';
@@ -61,8 +66,8 @@ $lang['Email address is missing'] = 'L\'adresse e-mail manque';
$lang['Email address'] = 'Adresse e-mail';
$lang['Enter your personnal informations'] = 'Entrer vos informations personnelles';
$lang['Error sending email'] = 'Erreur à l\'envoi du mail';
-$lang['File'] = 'Fichier';
$lang['File name'] = 'Nom du fichier';
+$lang['File'] = 'Fichier';
$lang['Filesize'] = 'Poids';
$lang['Filter and display'] = 'Filtrer et afficher';
$lang['Filter'] = 'Filtre';
@@ -90,21 +95,26 @@ $lang['Post date'] = 'Date d\'ajout';
$lang['Posted on'] = 'Ajoutée le';
$lang['Profile'] = 'Profil';
$lang['Quick connect'] = 'Connexion rapide';
-$lang['Rate'] = 'Note';
$lang['RSS feed'] = 'flux RSS';
+$lang['Rate'] = 'Note';
$lang['Register'] = 'S\'enregistrer';
$lang['Registration'] = 'Enregistrement';
+$lang['Related tags'] = 'Tags liés';
$lang['Reset'] = 'Annuler';
$lang['Retrieve password'] = 'Récupérer un mot de passe';
$lang['Search rules'] = 'Critères de recherche';
+$lang['Search tags'] = 'Rechercher les tags';
$lang['Search'] = 'Rechercher';
+$lang['See available tags'] = 'Voir les tags disponibles';
+$lang['See pictures linked to this tag only'] = 'Voir les images liées uniquement à ce tag';
$lang['Send new password'] = 'Envoyer le nouveau mot de passe';
$lang['Since'] = 'Depuis';
$lang['Sort by'] = 'Trier selon';
$lang['Sort order'] = 'Ordre de tri';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'Le flux RSS notifie les événements de la galerie : nouvelles images, catégories mises à jour, nouveaux commentaires utilisateur. À utiliser avec un lecteur de flux RSS.';
$lang['Unknown feed identifier'] = 'Identifiant de flux inconnu';
-$lang['nbm_unknown_identifier'] = 'Identifiants inconnus';
$lang['User comments'] = 'Commentaires utilisateur';
$lang['Username'] = 'Nom d\'utilisateur';
$lang['Visits'] = 'Visites';
@@ -116,6 +126,7 @@ $lang['add to caddie'] = 'ajouter au panier';
$lang['add_favorites_alt'] = 'Ajouter aux favoris';
$lang['add_favorites_hint'] = 'Ajouter cette image à vos favoris';
$lang['admin'] = 'Administration';
+$lang['adviser_mode_enabled'] = 'Mode conseiller actif';
$lang['all'] = 'tout';
$lang['all_categories'] = 'toutes les catégories';
$lang['already_rated'] = 'Vous avez déjà voté pour cette image';
@@ -134,8 +145,8 @@ $lang['calendar_any'] = 'Tout';
$lang['calendar_hint'] = 'affichage année par année, mois par mois, jour par jour';
$lang['calendar_picture_hint'] = 'afficher les images du ';
$lang['calendar_view'] = 'Vue';
-$lang['chronology_monthly_list'] = 'Liste mensuelle';
$lang['chronology_monthly_calendar'] = 'Calendrier mensuel';
+$lang['chronology_monthly_list'] = 'Liste mensuelle';
$lang['chronology_weekly_list'] = 'Liste hebdomadaire';
$lang['click_to_redirect'] = 'Cliquez ici si votre navigateur ne vous redirige pas.';
$lang['comment date'] = 'date du commentaire';
@@ -210,8 +221,8 @@ $lang['maxheight'] = 'Hauteur maximum des images';
$lang['maxheight_error'] = 'La hauteur maximum des images doit être supérieure à 50';
$lang['maxwidth'] = 'Largeur maximum des images';
$lang['maxwidth_error'] = 'La largeur des images doit être supérieure à 50';
-$lang['mode_normal_hint'] = 'retourne à la vue normale';
$lang['mode_created_hint'] = 'afficher un calendrier par date de création';
+$lang['mode_normal_hint'] = 'retourne à la vue normale';
$lang['mode_posted_hint'] = 'afficher un calendrier par date d\'ajout';
$lang['month'][10] = 'Octobre';
$lang['month'][11] = 'Novembre';
@@ -227,10 +238,11 @@ $lang['month'][8] = 'Août';
$lang['month'][9] = 'Septembre';
$lang['most_visited_cat'] = 'Plus vues';
$lang['most_visited_cat_hint'] = 'afficher les images les plus vues';
-$lang['nb_image_per_row'] = 'Nombre de miniatures par ligne';
$lang['nb_image_line_error'] = 'Le nombre d\'images par ligne doit être un entier non nul';
-$lang['nb_row_per_page'] = 'Nombre de lignes par page';
+$lang['nb_image_per_row'] = 'Nombre de miniatures par ligne';
$lang['nb_line_page_error'] = 'Le nombre de lignes par page doit être un entier non nul';
+$lang['nb_row_per_page'] = 'Nombre de lignes par page';
+$lang['nbm_unknown_identifier'] = 'Identifiants inconnus';
$lang['never_rated'] = 'Vous n\'avez jamais voté pour cette image';
$lang['new_password'] = 'Nouveau mot de passe';
$lang['new_password_hint'] = 'Vous n\'avez à confirmer votre mot de passe que si vous désirez en changer.';
@@ -332,5 +344,4 @@ $lang['upload_username'] = 'Nom d\'utilisateur';
$lang['useful when password forgotten'] = 'utile en cas d\'oubli de mot de passe';
$lang['w_month'] = 'Mois';
$lang['yes'] = 'Oui';
-$lang['adviser_mode_enabled'] = 'Mode conseiller actif';
?> \ No newline at end of file
diff --git a/picture.php b/picture.php
index 91a944bc9..bb4f8ead7 100644
--- a/picture.php
+++ b/picture.php
@@ -698,25 +698,43 @@ $infos['INFO_VISITS'] = $picture['current']['hit'];
// file
$infos['INFO_FILE'] = $picture['current']['file'];
-// keywords
-if (!empty($picture['current']['keywords']))
+// tags
+$query = '
+SELECT id, name, url_name
+ FROM '.IMAGE_TAG_TABLE.'
+ INNER JOIN '.TAGS_TABLE.' ON tag_id = id
+ WHERE image_id = '.$page['image_id'].'
+;';
+$result = pwg_query($query);
+
+if (mysql_num_rows($result) > 0)
{
- $infos['INFO_KEYWORDS'] =
- // FIXME because of search engine partial rewrite, giving the author
- // name threw GET is not supported anymore. This feature should come
- // back later, with a better design (tag classification).
-// preg_replace(
-// '/([^,]+)/',
-// '<a href="'.
-// PHPWG_ROOT_PATH.'category.php?cat=search&amp;search=keywords:$1'
-// .'">$1</a>',
-// $picture['current']['keywords']
-// );
- $picture['current']['keywords'];
+ $tags = array();
+
+ while ($row = mysql_fetch_array($result))
+ {
+ array_push(
+ $tags,
+ '<a href="'
+ .make_index_URL(
+ array(
+ 'tags' => array(
+ array(
+ 'id' => $row['id'],
+ 'url_name' => $row['url_name'],
+ ),
+ )
+ )
+ )
+ .'">'.$row['name'].'</a>'
+ );
+ }
+
+ $infos['INFO_TAGS'] = implode(', ', $tags);
}
else
{
- $infos['INFO_KEYWORDS'] = l10n('N/A');
+ $infos['INFO_TAGS'] = l10n('N/A');
}
$template->assign_vars($infos);
diff --git a/search.php b/search.php
index 09131320e..2d6ce0c8f 100644
--- a/search.php
+++ b/search.php
@@ -65,6 +65,14 @@ if (isset($_POST['submit']))
);
}
+ if (isset($_POST['tags']))
+ {
+ $search['fields']['tags'] = array(
+ 'words' => $_POST['tags'],
+ 'mode' => $_POST['tag_mode'],
+ );
+ }
+
if ($_POST['search_author'])
{
$search['fields']['author'] = array(
@@ -200,6 +208,16 @@ $template->assign_vars(array(
'S_SEARCH_ACTION' => 'search.php',
'U_HELP' => PHPWG_ROOT_PATH.'/popuphelp.php?page=search',
'U_HOME' => make_index_url(),
+
+ 'TAG_SELECTION' => get_html_tag_selection(
+ get_available_tags(
+ isset($user['forbidden_categories'])
+ ? explode(',', $user['forbidden_categories'])
+ : null
+ ),
+ 'tags',
+ isset($_POST['tags']) ? $_POST['tags'] : array()
+ ),
)
);
diff --git a/search_rules.php b/search_rules.php
index 6e6900e90..51ccaf2c0 100644
--- a/search_rules.php
+++ b/search_rules.php
@@ -83,6 +83,34 @@ if (isset($search['fields']['allwords']))
);
}
+if (isset($search['fields']['tags']))
+{
+ $template->assign_block_vars(
+ 'tags',
+ array(
+ 'LIST_INTRO' => ($search['fields']['tags']['mode'] == 'AND')
+ ? l10n('All tags must match')
+ : l10n('At least one tag must match')
+ )
+ );
+
+ $query = '
+SELECT name
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.implode(',', $search['fields']['tags']['words']).')
+;';
+ $result = pwg_query($query);
+ while ($row = mysql_fetch_array($result))
+ {
+ $template->assign_block_vars(
+ 'tags.tag',
+ array(
+ 'NAME' => $row['name'],
+ )
+ );
+ }
+}
+
if (isset($search['fields']['author']))
{
$template->assign_block_vars(
diff --git a/tags.php b/tags.php
new file mode 100644
index 000000000..e61ee1f24
--- /dev/null
+++ b/tags.php
@@ -0,0 +1,120 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | branch : BSF (Best So Far)
+// | file : $RCSfile$
+// | last update : $Date: 2006-03-22 02:01:47 +0100 (mer, 22 mar 2006) $
+// | last modifier : $Author: rvelices $
+// | revision : $Revision: 1092 $
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify |
+// | it under the terms of the GNU General Public License as published by |
+// | the Free Software Foundation |
+// | |
+// | This program is distributed in the hope that it will be useful, but |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
+// | General Public License for more details. |
+// | |
+// | You should have received a copy of the GNU General Public License |
+// | along with this program; if not, write to the Free Software |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA. |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// | functions |
+// +-----------------------------------------------------------------------+
+
+function counter_compare($a, $b)
+{
+ if ($a['counter'] == $b['counter'])
+ {
+ return tag_id_compare($a, $b);
+ }
+
+ return ($a['counter'] < $b['counter']) ? -1 : 1;
+}
+
+function tag_id_compare($a, $b)
+{
+ return ($a['tag_id'] < $b['tag_id']) ? -1 : 1;
+}
+
+// +-----------------------------------------------------------------------+
+// | initialization |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+check_status(ACCESS_GUEST);
+
+// +-----------------------------------------------------------------------+
+// | page header and options |
+// +-----------------------------------------------------------------------+
+
+$title= l10n('Tags');
+$page['body_id'] = 'theTagsPage';
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+$template->set_filenames(array('tags'=>'tags.tpl'));
+$template->assign_vars(
+ array(
+ 'U_HOME' => make_index_url(),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | tag cloud construction |
+// +-----------------------------------------------------------------------+
+
+// find all tags available for the current user
+$tags = get_available_tags(explode(',', $user['forbidden_categories']));
+
+// we want only the first most represented tags, so we sort them by counter
+// and take the first tags
+usort($tags, 'counter_compare');
+$tags = array_slice($tags, 0, $conf['full_tag_cloud_items_number']);
+
+// depending on its counter and the other tags counter, each tag has a level
+$tags = add_level_to_tags($tags);
+
+// we want tags diplayed in alphabetic order
+usort($tags, 'name_compare');
+
+// display sorted tags
+foreach ($tags as $tag)
+{
+ $template->assign_block_vars(
+ 'tag',
+ array(
+ 'URL' => make_index_url(
+ array(
+ 'tags' => array(
+ array(
+ 'id' => $tag['tag_id'],
+ 'url_name' => $tag['url_name'],
+ ),
+ ),
+ )
+ ),
+
+ 'NAME' => $tag['name'],
+ 'TITLE' => $tag['counter'],
+ 'CLASS' => 'tagLevel'.$tag['level'],
+ )
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | html code display |
+// +-----------------------------------------------------------------------+
+
+$template->assign_block_vars('title',array());
+$template->parse('tags');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?> \ No newline at end of file
diff --git a/template/yoga/admin.tpl b/template/yoga/admin.tpl
index 785e312d9..6f0a58789 100644
--- a/template/yoga/admin.tpl
+++ b/template/yoga/admin.tpl
@@ -54,6 +54,7 @@
<li><a href="{U_COMMENTS}">{lang:comments}</a></li>
<li><a href="{U_RATING}">{lang:Rating}</a></li>
<li><a href="{U_CADDIE}">{lang:Caddie}</a></li>
+ <li><a href="{U_TAGS}">{lang:Tags}</a></li>
</ul>
</dd>
diff --git a/template/yoga/admin/element_set_global.tpl b/template/yoga/admin/element_set_global.tpl
index 53c956d40..a4e46508c 100644
--- a/template/yoga/admin/element_set_global.tpl
+++ b/template/yoga/admin/element_set_global.tpl
@@ -83,21 +83,15 @@
</tr>
<tr>
- <td>{lang:add keywords}</td>
- <td><input type="text" name="add_keywords" value="" /></td>
+ <td>{lang:add tags}</td>
+ <td>{ADD_TAG_SELECTION}</td>
</tr>
<tr>
- <td>{lang:remove keyword}</td>
- <td>
- <select name="remove_keyword">
- <!-- BEGIN remove_keyword_option -->
- <option value="{remove_keyword_option.VALUE}">{remove_keyword_option.OPTION}</option>
- <!-- END remove_keyword_option -->
- </select>
- </td>
+ <td>{lang:remove tags}</td>
+ <td>{DEL_TAG_SELECTION}</td>
</tr>
-
+
<tr>
<td>{lang:author}</td>
<td>
diff --git a/template/yoga/admin/element_set_unit.tpl b/template/yoga/admin/element_set_unit.tpl
index a5e718012..63b7fa5b6 100644
--- a/template/yoga/admin/element_set_unit.tpl
+++ b/template/yoga/admin/element_set_unit.tpl
@@ -69,8 +69,8 @@
</tr>
<tr>
- <td><strong>{lang:Keywords}</strong></td>
- <td><input type="text" name="keywords-{element.ID}" value="{element.KEYWORDS}" size="50" /></td>
+ <td><strong>{lang:Tags}</strong></td>
+ <td>{element.TAG_SELECTION}</td>
</tr>
<tr>
diff --git a/template/yoga/admin/picture_modify.tpl b/template/yoga/admin/picture_modify.tpl
index 2be4547dd..c10e7744e 100644
--- a/template/yoga/admin/picture_modify.tpl
+++ b/template/yoga/admin/picture_modify.tpl
@@ -99,10 +99,11 @@
</tr>
<tr>
- <td><strong>{lang:Keywords}</strong></td>
- <td><input type="text" name="keywords" value="{KEYWORDS}" size="50" /></td>
+ <td><strong>{lang:Tags}</strong></td>
+ <td>{TAG_SELECTION}</td>
</tr>
+
<tr>
<td><strong>{lang:Description}</strong></td>
<td><textarea name="description" class="description">{DESCRIPTION}</textarea></td>
diff --git a/template/yoga/admin/tags.tpl b/template/yoga/admin/tags.tpl
new file mode 100644
index 000000000..c39181580
--- /dev/null
+++ b/template/yoga/admin/tags.tpl
@@ -0,0 +1,55 @@
+<div class="titrePage">
+ <h2>{lang:Manage tags}</h2>
+</div>
+
+<form action="{F_ACTION}" method="post">
+
+ <!-- BEGIN edit_tags -->
+ <input type="hidden" name="edit_list" value="{edit_tags.LIST}" />
+
+ <fieldset>
+ <legend>{lang:Edit tags}</legend>
+
+ <table class="table2">
+ <tr class="throw">
+ <th>{lang:Current name}</th>
+ <th>{lang:New name}</th>
+ </tr>
+ <!-- BEGIN tag -->
+ <tr>
+ <td>{edit_tags.tag.NAME}</td>
+ <td><input type="text" name="tag_name-{edit_tags.tag.ID}" value="{edit_tags.tag.NAME}" /></td>
+ </tr>
+ <!-- END tag -->
+ </table>
+
+ <p>
+ <input type="submit" name="submit" value="{lang:Submit}" {TAG_INPUT_ENABLED} />
+ <input type="reset" value="{lang:Reset}" />
+ </p>
+ </fieldset>
+ <!-- END edit_tags -->
+
+ <fieldset>
+ <legend>{lang:Add a tag}</legend>
+
+ <label>
+ {lang:New tag}
+ <input type="text" name="add_tag" />
+ </label>
+
+ <p><input type="submit" name="add" value="{lang:Submit}" {TAG_INPUT_ENABLED}/></p>
+ </fieldset>
+
+ <fieldset>
+ <legend>{lang:Tag selection}</legend>
+
+ {TAG_SELECTION}
+
+ <p>
+ <input type="submit" name="edit" value="{lang:Edit selected tags}" {TAG_INPUT_ENABLED}/>
+ <input type="submit" name="delete" value="{lang:Delete selected tags}" {TAG_INPUT_ENABLED}/>
+ </p>
+ </fieldset>
+
+</form>
diff --git a/template/yoga/content.css b/template/yoga/content.css
index 2054efd78..56599ec93 100644
--- a/template/yoga/content.css
+++ b/template/yoga/content.css
@@ -13,6 +13,7 @@ BODY#theAboutPage #content,
BODY#thePopuphelpPage #content,
BODY#thePasswordPage #content,
BODY#theNotificationPage #content,
+BODY#theTagsPage #content,
BODY#theNBMPage #content
{
margin: 1em;
diff --git a/template/yoga/default-layout.css b/template/yoga/default-layout.css
index d8aab0732..a5637c17e 100644
--- a/template/yoga/default-layout.css
+++ b/template/yoga/default-layout.css
@@ -261,3 +261,12 @@ UL.actions A {
border: none;
}
+UL.tagSelection {
+ width: 500px;
+ padding: 0;
+}
+
+UL.tagSelection LI {
+ display: inline;
+ white-space: nowrap;
+} \ No newline at end of file
diff --git a/template/yoga/icon/add_tag.png b/template/yoga/icon/add_tag.png
new file mode 100644
index 000000000..5c5e235de
--- /dev/null
+++ b/template/yoga/icon/add_tag.png
Binary files differ
diff --git a/template/yoga/index.tpl b/template/yoga/index.tpl
index df6e4d249..494d2059b 100644
--- a/template/yoga/index.tpl
+++ b/template/yoga/index.tpl
@@ -19,6 +19,23 @@
<p class="totalImages">{NB_PICTURE} {lang:total}</p>
</dd>
</dl>
+
+<!-- BEGIN tags -->
+<dl>
+ <dt>{lang:Related tags}</dt>
+ <dd>
+ <ul id="menuTagCloud">
+ <!-- BEGIN tag -->
+ <li>
+ <a href="{tags.tag.URL_ADD}" title="{tags.tag.TITLE_ADD}"><img src="{pwg_root}{themeconf:icon_dir}/add_tag.png" alt="+"></a>
+ <a href="{tags.tag.URL}" class="{tags.tag.CLASS}" title="{tags.tag.TITLE}">{tags.tag.NAME}</a>
+ </li>
+ <!-- END tag -->
+ </ul>
+ </dd>
+</dl>
+<!-- END tags -->
+
<dl>
<dt>{lang:special_categories}</dt>
<dd>
diff --git a/template/yoga/menubar.css b/template/yoga/menubar.css
index b1a768aa9..c965d0753 100644
--- a/template/yoga/menubar.css
+++ b/template/yoga/menubar.css
@@ -95,3 +95,12 @@ FORM#quickconnect LABEL {
margin: 0 0.5em 0 0.5em;
}
+#menubar #menuTagCloud {
+ text-align: center;
+ margin: 5px 0;
+}
+
+#menubar #menuTagCloud LI
+{
+ display: inline;
+} \ No newline at end of file
diff --git a/template/yoga/picture.tpl b/template/yoga/picture.tpl
index 50fcf5f5f..82260bc96 100644
--- a/template/yoga/picture.tpl
+++ b/template/yoga/picture.tpl
@@ -107,8 +107,8 @@
<td class="value">{INFO_FILESIZE}</td>
</tr>
<tr>
- <td class="label">{lang:Keywords}</td>
- <td class="value">{INFO_KEYWORDS}</td>
+ <td class="label">{lang:Tags}</td>
+ <td class="value">{INFO_TAGS}</td>
</tr>
<tr>
<td class="label">{lang:Categories}</td>
diff --git a/template/yoga/search.tpl b/template/yoga/search.tpl
index ca7e8346b..6a3fb9f1e 100644
--- a/template/yoga/search.tpl
+++ b/template/yoga/search.tpl
@@ -35,6 +35,16 @@
<input type="text" style="width: 300px" name="search_author" size="30" />
</td>
</tr>
+
+ <tr>
+ <td colspan="2"><b>{lang:Search tags} :</b></td>
+ <td colspan="2" valign="middle">
+ {TAG_SELECTION}
+ <br /><label><input type="radio" name="tag_mode" value="AND" checked="checked" /> {lang:All tags}</label>
+ <br /><label><input type="radio" name="tag_mode" value="OR" /> {lang:Any tag}</label>
+ </td>
+ </tr>
+
<tr>
<td colspan="2"><b>{L_SEARCH_DATE} :</b>
<td colspan="2" valign="middle">
diff --git a/template/yoga/search_rules.tpl b/template/yoga/search_rules.tpl
index aac2586fe..921df4a12 100644
--- a/template/yoga/search_rules.tpl
+++ b/template/yoga/search_rules.tpl
@@ -9,6 +9,18 @@
<li>{words.CONTENT}</li>
<!-- END words -->
+ <!-- BEGIN tags -->
+ <li>
+ <p>{tags.LIST_INTRO}</p>
+
+ <ul>
+ <!-- BEGIN tag -->
+ <li>{tags.tag.NAME}</li>
+ <!-- END tag -->
+ </ul>
+ </li>
+ <!-- END tags -->
+
<!-- BEGIN author -->
<li>{author.CONTENT}</li>
<!-- END author -->
diff --git a/template/yoga/tags.tpl b/template/yoga/tags.tpl
new file mode 100644
index 000000000..33f69ca69
--- /dev/null
+++ b/template/yoga/tags.tpl
@@ -0,0 +1,17 @@
+<!-- $Id: comments.tpl 960 2005-12-03 17:33:38Z chrisaga $ -->
+<div id="content">
+
+ <div class="titrePage">
+ <ul class="categoryActions">
+ <li><a href="{U_HOME}" title="{lang:return to homepage}"><img src="{themeconf:icon_dir}/home.png" class="button" alt="{lang:home}"/></a></li>
+ </ul>
+ <h2>{lang:Tags}</h2>
+ </div>
+
+ <ul id="fullTagCloud">
+ <!-- BEGIN tag -->
+ <li><a href="{tag.URL}" class="{tag.CLASS}" title="{tag.TITLE}">{tag.NAME}</a></li>
+ <!-- END tag -->
+ </ul>
+
+</div> <!-- content -->