diff options
Diffstat (limited to '')
-rw-r--r-- | include/category_default.inc.php | 2 | ||||
-rw-r--r-- | include/common.inc.php | 1 | ||||
-rw-r--r-- | include/config_default.inc.php | 13 | ||||
-rw-r--r-- | include/constants.php | 2 | ||||
-rw-r--r-- | include/functions.inc.php | 33 | ||||
-rw-r--r-- | include/functions_html.inc.php | 53 | ||||
-rw-r--r-- | include/functions_search.inc.php | 68 | ||||
-rw-r--r-- | include/functions_tag.inc.php | 218 | ||||
-rw-r--r-- | include/functions_url.inc.php | 34 | ||||
-rw-r--r-- | include/functions_user.inc.php | 1 | ||||
-rw-r--r-- | include/section_init.inc.php | 117 |
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, |