BxDolMForum.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup DolphinMigration Dolphin Migration
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. require_once('BxDolMData.php');
  12. bx_import('BxDolStorage');
  13. class BxDolMForum extends BxDolMData
  14. {
  15. private $_iSystem = 0;
  16. public function __construct(&$oMigrationModule, &$oDb)
  17. {
  18. parent::__construct($oMigrationModule, $oDb);
  19. $this -> _sModuleName = 'forum';
  20. $this -> _sTableWithTransKey = 'bx_forum_discussions';
  21. $this -> _iSystem = $this -> _oDb -> getOne("SELECT `ID` FROM `sys_objects_cmts` WHERE `Name` = 'bx_forum' LIMIT 1");
  22. }
  23. public function getTotalRecords()
  24. {
  25. $aResult = $this -> _mDb -> getRow("SELECT SUM(`forum_topics`) as `topics`, SUM(`forum_posts`) as `posts` FROM `bx_forum`");
  26. return !(int)$aResult['topics'] && !(int)$aResult['posts'] ? 0 : $aResult;
  27. }
  28. public function runMigration()
  29. {
  30. if (!$this -> getTotalRecords())
  31. {
  32. $this -> setResultStatus(_t('_bx_dolphin_migration_no_data_to_transfer'));
  33. return BX_MIG_SUCCESSFUL;
  34. }
  35. $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_forum'));
  36. $this -> createMIdField();
  37. $aResult = $this -> _mDb -> getAll("SELECT * FROM `bx_forum` ORDER BY `forum_id`");
  38. $iCmts = $iCount = 0;
  39. foreach($aResult as $iKey => $aValue)
  40. {
  41. $iCategory = $aValue['forum_uri'] == 'General-discussions' ? 1 : $this -> transferCategory($aValue['forum_title']);
  42. $aTopicts = $this -> _mDb -> getAll("SELECT * FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name'] . "`
  43. WHERE `forum_id` = :categ
  44. ORDER BY `topic_id`", array('categ' => $aValue['forum_id']));
  45. foreach($aTopicts as $iTopic => $aTopic)
  46. {
  47. $iTopicId = $this -> isItemExisted($aTopic['topic_id']);
  48. $iProfileId = $this -> getProfileIdByNickName($aTopic['first_post_user']);
  49. if (!$iTopicId && $iProfileId)
  50. {
  51. $sTitle = isset($aTopic['topic_title']) ? $aTopic['topic_title'] : time();
  52. $sStatus = !$aTopic['topic_hidden'] ? 'active' : 'hidden';
  53. $sQuery = $this -> _oDb -> prepare(
  54. "
  55. INSERT INTO
  56. `{$this -> _sTableWithTransKey}`
  57. SET
  58. `author` = ?,
  59. `added` = ?,
  60. `title` = ?,
  61. `text` = ?,
  62. `status_admin` = ?,
  63. `cat` = ?,
  64. `lock` = ?,
  65. `stick` = ?
  66. ",
  67. $iProfileId,
  68. $aTopic['when'],
  69. $sTitle,
  70. $sTitle,
  71. $sStatus,
  72. $iCategory,
  73. $aTopic['topic_locked'],
  74. $aTopic['topic_sticky']
  75. );
  76. $this -> _oDb -> query($sQuery);
  77. $iTopicId = $this -> _oDb -> lastId();
  78. if (!$iTopicId)
  79. {
  80. $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_forum_error', (int)$aTopic['topic_id']));
  81. return BX_MIG_FAILED;
  82. }
  83. $this -> setMID($iTopicId, $aTopic['topic_id']);
  84. }
  85. $aTopicsTrasnferInfo = $this -> transferMessages($iTopicId, (int)$aTopic['topic_id']);
  86. $this -> transferSubscribers($iTopicId, (int)$aTopic['topic_id']);
  87. $this -> _iTransferred++;
  88. $aStat = $this -> getTopicStat($iTopicId);
  89. $this -> _oDb -> query("UPDATE `{$this -> _sTableWithTransKey}` SET
  90. `allow_view_to` = 3,
  91. `comments` = :cmts,
  92. `lr_timestamp` = :lr_timestamp,
  93. `lr_profile_id` = :lr_profile_id,
  94. `lr_comment_id` = :lrc_id,
  95. `added` = :added,
  96. `changed` = :changed,
  97. `text_comments` = :all_text,
  98. `text` = :text
  99. WHERE `id` = :id",
  100. array(
  101. 'id' => $iTopicId,
  102. 'cmts' => $aTopicsTrasnferInfo['number'],
  103. 'lr_timestamp' => $aTopicsTrasnferInfo['lrt'],
  104. 'lr_profile_id' => $aTopicsTrasnferInfo['lrp'],
  105. 'lrc_id' => $aStat['lrc_id'],
  106. 'added' => $aStat['first_time'] ? $aStat['first_time'] : time(),
  107. 'changed' => $aStat['lr_timestamp'] ? $aStat['lr_timestamp'] : time(),
  108. 'all_text' => strip_tags($aStat['text']),
  109. 'text' => $aTopicsTrasnferInfo['first_message'],
  110. )
  111. );
  112. }
  113. }
  114. // set as finished;
  115. $this -> setResultStatus(_t('_bx_dolphin_migration_started_migration_forum_finished', $this -> _iTransferred));
  116. return BX_MIG_SUCCESSFUL;
  117. }
  118. /**
  119. * Transfer Forum posts
  120. *
  121. * @param int $iEntryId UNA forum ID
  122. * @param int $iTopicId Dolphin topic id
  123. * @return array first message, transferred posts number, last replay profile id, last replay time
  124. */
  125. protected function transferMessages($iEntryId, $iTopicId)
  126. {
  127. $aItems = $this -> _mDb -> getAll("SELECT
  128. `Profiles`.`ID` as `user`,
  129. `post_text` as `message`,
  130. `when`,
  131. `p`.`post_id`
  132. FROM `" . $this -> _oConfig -> _aMigrationModules[$this -> _sModuleName]['table_name_post'] . "` AS `p`
  133. LEFT JOIN `Profiles` ON `p`.`user` = `Profiles`.`NickName`
  134. WHERE `topic_id` = :id
  135. ORDER BY `id` ASC", array('id' => $iTopicId));
  136. if (empty($aItems))
  137. return false;
  138. $iNumber = 0;
  139. $sMessage = '';
  140. $iProfileId = 0;
  141. foreach($aItems as $iKey => $aValue)
  142. {
  143. $iProfileId = $this -> getProfileId($aValue['user']);
  144. $this -> _oDb -> query("INSERT INTO `bx_forum_cmts` (`cmt_id`, `cmt_parent_id`, `cmt_vparent_id`, `cmt_object_id`, `cmt_author_id`, `cmt_level`, `cmt_text`, `cmt_time`, `cmt_replies`, `cmt_rate`, `cmt_rate_count`)
  145. VALUES (NULL, 0, 0, :object, :user, 0, :message, :time, 0, 0, 0)",
  146. array(
  147. 'object' => $iEntryId,
  148. 'user' => $iProfileId,
  149. 'message' => $aValue['message'],
  150. 'time' => $aValue['when'],
  151. ));
  152. $iNumber++;
  153. if (!$sMessage)
  154. $sMessage = $aValue['message'];
  155. $iTime = $aValue['when'];
  156. $this -> transferAttachments($aValue['post_id'], $this -> _oDb -> lastId(), $iProfileId);
  157. }
  158. return array('first_message' => $sMessage, 'number' => $iNumber, 'lrp' => $iProfileId, 'lrt' => $iTime);
  159. }
  160. /**
  161. * Get profile ID in Una by Nickname in Dolphin
  162. *
  163. * @param string $sNickName Dolphin's nickname
  164. * @return mixed profile id or false if not found
  165. */
  166. private function getProfileIdByNickName($sNickName)
  167. {
  168. $iProfileId = $this -> _mDb -> getOne("SELECT `ID` FROM `Profiles` WHERE `NickName` = :user LIMIT 1", array('user' => $sNickName));
  169. return $iProfileId ? $this -> getProfileId($iProfileId) : 0;
  170. }
  171. protected function transferCategory($sTitle, $sPrefix = 'bx_forum', $sCategory = 'bx_forum_cats', $iValue = 0, $sData = '')
  172. {
  173. return parent::transferCategory($sTitle, $sPrefix, $sCategory);
  174. }
  175. /**
  176. * Transfer forum's subscribers
  177. *
  178. * @param int $iTopicId topic id in UNA
  179. * @param int $iEntryId forum id in Dolphin
  180. * @return void
  181. */
  182. private function transferSubscribers($iTopicId, $iEntryId)
  183. {
  184. $aSubscribers = $this -> _mDb -> getAll("SELECT
  185. *
  186. FROM `bx_forum_flag`
  187. WHERE `topic_id` = :id", array('id' => $iEntryId));
  188. foreach($aSubscribers as $iKey => $aValue)
  189. {
  190. $iProfileId = $this -> getProfileIdByNickName((int)$aValue['user']);
  191. if (!$iProfileId)
  192. continue;
  193. $sQuery = $this -> _oDb -> prepare(
  194. "
  195. REPLACE INTO
  196. `bx_forum_subscribers`
  197. SET
  198. `initiator` = ?,
  199. `content` = ?,
  200. `added` = ?
  201. ",
  202. $iProfileId,
  203. $iTopicId,
  204. $aValue['when']
  205. );
  206. $this -> _oDb -> query($sQuery);
  207. }
  208. }
  209. /**
  210. * Builds path to Forum image files in Dolphin
  211. *
  212. * @param string $s hash
  213. * @return string path
  214. */
  215. private function orca_build_path ($s)
  216. {
  217. return substr($s, 0, 1) . DIRECTORY_SEPARATOR . substr($s, 0, 2) . DIRECTORY_SEPARATOR . substr($s, 0, 3) . '/';
  218. }
  219. /**
  220. * Transfer attached images to the forum
  221. *
  222. * @param int $iPostId Dolphin's post ID
  223. * @param int $iCommentId una post ID
  224. * @param int $iProfileId profile ID
  225. * @return int first image ID
  226. */
  227. private function transferAttachments($iPostId, $iCommentId, $iProfileId)
  228. {
  229. $iFirstImage = 0;
  230. $iProfileId = (int)$iProfileId;
  231. $aAttachments = $this -> _mDb -> getAll("SELECT * FROM `bx_forum_attachments`
  232. WHERE `post_id` = :id", array('id' => $iPostId));
  233. if (empty($aAttachments))
  234. return false;
  235. $this -> _sImageForumFiles = $this -> _oDb -> getExtraParam('root') . 'modules' . DIRECTORY_SEPARATOR . 'boonex' . DIRECTORY_SEPARATOR . "forum" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR . "attachments" . DIRECTORY_SEPARATOR;
  236. foreach($aAttachments as $iKey => $aFile)
  237. {
  238. $sImageFile = $this -> _sImageForumFiles . $this -> orca_build_path($aFile['att_hash']). $aFile['att_hash'];
  239. if (file_exists($sImageFile) && copy($sImageFile, BX_DIRECTORY_PATH_TMP . $aFile['att_name']))
  240. {
  241. $oStorage = BxDolStorage::getObjectInstance('bx_forum_files_cmts');
  242. $iId = $oStorage->storeFileFromPath(BX_DIRECTORY_PATH_TMP . $aFile['att_name'], true, $iProfileId);
  243. $oStorage -> afterUploadCleanup($iId, $iProfileId);
  244. $sQuery = $this -> _oDb -> prepare("INSERT IGNORE INTO `sys_cmts_images2entries` SET `system_id`=?, `cmt_id`=?, `image_id`=?", $this -> _iSystem, $iCommentId, $iId);
  245. $this -> _oDb-> query($sQuery);
  246. }
  247. }
  248. return $iFirstImage;
  249. }
  250. /**
  251. * Returns Forums topics params
  252. *
  253. * @param int $iObjectId forum ID
  254. * @return array
  255. */
  256. private function getTopicStat($iObjectId)
  257. {
  258. return $this -> _oDb -> getRow("SELECT
  259. MAX(`cmt_id`) as `lrc_id`,
  260. MAX(`cmt_time`) as `lr_timestamp`,
  261. MIN(`cmt_time`) as `first_time`,
  262. GROUP_CONCAT(`cmt_text` SEPARATOR '\n') as `text`
  263. FROM `bx_forum_cmts`
  264. WHERE `cmt_object_id` = :id", array('id' => $iObjectId));
  265. }
  266. public function removeContent()
  267. {
  268. if (!$this -> _oDb -> isTableExists($this -> _sTableWithTransKey) || !$this -> _oDb -> isFieldExists($this -> _sTableWithTransKey, $this -> _sTransferFieldIdent))
  269. return false;
  270. $aRecords = $this -> _oDb -> getAll("SELECT * FROM `{$this -> _sTableWithTransKey}` WHERE `{$this -> _sTransferFieldIdent}` !=0");
  271. $iNumber = 0;
  272. if (!empty($aRecords))
  273. {
  274. foreach($aRecords as $iKey => $aValue)
  275. {
  276. BxDolService::call('bx_forum', 'delete_entity', array($aValue['id']));
  277. $iNumber++;
  278. }
  279. }
  280. parent::removeContent();
  281. return $iNumber;
  282. }
  283. }
  284. /** @} */