aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrvelices <rv-github@modusoptimus.com>2007-02-28 03:07:12 +0000
committerrvelices <rv-github@modusoptimus.com>2007-02-28 03:07:12 +0000
commitea56d7b2ac1d41ea19b5fb45843c839e30a0b37b (patch)
tree5f55c108b1a808867d44db2b6ebcf0ad573874b6
parent30e259904cc38172b2b730455009455675f0d8f5 (diff)
feature 657: permalinks for categories
git-svn-id: http://piwigo.org/svn/trunk@1866 68402e56-0260-453c-a942-63ccdbb3a9ee
-rw-r--r--admin.php4
-rw-r--r--admin/cat_list.php28
-rw-r--r--admin/include/functions.php5
-rw-r--r--admin/include/functions_permalinks.php170
-rw-r--r--admin/permalinks.php97
-rw-r--r--admin/plugin.php3
-rw-r--r--comments.php9
-rw-r--r--include/category_cats.inc.php4
-rw-r--r--include/constants.php4
-rw-r--r--include/functions.inc.php20
-rw-r--r--include/functions_category.inc.php89
-rw-r--r--include/functions_html.inc.php18
-rw-r--r--include/functions_url.inc.php18
-rw-r--r--include/section_init.inc.php73
-rw-r--r--include/ws_functions.inc.php6
-rw-r--r--install/db/54-database.php71
-rw-r--r--install/phpwebgallery_structure.sql18
-rw-r--r--language/en_UK.iso-8859-1/admin.lang.php11
-rw-r--r--language/fr_FR.iso-8859-1/admin.lang.php11
-rw-r--r--template/yoga/admin.tpl3
-rw-r--r--template/yoga/admin/permalinks.tpl71
-rw-r--r--template/yoga/default-layout.css6
22 files changed, 650 insertions, 89 deletions
diff --git a/admin.php b/admin.php
index 9b2147728..9282f3430 100644
--- a/admin.php
+++ b/admin.php
@@ -4,7 +4,6 @@
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
// +-----------------------------------------------------------------------+
-// | branch : BSF (Best So Far)
// | file : $Id$
// | last update : $Date$
// | last modifier : $Author$
@@ -107,10 +106,9 @@ $template->assign_vars(
'U_THUMBNAILS'=> $link_start.'thumbnail',
'U_USERS'=> $link_start.'user_list',
'U_GROUPS'=> $link_start.'group_list',
+ 'U_PERMALINKS'=> $link_start.'permalinks',
'U_RETURN'=> make_index_url(),
'U_ADMIN'=> PHPWG_ROOT_PATH.'admin.php',
- 'L_ADMIN' => $lang['admin'],
- 'L_ADMIN_HINT' => $lang['hint_admin']
)
);
if ($conf['ws_access_control']) // Do we need to display ws_checker
diff --git a/admin/cat_list.php b/admin/cat_list.php
index c34754f87..e11e13b8b 100644
--- a/admin/cat_list.php
+++ b/admin/cat_list.php
@@ -138,32 +138,6 @@ SELECT id, name
}
// +-----------------------------------------------------------------------+
-// | Cache management |
-// +-----------------------------------------------------------------------+
-$query = '
-SELECT *
- FROM '.CATEGORIES_TABLE;
-if (!isset($_GET['parent_id']))
-{
- $query.= '
- WHERE id_uppercat IS NULL';
-}
-else
-{
- $query.= '
- WHERE id_uppercat = '.$_GET['parent_id'];
-}
-$query.= '
- ORDER BY rank ASC
-;';
-$result = pwg_query($query);
-while ($row = mysql_fetch_assoc($result))
-{
- $categories[$row['rank']] = $row;
- $categories[$row['rank']]['nb_subcats'] = 0;
-}
-
-// +-----------------------------------------------------------------------+
// | Navigation path |
// +-----------------------------------------------------------------------+
@@ -209,7 +183,7 @@ $tpl = array('cat_first','cat_last');
$categories = array();
$query = '
-SELECT id, name, dir, rank, nb_images, status
+SELECT id, name, permalink, dir, rank, nb_images, status
FROM '.CATEGORIES_TABLE;
if (!isset($_GET['parent_id']))
{
diff --git a/admin/include/functions.php b/admin/include/functions.php
index ff54dbbab..99ebfac62 100644
--- a/admin/include/functions.php
+++ b/admin/include/functions.php
@@ -120,6 +120,11 @@ DELETE FROM '.CATEGORIES_TABLE.'
;';
pwg_query($query);
+ $query='
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+ WHERE cat_id IN ('.implode(',',$cat_ids).')';
+ pwg_query($query);
+
if (isset($counts['del_categories']))
{
$counts['del_categories']+= count($ids);
diff --git a/admin/include/functions_permalinks.php b/admin/include/functions_permalinks.php
new file mode 100644
index 000000000..9a36ccf3d
--- /dev/null
+++ b/admin/include/functions_permalinks.php
@@ -0,0 +1,170 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file : $Id: admin/function_permalinks.inc.php$
+// | last update : $Date$
+// | last modifier : $Author$
+// | revision : $Revision$
+// +-----------------------------------------------------------------------+
+// | 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. |
+// +-----------------------------------------------------------------------+
+
+/** deletes the permalink associated with a category
+ * returns true on success
+ * @param int cat_id the target category id
+ * @param boolean save if true, the current category-permalink association
+ * is saved in the old permalinks table in case external links hit it
+ */
+function delete_cat_permalink( $cat_id, $save )
+{
+ global $page, $cache;
+ $query = '
+SELECT permalink
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id="'.$cat_id.'"
+;';
+ $result = pwg_query($query);
+ if ( mysql_num_rows($result) )
+ {
+ list($permalink) = mysql_fetch_array($result);
+ }
+ if ( !isset($permalink) )
+ {// no permalink; nothing to do
+ return true;
+ }
+ if ($save)
+ {
+ $old_cat_id = get_cat_id_from_old_permalink($permalink, false);
+ if ( isset($old_cat_id) and $old_cat_id!=$cat_id )
+ {
+ $page['errors'][] =
+ sprintf(
+ l10n('Permalink_%s_histo_used_by_%s'),
+ $permalink, $old_cat_id
+ );
+ return false;
+ }
+ }
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET permalink=NULL
+ WHERE id='.$cat_id.'
+ LIMIT 1';
+ pwg_query($query);
+
+ unset( $cache['cat_names'] ); //force regeneration
+ if ($save)
+ {
+ if ( isset($old_cat_id) )
+ {
+ $query = '
+UPDATE '.OLD_PERMALINKS_TABLE.'
+ SET date_deleted=NOW()
+ WHERE cat_id='.$cat_id.' AND permalink="'.$permalink.'"';
+ }
+ else
+ {
+ $query = '
+INSERT INTO '.OLD_PERMALINKS_TABLE.'
+ (permalink, cat_id, date_deleted)
+VALUES
+ ( "'.$permalink.'",'.$cat_id.',NOW() )';
+ }
+ pwg_query( $query );
+ }
+ return true;
+}
+
+/** sets a new permalink for a category
+ * returns true on success
+ * @param int cat_id the target category id
+ * @param string permalink the new permalink
+ * @param boolean save if true, the current category-permalink association
+ * is saved in the old permalinks table in case external links hit it
+ */
+function set_cat_permalink( $cat_id, $permalink, $save )
+{
+ global $page, $cache;
+
+ $sanitized_permalink = preg_replace( '#[^a-zA-Z0-9_-]#', '' ,$permalink);
+ if ( $sanitized_permalink != $permalink
+ or preg_match( '#^(\d)+-?#', $permalink) )
+ {
+ $page['errors'][] = l10n('Permalink_name_rule');
+ return false;
+ }
+
+ $existing_cat_id = get_cat_id_from_permalink( $permalink );
+ if ( isset($existing_cat_id) )
+ {
+ if ( $existing_cat_id==$cat_id )
+ {// no change required
+ return true;
+ }
+ else
+ {
+ $page['errors'][] =
+ sprintf(
+ l10n('Permalink %s is already used by category %s'),
+ $permalink, $existing_cat_id
+ );
+ return false;
+ }
+ }
+
+ if ($save)
+ {
+ $old_cat_id = get_cat_id_from_old_permalink($permalink, false);
+ if ( isset($old_cat_id) )
+ {
+ if ( $old_cat_id!=$cat_id )
+ {
+ $page['errors'][] =
+ sprintf(
+ l10n('Permalink_%s_histo_used_by_%s'),
+ $permalink, $old_cat_id
+ );
+ return false;
+ }
+ else
+ {
+ $query = '
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+ WHERE cat_id='.$cat_id.' AND permalink="'.$permalink.'"';
+ pwg_query($query);
+ }
+ }
+ }
+
+ if ( !delete_cat_permalink($cat_id, $save ) )
+ {
+ return false;
+ }
+
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET permalink="'.$permalink.'"
+ WHERE id='.$cat_id.'
+ LIMIT 1';
+ pwg_query($query);
+
+ unset( $cache['cat_names'] ); //force regeneration
+
+ return true;
+}
+
+?>
diff --git a/admin/permalinks.php b/admin/permalinks.php
new file mode 100644
index 000000000..d00770dd9
--- /dev/null
+++ b/admin/permalinks.php
@@ -0,0 +1,97 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file : $Id$
+// | last update : $Date$
+// | last modifier : $Author$
+// | revision : $Revision$
+// +-----------------------------------------------------------------------+
+// | 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_permalinks.php');
+
+$selected_cat = array();
+if ( isset($_POST['set_permalink']) and $_POST['cat_id']>0 )
+{
+ $permalink = $_POST['permalink'];
+ if ( empty($permalink) )
+ delete_cat_permalink($_POST['cat_id'], isset($_POST['save']) );
+ else
+ set_cat_permalink($_POST['cat_id'], $permalink, isset($_POST['save']) );
+ $selected_cat = array( $_POST['cat_id'] );
+}
+elseif ( isset($_GET['delete_permanent']) )
+{
+ $query = '
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+ WHERE permalink="'.$_GET['delete_permanent'].'"
+ LIMIT 1';
+ pwg_query($query);
+ if (mysql_affected_rows()==0)
+ array_push($page['errors'], 'Cannot delete the old permalink !');
+}
+
+$template->set_filename('permalinks', 'admin/permalinks.tpl' );
+
+$query = '
+SELECT
+ id,
+ CONCAT(id, " - ", name, IF(permalink IS NULL, "", " &radic;") ) AS name,
+ uppercats, global_rank
+FROM '.CATEGORIES_TABLE;
+
+display_select_cat_wrapper( $query, $selected_cat, 'categories', false );
+
+$query = '
+SELECT id, name, permalink
+ FROM '.CATEGORIES_TABLE.'
+ WHERE permalink IS NOT NULL';
+$result=pwg_query($query);
+while ( $row=mysql_fetch_assoc($result) )
+{
+ $display_name = get_cat_display_name( array($row) );
+ $template->assign_block_vars( 'permalink',
+ array(
+ 'CAT_ID' => $row['id'],
+ 'CAT' => $display_name,
+ 'PERMALINK' => $row['permalink'],
+ )
+ );
+}
+
+$url_del_base = get_root_url().'admin.php?page=permalinks';
+
+$query = 'SELECT * FROM '.OLD_PERMALINKS_TABLE;
+$result = pwg_query($query);
+while ( $row=mysql_fetch_assoc($result) )
+{
+ $row['display_name'] = get_cat_display_name_cache($row['cat_id']);
+ $row['U_DELETE'] =
+ add_url_params(
+ $url_del_base,
+ array( 'delete_permanent'=> $row['permalink'] )
+ );
+ $template->assign_block_vars( 'deleted_permalink', $row );
+}
+
+$template->assign_var('U_HELP', get_root_url().'popuphelp.php?page=permalinks');
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'permalinks');
+?>
diff --git a/admin/plugin.php b/admin/plugin.php
index 1657f10c8..aa8faaade 100644
--- a/admin/plugin.php
+++ b/admin/plugin.php
@@ -49,8 +49,7 @@ if (count($sections)<2)
}
$plugin_id = $sections[0];
-$check_db_plugin = get_db_plugins('active', $plugin_id );
-if (empty($check_db_plugin))
+if ( !isset($pwg_loaded_plugins[$plugin_id]) )
{
die('Invalid URL - plugin '.$plugin_id.' not active');
}
diff --git a/comments.php b/comments.php
index 9a41dcb2b..b46ee3f8e 100644
--- a/comments.php
+++ b/comments.php
@@ -369,17 +369,12 @@ SELECT id, name, file, path, tn_ext
}
// retrieving category informations
- $categories = array();
$query = '
-SELECT id, name, uppercats
+SELECT id, name, permalink, uppercats
FROM '.CATEGORIES_TABLE.'
WHERE id IN ('.implode(',', $category_ids).')
;';
- $result = pwg_query($query);
- while ($row = mysql_fetch_assoc($result))
- {
- $categories[$row['id']] = $row;
- }
+ $categories = hash_from_query($query, 'id');
foreach ($comments as $comment)
{
diff --git a/include/category_cats.inc.php b/include/category_cats.inc.php
index e9549ba44..ccdfa5949 100644
--- a/include/category_cats.inc.php
+++ b/include/category_cats.inc.php
@@ -35,7 +35,7 @@ if ($page['section']=='recent_cats')
// $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
$query = '
SELECT
- id, name, representative_picture_id, comment, nb_images, uppercats,
+ id, name, permalink, representative_picture_id, comment, nb_images, uppercats,
date_last, max_date_last, count_images, count_categories, global_rank
FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
ON id = cat_id and user_id = '.$user['id'].'
@@ -57,7 +57,7 @@ else
// $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
$query = '
SELECT
- id, name, representative_picture_id, comment, nb_images,
+ id, name, permalink, representative_picture_id, comment, nb_images,
date_last, max_date_last, count_images, count_categories
FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
ON id = cat_id and user_id = '.$user['id'].'
diff --git a/include/constants.php b/include/constants.php
index 0d1b6f9ae..f442bac99 100644
--- a/include/constants.php
+++ b/include/constants.php
@@ -4,8 +4,7 @@
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
// +-----------------------------------------------------------------------+
-// | branch : BSF (Best So Far)
-// | file : $RCSfile$
+// | file : $Id$
// | last update : $Date$
// | last modifier : $Author$
// | revision : $Revision$
@@ -75,4 +74,5 @@ define('TAGS_TABLE', $prefixeTable.'tags');
define('IMAGE_TAG_TABLE', $prefixeTable.'image_tag');
define('PLUGINS_TABLE', $prefixeTable.'plugins');
define('WEB_SERVICES_ACCESS_TABLE', $prefixeTable.'ws_access');
+define('OLD_PERMALINKS_TABLE', $prefixeTable.'old_permalinks');
?>
diff --git a/include/functions.inc.php b/include/functions.inc.php
index 6b44c81dc..eb706e6ba 100644
--- a/include/functions.inc.php
+++ b/include/functions.inc.php
@@ -1175,6 +1175,26 @@ function simple_hash_from_query($query, $keyname, $valuename)
}
/**
+ * creates an hashed based on a query, this function is a very common
+ * pattern used here. The key is given as parameter, the value is an associative
+ * array.
+ *
+ * @param string $query
+ * @param string $keyname
+ * @return array
+ */
+function hash_from_query($query, $keyname)
+{
+ $array = array();
+ $result = pwg_query($query);
+ while ($row = mysql_fetch_assoc($result))
+ {
+ $array[ $row[$keyname] ] = $row;
+ }
+ return $array;
+}
+
+/**
* Return basename of the current script
* Lower case convertion is applied on return value
* Return value is without file extention ".php"
diff --git a/include/functions_category.inc.php b/include/functions_category.inc.php
index 66b8865da..5d1679e5c 100644
--- a/include/functions_category.inc.php
+++ b/include/functions_category.inc.php
@@ -59,7 +59,7 @@ function get_categories_menu()
SELECT ';
// From CATEGORIES_TABLE
$query.= '
- name, id, nb_images, global_rank,';
+ id, name, permalink, nb_images, global_rank,';
// From USER_CACHE_CATEGORIES_TABLE
$query.= '
date_last, max_date_last, count_images, count_categories';
@@ -159,25 +159,34 @@ SELECT *
$cat['comment'] = nl2br(@$cat['comment']);
}
- $names = array();
- $query = '
-SELECT id, name
- FROM '.CATEGORIES_TABLE.'
- WHERE id IN ('.$cat['uppercats'].')
-;';
- $result = pwg_query($query);
- while($row = mysql_fetch_assoc($result))
- {
- $names[$row['id']] = $row;
+ $upper_ids = explode(',', $cat['uppercats']);
+ if ( count($upper_ids)==1 )
+ {// no need to make a query for level 1
+ $cat['upper_names'] = array(
+ array(
+ 'id' => $cat['id'],
+ 'name' => $cat['name'],
+ 'permalink' => $cat['permalink'],
+ )
+ );
}
-
- // category names must be in the same order than uppercats list
- $cat['upper_names'] = array();
- foreach (explode(',', $cat['uppercats']) as $cat_id)
+ else
{
- $cat['upper_names'][$cat_id] = $names[$cat_id];
+ $names = array();
+ $query = '
+ SELECT id, name, permalink
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.$cat['uppercats'].')
+ ;';
+ $names = hash_from_query($query, 'id');
+
+ // category names must be in the same order than uppercats list
+ $cat['upper_names'] = array();
+ foreach ($upper_ids as $cat_id)
+ {
+ array_push( $cat['upper_names'], $names[$cat_id]);
+ }
}
-
return $cat;
}
@@ -308,7 +317,7 @@ function display_select_cat_wrapper($query, $selecteds, $blockname,
$categories = array();
if (!empty($result))
{
- while ($row = mysql_fetch_array($result))
+ while ($row = mysql_fetch_assoc($result))
{
array_push($categories, $row);
}
@@ -355,6 +364,50 @@ SELECT DISTINCT(id)
return $subcats;
}
+/** returns a category id that corresponds to the given permalink (or null)
+ * @param string permalink
+ */
+function get_cat_id_from_permalink( $permalink )
+{
+ $query ='
+SELECT id FROM '.CATEGORIES_TABLE.'
+ WHERE permalink="'.$permalink.'"';
+ $ids = array_from_query($query, 'id');
+ if (!empty($ids))
+ {
+ return $ids[0];
+ }
+ return null;
+}
+
+/** returns a category id that has used before this permalink (or null)
+ * @param string permalink
+ * @param boolean is_hit if true update the usage counters on the old permalinks
+ */
+function get_cat_id_from_old_permalink($permalink, $is_hit)
+{
+ $query='
+SELECT c.id
+ FROM '.OLD_PERMALINKS_TABLE.' op INNER JOIN '.CATEGORIES_TABLE.' c
+ ON op.cat_id=c.id
+ WHERE op.permalink="'.$permalink.'"
+ LIMIT 1';
+ $result = pwg_query($query);
+ $cat_id = null;
+ if ( mysql_num_rows($result) )
+ list( $cat_id ) = mysql_fetch_array($result);
+
+ if ( isset($cat_id) and $is_hit )
+ {
+ $query='
+UPDATE '.OLD_PERMALINKS_TABLE.' SET last_hit=NOW(), hit=hit+1
+ WHERE permalink="'.$permalink.'" AND cat_id='.$cat_id.'
+ LIMIT 1';
+ pwg_query($query);
+ }
+ return $cat_id;
+}
+
function global_rank_compare($a, $b)
{
return strnatcasecmp($a['global_rank'], $b['global_rank']);
diff --git a/include/functions_html.inc.php b/include/functions_html.inc.php
index dcb42cdb1..5612454b0 100644
--- a/include/functions_html.inc.php
+++ b/include/functions_html.inc.php
@@ -234,8 +234,8 @@ function create_navigation_bar(
* returns the list of categories as a HTML string
*
* categories string returned contains categories as given in the input
- * array $cat_informations. $cat_informations array must be an association
- * of {category_id => array( id, name) }. If url input parameter is null,
+ * array $cat_informations. $cat_informations array must be an array
+ * of array( id=>?, name=>?, permalink=>?). If url input parameter is null,
* returns only the categories name without links.
*
* @param array cat_informations
@@ -251,10 +251,10 @@ function get_cat_display_name($cat_informations,
$output = '';
$is_first = true;
- foreach ($cat_informations as $id => $cat)
+ foreach ($cat_informations as $cat)
{
is_array($cat) or trigger_error(
- 'get_cat_display_name wrong type for cat '.$id, E_USER_WARNING
+ 'get_cat_display_name wrong type for category ', E_USER_WARNING
);
if ($is_first)
{
@@ -282,7 +282,7 @@ function get_cat_display_name($cat_informations,
}
else
{
- $output.= '<a href="'.PHPWG_ROOT_PATH.$url.$id.'">';
+ $output.= '<a href="'.PHPWG_ROOT_PATH.$url.$cat['id'].'">';
$output.= $cat['name'].'</a>';
}
}
@@ -318,14 +318,10 @@ function get_cat_display_name_cache($uppercats,
if (!isset($cache['cat_names']))
{
$query = '
-SELECT id, name
+SELECT id, name, permalink
FROM '.CATEGORIES_TABLE.'
;';
- $result = pwg_query($query);
- while ($row = mysql_fetch_assoc($result))
- {
- $cache['cat_names'][$row['id']] = $row;
- }
+ $cache['cat_names'] = hash_from_query($query, 'id');
}
$output = '';
diff --git a/include/functions_url.inc.php b/include/functions_url.inc.php
index b96ed82b7..04e0b32d1 100644
--- a/include/functions_url.inc.php
+++ b/include/functions_url.inc.php
@@ -336,10 +336,22 @@ function make_section_in_url($params)
'make_section_in_url category name not set', E_USER_WARNING
);
- $section_string.= '/category/'.$params['category']['id'];
- if ( $conf['category_url_style']=='id-name' )
+ array_key_exists('permalink', $params['category']) or trigger_error(
+ 'make_section_in_url category permalink not set', E_USER_WARNING
+ );
+
+ $section_string.= '/category/';
+ if ( empty($params['category']['permalink']) )
+ {
+ $section_string.= $params['category']['id'];
+ if ( $conf['category_url_style']=='id-name' )
+ {
+ $section_string.= '-'.str2url($params['category']['name']);
+ }
+ }
+ else
{
- $section_string.= '-'.str2url($params['category']['name']);
+ $section_string.= $params['category']['permalink'];
}
}
diff --git a/include/section_init.inc.php b/include/section_init.inc.php
index 4434ec542..af633571a 100644
--- a/include/section_init.inc.php
+++ b/include/section_init.inc.php
@@ -107,7 +107,6 @@ if (script_basename() == 'picture') // basename without file extention
{
$page['image_file'] = $matches[2];
}
-
}
else
{
@@ -128,11 +127,39 @@ if (0 === strpos(@$tokens[$next_token], 'categor'))
$page['section'] = 'categories';
$next_token++;
- if (isset($tokens[$next_token])
- and preg_match('/^(\d+)/', $tokens[$next_token], $matches))
+ if (isset($tokens[$next_token]) )
{
- $page['category'] = $matches[1];
- $next_token++;
+ if (preg_match('/^(\d+)(?:-(.+))?$/', $tokens[$next_token], $matches))
+ {
+ if ( isset($matches[2]) )
+ $page['hit_by']['cat_url_name'] = $matches[2];
+ $page['category'] = $matches[1];
+ $next_token++;
+ }
+ else
+ {
+ if ( strpos($tokens[$next_token], 'created-')!==0
+ and strpos($tokens[$next_token], 'posted-')!==0
+ and $tokens[$next_token] != 'flat')
+ {// try a permalink
+ $cat_id = get_cat_id_from_permalink($tokens[$next_token]);
+ if ( !isset($cat_id) )
+ {//try old permalink
+ $cat_id = get_cat_id_from_old_permalink($tokens[$next_token], true);
+ }
+ if ( isset($cat_id) )
+ {
+ $page['category'] = $cat_id;
+ $page['hit_by']['cat_permalink'] = $tokens[$next_token];
+ }
+ else
+ {
+ page_not_found('Permalink for album not found');
+ }
+ unset($cat_id);
+ $next_token++;
+ }
+ }
}
}
else if (0 === strpos(@$tokens[$next_token], 'tag'))
@@ -690,5 +717,41 @@ if ( $filter['enabled'] )
$page['meta_robots']['noindex']=1;
}
+// see if we need a redirect because of a permalink
+if ( 'categories'==$page['section'] and isset($page['category']) )
+{
+ $need_redirect=false;
+ if ( empty($page['category']['permalink']) )
+ {
+ if ( $conf['category_url_style'] == 'id-name' and
+ @$page['hit_by']['cat_url_name'] !== str2url($page['category']['name']) )
+ {
+ $need_redirect=true;
+ }
+ }
+ else
+ {
+ if ( $page['category']['permalink'] !== @$page['hit_by']['cat_permalink'] )
+ {
+ $need_redirect=true;
+ }
+ }
+
+ if ($need_redirect)
+ {
+ $redirect_url = ( script_basename()=='picture'
+ ? duplicate_picture_url()
+ : duplicate_index_url()
+ );
+ if (!headers_sent())
+ { // this is a permanent redirection
+ set_status_header(302);
+ redirect_http( $redirect_url );
+ }
+ redirect( $redirect_url );
+ }
+ unset( $need_redirect, $page['hit_by'] );
+}
+
trigger_action('loc_end_section_init');
?> \ No newline at end of file
diff --git a/include/ws_functions.inc.php b/include/ws_functions.inc.php
index c8e2a0fe0..f6653a457 100644
--- a/include/ws_functions.inc.php
+++ b/include/ws_functions.inc.php
@@ -319,7 +319,7 @@ function ws_categories_getImages($params, &$service)
$where_clauses[] = 'id NOT IN ('.$user['forbidden_categories'].')';
$query = '
-SELECT id, name, image_order
+SELECT id, name, permalink, image_order
FROM '.CATEGORIES_TABLE.'
WHERE '. implode('
AND ', $where_clauses);
@@ -465,7 +465,7 @@ function ws_categories_getList($params, &$service)
}
$query = '
-SELECT id, name, uppercats, global_rank,
+SELECT id, name, permalink, uppercats, global_rank,
nb_images, count_images AS total_nb_images,
date_last, max_date_last, count_categories AS nb_categories
FROM '.CATEGORIES_TABLE.'
@@ -596,7 +596,7 @@ LIMIT 1;';
//-------------------------------------------------------- related categories
$query = '
-SELECT id, name, uppercats, global_rank, commentable
+SELECT id, name, permalink, uppercats, global_rank, commentable
FROM '.IMAGE_CATEGORY_TABLE.'
INNER JOIN '.CATEGORIES_TABLE.' ON category_id = id
WHERE image_id = '.$image_row['id'].'
diff --git a/install/db/54-database.php b/install/db/54-database.php
new file mode 100644
index 000000000..5014df0e0
--- /dev/null
+++ b/install/db/54-database.php
@@ -0,0 +1,71 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file : $Id$
+// | last update : $Date$
+// | last modifier : $Author$
+// | revision : $Revision$
+// +-----------------------------------------------------------------------+
+// | 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 = 'add column #categories.permalink and table #old_permalinks';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// | Upgrade content |
+// +-----------------------------------------------------------------------+
+
+defined('OLD_PERMALINKS_TABLE') or die('OLD_PERMALINKS_TABLE is not defined');
+
+$query = "
+CREATE TABLE `".OLD_PERMALINKS_TABLE."` (
+ `cat_id` smallint(5) unsigned NOT NULL,
+ `permalink` VARCHAR(64) NOT NULL,
+ `date_deleted` datetime NOT NULL,
+ `last_hit` datetime default NULL,
+ `hit` int(10) unsigned NOT NULL default '0',
+ PRIMARY KEY (`permalink`)
+) TYPE=MyISAM
+;";
+pwg_query($query);
+
+$query = "
+ALTER TABLE `".CATEGORIES_TABLE."`
+ ADD COLUMN `permalink` VARCHAR(64) default NULL
+;";
+pwg_query($query);
+
+$query = "
+ALTER TABLE `".CATEGORIES_TABLE."`
+ ADD UNIQUE INDEX `categories_i3` (`permalink`)
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
diff --git a/install/phpwebgallery_structure.sql b/install/phpwebgallery_structure.sql
index bc229dc6a..5a9d3e544 100644
--- a/install/phpwebgallery_structure.sql
+++ b/install/phpwebgallery_structure.sql
@@ -38,8 +38,10 @@ CREATE TABLE `phpwebgallery_categories` (
`commentable` enum('true','false') NOT NULL default 'true',
`global_rank` varchar(255) default NULL,
`image_order` varchar(128) default NULL,
+ `permalink` VARCHAR(64) default NULL,
PRIMARY KEY (`id`),
- KEY `categories_i2` (`id_uppercat`)
+ KEY `categories_i2` (`id_uppercat`),
+ UNIQUE KEY `categories_i3` (`permalink`)
) TYPE=MyISAM;
--
@@ -203,6 +205,20 @@ CREATE TABLE `phpwebgallery_images` (
) TYPE=MyISAM;
--
+-- Table structure for table `phpwebgallery_old_permalinks`
+--
+
+DROP TABLE IF EXISTS `phpwebgallery_old_permalinks`;
+CREATE TABLE `phpwebgallery_old_permalinks` (
+ `cat_id` smallint(5) unsigned NOT NULL,
+ `permalink` VARCHAR(64) NOT NULL,
+ `date_deleted` datetime NOT NULL,
+ `last_hit` datetime default NULL,
+ `hit` int(10) unsigned NOT NULL default '0',
+ PRIMARY KEY (`permalink`)
+) TYPE=MyISAM;
+
+--
-- Table structure for table `phpwebgallery_plugins`
--
diff --git a/language/en_UK.iso-8859-1/admin.lang.php b/language/en_UK.iso-8859-1/admin.lang.php
index 859ab6719..0dcb19ed0 100644
--- a/language/en_UK.iso-8859-1/admin.lang.php
+++ b/language/en_UK.iso-8859-1/admin.lang.php
@@ -4,8 +4,7 @@
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
// +-----------------------------------------------------------------------+
-// | branch : BSF (Best So Far)
-// | file : $RCSfile$
+// | file : $Id$
// | last update : $Date$
// | last modifier : $Author$
// | revision : $Revision$
@@ -43,6 +42,7 @@ $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['Activate'] = 'Activate';
+$lang['Add/delete a permalink'] = 'Add/delete a permalink';
$lang['Add a tag'] = 'Add a tag';
$lang['Add a user'] = 'Add a user';
$lang['Add group'] = 'Add group';
@@ -137,6 +137,12 @@ $lang['Other private categories'] = 'Other private categories';
$lang['Page banner'] = 'Page banner';
$lang['Parent category'] = 'Parent category';
$lang['Path'] = 'Path';
+$lang['Permalink'] = 'Permalink';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Permalink %s has been previously used by category %s. Delete from the permalink history first';
+$lang['Permalink_name_rule'] = 'The permalink name must be composed of a-z, A-Z, 0-9, "-" or "_". It must not be numeric or start with number followed by "-"';
+$lang['Permalink %s is already used by category %s'] = 'Permalink %s is already used by category %s';
+$lang['Permalink history'] = 'Permalink history';
+$lang['Permalinks'] = 'Permalinks';
$lang['Permission denied'] = 'Permission denied';
$lang['Permission granted thanks to a group'] = 'Permission granted thanks to a group';
$lang['Permission granted'] = 'Permission granted';
@@ -159,6 +165,7 @@ $lang['Representation of categories'] = 'Representation of categories';
$lang['Representative'] = 'Representative';
$lang['Represents'] = 'Represents';
$lang['Save order'] = 'Save order';
+$lang['Save to permalink history'] = 'Save to permalink history';
$lang['Select at least one category'] = 'Select at least one category';
$lang['Select at least one picture'] = 'Select at least one picture';
$lang['Select at least one user'] = 'Select at least one user';
diff --git a/language/fr_FR.iso-8859-1/admin.lang.php b/language/fr_FR.iso-8859-1/admin.lang.php
index ee335985e..49fd6a98c 100644
--- a/language/fr_FR.iso-8859-1/admin.lang.php
+++ b/language/fr_FR.iso-8859-1/admin.lang.php
@@ -4,8 +4,7 @@
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
// +-----------------------------------------------------------------------+
-// | branch : BSF (Best So Far)
-// | file : $RCSfile$
+// | file : $Id$
// | last update : $Date$
// | last modifier : $Author$
// | revision : $Revision$
@@ -43,6 +42,7 @@ $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['Activate'] = 'Activer';
+$lang['Add/delete a permalink'] = 'Ajouter/effacer un lien permanent';
$lang['Add a tag'] = 'Ajouter un tag';
$lang['Add a user'] = 'Ajouter un utilisateur';
$lang['Add group'] = 'Ajouter un groupe';
@@ -137,6 +137,12 @@ $lang['Other private categories'] = 'Autres catégories privées';
$lang['Page banner'] = 'Bannière des pages';
$lang['Parent category'] = 'Catégorie parente';
$lang['Path'] = 'Chemin';
+$lang['Permalink'] = 'Lien permanent';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Le lien permanent %s a été utilisé précédemment par la catégorie %s. Veuillez l\'effacer de l\'historique des liens permanents';
+$lang['Permalink_name_rule'] = 'Le lien permanent ne doit contenir des caractères que parmi "a-zA-Z0-9", "-" ou "_". Il ne doit pas être numérique ou commencer par un nombre suivi par "-"';
+$lang['Permalink %s is already used by category %s'] = 'Le lien permanent %s est dèja utilisé par la catégorie %s';
+$lang['Permalink history'] = 'Historique des liens permanents';
+$lang['Permalinks'] = 'Liens permanents';
$lang['Permission denied'] = 'Accès interdit';
$lang['Permission granted thanks to a group'] = 'Accès autorisé grâce à l\'appartenance aux groupes';
$lang['Permission granted'] = 'Accès autorisé';
@@ -159,6 +165,7 @@ $lang['Representation of categories'] = 'Représentation des catégories';
$lang['Representative'] = 'Représentant';
$lang['Represents'] = 'Représente';
$lang['Save order'] = 'Sauvegarder l\'ordre';
+$lang['Save to permalink history'] = 'Sauvegarder dans l\'historique des liens permanents';
$lang['Select at least one category'] = 'Sélectionner au moins une catégorie';
$lang['Select at least one picture'] = 'Sélectionner au moins une image';
$lang['Select at least one user'] = 'Sélectionner au moins un utilisateur';
diff --git a/template/yoga/admin.tpl b/template/yoga/admin.tpl
index fdbd50614..5920f4e95 100644
--- a/template/yoga/admin.tpl
+++ b/template/yoga/admin.tpl
@@ -6,7 +6,7 @@
<ul>
<li><a href="{U_RETURN}">{lang:home}</a></li>
<li><a href="{U_FAQ}">{lang:instructions}</a></li>
- <li><a href="{U_ADMIN}" title="{L_ADMIN_HINT}">{L_ADMIN}</a></li>
+ <li><a href="{U_ADMIN}" title="{lang:hint_admin}">{lang:admin}</a></li>
</ul>
</dd>
</dl>
@@ -34,6 +34,7 @@
<!-- BEGIN representative -->
<li><a href="{representative.URL}">{lang:Representative}</a></li>
<!-- END representative -->
+ <li><a href="{U_PERMALINKS}">{lang:Permalinks}</a></li>
</ul>
</dd>
</dl>
diff --git a/template/yoga/admin/permalinks.tpl b/template/yoga/admin/permalinks.tpl
new file mode 100644
index 000000000..508cf66a9
--- /dev/null
+++ b/template/yoga/admin/permalinks.tpl
@@ -0,0 +1,71 @@
+<div class="titrePage">
+ <ul class="categoryActions">
+ <li><a href="{U_HELP}" onclick="popuphelp(this.href); return false;" title="{lang:Help}"><img src="{themeconf:icon_dir}/help.png" class="button" alt="(?)"></a></li>
+ </ul>
+ <h2>{lang:Permalinks}</h2>
+</div>
+
+<form method="post">
+<fieldset><legend>{lang:Add/delete a permalink}</legend>
+ <label>Category:
+ <select name="cat_id">
+ <option value="0">------</option>
+<!-- BEGIN categories -->
+ <option value="{categories.VALUE}" {categories.SELECTED}>{categories.OPTION}</option>
+<!-- END categories -->
+ </select>
+ </label>
+
+ <label>{lang:Permalink}:
+ <input name="permalink" />
+ </label>
+
+ <label>{lang:Save to permalink history}:
+ <input type="checkbox" name="save" checked="checked" />
+ </label>
+
+ <p>
+ <input type="submit" class="submit" name="set_permalink" value="{lang:submit}"/>
+ </p>
+ </fieldset>
+</form>
+
+<h3>{lang:Permalinks}</h3>
+<table class="table2">
+ <tr class="throw">
+ <td>Id</td>
+ <td>{lang:Category}</td>
+ <td>{lang:Permalink}</td>
+ </tr>
+<!-- BEGIN permalink -->
+ <tr>
+ <td>{permalink.CAT_ID}</td>
+ <td>{permalink.CAT}</td>
+ <td>{permalink.PERMALINK}</td>
+ </tr>
+<!-- END permalink -->
+</table>
+
+<h3>{lang:Permalink history}</h3>
+<table class="table2">
+ <tr class="throw">
+ <td>Id</td>
+ <td>{lang:Category}</td>
+ <td>{lang:Permalink}</td>
+ <td>Deleted on</td>
+ <td>Last hit</td>
+ <td>Hit</td>
+ <td></td>
+ </tr>
+<!-- BEGIN deleted_permalink -->
+ <tr>
+ <td>{deleted_permalink.cat_id}</td>
+ <td>{deleted_permalink.display_name}</td>
+ <td>{deleted_permalink.permalink}</td>
+ <td>{deleted_permalink.date_deleted}</td>
+ <td>{deleted_permalink.last_hit}</td>
+ <td>{deleted_permalink.hit}</td>
+ <td><a href="{deleted_permalink.U_DELETE}"><img src="{pwg_root}{themeconf:icon_dir}/delete.png" alt="Delete"></a></td>
+ </tr>
+<!-- END deleted_permalink -->
+</table>
diff --git a/template/yoga/default-layout.css b/template/yoga/default-layout.css
index 647f27781..2b43bc5bc 100644
--- a/template/yoga/default-layout.css
+++ b/template/yoga/default-layout.css
@@ -80,6 +80,12 @@ FORM P {
margin-top: 2em;
margin-bottom: 2em;
}
+
+FORM FIELDSET P {
+ margin-top: 1em;
+ margin-bottom: 0;
+}
+
.small {
font-size: 80%;
}