PageRenderTime 81ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 1ms

/forum/gym_sitemaps/includes/gym_html.php

https://github.com/GreyTeardrop/socionicasys-forum
PHP | 834 lines | 668 code | 4 blank | 162 comment | 155 complexity | 8ea137a73acaebeb7c7566f4e5fffe79 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_html.php 314 2011-06-27 08:21:34Z dcz $
  6. * @copyright (c) 2006 - 2011 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_sitemaps.' . $phpEx);
  15. /**
  16. * gym_html Class
  17. * www.phpBB-SEO.com
  18. * @package phpBB SEO
  19. */
  20. class gym_html extends gym_sitemaps {
  21. var $html_config = array();
  22. var $start = 0;
  23. /**
  24. * constuctor
  25. */
  26. function gym_html($standalone = false) {
  27. global $phpbb_seo, $config;
  28. $this->gym_sitemaps('html');
  29. // Check the main vars
  30. $this->init_get_vars();
  31. if (empty($this->actions['action_modules'])) {
  32. $this->gym_error(404, '', __FILE__, __LINE__);
  33. }
  34. $this->output_data['tpl'] = $this->output_data['page_title'] = '';
  35. // Used to store module data upon index calls
  36. $this->output_data['module_data'] = array();
  37. $this->actions['pagination_limit'] = 0;
  38. // Setup the output
  39. $this->cache_config = array_merge(
  40. // Global
  41. $this->cache_config,
  42. // Other stuff required here
  43. array(
  44. 'main_cache_on' => (boolean) $this->set_module_option('main_cache_on', $this->override['cache']),
  45. 'opt_cache_on' => (boolean) $this->set_module_option('opt_cache_on', $this->override['cache']),
  46. 'main_cache_ttl' => round($this->set_module_option('main_cache_ttl', $this->override['cache']),2) * 3600,
  47. 'opt_cache_ttl' => round($this->set_module_option('opt_cache_ttl', $this->override['cache']),2) * 3600,
  48. )
  49. );
  50. $this->html_config = array(
  51. 'html_c_info' => $this->gym_config['html_c_info'],
  52. 'html_url' => $phpbb_seo->sslify($this->gym_config['html_url'], $phpbb_seo->ssl['use'], false),
  53. 'html_pagination' => (int) $this->set_module_option('pagination', $this->override['pagination']),
  54. 'html_item_pagination' => (int) $this->set_module_option('item_pagination', $this->override['pagination']),
  55. 'html_pagination_limit' => (int) max(1, $this->set_module_option('pagination_limit', $this->override['pagination'])),
  56. 'html_news_pagination' => $this->set_module_option('news_pagination', $this->override['pagination']),
  57. 'html_news_pagination_limit' => (int) max(1, $this->set_module_option('news_pagination_limit', $this->override['pagination'])),
  58. 'html_map_time_limit' => (int) max(0, $this->set_module_option('map_time_limit', $this->override['limit'])*3600*24),
  59. 'html_cat_time_limit' => (int) max(0, $this->set_module_option('cat_time_limit', $this->override['limit'])*3600*24),
  60. 'html_news_time_limit' => (int) max(0, $this->set_module_option('news_time_limit', $this->override['limit'])*3600*24),
  61. 'html_cat_news_time_limit' => (int) max(0, $this->set_module_option('cat_news_time_limit', $this->override['limit'])*3600*24),
  62. 'html_modrewrite' => (boolean) $this->set_module_option('modrewrite', $this->override['modrewrite']),
  63. 'html_modrtype' => (int) $this->set_module_option('modrtype', $this->override['modrewrite']),
  64. 'html_stats_on_news' => (boolean) $this->gym_auth_value($this->set_module_option('stats_on_news', $this->gym_config['html_override'])),
  65. 'html_stats_on_map' => (boolean) $this->gym_auth_value($this->set_module_option('stats_on_map', $this->gym_config['html_override'])),
  66. 'html_birthdays_on_news' => (boolean) $this->gym_auth_value($this->set_module_option('birthdays_on_news', $this->gym_config['html_override'])),
  67. 'html_birthdays_on_map' => (boolean) $this->gym_auth_value($this->set_module_option('html_birthdays_on_map', $this->gym_config['html_override'])),
  68. 'html_sitename' => $this->set_module_option('sitename'),
  69. 'html_site_desc' => $this->set_module_option('site_desc'),
  70. 'html_logo_url' => trim($this->set_module_option('logo_url'), '/'),
  71. 'html_sort' => $this->set_module_option('sort', $this->override['sort']),
  72. 'html_cat_sort' => $this->set_module_option('cat_sort', $this->override['sort']),
  73. 'html_news_sort' => $this->set_module_option('news_sort', $this->override['sort']),
  74. 'html_cat_news_sort' => $this->set_module_option('cat_news_sort', $this->override['sort']),
  75. 'html_allow_auth' => (boolean) $this->set_module_option('allow_auth', $this->gym_config['html_override']),
  76. 'html_disp_online' => (boolean) $this->gym_auth_value($this->set_module_option('disp_online', $this->gym_config['html_override'])),
  77. 'html_disp_tracking' => (boolean) $this->gym_auth_value($this->set_module_option('disp_tracking', $this->gym_config['html_override'])),
  78. 'html_disp_status' => (boolean) $this->gym_auth_value($this->set_module_option('disp_status', $this->gym_config['html_override'])),
  79. 'html_allow_profile' => (boolean) $this->gym_auth_value($this->set_module_option('allow_profile', $this->gym_config['html_override'])),
  80. 'html_allow_profile_links' => (boolean) $this->gym_auth_value($this->set_module_option('allow_profile_links', $this->gym_config['html_override'])),
  81. 'html_allow_map' => (boolean) $this->set_module_option('allow_map', $this->gym_config['html_override']),
  82. 'html_allow_cat_map' => (boolean) $this->set_module_option('allow_cat_map', $this->gym_config['html_override']),
  83. 'html_allow_news' => (boolean) $this->set_module_option('allow_news', $this->gym_config['html_override']),
  84. 'html_allow_cat_news' => (boolean) $this->set_module_option('allow_cat_news', $this->gym_config['html_override']),
  85. 'html_sumarize' => (int) $this->set_module_option('sumarize', $this->gym_config['html_override']),
  86. 'html_sumarize_method' => trim($this->set_module_option('sumarize_method', $this->gym_config['html_override'])),
  87. 'html_allow_bbcode' => (boolean) $this->gym_auth_value($this->set_module_option('allow_bbcode', $this->gym_config['html_override'])),
  88. 'html_strip_bbcode' => trim($this->set_module_option('strip_bbcode', $this->gym_config['html_override'])),
  89. 'html_allow_links' => (boolean) $this->gym_auth_value($this->set_module_option('allow_links', $this->gym_config['html_override'])),
  90. 'html_allow_emails' => (boolean) $this->set_module_option('allow_emails', $this->gym_config['html_override']),
  91. 'html_allow_smilies' => (boolean) $this->gym_auth_value($this->set_module_option('allow_smilies', $this->gym_config['html_override'])),
  92. 'html_allow_sig' => (boolean) $this->gym_auth_value($this->set_module_option('allow_sig', $this->gym_config['html_override'])),
  93. 'html_msg_filters' => array(),
  94. 'html_auth_msg' => '',
  95. 'html_do_explain' => false,
  96. );
  97. $config['gzip_compress'] = $config['gzip_compress'] ? 1 : (boolean) $this->set_module_option('gzip', $this->override['gzip']);
  98. $this->html_config['html_auth_guest'] = ($this->html_config['html_allow_auth'] && $this->gym_auth['reg']) ? false : true;
  99. $this->cache_config['do_cache_main'] = (boolean) ($this->html_config['html_auth_guest'] && $this->cache_config['main_cache_on']);
  100. $this->cache_config['do_cache_opt'] = (boolean) ($this->html_config['html_auth_guest'] && $this->cache_config['opt_cache_on']);
  101. $this->output_data['left_col_cache_file'] = $this->output_data['right_col_cache_file'] = '';
  102. $this->actions['is_auth'] = $this->actions['is_active'] = $this->actions['is_public'] = false;
  103. if (!$standalone) {
  104. // Check the rss specific vars and do basic set_up for msg output
  105. $this->init_html_vars();
  106. $this->html_output();
  107. }
  108. return;
  109. }
  110. /**
  111. * init_html_vars()
  112. * Set up the specific rss modules GET vars.
  113. * @access private
  114. */
  115. function init_html_vars() {
  116. global $user, $phpEx, $phpbb_seo;
  117. // Take care about module categorie urls, assuming that they are of the proper form
  118. // news|map/module_main/module_sub/
  119. // this code will filter in between special map|news and categroy map and news
  120. // assuming that the cat urls will be of the following form title-sepXX (forum-title-fxx.html or /)
  121. // or without ID, if the phpbb_seo cache array is properly set.
  122. if (!empty($this->actions['module_main']) && !empty($this->actions['module_sub']) && $this->actions['module_sub'] != 'map' && $this->actions['module_sub'] != 'news') {
  123. if (preg_match('`^[a-z0-9_-]*-[a-z]{1}+([0-9]+)`', $this->actions['module_sub'], $match)) {
  124. $this->actions['module_sub'] = $match[1];
  125. } else if ($id = @array_search($this->actions['module_sub'], $phpbb_seo->cache_config[$this->actions['module_main']]) ) {
  126. $this->actions['module_sub'] = (int) $id;
  127. }
  128. }
  129. $this->start = max(0, request_var('start', 0));
  130. $this->actions['html_news_list'] = $this->actions['html_map_list'] = false;
  131. $this->html_config['extra_title'] = $this->url_config['extra_params_full'] = $this->url_config['extra_params'] = '';
  132. if ( isset($_GET['news']) && ($this->html_config['html_allow_cat_news'] || $this->html_config['html_allow_news'])) {
  133. $this->actions['html_news_list'] = true;
  134. if (empty($this->actions['module_sub']) && $this->html_config['html_allow_news']) {
  135. $this->actions['module_sub'] = 'news';
  136. }
  137. } else if (@$this->actions['module_sub'] == 'news' && $this->html_config['html_allow_news']) {
  138. $this->actions['html_news_list'] = true;
  139. } else if (!empty($this->actions['module_sub']) && $this->html_config['html_allow_cat_map']) {
  140. $this->actions['html_map_list'] = true;
  141. } else if (!empty($this->actions['module_main']) && (empty($this->actions['module_sub']) || $this->actions['module_sub'] == 'map' ) && $this->html_config['html_allow_map']) {
  142. $this->actions['html_map_list'] = true;
  143. }
  144. if ($this->actions['html_news_list']) {
  145. $this->actions['html_type'] = 'news';
  146. $this->actions['display_stats'] = $this->html_config['html_stats_on_news'];
  147. $this->actions['display_birthdays'] = $this->html_config['html_birthdays_on_news'];
  148. } else {
  149. $this->actions['html_type'] = 'map';
  150. $this->actions['display_stats'] = $this->html_config['html_stats_on_map'];
  151. $this->actions['display_birthdays'] = $this->html_config['html_birthdays_on_map'];
  152. }
  153. // Adjust variable a bit
  154. if ($this->actions['html_news_list']) { // requested and auth
  155. $this->html_config['html_msg_filters'] = $this->set_msg_strip($this->html_config['html_strip_bbcode']);
  156. }
  157. // Set up module's urls : Pagination
  158. $this->url_config['html_start_ext'] = '';
  159. if ($this->html_config['html_modrewrite']) {
  160. $page = !empty($phpbb_seo->seo_static['pagination']) ? $phpbb_seo->seo_static['pagination'] : 'page';
  161. $html = !empty($phpbb_seo->seo_ext['pagination']) ? $phpbb_seo->seo_ext['pagination'] : '.html';
  162. $this->url_config['html_start'] = "$page%1\$s$html";
  163. $this->url_config['html_default'] = 'maps/';
  164. $this->url_config['html_news_default'] = 'news/';
  165. } else {
  166. $this->url_config['html_start'] = '&amp;start=%1$s';
  167. $this->url_config['html_news_default'] = $this->url_config['html_default'] . '?news';
  168. }
  169. }
  170. /**
  171. * html_add_start($start, $tpl_start_key) builds the pagination bit
  172. * @access private
  173. */
  174. function html_add_start($start, $tpl_start_key = 'html_start') {
  175. return $start > 0 ? sprintf($this->url_config[$tpl_start_key], $start) : @$this->url_config[$tpl_start_key . '_ext'];
  176. }
  177. /**
  178. * html_build_url($tpl_key, $title, $id, $start = 0, $tpl_start_key) builds the url
  179. * $title must be properly formated prior to injection
  180. * @access private
  181. */
  182. function html_build_url($tpl_key, $title = '', $id = 0, $start = 0, $tpl_start_key = 'html_start') {
  183. return sprintf($this->url_config[$tpl_key], $title, $id) . $this->html_add_start($start, $tpl_start_key);
  184. }
  185. /**
  186. * html_output() will build all html output
  187. * @access private
  188. */
  189. function html_output() {
  190. global $phpEx, $db, $config, $phpbb_root_path, $user, $template, $cache, $phpbb_seo;
  191. $module_obj = null;
  192. $left_col = $right_col = false;
  193. // Set up the base href tag, could be done better but saves a file edit this way ( and works too ;-) )
  194. // Assuming that map.php is either in phpBB's dir or above (not under).
  195. $bhref_ulr = ($phpbb_root_path === './') ? $phpbb_seo->seo_path['phpbb_url'] : str_replace(ltrim($phpbb_root_path, './'), '', $phpbb_seo->seo_path['phpbb_url']);
  196. $template->assign_vars(array(
  197. 'META' => '<base href="' . $bhref_ulr . '"/>' . "\n",
  198. 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'],
  199. 'S_CONTENT_FLOW_BEGIN' => ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right',
  200. 'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left',
  201. 'NEWEST_POST_IMG' => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
  202. 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
  203. ));
  204. // module action
  205. if (in_array($this->actions['module_main'], $this->actions['action_modules'])) { // List item from the module
  206. // Add index page in navigation links
  207. $template->assign_block_vars('navlinks', array(
  208. 'FORUM_NAME' => $user->lang['HTML_MAP'],
  209. 'U_VIEW_FORUM' => append_sid($this->html_config['html_url']. $this->url_config['html_default']))
  210. );
  211. $module_class = $this->actions['action_type'] . '_' . $this->actions['module_main'];
  212. $module_obj = $this->load_module($module_class, 'html_init', true);
  213. } else { // sitemap index
  214. // We are working on all available modules
  215. $left_col = $this->html_index();
  216. }
  217. $page_title = (!empty($this->output_data['page_title']) ? $this->output_data['page_title'] : $user->lang['HTML_' . strtoupper($this->actions['html_type'])]) . $this->html_config['extra_title'];
  218. // Add current page in navigation links
  219. $template->assign_block_vars('navlinks', array(
  220. 'FORUM_NAME' => $page_title,
  221. 'U_VIEW_FORUM' => append_sid($this->url_config['current']))
  222. );
  223. if (!$this->actions['is_active']) {
  224. header('HTTP/1.1 404 Not Found');
  225. global $msg_title;
  226. $msg_title = $user->lang['GYM_ERROR_404'];
  227. trigger_error('GYM_ERROR_404_EXPLAIN');
  228. }
  229. if (!$this->actions['is_auth']) {
  230. header('HTTP/1.1 401 Unauthorized');
  231. if ($user->data['user_id'] != ANONYMOUS) {
  232. trigger_error('GYM_ERROR_401');
  233. }
  234. login_box('', $user->lang['GYM_LOGIN']);
  235. }
  236. // Let's kill duplicate now !
  237. if (!empty($this->url_config['current'])) {
  238. $this->seo_kill_dupes(append_sid($this->url_config['current']));
  239. }
  240. $template->set_filenames(array('body' => 'gym_sitemaps/index_body.html'));
  241. $this->cache_config['do_cache_main'] = (boolean) ($this->cache_config['do_cache_main'] && $this->actions['is_public']);
  242. $this->cache_config['do_cache_opt'] = (boolean) ($this->cache_config['do_cache_opt'] && $this->actions['is_public']);
  243. $cache_find = array('`(\?|&amp;|&)sid\=[a-z0-9]+`i', '`[\s]+`');
  244. $cache_replace = array('',' ');
  245. $ssl_bit = $phpbb_seo->ssl['use'] ? 'ssl_' : '';
  246. // Main output
  247. if (!empty($this->output_data['left_col_tpl'])) {
  248. $template->set_filenames(array('left_col' => $this->output_data['left_col_tpl']));
  249. if ($this->cache_config['do_cache_main'] && !empty($this->output_data['left_col_cache_file'])) {
  250. $cache_file = '_gym_html_' . $this->output_data['left_col_cache_file'] . '_' . $ssl_bit . $user->data['user_lang'] . '_' . $this->start;
  251. if (($left_col = $cache->get($cache_file)) === false) {
  252. $module_obj->html_main();
  253. $left_col = $template->assign_display('left_col', '', true);
  254. // Strip whitespaces and sids
  255. $left_col = preg_replace($cache_find, $cache_replace, $left_col );
  256. $cache->put($cache_file, $left_col, $this->cache_config['main_cache_ttl']);
  257. }
  258. }
  259. if (!$left_col) {
  260. $module_obj->html_main();
  261. $left_col = $template->assign_display('left_col', '', true);
  262. }
  263. }
  264. // Optional output
  265. if (!empty($this->output_data['right_col'])) {
  266. if ($this->cache_config['do_cache_opt'] && !empty($this->output_data['right_col_cache_file'])) {
  267. $cache_file = '_gym_html_' . $this->output_data['right_col_cache_file'] . '_' . $ssl_bit . $user->data['user_lang'];
  268. if (($right_col = $cache->get($cache_file)) === false) {
  269. $module_obj->html_module();
  270. $template->set_filenames(array('right_col' => $this->output_data['right_col_tpl']));
  271. $right_col = $template->assign_display('right_col', '', true);
  272. // Strip whitespaces and sids
  273. $right_col = preg_replace($cache_find, $cache_replace, $right_col );
  274. $cache->put($cache_file, $right_col, $this->cache_config['opt_cache_ttl']);
  275. }
  276. }
  277. if (!$right_col) {
  278. $module_obj->html_module();
  279. $template->set_filenames(array('right_col' => $this->output_data['right_col_tpl']));
  280. $right_col = $template->assign_display('right_col', '', true);
  281. }
  282. }
  283. unset($module_obj);
  284. $tpl_data = array();
  285. if ($this->actions['display_stats']) {
  286. // Set some stats, get posts count from forums data if we... hum... retrieve all forums data
  287. $total_posts = $config['num_posts'];
  288. $total_topics = $config['num_topics'];
  289. $total_users = $config['num_users'];
  290. $l_total_user_s = ($total_users == 0) ? 'TOTAL_USERS_ZERO' : 'TOTAL_USERS_OTHER';
  291. $l_total_post_s = ($total_posts == 0) ? 'TOTAL_POSTS_ZERO' : 'TOTAL_POSTS_OTHER';
  292. $l_total_topic_s = ($total_topics == 0) ? 'TOTAL_TOPICS_ZERO' : 'TOTAL_TOPICS_OTHER';
  293. $tpl_data += array(
  294. 'TOTAL_POSTS' => sprintf($user->lang[$l_total_post_s], $total_posts),
  295. 'TOTAL_TOPICS' => sprintf($user->lang[$l_total_topic_s], $total_topics),
  296. 'TOTAL_USERS' => sprintf($user->lang[$l_total_user_s], $total_users),
  297. );
  298. if ($this->html_config['html_allow_profile']) {
  299. $tpl_data += array(
  300. 'NEWEST_USER' => sprintf($user->lang['NEWEST_USER'], get_username_string( $this->html_config['html_allow_profile_links'] ? 'full' : 'no_profile', $config['newest_user_id'], $config['newest_username'], $config['newest_user_colour'])),
  301. );
  302. }
  303. }
  304. // Generate birthday list if required ...
  305. if ($this->actions['display_birthdays']) {
  306. $birthday_list = '';
  307. $now = getdate(time() + $user->timezone + $user->dst - date('Z'));
  308. $sql = 'SELECT u.user_id, u.username, u.user_colour, u.user_birthday
  309. FROM ' . USERS_TABLE . ' u
  310. LEFT JOIN ' . BANLIST_TABLE . " b ON (u.user_id = b.ban_userid)
  311. WHERE (b.ban_id IS NULL
  312. OR b.ban_exclude = 1)
  313. AND u.user_birthday LIKE '" . $db->sql_escape(sprintf('%2d-%2d-', $now['mday'], $now['mon'])) . "%'
  314. AND u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')';
  315. $result = $db->sql_query($sql);
  316. while ($row = $db->sql_fetchrow($result)) {
  317. $birthday_list .= (($birthday_list != '') ? ', ' : '') . get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']);
  318. if ($age = (int) substr($row['user_birthday'], -4)) {
  319. $birthday_list .= ' (' . ($now['year'] - $age) . ')';
  320. }
  321. }
  322. $db->sql_freeresult($result);
  323. $tpl_data += array(
  324. 'BIRTHDAY_LIST' => $birthday_list,
  325. 'S_DISPLAY_BIRTHDAY_LIST' => !empty($birthday_list),
  326. );
  327. }
  328. $template->assign_vars($tpl_data + array(
  329. 'S_SINGLE_TRAKING' => !empty($this->output_data['single_traking']) ? true : false,
  330. 'S_LOGIN_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'),
  331. 'S_SEO_FORUM' => strpos($config['default_lang'], 'fr') !== false ? 'fr/' : 'en/',
  332. 'LEFT_COL' => $left_col,
  333. 'RIGHT_COL' => $right_col,
  334. ));
  335. if ($this->actions['pagination_limit'] > 0) { // Add page number to title
  336. $page_title .= $this->start > 0 ? ' - ' . $user->lang['HTML_PAGE'] . ' ' . ( floor( $this->start / $this->actions['pagination_limit'] ) + 1 ) : '';
  337. }
  338. page_header($page_title, $this->html_config['html_disp_online']);
  339. if (!empty($this->html_config['html_logo_url'])) {
  340. $template->assign_vars(array(
  341. 'SITE_LOGO_IMG' => '<img src="' . $this->path_config['gym_img_url'] . $this->html_config['html_logo_url'] . '" alt="' . $this->output_data['page_title'] . '" />',
  342. ));
  343. }
  344. page_footer();
  345. return;
  346. }
  347. /**
  348. * html_index()
  349. * Builds the site map index
  350. * @access private
  351. */
  352. function html_index() {
  353. global $phpEx, $phpbb_root_path, $user, $template, $cache, $phpbb_seo, $config;
  354. if ($this->actions['html_news_list']) {
  355. // Add index page in navigation links
  356. $template->assign_block_vars('navlinks', array(
  357. 'FORUM_NAME' => $user->lang['HTML_MAP'],
  358. 'U_VIEW_FORUM' => append_sid($this->html_config['html_url']. $this->url_config['html_default']),
  359. ));
  360. $this->url_config['current'] = $this->html_config['html_url'] . $this->url_config['html_news_default'];
  361. $this->actions['is_auth'] = true;
  362. $src_url = $this->gym_config['html_rss_news_url'];
  363. // if the source is set on the same domain, hanlde ssl properly
  364. if (strpos($src_url, $config['server_name']) !== false) {
  365. $src_url = $phpbb_seo->sslify($src_url, $phpbb_seo->ssl['use']);
  366. }
  367. $this->actions['is_active'] = $src_url ? 1 : 0;
  368. $params = array(
  369. // Full URL to the RSS 2.0 feed
  370. 'url' => str_replace('&amp;', '&', $src_url),
  371. 'desc' => true,
  372. 'html' => true,
  373. 'limit' => (int) $this->gym_config['html_rss_news_limit'],
  374. );
  375. display_feed($params);
  376. $template->assign_vars(array('GYM_RSS_SLIDE_SP' => false));
  377. $template->set_filenames(array('index_data' => 'gym_sitemaps/gym_link_body.html'));
  378. } else {
  379. $ssl_bit = $phpbb_seo->ssl['use'] ? 'ssl_' : '';
  380. $cache_file = '_gym_html_map_' . $ssl_bit . $user->data['user_lang'];
  381. if (($this->output_data['module_data'] = $cache->get($cache_file)) === false) {
  382. $this->load_modules('html_index');
  383. $cache->put($cache_file, $this->output_data['module_data']);
  384. }
  385. $this->output_data['page_title'] = sprintf($user->lang['HTML_MAP_OF'], $this->html_config['html_sitename']);
  386. $this->actions['is_active'] = $this->actions['is_auth'] = true;
  387. $this->url_config['current'] = $this->html_config['html_url'] . $this->url_config['html_default'];
  388. $template->set_filenames(array('index_data' => 'gym_sitemaps/index_list.html'));
  389. if (!empty($this->output_data['module_data'])) {
  390. foreach ($this->output_data['module_data'] as $module_name => $module_data) {
  391. // First modules
  392. $template->assign_block_vars('module', array(
  393. 'TITLE' => $module_data['title'],
  394. 'NEWS_TITLE' => sprintf($user->lang['HTML_NEWS_OF'], $module_data['title']),
  395. 'MAP_TITLE' => sprintf($user->lang['HTML_MAP_OF'], $module_data['title']),
  396. 'DESC' => $module_data['desc'],
  397. 'IMG' => $module_data['img'],
  398. 'MAP_URL' => append_sid($module_data['map_url']),
  399. 'NEWS_URL' => append_sid($module_data['news_url']),
  400. ));
  401. // Then the module maps & news pages
  402. foreach ($module_data['links'] as $data) {
  403. $template->assign_block_vars('module.links', array(
  404. 'MAP_TITLE' => $data['map_title'],
  405. 'MAP_URL' => append_sid($data['map_url']),
  406. 'NEWS_TITLE' => $data['news_title'],
  407. 'NEWS_URL' => append_sid($data['news_url']),
  408. ));
  409. }
  410. }
  411. }
  412. }
  413. $template->assign_vars(array(
  414. 'HTML_SITENAME' => $this->html_config['html_sitename'],
  415. 'HTML_SITEDESC' => $this->html_config['html_site_desc'],
  416. 'HTML_URL' => $this->html_config['html_allow_map'] ? append_sid($this->html_config['html_url'] . $this->url_config['html_default']) : '',
  417. 'HTML_NEWS_TITLE' => sprintf($user->lang['HTML_NEWS_OF'], $this->html_config['html_sitename']),
  418. 'HTML_NEWS_URL' => $this->html_config['html_allow_news'] ? append_sid($this->html_config['html_url'] . $this->url_config['html_news_default']) : '',
  419. 'NEWS_IMG_SRC' => $this->path_config['gym_img_url'] . 'html_news.gif',
  420. 'ROOT_PATH' => $phpbb_root_path,
  421. ));
  422. $return = $template->assign_display('index_data', '', true);
  423. return $return;
  424. }
  425. /**
  426. * prepare_message($message, $bbcode_uid, $bbcode_bitfield, $patterns = array(), $replaces = array())
  427. * will put together BBcodes and smilies before the output
  428. * @access private
  429. */
  430. function prepare_message(&$message, $bbcode_uid, $bitfield, $patterns = array(), $replaces = array()) {
  431. global $config, $user, $phpbb_root_path;
  432. static $bbcode;
  433. if (!empty($patterns)) {
  434. $message = preg_replace($patterns, $replaces, $message);
  435. }
  436. if ($this->html_config['html_sumarize'] > 0 ) {
  437. $message = $this->summarize( $message, $this->html_config['html_sumarize'], $this->html_config['html_sumarize_method'] );
  438. // Clean broken tag at the end of the message
  439. $message = preg_replace('`\<[^\<\>]*$`i', ' ...', $message);
  440. // Close broken bbcode tags requiring it, only quotes for now
  441. $this->close_bbcode_tags($message, $bbcode_uid);
  442. }
  443. $message = censor_text($message);
  444. if ($bitfield && $this->html_config['html_allow_bbcode']) {
  445. if (!class_exists('bbcode')) {
  446. global $phpbb_root_path, $phpEx;
  447. include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx);
  448. }
  449. if (empty($bbcode)) {
  450. $bbcode = new bbcode($bitfield);
  451. } else {
  452. $bbcode->bbcode($bitfield);
  453. }
  454. $bbcode->bbcode_second_pass($message, $bbcode_uid);
  455. }
  456. $message = bbcode_nl2br($message);
  457. // Parse smilies
  458. $message = $this->smiley_text($message, !$this->html_config['html_allow_smilies']);
  459. if ($this->html_config['html_sumarize'] > 0 ) {
  460. // last clean up
  461. static $_find = array('`\<\!--[^\<\>]+--\>`Ui', '`\[\/?[^\]\[]*\]`Ui');
  462. $message = preg_replace($_find, '', $message);
  463. }
  464. return true;
  465. }
  466. /**
  467. * close_bbcode_tags(&$message, $uid, $bbcodelist)
  468. * will tend to do it nicely ;-)
  469. * Will close the bbcode tags requiring it in the list (quote|b|u|i|color|*|list)
  470. * Beware, bo not reduce $bbcodelist without knowing what you are doing
  471. */
  472. function close_bbcode_tags(&$message, $uid, $bbcodelist = 'quote|b|u|i|color|*|list') {
  473. $open_lists = $close_lists = array();
  474. $bbcodelist = str_replace('|*', '|\*', $bbcodelist);
  475. $open_count = preg_match_all('`\[(' . $bbcodelist . ')(\=([a-z0-9]{1}))?[^\]\[]*\:' . $uid . '\]`i', $message, $open_matches);
  476. $close_count = preg_match_all('`\[/(' . $bbcodelist . ')(\:([a-z]{1}))?[^\]\[]*\:' . $uid . '\]`i', $message, $close_matches);
  477. if ($open_count == $close_count) { // No need to go further
  478. return;
  479. }
  480. if (!empty($open_matches[1])) {
  481. $open_list = array_count_values($open_matches[1]);
  482. $close_list = !empty($close_matches[1]) ? array_count_values($close_matches[1]) : array();
  483. $list_to_close = array();
  484. if (isset($open_list['list'])) {
  485. foreach ($open_matches[1] as $k => $v) {
  486. if ($v == 'list') {
  487. $open_lists[] = !empty($open_matches[3][$k]) ? 'o' : 'u';
  488. }
  489. }
  490. if (!empty($close_matches[1])) {
  491. foreach ($close_matches[1] as $k => $v) {
  492. if ($v == 'list') {
  493. $close_lists[] = !empty($close_matches[3][$k]) ? 'o' : 'u';
  494. }
  495. }
  496. }
  497. $list_to_close = array_reverse(array_diff_assoc($open_lists, $close_lists));
  498. }
  499. unset($open_list['*'], $open_list['list'], $open_matches, $close_matches);
  500. foreach ($open_list as $bbcode => $total) {
  501. if (empty($close_list[$bbcode]) || $close_list[$bbcode] < $total) {
  502. // close the tags
  503. $diff = empty($close_list[$bbcode]) ? $total : $total - $close_list[$bbcode];
  504. $message .= str_repeat("[/$bbcode:$uid]", $diff);
  505. }
  506. }
  507. // Close the lists if required
  508. foreach ($list_to_close as $ltype) {
  509. $message .= "[/*:m:$uid][/list:$ltype:$uid]";
  510. }
  511. }
  512. return;
  513. }
  514. /**
  515. * set_msg_strip($bbcode_list) will build up the unauthed bbcode list
  516. * $bbcode_list = 'code:0,img:1,quote';
  517. * $bbcode_list = 'all';
  518. * 1 means the bbcode and it's content will be striped.
  519. * all means all bbcodes.
  520. * $returned_list = array('patern' => $matching_patterns, 'replace' => $replace_patterns);
  521. * @access private
  522. */
  523. function set_msg_strip($bbcode_list) {
  524. $patterns = $replaces = array();
  525. // Now the bbcodes
  526. if (!$this->html_config['html_allow_bbcode'] || preg_match('`all\:?([0-1]*)`i', $bbcode_list, $matches)) {
  527. if ( (@$matches[1] != 1 ) ) {
  528. $patterns[] = '`\[\/?[a-z0-9\*\+\-]+(?:=(?:&quot;.*&quot;|[^\]]*))?(?::[a-z])?(\:[0-9a-z]{5,})\]`i';
  529. $replaces[] = '';
  530. } else {
  531. $patterns[] = '`\[([a-z0-9\*\+\-]+)((=|:)[^\:\]]*)?\:[0-9a-z]{5,}\].*\[/(?1)(:?[^\:\]]*)?\:[0-9a-z]{5,}\]`Usi';
  532. $replaces[] = "{ \\1 }";
  533. }
  534. $patterns[] = '`<[^>]*>(.*<[^>]*>)?`Usi'; // All html
  535. $replaces[] = '';
  536. } else {
  537. // Take care about links & emails
  538. if ( !$this->html_config['html_allow_links'] ) {
  539. if ( !$this->html_config['html_allow_emails'] ) { // Saves couple RegEx
  540. $email_find = '[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*[a-z]+';
  541. $email_replace = 'str_replace(array("@", "."), array(" AT ", " DOT "),"\\1")';
  542. $email_option = 'e';
  543. } else {
  544. $email_find = '.*?';
  545. $email_replace = "\\1";
  546. $email_option = '';
  547. }
  548. $patterns[] = '`<!\-\- ([lmw]+) \-\-><a (?:class="[\w-]+" )?href="(.*?)">.*?</a><!\-\- \1 \-\->`i';
  549. $replaces[] = "\\2";
  550. $patterns[] = '`\[/?url[^\]\[]*\]`i';
  551. $replaces[] = '';
  552. $patterns[] = '`<!\-\- e \-\-><a href="mailto:(' . $email_find . ')">.*?</a><!\-\- e \-\->`i' . $email_option;
  553. $replaces[] = $email_replace;
  554. }
  555. if ( !$this->html_config['html_allow_emails'] && $this->html_config['html_allow_links'] ) {
  556. $patterns[] = '`<!\-\- e \-\-><a href="mailto:([a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*[a-z]+)">.*?</a><!\-\- e \-\->`ei';
  557. $replaces[] = 'str_replace(array("@", "."), array(" AT ", " DOT "),"\\1")';
  558. }
  559. $exclude_list = ( empty($bbcode_list) ? array() : explode(',', trim($bbcode_list, ', ')) );
  560. $RegEx_unset = $RegEx_remove = '';
  561. foreach ($exclude_list as $key => $value ) { // Group the RegEx
  562. $value = trim($value, ', ');
  563. if (preg_match("`[a-z0-9]+(\:([0-1]*))?`i", $value, $matches) ) {
  564. $values = (strpos($value, ':') !== false) ? explode(':', $value) : array($value);
  565. if ( (@$matches[2] != 1 ) ) {
  566. $RegEx_unset .= (!empty($RegEx_unset) ? '|' : '' ) . $values[0];
  567. } else {
  568. $RegEx_remove .= (!empty($RegEx_remove) ? '|' : '' ) . $values[0];
  569. }
  570. }
  571. }
  572. if (!empty($RegEx_remove) ) {
  573. $patterns[] = '`\[(' . $RegEx_remove . ')((=|:)[^\:\]]*)?\:[0-9a-z]{5,}\].*\[/(?1)(:?[^\:\]]*)?\:[0-9a-z]{5,}\]`Usi';
  574. $replaces[] = "{ \\1 }";
  575. }
  576. if (!empty($RegEx_unset) ) {
  577. $patterns[] = '`\[/?(' . $RegEx_unset . ')(?:=(?:&quot;.*&quot;|[^\]]*))?(?::[a-z])?(\:[0-9a-z]{5,})?\]`i';
  578. $replaces[] = '';
  579. }
  580. }
  581. return array('pattern' => $patterns, 'replace' => $replaces);
  582. }
  583. /**
  584. * Summarize method selector
  585. * @access private
  586. */
  587. function summarize($string, $limit, $method = 'lines') {
  588. switch ($method) {
  589. case 'words':
  590. return $this->word_limit($string, $limit);
  591. break;
  592. case 'chars':
  593. return $this->char_limit($string, $limit);
  594. break;
  595. case 'lines':
  596. default:
  597. return $this->line_limit($string, $limit);
  598. break;
  599. }
  600. }
  601. /**
  602. * Cut the text by lines
  603. * @access private
  604. */
  605. function line_limit($string, $limit = 10, $ellipsis = ' ...') {
  606. return count($lines = preg_split("`[\n\r]+`", ltrim($string), $limit + 1)) > $limit ? rtrim(utf8_substr($string, 0, utf8_strlen($string) - utf8_strlen(end($lines)))) . $ellipsis : $string;
  607. }
  608. /**
  609. * Cut the text according to the number of words.
  610. * Borrowed from www.php.net http://www.php.net/preg_replace
  611. * @access private
  612. */
  613. function word_limit($string, $limit = 50, $ellipsis = ' ...') {
  614. return count($words = preg_split('`\s+`', ltrim($string), $limit + 1)) > $limit ? rtrim(utf8_substr($string, 0, utf8_strlen($string) - utf8_strlen(end($words)))) . $ellipsis : $string;
  615. }
  616. /**
  617. * Cut the text according to the number of characters.
  618. * Borrowed from www.php.net http://www.php.net/preg_replace
  619. * @access private
  620. */
  621. function char_limit($string, $limit = 100, $ellipsis = ' ...') {
  622. return utf8_strlen($fragment = utf8_substr($string, 0, $limit + 1 - utf8_strlen($ellipsis))) < utf8_strlen($string) + 1 ? preg_replace('`\s*\S*$`', '', $fragment) . $ellipsis : $string;
  623. }
  624. /**
  625. * Get forum children (one level or all, with or without info)
  626. * @access private
  627. */
  628. function get_forum_children($forum_id, $skip_pass = true, $only_post = true, $ids_only = true, $one_lvl = true) {
  629. global $db, $auth;
  630. $rows = array();
  631. $_sql_pre = $one_lvl ? 'f1' : 'f2';
  632. $sql_sel = $ids_only ? "$_sql_pre.forum_id, $_sql_pre.forum_type, $_sql_pre.forum_password" : "$_sql_pre.*";
  633. $sql_where = $only_post ? " AND $_sql_pre.forum_type = " . FORUM_POST : '';
  634. if (!$one_lvl) {
  635. $sql = "SELECT $sql_sel
  636. FROM " . FORUMS_TABLE . " f1
  637. LEFT JOIN " . FORUMS_TABLE . " f2 ON (f2.left_id BETWEEN f1.left_id AND f1.right_id)
  638. WHERE f1.forum_id = $forum_id
  639. $sql_where
  640. ORDER BY f2.left_id ASC";
  641. } else {
  642. $sql = "SELECT $sql_sel
  643. FROM " . FORUMS_TABLE . " f1
  644. WHERE f1.parent_id = $forum_id
  645. $sql_where
  646. ORDER BY f1.left_id ASC";
  647. }
  648. $result = $db->sql_query($sql);
  649. while ($row = $db->sql_fetchrow($result)) {
  650. if ($skip_pass && $row['forum_password']) {
  651. continue;
  652. }
  653. $rows[$row['forum_id']] = $row;
  654. }
  655. $db->sql_freeresult($result);
  656. // Do not return this forum info
  657. if (!$one_lvl) {
  658. unset($rows[$forum_id]);
  659. }
  660. // only keep authed forum
  661. foreach ($rows as $_forum_id => $null) {
  662. if (!$auth->acl_get('f_read', $_forum_id)) {
  663. unset($rows[$_forum_id]);
  664. }
  665. }
  666. return !empty($rows) ? $rows : false;
  667. }
  668. /**
  669. * Generate topic status
  670. */
  671. function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$folder_alt, &$topic_type) {
  672. global $user, $config;
  673. $folder = $folder_new = '';
  674. if ($topic_row['topic_status'] == ITEM_MOVED) {
  675. $topic_type = $user->lang['VIEW_TOPIC_MOVED'];
  676. $folder_img = 'topic_moved';
  677. $folder_alt = 'TOPIC_MOVED';
  678. } else {
  679. switch ($topic_row['topic_type']) {
  680. case POST_GLOBAL:
  681. $topic_type = $user->lang['VIEW_TOPIC_GLOBAL'];
  682. $folder = 'global_read';
  683. $folder_new = 'global_unread';
  684. break;
  685. case POST_ANNOUNCE:
  686. $topic_type = $user->lang['VIEW_TOPIC_ANNOUNCEMENT'];
  687. $folder = 'announce_read';
  688. $folder_new = 'announce_unread';
  689. break;
  690. case POST_STICKY:
  691. $topic_type = $user->lang['VIEW_TOPIC_STICKY'];
  692. $folder = 'sticky_read';
  693. $folder_new = 'sticky_unread';
  694. break;
  695. default:
  696. $topic_type = '';
  697. $folder = 'topic_read';
  698. $folder_new = 'topic_unread';
  699. if ($config['hot_threshold'] && $replies >= $config['hot_threshold'] && $topic_row['topic_status'] != ITEM_LOCKED) {
  700. $folder .= '_hot';
  701. $folder_new .= '_hot';
  702. }
  703. break;
  704. }
  705. if ($topic_row['topic_status'] == ITEM_LOCKED) {
  706. $topic_type = $user->lang['VIEW_TOPIC_LOCKED'];
  707. $folder .= '_locked';
  708. $folder_new .= '_locked';
  709. }
  710. $folder_img = ($unread_topic) ? $folder_new : $folder;
  711. $folder_alt = ($unread_topic) ? 'NEW_POSTS' : (($topic_row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_NEW_POSTS');
  712. // Posted image?
  713. if (!empty($topic_row['topic_posted']) && $topic_row['topic_posted']) {
  714. $folder_img .= '_mine';
  715. }
  716. }
  717. if ($topic_row['poll_start'] && $topic_row['topic_status'] != ITEM_MOVED) {
  718. $topic_type = $user->lang['VIEW_TOPIC_POLL'];
  719. }
  720. }
  721. /**
  722. * Generate topic pagination
  723. * Duplicated here to prevent from including functions_display.php
  724. */
  725. function topic_generate_pagination($replies, $url) {
  726. global $config, $user;
  727. // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  728. global $phpbb_seo, $phpEx;
  729. // www.phpBB-SEO.com SEO TOOLKIT END
  730. // Make sure $per_page is a valid value
  731. $per_page = ($config['posts_per_page'] <= 0) ? 1 : $config['posts_per_page'];
  732. if (($replies + 1) > $per_page) {
  733. $total_pages = ceil(($replies + 1) / $per_page);
  734. $pagination = '';
  735. $times = 1;
  736. for ($j = 0; $j < $replies + 1; $j += $per_page) {
  737. $pagination .= '<a href="' . $url . ($j == 0 ? '' : '&amp;start=' . $j) . '">' . $times . '</a>';
  738. if ($times == 1 && $total_pages > 5) {
  739. $pagination .= ' ... ';
  740. // Display the last three pages
  741. $times = $total_pages - 3;
  742. $j += ($total_pages - 4) * $per_page;
  743. } else if ($times < $total_pages) {
  744. $pagination .= '<span class="page-sep">' . $user->lang['COMMA_SEPARATOR'] . '</span>';
  745. }
  746. $times++;
  747. }
  748. // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  749. if (!empty($phpbb_seo->seo_opt['url_rewrite'])) {
  750. static $pagin_find = array();
  751. static $pagin_replace = array();
  752. if (empty($pagin_find)) {
  753. $pagin_find = array('`(https?\://[a-z0-9_/\.-]+/[a-z0-9_\.-]+)(\.(?!' . $phpEx . ')[a-z0-9]+)(\?[\w\#$%&~\-;:=,@+\.]+)?(&amp;|\?)start=([0-9]+)`i', '`(https?\://[a-z0-9_/\.-]+/[a-z0-9_\.-]+)/(\?[\w\#$%&~\-;:=,@+\.]+)?(&amp;|\?)start=([0-9]+)`i' );
  754. $pagin_replace = array( '\1' . $phpbb_seo->seo_delim['start'] . '\5\2\3', '\1/' . $phpbb_seo->seo_static['pagination'] . '\4' . $phpbb_seo->seo_ext['pagination'] . '\2' );
  755. }
  756. $pagination = preg_replace( $pagin_find, $pagin_replace, $pagination );
  757. }
  758. // www.phpBB-SEO.com SEO TOOLKIT END
  759. } else {
  760. $pagination = '';
  761. }
  762. return $pagination;
  763. }
  764. /**
  765. * Get user rank title and image
  766. *
  767. * @param int $user_rank the current stored users rank id
  768. * @param int $user_posts the users number of posts
  769. * @param string &$rank_title the rank title will be stored here after execution
  770. * @param string &$rank_img the rank image as full img tag is stored here after execution
  771. * @param string &$rank_img_src the rank image source is stored here after execution
  772. *
  773. */
  774. function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank_img_src) {
  775. global $ranks, $config, $phpbb_root_path;
  776. if (empty($ranks)) {
  777. global $cache;
  778. $ranks = $cache->obtain_ranks();
  779. }
  780. if (!empty($user_rank)) {
  781. $rank_title = (isset($ranks['special'][$user_rank]['rank_title'])) ? $ranks['special'][$user_rank]['rank_title'] : '';
  782. $rank_img = (!empty($ranks['special'][$user_rank]['rank_image'])) ? '<img src="' . $phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_rank]['rank_image'] . '" alt="' . $ranks['special'][$user_rank]['rank_title'] . '" title="' . $ranks['special'][$user_rank]['rank_title'] . '" />' : '';
  783. $rank_img_src = (!empty($ranks['special'][$user_rank]['rank_image'])) ? $phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_rank]['rank_image'] : '';
  784. } else {
  785. if (!empty($ranks['normal'])) {
  786. foreach ($ranks['normal'] as $rank) {
  787. if ($user_posts >= $rank['rank_min']) {
  788. $rank_title = $rank['rank_title'];
  789. $rank_img = (!empty($rank['rank_image'])) ? '<img src="' . $phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image'] . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : '';
  790. $rank_img_src = (!empty($rank['rank_image'])) ? $phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image'] : '';
  791. break;
  792. }
  793. }
  794. }
  795. }
  796. }
  797. /**
  798. * Get user avatar
  799. *
  800. * @param string $avatar Users assigned avatar name
  801. * @param int $avatar_type Type of avatar
  802. * @param string $avatar_width Width of users avatar
  803. * @param string $avatar_height Height of users avatar
  804. * @param string $alt Optional language string for alt tag within image, can be a language key or text
  805. *
  806. * @return string Avatar image
  807. */
  808. function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR') {
  809. static $avatar_cache = array();
  810. if (isset($avatar_cache[$avatar])) {
  811. return $avatar_cache[$avatar];
  812. }
  813. global $user, $config, $phpbb_root_path, $phpEx;
  814. if (empty($avatar) || !$avatar_type) {
  815. return '';
  816. }
  817. $avatar_img = '';
  818. switch ($avatar_type) {
  819. case AVATAR_UPLOAD:
  820. $avatar_img = $phpbb_root_path . "download/file.$phpEx?avatar=";
  821. break;
  822. case AVATAR_GALLERY:
  823. $avatar_img = $phpbb_root_path . $config['avatar_gallery_path'] . '/';
  824. break;
  825. }
  826. $avatar_img .= $avatar;
  827. return ($avatar_cache[$avatar] = '<img src="' . (str_replace(' ', '%20', $avatar_img)) . '" width="' . $avatar_width . '" height="' . $avatar_height . '" alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />');
  828. }
  829. }
  830. ?>