aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-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
11 files changed, 496 insertions, 46 deletions
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,