PageRenderTime 67ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/administrator/components/com_kunenaimporter/models/export_phpbb3.php

https://github.com/johker-wst/com_kunenaimporter
PHP | 2006 lines | 1321 code | 109 blank | 576 comment | 58 complexity | 27264a4da1e93ba32f4f4d96d7f4c533 MD5 | raw file
  1. <?php
  2. /**
  3. * Kunena Importer component
  4. * @package Kunena.com_kunenaimporter
  5. *
  6. * @copyright (C) 2008 - 2012 Kunena Team. All rights reserved.
  7. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
  8. * @link http://www.kunena.org
  9. **/
  10. defined ( '_JEXEC' ) or die ();
  11. // Import Joomla! libraries
  12. jimport ( 'joomla.application.component.model' );
  13. jimport ( 'joomla.application.application' );
  14. require_once (JPATH_COMPONENT . '/models/export.php');
  15. /**
  16. * phpBB3 Exporter Class
  17. *
  18. * Exports almost all data from phpBB3.
  19. * @todo Configuration import needs some work
  20. * @todo Forum ACL not exported (except for moderators)
  21. * @todo URL avatars not exported
  22. * @todo Ranks not exported
  23. * @todo Private messages not exported
  24. * @todo Some emoticons may be missing (images/db are not exported)
  25. */
  26. class KunenaimporterModelExport_phpBB3 extends KunenaimporterModelExport {
  27. /**
  28. * Extension name
  29. * @var string
  30. */
  31. public $extname = 'phpbb3';
  32. /**
  33. * Display name
  34. * @var string
  35. */
  36. public $exttitle = 'phpBB3';
  37. /**
  38. * External application
  39. * @var bool
  40. */
  41. public $external = true;
  42. /**
  43. * Minimum required version
  44. * @var string or null
  45. */
  46. protected $versionmin = '3.0.8';
  47. /**
  48. * Maximum accepted version
  49. * @var string or null
  50. */
  51. protected $versionmax = '3.0.999';
  52. protected $rokbridge = null;
  53. protected $dbconfig = null;
  54. /**
  55. * Get forum path from importer configuration
  56. *
  57. * @return bool
  58. */
  59. public function getPath($absolute = false) {
  60. // Load rokBridge configuration (if exists)
  61. if ($this->rokbridge === null && version_compare(JVERSION, '1.6', '<')) {
  62. $this->rokbridge = JComponentHelper::getParams( 'com_rokbridge' );
  63. }
  64. $path = $this->rokbridge ? $this->rokbridge->get('phpbb3_path') : '';
  65. if (!$this->params->get('path') && $path) {
  66. // Get phpBB3 path from rokBridge
  67. $this->relpath = $path;
  68. $this->basepath = JPATH_ROOT."/{$this->relpath}";
  69. return $absolute ? $this->basepath : $this->relpath;
  70. }
  71. return parent::getPath($absolute);
  72. }
  73. /**
  74. * Detect if component and config.php exists
  75. *
  76. * @return bool
  77. */
  78. public function detectComponent($path=null) {
  79. if ($path === null) $path = $this->basepath;
  80. // Make sure that configuration file exist, but check also something else
  81. if (!JFile::exists("{$path}/config.php")
  82. || !JFile::exists("{$path}/adm/swatch.php")
  83. || !JFile::exists("{$path}/viewtopic.php")) {
  84. return false;
  85. }
  86. return true;
  87. }
  88. /**
  89. * Get database object
  90. */
  91. public function getDatabase() {
  92. $config = $this->getDBConfig();
  93. $database = null;
  94. if ($config) {
  95. $app = JFactory::getApplication ();
  96. $option ['driver'] = $app->getCfg ( 'dbtype' );
  97. $option ['host'] = $config['dbhost'];
  98. $option ['user'] = $config['dbuser'];
  99. $option ['password'] = $config['dbpasswd'];
  100. $option ['database'] = $config['dbname'];
  101. $option ['prefix'] = $config['table_prefix'];
  102. $database = JDatabase::getInstance ( $option );
  103. }
  104. return $database;
  105. }
  106. /**
  107. * Get database settings
  108. */
  109. protected function &getDBConfig() {
  110. if (!$this->dbconfig) {
  111. require "{$this->basepath}/config.php";
  112. $this->dbconfig = get_defined_vars();
  113. }
  114. return $this->dbconfig;
  115. }
  116. public function initialize() {
  117. global $phpbb_root_path, $phpEx;
  118. if(!defined('IN_PHPBB')) {
  119. define('IN_PHPBB', true);
  120. }
  121. if(!defined('STRIP')) {
  122. define('STRIP', (get_magic_quotes_gpc()) ? true : false);
  123. }
  124. $phpbb_root_path = $this->basepath.'/';
  125. $phpEx = substr(strrchr(__FILE__, '.'), 1);
  126. }
  127. public function &getConfig() {
  128. if (empty($this->config)) {
  129. // Check if database settings are correct
  130. $query = "SELECT config_name, config_value AS value FROM #__config";
  131. $this->ext_database->setQuery ( $query );
  132. $this->config = $this->ext_database->loadObjectList ('config_name');
  133. }
  134. return $this->config;
  135. }
  136. /**
  137. * Full detection
  138. *
  139. * Make sure that everything is OK for full import.
  140. * Use $this->addMessage($html) to add status messages.
  141. * If you return false, remember also to fill $this->error
  142. *
  143. * @return bool
  144. */
  145. public function detect() {
  146. // Initialize detection (also calls $this->detectComponent())
  147. if (!parent::detect()) return false;
  148. // Check RokBridge
  149. if ($this->rokbridge && $this->rokbridge->get('phpbb3_path')) {
  150. $this->addMessage ( '<div>RokBridge: <b style="color:green">detected</b></div>' );
  151. }
  152. // Check authentication method
  153. $query = "SELECT config_value FROM #__config WHERE config_name='auth_method'";
  154. $this->ext_database->setQuery ( $query );
  155. $auth_method = $this->ext_database->loadResult () or die ( "<br />Invalid query:<br />$query<br />" . $this->ext_database->errorMsg () );
  156. $this->addMessage ( '<div>phpBB authentication method: <b style="color:green">' . $auth_method . '</b></div>' );
  157. // Find out which field is used as username
  158. $fields = $this->ext_database->getTableFields('#__users');
  159. $this->login_field = isset($fields['#__users']['login_name']);
  160. return true;
  161. }
  162. /**
  163. * Get component version
  164. */
  165. public function getVersion() {
  166. $query = "SELECT config_value FROM #__config WHERE config_name='version'";
  167. $this->ext_database->setQuery ( $query );
  168. $version = $this->ext_database->loadResult ();
  169. // phpBB2 version
  170. if ($version [0] == '.')
  171. $version = '2' . $version;
  172. return $version;
  173. }
  174. /**
  175. * Remove htmlentities, addslashes etc
  176. *
  177. * @param string $s String
  178. */
  179. protected function parseText(&$s) {
  180. $s = html_entity_decode ( $s );
  181. }
  182. /**
  183. * Convert BBCode to Kunena BBCode
  184. *
  185. * @param string $s String
  186. */
  187. protected function parseBBCode(&$s) {
  188. $s = html_entity_decode ( $s );
  189. // [b]: bold font
  190. $s = preg_replace ( '/\[b(:.*?)\]/', '[b]', $s );
  191. $s = preg_replace ( '/\[\/b(:.*?)\]/', '[/b]', $s );
  192. // [i]: italic font
  193. $s = preg_replace ( '/\[i(:.*?)\]/', '[i]', $s );
  194. $s = preg_replace ( '/\[\/i(:.*?)\]/', '[/i]', $s );
  195. // [u]: underlined font
  196. $s = preg_replace ( '/\[u(:.*?)\]/', '[u]', $s );
  197. $s = preg_replace ( '/\[\/u(:.*?)\]/', '[/u]', $s );
  198. // [quote], [quote=*]: (named) quotes
  199. $s = preg_replace ( '/\[quote(:.*?)\]/', '[quote]', $s );
  200. $s = preg_replace ( '/\[quote=["\']?([^"\']+?)["\']?(\s*):([^:]+?)\]/', '[quote="\\1"]', $s );
  201. $s = preg_replace ( '/\[\/quote(:.*?)\]/', '[/quote]', $s );
  202. // [img]: images
  203. $s = preg_replace ( '/\[img(:.*?)\]/', '[img]', $s );
  204. $s = preg_replace ( '/[\/img(:.*?)\]/', '[/img]', $s );
  205. // [color=*]: font color
  206. $s = preg_replace ( '/\[color=(.+?):([^:]+?)\]/', '[color=\\1]', $s );
  207. $s = preg_replace ( '/\[\/color(:.*?)\]/', '[/color]', $s );
  208. /*
  209. * [size=*]: font size
  210. * Sizes range from 1 <= size <= 200. Map them to 1-6 using the
  211. * following map:
  212. *
  213. * phpbb kunena
  214. * 1-39 1
  215. * 40-79 2
  216. * 80-119 3
  217. * 120-159 4
  218. * 160-179 5
  219. * 180-200 6
  220. */
  221. $s = preg_replace ( '/\[size=[123]?[0-9](:.*?)\]/', '[size=1]', $s );
  222. $s = preg_replace ( '/\[size=[4567][0-9](:.*?)\]/', '[size=2]', $s );
  223. $s = preg_replace ( '/\[size=(8|9|10|11)[0-9](:.*?)\]/', '[size=3]', $s );
  224. $s = preg_replace ( '/\[size=(12|13|14|15)[0-9](:.*?)\]/', '[size=4]', $s );
  225. $s = preg_replace ( '/\[size=(16|17)[0-9](:.*?)\]/', '[size=5]', $s );
  226. $s = preg_replace ( '/\[size=(((18|19)[0-9])|200)(:.*?)\]/', '[size=6]', $s );
  227. $s = preg_replace ( '/\[\/size(:.*?)\]/', '[/size]', $s );
  228. // [code], [code=*]: raw code with and without syntax highlighting
  229. $s = preg_replace ( '/\[code(:.*?)\]/', '[code]', $s );
  230. $s = preg_replace ( '/\[code=([a-z]+):([^:]+?)\]/', '[code type="\\1"]', $s );
  231. $s = preg_replace ( '/\[\/code(:.*?)\]/', '[/code]', $s );
  232. // [list], [list=*], [*], [/*]: lists (ordered, unordered), list elements
  233. // default list
  234. $s = preg_replace ( '/\[list(:.*?)\]/', '[list]', $s );
  235. // roman
  236. $s = preg_replace ( '/\[list=([iI])(:.*?)\]/', '[list=\\1]', $s );
  237. // numeric
  238. $s = preg_replace ( '/\[list=([0-9]+)(:.*?)\]/', '[list=1]', $s );
  239. // lower alpha
  240. $s = preg_replace ( '/\[list=([a-z])(:.*?)\]/', '[list=a]', $s );
  241. // upper alpha
  242. $s = preg_replace ( '/\[list=([A-Z])(:.*?)\]/', '[list=A]', $s );
  243. // misc
  244. $s = preg_replace ( '/\[list=(disc|circle|square)(:.*?)\]/', '[list=\\1]', $s );
  245. $s = preg_replace ( '/\[\/list:u(:.*?)\]/', '[/list]', $s );
  246. $s = preg_replace ( '/\[\/list:o(:.*?)\]/', '[/list]', $s );
  247. // TODO [*] does not need to be closed (no [/*])
  248. $s = preg_replace ( '/\[\*(:.*?)\]/', '[li]', $s );
  249. $s = preg_replace ( '/\[\/\*(:.*?)\]/', '[/li]', $s );
  250. // smileys
  251. $s = preg_replace ( '/<!-- s(.*?) --\>\<img src=\"{SMILIES_PATH}.*?\/\>\<!-- s.*? --\>/', ' \\1 ', $s );
  252. // misc
  253. $s = preg_replace ( '/\<!-- e(.*?) --\>/', '', $s );
  254. $s = preg_replace ( '/\<!-- w(.*?) --\>/', '', $s );
  255. $s = preg_replace ( '/\<!-- m(.*?) --\>/', '', $s );
  256. $s = preg_replace ( '/\<!-- l(.*?) --\>/', '', $s ); // local url
  257. $s = preg_replace ( '/\<!-- ia(.*?) --\>/', '', $s ); // inline attachment
  258. // [email], [email=*]: mailto link with optional text
  259. $s = preg_replace ( '/\[email(:.*?)\]/', '[email]', $s );
  260. $s = preg_replace ( '/\[email=(.+?):([^:]+?)\]/', '[email=\\1]', $s );
  261. $s = preg_replace ( '/\[\/email(:.*?)\]/', '[/email]', $s );
  262. // <a href="*">*</a>: HTML links with optional text
  263. // TODO: convert urls
  264. $s = preg_replace ( '/\<a class=\"postlink\" href=\"(.*?)\"\>(.*?)\<\/a\>/', '[url=\\1]\\2[/url]', $s );
  265. $s = preg_replace ( '/\<a class=\"postlink-local\" href=\"(.*?)\"\>(.*?)\<\/a\>/', '[url=\\1]\\2[/url]', $s );
  266. $s = preg_replace ( '/\<a href=\"(.*?)\"\>(.*?)\<\/a\>/', '[url=\\1]\\2[/url]', $s );
  267. $s = preg_replace ( '/\<a href=.*?mailto:.*?\>/', '', $s );
  268. // [url], [url=*]: URL links with optional text
  269. $s = preg_replace ( '/\[url(:.*?)\]/', '[url]', $s );
  270. $s = preg_replace ( '/\[url=(.+?):([^:]+?)\]/', '[url=\\1]', $s );
  271. $s = preg_replace ( '/\[\/url(:.*?)\]/', '[/url]', $s );
  272. $s = preg_replace ( '/\<\/a\>/', '', $s );
  273. // [flash]: flash videos
  274. $s = preg_replace ( '\[flash(.*?)\](.*?)\[\/flash(.*?)\]', '', $s );
  275. // snesfreaks specific
  276. $s = preg_replace ( '/\[(s|strike)(:.*?)\]/', '[strike]', $s );
  277. $s = preg_replace ( '/\[\/(s|strike)(:.*?)\]/', '[/strike]', $s );
  278. $s = preg_replace ( '/\[blink(:.*?)\]/', '', $s );
  279. $s = preg_replace ( '/\[\/blink(:.*?)\]/', '', $s );
  280. $s = preg_replace ( '/\[spoiler(:.*?)\]/', '[spoiler]', $s );
  281. $s = preg_replace ( '/\[\/spoiler(:.*?)\]/', '[/spoiler]', $s );
  282. // get youtube video id: http://stackoverflow.com/questions/3392993/php-regex-to-get-youtube-video-id
  283. $s = preg_replace_callback ( '/\[youtube(:.*?)\](.*)\[\/youtube(:.*?)\]/',
  284. function($m) {
  285. $parts = parse_url($m[2]);
  286. if (isset($parts['query'])) {
  287. parse_str($parts['query'], $qs);
  288. if (isset($qs['v'])) {
  289. $id = $qs['v'];
  290. } else if($qs['vi']) {
  291. $id = $qs['vi'];
  292. }
  293. }
  294. if (isset($parts['path'])) {
  295. $path = explode('/', trim($parts['path'], '/'));
  296. $id = $path[count($path)-1];
  297. }
  298. return '[video type="youtube"]' . $id . '[/video]';
  299. }
  300. , $s );
  301. }
  302. /**
  303. * Map Joomla user to external user
  304. *
  305. * @param object $joomlauser StdClass(id, username, email)
  306. * @return int External user ID
  307. */
  308. public function mapJoomlaUser($joomlauser) {
  309. if ($this->login_field) {
  310. // Use login_name created by SMF to phpBB3 convertor
  311. $field = 'login_name';
  312. $username = $joomlauser->username;
  313. } else {
  314. $field = 'username_clean';
  315. $username = utf8_clean_string($joomlauser->username);
  316. }
  317. $query = "SELECT user_id
  318. FROM #__users WHERE {$field}={$this->ext_database->Quote($username)}";
  319. $this->ext_database->setQuery( $query );
  320. $result = intval($this->ext_database->loadResult());
  321. return $result;
  322. }
  323. /**
  324. * Count total number of users to be exported
  325. */
  326. public function countUsers() {
  327. $query = "SELECT COUNT(*) FROM #__users AS u WHERE user_id > 0 AND u.user_type != 2";
  328. return $this->getCount ( $query );
  329. }
  330. /**
  331. * Export users
  332. *
  333. * Returns list of user extuser objects containing database fields
  334. * to #__kunenaimporter_users.
  335. *
  336. * @param int $start Pagination start
  337. * @param int $limit Pagination limit
  338. * @return array
  339. */
  340. public function &exportUsers($start = 0, $limit = 0) {
  341. // phpbb3 user_type: 0=normal, 1=inactive, 2=ignore, 3=founder (super admin)
  342. $username = $this->login_field ? 'login_name' : 'username';
  343. $query = "SELECT
  344. u.user_id AS extid,
  345. u.username_clean AS extusername,
  346. u.username AS name,
  347. u.{$username} AS username,
  348. u.user_email AS email,
  349. u.user_password AS password,
  350. IF(u.user_type=3, 'Administrator', 'Registered') AS usertype,
  351. IF(b.ban_userid>0 OR u.user_type=1, 1, 0) AS block,
  352. FROM_UNIXTIME(u.user_regdate) AS registerDate,
  353. IF(u.user_lastvisit>0, FROM_UNIXTIME(u.user_lastvisit), '0000-00-00 00:00:00') AS lastvisitDate,
  354. NULL AS params,
  355. u.user_pass_convert AS password_phpbb2
  356. FROM #__users AS u
  357. LEFT JOIN #__banlist AS b ON u.user_id = b.ban_userid
  358. WHERE user_id > 0 AND u.user_type != 2
  359. GROUP BY u.user_id
  360. ORDER BY u.user_id";
  361. $result = $this->getExportData ( $query, $start, $limit, 'extid' );
  362. foreach ( $result as &$row ) {
  363. $this->parseText ( $row->name );
  364. $this->parseText ( $row->username );
  365. $this->parseText ( $row->email );
  366. // Password hash check is described in phpBB3/includes/functions.php: phpbb_check_hash(),
  367. // _hash_crypt_private() and _hash_encode64() if we want to add plugin for phpBB3 authentication.
  368. // It works for all phpBB3 passwords, but phpBB2 passwords may need some extra work, which is
  369. // described in phpBB3/includes/auth/auth_db.php. Basically phpBB2 passwords are encoded by using
  370. // md5(utf8_to_cp1252(addslashes($password))).
  371. if ($row->password_phpbb2) {
  372. $row->password = 'phpbb2::'.$row->password;
  373. } else {
  374. $row->password = 'phpbb3::'.$row->password;
  375. }
  376. }
  377. return $result;
  378. }
  379. /**
  380. * Count total number of user profiles to be exported
  381. */
  382. public function countUserProfile() {
  383. $query = "SELECT COUNT(*) FROM #__users AS u WHERE user_id > 0 AND u.user_type != 2";
  384. return $this->getCount ( $query );
  385. }
  386. /**
  387. * Helper function to get list of all moderators
  388. */
  389. protected function getModerators() {
  390. static $mods = null;
  391. if ($mods === null) {
  392. // Get users in moderator groups
  393. $query = "SELECT
  394. u.user_id AS userid,
  395. ag.forum_id AS catid
  396. FROM #__acl_roles AS ar
  397. INNER JOIN #__acl_groups AS ag ON ar.role_id=ag.auth_role_id
  398. INNER JOIN #__user_group AS ug ON ug.group_id=ag.group_id
  399. INNER JOIN #__users AS u ON u.user_id=ug.user_id AND u.user_id > 0 AND u.user_type != 2
  400. WHERE role_type='m_'";
  401. $result = $this->getExportData ( $query, 0, 10000 );
  402. $mods = array();
  403. foreach ($result as $item) {
  404. $mods[$item->userid][$item->catid] = 1;
  405. }
  406. // Get individual moderator rights
  407. $query = "SELECT
  408. u.user_id AS userid,
  409. au.forum_id AS catid
  410. FROM #__acl_roles AS ar
  411. INNER JOIN #__acl_users AS au ON ar.role_id=au.auth_role_id
  412. INNER JOIN #__users AS u ON u.user_id=au.user_id AND u.user_id > 0 AND u.user_type != 2
  413. WHERE role_type='m_'";
  414. $result = $this->getExportData ( $query, 0, 10000 );
  415. foreach ($result as $item) {
  416. $mods[$item->userid][$item->catid] = 1;
  417. }
  418. }
  419. return $mods;
  420. }
  421. /**
  422. * Export user profiles
  423. *
  424. * Returns list of user profile objects containing database fields
  425. * to #__kunena_users.
  426. *
  427. * @param int $start Pagination start
  428. * @param int $limit Pagination limit
  429. * @return array
  430. */
  431. public function &exportUserProfile($start = 0, $limit = 0) {
  432. $query = "SELECT
  433. u.user_id AS userid,
  434. 'flat' AS view,
  435. u.user_sig AS signature,
  436. 0 AS moderator,
  437. NULL AS banned,
  438. 0 AS ordering,
  439. u.user_posts AS posts,
  440. u.user_avatar AS avatar,
  441. 0 AS karma,
  442. 0 AS karma_time,
  443. 0 AS uhits,
  444. NULL AS personalText,
  445. 0 AS gender,
  446. u.user_birthday AS birthdate,
  447. u.user_from AS location,
  448. u.user_icq AS ICQ,
  449. u.user_aim AS AIM,
  450. u.user_yim AS YIM,
  451. u.user_msnm AS MSN,
  452. NULL AS SKYPE,
  453. NULL AS TWITTER,
  454. NULL AS FACEBOOK,
  455. u.user_jabber AS GTALK,
  456. NULL AS MYSPACE,
  457. NULL AS LINKEDIN,
  458. NULL AS DELICIOUS,
  459. NULL AS FRIENDFEED,
  460. NULL AS DIGG,
  461. NULL AS BLOGSPOT,
  462. NULL AS FLICKR,
  463. NULL AS BEBO,
  464. u.user_website AS websitename,
  465. u.user_website AS websiteurl,
  466. 0 AS rank,
  467. (u.user_allow_viewemail=0) AS hideEmail,
  468. u.user_allow_viewonline AS showOnline,
  469. u.user_avatar_type AS avatartype
  470. FROM #__users AS u
  471. WHERE u.user_id > 0 AND u.user_type != 2
  472. ORDER BY u.user_id";
  473. $result = $this->getExportData ( $query, $start, $limit, 'userid' );
  474. $moderators = $this->getModerators();
  475. $config = $this->getConfig();
  476. $path = $config['avatar_path']->value;
  477. $salt = $config['avatar_salt']->value;
  478. foreach ( $result as &$row ) {
  479. // Assign global moderator status
  480. if (!empty($moderators[$row->userid])) $row->moderator = 1;
  481. // Convert bbcode in signature
  482. if ($row->avatar) {
  483. switch ($row->avatartype) {
  484. case 1:
  485. // Uploaded
  486. $filename = (int) $row->avatar;
  487. $ext = substr(strrchr($row->avatar, '.'), 1);
  488. $row->avatar = "users/{$row->avatar}";
  489. $row->copypath = "{$this->basepath}/{$path}/{$salt}_{$filename}.{$ext}";
  490. break;
  491. case 2:
  492. // URL not supported
  493. $row->avatar = '';
  494. break;
  495. case 3:
  496. // Gallery
  497. $row->avatar = "gallery/{$row->avatar}";
  498. break;
  499. default:
  500. $row->avatar = '';
  501. }
  502. }
  503. $this->parseBBCode ( $row->signature );
  504. $this->parseText ( $row->location );
  505. $this->parseText ( $row->AIM );
  506. $this->parseText ( $row->YIM );
  507. $this->parseText ( $row->MSN );
  508. $this->parseText ( $row->GTALK );
  509. $this->parseText ( $row->websitename );
  510. $this->parseText ( $row->websiteurl );
  511. }
  512. return $result;
  513. }
  514. /**
  515. * Count total number of sessions to be exported
  516. */
  517. public function countSessions() {
  518. $query = "SELECT COUNT(*) FROM #__users AS u WHERE user_lastvisit>0";
  519. return $this->getCount ( $query );
  520. }
  521. /**
  522. * Export user session information
  523. *
  524. * Returns list of session objects containing database fields
  525. * to #__kunena_sessions.
  526. *
  527. * @param int $start Pagination start
  528. * @param int $limit Pagination limit
  529. * @return array
  530. */
  531. public function &exportSessions($start = 0, $limit = 0) {
  532. $query = "SELECT
  533. user_id AS userid,
  534. NULL AS allowed,
  535. user_lastmark AS lasttime,
  536. 'na' AS readtopics,
  537. user_lastvisit AS currvisit
  538. FROM #__users
  539. WHERE user_lastvisit>0";
  540. $result = $this->getExportData ( $query, $start, $limit );
  541. return $result;
  542. }
  543. /**
  544. * Count total number of categories to be exported
  545. */
  546. public function countCategories() {
  547. $query = "SELECT COUNT(*) FROM #__forums";
  548. return $this->getCount ( $query );
  549. }
  550. /**
  551. * Export sections and categories
  552. *
  553. * Returns list of category objects containing database fields
  554. * to #__kunena_categories.
  555. * All categories without parent are sections.
  556. *
  557. * NOTE: it's very important to keep category IDs (containing topics) the same!
  558. * If there are two tables for sections and categories, change IDs on sections..
  559. *
  560. * @param int $start Pagination start
  561. * @param int $limit Pagination limit
  562. * @return array
  563. */
  564. public function &exportCategories($start = 0, $limit = 0) {
  565. $query = "SELECT
  566. forum_id AS id,
  567. parent_id AS parent_id,
  568. forum_name AS name,
  569. forum_name AS alias,
  570. 0 AS icon_id,
  571. (forum_status=1) AS locked,
  572. 'joomla.level' AS accesstype,
  573. 0 AS access,
  574. 0 AS pub_access,
  575. 1 AS pub_recurse,
  576. 0 AS admin_access,
  577. 1 AS admin_recurse,
  578. left_id AS ordering,
  579. 1 AS published,
  580. null AS channels,
  581. 0 AS checked_out,
  582. '0000-00-00 00:00:00' AS checked_out_time,
  583. 0 AS review,
  584. 0 AS allow_anonymous,
  585. 0 AS post_anonymous,
  586. 0 AS hits,
  587. forum_desc AS description,
  588. forum_rules AS headerdesc,
  589. '' AS class_sfx,
  590. 1 AS allow_polls,
  591. '' AS topic_ordering,
  592. forum_posts AS numPosts,
  593. forum_topics_real AS numTopics,
  594. 0 AS last_topic_id,
  595. forum_last_post_id AS last_post_id,
  596. forum_last_post_time AS last_post_time,
  597. (LENGTH(forum_desc_bitfield)>0) AS bbcode_desc,
  598. (LENGTH(forum_rules_bitfield)>0) AS bbcode_header,
  599. '' AS params
  600. FROM #__forums ORDER BY id";
  601. $result = $this->getExportData ( $query, $start, $limit, 'id' );
  602. foreach ( $result as &$row ) {
  603. $this->parseText ( $row->name );
  604. // FIXME: joomla level in J2.5
  605. // FIXME: remove id
  606. $row->alias = KunenaRoute::stringURLSafe("{$row->id}-{$row->alias}");
  607. if ($row->bbcode_desc) $this->parseBBCode ( $row->description );
  608. else $this->parseText ( $row->description );
  609. if ($row->bbcode_header) $this->parseBBCode ( $row->headerdesc );
  610. else $this->parseText ( $row->headerdesc );
  611. }
  612. return $result;
  613. }
  614. /**
  615. * Count total number of moderator columns to be exported
  616. */
  617. public function countUserCategories_Role() {
  618. $mods = $this->getModerators();
  619. $result = 0;
  620. foreach ($mods as $userid=>$item) {
  621. foreach ($item as $catid=>$value) {
  622. $result++;
  623. }
  624. }
  625. return $result;
  626. }
  627. /**
  628. * Export moderator columns
  629. *
  630. * Returns list of moderator objects containing database fields
  631. * to #__kunena_user_categories.
  632. *
  633. * @param int $start Pagination start
  634. * @param int $limit Pagination limit
  635. * @return array
  636. */
  637. public function &exportUserCategories_Role($start = 0, $limit = 0) {
  638. $mods = $this->getModerators();
  639. $result = array();
  640. foreach ($mods as $userid=>$item) {
  641. foreach ($item as $catid=>$value) {
  642. $mod = new StdClass();
  643. $mod->user_id = $userid;
  644. $mod->category_id = $catid;
  645. $mod->role = 1;
  646. $result[] = $mod;
  647. }
  648. }
  649. $result = array_slice($result, $start, $limit);
  650. return $result;
  651. }
  652. /**
  653. * Count total number of all read time columns to be exported
  654. */
  655. public function countUserCategories_Allreadtime() {
  656. $query = "SELECT COUNT(*) FROM #__forums_track";
  657. return $this->getCount ( $query );
  658. }
  659. /**
  660. * Export all read time columns
  661. *
  662. * Returns list of all userCategory objects containing database fields
  663. * to #__kunena_user_categories.
  664. *
  665. * @param int $start Pagination start
  666. * @param int $limit Pagination limit
  667. * @return array
  668. */
  669. public function &exportUserCategories_Allreadtime($start = 0, $limit = 0) {
  670. $query = "SELECT
  671. user_id AS user_id,
  672. forum_id AS category_id,
  673. FROM_UNIXTIME(mark_time) AS allreadtime
  674. FROM #__forums_track";
  675. return $this->getExportData ( $query, $start, $limit );
  676. }
  677. /**
  678. * Count total number of category subscription columns to be exported
  679. */
  680. public function countUserCategories_Subscribed() {
  681. $query = "SELECT COUNT(*) FROM #__forums_watch";
  682. return $this->getCount ( $query );
  683. }
  684. /**
  685. * Export category subscription columns
  686. *
  687. * Returns list of userCategory objects containing database fields
  688. * to #__kunena_user_categories.
  689. *
  690. * @param int $start Pagination start
  691. * @param int $limit Pagination limit
  692. * @return array
  693. */
  694. public function &exportUserCategories_Subscribed($start = 0, $limit = 0) {
  695. $query = "SELECT
  696. user_id AS user_id,
  697. forum_id AS category_id,
  698. (notify_status+1) AS subscribed
  699. FROM #__forums_watch";
  700. return $this->getExportData ( $query, $start, $limit );
  701. }
  702. /**
  703. * Count total number of topics to be exported
  704. */
  705. public function countTopics() {
  706. $query = "SELECT COUNT(*) FROM #__topics";
  707. $count = $this->getCount ( $query );
  708. return $count;
  709. }
  710. /**
  711. * Export topics
  712. *
  713. * Returns list of message objects containing database fields
  714. * to #__kunena_topics.
  715. *
  716. * @param int $start Pagination start
  717. * @param int $limit Pagination limit
  718. * @return array
  719. */
  720. public function &exportTopics($start = 0, $limit = 0) {
  721. $query = "SELECT
  722. topic_id AS id,
  723. forum_id AS category_id,
  724. topic_title AS subject,
  725. icon_id AS icon_id,
  726. (topic_status=1) AS locked,
  727. (topic_approved=0) AS hold,
  728. (topic_type>0) AS ordering,
  729. (topic_replies+1) AS posts,
  730. topic_views AS hits,
  731. topic_attachment AS attachments,
  732. 0 AS poll_id,
  733. IF(topic_status=1,topic_moved_id,0) AS moved_id,
  734. topic_first_post_id AS first_post_id,
  735. 0 AS first_post_time,
  736. 0 AS first_post_userid,
  737. '' AS first_post_message,
  738. topic_first_poster_name AS first_post_guest_name,
  739. topic_last_post_id AS last_post_id,
  740. 0 AS last_post_time,
  741. 0 AS last_post_userid,
  742. '' AS last_post_message,
  743. topic_last_poster_name AS last_post_guest_name,
  744. '' AS params
  745. FROM #__topics";
  746. // TODO: add support for announcements and global topics
  747. $result = $this->getExportData ( $query, $start, $limit );
  748. foreach ( $result as $key => &$row ) {
  749. $this->parseText ( $row->subject );
  750. $this->parseText ( $row->first_post_guest_name );
  751. $this->parseText ( $row->last_post_guest_name );
  752. $this->parseBBCode ( $row->first_post_message );
  753. $this->parseBBCode ( $row->last_post_message );
  754. }
  755. return $result;
  756. }
  757. /**
  758. * Count total number of messages to be exported
  759. */
  760. public function countMessages() {
  761. $query = "SELECT COUNT(*) FROM #__posts";
  762. return $this->getCount ( $query );
  763. }
  764. /**
  765. * Export messages
  766. *
  767. * Returns list of message objects containing database fields
  768. * to #__kunena_messages (and #__kunena_messages_text.message).
  769. *
  770. * @param int $start Pagination start
  771. * @param int $limit Pagination limit
  772. * @return array
  773. */
  774. public function &exportMessages($start = 0, $limit = 0) {
  775. $query = "SELECT
  776. p.post_id AS id,
  777. IF(p.post_id=t.topic_first_post_id,0,t.topic_first_post_id) AS parent,
  778. p.topic_id AS thread,
  779. p.forum_id AS catid,
  780. IF(p.post_username, p.post_username, u.username) AS name,
  781. p.poster_id AS userid,
  782. u.user_email AS email,
  783. IF(p.post_subject, p.post_subject, t.topic_title) AS subject,
  784. p.post_time AS time,
  785. p.poster_ip AS ip,
  786. 0 AS topic_emoticon,
  787. (t.topic_status=1 AND p.post_id=t.topic_first_post_id) AS locked,
  788. (p.post_approved=0) AS hold,
  789. (t.topic_type>0 AND p.post_id=t.topic_first_post_id) AS ordering,
  790. IF(p.post_id=t.topic_first_post_id,0,t.topic_views) AS hits,
  791. t.topic_moved_id AS moved,
  792. p.post_edit_user AS modified_by,
  793. p.post_edit_time AS modified_time,
  794. p.post_edit_reason AS modified_reason,
  795. p.post_text AS message,
  796. enable_bbcode
  797. FROM #__posts AS p
  798. LEFT JOIN #__topics AS t ON p.topic_id = t.topic_id
  799. LEFT JOIN #__users AS u ON p.poster_id = u.user_id
  800. ORDER BY p.post_id";
  801. $result = $this->getExportData ( $query, $start, $limit, 'id' );
  802. foreach ( $result as &$row ) {
  803. $this->parseText ( $row->name );
  804. $this->parseText ( $row->email );
  805. $this->parseText ( $row->subject );
  806. if (! $row->modified_time)
  807. $row->modified_by = 0;
  808. $this->parseText ( $row->modified_reason );
  809. if ($row->moved) {
  810. // TODO: support moved messages (no txt)
  811. $row->message = "id={$row->moved}";
  812. $row->moved = 1;
  813. } else {
  814. if ($row->enable_bbcode) $this->parseBBcode ( $row->message );
  815. else $this->parseText ( $row->message );
  816. }
  817. }
  818. return $result;
  819. }
  820. /**
  821. * Count total polls to be exported
  822. */
  823. public function countPolls() {
  824. $query="SELECT COUNT(*) FROM #__topics WHERE poll_title!=''";
  825. return $this->getCount($query);
  826. }
  827. /**
  828. * Export polls
  829. *
  830. * Returns list of poll objects containing database fields
  831. * to #__kunena_polls.
  832. *
  833. * @param int $start Pagination start
  834. * @param int $limit Pagination limit
  835. * @return array
  836. */
  837. public function &exportPolls($start=0, $limit=0) {
  838. $query="SELECT
  839. topic_id AS id,
  840. poll_title AS title,
  841. topic_id AS threadid,
  842. IF(poll_length>0,FROM_UNIXTIME(poll_start+poll_length),'0000-00-00 00:00:00') AS polltimetolive
  843. FROM #__topics
  844. WHERE poll_title!=''
  845. ORDER BY threadid";
  846. $result = $this->getExportData($query, $start, $limit, 'id');
  847. return $result;
  848. }
  849. /**
  850. * Count total poll options to be exported
  851. */
  852. public function countPollsOptions() {
  853. $query="SELECT COUNT(*) FROM #__poll_options AS o INNER JOIN #__topics AS t ON o.topic_id=t.topic_id";
  854. return $this->getCount($query);
  855. }
  856. /**
  857. * Export poll options
  858. *
  859. * Returns list of poll options objects containing database fields
  860. * to #__kunena_polls_options.
  861. *
  862. * @param int $start Pagination start
  863. * @param int $limit Pagination limit
  864. * @return array
  865. */
  866. public function &exportPollsOptions($start=0, $limit=0) {
  867. $query="SELECT
  868. 0 AS id,
  869. t.topic_id AS pollid,
  870. o.poll_option_text AS text,
  871. o.poll_option_total AS votes
  872. FROM #__poll_options AS o
  873. INNER JOIN #__topics AS t ON o.topic_id=t.topic_id
  874. ORDER BY pollid, o.poll_option_id";
  875. $result = $this->getExportData($query, $start, $limit);
  876. return $result;
  877. }
  878. /**
  879. * Count total poll users to be exported
  880. */
  881. public function countPollsUsers() {
  882. $query="SELECT COUNT(DISTINCT v.vote_user_id) FROM #__poll_votes AS v INNER JOIN #__topics AS t ON v.topic_id=t.topic_id";
  883. return $this->getCount($query);
  884. }
  885. /**
  886. * Export poll users
  887. *
  888. * Returns list of poll users objects containing database fields
  889. * to #__kunena_polls_users.
  890. *
  891. * @param int $start Pagination start
  892. * @param int $limit Pagination limit
  893. * @return array
  894. */
  895. public function &exportPollsUsers($start=0, $limit=0) {
  896. // WARNING: from unknown reason pollid = threadid!!!
  897. $query="SELECT
  898. t.topic_id AS pollid,
  899. v.vote_user_id AS userid,
  900. COUNT(*) AS votes,
  901. '0000-00-00 00:00:00' AS lasttime,
  902. 0 AS lastvote
  903. FROM #__poll_votes AS v
  904. INNER JOIN #__topics AS t ON v.topic_id=t.topic_id
  905. GROUP BY v.vote_user_id";
  906. $result = $this->getExportData($query, $start, $limit);
  907. return $result;
  908. }
  909. /**
  910. * Count total number of all read time columns to be exported
  911. */
  912. public function countUserTopics_Allreadtime() {
  913. $query = "SELECT COUNT(*) FROM #__topics_track";
  914. return $this->getCount ( $query );
  915. }
  916. /**
  917. * Export mark read information for topics
  918. *
  919. * Returns list of items containing database fields
  920. * to #__kunena_user_topics.
  921. *
  922. * @param int $start Pagination start
  923. * @param int $limit Pagination limit
  924. * @return array
  925. */
  926. public function &exportUserTopics_Allreadtime($start = 0, $limit = 0) {
  927. $query = "SELECT
  928. user_id AS user_id,
  929. topic_id AS topic_id,
  930. forum_id AS category_id,
  931. 0 AS message_id,
  932. mark_time AS time
  933. FROM #__topics_track";
  934. return $this->getExportData ( $query, $start, $limit );
  935. }
  936. /**
  937. * Count total number of category subscription columns to be exported
  938. */
  939. public function countUserTopics_Subscribed() {
  940. $query = "SELECT COUNT(*) FROM #__topics_watch";
  941. return $this->getCount ( $query );
  942. }
  943. /**
  944. * Export category subscriptions
  945. *
  946. * Returns list of items containing database fields
  947. * to #__kunena_user_topics.
  948. *
  949. * @param int $start Pagination start
  950. * @param int $limit Pagination limit
  951. * @return array
  952. */
  953. public function &exportUserTopics_Subscribed($start = 0, $limit = 0) {
  954. $query = "SELECT
  955. user_id AS user_id,
  956. topic_id AS topic_id,
  957. (notify_status+1) AS subscribed
  958. FROM #__topics_watch";
  959. return $this->getExportData ( $query, $start, $limit );
  960. }
  961. /**
  962. * Count total number of attachments to be exported
  963. */
  964. public function countAttachments() {
  965. $query = "SELECT COUNT(*) FROM #__attachments";
  966. return $this->getCount ( $query );
  967. }
  968. /**
  969. * Export attachments in messages
  970. *
  971. * Returns list of attachment objects containing database fields
  972. * to #__kunena_attachments.
  973. * NOTE: copies all files found in $row->copyfile (full path) to Kunena.
  974. *
  975. * @param int $start Pagination start
  976. * @param int $limit Pagination limit
  977. * @return array
  978. */
  979. public function &exportAttachments($start = 0, $limit = 0) {
  980. $query = "SELECT
  981. attach_id AS id,
  982. post_msg_id AS mesid,
  983. poster_id AS userid,
  984. NULL AS hash,
  985. filesize AS size,
  986. 'phpbb3' AS folder,
  987. IF(LENGTH(mimetype)>0,mimetype,extension) AS filetype,
  988. real_filename AS filename,
  989. physical_filename AS realfile
  990. FROM `#__attachments`
  991. ORDER BY attach_id";
  992. $result = $this->getExportData ( $query, $start, $limit, 'id' );
  993. foreach ( $result as &$row ) {
  994. $row->copypath = "{$this->basepath}/files/{$row->realfile}";
  995. $row->copypaththumb = "{$this->basepath}/files/thumb_{$row->realfile}";
  996. }
  997. return $result;
  998. }
  999. /**
  1000. * Count total number of avatar galleries to be exported
  1001. */
  1002. public function countAvatarGalleries() {
  1003. return count($this->getAvatarGalleries());
  1004. }
  1005. /**
  1006. * Export avatar galleries
  1007. *
  1008. * Returns list of folder=>fullpath to be copied, where fullpath points
  1009. * to the directory in the filesystem.
  1010. *
  1011. * @param int $start Pagination start
  1012. * @param int $limit Pagination limit
  1013. * @return array
  1014. */
  1015. public function &exportAvatarGalleries($start = 0, $limit = 0) {
  1016. $galleries = array_slice($this->getAvatarGalleries(), $start, $limit);
  1017. return $galleries;
  1018. }
  1019. /**
  1020. * Internal function to fetch all avatar galleries
  1021. *
  1022. * @return array (folder=>full path, ...)
  1023. */
  1024. protected function &getAvatarGalleries() {
  1025. $config = $this->getConfig();
  1026. static $galleries = false;
  1027. if ($galleries === false) {
  1028. $galleries = array();
  1029. if (isset($config['avatar_gallery_path'])) {
  1030. $path = "{$this->basepath}/{$config['avatar_gallery_path']->value}";
  1031. $folders = JFolder::folders($path);
  1032. foreach ($folders as $folder) {
  1033. $galleries[$folder] = "{$path}/{$folder}";
  1034. }
  1035. }
  1036. }
  1037. return $galleries;
  1038. }
  1039. /**
  1040. * Count global configurations to be exported
  1041. * @return 1
  1042. */
  1043. public function countConfig() {
  1044. return 1;
  1045. }
  1046. /**
  1047. * Export global configuration
  1048. *
  1049. * @param int $start Pagination start
  1050. * @param int $limit Pagination limit
  1051. * @return array (1=>(array(option=>value, ...)))
  1052. */
  1053. public function &exportConfig($start = 0, $limit = 0) {
  1054. $config = array ();
  1055. if ($start)
  1056. return $config;
  1057. $result = $this->getConfig();
  1058. // Time delta in seconds from UTC (=JFactory::getDate()->toUnix())
  1059. $config['timedelta'] = JFactory::getDate()->toUnix() - time();
  1060. $config ['id'] = 1; // $result['config_id']->value;
  1061. $config ['board_title'] = $result ['sitename']->value;
  1062. $config ['email'] = $result ['board_email']->value;
  1063. $config ['board_offline'] = $result ['board_disable']->value;
  1064. // $config['offline_message'] = null;
  1065. // $config['enablerss'] = null;
  1066. // $config['enablepdf'] = null;
  1067. $config ['threads_per_page'] = $result ['topics_per_page']->value;
  1068. $config ['messages_per_page'] = $result ['posts_per_page']->value;
  1069. // $config['messages_per_page_search'] = null;
  1070. // $config['showhistory'] = null;
  1071. // $config['historylimit'] = null;
  1072. // $config['shownew'] = null;
  1073. // $config['jmambot'] = null;
  1074. $config ['disemoticons'] = $result ['allow_smilies']->value ^ 1;
  1075. // $config['template'] = null;
  1076. // $config['showannouncement'] = null;
  1077. // $config['avataroncat'] = null;
  1078. // $config['catimagepath'] = null;
  1079. // $config['showchildcaticon'] = null;
  1080. // $config['annmodid'] = null;
  1081. // $config['rtewidth'] = null;
  1082. // $config['rteheight'] = null;
  1083. // $config['enableforumjump'] = null;
  1084. // $config['reportmsg'] = null;
  1085. // $config['username'] = null;
  1086. // $config['askemail'] = null;
  1087. // $config['showemail'] = null;
  1088. // $config['showuserstats'] = null;
  1089. // $config['showkarma'] = null;
  1090. // $config['useredit'] = null;
  1091. // $config['useredittime'] = null;
  1092. // $config['useredittimegrace'] = null;
  1093. // $config['editmarkup'] = null;
  1094. $config ['allowsubscriptions'] = $result ['allow_topic_notify']->value;
  1095. // $config['subscriptionschecked'] = null;
  1096. // $config['allowfavorites'] = null;
  1097. // $config['maxsubject'] = null;
  1098. $config ['maxsig'] = $result ['allow_sig']->value ? $result ['max_sig_chars']->value : 0;
  1099. // $config['regonly'] = null;
  1100. $config ['changename'] = $result ['allow_namechange']->value;
  1101. // $config['pubwrite'] = null;
  1102. $config ['floodprotection'] = $result ['flood_interval']->value;
  1103. // $config['mailmod'] = null;
  1104. // $config['mailadmin'] = null;
  1105. // $config['captcha'] = null;
  1106. // $config['mailfull'] = null;
  1107. $config ['allowavatar'] = $result ['allow_avatar_upload']->value || $result ['allow_avatar_local']->value;
  1108. $config ['allowavatarupload'] = $result ['allow_avatar_upload']->value;
  1109. $config ['allowavatargallery'] = $result ['allow_avatar_local']->value;
  1110. // $config['avatarquality'] = null;
  1111. $config ['avatarsize'] = ( int ) ($result ['avatar_filesize']->value / 1000);
  1112. // $config['allowimageupload'] = null;
  1113. // $config['allowimageregupload'] = null;
  1114. $config['imageheight'] = $result ['img_max_height']->value;
  1115. $config['imagewidth'] = $result ['img_max_width']->value;
  1116. // $config['imagesize'] = null;
  1117. // $config['allowfileupload'] = null;
  1118. // $config['allowfileregupload'] = null;
  1119. // $config['filetypes'] = null;
  1120. $config ['filesize'] = ( int ) ($result ['max_filesize']->value / 1000);
  1121. // $config['showranking'] = null;
  1122. // $config['rankimages'] = null;
  1123. // $config['avatar_src'] = null;
  1124. // $config['pm_component'] = null;
  1125. // $config['discussbot'] = null;
  1126. // $config['userlist_rows'] = null;
  1127. // $config['userlist_online'] = null;
  1128. // $config['userlist_avatar'] = null;
  1129. // $config['userlist_name'] = null;
  1130. // $config['userlist_username'] = null;
  1131. // $config['userlist_posts'] = null;
  1132. // $config['userlist_karma'] = null;
  1133. // $config['userlist_email'] = null;
  1134. // $config['userlist_usertype'] = null;
  1135. // $config['userlist_joindate'] = null;
  1136. // $config['userlist_lastvisitdate'] = null;
  1137. // $config['userlist_userhits'] = null;
  1138. // $config['latestcategory'] = null;
  1139. // $config['showstats'] = null;
  1140. // $config['showwhoisonline'] = null;
  1141. // $config['showgenstats'] = null;
  1142. // $config['showpopuserstats'] = null;
  1143. // $config['popusercount'] = null;
  1144. // $config['showpopsubjectstats'] = null;
  1145. // $config['popsubjectcount'] = null;
  1146. // $config['usernamechange'] = null;
  1147. // $config['rules_infb'] = null;
  1148. // $config['rules_cid'] = null;
  1149. // $config['help_infb'] = null;
  1150. // $config['help_cid'] = null;
  1151. // $config['showspoilertag'] = null;
  1152. // $config['showvideotag'] = null;
  1153. // $config['showebaytag'] = null;
  1154. // $config['trimlongurls'] = null;
  1155. // $config['trimlongurlsfront'] = null;
  1156. // $config['trimlongurlsback'] = null;
  1157. // $config['autoembedyoutube'] = null;
  1158. // $config['autoembedebay'] = null;
  1159. // $config['ebaylanguagecode'] = null;
  1160. $config ['fbsessiontimeout'] = $result ['session_length']->value;
  1161. // $config['highlightcode'] = null;
  1162. // $config['rss_type'] = null;
  1163. // $config['rss_timelimit'] = null;
  1164. // $config['rss_limit'] = null;
  1165. // $config['rss_included_categories'] = null;
  1166. // $config['rss_excluded_categories'] = null;
  1167. // $config['rss_specification'] = null;
  1168. // $config['rss_allow_html'] = null;
  1169. // $config['rss_author_format'] = null;
  1170. // $config['rss_author_in_title'] = null;
  1171. // $config['rss_word_count'] = null;
  1172. // $config['rss_old_titles'] = null;
  1173. // $config['rss_cache'] = null;
  1174. $config['fbdefaultpage'] = 'categories';
  1175. // $config['default_sort'] = null;
  1176. // $config['alphauserpointsnumchars'] = null;
  1177. // $config['sef'] = null;
  1178. // $config['sefcats'] = null;
  1179. // $config['sefutf8'] = null;
  1180. // $config['showimgforguest'] = null;
  1181. // $config['showfileforguest'] = null;
  1182. // $config['pollnboptions'] = null;
  1183. // $config['pollallowvoteone'] = null;
  1184. // $config['pollenabled'] = null;
  1185. // $config['poppollscount'] = null;
  1186. // $config['showpoppollstats'] = null;
  1187. // $config['polltimebtvotes'] = null;
  1188. // $config['pollnbvotesbyuser'] = null;
  1189. // $config['pollresultsuserslist'] = null;
  1190. // $config['maxpersotext'] = null;
  1191. // $config['ordering_system'] = null;
  1192. // $config['post_dateformat'] = null;
  1193. // $config['post_dateformat_hover'] = null;
  1194. // $config['hide_ip'] = null;
  1195. // $config['js_actstr_integration'] = null;
  1196. // $config['imagetypes'] = null;
  1197. // $config['checkmimetypes'] = null;
  1198. // $config['imagemimetypes'] = null;
  1199. // $config['imagequality'] = null;
  1200. $config['thumbwidth'] = isset($result ['img_max_thumb_width']->value) ? $result ['img_max_thumb_width']->value : 32;
  1201. $config['thumbheight'] = isset($result ['img_max_thumb_height']->value) ? $result ['img_max_thumb_height']->value : $config['thumbwidth'];
  1202. // $config['hideuserprofileinfo'] = null;
  1203. // $config['integration_access'] = null;
  1204. // $config['integration_login'] = null;
  1205. // $config['integration_avatar'] = null;
  1206. // $config['integration_profile'] = null;
  1207. // $config['integration_private'] = null;
  1208. // $config['integration_activity'] = null;
  1209. // $config['boxghostmessage'] = null;
  1210. // $config['userdeletetmessage'] = null;
  1211. // $config['latestcategory_in'] = null;
  1212. // $config['topicicons'] = null;
  1213. // $config['onlineusers'] = null;
  1214. // $config['debug'] = null;
  1215. // $config['catsautosubscribed'] = null;
  1216. // $config['showbannedreason'] = null;
  1217. // $config['version_check'] = null;
  1218. // $config['showthankyou'] = null;
  1219. // $config['showpopthankyoustats'] = null;
  1220. // $config['popthankscount'] = null;
  1221. // $config['mod_see_deleted'] = null;
  1222. // $config['bbcode_img_secure'] = null;
  1223. // $config['listcat_show_moderators'] = null;
  1224. // $config['lightbox'] = null;
  1225. // $config['activity_limit'] = null;
  1226. // $config['show_list_time'] = null;
  1227. // $config['show_session_type'] = null;
  1228. // $config['show_session_starttime'] = null;
  1229. // $config['userlist_allowed'] = null;
  1230. // $config['userlist_count_users'] = null;
  1231. // $config['enable_threaded_layouts'] = null;
  1232. // $config['category_subscriptions'] = null;
  1233. // $config['topic_subscriptions'] = null;
  1234. // $config['pubprofile'] = null;
  1235. // $config['thankyou_max'] = null;
  1236. $result = array ('1' => $config );
  1237. return $result;
  1238. }
  1239. }
  1240. if (!function_exists('utf8_clean_string')) {
  1241. /**
  1242. * This function is used to generate a "clean" version of a string.
  1243. * Clean means that it is a case insensitive form (case folding) and that it is normalized (NFC).
  1244. * Additionally a homographs of one character are transformed into one specific character (preferably ASCII
  1245. * if it is an ASCII character).
  1246. *
  1247. * Please be aware that if you change something within this function or within
  1248. * functions used here you need to rebuild/update the username_clean column in the users table. And all other
  1249. * columns that store a clean string otherwise you will break this functionality.
  1250. *
  1251. * @param string $text An unclean string, mabye user input (has to be valid UTF-8!)
  1252. * @return string Cleaned up version of the input string
  1253. */
  1254. function utf8_clean_string($text)
  1255. {
  1256. global $phpbb_root_path, $phpEx;
  1257. static $homographs = array();
  1258. if (empty($homographs)) {
  1259. $homographs = include($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx);
  1260. }
  1261. $text = utf8_case_fold_nfkc($text);
  1262. $text = strtr($text, $homographs);
  1263. // Other control characters
  1264. $text = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $text);
  1265. // we can use trim here as all the other space characters should have been turned
  1266. // into normal ASCII spaces by now
  1267. return trim($text);
  1268. }
  1269. }
  1270. if (!function_exists('utf8_case_fold_nfkc')) {
  1271. /**
  1272. * Takes the input and does a "special" case fold. It does minor normalization
  1273. * and returns NFKC compatable text
  1274. *
  1275. * @param string $text text to be case folded
  1276. * @param string $option determines how we will fold the cases
  1277. * @return string case folded text
  1278. */
  1279. function utf8_case_fold_nfkc($text, $option = 'full')
  1280. {
  1281. static $fc_nfkc_closure = array(
  1282. "\xCD\xBA" => "\x20\xCE\xB9",
  1283. "\xCF\x92" => "\xCF\x85",
  1284. "\xCF\x93" => "\xCF\x8D",
  1285. "\xCF\x94" => "\xCF\x8B",
  1286. "\xCF\xB2" => "\xCF\x83",
  1287. "\xCF\xB9" => "\xCF\x83",
  1288. "\xE1\xB4\xAC" => "\x61",
  1289. "\xE1\xB4\xAD" => "\xC3\xA6",
  1290. "\xE1\xB4\xAE" => "\x62",
  1291. "\xE1\xB4\xB0" => "\x64",
  1292. "\xE1\xB4\xB1" => "\x65",
  1293. "\xE1\xB4\xB2" => "\xC7\x9D",
  1294. "\xE1\xB4\xB3" => "\x67",
  1295. "\xE1\xB4\xB4" => "\x68",
  1296. "\xE1\xB4\xB5" => "\x69",
  1297. "\xE1\xB4\xB6" => "\x6A",
  1298. "\xE1\xB4\xB7" => "\x6B",
  1299. "\xE1\xB4\xB8" => "\x6C",
  1300. "\xE1\xB4\xB9" => "\x6D",
  1301. "\xE1\xB4\xBA" => "\x6E",
  1302. "\xE1\xB4\xBC" => "\x6F",
  1303. "\xE1\xB4\xBD" => "\xC8\xA3",
  1304. "\xE1\xB4\xBE" => "\x70",
  1305. "\xE1\xB4\xBF" => "\x72",
  1306. "\xE1\xB5\x80" => "\x74",
  1307. "\xE1\xB5\x81" => "\x75",
  1308. "\xE1\xB5\x82" => "\x77",
  1309. "\xE2\x82\xA8" => "\x72\x73",
  1310. "\xE2\x84\x82" => "\x63",
  1311. "\xE2\x84\x83" => "\xC2\xB0\x63",
  1312. "\xE2\x84\x87" => "\xC9\x9B",
  1313. "\xE2\x84\x89" => "\xC2\xB0\x66",
  1314. "\xE2\x84\x8B" => "\x68",
  1315. "\xE2\x84\x8C" => "\x68",
  1316. "\xE2\x84\x8D" => "\x68",
  1317. "\xE2\x84\x90" => "\x69",
  1318. "\xE2\x84\x91" => "\x69",
  1319. "\xE2\x84\x92" => "\x6C",
  1320. "\xE2\x84\x95" => "\x6E",
  1321. "\xE2\x84\x96" => "\x6E\x6F",
  1322. "\xE2\x84\x99" => "\x70",
  1323. "\xE2\x84\x9A" => "\x71",
  1324. "\xE2\x84\x9B" => "\x72",
  1325. "\xE2\x84\x9C" => "\x72",
  1326. "\xE2\x84\x9D" => "\x72",
  1327. "\xE2\x84\xA0" => "\x73\x6D",
  1328. "\xE2\x84\xA1" => "\x74\x65\x6C",
  1329. "\xE2\x84\xA2" => "\x74\x6D",
  1330. "\xE2\x84\xA4" => "\x7A",
  1331. "\xE2\x84\xA8" => "\x7A",
  1332. "\xE2\x84\xAC" => "\x62",
  1333. "\xE2\x84\xAD" => "\x63",
  1334. "\xE2\x84\xB0" => "\x65",
  1335. "\xE2\x84\xB1" => "\x66",
  1336. "\xE2\x84\xB3" => "\x6D",
  1337. "\xE2\x84\xBB" => "\x66\x61\x78",
  1338. "\xE2\x84\xBE" => "\xCE\xB3",
  1339. "\xE2\x84\xBF" => "\xCF\x80",
  1340. "\xE2\x85\x85" => "\x64",
  1341. "\xE3\x89\x90" => "\x70\x74\x65",
  1342. "\xE3\x8B\x8C" => "\x68\x67",
  1343. "\xE3\x8B\x8E" => "\x65\x76",
  1344. "\xE3\x8B\x8F" => "\x6C\x74\x64",
  1345. "\xE3\x8D\xB1" => "\x68\x70\x61",
  1346. "\xE3\x8D\xB3" => "\x61\x75",
  1347. "\xE3\x8D\xB5" => "\x6F\x76",
  1348. "\xE3\x8D\xBA" => "\x69\x75",
  1349. "\xE3\x8E\x80" => "\x70\x61",
  1350. "\xE3\x8E\x81" => "\x6E\x61",
  1351. "\xE3\x8E\x82" => "\xCE\xBC\x61",
  1352. "\xE3\x8E\x83" => "\x6D\x61",
  1353. "\xE3\x8E\x84" => "\x6B\x61",
  1354. "\xE3\x8E\x85" => "\x6B\x62",
  1355. "\xE3\x8E\x86" => "\x6D\x62",
  1356. "\xE3\x8E\x87" => "\x67\x62",
  1357. "\xE3\x8E\x8A" => "\x70\x66",
  1358. "\xE3\x8E\x8B" => "\x6E\x66",
  1359. "\xE3\x8E\x8C" => "\xCE\xBC\x66",
  1360. "\xE3\x8E\x90" => "\x68\x7A",
  1361. "\xE3\x8E\x91" => "\x6B\x68\x7A",
  1362. "\xE3\x8E\x92" => "\x6D\x68\x7A",
  1363. "\xE3\x8E\x93" => "\x67\x68\x7A",
  1364. "\xE3\x8E\x94" => "\x74\x68\x7A",
  1365. "\xE3\x8E\xA9" => "\x70\x61",
  1366. "\xE3\x8E\xAA" => "\x6B\x70\x61",
  1367. "\xE3\x8E\xAB" => "\x6D\x70\x61",
  1368. "\xE3\x8E\xAC" => "\x67\x70\x61",
  1369. "\xE3\x8E\xB4" => "\x70\x76",
  1370. "\xE3\x8E\xB5" => "\x6E\x76",
  1371. "\xE3\x8E\xB6" => "\xCE\xBC\x76",
  1372. "\xE3\x8E\xB7" => "\x6D\x76",
  1373. "\xE3\x8E\xB8" => "\x6B\x76",
  1374. "\xE3\x8E\xB9" => "\x6D\x76",
  1375. "\xE3\x8E\xBA" => "\x70\x77",
  1376. "\xE3\x8E\xBB" => "\x6E\x77",
  1377. "\xE3\x8E\xBC" => "\xCE\xBC\x77",
  1378. "\xE3\x8E\xBD" => "\x6D\x77",
  1379. "\xE3\x8E\xBE" => "\x6B\x77",
  1380. "\xE3\x8E\xBF" => "\x6D\x77",
  1381. "\xE3\x8F\x80" => "\x6B\xCF\x89",
  1382. "\xE3\x8F\x81" => "\x6D\xCF\x89",
  1383. "\xE3\x8F\x83" => "\x62\x71",
  1384. "\xE3\x8F\x86" => "\x63\xE2\x88\x95\x6B\x67",
  1385. "\xE3\x8F\x87" => "\x63\x6F\x2E",
  1386. "\xE3\x8F\x88" => "\x64\x62",
  1387. "\xE3\x8F\x89" => "\x67\x79",
  1388. "\xE3\x8F\x8B" => "\x68\x70",
  1389. "\xE3\x8F\x8D" => "\x6B\x6B",
  1390. "\xE3\x8F\x8E" => "\x6B\x6D",
  1391. "\xE3\x8F\x97" => "\x70\x68",
  1392. "\xE3\x8F\x99" => "\x70\x70\x6D",
  1393. "\xE3\x8F\x9A" => "\x70\x72",
  1394. "\xE3\x8F\x9C" => "\x73\x76",
  1395. "\xE3\x8F\x9D" => "\x77\x62",
  1396. "\xE3\x8F\x9E" => "\x76\xE2\x88\x95\x6D",
  1397. "\xE3\x8F\x9F" => "\x61\xE2\x88\x95\x6D",
  1398. "\xF0\x9D\x90\x80" => "\x61",
  1399. "\xF0\x9D\x90\x81" => "\x62",
  1400. "\xF0\x9D\x90\x82" => "\x63",
  1401. "\xF0\x9D\x90\x83" => "\x64",
  1402. "\xF0\x9D\x90\x84" => "\x65",
  1403. "\xF0\x9D\x90\x85" => "\x66",
  1404. "\xF0\x9D\x90\x86" => "\x67",
  1405. "\xF0\x9D\x90\x87" => "\x68",
  1406. "\xF0\x9D\x90\x88" => "\x69",
  1407. "\xF0\x9D\x90\x89" => "\x6A",
  1408. "\xF0\x9D\x90\x8A" => "\x6B",
  1409. "\xF0\x9D\x90\x8B" => "\x6C",
  1410. "\xF0\x9D\x90\x8C" => "\x6D",
  1411. "\xF0\x9D\x90\x8D" => "\x6E",
  1412. "\xF0\x9D\x90\x8E" => "\x6F",
  1413. "\xF0\x9D\x90\x8F" => "\x70",
  1414. "\xF0\x9D\x90\x90" => "\x71",
  1415. "\xF0\x9D\x90\x91" => "\x72",
  1416. "\xF0\x9D\x90\x92" => "\x73",
  1417. "\xF0\x9D\x90\x93" => "\x74",
  1418. "\xF0\x9D\x90\x94" => "\x75",
  1419. "\xF0\x9D\x90\x95" => "\x76",
  1420. "\xF0\x9D\x90\x96" => "\x77",
  1421. "\xF0\x9D\x90\x97" => "\x78",
  1422. "\xF0\x9D\x90\x98" => "\x79",
  1423. "\xF0\x9D\x90\x99" => "\x7A",
  1424. "\xF0\x9D\x90\xB4" => "\x61",
  1425. "\xF0\x9D\x90\xB5" => "\x62",
  1426. "\xF0\x9D\x90\xB6" => "\x63",
  1427. "\xF0\x9D\x90\xB7" => "\x64",
  1428. "\xF0\x9D\x90\xB8" => "\x65",
  1429. "\xF0\x9D\x90\xB9" => "\x66",
  1430. "\xF0\x9D\x90\xBA" => "\x67",
  1431. "\xF0\x9D\x90\xBB" => "\x68",
  1432. "\xF0\x9D\x90\xBC" => "\x69",
  1433. "\xF0\x9D\x90\xBD" => "\x6A",
  1434. "\xF0\x9D\x90\xBE" => "\x6B",
  1435. "\xF0\x9D\x90\xBF" => "\x6C",
  1436. "\xF0\x9D\x91\x80" => "\x6D",
  1437. "\xF0\x9D\x91\x81" => "\x6E",
  1438. "\xF0\x9D\x91\x82" => "\x6F",
  1439. "\xF0\x9D\x91\x83" => "\x70",
  1440. "\xF0\x9D\x91\x84" => "\x71",
  1441. "\xF0\x9D\x91\x85" => "\x72",
  1442. "\xF0\x9D\x91\x86" => "\x73",
  1443. "\xF0\x9D\x91\x87" => "\x74",
  1444. "\xF0\x9D\x91\x88" => "\x75",
  1445. "\xF0\x9D\x91\x89" => "\x76",
  1446. "\xF0\x9D\x91\x8A" => "\x77",
  1447. "\xF0\x9D\x91\x8B" => "\x78",
  1448. "\xF0\x9D\x91\x8C" => "\x79",
  1449. "\xF0\x9D\x91\x8D" => "\x7A",
  1450. "\xF0\x9D\x91\xA8" => "\x61",
  1451. "\xF0\x9D\x91\xA9" => "\x62",
  1452. "\xF0\x9D\x91\xAA" => "\x63",
  1453. "\xF0\x9D\x91\xAB" => "\x64",
  1454. "\xF0\x9D\x91\xAC" => "\x65",
  1455. "\xF0\x9D\x91\xAD" => "\x66",
  1456. "\xF0\x9D\x91\xAE" => "\x67",
  1457. "\xF0\x9D\x91\xAF" => "\x68",
  1458. "\xF0\x9D\x91\xB0" => "\x69",
  1459. "\xF0\x9D\x91\xB1" => "\x6A",
  1460. "\xF0\x9D\x91\xB2" => "\x6B",
  1461. "\xF0\x9D\x91\xB3" => "\x6C",
  1462. "\xF0\x9D\x91\xB4" => "\x6D",
  1463. "\xF0\x9D\x91\xB5" => "\x6E",
  1464. "\xF0\x9D\x91\xB6" => "\x6F",
  1465. "\xF0\x9D\x91\xB7" => "\x70",
  1466. "\xF0\x9D\x91\xB8" => "\x71",
  1467. "\xF0\x9D\x91\xB9" => "\x72",
  1468. "\xF0\x9D\x91\xBA" => "\x73",
  1469. "\xF0\x9D\x91\xBB" => "\x74",
  1470. "\xF0\x9D\x91\xBC" => "\x75",
  1471. "\xF0\x9D\x91\xBD" => "\x76",
  1472. "\xF0\x9D\x91\xBE" => "\x77",
  1473. "\xF0\x9D\x91\xBF" => "\x78",
  1474. "\xF0\x9D\x92\x80" => "\x79",
  1475. "\xF0\x9D\x92\x81" => "\x7A",
  1476. "\xF0\x9D\x92\x9C" => "\x61",
  1477. "\xF0\x9D\x92\x9E" => "\x63",
  1478. "\xF0\x9D\x92\x9F" => "\x64",
  1479. "\xF0\x9D\x92\xA2" => "\x67",
  1480. "\xF0\x9D\x92\xA5" => "\x6A",
  1481. "\xF0\x9D\x92\xA6" => "\x6B",
  1482. "\xF0\x9D\x92\xA9" => "\x6E",
  1483. "\xF0\x9D\x92\xAA" => "\x6F",
  1484. "\xF0\x9D\x92\xAB" => "\x70",
  1485. "\xF0\x9D\x92\xAC" => "\x71",
  1486. "\xF0\x9D\x92\xAE" => "\x73",
  1487. "\xF0\x9D\x92\xAF" => "\x74",
  1488. "\xF0\x9D\x92\xB0" => "\x75",
  1489. "\xF0\x9D\x92\xB1" => "\x76",
  1490. "\xF0\x9D\x92\xB2" => "\x77",
  1491. "\xF0\x9D\x92\xB3" => "\x78",
  1492. "\xF0\x9D\x92\xB4" => "\x79",
  1493. "\xF0\x9D\x92\xB5" => "\x7A",
  1494. "\xF0\x9D\x93\x90" => "\x61",
  1495. "\xF0\x9D\x93\x91" => "\x62",
  1496. "\xF0\x9D\x93\x92" => "\x63",
  1497. "\xF0\x9D\x93\x93" => "\x64",
  1498. "\xF0\x9D\x93\x94" => "\x65",
  1499. "\xF0\x9D\x93\x95" => "\x66",
  1500. "\xF0\x9D\x93\x96" => "\x67",
  1501. "\xF0\x9D\x93\x97" => "\x68",
  1502. "\xF0\x9D\x93\x98" => "\x69",
  1503. "\xF0\x9D\x93\x99" => "\x6A",
  1504. "\xF0\x9D\x93\x9A" => "\x6B",
  1505. "\xF0\x9D\x93\x9B" => "\x6C",
  1506. "\xF0\x9D\x93\x9C" => "\x6D",
  1507. "\xF0\x9D\x93\x9D" => "\x6E",
  1508. "\xF0\x9D\x93\x9E" => "\x6F",
  1509. "\xF0\x9D\x93\x9F" => "\x70",
  1510. "\xF0\x9D\x93\xA0" => "\x71",
  1511. "\xF0\x9D\x93\xA1" => "\x72",
  1512. "\xF0\x9D\x93\xA2" => "\x73",
  1513. "\xF0\x9D\x93\xA3" => "\x74",
  1514. "\xF0\x9D\x93\xA4" => "\x75",
  1515. "\xF0\x9D\x93\xA5" => "\x76",
  1516. "\xF0\x9D\x93\xA6" => "\x77",
  1517. "\xF0\x9D\x93\xA7" => "\x78",
  1518. "\xF0\x9D\x93\xA8" => "\x79",
  1519. "\xF0\x9D\x93\xA9" => "\x7A",
  1520. "\xF0\x9D\x94\x84" => "\x61",
  1521. "\xF0\x9D\x94\x85" => "\x62",
  1522. "\xF0\x9D\x94\x87" => "\x64",
  1523. "\xF0\x9D\x94\x88" => "\x65",
  1524. "\xF0\x9D\x94\x89" => "\x66",
  1525. "\xF0\x9D\x94\x8A" => "\x67",
  1526. "\xF0\x9D\x94\x8D" => "\x6A",
  1527. "\xF0\x9D\x94\x8E" => "\x6B",
  1528. "\xF0\x9D\x94\x8F" => "\x6C",
  1529. "\xF0\x9D\x94\x90" => "\x6D",
  1530. "\xF0\x9D\x94\x91" => "\x6E",
  1531. "\xF0\x9D\x94\x92" => "\x6F",
  1532. "\xF0\x9D\x94\x93" => "\x70",
  1533. "\xF0\x9D\x94\x94" => "\x71",
  1534. "\xF0\x9D\x94\x96" => "\x73",
  1535. "\xF0\x9D\x94\x97" => "\x74",
  1536. "\xF0\x9D\x94\x98" => "\x75",
  1537. "\xF0\x9D\x94\x99" => "\x76",
  1538. "\xF0\x9D\x94\x9A" => "\x77",
  1539. "\xF0\x9D\x94\x9B" => "\x78",
  1540. "\xF0\x9D\x94\x9C" => "\x79",
  1541. "\xF0\x9D\x94\xB8" => "\x61",
  1542. "\xF0\x9D\x94\xB9" => "\x62",
  1543. "\xF0\x9D\x94\xBB" => "\x64",
  1544. "\xF0\x9D\x94\xBC" => "\x65",
  1545. "\xF0\x9D\x94\xBD" => "\x66",
  1546. "\xF0\x9D\x94\xBE" => "\x67",
  1547. "\xF0\x9D\x95\x80" => "\x69",
  1548. "\xF0\x9D\x95\x81" => "\x6A",
  1549. "\xF0\x9D\x95\x82" => "\x6B",
  1550. "\xF0\x9D\x95\x83" => "\x6C",
  1551. "\xF0\x9D\x95\x84" => "\x6D",
  1552. "\xF0\x9D\x95\x86" => "\x6F",
  1553. "\xF0\x9D\x95\x8A" => "\x73",
  1554. "\xF0\x9D\x95\x8B" => "\x74",
  1555. "\xF0\x9D\x95\x8C" => "\x75",
  1556. "\xF0\x9D\x95\x8D" => "\x76",
  1557. "\xF0\x9D\x95\x8E" => "\x77",
  1558. "\xF0\x9D\x95\x8F" => "\x78",
  1559. "\xF0\x9D\x95\x90" => "\x79",
  1560. "\xF0\x9D\x95\xAC" => "\x61",
  1561. "\xF0\x9D\x95\xAD" => "\x62",
  1562. "\xF0\x9D\x95\xAE" => "\x63",
  1563. "\xF0\x9D\x95\xAF" => "\x64",
  1564. "\xF0\x9D\x95\xB0" => "\x65",
  1565. "\xF0\x9D\x95\xB1" => "\x66",
  1566. "\xF0\x9D\x95\xB2" => "\x67",
  1567. "\xF0\x9D\x95\xB3" => "\x68",
  1568. "\xF0\x9D\x95\xB4" => "\x69",
  1569. "\xF0\x9D\x95\xB5" => "\x6A",
  1570. "\xF0\x9D\x95\xB6" => "\x6B",
  1571. "\xF0\x9D\x95\xB7" => "\x6C",
  1572. "\xF0\x9D\x95\xB8" => "\x6D",
  1573. "\xF0\x9D\x95\xB9" => "\x6E",
  1574. "\xF0\x9D\x95\xBA" => "\x6F",
  1575. "\xF0\x9D\x95\xBB" => "\x70",
  1576. "\xF0\x9D\x95\xBC" => "\x71",
  1577. "\xF0\x9D\x95\xBD" => "\x72",
  1578. "\xF0\x9D\x95\xBE" => "\x73",
  1579. "\xF0\x9D\x95\xBF" => "\x74",
  1580. "\xF0\x9D\x96\x80" => "\x75",
  1581. "\xF0\x9D\x96\x81" => "\x76",
  1582. "\xF0\x9D\x96\x82" => "\x77",
  1583. "\xF0\x9D\x96\x83" => "\x78",
  1584. "\xF0\x9D\x96\x84" => "\x79",
  1585. "\xF0\x9D\x96\x85" => "\x7A",
  1586. "\xF0\x9D\x96\xA0" => "\x61",
  1587. "\xF0\x9D\x96\xA1" => "\x62",
  1588. "\xF0\x9D\x96\xA2" => "\x63",
  1589. "\xF0\x9D\x96\xA3" => "\x64",
  1590. "\xF0\x9D\x96\xA4" => "\x65",
  1591. "\xF0\x9D\x96\xA5" => "\x66",
  1592. "\xF0\x9D\x96\xA6" => "\x67",
  1593. "\xF0\x9D\x96\xA7" => "\x68",
  1594. "\xF0\x9D\x96\xA8" => "\x69",
  1595. "\xF0\x9D\x96\xA9" => "\x6A",
  1596. "\xF0\x9D\x96\xAA" => "\x6B",
  1597. "\xF0\x9D\x96\xAB" => "\x6C",
  1598. "\xF0\x9D\x96\xAC" => "\x6D",
  1599. "\xF0\x9D\x96\xAD" => "\x6E",
  1600. "\xF0\x9D\x96\xAE" => "\x6F",
  1601. "\xF0\x9D\x96\xAF" => "\x70",
  1602. "\xF0\x9D\x96\xB0" => "\x71",
  1603. "\xF0\x9D\x96\xB1" => "\x72",
  1604. "\xF0\x9D\x96\xB2" => "\x73",
  1605. "\xF0\x9D\x96\xB3" => "\x74",
  1606. "\xF0\x9D\x96\xB4" => "\x75",
  1607. "\xF0\x9D\x96\xB5" => "\x76",
  1608. "\xF0\x9D\x96\xB6" => "\x77",
  1609. "\xF0\x9D\x96\xB7" => "\x78",
  1610. "\xF0\x9D\x96\xB8" => "\x79",
  1611. "\xF0\x9D\x96\xB9" => "\x7A",
  1612. "\xF0\x9D\x97\x94" => "\x61",
  1613. "\xF0\x9D\x97\x95" => "\x62",
  1614. "\xF0\x9D\x97\x96" => "\x63",
  1615. "\xF0\x9D\x97\x97" => "\x64",
  1616. "\xF0\x9D\x97\x98" => "\x65",
  1617. "\xF0\x9D\x97\x99" => "\x66",
  1618. "\xF0\x9D\x97\x9A" => "\x67",
  1619. "\xF0\x9D\x97\x9B" => "\x68",
  1620. "\xF0\x9D\x97\x9C" => "\x69",
  1621. "\xF0\x9D\x97\x9D" => "\x6A",
  1622. "\xF0\x9D\x97\x9E" => "\x6B",
  1623. "\xF0\x9D\x97\x9F" => "\x6C",
  1624. "\xF0\x9D\x97\xA0" => "\x6D",
  1625. "\xF0\x9D\x97\xA1" => "\x6E",
  1626. "\xF0\x9D\x97\xA2" => "\x6F",
  1627. "\xF0\x9D\x97\xA3" => "\x70",
  1628. "\xF0\x9D\x97\xA4" => "\x71",
  1629. "\xF0\x9D\x97\xA5" => "\x72",
  1630. "\xF0\x9D\x97\xA6" => "\x73",
  1631. "\xF0\x9D\x97\xA7" => "\x74",
  1632. "\xF0\x9D\x97\xA8" => "\x75",
  1633. "\xF0\x9D\x97\xA9" => "\x76",
  1634. "\xF0\x9D\x97\xAA" => "\x77",
  1635. "\xF0\x9D\x97\xAB" => "\x78",
  1636. "\xF0\x9D\x97\xAC" => "\x79",
  1637. "\xF0\x9D\x97\xAD" => "\x7A",
  1638. "\xF0\x9D\x98\x88" => "\x61",
  1639. "\xF0\x9D\x98\x89" => "\x62",
  1640. "\xF0\x9D\x98\x8A" => "\x63",
  1641. "\xF0\x9D\x98\x8B" => "\x64",
  1642. "\xF0\x9D\x98\x8C" => "\x65",
  1643. "\xF0\x9D\x98\x8D" => "\x66",
  1644. "\xF0\x9D\x98\x8E" => "\x67",
  1645. "\xF0\x9D\x98\x8F" => "\x68",
  1646. "\xF0\x9D\x98\x90" => "\x69",
  1647. "\xF0\x9D\x98\x91" => "\x6A",
  1648. "\xF0\x9D\x98\x92" => "\x6B",
  1649. "\xF0\x9D\x98\x93" => "\x6C",
  1650. "\xF0\x9D\x98\x94" => "\x6D",
  1651. "\xF0\x9D\x98\x95" => "\x6E",
  1652. "\xF0\x9D\x98\x96" => "\x6F",
  1653. "\xF0\x9D\x98\x97" => "\x70",
  1654. "\xF0\x9D\x98\x98" => "\x71",
  1655. "\xF0\x9D\x98\x99" => "\x72",
  1656. "\xF0\x9D\x98\x9A" => "\x73",
  1657. "\xF0\x9D\x98\x9B" => "\x74",
  1658. "\xF0\x9D\x98\x9C" => "\x75",
  1659. "\xF0\x9D\x98\x9D" => "\x76",
  1660. "\xF0\x9D\x98\x9E" => "\x77",
  1661. "\xF0\x9D\x98\x9F" => "\x78",
  1662. "\xF0\x9D\x98\xA0" => "\x79",
  1663. "\xF0\x9D\x98\xA1" => "\x7A",
  1664. "\xF0\x9D\x98\xBC" => "\x61",
  1665. "\xF0\x9D\x98\xBD" => "\x62",
  1666. "\xF0\x9D\x98\xBE" => "\x63",
  1667. "\xF0\x9D\x98\xBF" => "\x64",
  1668. "\xF0\x9D\x99\x80" => "\x65",
  1669. "\xF0\x9D\x99\x81" => "\x66",
  1670. "\xF0\x9D\x99\x82" => "\x67",
  1671. "\xF0\x9D\x99\x83" => "\x68",
  1672. "\xF0\x9D\x99\x84" => "\x69",
  1673. "\xF0\x9D\x99\x85" => "\x6A",
  1674. "\xF0\x9D\x99\x86" => "\x6B",
  1675. "\xF0\x9D\x99\x87" => "\x6C",
  1676. "\xF0\x9D\x99\x88" => "\x6D",
  1677. "\xF0\x9D\x99\x89" => "\x6E",
  1678. "\xF0\x9D\x99\x8A" => "\x6F",
  1679. "\xF0\x9D\x99\x8B" => "\x70",
  1680. "\xF0\x9D\x99\x8C" => "\x71",
  1681. "\xF0\x9D\x99\x8D" => "\x72",
  1682. "\xF0\x9D\x99\x8E" => "\x73",
  1683. "\xF0\x9D\x99\x8F" => "\x74",
  1684. "\xF0\x9D\x99\x90" => "\x75",
  1685. "\xF0\x9D\x99\x91" => "\x76",
  1686. "\xF0\x9D\x99\x92" => "\x77",
  1687. "\xF0\x9D\x99\x93" => "\x78",
  1688. "\xF0\x9D\x99\x94" => "\x79",
  1689. "\xF0\x9D\x99\x95" => "\x7A",
  1690. "\xF0\x9D\x99\xB0" => "\x61",
  1691. "\xF0\x9D\x99\xB1" => "\x62",
  1692. "\xF0\x9D\x99\xB2" => "\x63",
  1693. "\xF0\x9D\x99\xB3" => "\x64",
  1694. "\xF0\x9D\x99\xB4" => "\x65",
  1695. "\xF0\x9D\x99\xB5" => "\x66",
  1696. "\xF0\x9D\x99\xB6" => "\x67",
  1697. "\xF0\x9D\x99\xB7" => "\x68",
  1698. "\xF0\x9D\x99\xB8" => "\x69",
  1699. "\xF0\x9D\x99\xB9" => "\x6A",
  1700. "\xF0\x9D\x99\xBA" => "\x6B",
  1701. "\xF0\x9D\x99\xBB" => "\x6C",
  1702. "\xF0\x9D\x99\xBC" => "\x6D",
  1703. "\xF0\x9D\x99\xBD" => "\x6E",
  1704. "\xF0\x9D\x99\xBE" => "\x6F",
  1705. "\xF0\x9D\x99\xBF" => "\x70",
  1706. "\xF0\x9D\x9A\x80" => "\x71",
  1707. "\xF0\x9D\x9A\x81" => "\x72",
  1708. "\xF0\x9D\x9A\x82" => "\x73",
  1709. "\xF0\x9D\x9A\x83" => "\x74",
  1710. "\xF0\x9D\x9A\x84" => "\x75",
  1711. "\xF0\x9D\x9A\x85" => "\x76",
  1712. "\xF0\x9D\x9A\x86" => "\x77",
  1713. "\xF0\x9D\x9A\x87" => "\x78",
  1714. "\xF0\x9D\x9A\x88" => "\x79",
  1715. "\xF0\x9D\x9A\x89" => "\x7A",
  1716. "\xF0\x9D\x9A\xA8" => "\xCE\xB1",
  1717. "\xF0\x9D\x9A\xA9" => "\xCE\xB2",
  1718. "\xF0\x9D\x9A\xAA" => "\xCE\xB3",
  1719. "\xF0\x9D\x9A\xAB" => "\xCE\xB4",
  1720. "\xF0\x9D\x9A\xAC" => "\xCE\xB5",
  1721. "\xF0\x9D\x9A\xAD" => "\xCE\xB6",
  1722. "\xF0\x9D\x9A\xAE" => "\xCE\xB7",
  1723. "\xF0\x9D\x9A\xAF" => "\xCE\xB8",
  1724. "\xF0\x9D\x9A\xB0" => "\xCE\xB9",
  1725. "\xF0\x9D\x9A\xB1" => "\xCE\xBA",
  1726. "\xF0\x9D\x9A\xB2" => "\xCE\xBB",
  1727. "\xF0\x9D\x9A\xB3" => "\xCE\xBC",
  1728. "\xF0\x9D\x9A\xB4" => "\xCE\xBD",
  1729. "\xF0\x9D\x9A\xB5" => "\xCE\xBE",
  1730. "\xF0\x9D\x9A\xB6" => "\xCE\xBF",
  1731. "\xF0\x9D\x9A\xB7" => "\xCF\x80",
  1732. "\xF0\x9D\x9A\xB8" => "\xCF\x81",
  1733. "\xF0\x9D\x9A\xB9" => "\xCE\xB8",
  1734. "\xF0\x9D\x9A\xBA" => "\xCF\x83",
  1735. "\xF0\x9D\x9A\xBB" => "\xCF\x84",
  1736. "\xF0\x9D\x9A\xBC" => "\xCF\x85",
  1737. "\xF0\x9D\x9A\xBD" => "\xCF\x86",
  1738. "\xF0\x9D\x9A\xBE" => "\xCF\x87",
  1739. "\xF0\x9D\x9A\xBF" => "\xCF\x88",
  1740. "\xF0\x9D\x9B\x80" => "\xCF\x89",
  1741. "\xF0\x9D\x9B\x93" => "\xCF\x83",
  1742. "\xF0\x9D\x9B\xA2" => "\xCE\xB1",
  1743. "\xF0\x9D\x9B\xA3" => "\xCE\xB2",
  1744. "\xF0\x9D\x9B\xA4" => "\xCE\xB3",
  1745. "\xF0\x9D\x9B\xA5" => "\xCE\xB4",
  1746. "\xF0\x9D\x9B\xA6" => "\xCE\xB5",
  1747. "\xF0\x9D\x9B\xA7" => "\xCE\xB6",
  1748. "\xF0\x9D\x9B\xA8" => "\xCE\xB7",
  1749. "\xF0\x9D\x9B\xA9" => "\xCE\xB8",
  1750. "\xF0\x9D\x9B\xAA" => "\xCE\xB9",
  1751. "\xF0\x9D\x9B\xAB" => "\xCE\xBA",
  1752. "\xF0\x9D\x9B\xAC" => "\xCE\xBB",
  1753. "\xF0\x9D\x9B\xAD" => "\xCE\xBC",
  1754. "\xF0\x9D\x9B\xAE" => "\xCE\xBD",
  1755. "\xF0\x9D\x9B\xAF" => "\xCE\xBE",
  1756. "\xF0\x9D\x9B\xB0" => "\xCE\xBF",
  1757. "\xF0\x9D\x9B\xB1" => "\xCF\x80",
  1758. "\xF0\x9D\x9B\xB2" => "\xCF\x81",
  1759. "\xF0\x9D\x9B\xB3" => "\xCE\xB8",
  1760. "\xF0\x9D\x9B\xB4" => "\xCF\x83",
  1761. "\xF0\x9D\x9B\xB5" => "\xCF\x84",
  1762. "\xF0\x9D\x9B\xB6" => "\xCF\x85",
  1763. "\xF0\x9D\x9B\xB7" => "\xCF\x86",
  1764. "\xF0\x9D\x9B\xB8" => "\xCF\x87",
  1765. "\xF0\x9D\x9B\xB9" => "\xCF\x88",
  1766. "\xF0\x9D\x9B\xBA" => "\xCF\x89",
  1767. "\xF0\x9D\x9C\x8D" => "\xCF\x83",
  1768. "\xF0\x9D\x9C\x9C" => "\xCE\xB1",
  1769. "\xF0\x9D\x9C\x9D" => "\xCE\xB2",
  1770. "\xF0\x9D\x9C\x9E" => "\xCE\xB3",
  1771. "\xF0\x9D\x9C\x9F" => "\xCE\xB4",
  1772. "\xF0\x9D\x9C\xA0" => "\xCE\xB5",
  1773. "\xF0\x9D\x9C\xA1" => "\xCE\xB6",
  1774. "\xF0\x9D\x9C\xA2" => "\xCE\xB7",
  1775. "\xF0\x9D\x9C\xA3" => "\xCE\xB8",
  1776. "\xF0\x9D\x9C\xA4" => "\xCE\xB9",
  1777. "\xF0\x9D\x9C\xA5" => "\xCE\xBA",
  1778. "\xF0\x9D\x9C\xA6" => "\xCE\xBB",
  1779. "\xF0\x9D\x9C\xA7" => "\xCE\xBC",
  1780. "\xF0\x9D\x9C\xA8" => "\xCE\xBD",
  1781. "\xF0\x9D\x9C\xA9" => "\xCE\xBE",
  1782. "\xF0\x9D\x9C\xAA" => "\xCE\xBF",
  1783. "\xF0\x9D\x9C\xAB" => "\xCF\x80",
  1784. "\xF0\x9D\x9C\xAC" => "\xCF\x81",
  1785. "\xF0\x9D\x9C\xAD" => "\xCE\xB8",
  1786. "\xF0\x9D\x9C\xAE" => "\xCF\x83",
  1787. "\xF0\x9D\x9C\xAF" => "\xCF\x84",
  1788. "\xF0\x9D\x9C\xB0" => "\xCF\x85",
  1789. "\xF0\x9D\x9C\xB1" => "\xCF\x86",
  1790. "\xF0\x9D\x9C\xB2" => "\xCF\x87",
  1791. "\xF0\x9D\x9C\xB3" => "\xCF\x88",
  1792. "\xF0\x9D\x9C\xB4" => "\xCF\x89",
  1793. "\xF0\x9D\x9D\x87" => "\xCF\x83",
  1794. "\xF0\x9D\x9D\x96" => "\xCE\xB1",
  1795. "\xF0\x9D\x9D\x97" => "\xCE\xB2",
  1796. "\xF0\x9D\x9D\x98" => "\xCE\xB3",
  1797. "\xF0\x9D\x9D\x99" => "\xCE\xB4",
  1798. "\xF0\x9D\x9D\x9A" => "\xCE\xB5",
  1799. "\xF0\x9D\x9D\x9B" => "\xCE\xB6",
  1800. "\xF0\x9D\x9D\x9C" => "\xCE\xB7",
  1801. "\xF0\x9D\x9D\x9D" => "\xCE\xB8",
  1802. "\xF0\x9D\x9D\x9E" => "\xCE\xB9",
  1803. "\xF0\x9D\x9D\x9F" => "\xCE\xBA",
  1804. "\xF0\x9D\x9D\xA0" => "\xCE\xBB",
  1805. "\xF0\x9D\x9D\xA1" => "\xCE\xBC",
  1806. "\xF0\x9D\x9D\xA2" => "\xCE\xBD",
  1807. "\xF0\x9D\x9D\xA3" => "\xCE\xBE",
  1808. "\xF0\x9D\x9D\xA4" => "\xCE\xBF",
  1809. "\xF0\x9D\x9D\xA5" => "\xCF\x80",
  1810. "\xF0\x9D\x9D\xA6" => "\xCF\x81",
  1811. "\xF0\x9D\x9D\xA7" => "\xCE\xB8",
  1812. "\xF0\x9D\x9D\xA8" => "\xCF\x83",
  1813. "\xF0\x9D\x9D\xA9" => "\xCF\x84",
  1814. "\xF0\x9D\x9D\xAA" => "\xCF\x85",
  1815. "\xF0\x9D\x9D\xAB" => "\xCF\x86",
  1816. "\xF0\x9D\x9D\xAC" => "\xCF\x87",
  1817. "\xF0\x9D\x9D\xAD" => "\xCF\x88",
  1818. "\xF0\x9D\x9D\xAE" => "\xCF\x89",
  1819. "\xF0\x9D\x9E\x81" => "\xCF\x83",
  1820. "\xF0\x9D\x9E\x90" => "\xCE\xB1",
  1821. "\xF0\x9D\x9E\x91" => "\xCE\xB2",
  1822. "\xF0\x9D\x9E\x92" => "\xCE\xB3",
  1823. "\xF0\x9D\x9E\x93" => "\xCE\xB4",
  1824. "\xF0\x9D\x9E\x94" => "\xCE\xB5",
  1825. "\xF0\x9D\x9E\x95" => "\xCE\xB6",
  1826. "\xF0\x9D\x9E\x96" => "\xCE\xB7",
  1827. "\xF0\x9D\x9E\x97" => "\xCE\xB8",
  1828. "\xF0\x9D\x9E\x98" => "\xCE\xB9",
  1829. "\xF0\x9D\x9E\x99" => "\xCE\xBA",
  1830. "\xF0\x9D\x9E\x9A" => "\xCE\xBB",
  1831. "\xF0\x9D\x9E\x9B" => "\xCE\xBC",
  1832. "\xF0\x9D\x9E\x9C" => "\xCE\xBD",
  1833. "\xF0\x9D\x9E\x9D" => "\xCE\xBE",
  1834. "\xF0\x9D\x9E\x9E" => "\xCE\xBF",
  1835. "\xF0\x9D\x9E\x9F" => "\xCF\x80",
  1836. "\xF0\x9D\x9E\xA0" => "\xCF\x81",
  1837. "\xF0\x9D\x9E\xA1" => "\xCE\xB8",
  1838. "\xF0\x9D\x9E\xA2" => "\xCF\x83",
  1839. "\xF0\x9D\x9E\xA3" => "\xCF\x84",
  1840. "\xF0\x9D\x9E\xA4" => "\xCF\x85",
  1841. "\xF0\x9D\x9E\xA5" => "\xCF\x86",
  1842. "\xF0\x9D\x9E\xA6" => "\xCF\x87",
  1843. "\xF0\x9D\x9E\xA7" => "\xCF\x88",
  1844. "\xF0\x9D\x9E\xA8" => "\xCF\x89",
  1845. "\xF0\x9D\x9E\xBB" => "\xCF\x83",
  1846. "\xF0\x9D\x9F\x8A" => "\xCF\x9D",
  1847. );
  1848. global $phpbb_root_path, $phpEx;
  1849. // do the case fold
  1850. $text = utf8_case_fold($text, $option);
  1851. if (!class_exists('utf_normalizer')) {
  1852. global $phpbb_root_path, $phpEx;
  1853. include($phpbb_root_path . 'includes/utf/utf_normalizer.' . $phpEx);
  1854. }
  1855. // convert to NFKC
  1856. utf_normalizer::nfkc($text);
  1857. // FC_NFKC_Closure, http://www.unicode.org/Public/5.0.0/ucd/DerivedNormalizationProps.txt
  1858. $text = strtr($text, $fc_nfkc_closure);
  1859. return $text;
  1860. }
  1861. }
  1862. if (!function_exists('utf8_case_fold')) {
  1863. /**
  1864. * Case folds a unicode string as per Unicode 5.0, section 3.13
  1865. *
  1866. * @param string $text text to be case folded
  1867. * @param string $option determines how we will fold the cases
  1868. * @return string case folded text
  1869. */
  1870. function utf8_case_fold($text, $option = 'full')
  1871. {
  1872. static $uniarray = array();
  1873. global $phpbb_root_path, $phpEx;
  1874. // common is always set
  1875. if (!isset($uniarray['c'])) {
  1876. $uniarray['c'] = include($phpbb_root_path . 'includes/utf/data/case_fold_c.' . $phpEx);
  1877. }
  1878. // only set full if we need to
  1879. if ($option === 'full' && !isset($uniarray['f'])) {
  1880. $uniarray['f'] = include($phpbb_root_path . 'includes/utf/data/case_fold_f.' . $phpEx);
  1881. }
  1882. // only set simple if we need to
  1883. if ($option !== 'full' && !isset($uniarray['s'])) {
  1884. $uniarray['s'] = include($phpbb_root_path . 'includes/utf/data/case_fold_s.' . $phpEx);
  1885. }
  1886. // common is always replaced
  1887. $text = strtr($text, $uniarray['c']);
  1888. if ($option === 'full') {
  1889. // full replaces a character with multiple characters
  1890. $text = strtr($text, $uniarray['f']);
  1891. } else {
  1892. // simple replaces a character with another character
  1893. $text = strtr($text, $uniarray['s']);
  1894. }
  1895. return $text;
  1896. }
  1897. }