diff options
Diffstat (limited to 'phpBB/phpbb_seo')
-rw-r--r-- | phpBB/phpbb_seo/cache/.htaccess | 80 | ||||
-rw-r--r-- | phpBB/phpbb_seo/cache/.htaccess.current | 80 | ||||
-rw-r--r-- | phpBB/phpbb_seo/cache/phpbb_cache.php | 12 | ||||
-rw-r--r-- | phpBB/phpbb_seo/cache/phpbb_cache.php.current | 12 | ||||
-rw-r--r-- | phpBB/phpbb_seo/cache/phpbb_cache.php.old | 12 | ||||
-rw-r--r-- | phpBB/phpbb_seo/docs/COPYING | 545 | ||||
-rw-r--r-- | phpBB/phpbb_seo/includes/.htaccess | 4 | ||||
-rw-r--r-- | phpBB/phpbb_seo/includes/setup_phpbb_seo.php | 262 | ||||
-rw-r--r-- | phpBB/phpbb_seo/phpbb_seo_class.php | 886 | ||||
-rw-r--r-- | phpBB/phpbb_seo/phpbb_seo_install.php | 776 | ||||
-rw-r--r-- | phpBB/phpbb_seo/phpbb_seo_meta.php | 271 | ||||
-rw-r--r-- | phpBB/phpbb_seo/phpbb_seo_related.php | 243 | ||||
-rw-r--r-- | phpBB/phpbb_seo/phpbb_seo_related_install.php | 193 | ||||
-rw-r--r-- | phpBB/phpbb_seo/sync_url.php | 141 |
14 files changed, 3517 insertions, 0 deletions
diff --git a/phpBB/phpbb_seo/cache/.htaccess b/phpBB/phpbb_seo/cache/.htaccess new file mode 100644 index 0000000000..69e3a64277 --- /dev/null +++ b/phpBB/phpbb_seo/cache/.htaccess @@ -0,0 +1,80 @@ +# Lines That should already be in your .htacess +<Files "config.php"> + Order Allow,Deny + Deny from All +</Files> +<Files "common.php"> + Order Allow,Deny + Deny from All +</Files> + +# You may need to un-comment the following lines +# Options +FollowSymlinks +# To make sure that rewritten dir or file (/|.html) will not load dir.php in case it exist +# Options -MultiViews +# REMEBER YOU ONLY NEED TO STARD MOD REWRITE ONCE +RewriteEngine On +# Uncomment the statement below if you want to make use of +# HTTP authentication and it does not already work. +# This could be required if you are for example using PHP via Apache CGI. +# RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] +# REWRITE BASE +RewriteBase / +# HERE IS A GOOD PLACE TO FORCE CANONICAL DOMAIN +# RewriteCond %{HTTP_HOST} !^forums\.mageia\.org$ [NC] +# RewriteRule ^(.*)$ http://forums.mageia.org/$1 [QSA,L,R=301] + +# DO NOT GO FURTHER IF THE REQUESTED FILE / DIR DOES EXISTS +RewriteCond %{REQUEST_FILENAME} -f +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule . - [L] +##################################################### +# PHPBB SEO REWRITE RULES ALL MODES +##################################################### +# AUTHOR : dcz www.phpbb-seo.com +# STARTED : 01/2006 +################################# +# FORUMS PAGES +############### +# FORUM INDEX REWRITERULE WOULD STAND HERE IF USED. "forum" REQUIRES TO BE SET AS FORUM INDEX +# RewriteRule ^en/forum\.html$ /en/index.php [QSA,L,NC] +# FORUM ALL MODES +RewriteRule ^en/(forum|[a-z0-9_-]*-f)([0-9]+)/?(page([0-9]+)\.html)?$ /en/viewforum.php?f=$2&start=$4 [QSA,L,NC] +# TOPIC WITH VIRTUAL FOLDER ALL MODES +RewriteRule ^en/(forum|[a-z0-9_-]*-f)([0-9]+)/(topic|[a-z0-9_-]*-t)([0-9]+)(-([0-9]+))?\.html$ /en/viewtopic.php?f=$2&t=$4&start=$6 [QSA,L,NC] +# TOPIC WITHOUT FORUM ID & DELIM ALL MODES +RewriteRule ^en/([a-z0-9_-]*)/?(topic|[a-z0-9_-]*-t)([0-9]+)(-([0-9]+))?\.html$ /en/viewtopic.php?forum_uri=$1&t=$3&start=$5 [QSA,L,NC] +# PHPBB FILES ALL MODES +RewriteRule ^en/resources/[a-z0-9_-]+/(thumb/)?([0-9]+)$ /en/download/file.php?id=$2&t=$1 [QSA,L,NC] +# PROFILES THROUGH USERNAME +RewriteRule ^en/member/([^/]+)/?$ /en/memberlist.php?mode=viewprofile&un=$1 [QSA,L,NC] +# USER MESSAGES THROUGH USERNAME +RewriteRule ^en/member/([^/]+)/(topics|posts)/?(page([0-9]+)\.html)?$ /en/search.php?author=$1&sr=$2&start=$4 [QSA,L,NC] +# GROUPS ALL MODES +RewriteRule ^en/(group|[a-z0-9_-]*-g)([0-9]+)(-([0-9]+))?\.html$ /en/memberlist.php?mode=group&g=$2&start=$4 [QSA,L,NC] +# POST +RewriteRule ^en/post([0-9]+)\.html$ /en/viewtopic.php?p=$1 [QSA,L,NC] +# ACTIVE TOPICS +RewriteRule ^en/active-topics(-([0-9]+))?\.html$ /en/search.php?search_id=active_topics&start=$2&sr=topics [QSA,L,NC] +# UNANSWERED TOPICS +RewriteRule ^en/unanswered(-([0-9]+))?\.html$ /en/search.php?search_id=unanswered&start=$2&sr=topics [QSA,L,NC] +# NEW POSTS +RewriteRule ^en/newposts(-([0-9]+))?\.html$ /en/search.php?search_id=newposts&start=$2&sr=topics [QSA,L,NC] +# UNREAD POSTS +RewriteRule ^en/unreadposts(-([0-9]+))?\.html$ /en/search.php?search_id=unreadposts&start=$2 [QSA,L,NC] +# THE TEAM +RewriteRule ^en/the-team\.html$ /en/memberlist.php?mode=leaders [QSA,L,NC] +# HERE IS A GOOD PLACE TO ADD OTHER PHPBB RELATED REWRITERULES + +# FORUM WITHOUT ID & DELIM ALL MODES +# THESE THREE LINES MUST BE LOCATED AT THE END OF YOUR HTACCESS TO WORK PROPERLY +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^en/([a-z0-9_-]+)/?(page([0-9]+)\.html)?$ /en/viewforum.php?forum_uri=$1&start=$3 [QSA,L,NC] +# FIX RELATIVE PATHS : FILES +RewriteRule ^en/.+/(style\.php|ucp\.php|mcp\.php|faq\.php|download/file.php)$ /en/$1 [QSA,L,NC,R=301] +# FIX RELATIVE PATHS : IMAGES +RewriteRule ^en/.+/(styles/.*|images/.*)/$ /en/$1 [QSA,L,NC,R=301] +# END PHPBB PAGES +##################################################### + diff --git a/phpBB/phpbb_seo/cache/.htaccess.current b/phpBB/phpbb_seo/cache/.htaccess.current new file mode 100644 index 0000000000..69e3a64277 --- /dev/null +++ b/phpBB/phpbb_seo/cache/.htaccess.current @@ -0,0 +1,80 @@ +# Lines That should already be in your .htacess +<Files "config.php"> + Order Allow,Deny + Deny from All +</Files> +<Files "common.php"> + Order Allow,Deny + Deny from All +</Files> + +# You may need to un-comment the following lines +# Options +FollowSymlinks +# To make sure that rewritten dir or file (/|.html) will not load dir.php in case it exist +# Options -MultiViews +# REMEBER YOU ONLY NEED TO STARD MOD REWRITE ONCE +RewriteEngine On +# Uncomment the statement below if you want to make use of +# HTTP authentication and it does not already work. +# This could be required if you are for example using PHP via Apache CGI. +# RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] +# REWRITE BASE +RewriteBase / +# HERE IS A GOOD PLACE TO FORCE CANONICAL DOMAIN +# RewriteCond %{HTTP_HOST} !^forums\.mageia\.org$ [NC] +# RewriteRule ^(.*)$ http://forums.mageia.org/$1 [QSA,L,R=301] + +# DO NOT GO FURTHER IF THE REQUESTED FILE / DIR DOES EXISTS +RewriteCond %{REQUEST_FILENAME} -f +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule . - [L] +##################################################### +# PHPBB SEO REWRITE RULES ALL MODES +##################################################### +# AUTHOR : dcz www.phpbb-seo.com +# STARTED : 01/2006 +################################# +# FORUMS PAGES +############### +# FORUM INDEX REWRITERULE WOULD STAND HERE IF USED. "forum" REQUIRES TO BE SET AS FORUM INDEX +# RewriteRule ^en/forum\.html$ /en/index.php [QSA,L,NC] +# FORUM ALL MODES +RewriteRule ^en/(forum|[a-z0-9_-]*-f)([0-9]+)/?(page([0-9]+)\.html)?$ /en/viewforum.php?f=$2&start=$4 [QSA,L,NC] +# TOPIC WITH VIRTUAL FOLDER ALL MODES +RewriteRule ^en/(forum|[a-z0-9_-]*-f)([0-9]+)/(topic|[a-z0-9_-]*-t)([0-9]+)(-([0-9]+))?\.html$ /en/viewtopic.php?f=$2&t=$4&start=$6 [QSA,L,NC] +# TOPIC WITHOUT FORUM ID & DELIM ALL MODES +RewriteRule ^en/([a-z0-9_-]*)/?(topic|[a-z0-9_-]*-t)([0-9]+)(-([0-9]+))?\.html$ /en/viewtopic.php?forum_uri=$1&t=$3&start=$5 [QSA,L,NC] +# PHPBB FILES ALL MODES +RewriteRule ^en/resources/[a-z0-9_-]+/(thumb/)?([0-9]+)$ /en/download/file.php?id=$2&t=$1 [QSA,L,NC] +# PROFILES THROUGH USERNAME +RewriteRule ^en/member/([^/]+)/?$ /en/memberlist.php?mode=viewprofile&un=$1 [QSA,L,NC] +# USER MESSAGES THROUGH USERNAME +RewriteRule ^en/member/([^/]+)/(topics|posts)/?(page([0-9]+)\.html)?$ /en/search.php?author=$1&sr=$2&start=$4 [QSA,L,NC] +# GROUPS ALL MODES +RewriteRule ^en/(group|[a-z0-9_-]*-g)([0-9]+)(-([0-9]+))?\.html$ /en/memberlist.php?mode=group&g=$2&start=$4 [QSA,L,NC] +# POST +RewriteRule ^en/post([0-9]+)\.html$ /en/viewtopic.php?p=$1 [QSA,L,NC] +# ACTIVE TOPICS +RewriteRule ^en/active-topics(-([0-9]+))?\.html$ /en/search.php?search_id=active_topics&start=$2&sr=topics [QSA,L,NC] +# UNANSWERED TOPICS +RewriteRule ^en/unanswered(-([0-9]+))?\.html$ /en/search.php?search_id=unanswered&start=$2&sr=topics [QSA,L,NC] +# NEW POSTS +RewriteRule ^en/newposts(-([0-9]+))?\.html$ /en/search.php?search_id=newposts&start=$2&sr=topics [QSA,L,NC] +# UNREAD POSTS +RewriteRule ^en/unreadposts(-([0-9]+))?\.html$ /en/search.php?search_id=unreadposts&start=$2 [QSA,L,NC] +# THE TEAM +RewriteRule ^en/the-team\.html$ /en/memberlist.php?mode=leaders [QSA,L,NC] +# HERE IS A GOOD PLACE TO ADD OTHER PHPBB RELATED REWRITERULES + +# FORUM WITHOUT ID & DELIM ALL MODES +# THESE THREE LINES MUST BE LOCATED AT THE END OF YOUR HTACCESS TO WORK PROPERLY +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^en/([a-z0-9_-]+)/?(page([0-9]+)\.html)?$ /en/viewforum.php?forum_uri=$1&start=$3 [QSA,L,NC] +# FIX RELATIVE PATHS : FILES +RewriteRule ^en/.+/(style\.php|ucp\.php|mcp\.php|faq\.php|download/file.php)$ /en/$1 [QSA,L,NC,R=301] +# FIX RELATIVE PATHS : IMAGES +RewriteRule ^en/.+/(styles/.*|images/.*)/$ /en/$1 [QSA,L,NC,R=301] +# END PHPBB PAGES +##################################################### + diff --git a/phpBB/phpbb_seo/cache/phpbb_cache.php b/phpBB/phpbb_seo/cache/phpbb_cache.php new file mode 100644 index 0000000000..ff7fa5de0c --- /dev/null +++ b/phpBB/phpbb_seo/cache/phpbb_cache.php @@ -0,0 +1,12 @@ +<?php +/** +* phpBB_SEO Class +* www.phpBB-SEO.com +* @package Advanced phpBB3 SEO mod Rewrite +*/ +if (!defined('IN_PHPBB')) { + exit; +} +$this->cache_config['settings'] = array ( 'url_rewrite' => true, 'modrtype' => 2, 'sql_rewrite' => true, 'profile_inj' => true, 'profile_vfolder' => false, 'profile_noids' => true, 'rewrite_usermsg' => false, 'rewrite_files' => true, 'rem_sid' => true, 'rem_hilit' => true, 'rem_small_words' => true, 'virtual_folder' => true, 'virtual_root' => false, 'cache_layer' => true, 'rem_ids' => false, 'copyrights' => array ( 'img' => false, 'txt' => '', 'title' => '', ), 'no_dupe' => array ( 'on' => true, ), 'zero_dupe' => array ( 'on' => true, 'strict' => true, 'post_redir' => 'guest', ), ); +$this->cache_config['forum'] = array ( 2 => 'welcome-board-f2', 6 => 'getting-support-f6', 7 => 'basic-support-f7', 8 => 'advanced-support-f8', 1 => 'the-community-f1', 3 => 'announcements-f3', 4 => 'general-f4', 5 => 'wizards-lair-f5', 9 => 'contributing-f9', 12 => 'basic-contrib-f12', 10 => 'packaging-f10', 11 => 'other-f11', 14 => 'moderation-f14', ); +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/cache/phpbb_cache.php.current b/phpBB/phpbb_seo/cache/phpbb_cache.php.current new file mode 100644 index 0000000000..ff7fa5de0c --- /dev/null +++ b/phpBB/phpbb_seo/cache/phpbb_cache.php.current @@ -0,0 +1,12 @@ +<?php +/** +* phpBB_SEO Class +* www.phpBB-SEO.com +* @package Advanced phpBB3 SEO mod Rewrite +*/ +if (!defined('IN_PHPBB')) { + exit; +} +$this->cache_config['settings'] = array ( 'url_rewrite' => true, 'modrtype' => 2, 'sql_rewrite' => true, 'profile_inj' => true, 'profile_vfolder' => false, 'profile_noids' => true, 'rewrite_usermsg' => false, 'rewrite_files' => true, 'rem_sid' => true, 'rem_hilit' => true, 'rem_small_words' => true, 'virtual_folder' => true, 'virtual_root' => false, 'cache_layer' => true, 'rem_ids' => false, 'copyrights' => array ( 'img' => false, 'txt' => '', 'title' => '', ), 'no_dupe' => array ( 'on' => true, ), 'zero_dupe' => array ( 'on' => true, 'strict' => true, 'post_redir' => 'guest', ), ); +$this->cache_config['forum'] = array ( 2 => 'welcome-board-f2', 6 => 'getting-support-f6', 7 => 'basic-support-f7', 8 => 'advanced-support-f8', 1 => 'the-community-f1', 3 => 'announcements-f3', 4 => 'general-f4', 5 => 'wizards-lair-f5', 9 => 'contributing-f9', 12 => 'basic-contrib-f12', 10 => 'packaging-f10', 11 => 'other-f11', 14 => 'moderation-f14', ); +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/cache/phpbb_cache.php.old b/phpBB/phpbb_seo/cache/phpbb_cache.php.old new file mode 100644 index 0000000000..b9acb750c3 --- /dev/null +++ b/phpBB/phpbb_seo/cache/phpbb_cache.php.old @@ -0,0 +1,12 @@ +<?php +/** +* phpBB_SEO Class +* www.phpBB-SEO.com +* @package Advanced phpBB3 SEO mod Rewrite +*/ +if (!defined('IN_PHPBB')) { + exit; +} +$this->cache_config['settings'] = array ( 'url_rewrite' => true, 'modrtype' => 2, 'sql_rewrite' => true, 'profile_inj' => true, 'profile_vfolder' => false, 'profile_noids' => true, 'rewrite_usermsg' => false, 'rewrite_files' => true, 'rem_sid' => true, 'rem_hilit' => true, 'rem_small_words' => true, 'virtual_folder' => true, 'virtual_root' => false, 'cache_layer' => true, 'rem_ids' => false, 'copyrights' => array ( 'img' => false, 'txt' => '', 'title' => '', ), 'no_dupe' => array ( 'on' => true, ), 'zero_dupe' => array ( 'on' => true, 'strict' => true, 'post_redir' => 'guest', ), ); +$this->cache_config['forum'] = array ( 2 => 'welcome-board-f2', 6 => 'getting-support-f6', 7 => 'basic-support-f7', 8 => 'advanced-support-f8', 1 => 'the-community-f1', 3 => 'announcements-f3', 4 => 'general-f4', 5 => 'wizards-lair-f5', 9 => 'contributing-f9', 12 => 'basic-contribution-f12', 10 => 'packaging-translating-f10', 11 => 'other-f11', 14 => 'moderation-f14', ); +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/docs/COPYING b/phpBB/phpbb_seo/docs/COPYING new file mode 100644 index 0000000000..c22a73c5db --- /dev/null +++ b/phpBB/phpbb_seo/docs/COPYING @@ -0,0 +1,545 @@ +Reciprocal Public License 1.5 (RPL1.5) +[OSI Approved License] + +Reciprocal Public License (RPL) + +Version 1.5, July 15, 2007 + +Copyright (C) 2001-2007 +Technical Pursuit Inc., +All Rights Reserved. + +PREAMBLE + +The Reciprocal Public License (RPL) is based on the concept of reciprocity or, +if you prefer, fairness. + +In short, this license grew out of a desire to close loopholes in previous open +source licenses, loopholes that allowed parties to acquire open source software +and derive financial benefit from it without having to release their +improvements or derivatives to the community which enabled them. This occurred +any time an entity did not release their application to a "third party". + +While there is a certain freedom in this model of licensing, it struck the +authors of the RPL as being unfair to the open source community at large and to +the original authors of the works in particular. After all, bug fixes, +extensions, and meaningful and valuable derivatives were not consistently +finding their way back into the community where they could fuel further, and +faster, growth and expansion of the overall open source software base. + +While you should clearly read and understand the entire license, the essence of +the RPL is found in two definitions: "Deploy" and "Required Components". + +Regarding deployment, under the RPL your changes, bug fixes, extensions, etc. +must be made available to the open source community at large when you Deploy in +any form -- either internally or to an outside party. Once you start running +the software you have to start sharing the software. + +Further, under the RPL all components you author including schemas, scripts, +source code, etc. -- regardless of whether they're compiled into a single +binary or used as two halves of client/server application -- must be shared. +You have to share the whole pie, not an isolated slice of it. + +In addition to these goals, the RPL was authored to meet the requirements of +the Open Source Definition as maintained by the Open Source Initiative (OSI). + +The specific terms and conditions of the license are defined in the remainder +of this document. + +LICENSE TERMS + +1.0 General; Applicability & Definitions. This Reciprocal Public License +Version 1.5 ("License") applies to any programs or other works as well as any +and all updates or maintenance releases of said programs or works ("Software") +not already covered by this License which the Software copyright holder +("Licensor") makes available containing a License Notice (hereinafter defined) +from the Licensor specifying or allowing use or distribution under the terms of +this License. As used in this License: + +1.1 "Contributor" means any person or entity who created or contributed to the +creation of an Extension. + +1.2 "Deploy" means to use, Serve, sublicense or distribute Licensed Software +other than for Your internal Research and/or Personal Use, and includes +without limitation, any and all internal use or distribution of Licensed +Software within Your business or organization other than for Research and/or +Personal Use, as well as direct or indirect sublicensing or distribution of +Licensed Software by You to any third party in any form or manner. + +1.3 "Derivative Works" as used in this License is defined under U.S. copyright +law. + +1.4 "Electronic Distribution Mechanism" means a mechanism generally accepted +in the software development community for the electronic transfer of data such +as download from an FTP server or web site, where such mechanism is publicly +accessible. + +1.5 "Extensions" means any Modifications, Derivative Works, or Required +Components as those terms are defined in this License. + +1.6 "License" means this Reciprocal Public License. + +1.7 "License Notice" means any notice contained in EXHIBIT A. + +1.8 "Licensed Software" means any Software licensed pursuant to this License. +Licensed Software also includes all previous Extensions from any Contributor +that You receive. + +1.9 "Licensor" means the copyright holder of any Software previously not +covered by this License who releases the Software under the terms of this +License. + +1.10 "Modifications" means any additions to or deletions from the substance or +structure of (i) a file or other storage containing Licensed Software, or (ii) +any new file or storage that contains any part of Licensed Software, or (iii) +any file or storage which replaces or otherwise alters the original +functionality of Licensed Software at runtime. + +1.11 "Personal Use" means use of Licensed Software by an individual solely for +his or her personal, private and non-commercial purposes. An individual's use +of Licensed Software in his or her capacity as an officer, employee, member, +independent contractor or agent of a corporation, business or organization +(commercial or non-commercial) does not qualify as Personal Use. + +1.12 "Required Components" means any text, programs, scripts, schema, +interface definitions, control files, or other works created by You which are +required by a third party of average skill to successfully install and run +Licensed Software containing Your Modifications, or to install and run Your +Derivative Works. + +1.13 "Research" means investigation or experimentation for the purpose of +understanding the nature and limits of the Licensed Software and its potential +uses. + +1.14 "Serve" means to deliver Licensed Software and/or Your Extensions by +means of a computer network to one or more computers for purposes of execution +of Licensed Software and/or Your Extensions. + +1.15 "Software" means any computer programs or other works as well as any +updates or maintenance releases of those programs or works which are +distributed publicly by Licensor. + +1.16 "Source Code" means the preferred form for making modifications to the +Licensed Software and/or Your Extensions, including all modules contained +therein, plus any associated text, interface definition files, scripts used to +control compilation and installation of an executable program or other +components required by a third party of average skill to build a running +version of the Licensed Software or Your Extensions. + +1.17 "User-Visible Attribution Notice" means any notice contained in EXHIBIT B. + +1.18 "You" or "Your" means an individual or a legal entity exercising rights +under this License. For legal entities, "You" or "Your" includes any entity +which controls, is controlled by, or is under common control with, You, where +"control" means (a) the power, direct or indirect, to cause the direction or +management of such entity, whether by contract or otherwise, or (b) ownership +of fifty percent (50%) or more of the outstanding shares or beneficial +ownership of such entity. + +2.0 Acceptance Of License. You are not required to accept this License since +you have not signed it, however nothing else grants you permission to use, +copy, distribute, modify, or create derivatives of either the Software or any +Extensions created by a Contributor. These actions are prohibited by law if +you do not accept this License. Therefore, by performing any of these actions +You indicate Your acceptance of this License and Your agreement to be bound by +all its terms and conditions. IF YOU DO NOT AGREE WITH ALL THE TERMS AND +CONDITIONS OF THIS LICENSE DO NOT USE, MODIFY, CREATE DERIVATIVES, OR +DISTRIBUTE THE SOFTWARE. IF IT IS IMPOSSIBLE FOR YOU TO COMPLY WITH ALL THE +TERMS AND CONDITIONS OF THIS LICENSE THEN YOU CAN NOT USE, MODIFY, CREATE +DERIVATIVES, OR DISTRIBUTE THE SOFTWARE. + +3.0 Grant of License From Licensor. Subject to the terms and conditions of +this License, Licensor hereby grants You a world-wide, royalty-free, non- +exclusive license, subject to Licensor's intellectual property rights, and any +third party intellectual property claims derived from the Licensed Software +under this License, to do the following: + +3.1 Use, reproduce, modify, display, perform, sublicense and distribute +Licensed Software and Your Extensions in both Source Code form or as an +executable program. + +3.2 Create Derivative Works (as that term is defined under U.S. copyright law) +of Licensed Software by adding to or deleting from the substance or structure +of said Licensed Software. + +3.3 Under claims of patents now or hereafter owned or controlled by Licensor, +to make, use, have made, and/or otherwise dispose of Licensed Software or +portions thereof, but solely to the extent that any such claim is necessary to +enable You to make, use, have made, and/or otherwise dispose of Licensed +Software or portions thereof. + +3.4 Licensor reserves the right to release new versions of the Software with +different features, specifications, capabilities, functions, licensing terms, +general availability or other characteristics. Title, ownership rights, and +intellectual property rights in and to the Licensed Software shall remain in +Licensor and/or its Contributors. + +4.0 Grant of License From Contributor. By application of the provisions in +Section 6 below, each Contributor hereby grants You a world-wide, royalty- +free, non-exclusive license, subject to said Contributor's intellectual +property rights, and any third party intellectual property claims derived from +the Licensed Software under this License, to do the following: + +4.1 Use, reproduce, modify, display, perform, sublicense and distribute any +Extensions Deployed by such Contributor or portions thereof, in both Source +Code form or as an executable program, either on an unmodified basis or as +part of Derivative Works. + +4.2 Under claims of patents now or hereafter owned or controlled by +Contributor, to make, use, have made, and/or otherwise dispose of Extensions +or portions thereof, but solely to the extent that any such claim is necessary +to enable You to make, use, have made, and/or otherwise dispose of +Licensed Software or portions thereof. + +5.0 Exclusions From License Grant. Nothing in this License shall be deemed to +grant any rights to trademarks, copyrights, patents, trade secrets or any +other intellectual property of Licensor or any Contributor except as expressly +stated herein. Except as expressly stated in Sections 3 and 4, no other patent +rights, express or implied, are granted herein. Your Extensions may require +additional patent licenses from Licensor or Contributors which each may grant +in its sole discretion. No right is granted to the trademarks of Licensor or +any Contributor even if such marks are included in the Licensed Software. +Nothing in this License shall be interpreted to prohibit Licensor from +licensing under different terms from this License any code that Licensor +otherwise would have a right to license. + +5.1 You expressly acknowledge and agree that although Licensor and each +Contributor grants the licenses to their respective portions of the Licensed +Software set forth herein, no assurances are provided by Licensor or any +Contributor that the Licensed Software does not infringe the patent or other +intellectual property rights of any other entity. Licensor and each +Contributor disclaim any liability to You for claims brought by any other +entity based on infringement of intellectual property rights or otherwise. As +a condition to exercising the rights and licenses granted hereunder, You +hereby assume sole responsibility to secure any other intellectual property +rights needed, if any. For example, if a third party patent license is +required to allow You to distribute the Licensed Software, it is Your +responsibility to acquire that license before distributing the Licensed +Software. + +6.0 Your Obligations And Grants. In consideration of, and as an express +condition to, the licenses granted to You under this License You hereby agree +that any Modifications, Derivative Works, or Required Components (collectively +Extensions) that You create or to which You contribute are governed by the +terms of this License including, without limitation, Section 4. Any Extensions +that You create or to which You contribute must be Deployed under the terms of +this License or a future version of this License released under Section 7. You +hereby grant to Licensor and all third parties a world-wide, non-exclusive, +royalty-free license under those intellectual property rights You own or +control to use, reproduce, display, perform, modify, create derivatives, +sublicense, and distribute Licensed Software, in any form. Any Extensions You +make and Deploy must have a distinct title so as to readily tell any +subsequent user or Contributor that the Extensions are by You. You must +include a copy of this License or directions on how to obtain a copy with +every copy of the Extensions You distribute. You agree not to offer or impose +any terms on any Source Code or executable version of the Licensed Software, +or its Extensions that alter or restrict the applicable version of this +License or the recipients' rights hereunder. + +6.1 Availability of Source Code. You must make available, under the terms of +this License, the Source Code of any Extensions that You Deploy, via an +Electronic Distribution Mechanism. The Source Code for any version that You +Deploy must be made available within one (1) month of when you Deploy and must +remain available for no less than twelve (12) months after the date You cease +to Deploy. You are responsible for ensuring that the Source Code to each +version You Deploy remains available even if the Electronic Distribution +Mechanism is maintained by a third party. You may not charge a fee for any +copy of the Source Code distributed under this Section in excess of Your +actual cost of duplication and distribution of said copy. + +6.2 Description of Modifications. You must cause any Modifications that You +create or to which You contribute to be documented in the Source Code, clearly +describing the additions, changes or deletions You made. You must include a +prominent statement that the Modifications are derived, directly or indirectly, +from the Licensed Software and include the names of the Licensor and any +Contributor to the Licensed Software in (i) the Source Code and (ii) in any +notice displayed by the Licensed Software You distribute or in related +documentation in which You describe the origin or ownership of the Licensed +Software. You may not modify or delete any pre-existing copyright notices, +change notices or License text in the Licensed Software without written +permission of the respective Licensor or Contributor. + +6.3 Intellectual Property Matters. + +a. Third Party Claims. If You have knowledge that a license to a third party's +intellectual property right is required to exercise the rights granted by this +License, You must include a human-readable file with Your distribution that +describes the claim and the party making the claim in sufficient detail that a +recipient will know whom to contact. + +b. Contributor APIs. If Your Extensions include an application programming +interface ("API") and You have knowledge of patent licenses that are +reasonably necessary to implement that API, You must also include this +information in a human-readable file supplied with Your distribution. + +c. Representations. You represent that, except as disclosed pursuant to 6.3(a) +above, You believe that any Extensions You distribute are Your original +creations and that You have sufficient rights to grant the rights conveyed by +this License. + +6.4 Required Notices. + +a. License Text. You must duplicate this License or instructions on how to +acquire a copy in any documentation You provide along with the Source Code of +any Extensions You create or to which You contribute, wherever You describe +recipients' rights relating to Licensed Software. + +b. License Notice. You must duplicate any notice contained in EXHIBIT A (the +"License Notice") in each file of the Source Code of any copy You distribute +of the Licensed Software and Your Extensions. If You create an Extension, You +may add Your name as a Contributor to the Source Code and accompanying +documentation along with a description of the contribution. If it is not +possible to put the License Notice in a particular Source Code file due to its +structure, then You must include such License Notice in a location where a +user would be likely to look for such a notice. + +c. Source Code Availability. You must notify the software community of the +availability of Source Code to Your Extensions within one (1) month of the date +You initially Deploy and include in such notification a description of the +Extensions, and instructions on how to acquire the Source Code. Should such +instructions change you must notify the software community of revised +instructions within one (1) month of the date of change. You must provide +notification by posting to appropriate news groups, mailing lists, weblogs, or +other sites where a publicly accessible search engine would reasonably be +expected to index your post in relationship to queries regarding the Licensed +Software and/or Your Extensions. + +d. User-Visible Attribution. You must duplicate any notice contained in +EXHIBIT B (the "User-Visible Attribution Notice") in each user-visible display +of the Licensed Software and Your Extensions which delineates copyright, +ownership, or similar attribution information. If You create an Extension, +You may add Your name as a Contributor, and add Your attribution notice, as an +equally visible and functional element of any User-Visible Attribution Notice +content. To ensure proper attribution, You must also include such User-Visible +Attribution Notice in at least one location in the Software documentation +where a user would be likely to look for such notice. + +6.5 Additional Terms. You may choose to offer, and charge a fee for, warranty, +support, indemnity or liability obligations to one or more recipients of +Licensed Software. However, You may do so only on Your own behalf, and not on +behalf of the Licensor or any Contributor except as permitted under other +agreements between you and Licensor or Contributor. You must make it clear that +any such warranty, support, indemnity or liability obligation is offered by You +alone, and You hereby agree to indemnify the Licensor and every Contributor for +any liability plus attorney fees, costs, and related expenses due to any such +action or claim incurred by the Licensor or such Contributor as a result of +warranty, support, indemnity or liability terms You offer. + +6.6 Conflicts With Other Licenses. Where any portion of Your Extensions, by +virtue of being Derivative Works of another product or similar circumstance, +fall under the terms of another license, the terms of that license should be +honored however You must also make Your Extensions available under this +License. If the terms of this License continue to conflict with the terms of +the other license you may write the Licensor for permission to resolve the +conflict in a fashion that remains consistent with the intent of this License. +Such permission will be granted at the sole discretion of the Licensor. + +7.0 Versions of This License. Licensor may publish from time to time revised +versions of the License. Once Licensed Software has been published under a +particular version of the License, You may always continue to use it under the +terms of that version. You may also choose to use such Licensed Software under +the terms of any subsequent version of the License published by Licensor. No +one other than Licensor has the right to modify the terms applicable to +Licensed Software created under this License. + +7.1 If You create or use a modified version of this License, which You may do +only in order to apply it to software that is not already Licensed Software +under this License, You must rename Your license so that it is not confusingly +similar to this License, and must make it clear that Your license contains +terms that differ from this License. In so naming Your license, You may not +use any trademark of Licensor or of any Contributor. Should Your modifications +to this License be limited to alteration of a) Section 13.8 solely to modify +the legal Jurisdiction or Venue for disputes, b) EXHIBIT A solely to define +License Notice text, or c) to EXHIBIT B solely to define a User-Visible +Attribution Notice, You may continue to refer to Your License as the +Reciprocal Public License or simply the RPL. + +8.0 Disclaimer of Warranty. LICENSED SOFTWARE IS PROVIDED UNDER THIS LICENSE +ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE LICENSED SOFTWARE IS FREE +OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. +FURTHER THERE IS NO WARRANTY MADE AND ALL IMPLIED WARRANTIES ARE DISCLAIMED +THAT THE LICENSED SOFTWARE MEETS OR COMPLIES WITH ANY DESCRIPTION OF +PERFORMANCE OR OPERATION, SAID COMPATIBILITY AND SUITABILITY BEING YOUR +RESPONSIBILITY. LICENSOR DISCLAIMS ANY WARRANTY, IMPLIED OR EXPRESSED, THAT +ANY CONTRIBUTOR'S EXTENSIONS MEET ANY STANDARD OF COMPATIBILITY OR DESCRIPTION +OF PERFORMANCE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LICENSED SOFTWARE IS WITH YOU. SHOULD LICENSED SOFTWARE PROVE DEFECTIVE IN ANY +RESPECT, YOU (AND NOT THE LICENSOR OR ANY OTHER CONTRIBUTOR) ASSUME THE COST +OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. UNDER THE TERMS OF THIS +LICENSOR WILL NOT SUPPORT THIS SOFTWARE AND IS UNDER NO OBLIGATION TO ISSUE +UPDATES TO THIS SOFTWARE. LICENSOR HAS NO KNOWLEDGE OF ERRANT CODE OR VIRUS IN +THIS SOFTWARE, BUT DOES NOT WARRANT THAT THE SOFTWARE IS FREE FROM SUCH ERRORS +OR VIRUSES. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS +LICENSE. NO USE OF LICENSED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS +DISCLAIMER. + +9.0 Limitation of Liability. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, +WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE +LICENSOR, ANY CONTRIBUTOR, OR ANY DISTRIBUTOR OF LICENSED SOFTWARE, OR ANY +SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, +WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER +FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, +EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH +DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH +OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT +APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE +EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS +EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10.0 High Risk Activities. THE LICENSED SOFTWARE IS NOT FAULT-TOLERANT AND IS +NOT DESIGNED, MANUFACTURED, OR INTENDED FOR USE OR DISTRIBUTION AS ON-LINE +CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE PERFORMANCE, +SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT NAVIGATION OR +COMMUNICATIONS SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE SUPPORT MACHINES, OR +WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE LICENSED SOFTWARE COULD LEAD +DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE +("HIGH RISK ACTIVITIES"). LICENSOR AND CONTRIBUTORS SPECIFICALLY DISCLAIM ANY +EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + +11.0 Responsibility for Claims. As between Licensor and Contributors, each +party is responsible for claims and damages arising, directly or indirectly, +out of its utilization of rights under this License which specifically +disclaims warranties and limits any liability of the Licensor. This paragraph +is to be used in conjunction with and controlled by the Disclaimer Of +Warranties of Section 8, the Limitation Of Damages in Section 9, and the +disclaimer against use for High Risk Activities in Section 10. The Licensor +has thereby disclaimed all warranties and limited any damages that it is or +may be liable for. You agree to work with Licensor and Contributors to +distribute such responsibility on an equitable basis consistent with the terms +of this License including Sections 8, 9, and 10. Nothing herein is intended or +shall be deemed to constitute any admission of liability. + +12.0 Termination. This License and all rights granted hereunder will terminate +immediately in the event of the circumstances described in Section 13.6 or if +applicable law prohibits or restricts You from fully and or specifically +complying with Sections 3, 4 and/or 6, or prevents the enforceability of any +of those Sections, and You must immediately discontinue any use of Licensed +Software. + +12.1 Automatic Termination Upon Breach. This License and the rights granted +hereunder will terminate automatically if You fail to comply with the terms +herein and fail to cure such breach within thirty (30) days of becoming aware +of the breach. All sublicenses to the Licensed Software that are properly +granted shall survive any termination of this License. Provisions that, by +their nature, must remain in effect beyond the termination of this License, +shall survive. + +12.2 Termination Upon Assertion of Patent Infringement. If You initiate +litigation by asserting a patent infringement claim (excluding declaratory +judgment actions) against Licensor or a Contributor (Licensor or Contributor +against whom You file such an action is referred to herein as "Respondent") +alleging that Licensed Software directly or indirectly infringes any patent, +then any and all rights granted by such Respondent to You under Sections 3 or +4 of this License shall terminate prospectively upon sixty (60) days notice +from Respondent (the "Notice Period") unless within that Notice Period You +either agree in writing (i) to pay Respondent a mutually agreeable reasonably +royalty for Your past or future use of Licensed Software made by such +Respondent, or (ii) withdraw Your litigation claim with respect to Licensed +Software against such Respondent. If within said Notice Period a reasonable +royalty and payment arrangement are not mutually agreed upon in writing by the +parties or the litigation claim is not withdrawn, the rights granted by +Licensor to You under Sections 3 and 4 automatically terminate at the +expiration of said Notice Period. + +12.3 Reasonable Value of This License. If You assert a patent infringement +claim against Respondent alleging that Licensed Software directly or +indirectly infringes any patent where such claim is resolved (such as by +license or settlement) prior to the initiation of patent infringement +litigation, then the reasonable value of the licenses granted by said +Respondent under Sections 3 and 4 shall be taken into account in determining +the amount or value of any payment or license. + +12.4 No Retroactive Effect of Termination. In the event of termination under +this Section all end user license agreements (excluding licenses to +distributors and resellers) that have been validly granted by You or any +distributor hereunder prior to termination shall survive termination. + +13.0 Miscellaneous. + +13.1 U.S. Government End Users. The Licensed Software is a "commercial item," +as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of +"commercial computer software" and "commercial computer software +documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). +Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 +(June 1995), all U.S. Government End Users acquire Licensed Software with only +those rights set forth herein. + +13.2 Relationship of Parties. This License will not be construed as creating +an agency, partnership, joint venture, or any other form of legal association +between or among You, Licensor, or any Contributor, and You will not represent +to the contrary, whether expressly, by implication, appearance, or otherwise. + +13.3 Independent Development. Nothing in this License will impair Licensor's +right to acquire, license, develop, subcontract, market, or distribute +technology or products that perform the same or similar functions as, or +otherwise compete with, Extensions that You may develop, produce, market, or +distribute. + +13.4 Consent To Breach Not Waiver. Failure by Licensor or Contributor to +enforce any provision of this License will not be deemed a waiver of future enforcement +of that or any other provision. + +13.5 Severability. This License represents the complete agreement concerning +the subject matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent necessary +to make it enforceable. + +13.6 Inability to Comply Due to Statute or Regulation. If it is impossible for +You to comply with any of the terms of this License with respect to some or +all of the Licensed Software due to statute, judicial order, or regulation, +then You cannot use, modify, or distribute the software. + +13.7 Export Restrictions. You may be restricted with respect to downloading or +otherwise acquiring, exporting, or reexporting the Licensed Software or any +underlying information or technology by United States and other applicable +laws and regulations. By downloading or by otherwise obtaining the Licensed +Software, You are agreeing to be responsible for compliance with all +applicable laws and regulations. + +13.8 Arbitration, Jurisdiction & Venue. This License shall be governed by +Colorado law provisions (except to the extent applicable law, if any, provides +otherwise), excluding its conflict-of-law provisions. You expressly agree that +any dispute relating to this License shall be submitted to binding arbitration +under the rules then prevailing of the American Arbitration Association. You +further agree that Adams County, Colorado USA is proper venue and grant such +arbitration proceeding jurisdiction as may be appropriate for purposes of +resolving any dispute under this License. Judgement upon any award made in +arbitration may be entered and enforced in any court of competent +jurisdiction. The arbitrator shall award attorney's fees and costs of +arbitration to the prevailing party. Should either party find it necessary to +enforce its arbitration award or seek specific performance of such award in a +civil court of competent jurisdiction, the prevailing party shall be entitled +to reasonable attorney's fees and costs. The application of the United Nations +Convention on Contracts for the International Sale of Goods is expressly +excluded. You and Licensor expressly waive any rights to a jury trial in any +litigation concerning Licensed Software or this License. Any law or regulation +that provides that the language of a contract shall be construed against the +drafter shall not apply to this License. + +13.9 Entire Agreement. This License constitutes the entire agreement between +the parties with respect to the subject matter hereof. + +EXHIBIT A + +The License Notice below must appear in each file of the Source Code of any +copy You distribute of the Licensed Software or any Extensions thereto: + +Unless explicitly acquired and licensed from Licensor under another +license, the contents of this file are subject to the Reciprocal Public +License ("RPL") Version 1.5, or subsequent versions as allowed by the RPL, +and You may not copy or use this file in either source code or executable +form, except in compliance with the terms and conditions of the RPL. + +All software distributed under the RPL is provided strictly on an "AS +IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND +LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT +LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the RPL for specific +language governing rights and limitations under the RPL. + +EXHIBIT B + +The User-Visible Attribution Notice below, when provided, must appear in each +user-visible display as defined in Section 6.4 (d): diff --git a/phpBB/phpbb_seo/includes/.htaccess b/phpBB/phpbb_seo/includes/.htaccess new file mode 100644 index 0000000000..aa5afc1640 --- /dev/null +++ b/phpBB/phpbb_seo/includes/.htaccess @@ -0,0 +1,4 @@ +<Files *> + Order Allow,Deny + Deny from All +</Files>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/includes/setup_phpbb_seo.php b/phpBB/phpbb_seo/includes/setup_phpbb_seo.php new file mode 100644 index 0000000000..f7ace88291 --- /dev/null +++ b/phpBB/phpbb_seo/includes/setup_phpbb_seo.php @@ -0,0 +1,262 @@ +<?php +/** +* +* @package Ultimate SEO URL phpBB SEO +* @version $Id: setup_phpbb_seo.php 262 2010-04-20 11:06:58Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://www.opensource.org/licenses/rpl1.5.txt Reciprocal Public License 1.5 +* +*/ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) { + exit; +} +/** +* setup_phpbb_seo Class +* www.phpBB-SEO.com +* @package Ultimate SEO URL phpBB SEO +*/ +class setup_phpbb_seo { + /** + * Do the init + */ + function init_phpbb_seo() { + global $phpEx, $config, $phpbb_root_path; + // --> No Dupe + $this->seo_opt['no_dupe']['on'] = $this->cache_config['dynamic_options']['no_dupe']['on'] = false; + // <-- No Dupe + // --> Zero Dupe + $this->seo_opt['zero_dupe'] = array( 'on' => false, // Activate or not the redirections : true / false + 'strict' => false, // strict compare, == VS strpos() : true / false + 'post_redir' => 'guest', // Redirect post urls if not valid ? : guest / all / post / off + ); + $this->cache_config['dynamic_options']['zero_dupe'] = $this->seo_opt['zero_dupe']; // Do not change + $this->seo_opt['zero_dupe']['do_redir'] = false; // do not change + $this->seo_opt['zero_dupe']['go_redir'] = true; // do not change + $this->seo_opt['zero_dupe']['do_redir_post'] = false; // do not change + $this->seo_opt['zero_dupe']['start'] = 0; // do not change + $this->seo_opt['zero_dupe']['redir_def'] = array(); // do not change + // <-- Zero Dupe + // Let's load config and forum urls, mods adding options in the cache file must do it before + if ($this->check_cache()) { + foreach($this->cache_config['dynamic_options'] as $optionname => $optionvalue ) { + if (@is_array($this->cache_config['settings'][$optionname])) { + $this->seo_opt[$optionname] = array_merge($this->seo_opt[$optionname], $this->cache_config['settings'][$optionname]); + } elseif ( @isset($this->cache_config['settings'][$optionvalue]) ) { + $this->seo_opt[$optionvalue] = $this->cache_config['settings'][$optionvalue]; + } + } + $this->modrtype = @isset($this->seo_opt['modrtype']) ? $this->seo_opt['modrtype'] : $this->modrtype; + if ( $this->modrtype > 1 ) { // Load cached URLs + $this->seo_url['forum'] =& $this->cache_config['forum']; + } + } + // ====> here starts the add-on and custom set up <==== + + // ===> Custom url replacements <=== + // Here you can set up custom replacements to be used in title injection. + // Example : array( 'find' => 'replace') + // $this->url_replace = array( + // // Purely cosmetic replace + // '$' => 'dollar', '€' => 'euro', + // '\'s' => 's', // it's => its / mary's => marys ... + // // Language specific replace (German example) + // 'ß' => 'ss', + // 'Ä' => 'Ae', 'ä' => 'ae', + // 'Ö' => 'Oe', 'ö' => 'oe', + // 'Ü' => 'Ue', 'ü' => 'ue', + // ); + + // ===> Custom values Delimiters, Static parts and Suffixes <=== + // ==> Delimiters <== + // Can be overridden, requires .htaccess update <= + // Example : + // $this->seo_delim['forum'] = '-mydelim'; // instead of the default "-f" + + // ==> Static parts <== + // Can be overridden, requires .htaccess update. + // Example : + // $this->seo_static['post'] = 'message'; // instead of the default "post" + // !! phpBB files must be treated a bit differently !! + // Example : + // $this->seo_static['file'][ATTACHMENT_CATEGORY_QUICKTIME] = 'quicktime'; // instead of the default "qt" + // $this->seo_static['file_index'] = 'my_files_virtual_dir'; // instead of the default "resources" + + // ==> Suffixes <== + // Can be overridden, requires .htaccess update <= + // Example : + // $this->seo_ext['topic'] = '/'; // instead of the default ".html" + + // ==> Special for lazy French, others may delete this part + if ( strpos($config['default_lang'], 'fr') !== false ) { + $this->seo_static['user'] = 'membre'; + $this->seo_static['group'] = 'groupe'; + $this->seo_static['global_announce'] = 'annonces'; + $this->seo_static['leaders'] = 'equipe'; + $this->seo_static['atopic'] = 'sujets-actifs'; + $this->seo_static['utopic'] = 'sans-reponses'; + $this->seo_static['npost'] = 'nouveaux-messages'; + $this->seo_static['urpost'] = 'non-lu'; + $this->seo_static['file_index'] = 'ressources'; + } + // <== Special for lazy French, others may delete this part + + // Let's make sure that settings are consistent + $this->check_config(); + } + // Here start the add-on methods + // --> Zero Duplicate + /** + * Custom HTTP 301 redirections. + * To kill duplicates + */ + function seo_redirect($url, $header = '301 Moved Permanently', $code = 301, $replace = true) { + global $db; + if (!$this->seo_opt['zero_dupe']['on'] || @headers_sent()) { + return false; + } + garbage_collection(); + $url = str_replace('&', '&', $url); + // Behave as redirect() for checks to provide with the same level of protection + // Make sure no linebreaks are there... to prevent http response splitting for PHP < 4.4.2 + if (strpos(urldecode($url), "\n") !== false || strpos(urldecode($url), "\r") !== false || strpos($url, ';') !== false) { + trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR); + } + // Now, also check the protocol and for a valid url the last time... + $allowed_protocols = array('http', 'https'/*, 'ftp', 'ftps'*/); + $url_parts = parse_url($url); + if ($url_parts === false || empty($url_parts['scheme']) || !in_array($url_parts['scheme'], $allowed_protocols)) { + trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR); + } + $http = 'HTTP/1.1 '; + header($http . $header, $replace, $code); + header('Location: ' . $url); + exit_handler(); + } + /** + * Set the do_redir_post option right + */ + function set_do_redir_post() { + global $user; + switch ($this->seo_opt['zero_dupe']['post_redir']) { + case 'guest': + if ( empty($user->data['is_registered']) ) { + $this->seo_opt['zero_dupe']['do_redir_post'] = true; + } + break; + case 'all': + $this->seo_opt['zero_dupe']['do_redir_post'] = true; + break; + case 'off': // Do not redirect + $this->seo_opt['zero_dupe']['do_redir'] = false; + $this->seo_opt['zero_dupe']['go_redir'] = false; + $this->seo_opt['zero_dupe']['do_redir_post'] = false; + break; + default: + $this->seo_opt['zero_dupe']['do_redir_post'] = false; + break; + } + return $this->seo_opt['zero_dupe']['do_redir_post']; + } + /** + * Redirects if the uri sent does not match (fully) the + * attended url + */ + function seo_chk_dupe($url = '', $uri = '', $path = '') { + global $auth, $user, $_SID, $phpbb_root_path, $config; + if (empty($this->seo_opt['req_file']) || (!$this->seo_opt['rewrite_usermsg'] && $this->seo_opt['req_file'] == 'search') ) { + return false; + } + if (!empty($_REQUEST['explain']) && (boolean) ($auth->acl_get('a_') && defined('DEBUG_EXTRA'))) { + if ($_REQUEST['explain'] == 1) { + return true; + } + } + $path = empty($path) ? $phpbb_root_path : $path; + $uri = !empty($uri) ? $uri : $this->seo_path['uri']; + $reg = !empty($user->data['is_registered']) ? true : false; + $url = empty($url) ? $this->expected_url($path) : str_replace('&', '&', append_sid($url, false, true, 0)); + $url = $this->drop_sid($url); + // Only add sid if user is registered and needs it to keep session + if (!empty($_GET['sid']) && !empty($_SID) && ($reg || !$this->seo_opt['rem_sid']) ) { + if ($_GET['sid'] == $user->session_id) { + $url .= (utf8_strpos( $url, '?' ) !== false ? '&' : '?') . 'sid=' . $user->session_id; + } + } + $url = str_replace( '%26', '&', urldecode($url)); + if ($this->seo_opt['zero_dupe']['do_redir']) { + $this->seo_redirect($url); + } else { + $url_check = $url; + // we remove url hash for comparison, but keep it for redirect + if (strpos($url, '#') !== false) { + list($url_check, $hash) = explode('#', $url, 2); + } + if ($this->seo_opt['zero_dupe']['strict']) { + return $this->seo_opt['zero_dupe']['go_redir'] && ( ($uri != $url_check) ? $this->seo_redirect($url) : false ); + } else { + return $this->seo_opt['zero_dupe']['go_redir'] && ( (utf8_strpos( $uri, $url_check ) === false) ? $this->seo_redirect($url) : false ); + } + } + } + /** + * expected_url($path = '') + * build expected url + */ + function expected_url($path = '') { + global $phpbb_root_path, $phpEx; + $path = empty($path) ? $phpbb_root_path : $path; + $params = array(); + foreach ($this->seo_opt['zero_dupe']['redir_def'] as $get => $def) { + if ((isset($_GET[$get]) && $def['keep']) || !empty($def['force'])) { + $params[$get] = $def['val']; + if (!empty($def['hash'])) { + $params['#'] = $def['hash']; + } + } + } + $this->page_url = append_sid($path . $this->seo_opt['req_file'] . ".$phpEx", $params, false, 0); + return $this->page_url; + } + /** + * set_cond($bool, $type = 'bool_redir', $or = true) + * Helps out grabbing boolean vars + */ + function set_cond($bool, $type = 'do_redir', $or = true) { + if ( $or ) { + $this->seo_opt['zero_dupe'][$type] = (boolean) ($bool || $this->seo_opt['zero_dupe'][$type]); + } else { + $this->seo_opt['zero_dupe'][$type] = (boolean) ($bool && $this->seo_opt['zero_dupe'][$type]); + } + return; + } + /** + * check start var consistency + * Returns our best guess for $start, eg the first valid page + */ + function seo_chk_start($start = 0, $limit = 0) { + if ($limit > 0) { + $start = is_int($start/$limit) ? $start : intval($start/$limit)*$limit; + } + if ( $start >= 1 ) { + $this->start = $this->seo_delim['start'] . (int) $start; + return (int) $start; + } + $this->start = ''; + return 0; + } + /** + * get_canonical + * Returns the canonical url if ever built + * Beware with ssl : + * Since we want zero duplicate, the canonical element will only use https when ssl is forced + * (eg set as THE server protocol in config) and will use http in other cases. + */ + function get_canonical() { + return $this->sslify($this->seo_path['canonical'], $this->ssl['forced'], true); + } + // <-- Zero Duplicate +} +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/phpbb_seo_class.php b/phpBB/phpbb_seo/phpbb_seo_class.php new file mode 100644 index 0000000000..63955467b6 --- /dev/null +++ b/phpBB/phpbb_seo/phpbb_seo_class.php @@ -0,0 +1,886 @@ +<?php +/** +* +* @package Ultimate SEO URL phpBB SEO +* @version $Id: phpbb_seo_class.php 277 2010-11-25 12:09:02Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://www.opensource.org/licenses/rpl1.5.txt Reciprocal Public License 1.5 +* +*/ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) { + exit; +} +require($phpbb_root_path . "phpbb_seo/includes/setup_phpbb_seo.$phpEx"); +/** +* phpBB_SEO Class +* www.phpBB-SEO.com +* @package Ultimate SEO URL phpBB SEO +*/ +class phpbb_seo extends setup_phpbb_seo { + var $version = '0.6.6'; + var $modrtype = 2; // We set it to mixed as a default value + var $seo_path = array(); + var $seo_url = array( 'forum' => array(), 'topic' => array(), 'user' => array(), 'username' => array(), 'group' => array(), 'file' => array() ); + var $phpbb_filter = array( + 'forum' => array('st' => 0, 'sk' => 't', 'sd' => 'd'), + 'topic' => array('st' => 0, 'sk' => 't', 'sd' => 'a', 'hilit' => ''), + 'search' => array('st' => 0, 'sk' => 't', 'sd' => 'd', 'ch' => ''), + ); + var $seo_stop_files = array('posting' => 1, 'faq' => 1, 'ucp' => 1, 'swatch' => 1, 'mcp' => 1, 'style' => 1, 'cron' => 1); + var $seo_stop_vars = array('view=', 'mark=', 'watch=', 'hash='); + var $seo_stop_dirs = array(); + var $seo_delim = array( 'forum' => '-f', 'topic' => '-t', 'user' => '-u', 'group' => '-g', 'start' => '-', 'sr' => '-', 'file' => '/'); + var $seo_ext = array( 'forum' => '.html', 'topic' => '.html', 'post' => '.html', 'user' => '.html', 'group' => '.html', 'index' => '', 'global_announce' => '/', 'leaders' => '.html', 'atopic' => '.html', 'utopic' => '.html', 'npost' => '.html', 'urpost' => '.html', 'pagination' => '.html', 'gz_ext' => ''); + var $seo_static = array( 'forum' => 'forum', 'topic' => 'topic', 'post' => 'post', 'user' => 'member', 'group' => 'group', 'index' => '', 'global_announce' => 'announces', 'leaders' => 'the-team', 'atopic' => 'active-topics', 'utopic' => 'unanswered', 'npost' => 'newposts', 'urpost' => 'unreadposts', 'pagination' => 'page', 'gz_ext' => '.gz' ); + var $file_hbase = array(); + var $get_vars = array(); + var $path = ''; + var $start = ''; + var $filename = ''; + var $file = ''; + var $url_in = ''; + var $url = ''; + var $page_url = ''; + var $seo_opt = array( 'url_rewrite' => false, 'modrtype' => 2, 'sql_rewrite' => false, 'profile_inj' => false, 'profile_vfolder' => false, 'profile_noids' => false, 'rewrite_usermsg' => false, 'rewrite_files' => false, 'rem_sid' => false, 'rem_hilit' => true, 'rem_small_words' => false, 'virtual_folder' => false, 'virtual_root' => false, 'cache_layer' => true, 'rem_ids' => false, ); + var $rewrite_method = array(); + var $paginate_method = array(); + var $seo_cache = array(); + var $cache_config = array(); + var $RegEx = array(); + var $sftpl = array(); + var $url_replace = array(); + var $ssl = array('requested' => false, 'forced' => false); + /** + * constuctor + */ + function phpbb_seo() { + global $phpEx, $config, $phpbb_root_path; + // fix for an interesting bug with parse_str http://bugs.php.net/bug.php?id=48697 + // and apparently, the bug is still here in php5.3 + @ini_set("mbstring.internal_encoding", 'UTF-8'); + // Nothing should be edited here, please do your custom settings in the + // phpbb_seo/includes/setup_phpbb_seo.php instead to make your updates easier. + // reset the rewrite_method for $phpbb_root_path + $this->rewrite_method[$phpbb_root_path] = array(); + // phpBB files must be treated a bit differently + $this->seo_static['file'] = array(ATTACHMENT_CATEGORY_NONE => 'file', ATTACHMENT_CATEGORY_IMAGE => 'image', ATTACHMENT_CATEGORY_WM => 'wm', ATTACHMENT_CATEGORY_RM => 'rm', ATTACHMENT_CATEGORY_THUMB => 'image', ATTACHMENT_CATEGORY_FLASH => 'flash', ATTACHMENT_CATEGORY_QUICKTIME => 'qt'); + $this->seo_static['file_index'] = 'resources'; + $this->seo_static['thumb'] = 'thumb'; + // Options that may be bypassed by the cached settings. + $this->cache_config['dynamic_options'] = array_keys($this->seo_opt); // Do not change + // copyright notice, do not change + $this->cache_config['dynamic_options']['copyrights'] = $this->seo_opt['copyrights'] = array('img' => true, 'txt' => '', 'title' => ''); + // Caching config + $this->seo_opt['cache_folder'] = 'phpbb_seo/cache/'; // Folder where the cache file is stored + define('SEO_CACHE_PATH', rtrim(phpbb_realpath($phpbb_root_path . $this->seo_opt['cache_folder']), '/') . '/'); // do not change + $this->seo_opt['topic_type'] = array(); // do not change + $this->seo_opt['topic_last_page'] = array(); // do not change + $this->cache_config['cache_enable'] = true; // do not change + $this->cache_config['rem_ids'] = $this->seo_opt['rem_ids']; // do not change, set up above + $this->cache_config['files'] = array('forum' => 'phpbb_cache.' . $phpEx, 'htaccess' => '.htaccess'); + $this->cache_config['cached'] = false; // do not change + $this->cache_config['forum'] = array(); // do not change + $this->cache_config['topic'] = array(); // do not change + $this->cache_config['settings'] = array(); // do not change + // --> DOMAIN SETTING <-- // + // SSL, beware with cookie secure, it won't force ssl here, + // so you will need to switch to ssl for your user to use cookie based session (no sid) + // could be done by using an https link to login form (or within the redirect after login) + $this->ssl['requested'] = (bool) ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === true)) || (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443)); + $this->ssl['forced'] = (bool) (($config['server_protocol'] === 'https//')); + $this->ssl['use'] = (bool) ($this->ssl['requested'] || $this->ssl['forced']); + // Server Settings, rely on DB + $server_protocol = $this->ssl['use'] ? 'https://' : 'http://'; + $server_name = trim($config['server_name'], '/ '); + $server_port = max(0, (int) $config['server_port']); + $server_port = ($server_port && $server_port <> 80) ? ':' . $server_port : ''; + $script_path = trim($config['script_path'], './ '); + $script_path = (empty($script_path) ) ? '' : $script_path . '/'; + $this->seo_path['root_url'] = strtolower($server_protocol . $server_name . $server_port . '/'); + $this->seo_path['phpbb_urlR'] = $this->seo_path['phpbb_url'] = $this->seo_path['root_url'] . $script_path; + $this->seo_path['phpbb_script'] = $script_path; + $this->seo_path['phpbb_files'] = $this->seo_path['phpbb_url'] . 'download/'; + $this->seo_path['canonical'] = ''; + // magic quotes, do it like this in case phpbb_seo class is not started in common.php + if (!defined('STRIP')) { + if (version_compare(PHP_VERSION, '6.0.0-dev', '<') ) { + if (get_magic_quotes_gpc()) { + define('SEO_STRIP', true); + } + } + } elseif (STRIP) { + define('SEO_STRIP', true); + } + // File setting + $this->seo_req_uri(); + $this->seo_opt['seo_base_href'] = $this->seo_opt['req_file'] = $this->seo_opt['req_self'] = ''; + if ($script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF')) { + // From session.php + // Replace backslashes and doubled slashes (could happen on some proxy setups) + $this->seo_opt['req_self'] = str_replace(array('\\', '//'), '/', $script_name); + // basenamed page name (for example: index) + $this->seo_opt['req_file'] = urlencode(htmlspecialchars(str_replace(".$phpEx", '', basename($this->seo_opt['req_self'])))); + } + // Load settings from phpbb_seo/includes/setup_phpbb_seo.php + $this->init_phpbb_seo(); + $this->seo_path['phpbb_filesR'] = $this->seo_path['phpbb_urlR'] . $this->seo_static['file_index'] . $this->seo_delim['file']; + // see if we have some custom replacement + if (!empty($this->url_replace)) { + $this->url_replace = array( + 'find' => array_keys($this->url_replace), + 'replace' => array_values($this->url_replace) + ); + } + $this->seo_opt['topic_per_page'] = ($config['posts_per_page'] <= 0) ? 1 : $config['posts_per_page']; // do not change + // Array of the filenames that require the use of a base href tag. + $this->file_hbase = array_merge(array('viewtopic' => $this->seo_path['phpbb_url'], 'viewforum' => $this->seo_path['phpbb_url'], 'memberlist' => $this->seo_path['phpbb_url'], 'search' => $this->seo_path['phpbb_url']), $this->file_hbase); + // Stop dirs + $this->seo_stop_dirs = array_merge(array($phpbb_root_path . 'adm/' => false), $this->seo_stop_dirs); + // Rewrite functions array : array( 'path' => array('file_name' => 'function_name')); + // Warning, this way of doing things is path aware, this implies path to be properly sent to append_sid() + // Allow to add options without slowing down the URL rewriting process + $this->rewrite_method[$phpbb_root_path] = array_merge( + array( + 'viewtopic' => 'viewtopic', + 'viewforum' => 'viewforum', + 'index' => 'index', + 'memberlist' => 'memberlist', + 'search' => $this->seo_opt['rewrite_usermsg'] ? 'search' : '', + ), + $this->rewrite_method[$phpbb_root_path] + ); + $this->rewrite_method[$phpbb_root_path . 'download/']['file'] = $this->seo_opt['rewrite_files'] ? 'phpbb_files' : ''; + $this->paginate_method = array_merge( + array( + 'topic' => $this->seo_ext['topic'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'forum' => $this->seo_ext['forum'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'group' => $this->seo_ext['group'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'user' => $this->seo_ext['user'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'atopic' => $this->seo_ext['atopic'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'utopic' => $this->seo_ext['utopic'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'npost' => $this->seo_ext['npost'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + 'urpost' => $this->seo_ext['urpost'] === '/' ? 'rewrite_pagination_page' : 'rewrite_pagination', + ), + $this->paginate_method + ); + $this->RegEx = array_merge( + array( + 'topic' => array( + 'check' => '`^' . ($this->seo_opt['virtual_folder'] ? '%1$s/' : '') . '(' . $this->seo_static['topic'] . '|[a-z0-9_-]+' . $this->seo_delim['topic'] . ')$`i', + 'match' => '`^((([a-z0-9_-]+)(' . $this->seo_delim['forum'] . '([0-9]+))?/)?(' . $this->seo_static['topic'] . '(?!=' . $this->seo_delim['topic'] . ')|.+(?=' . $this->seo_delim['topic'] . '))(' . $this->seo_delim['topic'] . ')?)([0-9]+)$`i', + 'parent' => 2, + 'parent_id' => 5, + 'title' => 6, + 'id' => 8, + 'url' => 1, + ), + 'forum' => array( + 'check' => $this->modrtype >= 2 ? '`^[a-z0-9_-]+(' . $this->seo_delim['forum'] . '[0-9]+)?$`i' : '`^' . $this->seo_static['forum'] . '[0-9]+$`i', + 'match' => '`^((' . $this->seo_static['forum'] . '|.+)(' . $this->seo_delim['forum'] . '([0-9]+))?)$`i', + 'title' => '\2', + 'id' => '\4', + ), + ), + $this->RegEx + ); + // preg_replace() patterns for format_url() + // One could want to add |th|horn after |slash, but I'm not sure that Þ should be replaced with t and Ð with e + $this->RegEx['url_find'] = array('`&([a-z]+)(acute|grave|circ|cedil|tilde|uml|lig|ring|caron|slash);`i', '`&(amp;)?[^;]+;`i', '`[^a-z0-9]`i'); // Do not remove : deaccentuation, html/xml entities & non a-z chars + $this->RegEx['url_replace'] = array('\1', '-', '-'); + if ($this->seo_opt['rem_small_words']) { + $this->RegEx['url_find'][] = '`(^|-)[a-z0-9]{1,2}(?=-|$)`i'; + $this->RegEx['url_replace'][] = '-'; + } + $this->RegEx['url_find'][] ='`[-]+`'; // Do not remove : multi hyphen reduction + $this->RegEx['url_replace'][] = '-'; + // $1 parent : string/ + // $2 title / url : topic-title / forum-url-fxx + // $3 id + $this->sftpl = array_merge( + array( + 'topic' => ($this->seo_opt['virtual_folder'] ? '%1$s/' : '') . '%2$s' . $this->seo_delim['topic'] . '%3$s', + 'topic_smpl' => ($this->seo_opt['virtual_folder'] ? '%1$s/' : '') . $this->seo_static['topic'] . '%3$s', + 'forum' => $this->modrtype >= 2 ? '%2$s' : $this->seo_static['forum'] . '%3$s', + 'group' => $this->seo_opt['profile_inj'] ? '%2$s' . $this->seo_delim['group'] . '%3$s' : $this->seo_static['group'] . '%3$s', + ), + $this->sftpl + ); + if ( $this->seo_opt['url_rewrite'] && !defined('ADMIN_START') && isset($this->file_hbase[$this->seo_opt['req_file']])) { + $this->seo_opt['seo_base_href'] = '<base href="' . $this->file_hbase[$this->seo_opt['req_file']] . '"/>'; + } + return; + } + /** + * will make sure that configured options are consistent + * @access private + */ + function check_config() { + $this->modrtype = max(0, (int) $this->modrtype); + // For profiles and user messages pages, if we do not inject, we do not get rid of ids + $this->seo_opt['profile_noids'] = $this->seo_opt['profile_inj'] ? $this->seo_opt['profile_noids'] : false; + // If profile noids ... + if ($this->seo_opt['profile_noids']) { + $this->seo_ext['user'] = '/'; + } + // Profile ans user messages virtual folder + if ($this->seo_opt['profile_vfolder']) { + $this->seo_ext['user'] = '/'; + } + $this->seo_delim['sr'] = $this->seo_ext['user'] == '/' ? '/' : $this->seo_delim['sr']; + // If we use virtual folder, we need '/' at the end of the forum URLs + if ($this->seo_opt['virtual_folder']) { + $this->seo_ext['forum'] = $this->seo_ext['global_announce'] = '/'; + } + // If the forum cache is not activated + if (!$this->seo_opt['cache_layer']) { + $this->seo_opt['rem_ids'] = false; + } + // virtual root option + if ($this->seo_opt['virtual_root'] && $this->seo_path['phpbb_script']) { + // virtual root is available and activated + $this->seo_path['phpbb_urlR'] = $this->seo_path['root_url']; + $this->file_hbase['index'] = $this->seo_path['phpbb_url']; + $this->seo_static['index'] = empty($this->seo_static['index']) ? 'forum' : $this->seo_static['index']; + } else { + // virtual root is not used or usable + $this->seo_opt['virtual_root'] = false; + } + $this->seo_ext['index'] = empty($this->seo_static['index']) ? '' : ( empty($this->seo_ext['index']) ? '.html' : $this->seo_ext['index']); + // In case url rewriting is deactivated + if (!$this->seo_opt['url_rewrite'] || $this->modrtype == 0) { + $this->seo_opt['sql_rewrite'] = false; + $this->seo_opt['zero_dupe']['on'] = false; + } + } + // --> URL rewriting functions <-- + /** + * format_url( $url, $type = 'topic' ) + * Prepare Titles for URL injection + */ + function format_url( $url, $type = 'topic' ) { + $url = preg_replace('`\[.*\]`U','',$url); + if (isset($this->url_replace['find'])) { + $url = str_replace($this->url_replace['find'], $this->url_replace['replace'], $url); + } + $url = htmlentities($url, ENT_COMPAT, 'UTF-8'); + $url = preg_replace($this->RegEx['url_find'] , $this->RegEx['url_replace'], $url); + $url = strtolower(trim($url, '-')); + return empty($url) ? $type : $url; + } + /** + * set_url( $url, $id = 0, $type = 'forum', $parent = '' ) + * Prepare url first part and checks cache + */ + function set_url( $url, $id = 0, $type = 'forum', $parent = '') { + if ( empty($this->seo_url[$type][$id]) ) { + return ( $this->seo_url[$type][$id] = !empty($this->cache_config[$type][$id]) ? $this->cache_config[$type][$id] : sprintf($this->sftpl[$type], $parent, $this->format_url($url, $this->seo_static[$type]) . $this->seo_delim[$type] . $id, $id) ); + } + return $this->seo_url[$type][$id]; + } + /** + * prepare_url( $type, $title, $id, $parent = '', $smpl = false ) + * Prepare url first part + */ + function prepare_url( $type, $title, $id, $parent = '', $smpl = false ) { + return empty($this->seo_url[$type][$id]) ? ($this->seo_url[$type][$id] = sprintf($this->sftpl[$type . ($smpl ? '_smpl' : '')], $parent, !$smpl ? $this->format_url($title, $this->seo_static[$type]) : '', $id)) : $this->seo_url[$type][$id]; + } + /** + * set_title( $type, $title, $id, $parent = '' ) + * Set title for url injection + */ + function set_title( $type, $title, $id, $parent = '' ) { + return empty($this->seo_url[$type][$id]) ? ($this->seo_url[$type][$id] = ($parent ? $parent . '/' : '') . $this->format_url($title, $this->seo_static[$type])) : $this->seo_url[$type][$id]; + } + /** + * get_url_info($type, $url, $info = 'title') + * Get info from url (title, id, parent etc ...) + */ + function get_url_info($type, $url, $info = 'title') { + $url = trim($url, '/ '); + if (preg_match($this->RegEx[$type]['match'], $url, $matches)) { + return !empty($matches[$this->RegEx[$type][$info]]) ? $matches[$this->RegEx[$type][$info]] : ''; + } + return ''; + } + /** + * check_url( $type, $url, $parent = '') + * Validate a prepared url + */ + function check_url( $type, $url, $parent = '') { + if (empty($url)) { + return false; + } + $parent = !empty($parent) ? (string) $parent : '[a-z0-9/_-]+'; + return !empty($this->RegEx[$type]['check']) ? preg_match(sprintf($this->RegEx[$type]['check'], $parent), $url) : false; + } + /** + * prepare_iurl( $data, $type, $parent = '' ) + * Prepare url first part (not for forums) with SQL based URL rewriting + */ + function prepare_iurl( $data, $type, $parent = '' ) { + $id = max(0, (int) $data[$type . '_id']); + if ( empty($this->seo_url[$type][$id]) ) { + if (!empty($data[$type . '_url'])) { + return ($this->seo_url[$type][$id] = $data[$type . '_url'] . $id); + } else { + return ($this->seo_url[$type][$id] = sprintf($this->sftpl[$type . ($this->modrtype > 2 ? '' : '_smpl')], $parent, $this->modrtype > 2 ? $this->format_url($data[$type . '_title'], $this->seo_static[$type]) : '', $id)); + } + } + return $this->seo_url[$type][$id]; + } + /** + * drop_sid( $url ) + * drop the sid's in url + */ + function drop_sid( $url ) { + return (strpos($url, 'sid=') !== false) ? trim(preg_replace(array('`&(amp;)?sid=[a-z0-9]*(&|&)?`', '`(\?)sid=[a-z0-9]*`'), array('\2', '\1'), $url), '?') : $url; + } + /** + * set_user_url( $username, $user_id = 0 ) + * Prepare profile url + */ + function set_user_url( $username, $user_id = 0 ) { + if (empty($this->seo_url['user'][$user_id])) { + $username = strip_tags($username); + $this->seo_url['username'][$username] = $user_id; + if ( $this->seo_opt['profile_inj'] ) { + if ( $this->seo_opt['profile_noids'] ) { + $this->seo_url['user'][$user_id] = $this->seo_static['user'] . '/' . $this->seo_url_encode($username); + } else { + $this->seo_url['user'][$user_id] = $this->format_url($username, $this->seo_delim['user']) . $this->seo_delim['user'] . $user_id; + } + } else { + $this->seo_url['user'][$user_id] = $this->seo_static['user'] . $user_id; + } + } + } + /** + * seo_url_encode( $url ) + * custom urlencoding + */ + function seo_url_encode( $url ) { + // can be faster to return $url directly if you do not allow more chars than + // [a-zA-Z0-9_\.-] in your usernames + // return $url; + // Here we hanlde the "&", "/", "+" and "#" case proper ( http://www.php.net/urlencode => http://issues.apache.org/bugzilla/show_bug.cgi?id=34602 ) + static $find = array('&', '/', '#', '+'); + static $replace = array('%26', '%2F', '%23', '%2b'); + return rawurlencode(str_replace( $find, $replace, utf8_normalize_nfc(htmlspecialchars_decode(str_replace('&amp;', '%26', rawurldecode($url)))))); + } + /** + * url_rewrite($url, $params = false, $is_amp = true, $session_id = false) + * builds and Rewrite URLs. + * Allow adding of many more cases than just the + * regular phpBB URL rewritting without slowing down the process. + * Mimics append_sid with some shortcuts related to how url are rewritten + */ + function url_rewrite($url, $params = false, $is_amp = true, $session_id = false) { + global $phpEx, $user, $_SID, $_EXTRA_URL, $phpbb_root_path; + $qs = $anchor = ''; + $this->get_vars = array(); + $amp_delim = ($is_amp) ? '&' : '&'; + if (strpos($url, '#') !== false) { + list($url, $anchor) = explode('#', $url, 2); + $anchor = '#' . $anchor; + } + @list($this->path, $qs) = explode('?', $url, 2); + if (is_array($params)) { + if (!empty($params['#'])) { + $anchor = '#' . $params['#']; + unset($params['#']); + } + $qs .= ($qs ? $amp_delim : '') . $this->query_string($params, $amp_delim, ''); + } elseif ($params) { + if (strpos($params, '#') !== false) { + list($params, $anchor) = explode('#', $params, 2); + $anchor = '#' . $anchor; + } + $qs .= ($qs ? $amp_delim : '') . $params; + } + // Appending custom url parameter? + if (!empty($_EXTRA_URL)) { + $qs .= ($qs ? $amp_delim : '') . implode($amp_delim, $_EXTRA_URL); + } + // Sid ? + if ($session_id === false && !empty($_SID)) { + $qs .= ($qs ? $amp_delim : '') . "sid=$_SID"; + } else if ($session_id) { + $qs .= ($qs ? $amp_delim : '') . "sid=$session_id"; + } + // Build vanilla URL + if (preg_match("`\.[a-z0-9]+$`i", $this->path) ) { + $this->file = basename($this->path); + $this->path = ltrim(str_replace($this->file, '', $this->path), '/'); + } else { + $this->file = ''; + $this->path = ltrim($this->path, '/'); + } + $this->url_in = $this->file . ($qs ? '?' . $qs : ''); + $url = $this->path . $this->url_in . $anchor; + if (isset($this->seo_cache[$url])) { + return $this->seo_cache[$url]; + } + if ( !$this->seo_opt['url_rewrite'] || defined('ADMIN_START') || isset($this->seo_stop_dirs[$this->path]) ) { + return ($this->seo_cache[$url] = $url); + } + $this->filename = trim(str_replace(".$phpEx", '', $this->file)); + if ( isset($this->seo_stop_files[$this->filename]) ) { + // add full url + $url = $this->path == $phpbb_root_path ? $this->seo_path['phpbb_url'] . preg_replace('`^' . $phpbb_root_path . '`', '', $url) : $url; + return ($this->seo_cache[$url] = $url); + } + parse_str(str_replace('&', '&', $qs), $this->get_vars); + // strp slashes if necessary + if (defined('SEO_STRIP')) { + $this->get_vars = array_map(array(&$this, 'stripslashes'), $this->get_vars); + } + if (empty($user->data['is_registered'])) { + if ( $this->seo_opt['rem_sid'] ) { + unset($this->get_vars['sid']); + } + if ( $this->seo_opt['rem_hilit'] ) { + unset($this->get_vars['hilit']); + } + } + $this->url = $this->file; + if ( !empty($this->rewrite_method[$this->path][$this->filename]) ) { + $this->{$this->rewrite_method[$this->path][$this->filename]}(); + return ($this->seo_cache[$url] = $this->path . $this->url . $this->query_string($this->get_vars, $amp_delim, '?') . $anchor); + } else { + return ($this->seo_cache[$url] = $url); + } + } + /** + * URL rewritting for viewtopic.php + * With Virtual Folder Injection + * @access private + */ + function viewtopic() { + global $phpbb_root_path; + $this->filter_url($this->seo_stop_vars); + $this->path = $this->seo_path['phpbb_urlR']; + if ( !empty($this->get_vars['p']) ) { + $this->url = $this->seo_static['post'] . $this->get_vars['p'] . $this->seo_ext['post']; + unset($this->get_vars['p'], $this->get_vars['f'], $this->get_vars['t'], $this->get_vars['start']); + return; + } + if ( isset($this->get_vars['t']) && !empty($this->seo_url['topic'][$this->get_vars['t']]) ) { + // Filter default params + $this->filter_get_var($this->phpbb_filter['topic']); + $this->{$this->paginate_method['topic']}($this->seo_ext['topic']); + $this->url = $this->seo_url['topic'][$this->get_vars['t']] . $this->start; + unset($this->get_vars['t'], $this->get_vars['f'], $this->get_vars['p']); + return; + } else if (!empty($this->get_vars['t'])) { + // Filter default params + $this->filter_get_var($this->phpbb_filter['topic']); + $this->{$this->paginate_method['topic']}($this->seo_ext['topic']); + $this->url = $this->seo_static['topic'] . $this->get_vars['t'] . $this->start; + unset($this->get_vars['t'], $this->get_vars['f'], $this->get_vars['p']); + return; + } + $this->path = $this->seo_path['phpbb_url']; + return; + } + /** + * URL rewritting for viewforum.php + * @access private + */ + function viewforum() { + global $phpbb_root_path; + $this->path = $this->seo_path['phpbb_urlR']; + $this->filter_url($this->seo_stop_vars); + if ( isset($this->get_vars['f']) && !empty($this->seo_url['forum'][$this->get_vars['f']]) ) { + // Filter default params + $this->filter_get_var($this->phpbb_filter['forum']); + $this->{$this->paginate_method['forum']}($this->seo_ext['forum']); + $this->url = $this->seo_url['forum'][$this->get_vars['f']] . $this->start; + unset($this->get_vars['f']); + return; + } else if (!empty($this->get_vars['f'])) { + // Filter default params + $this->filter_get_var($this->phpbb_filter['forum']); + $this->{$this->paginate_method['forum']}($this->seo_ext['forum']); + $this->url = $this->seo_static['forum'] . $this->get_vars['f'] . $this->start; + unset($this->get_vars['f']); + return; + } + $this->path = $this->seo_path['phpbb_url']; + return; + } + /** + * URL rewritting for memberlist.php + * with nicknames and group name injection + * @access private + */ + function memberlist() { + global $phpbb_root_path; + $this->path = $this->seo_path['phpbb_urlR']; + if ( @$this->get_vars['mode'] === 'viewprofile' && !@empty($this->seo_url['user'][$this->get_vars['u']]) ) { + $this->url = $this->seo_url['user'][$this->get_vars['u']] . $this->seo_ext['user']; + unset($this->get_vars['mode'], $this->get_vars['u']); + return; + } elseif ( @$this->get_vars['mode'] === 'group' && !@empty($this->seo_url['group'][$this->get_vars['g']]) ) { + $this->{$this->paginate_method['group']}($this->seo_ext['group']); + $this->url = $this->seo_url['group'][$this->get_vars['g']] . $this->start; + unset($this->get_vars['mode'], $this->get_vars['g']); + return; + } elseif (@$this->get_vars['mode'] === 'leaders') { + $this->url = $this->seo_static['leaders'] . $this->seo_ext['leaders']; + unset($this->get_vars['mode']); + return; + } + $this->path = $this->seo_path['phpbb_url']; + return; + } + /** + * URL rewritting for search.php + * @access private + */ + function search() { + global $phpbb_root_path; + if (isset($this->get_vars['fid'])) { + $this->get_vars = array(); + $this->url = $this->url_in; + return; + } + $this->path = $this->seo_path['phpbb_urlR']; + $user_id = !empty($this->get_vars['author_id']) ? $this->get_vars['author_id'] : ( isset($this->seo_url['username'][rawurldecode(@$this->get_vars['author'])]) ? $this->seo_url['username'][rawurldecode(@$this->get_vars['author'])] : 0); + if ( $user_id && isset($this->seo_url['user'][$user_id]) ) { + // Filter default params + $this->filter_get_var($this->phpbb_filter['search']); + $this->{$this->paginate_method['user']}($this->seo_ext['user']); + $sr = (@$this->get_vars['sr'] == 'topics' ) ? 'topics' : 'posts'; + $this->url = $this->seo_url['user'][$user_id] . $this->seo_delim['sr'] . $sr . $this->start; + unset($this->get_vars['author_id'], $this->get_vars['author'], $this->get_vars['sr']); + return; + } elseif ( $this->seo_opt['profile_noids'] && !empty($this->get_vars['author']) ) { + // Filter default params + $this->filter_get_var($this->phpbb_filter['search']); + $this->rewrite_pagination_page(); + $sr = (@$this->get_vars['sr'] == 'topics' ) ? '/topics' : '/posts'; + $this->url = $this->seo_static['user'] . '/' . $this->seo_url_encode($this->get_vars['author']) . $sr . $this->start; + unset($this->get_vars['author'], $this->get_vars['author_id'], $this->get_vars['sr']); + return; + } elseif (!empty($this->get_vars['search_id'])) { + switch ($this->get_vars['search_id']) { + case 'active_topics': + $this->filter_get_var($this->phpbb_filter['search']); + $this->{$this->paginate_method['atopic']}($this->seo_ext['atopic']); + $this->url = $this->seo_static['atopic'] . $this->start; + unset($this->get_vars['search_id'], $this->get_vars['sr']); + if (@$this->get_vars['st'] == 7) { + unset($this->get_vars['st']); + } + return; + case 'unanswered': + $this->filter_get_var($this->phpbb_filter['search']); + $this->{$this->paginate_method['utopic']}($this->seo_ext['utopic']); + $this->url = $this->seo_static['utopic'] . $this->start; + unset($this->get_vars['search_id']); + if (@$this->get_vars['sr'] == 'topics') { + unset($this->get_vars['sr']); + } + return; + case 'egosearch': + global $user; + $this->set_user_url($user->data['username'], $user->data['user_id']); + $this->url = $this->seo_url['user'][$user->data['user_id']] . $this->seo_delim['sr'] . 'topics' . $this->seo_ext['user']; + unset($this->get_vars['search_id']); + return; + case 'newposts': + $this->filter_get_var($this->phpbb_filter['search']); + $this->{$this->paginate_method['npost']}($this->seo_ext['npost']); + $this->url = $this->seo_static['npost'] . $this->start; + unset($this->get_vars['search_id']); + if (@$this->get_vars['sr'] == 'topics') { + unset($this->get_vars['sr']); + } + return; + case 'unreadposts': + $this->filter_get_var($this->phpbb_filter['search']); + $this->{$this->paginate_method['urpost']}($this->seo_ext['urpost']); + $this->url = $this->seo_static['urpost'] . $this->start; + unset($this->get_vars['search_id']); + if (@$this->get_vars['sr'] == 'topics') { + unset($this->get_vars['sr']); + } + return; + } + } + $this->path = $this->seo_path['phpbb_url']; + return; + } + /** + * URL rewritting for download/file.php + * @access private + */ + function phpbb_files() { + $this->filter_url($this->seo_stop_vars); + $this->path = $this->seo_path['phpbb_filesR']; + if (isset($this->get_vars['id']) && !empty($this->seo_url['file'][$this->get_vars['id']])) { + $this->url = $this->seo_url['file'][$this->get_vars['id']]; + if (!empty($this->get_vars['t'])) { + $this->url .= $this->seo_delim['file'] . $this->seo_static['thumb']; + } /*else if (@$this->get_vars['mode'] == 'view') { + $this->url .= $this->seo_delim['file'] . 'view'; + }*/ + $this->url .= $this->seo_delim['file'] . $this->get_vars['id']; + unset($this->get_vars['id'], $this->get_vars['t'], $this->get_vars['mode']); + return; + } + $this->path = $this->seo_path['phpbb_files']; + return; + } + /** + * URL rewritting for index.php + * @access private + */ + function index() { + $this->path = $this->seo_path['phpbb_urlR']; + if ($this->filter_url($this->seo_stop_vars)) { + $this->url = $this->seo_static['index'] . $this->seo_ext['index']; + return; + } + $this->path = $this->seo_path['phpbb_url']; + return; + } + /** + * Returns true if the user can edit urls + * @access public + */ + function url_can_edit($forum_id = 0) { + global $user, $auth; + if (empty($this->seo_opt['sql_rewrite']) || empty($user->data['is_registered'])) { + return false; + } + if ($auth->acl_get('a_')) { + return true; + } + // un comment to grant url edit perm to moderators in at least a forums + /*if ($auth->acl_getf_global('m_')) { + return true; + }*/ + $forum_id = max(0, (int) $forum_id); + if ($forum_id && $auth->acl_get('m_', $forum_id)) { + return true; + } + return false; + } + /** + * Will break if a $filter pattern is foundin $url. + * Example $filter = array("view=", "mark="); + * @access private + */ + function filter_url($filter = array()) { + foreach ($filter as $patern ) { + if ( strpos($this->url_in, $patern) !== false ) { + $this->get_vars = array(); + $this->url = $this->url_in; + return false; + } + } + return true; + } + /** + * Will unset all default var stored in $filter array. + * Example $filter = array('st' => 0, 'sk' => 't', 'sd' => 'a', 'hilit' => ''); + * @access private + */ + function filter_get_var($filter = array()) { + if ( !empty($this->get_vars) ) { + foreach ($this->get_vars as $paramkey => $paramval) { + if ( isset($filter[$paramkey]) ) { + if ( $filter[$paramkey] == $this->get_vars[$paramkey] || !isset($this->get_vars[$paramkey])) { + unset($this->get_vars[$paramkey]); + } + } + } + } + return; + } + /** + * Appends the GET vars in the query string + * @access public + */ + function query_string($get_vars = array(), $amp_delim = '&', $url_delim = '?') { + if(empty($get_vars)) { + return ''; + } + $params = array(); + foreach($get_vars as $key => $value) { + if (is_array($value)) { + foreach($value as $k => $v) { + $params[] = $key . '[' . $k . ']=' . $v; + } + } else { + $params[] = $key . (!trim($value) ? '' : '=' . $value); + } + } + return $url_delim . implode($amp_delim , $params); + } + /** + * rewrite pagination, simple + * -xx.html + */ + function rewrite_pagination($suffix) { + $this->start = $this->seo_start( @$this->get_vars['start'] ) . $suffix; + unset($this->get_vars['start']); + } + /** + * rewrite pagination, virtual folder + * /pagexx.html + */ + function rewrite_pagination_page() { + $this->start = '/' . $this->seo_start_page( @$this->get_vars['start'] ); + unset($this->get_vars['start']); + } + /** + * Returns usable start param + * -xx + */ + function seo_start($start) { + return ($start >= 1 ) ? $this->seo_delim['start'] . (int) $start : ''; + } + /** + * Returns usable start param + * pagexx.html + * Only used in virtual folder mode + */ + function seo_start_page($start) { + return ($start >=1 ) ? $this->seo_static['pagination'] . (int) $start . $this->seo_ext['pagination'] : ''; + } + /** + * Returns the full REQUEST_URI + */ + function seo_req_uri() { + if ( !empty($_SERVER['HTTP_X_REWRITE_URL']) ) { // IIS isapi_rewrite + $this->seo_path['uri'] = ltrim($_SERVER['HTTP_X_REWRITE_URL'], '/'); + } elseif ( !empty($_SERVER['REQUEST_URI']) ) { // Apache mod_rewrite + $this->seo_path['uri'] = ltrim($_SERVER['REQUEST_URI'], '/'); + } else { // no mod rewrite + $this->seo_path['uri'] = ltrim($_SERVER['SCRIPT_NAME'], '/') . ( ( !empty($_SERVER['QUERY_STRING']) ) ? '?'.$_SERVER['QUERY_STRING'] : '' ); + } + $this->seo_path['uri'] = str_replace( '%26', '&', rawurldecode($this->seo_path['uri'])); + // workaround for FF default iso encoding + if (!$this->is_utf8($this->seo_path['uri'])) { + $this->seo_path['uri'] = utf8_normalize_nfc(utf8_recode($this->seo_path['uri'], 'iso-8859-1')); + } + $this->seo_path['uri'] = $this->seo_path['root_url'] . $this->seo_path['uri']; + return $this->seo_path['uri']; + } + /** + * seo_end() : The last touch function + * Note : This mod is going to help your site a lot in Search Engines + * We request that you keep this copyright notice as specified in the licence. + * If You really cannot put this link, you should at least provide us with one visible + * (can be small but visible) link on your home page or your forum Index using this code for example : + * <a href="http://www.phpbb-seo.com/" title="Search Engine Optimization">phpBB SEO</a> + */ + function seo_end($return = false) { + global $user, $config; + if (empty($this->seo_opt['copyrights']['title'])) { + $this->seo_opt['copyrights']['title'] = strpos($config['default_lang'], 'fr') !== false ? 'Optimisation du Référencement' : 'Search Engine Optimization'; + } + if (empty($this->seo_opt['copyrights']['txt'])) { + $this->seo_opt['copyrights']['txt'] = 'phpBB SEO'; + } + if ($this->seo_opt['copyrights']['img']) { + $output = '<br /><a href="http://www.phpbb-seo.com/" title="' . $this->seo_opt['copyrights']['title'] . '"><img src="' . $this->seo_path['phpbb_url'] . 'images/phpbb-seo.png" alt="' . $this->seo_opt['copyrights']['txt'] . '"/></a>'; + } else { + $output = '<br /><a href="http://www.phpbb-seo.com/" title="' . $this->seo_opt['copyrights']['title'] . '">' . $this->seo_opt['copyrights']['txt'] . '</a>'; + } + if ($return) { + return $output; + } else { + $user->lang['TRANSLATION_INFO'] .= $output; + } + return; + } + // -> Cache functions + /** + * forum_id(&$forum_id, $forum_uri = '') + * will tell the forum id from the uri or the forum_uri GET var by checking the cache. + */ + function get_forum_id(&$forum_id, $forum_uri = '') { + if (empty($forum_uri)) { + $forum_uri = request_var('forum_uri', ''); + unset($_GET['forum_uri'], $_REQUEST['forum_uri']); + } + if (empty($forum_uri) || $forum_uri == $this->seo_static['global_announce']) { + return 0; + } + if ($id = @array_search($forum_uri, $this->cache_config['forum']) ) { + $forum_id = max(0, (int) $id); + } elseif ( $id = $this->get_url_info('forum', $forum_uri, 'id')) { + $forum_id = max(0, (int) $id); + } + return $forum_id; + } + /** + * check_cache() will tell if the required file exists. + * @access private + */ + function check_cache( $type = 'forum', $from_bkp = false ) { + $file = SEO_CACHE_PATH . @$this->cache_config['files'][$type]; + if( !$this->cache_config['cache_enable'] || !isset($this->cache_config['files'][$type]) || !file_exists($file) ) { + $this->cache_config['cached'] = false; + return false; + } + include($file); + if (is_array($this->cache_config[$type]) ) { + $this->cache_config['cached'] = true; + return true; + } else { + if ( !$from_bkp ) { + // Try the current backup + @copy($file . '.current', $file); + $this->check_cache( $type, true ); + } + $this->cache_config['cached'] = false; + return false; + } + } + /** + * sslify($url, $ssl = true, $proto_check = true) + * properly set http protocol (eg http or https) + * if no protocol is specified, will return false with $proto_check set to true + */ + function sslify($url, $ssl = true, $proto_check = true) { + static $mask = '`^https?://`i'; + $url = trim($url); + if ($url && preg_match($mask, $url)) { + $replace = $ssl ? 'https://' : 'http://'; + return preg_replace($mask, $replace, $url); + } + return $proto_check ? false : $url; + } + /** + * is_utf8($string) + * Borrowed from php.net : http://www.php.net/mb_detect_encoding (detectUTF8) + */ + function is_utf8($string) { + // non-overlong 2-byte|excluding overlongs|straight 3-byte|excluding surrogates|planes 1-3|planes 4-15|plane 16 + return preg_match('%(?:[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF] |\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+%xs', $string); + } + /** + * stripslashes($value) + * Borrowed from php.net : http://www.php.net/stripslashes + */ + function stripslashes($value) { + return is_array($value) ? array_map(array(&$this, 'stripslashes'), $value) : stripslashes($value); + } + // --> Add on Functions <-- + // --> Gen stats + /** + * Returns usable microtime + * Borrowed from php.net + */ + function microtime_float() { + return array_sum(explode(' ',microtime())); + } +} // End of the phpbb_seo class +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/phpbb_seo_install.php b/phpBB/phpbb_seo/phpbb_seo_install.php new file mode 100644 index 0000000000..5654f97b59 --- /dev/null +++ b/phpBB/phpbb_seo/phpbb_seo_install.php @@ -0,0 +1,776 @@ +<?php +/** +* +* @package Ultimate SEO URL phpBB SEO +* @version $Id: phpbb_seo_install.php 222 2010-02-27 13:08:48Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://www.opensource.org/licenses/rpl1.5.txt Reciprocal Public License 1.5 +* +*/ +/* + * Based on the phpBB3 install package / www.phpBB.com + */ +define('IN_PHPBB', true); +define('IN_INSTALL', true); +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); +// Try to override some limits - maybe it helps some... +@set_time_limit(0); +$mem_limit = @ini_get('memory_limit'); +if (!empty($mem_limit)) { + $unit = strtolower(substr($mem_limit, -1, 1)); + $mem_limit = (int) $mem_limit; + if ($unit == 'k') { + $mem_limit = floor($mem_limit / 1024); + } else if ($unit == 'g') { + $mem_limit *= 1024; + } else if (is_numeric($unit)) { + $mem_limit = floor((int) ($mem_limit . $unit) / 1048576); + } + $mem_limit = max(128, $mem_limit) . 'M'; +} else { + $mem_limit = '128M'; +} +@ini_set('memory_limit', $mem_limit); +include($phpbb_root_path . 'common.' . $phpEx); +// Include essential scripts +require($phpbb_root_path . 'includes/functions_install.' . $phpEx); +// Start session management +$user->session_begin(); +$auth->acl($user->data); +$user->setup('mods/acp_phpbb_seo'); +// Security check +// Circumvent a potential phpbb bug with paths +$redirect = append_sid(generate_board_url() . "/phpbb_seo/phpbb_seo_install.$phpEx"); +if (!$user->data['is_registered']) { + login_box($redirect, $user->lang['SEO_LOGIN'],'', false, false); +} +if (!$auth->acl_get('a_')) { + $user->session_kill(true); + login_box($redirect, $user->lang['SEO_LOGIN_ADMIN'],'', false, false); +} +if ($user->data['user_type'] != USER_FOUNDER) { + login_box($redirect, $user->lang['SEO_LOGIN_FOUNDER'],'', false, false); +} +$user->add_lang(array('acp/common', 'acp/board', 'install', 'posting', 'acp/modules')); +$mode = request_var('mode', 'overview'); +$sub = request_var('sub', ''); +// Set some standard variables we want to force +$config['load_tplcompile'] = '1'; +$template->set_custom_template('../adm/style', '../admin'); +$template->assign_var('T_TEMPLATE_PATH', '../adm/style'); +// the acp template is never stored in the database +$user->theme['template_storedb'] = false; +// Start the installer +$install = new module(); +$install->create('install', "phpbb_seo_install.$phpEx", $mode, $sub); +$install->load(); +// Generate the page +$install->page_header(); +$install->generate_navigation(); +$template->set_filenames(array( + 'body' => $install->get_tpl_name()) +); +$install->page_footer(); +/** +* @package install +*/ +class module { + var $id = 0; + var $type = 'install'; + var $module_ary = array(); + var $filename; + var $module_url = ''; + var $tpl_name = ''; + var $mode; + var $sub; + /** + * Private methods, should not be overwritten + */ + function create($module_type, $module_url, $selected_mod = false, $selected_submod = false) { + global $db, $config, $phpEx, $phpbb_root_path, $user; + $module = array( + array( + 'module_type' => 'install', + 'module_title' => 'OVERVIEW', + 'module_filename' => 'overview_phpbb_seo', + 'module_order' => 0, + 'module_subs' => array('INTRO', 'LICENSE', 'SUPPORT'), + 'module_stages' => '', + 'module_reqs' => '' + ), + array( + 'module_type' => 'install', + 'module_title' => 'INSTALL_PHPBB_SEO', + 'module_filename' => 'install_phpbb_seo', + 'module_order' => 1, + 'module_subs' => '', + 'module_stages' => array('INTRO', 'FINAL'), + 'module_reqs' => '' + ), + array( + 'module_type' => 'uninstall', + 'module_title' => 'UNINSTALL_PHPBB_SEO', + 'module_filename' => 'install_phpbb_seo', + 'module_order' => 2, + 'module_subs' => '', + 'module_stages' => array('INTRO', 'FINAL'), + 'module_reqs' => '' + ), + ); + // Order to use and count further if modules get assigned to the same position or not having an order + $max_module_order = 1000; + foreach ($module as $row) { + // Module order not specified or module already assigned at this position? + if (!isset($row['module_order']) || isset($this->module_ary[$row['module_order']])) { + $row['module_order'] = $max_module_order; + $max_module_order++; + } + $this->module_ary[$row['module_order']]['name'] = $row['module_title']; + $this->module_ary[$row['module_order']]['filename'] = $row['module_filename']; + $this->module_ary[$row['module_order']]['subs'] = $row['module_subs']; + $this->module_ary[$row['module_order']]['stages'] = $row['module_stages']; + if (strtolower($selected_mod) == strtolower($row['module_title'])) { + $this->id = (int) $row['module_order']; + $this->filename = (string) $row['module_filename']; + $this->module_url = (string) $module_url; + $this->mode = (string) $selected_mod; + // Check that the sub-mode specified is valid or set a default if not + if (is_array($row['module_subs'])) { + $this->sub = strtolower((in_array(strtoupper($selected_submod), $row['module_subs'])) ? $selected_submod : $row['module_subs'][0]); + } else if (is_array($row['module_stages'])) { + $this->sub = strtolower((in_array(strtoupper($selected_submod), $row['module_stages'])) ? $selected_submod : $row['module_stages'][0]); + } else { + $this->sub = ''; + } + } + } // END foreach + } // END create + /** + * Load and run the relevant module if applicable + */ + function load($mode = false, $run = true) { + global $phpbb_root_path, $phpEx; + if ($run) { + if (!empty($mode)) { + $this->mode = $mode; + } + $module = $this->filename; + if (!class_exists($module)) { + $this->error('Module "' . htmlspecialchars($module) . '" not accessible.', __LINE__, __FILE__); + } + $this->module = new $module($this); + if (method_exists($this->module, 'main')) { + $this->module->main($this->mode, $this->sub); + } + } + } + /** + * Output the standard page header + */ + function page_header() { + if (defined('HEADER_INC')) { + return; + } + define('HEADER_INC', true); + global $template, $user, $stage, $phpbb_root_path; + $template->assign_vars(array( + 'L_INSTALL_PANEL' => $user->lang['SEO_INSTALL_PANEL'], + 'L_SKIP' => $user->lang['SKIP'], + 'PAGE_TITLE' => $this->get_page_title(), + 'T_IMAGE_PATH' => $phpbb_root_path . 'adm/images/', + 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'], + 'S_CONTENT_ENCODING' => 'UTF-8', + 'S_USER_LANG' => $user->lang['USER_LANG'], + ) + ); + header('Content-type: text/html; charset=UTF-8'); + header('Cache-Control: private, no-cache="set-cookie"'); + header('Expires: 0'); + header('Pragma: no-cache'); + return; + } + /** + * Output the standard page footer + */ + function page_footer() { + global $db, $template, $phpbb_seo; + $template->display('body'); + // Close our DB connection. + if (!empty($db) && is_object($db)) { + $db->sql_close(); + } + exit; + } + /** + * Returns desired template name + */ + function get_tpl_name() { + return $this->module->tpl_name . '.html'; + } + /** + * Returns the desired page title + */ + function get_page_title() { + global $user; + if (!isset($this->module->page_title)) { + return ''; + } + return (isset($user->lang[$this->module->page_title])) ? $user->lang[$this->module->page_title] : $this->module->page_title; + } + /** + * Generate an HTTP/1.1 header to redirect the user to another page + * This is used during the installation when we do not have a database available to call the normal redirect function + * @param string $page The page to redirect to relative to the installer root path + */ + function redirect($page) { + $server_name = (!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'); + $server_port = (!empty($_SERVER['SERVER_PORT'])) ? (int) $_SERVER['SERVER_PORT'] : (int) getenv('SERVER_PORT'); + $secure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 1 : 0; + + $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF'); + if (!$script_name) { + $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI'); + } + // Replace backslashes and doubled slashes (could happen on some proxy setups) + $script_name = str_replace(array('\\', '//'), '/', $script_name); + $script_path = trim(dirname($script_name)); + $url = (($secure) ? 'https://' : 'http://') . $server_name; + if ($server_port && (($secure && $server_port <> 443) || (!$secure && $server_port <> 80))) { + $url .= ':' . $server_port; + } + $url .= $script_path . '/' . $page; + header('Location: ' . $url); + exit; + } + /** + * Generate the navigation tabs + */ + function generate_navigation() { + global $user, $template, $phpEx; + if (is_array($this->module_ary)) { + @ksort($this->module_ary); + foreach ($this->module_ary as $cat_ary) { + $cat = $cat_ary['name']; + $l_cat = (!empty($user->lang['CAT_' . $cat])) ? $user->lang['CAT_' . $cat] : preg_replace('#_#', ' ', $cat); + $cat = strtolower($cat); + $url = $this->module_url . "?mode=$cat"; + if ($this->mode == $cat) { + $template->assign_block_vars('t_block1', array( + 'L_TITLE' => $l_cat, + 'S_SELECTED' => true, + 'U_TITLE' => $url, + )); + if (is_array($this->module_ary[$this->id]['subs'])) { + $subs = $this->module_ary[$this->id]['subs']; + foreach ($subs as $option) { + $l_option = (!empty($user->lang['SUB_' . $option])) ? $user->lang['SUB_' . $option] : preg_replace('#_#', ' ', $option); + $option = strtolower($option); + $url = $this->module_url . '?mode=' . $this->mode . "&sub=$option"; + $template->assign_block_vars('l_block1', array( + 'L_TITLE' => $l_option, + 'S_SELECTED' => ($this->sub == $option), + 'U_TITLE' => $url, + )); + } + } + if (is_array($this->module_ary[$this->id]['stages'])) { + $subs = $this->module_ary[$this->id]['stages']; + $matched = false; + foreach ($subs as $option) { + $l_option = (!empty($user->lang['STAGE_' . $option])) ? $user->lang['STAGE_' . $option] : preg_replace('#_#', ' ', $option); + $option = strtolower($option); + $matched = ($this->sub == $option) ? true : $matched; + + $template->assign_block_vars('l_block2', array( + 'L_TITLE' => $l_option, + 'S_SELECTED' => ($this->sub == $option), + 'S_COMPLETE' => !$matched, + )); + } + } + } else { + $template->assign_block_vars('t_block1', array( + 'L_TITLE' => $l_cat, + 'S_SELECTED' => false, + 'U_TITLE' => $url, + )); + } + } + } + } + /** + * Output an error message + * If skip is true, return and continue execution, else exit + */ + function error($error, $line = '', $file = '', $skip = false, $title = '') { + global $user, $db, $template, $phpbb_seo; + $title = !empty($title) ? $title : $user->lang['INST_ERR_FATAL']; + $file = !empty($file) ? basename($file) . ' [ ' . $line . ' ]' : ''; + if ($skip) { + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $user->lang['INST_ERR'], + )); + $template->assign_block_vars('checks', array( + 'TITLE' => basename($file) . ' [ ' . $line . ' ]', + 'RESULT' => '<b style="color:red">' . $error . '</b>', + )); + return; + } + echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; + echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">'; + echo '<head>'; + echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'; + echo '<title>' . $title . '</title>'; + echo '<link href="../adm/style/admin.css" rel="stylesheet" type="text/css" media="screen" />'; + echo '</head>'; + echo '<body id="errorpage">'; + echo '<div id="wrap">'; + echo ' <div id="page-header">'; + echo ' </div>'; + echo ' <div id="page-body">'; + echo ' <div id="acp">'; + echo ' <div class="panel">'; + echo ' <span class="corners-top"><span></span></span>'; + echo ' <div id="content">'; + echo ' <h1>' . $title . '</h1>'; + echo ' <p>' . $file . '</p>' . "\n"; + echo ' <p><b>' . $error . "</b></p>\n"; + echo ' </div>'; + echo ' <span class="corners-bottom"><span></span></span>'; + echo ' </div>'; + echo ' </div>'; + echo ' </div>'; + echo ' <div id="page-footer">'; + echo ' Powered by phpBB © 2000, 2002, 2005, 2007 <a href="http://www.phpbb.com/">phpBB Group</a>'; + echo $phpbb_seo->seo_end(true); + echo ' </div>'; + echo '</div>'; + echo '</body>'; + echo '</html>'; + if (!empty($db) && is_object($db)) { + $db->sql_close(); + } + exit; + } + /** + * Output an error message for a database related problem + * If skip is true, return and continue execution, else exit + */ + function db_error($error, $sql, $line, $file, $skip = false) { + global $user, $db, $template; + if ($skip) { + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $user->lang['INST_ERR_FATAL'], + )); + $template->assign_block_vars('checks', array( + 'TITLE' => basename($file) . ' [ ' . $line . ' ]', + 'RESULT' => '<b style="color:red">' . $error . '</b><br />» SQL:' . $sql, + )); + return; + } + $template->set_filenames(array( + 'body' => 'install_error.html') + ); + $this->page_header(); + $this->generate_navigation(); + $template->assign_vars(array( + 'MESSAGE_TITLE' => $user->lang['INST_ERR_FATAL_DB'], + 'MESSAGE_TEXT' => '<p>' . basename($file) . ' [ ' . $line . ' ]</p><p>SQL : ' . $sql . '</p><p><b>' . $error . '</b></p>', + )); + // Rollback if in transaction + if ($db->transaction) { + $db->sql_transaction('rollback'); + } + $this->page_footer(); + } +} +/** +* Installation Tabs +*/ +class install_phpbb_seo extends module { + var $errors = array(); + var $uninst_prefix = ''; + var $modrtype_lang = array(); + function install_phpbb_seo(&$p_master) { + global $user, $phpbb_seo, $config; + $this->modrtype_lang = set_phpbb_seo_links(); + $this->p_master = &$p_master; + } + function main($mode, $sub) { + global $user, $template, $phpbb_root_path, $phpbb_seo; + $this->uninst_prefix = $mode == 'install_phpbb_seo' ? '' : 'UN_'; + switch ($sub) { + case 'intro': + $this->page_title = $user->lang['SUB_INTRO']; + $template->assign_vars(array( + 'TITLE' => $user->lang[$this->uninst_prefix . 'SEO_INSTALL_INTRO'], + 'BODY' => sprintf($user->lang[$this->uninst_prefix . 'SEO_INSTALL_INTRO_BODY'], $this->modrtype_lang['ulink'], $phpbb_seo->version), + 'L_SUBMIT' => $user->lang[$this->uninst_prefix . 'SEO_INSTALL'], + 'S_LANG_SELECT' => '', + 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=final", + )); + break; + case 'final': + if ($mode == 'install_phpbb_seo') { + $this->add_modules($mode, $sub); + } else { + $this->remove_modules($mode, $sub); + } + $this->final_stage($mode, $sub); + break; + } + $this->tpl_name = 'install_install'; + } + /** + * Populate the module tables + */ + function add_modules($mode, $sub) { + global $db, $user, $phpbb_root_path, $phpEx; + include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); + $_module = new acp_modules(); + if ( $this->get_module_id('ACP_MOD_REWRITE') > 0 ) { + $url_mod = !empty($sub) ? '?mode=' . $mode : ''; + $this->p_master->error(sprintf($user->lang['SEO_ERROR_INSTALLED'], $user->lang['ACP_CAT_PHPBB_SEO'] ) . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->p_master->module_url . $url_mod . '">', '</a>'), '', '', false, $user->lang['SEO_ERROR_INFO']); + } + $module_classes = array('acp'); + // Add categories + foreach ($module_classes as $module_class) { + $categories = array(); + // Set the module class + $_module->module_class = $module_class; + foreach ($this->module_categories[$module_class] as $cat_name => $subs) { + $module_data = array( + 'module_basename' => '', + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => 0, + 'module_class' => $module_class, + 'module_langname' => $cat_name, + 'module_mode' => '', + 'module_auth' => '', + ); + if ( $this->get_module_id('ACP_CAT_PHPBB_SEO') < 1 ) { + // Add category + $_module->update_module_data($module_data, true); + } else { + $module_data['module_id'] = $this->check_module_id('ACP_CAT_PHPBB_SEO'); + } + // Check for last sql error happened + if ($db->sql_error_triggered) { + $error = $db->sql_error($db->sql_error_sql); + $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__); + } + $categories[$cat_name]['id'] = (int) $module_data['module_id']; + $categories[$cat_name]['parent_id'] = 0; + // Create sub-categories... + if (is_array($subs)) { + foreach ($subs as $level2_name) { + $module_data = array( + 'module_basename' => '', + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => (int) $categories[$cat_name]['id'], + 'module_class' => $module_class, + 'module_langname' => $level2_name, + 'module_mode' => '', + 'module_auth' => '', + ); + $_module->update_module_data($module_data, true); + // Check for last sql error happened + if ($db->sql_error_triggered) { + $error = $db->sql_error($db->sql_error_sql); + $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__); + } + $categories[$level2_name]['id'] = (int) $module_data['module_id']; + $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id']; + } + } + } + // Get the modules we want to add... returned sorted by name + $module_info = $_module->get_module_infos('phpbb_seo', $module_class); + foreach ($module_info as $module_basename => $fileinfo) { + foreach ($fileinfo['modes'] as $module_mode => $row) { + foreach ($row['cat'] as $cat_name) { + if (!isset($categories[$cat_name])) { + continue; + } + $module_data = array( + 'module_basename' => $module_basename, + 'module_enabled' => 1, + 'module_display' => (isset($row['display'])) ? (int) $row['display'] : 1, + 'parent_id' => (int) $categories[$cat_name]['id'], + 'module_class' => $module_class, + 'module_langname' => $row['title'], + 'module_mode' => $module_mode, + 'module_auth' => $row['auth'], + ); + $_module->update_module_data($module_data, true); + // Check for last sql error happened + if ($db->sql_error_triggered) { + $error = $db->sql_error($db->sql_error_sql); + $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__); + } + } + } + } + $_module->remove_cache_file(); + } + } + /** + * remove_modules + */ + function remove_modules($mode, $sub) { + global $db, $user, $phpbb_root_path, $phpEx; + include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx); + $_module = new acp_modules(); + // Set the module class + $module_classes = array_keys($this->module_categories); + $_module->u_action = "phpbb_seo_install.$phpEx"; + $cat_module_data = array(); + $module_data = array(); + $delete_module_data = array(); + foreach ($module_classes as $module_class) { + $_module->module_class = $module_class; + foreach ($this->module_categories[$module_class] as $cat_name => $subs) { + // If the cat is already uninstalled break for now + if ( $this->get_module_id($cat_name) < 1 ) { + $url_mod = !empty($this->sub) ? '?mode=' . $this->mode : ''; + $this->p_master->error(sprintf($user->lang['SEO_ERROR_UNINSTALLED'], $user->lang[$cat_name] ). '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->p_master->module_url . $url_mod . '">', '</a>'), '', '', false, $user->lang['SEO_ERROR_INFO']); + } + $cat_module_data[$cat_name] = array( + 'module_id' => $this->check_module_id($cat_name, ''), + 'module_basename' => '', + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => 0, + 'module_class' => $module_class, + 'module_langname' => $cat_name, + 'module_mode' => '', + 'module_auth' => '', + ); + if (is_array($subs)) { + foreach ($subs as $sub_cat) { + $sub_cat_module_data[$sub_cat] = array( + 'module_id' => $this->check_module_id($sub_cat), + 'module_basename' => '', + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => (int) $cat_module_data[$cat_name]['module_id'], + 'module_class' => $module_class, + 'module_langname' => $sub_cat, + 'module_mode' => '', + 'module_auth' => '', + ); + $branch = $_module->get_module_branch($sub_cat_module_data[$sub_cat]['module_id'],'children', 'descending', false); + if (sizeof($branch)) { + foreach ($branch as $module) { + $error = $_module->delete_module($module['module_id']); + if (!sizeof($error)) { + $_module->remove_cache_file(); + $delete_module_data[$module['module_id']] = $module['module_langname'] . ' - id : ' . $module['module_id']; + } else { + $this->errors[] = implode(' ', $error); + } + } // End modules + } + if (!sizeof($this->errors)) { + $error = $_module->delete_module($sub_cat_module_data[$sub_cat]['module_id']); + if (!sizeof($error)) { + $_module->remove_cache_file(); + $delete_module_data[$sub_cat_module_data[$sub_cat]['module_id']] = $sub_cat_module_data[$sub_cat]['module_langname'] . ' - id : ' . $sub_cat_module_data[$sub_cat]['module_id']; + } else { + $this->errors[] = implode(' ', $error); + } + } + } + } // End sub categories + if (!sizeof($this->errors)) { + $branch = $_module->get_module_branch($cat_module_data[$cat_name]['module_id'],'children', 'descending', false); + if (empty($branch)) { + $error = $_module->delete_module($cat_module_data[$cat_name]['module_id']); + } + if (!sizeof($error)) { + $_module->remove_cache_file(); + $delete_module_data[$cat_module_data[$cat_name]['module_id']] = $cat_module_data[$cat_name]['module_langname'] . ' - id : ' . $cat_module_data[$cat_name]['module_id']; + } else { + $this->errors[] = implode(' ', $error); + } + } + } // End categories + } // End classes + return; + } + /** + * check_module_id by title + */ + function check_module_id($title) { + global $user; + if ( $module_id = $this->get_module_id($title)) { + return $module_id; + } else { + $url_mod = !empty($this->sub) ? '?mode=' . $this->mode : ''; + $this->p_master->error(sprintf($user->lang['SEO_ERROR_ID'], $title ) . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->p_master->module_url . $url_mod . '">', '</a>'), '', '', false, $user->lang['SEO_ERROR_INFO']); + } + } + /** + * get_module_id by title + */ + function get_module_id($title) { + global $db, $user, $phpEx; + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $db->sql_escape($title) . "'"; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + if ($row['module_id'] > 1) { + return intval($row['module_id']); + } + return 0; + } + /** + * Sends an email to the board administrator with their password and some useful links + */ + function final_stage($mode, $sub) { + global $auth, $config, $db, $user, $template, $user, $phpbb_root_path, $phpEx, $phpbb_seo, $cache; + if (!sizeof($this->errors) ) { + add_log('admin', 'SEO_LOG_' . strtoupper($mode), $phpbb_seo->version ); + } else { + add_log('admin', 'SEO_LOG_' . strtoupper($mode) . '_FAIL', $this->errors); + $cache->purge(); + $this->p_master->error($user->lang['SEO_ERROR_INSTALL'] . '<br/><pre>' . implode('<br/>', $this->errors) . '</pre>', __LINE__, __FILE__); + } + $this->page_title = $user->lang['STAGE_FINAL']; + if (!class_exists('phpbb_db_tools')) { + include($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); + } + $db_tools = new phpbb_db_tools($db); + $indexes = $db_tools->sql_list_index(TOPICS_TABLE); + $drop_index_name = 'topic_last_post_id'; + $add_index_name = 'topic_lpid'; + if ( $mode == 'install_phpbb_seo' ) { + if (!$db_tools->sql_column_exists(TOPICS_TABLE, 'topic_url')) { + $db_tools->sql_column_add(TOPICS_TABLE, 'topic_url', array('VCHAR', '')); + } + if (in_array($drop_index_name, $indexes)) { + $db_tools->sql_index_drop(TOPICS_TABLE, $drop_index_name); + } + if (!in_array($add_index_name, $indexes)) { + $db_tools->sql_create_index(TOPICS_TABLE, $add_index_name, array('topic_last_post_id')); + } + $submit_action = append_sid($phpbb_root_path . 'adm/index.' . $phpEx . '?sid=' . $user->session_id); + $title = $user->lang['SEO_INSTALL_CONGRATS']; + $body = sprintf($user->lang['SEO_INSTALL_CONGRATS_EXPLAIN'], $this->modrtype_lang['ulink'], $phpbb_seo->version); + } else { + $purge_topic_table = false; + if ($purge_topic_table) { + if ($db_tools->sql_column_exists(TOPICS_TABLE, 'topic_url')) { + $db_tools->sql_column_remove(TOPICS_TABLE, 'topic_url'); + } + } + if (in_array($drop_index_name, $indexes)) { + $db_tools->sql_index_drop(TOPICS_TABLE, $drop_index_name); + } + if (in_array($add_index_name, $indexes)) { + $db_tools->sql_index_drop(TOPICS_TABLE, $add_index_name); + } + $submit_action = append_sid($phpbb_root_path . 'index.' . $phpEx); + $title = $user->lang['UN_SEO_INSTALL_CONGRATS']; + $body = sprintf($user->lang['UN_SEO_INSTALL_CONGRATS_EXPLAIN'], $this->modrtype_lang['ulink'], $phpbb_seo->version); + } + $cache->purge(); + $template->assign_vars(array( + 'TITLE' => $title, + 'BODY' => $body, + 'L_SUBMIT' => $user->lang['SEO_FINAL_' . strtoupper($mode)], + 'U_ACTION' => $submit_action, + )); + } + var $module_categories = array( + 'acp' => array( + 'ACP_CAT_PHPBB_SEO' => array( + 'ACP_MOD_REWRITE', + ), + ), + ); +} +function set_phpbb_seo_links() { + global $user, $phpbb_seo, $config; + $modrtype_lang = array(); + $phpbb_seo->version = htmlspecialchars($phpbb_seo->version); + $phpbb_seo->modrtype = intval($phpbb_seo->modrtype); + if ($phpbb_seo->modrtype < 1 || $phpbb_seo->modrtype > 3) { + $phpbb_seo->modrtype = 1; + } + $modrtype_lang['titles'] = array( 1 => $user->lang['ACP_SEO_SIMPLE'], 2 => $user->lang['ACP_SEO_MIXED'], 3 => $user->lang['ACP_SEO_ADVANCED'], 'u' => $user->lang['ACP_ULTIMATE_SEO_URL']); + $modrtype_lang['title'] = $modrtype_lang['titles'][$phpbb_seo->modrtype]; + $modrtype_lang['utitle'] = $modrtype_lang['titles']['u']; + $modrtype_lang['types'] = array( 1 => 'SIMPLE', 2 => 'MIXED', 1 => 'SIMPLE', 3 => 'ADVANCED'); + $modrtype_lang['type'] = $modrtype_lang['types'][$phpbb_seo->modrtype]; + $modrtype_lang['modrlinks_en'] = array( 1 => 'http://www.phpbb-seo.com/en/simple-seo-url/simple-phpbb-seo-url-t1566.html', 2 => 'http://www.phpbb-seo.com/en/mixed-seo-url/mixed-phpbb-seo-url-t1565.html', 3 => 'http://www.phpbb-seo.com/en/advanced-seo-url/advanced-phpbb-seo-url-t1219.html', 'u' => 'http://www.phpbb-seo.com/en/phpbb-mod-rewrite/ultimate-seo-url-t4608.html' ); + $modrtype_lang['modrlinks_fr'] = array( 1 => 'http://www.phpbb-seo.com/fr/reecriture-url-simple/seo-url-phpbb-simple-t1945.html', 2 => 'http://www.phpbb-seo.com/fr/reecriture-url-intermediaire/seo-url-intermediaire-t1946.html', 3 => 'http://www.phpbb-seo.com/fr/reecriture-url-avancee/seo-url-phpbb-avance-t1501.html', 'u' => 'http://www.phpbb-seo.com/fr/mod-rewrite-phpbb/ultimate-seo-url-t4489.html' ); + $modrtype_lang['modrforumlinks_en'] = array( 1 => 'http://www.phpbb-seo.com/en/simple-seo-url/', 2 => 'http://www.phpbb-seo.com/en/mixed-seo-url/', 3 => 'http://www.phpbb-seo.com/en/advanced-seo-url/', 'u' => 'http://www.phpbb-seo.com/en/phpbb-mod-rewrite/' ); + $modrtype_lang['modrforumlinks_fr'] = array( 1 => 'http://www.phpbb-seo.com/fr/reecriture-url-simple/', 2 => 'http://www.phpbb-seo.com/fr/reecriture-url-intermediaire/', 3 => 'http://www.phpbb-seo.com/fr/reecriture-url-avancee/', 'u' => 'http://www.phpbb-seo.com/fr/mod-rewrite-phpbb/' ); + if (strpos($config['default_lang'], 'fr') !== false ) { + $modrtype_lang['linkurl'] = $modrtype_lang['modrlinks_fr'][$phpbb_seo->modrtype]; + $modrtype_lang['forumlinkurl'] = $modrtype_lang['modrforumlinks_fr'][$phpbb_seo->modrtype]; + $modrtype_lang['ulinkurl'] = $modrtype_lang['modrlinks_fr']['u']; + $modrtype_lang['uforumlinkurl'] = $modrtype_lang['modrforumlinks_fr']['u']; + } else { + $modrtype_lang['linkurl'] = $modrtype_lang['modrlinks_en'][$phpbb_seo->modrtype]; + $modrtype_lang['forumlinkurl'] = $modrtype_lang['modrforumlinks_en'][$phpbb_seo->modrtype]; + $modrtype_lang['ulinkurl'] = $modrtype_lang['modrlinks_en']['u']; + $modrtype_lang['uforumlinkurl'] = $modrtype_lang['modrforumlinks_en']['u']; + } + $modrtype_lang['link'] = '<a href="' . $modrtype_lang['linkurl'] . '" title="' . $user->lang['ACP_PHPBB_SEO_VERSION'] . ' ' . $modrtype_lang['title'] . '" onclick="window.open(this.href); return false;"><b>' . $modrtype_lang['title'] . '</b></a>'; + $modrtype_lang['forumlink'] = '<a href="' . $modrtype_lang['forumlinkurl'] . '" title="' . $user->lang['ACP_SEO_SUPPORT_FORUM'] . '" onclick="window.open(this.href); return false;"><b>' . $user->lang['ACP_SEO_SUPPORT_FORUM'] . '</b></a>'; + $modrtype_lang['ulink'] = '<a href="' . $modrtype_lang['ulinkurl'] . '" title="' . $user->lang['ACP_PHPBB_SEO_VERSION'] . ' ' . $modrtype_lang['utitle'] . '" onclick="window.open(this.href); return false;"><b>' . $modrtype_lang['utitle'] . '</b></a>'; + $modrtype_lang['uforumlink'] = '<a href="' . $modrtype_lang['uforumlinkurl'] . '" title="' . $user->lang['ACP_SEO_SUPPORT_FORUM'] . '" onclick="window.open(this.href); return false;"><b>' . $user->lang['ACP_SEO_SUPPORT_FORUM'] . '</b></a>'; + return $modrtype_lang; +} +/** +* Main Tab - Overview +*/ +class overview_phpbb_seo extends module { + var $modrtype_lang = array(); + function overview_phpbb_seo(&$p_master) { + $this->modrtype_lang = set_phpbb_seo_links(); + $this->p_master = &$p_master; + } + function main($mode, $sub) { + global $lang, $template, $language, $user, $phpbb_seo; + switch ($sub) { + case 'intro' : + $title = $user->lang['SEO_OVERVIEW_TITLE']; + $body = sprintf($user->lang['SEO_OVERVIEW_BODY'], $this->modrtype_lang['ulink'], $phpbb_seo->version, $this->modrtype_lang['ulinkurl']); + break; + case 'license' : + $title = $user->lang['SEO_LICENCE_TITLE']; + $body = '<p>' . $user->lang['SEO_LICENCE_BODY'] . '</p><br/><hr/>' . implode("<br/>\n", file('./docs/COPYING')); + break; + case 'support' : + $title = $user->lang['SEO_SUPPORT_TITLE']; + $body = sprintf($user->lang['SEO_SUPPORT_BODY'],$this->modrtype_lang['uforumlinkurl'], $this->modrtype_lang['utitle'], $this->modrtype_lang['ulinkurl'] ); + break; + } + $this->tpl_name = 'install_main'; + $this->page_title = $title; + $template->assign_vars(array( + 'TITLE' => $title, + 'BODY' => $body, + + 'S_LANG_SELECT' => '', + )); + } +} +/** +* Quick fix for using the module class outside ACP. +*/ +function adm_back_link($u_action) { + global $user, $install; + $url_mod = !empty($install->sub) ? '?mode=' . $install->mode : ''; + return '<br /><br /><a href="' . $install->module_url . $url_mod . '">« ' . $user->lang['BACK_TO_PREV'] . '</a>'; +} +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/phpbb_seo_meta.php b/phpBB/phpbb_seo/phpbb_seo_meta.php new file mode 100644 index 0000000000..386eac92ca --- /dev/null +++ b/phpBB/phpbb_seo/phpbb_seo_meta.php @@ -0,0 +1,271 @@ +<?php +/** +* +* @package phpBB SEO Dynamic Meta tags +* @version $Id: phpbb_seo_meta.php 252 2010-03-12 09:23:51Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) { + exit; +} +/** +* seo_meta Class +* www.phpBB-SEO.com +* @package phpBB SEO Dynamic Meta tags +*/ +class seo_meta { + var $meta = array('title' => '', 'description' => '', 'keywords' => '', 'lang' => '', 'category' => '', 'robots' => '', 'distribution' => '', 'resource-type' => '', 'copyright' => ''); + var $meta_def = array(); + var $filters = array('description' => 'meta_filter_txt', 'keywords' => 'make_keywords'); + // here you can comment a tag line to deactivate it + var $tpl = array( + 'lang' => '<meta name="content-language" content="%s" />', + 'title' => '<meta name="title" content="%s" />', + 'description' => '<meta name="description" content="%s" />', + 'keywords' => '<meta name="keywords" content="%s" />', + 'category' => '<meta name="category" content="%s" />', + 'robots' => '<meta name="robots" content="%s" />', + 'distribution' => '<meta name="distribution" content="%s" />', + 'resource-type' => '<meta name="resource-type" content="%s" />', + 'copyright' => '<meta name="copyright" content="%s" />', + ); + /** + * Some config : + * => keywordlimit : number of keywords (max) in the keyword tag, + * => wordlimit : number of words (max) in the desc tag, + * => wordminlen : only words with more than wordminlen letters will be used, default is 2, + * => bbcodestrip : | separated list of bbcode to fully delete, tag + content, default is 'img|url|flash', + * => ellipsis : ellipsis to use if clipping, + * => topic_sql : Do a SQL to build topic meta keywords or just use the meta desc tag, + * => check_ignore : Check the search_ignore_words.php list. + * Please note : + * This will require some more work for the server. + * And this is mostly useless if you have re-enabled the search_ignore_words.php list + * filtering in includes/search/fulltest_native.php (and of course use fulltest_native index). + * => bypass_common : Bypass common words in viewtopic.php. + * Set to true by default because the most interesting keywords are as well among the most common. + * This of course provides with even better results when fulltest_native is used + * and search_ignore_words.php list was re-enabled. + * => get_filter : Disallow tag based on GET var used : coma separated list, will through a disallow meta tag. + * => file_filter : Disallow tag based on the physical script file name : coma separated list of file names + * Some default values are set bellow in the seo_meta_tags() method, + * most are acp configurable when using the Ultimate SEO URL mod : + * => http://www.phpbb-seo.com/en/phpbb-mod-rewrite/ultimate-seo-url-t4608.html (en) + * => http://www.phpbb-seo.com/fr/mod-rewrite-phpbb/ultimate-seo-url-t4489.html (fr) + **/ + var $mconfig = array('keywordlimit' => 15, 'wordlimit' => 25, 'wordminlen' => 2, 'bbcodestrip' => 'img|url|flash|code', 'ellipsis' => ' ...', 'topic_sql' => true, 'check_ignore' => false, 'bypass_common' => true, + // Consider adding ", 'p' => 1" if your forum is no indexed yet or if no post urls are to be redirected + // to add a noindex tag on post urls + 'get_filter' => 'style,hilit,sid', + // noindex based on physical script file name + 'file_filter' => 'ucp', + ); + /** + * constructor : Initialize meta tags + * All values from here will pass through utf8_htmlspecialchars() later + */ + function seo_meta() { + global $config; + // default values, leave empty to only output the corresponding tag if filled + $this->meta_def['robots'] = 'index,follow'; + // global values, if these are empty, the corresponding meta will not show up + $this->meta['category'] = 'general'; + $this->meta['distribution'] = 'global'; + $this->meta['resource-type'] = 'document'; + // other settings that may be set through acp in cas the mod is not used standalone + if (isset($config['seo_meta_desc_limit'])) { + // defaults + $this->meta_def['title'] = $config['seo_meta_title']; + $this->meta_def['description'] = $config['seo_meta_desc']; + $this->meta_def['keywords'] = $config['seo_meta_keywords']; + $this->meta_def['robots'] = $config['seo_meta_robots']; + // global + $this->meta['lang'] = $config['seo_meta_lang']; + $this->meta['copyright'] = $config['seo_meta_copy']; + // settings + $this->mconfig['wordlimit'] = (int) $config['seo_meta_desc_limit']; + $this->mconfig['keywordlimit'] = (int) $config['seo_meta_keywords_limit']; + $this->mconfig['wordminlen'] = (int) $config['seo_meta_min_len']; + $this->mconfig['check_ignore'] = (int) $config['seo_meta_check_ignore']; + $this->mconfig['file_filter'] = preg_replace('`[\s]+`', '', trim($config['seo_meta_file_filter'], ', ')); + $this->mconfig['get_filter'] = preg_replace('`[\s]+`', '', trim($config['seo_meta_get_filter'], ', ')); + $this->mconfig['bbcodestrip'] = str_replace(',', '|', preg_replace('`[\s]+`', '', trim($config['seo_meta_bbcode_filter'], ', '))); + } else { + // default values, leave empty to only output the corresponding tag if filled + $this->meta_def['title'] = $config['sitename']; + $this->meta_def['description'] = $config['site_desc']; + $this->meta_def['keywords'] = $config['site_desc']; + // global values, if these are empty, the corresponding meta will not show up + $this->meta['lang'] = $config['default_lang']; + $this->meta['copyright'] = $config['sitename']; + } + $this->mconfig['get_filter'] = !empty($this->mconfig['get_filter']) ? @explode(',', $this->mconfig['get_filter']) : array(); + $this->mconfig['topic_sql'] = $config['search_type'] == 'fulltext_native' ? $this->mconfig['topic_sql'] : false; + return; + } + /** + * assign / retrun meta tag code + */ + function build_meta( $page_title = '', $return = false) { + global $phpEx, $user, $phpbb_seo, $template, $config; + // If meta robots was not manually set + if (empty($this->meta['robots'])) { + // If url Rewriting is on, we shall be more strict on noindex (since we can :p) + if (!empty($phpbb_seo->seo_opt['url_rewrite'])) { + // If url Rewriting is on, we can deny indexing for any rewritten url with ? + if (preg_match('`(\.html?|/)\?[^\?]*$`i', $phpbb_seo->seo_path['uri'])) { + $this->meta['robots'] = 'noindex,follow'; + } else { + // lets still add some more specific ones + $this->mconfig['get_filter'] = array_merge($this->mconfig['get_filter'], array('st','sk','sd','ch')); + } + } + // Do we allow indexing based on physical script file name + if (empty($this->meta['robots'])) { + if (strpos($this->mconfig['file_filter'], str_replace(".$phpEx", '', $user->page['page_name'])) !== false) { + $this->meta['robots'] = 'noindex,follow'; + } + } + // Do we allow indexing based on get variable + if (empty($this->meta['robots'])) { + foreach ( $this->mconfig['get_filter'] as $get ) { + if (isset($_GET[$get])) { + $this->meta['robots'] = 'noindex,follow'; + break; + } + } + } + // fallback to default if necessary + if (empty($this->meta['robots'])) { + $this->meta['robots'] = $this->meta_def['robots']; + } + } + if (!empty($config['seo_meta_noarchive'])) { + $forum_id = isset($_GET['f']) ? max(0, (int) request_var('f', 0)) : 0; + if ($forum_id) { + $forum_ids = @explode(',', preg_replace('`[\s]+`', '', trim($config['seo_meta_noarchive'], ', '))); + if (in_array($forum_id, $forum_ids)) { + $this->meta['robots'] .= (!empty($this->meta['robots']) ? ',' : '') . 'noarchive'; + } + } + } + // deal with titles, assign the tag if a default is set + if (empty($this->meta['title']) && !empty($this->meta_def['title'])) { + $this->meta['title'] = $page_title; + } + $meta_code = ''; + foreach ($this->tpl as $key => $value) { + if (isset($this->meta[$key])) { + // do like this so we can deactivate one particular tag on a given page, + // by just setting the meta to an empty string + if (trim($this->meta[$key])) { + $this->meta[$key] = isset($this->filters[$key]) ? $this->{$this->filters[$key]}($this->meta[$key]) : $this->meta[$key]; + } + } else if (!empty($this->meta_def[$key])) { + $this->meta[$key] = isset($this->filters[$key]) ? $this->{$this->filters[$key]}($this->meta_def[$key]) : $this->meta_def[$key]; + } + if (trim($this->meta[$key])) { + $meta_code .= sprintf($value, utf8_htmlspecialchars($this->meta[$key])) . "\n"; + } + } + if (!$return) { + $template->assign_var('META_TAG', $meta_code); + } else { + return $meta_code; + } + } + /** + * Returns a coma separated keyword list + */ + function make_keywords($text, $decode_entities = false) { + static $filter = array('`&(amp;)?[^;]+;`i', '`[[:punct:]]+`', '`[0-9]+`', '`[\s]+`'); + $keywords = ''; + $num = 0; + $text = $decode_entities ? html_entity_decode(strip_tags($text), ENT_COMPAT, 'UTF-8') : strip_tags($text); + $text = utf8_strtolower(trim(preg_replace($filter, ' ', $text))); + if (!$text) { + return ''; + } + $text = explode(' ', trim($text)); + if ($this->mconfig['check_ignore']) { + global $phpbb_root_path, $user, $phpEx; + // add stop words to $user to allow reuse + if (empty($user->stop_words)) { + $words = array(); + if (file_exists("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx")) { + // include the file containing ignore words + include("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx"); + } + $user->stop_words = & $words; + } + $text = array_diff($text, $user->stop_words); + } + if (empty($text)) { + return ''; + } + // We take the most used words first + $text = array_count_values($text); + arsort($text); + foreach ($text as $word => $count) { + if ( utf8_strlen($word) > $this->mconfig['wordminlen'] ) { + $keywords .= ', ' . $word; + $num++; + if ( $num >= $this->mconfig['keywordlimit'] ) { + break; + } + } + } + return trim($keywords, ', '); + } + /** + * Filter php/html tags and white spaces and string with limit in words + */ + function meta_filter_txt($text, $bbcode = true) { + if ($bbcode) { + static $RegEx = array(); + static $replace = array(); + if (empty($RegEx)) { + $RegEx = array('`&(amp;)?[^;]+;`i', // HTML entitites + '`<[^>]*>(.*<[^>]*>)?`Usi', // HTML code + ); + $replace = array(' ', ' '); + if (!empty($this->mconfig['bbcodestrip'])) { + $RegEx[] = '`\[(' . $this->mconfig['bbcodestrip'] . ')[^\[\]]*\].*\[/\1[^\[\]]*\]`Usi'; // bbcode to strip + $replace[] = ' '; + } + $RegEx[] = '`\[\/?[a-z0-9\*\+\-]+(?:=(?:".*"|[^\]]*))?(?::[a-z])?(\:[0-9a-z]{5,})\]`'; // Strip all bbcode tags + $replace[] = ''; + $RegEx[] = '`[\s]+`'; // Multiple spaces + $replace[] = ' '; + } + return $this->word_limit(preg_replace($RegEx, $replace, $text)); + } + return $this->word_limit(preg_replace(array('`<[^>]*>(.*<[^>]*>)?`Usi', '`\[\/?[a-z0-9\*\+\-]+(?:=(?:".*"|[^\]]*))?(?::[a-z])?(\:[0-9a-z]{5,})\]`', '`[\s]+`'), ' ', $text)); + } + /** + * Cut the text according to the number of words. + * Borrowed from www.php.net http://www.php.net/preg_replace + */ + function word_limit($string) { + return count($words = preg_split('/\s+/', ltrim($string), $this->mconfig['wordlimit'] + 1)) > $this->mconfig['wordlimit'] ? rtrim(utf8_substr($string, 0, utf8_strlen($string) - utf8_strlen(end($words)))) . $this->mconfig['ellipsis'] : $string; + } + /** + * add meta tag + * $content : if empty, the called tag will show up + * do not call to fall back to default + */ + function collect($type, $content = '', $combine = false) { + if ($combine) { + $this->meta[$type] = (isset($this->meta[$type]) ? $this->meta[$type] . ' ' : '') . (string) $content; + } else { + $this->meta[$type] = (string) $content; + } + } +} +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/phpbb_seo_related.php b/phpBB/phpbb_seo/phpbb_seo_related.php new file mode 100644 index 0000000000..d8e1802f1c --- /dev/null +++ b/phpBB/phpbb_seo/phpbb_seo_related.php @@ -0,0 +1,243 @@ +<?php +/** +* +* @package phpBB SEO Related topics +* @version $Id: phpbb_seo_related.php 222 2010-02-27 13:08:48Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) { + exit; +} +/** +* seo_related Class +* www.phpBB-SEO.com +* @package phpBB SEO Related topics +*/ +class seo_related { + var $fulltext = true; + var $limit = 5; + var $allforums = false; + var $check_ignore = false; + /** + * constructor + */ + function seo_related() { + global $db, $config; + if (empty($config['seo_related'])) { + return; + } + // override the above defaults when the acp is in use + $this->limit = !empty($config['seo_related_limit']) ? max(1, (int) $config['seo_related_limit']) : $this->limit; + $this->allforums = isset($config['seo_related_allforums']) ? max(0, (int) $config['seo_related_allforums']) : $this->allforums; + $this->check_ignore = isset($config['seo_related_check_ignore']) ? max(0, (int) $config['seo_related_check_ignore']) : $this->check_ignore; + // better to always check, since it's fast + if ($db->sql_layer != 'mysql4' && $db->sql_layer != 'mysqli') { + $this->fulltext = false; + } else { + $this->fulltext = isset($config['seo_related_fulltext']) ? max(0, (int) $config['seo_related_fulltext']) : $this->fulltext; + } + } + /** + * get related topic list + * @param array $topic_data shuld at least provide with topic_id and topic_title + * @param mixed $forum_id The forum id to search in (false / 0 / null to search into all forums) + * */ + function get($topic_data, $forum_id = false) { + global $db, $auth, $cache, $template, $user, $phpEx, $phpbb_root_path, $topic_tracking_info, $config, $phpbb_seo; + if (empty($config['seo_related'])) { + return; + } + $related_result = false; + $enable_icons = 0; + $this->allforums = !$forum_id ? true : $this->allforums; + $sql = $this->build_query($topic_data, $forum_id); + if ($sql && ($result = $db->sql_query_limit($sql, $this->limit))) { + // Grab icons + $icons = $cache->obtain_icons(); + $attachement_icon = $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']); + $s_attachement = $auth->acl_get('u_download'); + while($row = $db->sql_fetchrow($result)) { + $related_forum_id = (int) $row['forum_id']; + $related_topic_id = (int) $row['topic_id']; + $enable_icons = max($enable_icons, $row['enable_icons']); + if ($auth->acl_get('f_list', $related_forum_id)) { + $row['topic_title'] = censor_text($row['topic_title']); + // www.phpBB-SEO.com SEO TOOLKIT BEGIN + if (!empty($phpbb_seo->seo_opt['url_rewrite'])) { + $phpbb_seo->set_url($row['forum_name'], $related_forum_id, $phpbb_seo->seo_static['forum']); + $phpbb_seo->prepare_iurl($row, 'topic', $row['topic_type'] == POST_GLOBAL ? $phpbb_seo->seo_static['global_announce'] : $phpbb_seo->seo_url['forum'][$related_forum_id]); + } + // www.phpBB-SEO.com SEO TOOLKIT END + // Replies + $replies = ($auth->acl_get('m_approve', $related_forum_id)) ? $row['topic_replies_real'] : $row['topic_replies']; + $unread_topic = (isset($topic_tracking_info[$related_topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$related_topic_id]) ? true : false; + $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$related_forum_id&t=$related_topic_id"); + $topic_unapproved = (!$row['topic_approved'] && $auth->acl_get('m_approve', $related_forum_id)) ? true : false; + $u_mcp_queue = ($topic_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&mode=approve_details&t=$related_topic_id", true, $user->session_id) : ''; + // Get folder img, topic status/type related information + $folder_img = $folder_alt = $topic_type = ''; + topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type); + // www.phpBB-SEO.com SEO TOOLKIT BEGIN -> no dupe + if (!empty($phpbb_seo->seo_opt['no_dupe']['on'])) { + if (($replies + 1) > $phpbb_seo->seo_opt['topic_per_page']) { + $phpbb_seo->seo_opt['topic_last_page'][$related_topic_id] = floor($replies / $phpbb_seo->seo_opt['topic_per_page']) * $phpbb_seo->seo_opt['topic_per_page']; + } + } + // www.phpBB-SEO.com SEO TOOLKIT END -> no dupe + $template->assign_block_vars('related', array( + 'TOPIC_TITLE' => $row['topic_title'], + 'U_TOPIC' => $view_topic_url, + 'U_FORUM' => $this->allforums ? append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$related_forum_id") : '', + 'FORUM' => $row['forum_name'], + 'PAGINATION' => topic_generate_pagination($replies, $view_topic_url), + 'REPLIES' => $replies, + 'VIEWS' => $row['topic_views'], + 'FIRST_POST_TIME' => $user->format_date($row['topic_time']), + 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), + 'TOPIC_AUTHOR_FULL' => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), + 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), + // www.phpBB-SEO.com SEO TOOLKIT BEGIN -> no dupe + 'U_LAST_POST' => !empty($phpbb_seo->seo_opt['no_dupe']['on']) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$related_forum_id&t=$related_topic_id&start=" . @intval($phpbb_seo->seo_opt['topic_last_page'][$related_topic_id])) . '#p' . $row['topic_last_post_id'] : append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$related_forum_id&t=$related_topic_id&p=" . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'], + // www.phpBB-SEO.com SEO TOOLKIT END -> no dupe + 'TOPIC_FOLDER_IMG_SRC' => $user->img($folder_img, $folder_alt, false, '', 'src'), + 'TOPIC_FOLDER_IMG' => $user->img($folder_img, $folder_alt, false), + 'TOPIC_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '', + 'ATTACH_ICON_IMG' => ($row['topic_attachment'] && $s_attachement) ? $attachement_icon : '', + 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $related_forum_id)) ? true : false, + 'S_UNREAD_TOPIC' => $unread_topic, + 'S_POST_ANNOUNCE' => ($row['topic_type'] == POST_ANNOUNCE) ? true : false, + 'S_POST_GLOBAL' => ($row['topic_type'] == POST_GLOBAL) ? true : false, + 'S_POST_STICKY' => ($row['topic_type'] == POST_STICKY) ? true : false, + 'S_TOPIC_LOCKED' => ($row['topic_status'] == ITEM_LOCKED) ? true : false, + 'S_TOPIC_UNAPPROVED' => $topic_unapproved, + 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=reports&f=' . $related_forum_id . '&t=' . $related_topic_id, true, $user->session_id), + 'U_MCP_QUEUE' => $u_mcp_queue, + )); + $related_result = true; + } + } + $db->sql_freeresult($result); + } + if ($related_result) { + $template->assign_vars(array( + 'S_RELATED_RESULTS' => $related_result, + 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'), + 'NEWEST_POST_IMG' => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'), + 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'), + 'REPORTED_IMG' => $user->img('icon_topic_reported', 'TOPIC_REPORTED'), + 'GOTO_PAGE_IMG' => $user->img('icon_post_target', 'GOTO_PAGE'), + 'S_TOPIC_ICONS' => $enable_icons, + )); + } + } + /** + * build_query + * @param array $topic_data shuld at least provide with topic_id and topic_title + * @param mixed $forum_id The forum id to search in (false / 0 / null to search into all forums) + */ + function build_query($topic_data, $forum_id = false) { + global $db; + if (!($match = $this->prepare_match($topic_data['topic_title']))) { + return false; + } + if (!$forum_id || $this->allforums) { + global $auth; + // Do not include those forums the user is not having read access to... + $related_read_ary = $auth->acl_getf('f_read', true); + $related_forum_ids = array(); + foreach ($related_read_ary as $_forum_id => $null) { + $related_forum_ids[$_forum_id] = (int) $_forum_id; + } + $forum_sql = sizeof($related_forum_ids) ? $db->sql_in_set('t.forum_id', $related_forum_ids, false, true) . ' AND ' : ''; + } else { + $forum_sql = ' t.forum_id = ' . (int) $forum_id . ' AND '; + } + $sql_array = array( + 'SELECT' => 't.*, f.forum_name, f.enable_icons', + 'FROM' => array( + TOPICS_TABLE => 't', + FORUMS_TABLE => 'f' + ), + 'WHERE' => "$forum_sql f.forum_id = t.forum_id", + ); + if ($this->fulltext) { + $sql_array['SELECT'] .= ", MATCH (t.topic_title) AGAINST ('" . $db->sql_escape($match) . "') relevancy"; + $sql_array['WHERE'] .= " AND MATCH (t.topic_title) AGAINST ('" . $db->sql_escape($match) . "')"; + $sql_array['ORDER_BY'] = 'relevancy DESC'; + } else { + $sql_like = $this->buil_sql_like($match); + if (!$sql_like) { + return false; + } + $sql_array['WHERE'] .= " AND t.topic_title $sql_like"; + $sql_array['ORDER_BY'] = 't.topic_id DESC'; + } + $sql_array['WHERE'] .= " AND t.topic_status <> " . ITEM_MOVED . " + AND t.topic_id <> " . (int) $topic_data['topic_id']; + return $db->sql_build_query('SELECT', $sql_array); + } + /** + * prepare_match : Prepares the word list to search for + * @param string $text the string of all words to search for, eg topic_title + * @param int $min_lenght word with less than $min_lenght letters will be dropped + * @param int $max_lenght word with more than $max_lenght letters will be dropped + */ + function prepare_match($text, $min_lenght = 3, $max_lenght = 14) { + $word_list = array(); + $text = trim(preg_replace('`[\s]+`', ' ', $text)); + if (!empty($text)) { + $word_list = array_unique(explode(' ', utf8_strtolower($text))); + foreach ($word_list as $k => $word) { + $len = utf8_strlen(trim($word)); + if ( ($len < $min_lenght) || ($len > $max_lenght) ) { + unset($word_list[$k]); + } + } + } + if (!empty($word_list) && $this->check_ignore) { + global $phpbb_root_path, $user, $phpEx; + // add stop words to $user to allow reuse + if (empty($user->stop_words)) { + $words = array(); + if (file_exists("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx")){ + // include the file containing ignore words + include("{$user->lang_path}{$user->lang_name}/search_ignore_words.$phpEx"); + } + $user->stop_words = & $words; + } + $word_list = array_diff($word_list, $user->stop_words); + } + return !empty($word_list) ? implode(' ', $word_list) : ''; + } + /** + * buil_sql_like + * @param string $text the string of all words to search for,prepared with prepare_match + * @param int $limit maxximum number of words to use in the query + */ + function buil_sql_like($text, $limit = 3) { + global $db; + $sql_like = ''; + $i = 0; + $text = str_replace(array('_', '%'), array("\_", "\%"), $text); + $text = str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $text); + $text = explode(' ', trim(preg_replace('`[\s]+`', ' ', $text))); + if ( !empty($text) ) { + foreach ($text as $word) { + $word = $db->sql_escape(trim($word)); + $sql_like .= empty($sql_like) ? " LIKE '%$word%'" : " OR '%$word%'"; + $i++; + if ($i >= $limit) { + return $sql_like; + } + } + } + return $sql_like; + } +} +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/phpbb_seo_related_install.php b/phpBB/phpbb_seo/phpbb_seo_related_install.php new file mode 100644 index 0000000000..728a8fe5b7 --- /dev/null +++ b/phpBB/phpbb_seo/phpbb_seo_related_install.php @@ -0,0 +1,193 @@ +<?php +/** +* +* @package phpBB SEO Related topics +* @version $Id: phpbb_seo_related_install.php 222 2010-02-27 13:08:48Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +/* + * Based on the phpBB3 install package / www.phpBB.com + */ +define('IN_PHPBB', true); +define('IN_INSTALL', true); +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); +// Try to override some limits - maybe it helps some... +@set_time_limit(0); +$mem_limit = @ini_get('memory_limit'); +if (!empty($mem_limit)) { + $unit = strtolower(substr($mem_limit, -1, 1)); + $mem_limit = (int) $mem_limit; + if ($unit == 'k') { + $mem_limit = floor($mem_limit / 1024); + } else if ($unit == 'g') { + $mem_limit *= 1024; + } else if (is_numeric($unit)) { + $mem_limit = floor((int) ($mem_limit . $unit) / 1048576); + } + $mem_limit = max(128, $mem_limit) . 'M'; +} else { + $mem_limit = '128M'; +} +@ini_set('memory_limit', $mem_limit); +include($phpbb_root_path . 'common.' . $phpEx); +// Start session management +$user->session_begin(); +$auth->acl($user->data); +$user->setup('mods/phpbb_seo_related_install'); +// Security check +// Circumvent a potential phpbb bug with paths +$redirect = append_sid(generate_board_url() . "/phpbb_seo/phpbb_seo_related_install.$phpEx"); +if (!$user->data['is_registered']) { + login_box($redirect, $user->lang['SEO_LOGIN'],'', false, false); +} +if (!$auth->acl_get('a_')) { + $user->session_kill(true); + login_box($redirect, $user->lang['SEO_LOGIN_ADMIN'],'', false, false); +} +if ($user->data['user_type'] != USER_FOUNDER) { + login_box($redirect, $user->lang['SEO_LOGIN_FOUNDER'],'', false, false); +} +$mode = request_var('mode', 'start'); + +/** +* seo_related_install Class +* www.phpBB-SEO.com +* @package phpBB SEO Related topics +*/ +class seo_related_install { + var $force_check = 0; + var $mode = 'install'; + var $silent = false; + var $config_names = array('seo_related', 'seo_related_fulltext', 'seo_related_check_ignore', 'seo_related_limit', 'seo_related_allforums'); + /** + * constructor + */ + function seo_related_install($mode, $force_check = 0, $silent = false) { + $this->force_check = $force_check ? $force_check : max(0, request_var('force_check', 0)); + $this->mode = $mode === 'install' ? 'install' : ($mode === 'uninstall' ? 'uninstall' : 'start'); + $this->silent = $silent ? true : false; + $this->{$this->mode}(); + } + /** + * start + */ + function start() { + global $phpbb_root_path, $phpEx, $msg_title, $user; + $install_url = append_sid($phpbb_root_path . "phpbb_seo/phpbb_seo_related_install.$phpEx?mode=install"); + $install_force_url = append_sid($phpbb_root_path . "phpbb_seo/phpbb_seo_related_install.$phpEx?mode=install&force_check=1"); + $uninstall_url = append_sid($phpbb_root_path . "phpbb_seo/phpbb_seo_related_install.$phpEx?mode=uninstall"); + $msg_title = $user->lang['INSTALLATION']; + $msg = sprintf($user->lang['INSTALLATION_START'], $install_url, $install_force_url, $uninstall_url); + trigger_error($msg); + } + /** + * install + */ + function install() { + global $db, $config, $user; + $fulltext = $already_installed = 0; + $no_error = 1; + $errno = E_USER_NOTICE; + $msg = $user->lang['INSTALLED']; + if (!isset($config['seo_related']) || $this->force_check) { + if ($db->sql_layer == 'mysql4' || $db->sql_layer == 'mysqli') { + // we can proceed with trying to add fulltext + global $phpbb_root_path, $phpEx; + if (!class_exists('phpbb_db_tools')) { + include($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); + } + $db_tools = new phpbb_db_tools($db); + $indexes = $db_tools->sql_list_index(TOPICS_TABLE); + if (!in_array('topic_tft', $indexes)) { + $sql = 'ALTER TABLE ' . TOPICS_TABLE . ' + ADD FULLTEXT topic_tft (topic_title)'; + $db->sql_return_on_error(true); + $db->sql_query($sql); + if ($db->sql_error_triggered) { + $no_error = 0; + $errno = E_USER_WARNING; + $msg = $user->lang['INSTALLATION']; + $msg .= '<br/>' . sprintf($user->lang['SQL_REQUIRED'], $db->sql_error_sql); + } + $db->sql_return_on_error(false); + } + // make *sure* we have the index ! + $indexes = $db_tools->sql_list_index(TOPICS_TABLE); + $fulltext = in_array('topic_tft', $indexes) ? 1 : 0; + } + } else { + $msg = $user->lang['ALREADY_INSTALLED']; + $already_installed = 1; + } + if ($no_error) { + if (!$already_installed) { + set_config('seo_related_fulltext', $fulltext); + $msg .= '<br/>' . ($fulltext ? $user->lang['FULLTEXT_INSTALLED'] : $user->lang['FULLTEXT_NOT_INSTALLED']); + } + set_config('seo_related', 1); + } + // Log this since it could help some to understand + add_log('admin', $msg); + if (!$this->silent) { + trigger_error($msg, $errno); + } else { + return $no_error ? true : false; + } + } + /** + * uninstall + */ + function uninstall() { + global $db, $config, $cache, $phpbb_root_path, $phpEx, $user; + $no_error = 1; + $errno = E_USER_NOTICE; + $msg = $user->lang['UNINSTALLED']; + // use db_tools to check the index + if (!class_exists('phpbb_db_tools')) { + include($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); + } + $db_tools = new phpbb_db_tools($db); + $indexes = $db_tools->sql_list_index(TOPICS_TABLE); + if (in_array('topic_tft', $indexes)) { + $sql = 'ALTER TABLE ' . TOPICS_TABLE . ' + DROP INDEX topic_tft'; + $db->sql_return_on_error(true); + $db->sql_query($sql); + if ($db->sql_error_triggered) { + $msg = $user->lang['UNINSTALLATION']; + $msg .= '<br/>' . sprintf($user->lang['SQL_REQUIRED'], $db->sql_error_sql); + $no_error = 0; + $errno = E_USER_WARNING; + } + $db->sql_return_on_error(false); + } + $did_something = false; + foreach ($this->config_names as $config_name) { + if (isset($config[$config_name])) { + $sql = 'DELETE FROM ' . CONFIG_TABLE . " + WHERE config_name = '" . $db->sql_escape($config_name) . "'"; + $db->sql_query($sql); + unset($config[$config_name]); + $did_something = true; + } + } + if ($did_something) { + $cache->destroy('config'); + } else { + $msg = $user->lang['ALREADY_UNINSTALLED']; + } + // Log this since it could help some to understand + add_log('admin', $msg); + if (!$this->silent) { + trigger_error($msg, $errno); + } else { + return $no_error ? true : false; + } + } +} +$seo_related_install = new seo_related_install($mode); +?>
\ No newline at end of file diff --git a/phpBB/phpbb_seo/sync_url.php b/phpBB/phpbb_seo/sync_url.php new file mode 100644 index 0000000000..9d814837f5 --- /dev/null +++ b/phpBB/phpbb_seo/sync_url.php @@ -0,0 +1,141 @@ +<?php +/** +* +* @package Ultimate SEO URL phpBB SEO +* @version $Id: sync_url.php 222 2010-02-27 13:08:48Z dcz $ +* @copyright (c) 2006 - 2010 www.phpbb-seo.com +* @license http://www.opensource.org/licenses/rpl1.5.txt Reciprocal Public License 1.5 +* +*/ +define('IN_PHPBB', true); +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); +// Try to override some limits - maybe it helps some... +@set_time_limit(0); +$mem_limit = @ini_get('memory_limit'); +if (!empty($mem_limit)) { + $unit = strtolower(substr($mem_limit, -1, 1)); + $mem_limit = (int) $mem_limit; + if ($unit == 'k') { + $mem_limit = floor($mem_limit / 1024); + } else if ($unit == 'g') { + $mem_limit *= 1024; + } else if (is_numeric($unit)) { + $mem_limit = floor((int) ($mem_limit . $unit) / 1048576); + } + $mem_limit = max(128, $mem_limit) . 'M'; +} else { + $mem_limit = '128M'; +} +@ini_set('memory_limit', $mem_limit); +include($phpbb_root_path . 'common.' . $phpEx); + +// Start session management +$user->session_begin(); +$auth->acl($user->data); +$user->setup('mods/acp_phpbb_seo'); +// Security check +// Circumvent a potential phpbb bug with paths +$redirect = append_sid(generate_board_url() . "/phpbb_seo/sync_url.$phpEx"); +if (!$user->data['is_registered']) { + login_box($redirect, $user->lang['SEO_LOGIN'],'', false, false); +} +if (!$auth->acl_get('a_')) { + $user->session_kill(true); + login_box($redirect, $user->lang['SEO_LOGIN_ADMIN'],'', false, false); +} +if ($user->data['user_type'] != USER_FOUNDER) { + login_box($redirect, $user->lang['SEO_LOGIN_FOUNDER'],'', false, false); +} +$start = max(0, request_var('start', 0)); +$limit = max(100, request_var('limit', 0)); +// Do not go over 1000 topic in a row +$limit = min(1000, $limit); +$go = max(0, request_var('go', 0)); +$mode = request_var('mode', ''); +$poll_processed = 0; +// Add navigation links +$template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => "Sync Topic URL", + 'U_VIEW_FORUM' => append_sid("./sync_url.$phpEx")) +); +$msg_title = $user->lang['SYNC_TITLE']; +if (empty($phpbb_seo->seo_opt['sql_rewrite'])) { + trigger_error($user->lang['SYNC_REQ_SQL_REW'], E_USER_WARNING); +} +if(!$go) { + trigger_error($user->lang['SYNC_WARN'] . '<br/><br/><b> • <a href="' . append_sid("./sync_url.$phpEx?go=1&mode=sync") . '">' . $user->lang['SYNC_TOPIC_URLS'] . '</a><br/><br/> • <a href="' . append_sid("./sync_url.$phpEx?go=1&mode=reset") . '" >' . $user->lang['SYNC_RESET_TOPIC_URLS'] . '</a></b>'); +} + +$forum_data = array(); +$url_updated = 0; +if ($mode === 'sync') { + // get all forum info + $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE; + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) { + $forum_data[$row['forum_id']] = $row['forum_name']; + $phpbb_seo->set_url($row['forum_name'], $row['forum_id'], $phpbb_seo->seo_static['forum']); + } + $db->sql_freeresult($result); + // let's work + $sql = 'SELECT * FROM ' . TOPICS_TABLE . ' + ORDER BY topic_id ASC'; + $result = $db->sql_query_limit($sql, $limit, $start); + while ($row = $db->sql_fetchrow($result)) { + $forum_id = (int) $row['forum_id']; + $topic_id = (int) $row['topic_id']; + $_parent = $row['topic_type'] == POST_GLOBAL ? $phpbb_seo->seo_static['global_announce'] : $phpbb_seo->seo_url['forum'][$forum_id]; + if ( !$phpbb_seo->check_url('topic', $row['topic_url'], $_parent)) { + if (!empty($row['topic_url'])) { + // Here we get rid of the seo delim (-t) and put it back even in simple mod + // to be able to handle all cases at once + $_url = preg_replace('`' . $phpbb_seo->seo_delim['topic'] . '$`i', '', $row['topic_url']); + $_title = $phpbb_seo->get_url_info('topic', $_url . $phpbb_seo->seo_delim['topic'] . $topic_id, 'title'); + } else { + $_title = $phpbb_seo->modrtype > 2 ? censor_text($row['topic_title']) : ''; + } + unset($phpbb_seo->seo_url['topic'][$topic_id]); + $row['topic_url'] = $phpbb_seo->get_url_info('topic', $phpbb_seo->prepare_url( 'topic', $_title, $topic_id, $_parent, (( empty($_title) || ($_title == $phpbb_seo->seo_static['topic']) ) ? true : false) ), 'url'); + unset($phpbb_seo->seo_url['topic'][$topic_id]); + if ($row['topic_url']) { + // Update the topic_url field for later re-use + $sql = "UPDATE " . TOPICS_TABLE . " SET topic_url = '" . $db->sql_escape($row['topic_url']) . "' + WHERE topic_id = $topic_id"; + $db->sql_query($sql); + $url_updated++; + } + } + } + $db->sql_freeresult($result); + $sql = 'SELECT count(topic_id) as topic_cnt FROM ' . TOPICS_TABLE; + $result = $db->sql_query($sql); + $cnt = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + if ($cnt['topic_cnt'] > ($start + $limit)) { + $endtime = array_sum(explode(' ', microtime())); + $duration = $endtime - $starttime; + $speed = round($limit/$duration, 2); + $percent = round((($start + $limit) / $cnt['topic_cnt']) * 100, 2); + $message = sprintf($user->lang['SYNC_PROCESSING'], $percent, ($start + $limit), $cnt['topic_cnt'], $limit, $speed, round($duration, 2) , round((($cnt['topic_cnt'] - $start)/$speed)/60, 2)); + if ($url_updated) { + $message.= sprintf($user->lang['SYNC_ITEM_UPDATED'], '<br/>' . $url_updated); + } + $new_limit = ($duration < 10) ? $limit + 50 : $limit - 10; + meta_refresh(1, append_sid('./sync_url.' . $phpEx . '?go=1&start=' . ($start + $limit) . "&limit=$new_limit&mode=sync")); + trigger_error("$message<br/>"); + } else { + trigger_error($user->lang['SYNC_COMPLETE'] . sprintf($user->lang['RETURN_INDEX'], '<br/><br/><a href="' . append_sid($phpbb_root_path) . '" >', '</a>')); + } +} elseif ($mode === 'reset') { + if (confirm_box(true)) { + $sql = "UPDATE " . TOPICS_TABLE . " SET topic_url = ''"; + $db->sql_query($sql); + trigger_error($user->lang['SYNC_RESET_COMPLETE'] . '<br/><br/><b> • <a href="' . append_sid("./sync_url.$phpEx?go=1&mode=sync") . '">' . $user->lang['SYNC_TOPIC_URLS'] . '</a><br/><br/> • ' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid($phpbb_root_path) . '" >', '</a></b>')); + } else { + confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array('go' => '1', 'mode' => 'reset')), 'confirm_body.html', append_sid("./phpbb_seo/sync_url.$phpEx")); + } +} else { + trigger_error($user->lang['SYNC_WARN'] . '<br/><br/><b> • <a href="' . append_sid("./sync_url.$phpEx?go=1&mode=sync") . '">' . $user->lang['SYNC_TOPIC_URLS'] . '</a><br/><br/> • <a href="' . append_sid("./sync_url.$phpEx?go=1&mode=reset") . '" >' . $user->lang['SYNC_RESET_TOPIC_URLS'] . '</a></b>'); +} +?>
\ No newline at end of file |