PageRenderTime 59ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/forum/gym_sitemaps/includes/gym_sitemaps.php

https://github.com/GreyTeardrop/socionicasys-forum
PHP | 659 lines | 483 code | 5 blank | 171 comment | 92 complexity | bf07c40d5adc50c6bad8786995dac5a5 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-3.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. *
  4. * @package phpBB SEO GYM Sitemaps
  5. * @version $Id: gym_sitemaps.php 272 2010-11-21 13:56:31Z dcz $
  6. * @copyright (c) 2006 - 2010 www.phpbb-seo.com
  7. * @license http://opensource.org/osi3.0/licenses/lgpl-license.php GNU Lesser General Public License
  8. *
  9. */
  10. // First basic security
  11. if ( !defined('IN_PHPBB') ) {
  12. exit;
  13. }
  14. require_once($phpbb_root_path . 'gym_sitemaps/includes/gym_common.' . $phpEx);
  15. // For Compatibility with the phpBB SEO mod rewrites
  16. if (empty($phpbb_seo)) {
  17. require_once($phpbb_root_path . 'gym_sitemaps/includes/phpbb_seo_class_light.' . $phpEx);
  18. $phpbb_seo = new phpbb_seo();
  19. define('STARTED_LIGHT', true);
  20. }
  21. /**
  22. * gym_sitemaps Class
  23. * www.phpBB-SEO.com
  24. * @package phpBB SEO
  25. */
  26. class gym_sitemaps {
  27. // $_GET vars
  28. var $actions = array();
  29. // Working vars
  30. var $gym_config = array();
  31. var $override = array();
  32. var $override_type = array();
  33. var $gym_output;
  34. var $output_data = array();
  35. var $cache_config = array();
  36. var $yahoo_config = array();
  37. var $ext_config = array();
  38. var $gzip_config = array();
  39. var $style_config = array();
  40. var $gym_auth = array();
  41. var $module_auth = array();
  42. /**
  43. * constuctor
  44. */
  45. function gym_sitemaps($action_type = '') {
  46. global $phpEx, $phpbb_seo, $user, $config, $phpbb_root_path, $_action_types, $_override_types, $auth;
  47. $start_time = $phpbb_seo->microtime_float();
  48. // Set default values
  49. $this->gym_config = $this->actions = array();
  50. $this->override_type = $_override_types;
  51. $this->actions['action_types'] = $_action_types;
  52. $this->actions['action_type'] = in_array($action_type, $this->actions['action_types']) ? $action_type : '';
  53. $this->actions['extra_params'] = $this->actions['extra_params_full'] = $this->actions['auth_param'] = $this->actions['sql_report_msg'] = '';
  54. $this->actions['auth_guest_list'] = $this->actions['auth_guest_read'] = $this->actions['auth_view_list'] = $this->actions['auth_read_list'] = array();
  55. $this->actions['robots_patterns'] = array();
  56. if (empty($this->actions['action_type']) ) {
  57. $this->gym_error(403, '', __FILE__, __LINE__);
  58. }
  59. // Grab required config
  60. obtain_gym_config($this->actions['action_type'], $this->gym_config);
  61. if (empty($this->gym_config) ) {
  62. $this->gym_error(404, '', __FILE__, __LINE__);
  63. }
  64. // Set the overidding options
  65. $this->set_override();
  66. $this->path_config = array('gym_path' => $phpbb_root_path . 'gym_sitemaps/',
  67. 'gym_img_url' => $phpbb_seo->seo_path['phpbb_url'] . 'gym_sitemaps/images/');
  68. // The main array
  69. $this->output_data = array('microtime'=> $start_time,
  70. 'time' => time(),
  71. 'mem_usage' => 0,
  72. 'gen_data' => '',
  73. 'gen_out' => '',
  74. 'url_sofar' => 0,
  75. 'url_sofar_total' => 0,
  76. 'showstats' => 0,
  77. 'data' => '',
  78. 'expires_time' => 0,
  79. );
  80. // Ceck the day interval and reset pinged
  81. if (@$config['gym_today'] < $this->output_data['time']) {
  82. set_config('gym_today', $this->output_data['time'] + 3600*24, 1);
  83. set_config('gym_pinged_today', 0, 1);
  84. }
  85. $this->url_config = array( 'start_default' => '&amp;start=',
  86. 'google_default' => "sitemap.$phpEx",
  87. 'html_default' => "map.$phpEx",
  88. 'rss_default' => "gymrss.$phpEx",
  89. 'gzip_ext_out' => '',
  90. 'zero_dupe' => (boolean) $this->gym_config['gym_zero_dupe'],
  91. 'uri' => $phpbb_seo->seo_path['uri'],
  92. 'current' => '',
  93. 'modrewrite' => false,
  94. );
  95. $this->gzip_config = array('gzip_level' => (int) $this->gym_config['gym_gzip_level']);
  96. $this->cache_config = array(
  97. 'do_cache' => true, // this is used when preventing the caching of private content.
  98. 'cached' => 'false',
  99. 'mod_since' => (boolean) $this->gym_config['gym_mod_since'],
  100. );
  101. // init $gym_auth
  102. $this->gym_auth = array(
  103. 'admin' => $auth->acl_gets('a_') ? true : false,
  104. 'globalmod' => $auth->acl_getf_global('m_') ? true : false,
  105. 'reg' => $user->data['is_registered'] ? true : false,
  106. 'guest' => $user->data['is_registered'] ? false : true,
  107. 'all' => true,
  108. 'none' => false,
  109. );
  110. // Workaround for error message handling
  111. $phpbb_seo->file_hbase['map'] = $phpbb_seo->file_hbase['gymrss'] = $phpbb_seo->file_hbase['sitemap'] = $phpbb_seo->seo_path['phpbb_url'];
  112. // Clear buffer, just in case it was started elswhere
  113. while (@ob_end_clean());
  114. return;
  115. }
  116. /**
  117. * init_get_vars ().
  118. * Get and check the basic get vars
  119. * @access private
  120. */
  121. function init_get_vars() {
  122. // Builds the action_modules array
  123. $this->init_action_modules();
  124. // Basic options : gymfile.php?var(=value)
  125. $this->actions['module_main'] = $this->actions['module_sub'] = '';
  126. foreach ($this->actions['action_modules'] as $module) {
  127. if (isset($_GET[$module])) {
  128. $this->actions['module_main'] = $module;
  129. $this->actions['module_sub'] = !empty($_GET[$module]) ? trim(utf8_htmlspecialchars(str_replace(array("\n", "\r", "\0"), '', $_GET[$module]))) : '';
  130. unset($_GET[$module]);
  131. }
  132. }
  133. return;
  134. }
  135. /**
  136. * init_action_modules ().
  137. * Build the autogenerated array of all expected actions
  138. * @access private
  139. */
  140. function init_action_modules() {
  141. global $cache, $phpEx;
  142. if (($this->actions['action_modules'] = $cache->get('_gym_action_' . $this->actions['action_type'])) === false) {
  143. $this->actions['action_modules'] = array();
  144. $dir = @opendir( $this->path_config['gym_path'] . 'modules' );
  145. $action_from_file = '';
  146. while( ($file = @readdir($dir)) !== FALSE ) {
  147. if(preg_match('`^' . $this->actions['action_type'] . '_[a-z0-9_-]+\.' . $phpEx . '$`i', $file)) {
  148. $action_from_file = trim(str_replace( $this->actions['action_type'] . '_', '' , str_replace('.' . $phpEx , '' ,$file)), "/");
  149. if (@$this->gym_config[$this->actions['action_type'] . '_' . $action_from_file . '_installed']) {
  150. $this->actions['action_modules'][$action_from_file] = $action_from_file;
  151. }
  152. }
  153. }
  154. @closedir($dir);
  155. $cache->put('_gym_action_' . $this->actions['action_type'], $this->actions['action_modules']);
  156. }
  157. }
  158. /**
  159. * load_modules ( $module_type, $method = '' ).
  160. * loads all modules for a given action_type
  161. * Optional, starts a method
  162. * @access private
  163. */
  164. function load_modules( $method = '' ) {
  165. foreach ( $this->actions['action_modules'] as $module ) {
  166. $this->load_module( $this->actions['action_type'] . "_$module", $method);
  167. }
  168. }
  169. /**
  170. * load_module ( $module_class, $method = '' ).
  171. * loads a module for a given action
  172. * Optional, starts a method
  173. * @access private
  174. */
  175. function load_module( $module_class, $method = '', $return = false ) {
  176. global $phpEx;
  177. $module_file = $this->path_config['gym_path'] . 'modules/' . $module_class . '.' . $phpEx;
  178. if ( !empty($this->gym_config[$module_class . '_installed']) && file_exists($module_file) ) {
  179. include_once($module_file);
  180. if (class_exists($module_class)) {
  181. $gym_module = new $module_class($this);
  182. if ( !empty($method) && method_exists($gym_module, $method)) {
  183. $gym_module->$method();
  184. }
  185. if ($return) {
  186. return $gym_module;
  187. }
  188. }
  189. } else {
  190. $this->gym_error(500, '', __FILE__, __LINE__);
  191. }
  192. }
  193. /**
  194. * gym_init_output ()
  195. * In case we need to hanlde the output
  196. * @access private
  197. */
  198. function gym_init_output() {
  199. global $phpEx;
  200. include_once($this->path_config['gym_path'] . 'includes/gym_output.' . $phpEx);
  201. $this->gym_output = new gym_output($this);
  202. }
  203. /**
  204. * gym_auth_value()
  205. * @access private
  206. */
  207. function gym_auth_value($value) {
  208. return !empty($this->gym_auth[$value]);
  209. }
  210. /**
  211. * set_module_option($config_key, $override ='')
  212. * will check if a module config value is available
  213. * Set it or use the main type default value or the main global value
  214. * Globale module value is used when cyclying through modules ( $this->actions['module_main'] = '' )
  215. * $override = global => global config
  216. * $override = output_type => module config
  217. * $override = module => sub module config
  218. * degrades to the global config in case there is no better otpion
  219. * @access private
  220. */
  221. function set_module_option($config_key, $override = OVERRIDE_MODULE) {
  222. $cond = '';
  223. // Check if we have a sub module option
  224. if ( ($override == OVERRIDE_MODULE) && @isset($this->gym_config[$this->actions['action_type'] . '_' . $this->actions['module_main'] . "_$config_key"]) ) {
  225. return $this->gym_config[$this->actions['action_type'] . '_' . $this->actions['module_main'] . "_$config_key"];
  226. }
  227. // Else look for an output type option
  228. if ( ($override != OVERRIDE_GLOBAL) && @isset($this->gym_config[$this->actions['action_type'] . "_$config_key"]) ) {
  229. return $this->gym_config[$this->actions['action_type'] . "_$config_key"];
  230. }
  231. // Else return the global config value or the next available valid option from the output type to the module level or null
  232. return isset($this->gym_config["gym_$config_key"]) ? $this->gym_config["gym_$config_key"] : ( @isset($this->gym_config[$this->actions['action_type'] . "_$config_key"]) ? $this->gym_config[$this->actions['action_type'] . "_$config_key"] : ( @isset($this->gym_config[$this->actions['action_type'] . '_' . $this->actions['module_main'] . "_$config_key"]) ? $this->gym_config[$this->actions['action_type'] . '_' . $this->actions['module_main'] . "_$config_key"] : null) );
  233. }
  234. /**
  235. * set_override()
  236. * Will set the three levels of overriding
  237. */
  238. function set_override() {
  239. foreach ($this->override_type as $type) {
  240. $this->override[$type] = $this->_set_override($type);
  241. }
  242. $this->override[$this->actions['action_type']] = $this->gym_config[$this->actions['action_type'] . '_override'];
  243. return;
  244. }
  245. /**
  246. * _set_override()
  247. * helper for set_override()
  248. */
  249. function _set_override($type) {
  250. $main_key = 'gym_override_' . $type;
  251. $mode_key = $this->actions['action_type'] . '_override_' . $type;
  252. // $module_key = !empty($this->actions['module_main']) ? $this->actions['action_type'] . '_' . $this->actions['module_main'] . '_override_' . $type : 0;
  253. if ($this->gym_config['gym_override']) { // if top level overrinding is activated
  254. return ($this->gym_config[$main_key] != OVERRIDE_GLOBAL) ? ($this->gym_config[$mode_key] != OVERRIDE_GLOBAL ? $this->gym_config[$mode_key] : $this->gym_config[$main_key]) : OVERRIDE_GLOBAL;
  255. } else {
  256. return $this->gym_config[$mode_key];
  257. }
  258. }
  259. /**
  260. * xml_encode()
  261. * helper
  262. */
  263. function xml_encode($utf8_string) {
  264. static $find = array('&', '<', '>');
  265. static $replace = array('&#x26;', '&#x3C;', '&#x3E;');
  266. return numeric_entify_utf8(str_replace($find, $replace, $utf8_string));
  267. }
  268. /**
  269. * check_forum_auth()
  270. * Returns various forum auth and properties
  271. */
  272. function check_forum_auth($guest_auth = true) {
  273. global $auth, $db, $user, $cache;
  274. $forum_auth_list = array('list' => array(), 'read' => array(), 'list_post' => array(), 'read_post' => array(), 'public_list' => array(), 'public_read' => array(), 'skip_pass' => array(), 'skip_cat' => array(), 'skip_all' => array(), 'skip_link' => array());
  275. $need_cache = false;
  276. $cache_file = '_gym_auth_forum_guest';
  277. // First check the public forum list
  278. if (($forum_auth_list = $cache->get($cache_file)) === false) {
  279. $forum_auth_list = array('list' => array(), 'read' => array(), 'list_post' => array(), 'read_post' => array(), 'public_list' => array(), 'public_read' => array(), 'skip_pass' => array(), 'skip_cat' => array(), 'skip_all' => array(), 'skip_link' => array());
  280. $guest_data = array('user_id' => ANONYMOUS,
  281. 'user_type' => USER_IGNORE,
  282. 'user_permissions' . (defined('XLANG_AKEY') ? XLANG_AKEY : '') => '',
  283. );
  284. $g_auth = new auth();
  285. $g_auth->acl($guest_data);
  286. // the forum id array
  287. $forum_list_ary = $g_auth->acl_getf('f_list', true);
  288. foreach ($forum_list_ary as $forum_id => $null) {
  289. $forum_auth_list['list'][$forum_id] = (int) $forum_id;
  290. }
  291. $forum_read_ary = $g_auth->acl_getf('f_read', true);
  292. foreach ($forum_read_ary as $forum_id => $null) {
  293. $forum_auth_list['read'][$forum_id] = (int) $forum_id;
  294. }
  295. ksort($forum_auth_list['list']);
  296. ksort($forum_auth_list['read']);
  297. $sql = "SELECT forum_id, forum_type, forum_password
  298. FROM " . FORUMS_TABLE . "
  299. WHERE forum_type <> " . FORUM_POST . " OR forum_password <> ''";
  300. $result = $db->sql_query($sql);
  301. while ( $row = $db->sql_fetchrow($result) ) {
  302. $forum_id = (int) $row['forum_id'];
  303. if ($row['forum_password']) {
  304. $forum_auth_list['skip_pass'][$forum_id] = $forum_id;
  305. }
  306. if ($row['forum_type'] == FORUM_CAT) {
  307. $forum_auth_list['skip_cat'][$forum_id] = $forum_id;
  308. } else if ($row['forum_type'] == FORUM_LINK) {
  309. $forum_auth_list['skip_link'][$forum_id] = $forum_id;
  310. }
  311. $forum_auth_list['skip_all'][$forum_id] = $forum_id;
  312. }
  313. $db->sql_freeresult($result);
  314. ksort($forum_auth_list['skip_pass']);
  315. ksort($forum_auth_list['skip_all']);
  316. ksort($forum_auth_list['skip_link']);
  317. ksort($forum_auth_list['skip_cat']);
  318. // Never mind about fourm links
  319. $forum_auth_list['read'] = array_diff_assoc($forum_auth_list['read'], $forum_auth_list['skip_link']);
  320. $forum_auth_list['list'] = array_diff_assoc($forum_auth_list['list'], $forum_auth_list['skip_link']);
  321. ksort($forum_auth_list['read']);
  322. ksort($forum_auth_list['list']);
  323. $forum_auth_list['list_post'] = array_diff_assoc($forum_auth_list['list'], $forum_auth_list['skip_all']);
  324. $forum_auth_list['read_post'] = array_diff_assoc($forum_auth_list['read'], $forum_auth_list['skip_all']);
  325. $forum_auth_list['public_list'] = array_diff_assoc($forum_auth_list['list'], $forum_auth_list['skip_pass']);
  326. $forum_auth_list['public_read'] = array_diff_assoc($forum_auth_list['read'], $forum_auth_list['skip_pass']);
  327. $cache->put($cache_file, $forum_auth_list);
  328. }
  329. $this->module_auth['forum'] = & $forum_auth_list;
  330. if ($guest_auth) { // sometime, we need to only check guest auths, even if user is registered
  331. $this->actions['auth_param'] = implode('-', $forum_auth_list['read_post']);
  332. return $forum_auth_list['read_post'];
  333. }
  334. // else handle the real auth
  335. $forum_auth_list['read'] = $forum_auth_list['list'] = array();
  336. $forum_list_ary = $auth->acl_getf('f_list', true);
  337. foreach ($forum_list_ary as $forum_id => $null) {
  338. $forum_auth_list['list'][$forum_id] = (int) $forum_id;
  339. }
  340. $forum_read_ary = $auth->acl_getf('f_read', true);
  341. foreach ($forum_read_ary as $forum_id => $null) {
  342. $forum_auth_list['read'][$forum_id] = (int) $forum_id;
  343. }
  344. ksort($forum_auth_list['list']);
  345. ksort($forum_auth_list['read']);
  346. $forum_auth_list['list'] = array_diff_assoc($forum_auth_list['list'], $forum_auth_list['skip_link']);
  347. $forum_auth_list['read'] = array_diff_assoc($forum_auth_list['read'], $forum_auth_list['skip_link']);
  348. $forum_auth_list['list_post'] = array_diff_assoc($forum_auth_list['list'], $forum_auth_list['skip_all']);
  349. $forum_auth_list['read_post'] = array_diff_assoc($forum_auth_list['read'], $forum_auth_list['skip_all']);
  350. $this->actions['auth_param'] = implode('-', $forum_auth_list['read_post']);
  351. return $forum_auth_list['read_post'];
  352. }
  353. /**
  354. * Smiley processing, the phpBB3 function, but, with absolute linking
  355. * a little optimization and regular config bypass.
  356. */
  357. function smiley_text($text, $force_option = false) {
  358. global $config, $user, $phpbb_seo;
  359. static $viewsmilies;
  360. if (!isset($viewsmilies)) { // Costs less than optionget ;-)
  361. $viewsmilies = $user->optionget('viewsmilies');
  362. }
  363. if ($force_option || !$viewsmilies) {
  364. return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#', '\1', $text);
  365. } else {
  366. return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/(.*?) \/><!\-\- s\1 \-\->#', '<img src="' . $phpbb_seo->seo_path['phpbb_url'] . $config['smilies_path'] . '/\2 />', $text);
  367. }
  368. }
  369. /**
  370. * obtain_robots_disallows()
  371. * obtain the eventual robots.txt exclusions
  372. * and parse them into a patern array for later use
  373. * @access private
  374. */
  375. function obtain_robots_disallows() {
  376. global $phpbb_root_path, $phpbb_seo, $cache, $phpEx;
  377. if (function_exists('file_get_contents')) {
  378. // Build the domain root path
  379. $phpbb_real_path = trim(phpbb_realpath($phpbb_root_path), '/');
  380. $root_real_path = str_replace(trim($phpbb_seo->seo_path['phpbb_script'], '/'), '', $phpbb_real_path);
  381. if (file_exists($root_real_path . '/robots.txt')) {
  382. $time_created = filemtime($root_real_path . '/robots.txt');
  383. if (($this->actions['robots_patterns'] = $cache->get('_gym_config_robots_regex' )) === false) {
  384. $robots = file_get_contents($root_real_path . '/robots.txt');
  385. preg_match_all('`^Disallow[\s]*:[\s]*([a-z0-9_\.&;\?,:/-]+)[\s]*$`im', $robots, $matches,PREG_SET_ORDER);
  386. if (!empty($matches[0][1])) {
  387. foreach ($matches as $match) {
  388. if (!empty($match[1])) {
  389. $this->actions['robots_patterns'][] = $phpbb_seo->seo_path['root_url'] . trim($match[1], '/');
  390. }
  391. }
  392. }
  393. $this->actions['robots_patterns']['date'] = $time_created;
  394. $cache->put('_gym_config_robots_regex' , $this->actions['robots_patterns']);
  395. } elseif ($this->actions['robots_patterns']['date'] < $time_created) { // robots.tx was updated
  396. $cache->destroy('_gym_config_robots_regex');
  397. $this->obtain_robots_disallows();
  398. }
  399. }
  400. }
  401. return;
  402. }
  403. /**
  404. * is_robots_disallowed()
  405. * checks if an url is disallowed by the robots.txt patterns
  406. * @access private
  407. */
  408. function is_robots_disallowed($url) {
  409. if (!empty($this->actions['robots_patterns'])) {
  410. foreach($this->actions['robots_patterns'] as $pattern) {
  411. if (stripos( $url, $pattern) !== false) {
  412. return true;
  413. }
  414. }
  415. }
  416. return false;
  417. }
  418. /**
  419. * set_exclude_list($id_list) will build up the public unauthed ids
  420. * @access private
  421. */
  422. function set_exclude_list($id_list) {
  423. $exclude_list = empty($id_list) ? array() : explode(',', $id_list);
  424. $ret = array();
  425. foreach ($exclude_list as $value ) {
  426. $value = (int) trim($value);
  427. if (!empty($value)) {
  428. $ret[$value] = $value;
  429. }
  430. }
  431. return $ret;
  432. }
  433. /**
  434. * set_exclude_list($id_list) will build up the public unauthed ids
  435. * This method is deprecated since 2.0.RC2
  436. * @access private
  437. */
  438. function set_not_in_list($id_list = array(), $field = '', $and = '') {
  439. if ( !empty($id_list) && is_array($id_list) ) {
  440. $not_in_id_sql = " $field NOT IN (" . implode(",", array_map('intval', $id_list)) . ") $and ";
  441. } else {
  442. $not_in_id_sql = '';
  443. }
  444. return $not_in_id_sql;
  445. }
  446. /**
  447. * is_forum_public($forum_id) Will tell if a forum is publicly viewable or listable (auth guest)
  448. * @access private
  449. */
  450. function is_forum_public($forum_id, $type = 'read') {
  451. $type = $type === 'list' ? 'list' : 'read';
  452. return (boolean) isset($this->actions["auth_guest_$type"][$forum_id]);
  453. }
  454. // --> Others <--
  455. /**
  456. * init_url_rewrite()
  457. */
  458. function init_url_rewrite($modr = false, $type = 0) {
  459. global $phpbb_seo, $phpEx;
  460. $this->url_config['modrewrite'] = $modr ? true : false;
  461. // Mod rewrite type auto detection
  462. $this->url_config['modrtype'] = !empty($phpbb_seo->modrtype) ? max(0, (int) $phpbb_seo->modrtype) : max(0, (int) $type);
  463. if (!@isset($phpbb_seo->seo_opt['url_rewrite'])) {
  464. $phpbb_seo->seo_opt['url_rewrite'] = $this->url_config['modrtype'] > 0 ? true : false;
  465. }
  466. // make sure virtual_folder uses the proper value
  467. $phpbb_seo->seo_opt['virtual_folder'] = $this->url_config['modrtype'] ? $phpbb_seo->seo_opt['virtual_folder'] : false;
  468. $this->url_config['forum_start_tpl'] = $this->url_config['start_default'] . '%1$d';
  469. $this->url_config['topic_start_tpl'] = $this->url_config['start_default'] . '%1$d';
  470. $this->url_config['forum_tpl'] = "viewforum.$phpEx?f=%1\$d";
  471. $this->url_config['topic_tpl'] = "viewtopic.$phpEx?f=%1\$d&amp;t=%2\$d";
  472. if (!$phpbb_seo->seo_opt['url_rewrite']) {
  473. $this->url_config['forum_index'] = "index.$phpEx";
  474. $phpbb_seo->seo_opt['virtual_folder'] = false;
  475. $this->url_config['forum_ext'] = '';
  476. $this->url_config['topic_ext'] = '';
  477. } else {
  478. $this->url_config['forum_index'] = !empty($phpbb_seo->seo_static['index']) ? $phpbb_seo->seo_static['index'] . $phpbb_seo->seo_ext['index'] : '';
  479. if ($this->url_config['modrtype'] >= 1) { // Simple mod rewrite, default is none (0)
  480. $this->url_config['forum_ext'] = $phpbb_seo->seo_ext['forum'];
  481. $this->url_config['topic_ext'] = $phpbb_seo->seo_ext['topic'];
  482. $this->url_config['forum_start_tpl'] = $phpbb_seo->seo_opt['virtual_folder'] ? '/' . $phpbb_seo->seo_static['pagination'] . '%1$d' . $phpbb_seo->seo_ext['pagination'] : $phpbb_seo->seo_delim['start'] . '%1$d' . $this->url_config['forum_ext'];
  483. $this->url_config['topic_start_tpl'] = $this->url_config['topic_ext'] == '/' ? '/' . $phpbb_seo->seo_static['pagination'] . '%1$d' . $phpbb_seo->seo_ext['pagination'] : $phpbb_seo->seo_delim['start'] . '%1$d' . $this->url_config['topic_ext'];
  484. }
  485. if ($this->url_config['modrtype'] >= 2) { // +Mixed
  486. }
  487. if ($this->url_config['modrtype'] >= 3) { // +Advanced
  488. }
  489. }
  490. }
  491. /**
  492. * forum_url() builds forum url with proper options
  493. * Suffixe is not added here, to properly deal with pagination
  494. */
  495. function forum_url($forum_name, $forum_id) {
  496. global $phpbb_seo;
  497. return $phpbb_seo->seo_opt['url_rewrite'] ? $phpbb_seo->set_url($forum_name, $forum_id, 'forum') : sprintf($this->url_config['forum_tpl'], $forum_id);
  498. }
  499. /**
  500. * topic_url($topic_title, $topic_id, $forum_url, $forum_id) builds forum url with proper options
  501. * Suffixe is not added here, to properly deal with pagination
  502. */
  503. function topic_url($topic_data, $forum_id, $forum_url = '') {
  504. global $phpbb_seo;
  505. return $phpbb_seo->seo_opt['url_rewrite'] ? $phpbb_seo->prepare_iurl($topic_data, 'topic', trim($forum_url, '/')) : sprintf($this->url_config['topic_tpl'], $forum_id, (int) $topic_data['topic_id']);
  506. }
  507. /**
  508. * Returns usable start param
  509. * -xx | /pagexx.html
  510. */
  511. function set_start($type, $start) {
  512. global $phpbb_seo;
  513. return $start > 0 ? sprintf($this->url_config[$type . '_start_tpl'], (int) $start) : $this->url_config[$type . '_ext'];
  514. }
  515. /**
  516. * check start var consistency
  517. * and return our best guess for $start, eg the first valid page
  518. * parameter according to pagination settings being lower
  519. * than the one sent.
  520. */
  521. function chk_start($start = 0, $limit = 0) {
  522. if ($limit > 0) {
  523. $start = is_int($start/$limit) ? $start : intval($start/$limit)*$limit;
  524. }
  525. return (int) $start;
  526. }
  527. /**
  528. * parse_link() builds an html link
  529. */
  530. function parse_link($url, $title = '', $tag_arround = '') {
  531. global $config;
  532. static $linktpl = '%4$s<a href="%1$s" %2$s>%3$s</a>%5$s';
  533. $title_tag = $tag1 = $tag2 = '';
  534. if (empty($title) ) {
  535. $title = $url;
  536. } else {
  537. $title_tag = 'title="' . $title . '"';
  538. }
  539. if (!empty($tag_arround)) {
  540. $tag1 = "<$tag_arround>";
  541. $tag2 = "</$tag_arround>";
  542. }
  543. return sprintf($linktpl, $url, $title_tag, $title, $tag1, $tag2);
  544. }
  545. /**
  546. * seo_kill_dupes($url) will kill duplicates when pages are not cached
  547. * @access private
  548. */
  549. function seo_kill_dupes($url) {
  550. global $user, $auth, $_SID, $phpbb_seo;
  551. $url = str_replace('&amp;', '&', $url);
  552. // if an https request lead us here or if it is forced, then use it as a reference
  553. $url = $phpbb_seo->sslify($url, $phpbb_seo->ssl['use']);
  554. if ($this->url_config['zero_dupe']) {
  555. $requested_url = $this->url_config['uri'];
  556. if (!empty($_REQUEST['explain']) && (boolean) ($auth->acl_get('a_') && defined('DEBUG_EXTRA'))) {
  557. if ($_REQUEST['explain'] == 1) {
  558. return;
  559. }
  560. }
  561. $url = $phpbb_seo->drop_sid($url);
  562. if (!empty($_GET['sid']) && !empty($_SID)) {
  563. $url .= (utf8_strpos( $url, '?' ) !== false ? '&' : '?') . 'sid=' . $user->session_id;
  564. }
  565. if ( $requested_url !== $url ) {
  566. $this->gym_redirect($url);
  567. }
  568. }
  569. $this->url_config['current'] = $url;
  570. return;
  571. }
  572. /**
  573. * Custom HTTP 301 redirections.
  574. * To kill duplicates
  575. */
  576. function gym_redirect($url, $header = "301 Moved Permanently", $code = 301, $replace = true) {
  577. if (headers_sent()) {
  578. return false;
  579. }
  580. if (strstr(urldecode($url), "\n") || strstr(urldecode($url), "\r") || strstr(urldecode($url), ';url')) {
  581. $this->gym_error(400, '', __FILE__, __LINE__);
  582. }
  583. $http = "HTTP/1.1 ";
  584. header($http . $header, $replace, $code);
  585. header("Location:" . $url);
  586. $this->safe_exit();
  587. }
  588. /**
  589. * gym_error(($errno, $msg_text, $errfile, $errline)
  590. * Will properly handle error for all cases, admin always get full debug
  591. * Partly based on msg_handler()
  592. * @access private
  593. */
  594. function gym_error($errno = 0, $msg_key = '', $errfile = '', $errline = '', $sql = '') {
  595. global $user, $phpbb_seo, $auth, $phpbb_root_path, $phpEx, $msg_title;
  596. $http_codes = array (
  597. 204 => 'HTTP/1.1 204 No Content',
  598. 400 => 'HTTP/1.1 400 Bad Request',
  599. 401 => 'HTTP/1.1 401 Unauthorized',
  600. 403 => 'HTTP/1.1 403 Forbidden',
  601. 404 => 'HTTP/1.1 404 Not Found',
  602. 405 => 'HTTP/1.1 405 Method Not Allowed',
  603. 406 => 'HTTP/1.1 406 Not Acceptable',
  604. 410 => 'HTTP/1.1 410 Gone',
  605. 500 => 'HTTP/1.1 500 Internal Server Error',
  606. 503 => 'HTTP/1.1 503 Service Unavailable',
  607. );
  608. $header = isset($http_codes[$errno]) ? $http_codes[$errno] : '';
  609. $return_url = append_sid("{$phpbb_root_path}index.$phpEx");
  610. if (!empty($user) && !empty($user->lang)) {
  611. $msg_title = (empty($msg_key)) ? ( !empty($user->lang['GYM_ERROR_' . $errno]) ? $user->lang['GYM_ERROR_' . $errno] : ( !empty($header) ? $header : $user->lang['GENERAL_ERROR']) ) : ((!empty($user->lang[$msg_key])) ? $user->lang[$msg_key] : $msg_key);
  612. $msg_text = !empty($user->lang[$msg_key . '_EXPLAIN']) ? $user->lang[$msg_key . '_EXPLAIN'] : (!empty($user->lang['GYM_ERROR_' . $errno . '_EXPLAIN']) ? $user->lang['GYM_ERROR_' . $errno . '_EXPLAIN'] : ( (!empty($msg_key) ? $msg_key : (!empty($header) ? $header : $msg_title) ) ) );
  613. $l_return_index = sprintf($user->lang['RETURN_INDEX'], '<a href="' . $return_url . '">', '</a>');
  614. if ( ( $errno == 500 || $errno == 503 ) && !empty($config['board_contact'])) {
  615. $msg_text .= '<p>' . sprintf($user->lang['NOTIFY_ADMIN_EMAIL'], $config['board_contact']) . '</p>';
  616. }
  617. } else {
  618. $msg_title = 'GYM Sitemaps General Error';
  619. $l_return_index = '<a href="' . $return_url . '">Return to index page</a>';
  620. if ( ( $errno == 500 || $errno == 503 ) && !empty($config['board_contact'])) {
  621. $msg_text .= '<p>Please notify the board administrator or webmaster: <a href="mailto:' . $config['board_contact'] . '">' . $config['board_contact'] . '</a></p>';
  622. }
  623. }
  624. $msg_text .= '<br/><br/>' . $l_return_index;
  625. if (@$auth->acl_get('a_')) {
  626. if (!empty($user->lang[$msg_key . '_EXPLAIN_ADMIN'])) {
  627. $msg_text .= '<br/><br/>' . $user->lang[$msg_key . '_EXPLAIN_ADMIN'];
  628. }
  629. if (defined('DEBUG')) {
  630. $msg_text .= '</p><br/><h2>Debug :</h2><p>' . (!empty($errfile) ? "<br/><b>File :</b> " . utf8_htmlspecialchars($errfile) . "<br/>" : '');
  631. $msg_text .= !empty($errline) ? "<br/><b>Line :</b> " . utf8_htmlspecialchars($errline) . "<br/>" : '';
  632. $msg_text .= !empty($sql) ? "<br/><b>Sql :</b> " . utf8_htmlspecialchars($sql) . "<br/>" : '';
  633. $msg_text .= '</p><div style="font-size:12px">' . get_backtrace() . '</div><p>';
  634. }
  635. }
  636. if ( !empty($header) ) {
  637. header($header);
  638. }
  639. meta_refresh(5, $return_url);
  640. trigger_error($msg_text);
  641. $this->safe_exit();
  642. return;
  643. }
  644. /**
  645. * For a safe exit
  646. * @access private
  647. */
  648. function safe_exit() {
  649. garbage_collection();
  650. exit_handler();
  651. exit;
  652. }
  653. }
  654. ?>