aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorplegall <plg@piwigo.org>2006-04-02 22:26:19 +0000
committerplegall <plg@piwigo.org>2006-04-02 22:26:19 +0000
commit42abf4c57664d2596872d437f70b95193f9a5d18 (patch)
treea1262b8601d5ac5b04b5b2e71af52c453712b9df
parent68ed2ea617ede199a0e2f15fdd4886095ae600cb (diff)
improvement: tags replace keywords. Better data model, less
limitations. Each image can be associated to as many tag as needed. Tags can contain non ASCII characters. Oriented navigation with tags by association. git-svn-id: http://piwigo.org/svn/trunk@1119 68402e56-0260-453c-a942-63ccdbb3a9ee
Diffstat (limited to '')
-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&amp;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 -->