PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/importer/importer.admin.controller.php

https://github.com/prologos/xe-core
PHP | 1213 lines | 916 code | 106 blank | 191 comment | 191 complexity | 517a12597f9c9be93ea843a90637b97a MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /* Copyright (C) NAVER <http://www.navercorp.com> */
  3. @set_time_limit(0);
  4. require_once('./modules/importer/extract.class.php');
  5. /**
  6. * importerAdminController class
  7. * admin controller class of importer module
  8. *
  9. * @author NAVER (developers@xpressengine.com)
  10. * @package /modules/importer
  11. * @version 0.1
  12. */
  13. class importerAdminController extends importer
  14. {
  15. /**
  16. * Unit count
  17. * @var int
  18. */
  19. var $unit_count = 300;
  20. /**
  21. * Xml parser
  22. * @var XmlParser
  23. */
  24. var $oXmlParser = null;
  25. /**
  26. * Initialization
  27. * @return void
  28. */
  29. function init()
  30. {
  31. }
  32. /**
  33. * Check whether the passing filename exists or not. Detect the file type, too.
  34. * @return void
  35. */
  36. function procImporterAdminCheckXmlFile()
  37. {
  38. global $lang;
  39. $filename = Context::get('filename');
  40. $isExists = 'false';
  41. if(strncasecmp('http://', $filename, 7) === 0)
  42. {
  43. if(ini_get('allow_url_fopen'))
  44. {
  45. $fp = @fopen($filename, "r");
  46. if($fp)
  47. {
  48. $str = fgets($fp, 100);
  49. if(strlen($str) > 0)
  50. {
  51. $isExists = 'true';
  52. $type = 'XML';
  53. if(stristr($str, 'tattertools')) $type = 'TTXML';
  54. $this->add('type', $type);
  55. }
  56. fclose($fp);
  57. $resultMessage = $lang->found_xml_file;
  58. }
  59. else $resultMessage = $lang->cannot_url_file;
  60. }
  61. else $resultMessage = $lang->cannot_allow_fopen_in_phpini;
  62. $this->add('exists', $isExists);
  63. }
  64. else
  65. {
  66. $realPath = FileHandler::getRealPath($filename);
  67. if(file_exists($realPath) && is_file($realPath)) $isExists = 'true';
  68. $this->add('exists', $isExists);
  69. if($isExists == 'true')
  70. {
  71. $type = 'XML';
  72. $fp = fopen($realPath, "r");
  73. $str = fgets($fp, 100);
  74. if(stristr($str, 'tattertools')) $type = 'TTXML';
  75. fclose($fp);
  76. $this->add('type', $type);
  77. $resultMessage = $lang->found_xml_file;
  78. }
  79. else $resultMessage = $lang->not_found_xml_file;
  80. }
  81. $this->add('result_message', $resultMessage);
  82. }
  83. /**
  84. * Sync member information with document information
  85. * @return void
  86. */
  87. function procImporterAdminSync()
  88. {
  89. $oMemberModel = getModel('member');
  90. $member_config = $oMemberModel->getMemberConfig();
  91. $postFix = ($member_config->identifier == 'email_address') ? 'ByEmail' : '';
  92. // 계정이 이메일인 경우 이메일 정보로 사용자를 싱크하도록 한다. 이때 변수명은 그대로 user_id를 사용한다.
  93. /* DBMS가 CUBRID인 경우 MySQL과 동일한 방법으로는 문서 및 댓글에 대한 사용자 정보를 동기화 할 수 없으므로 예외 처리 합니다.
  94. CUBRID를 사용하지 않는 경우에만 보편적인 기존 질의문을 사용합니다. */
  95. $db_info = Context::getDBInfo ();
  96. if($db_info->db_type != "cubrid")
  97. {
  98. $output = executeQuery('importer.updateDocumentSync'.$postFix);
  99. $output = executeQuery('importer.updateCommentSync'.$postFix);
  100. }
  101. else
  102. {
  103. $output = executeQueryArray ('importer.getDocumentMemberSrlWithUserID'.$postFix);
  104. if(is_array ($output->data) && count ($output->data))
  105. {
  106. $success_count = 0;
  107. $error_count = 0;
  108. $total_count = 0;
  109. foreach ($output->data as $val)
  110. {
  111. $args->user_id = $val->user_id;
  112. $args->member_srl = $val->member_srl;
  113. $tmp = executeQuery ('importer.updateDocumentSyncForCUBRID'.$postFix, $args);
  114. if($tmp->toBool () === true)
  115. {
  116. $success_count++;
  117. }
  118. else
  119. {
  120. $error_count++;
  121. }
  122. $total_count++;
  123. }
  124. } // documents section
  125. $output = executeQueryArray ('importer.getCommentMemberSrlWithUserID'.$postFix);
  126. if(is_array ($output->data) && count ($output->data))
  127. {
  128. $success_count = 0;
  129. $error_count = 0;
  130. $total_count = 0;
  131. foreach ($output->data as $val)
  132. {
  133. $args->user_id = $val->user_id;
  134. $args->member_srl = $val->member_srl;
  135. $tmp = executeQuery ('importer.updateCommentSyncForCUBRID'.$postFix, $args);
  136. if($tmp->toBool () === true)
  137. {
  138. $success_count++;
  139. }
  140. else
  141. {
  142. $error_count++;
  143. }
  144. $total_count++;
  145. }
  146. } // comments section
  147. }
  148. $this->setMessage('msg_sync_completed');
  149. }
  150. /**
  151. * Pre-analyze the xml file and cache it
  152. * @return void
  153. */
  154. function procImporterAdminPreProcessing()
  155. {
  156. // Get the target xml file to import
  157. $xml_file = Context::get('xml_file');
  158. // Get a type of the target
  159. $type = Context::get('type');
  160. // Extract and cache information from the xml file
  161. $oExtract = new extract();
  162. switch($type)
  163. {
  164. case 'member' :
  165. $output = $oExtract->set($xml_file,'<members ', '</members>', '<member>', '</member>');
  166. if($output->toBool()) $oExtract->saveItems();
  167. break;
  168. case 'message' :
  169. $output = $oExtract->set($xml_file,'<messages ', '</messages>', '<message>','</message>');
  170. if($output->toBool()) $oExtract->saveItems();
  171. break;
  172. case 'ttxml' :
  173. // Category information
  174. $output = $oExtract->set($xml_file, '', '', '', '');
  175. if ($output->toBool())
  176. {
  177. // Get a category of ttxml separately
  178. $started = false;
  179. $buff = '';
  180. while (!feof($oExtract->fd))
  181. {
  182. $str = fgets($oExtract->fd, 1024);
  183. if(strstr($str, '<category>'))
  184. {
  185. $started = true;
  186. $str = strstr($str, '<category>');
  187. }
  188. if(substr($str,0,strlen('<post ')) == '<post ') break;
  189. if ($started) $buff .= $str;
  190. }
  191. $buff = '<categories>'.$buff.'</categories>';
  192. $oExtract->closeFile();
  193. $category_filename = sprintf('%s/%s', $oExtract->cache_path, 'category.xml');
  194. FileHandler::writeFile($category_filename, $buff);
  195. // Guestbook information
  196. $output = $oExtract->set($xml_file, '', '', '', '');
  197. if($output->toBool())
  198. {
  199. $started = false;
  200. $buff = '';
  201. while (!feof($oExtract->fd))
  202. {
  203. $str = fgets($oExtract->fd, 1024);
  204. if(strstr($str, '<guestbook>'))
  205. {
  206. $started = true;
  207. $str = strstr($str, '<guestbook>');
  208. }
  209. if($started)
  210. {
  211. $pos = strpos($str, '</guestbook>');
  212. if($pos !== false)
  213. {
  214. $buff .= substr($str, 0, $pos + strlen('</guestbook>'));
  215. break;
  216. }
  217. $buff .= $str;
  218. }
  219. }
  220. $oExtract->closeFile();
  221. $guestbook_filename = sprintf('%s/%s', $oExtract->cache_path, 'guestbook.xml');
  222. FileHandler::writeFile($guestbook_filename, $buff);
  223. // Individual items
  224. $output = $oExtract->set($xml_file,'<blog', '</blog>', '<post ', '</post>');
  225. if($output->toBool()) $oExtract->saveItems();
  226. }
  227. }
  228. break;
  229. default :
  230. // First get category information
  231. $output = $oExtract->set($xml_file,'<categories>', '</categories>', '<category','</category>');
  232. if($output->toBool())
  233. {
  234. $oExtract->mergeItems('category.xml');
  235. // Get each item
  236. $output = $oExtract->set($xml_file,'<posts ', '</posts>', '<post>', '</post>');
  237. if($output->toBool()) $oExtract->saveItems();
  238. }
  239. break;
  240. }
  241. if(!$output->toBool())
  242. {
  243. $this->add('error',0);
  244. $this->add('status',-1);
  245. $this->setMessage($output->getMessage());
  246. return;
  247. }
  248. // Notify that all data completely extracted
  249. $this->add('type',$type);
  250. $this->add('total',$oExtract->getTotalCount());
  251. $this->add('cur',0);
  252. $this->add('key', $oExtract->getKey());
  253. $this->add('status',0);
  254. }
  255. /**
  256. * Migrate data after completing xml file extraction
  257. * @return void
  258. */
  259. function procImporterAdminImport()
  260. {
  261. // Variable setting
  262. $type = Context::get('type');
  263. $total = Context::get('total');
  264. $cur = Context::get('cur');
  265. $key = Context::get('key');
  266. $user_id = Context::get('user_id');
  267. $target_module = Context::get('target_module');
  268. $guestbook_target_module = Context::get('guestbook_target_module');
  269. $this->unit_count = Context::get('unit_count');
  270. // Check if an index file exists
  271. $index_file = './files/cache/importer/'.$key.'/index';
  272. if(!file_exists($index_file)) return new Object(-1, 'msg_invalid_xml_file');
  273. switch($type)
  274. {
  275. case 'ttxml' :
  276. if(!$target_module) return new Object(-1,'msg_invalid_request');
  277. $oModuleModel = getModel('module');
  278. $columnList = array('module_srl', 'module');
  279. $target_module_info = $oModuleModel->getModuleInfoByModuleSrl($target_module, $columnList);
  280. $ttimporter = FileHandler::exists(_XE_PATH_ . 'modules/importer/ttimport.class.php');
  281. if($ttimporter) require_once($ttimporter);
  282. $oTT = new ttimport();
  283. $cur = $oTT->importModule($key, $cur, $index_file, $this->unit_count, $target_module, $guestbook_target_module, $user_id, $target_module_info->module);
  284. break;
  285. case 'message' :
  286. $cur = $this->importMessage($key, $cur, $index_file);
  287. break;
  288. case 'member' :
  289. $cur = $this->importMember($key, $cur, $index_file);
  290. break;
  291. case 'module' :
  292. // Check if the target module exists
  293. if(!$target_module) return new Object(-1,'msg_invalid_request');
  294. $cur = $this->importModule($key, $cur, $index_file, $target_module);
  295. break;
  296. }
  297. // Notify that all data completely extracted
  298. $this->add('type',$type);
  299. $this->add('total',$total);
  300. $this->add('cur',$cur);
  301. $this->add('key', $key);
  302. $this->add('target_module', $target_module);
  303. // When completing, success message appears and remove the cache files
  304. if($total <= $cur)
  305. {
  306. $this->setMessage( sprintf(Context::getLang('msg_import_finished'), $cur, $total) );
  307. FileHandler::removeDir('./files/cache/importer/'.$key);
  308. }
  309. else $this->setMessage( sprintf(Context::getLang('msg_importing'), $total, $cur) );
  310. }
  311. /**
  312. * Import member information
  313. * @param int $key
  314. * @param int $cur
  315. * @param string $index_file
  316. * @return int
  317. */
  318. function importMember($key, $cur, $index_file)
  319. {
  320. if(!$cur) $cur = 0;
  321. // Create the xmlParser object
  322. $oXmlParser = new XmlParser();
  323. // Create objects for importing member information
  324. $this->oMemberController = getController('member');
  325. $this->oMemberModel = getModel('member');
  326. // Get a default member group
  327. $default_group = $this->oMemberModel->getDefaultGroup();
  328. $default_group_srl = $default_group->group_srl;
  329. // Get information of the Webmaster
  330. $oModuleModel = getModel('module');
  331. $member_config = $oModuleModel->getModuleConfig('member');
  332. // Open an index file
  333. $f = fopen($index_file,"r");
  334. // Pass if already read
  335. for($i=0;$i<$cur;$i++) fgets($f, 1024);
  336. // Read by each line until the condition meets
  337. for($idx=$cur;$idx<$cur+$this->unit_count;$idx++)
  338. {
  339. if(feof($f)) break;
  340. // Find a given location
  341. $target_file = trim(fgets($f, 1024));
  342. // Load and parse the file
  343. $xmlObj = $oXmlParser->loadXmlFile($target_file);
  344. FileHandler::removeFile($target_file);
  345. if(!$xmlObj) continue;
  346. // List Objects
  347. $obj = null;
  348. $obj->user_id = base64_decode($xmlObj->member->user_id->body);
  349. $obj->password = base64_decode($xmlObj->member->password->body);
  350. $obj->user_name = base64_decode($xmlObj->member->user_name->body);
  351. $obj->nick_name = base64_decode($xmlObj->member->nick_name->body);
  352. if(!$obj->user_name) $obj->user_name = $obj->nick_name;
  353. $obj->email = base64_decode($xmlObj->member->email->body);
  354. $obj->homepage = base64_decode($xmlObj->member->homepage->body);
  355. $obj->blog = base64_decode($xmlObj->member->blog->body);
  356. $obj->birthday = substr(base64_decode($xmlObj->member->birthday->body),0,8);
  357. $obj->allow_mailing = base64_decode($xmlObj->member->allow_mailing->body);
  358. $obj->point = base64_decode($xmlObj->member->point->body);
  359. $obj->image_nickname = base64_decode($xmlObj->member->image_nickname->buff->body);
  360. $obj->image_mark = base64_decode($xmlObj->member->image_mark->buff->body);
  361. $obj->profile_image = base64_decode($xmlObj->member->profile_image->buff->body);
  362. $obj->signature = base64_decode($xmlObj->member->signature->body);
  363. $obj->regdate = base64_decode($xmlObj->member->regdate->body);
  364. $obj->last_login = base64_decode($xmlObj->member->last_login->body);
  365. if($xmlObj->member->extra_vars)
  366. {
  367. foreach($xmlObj->member->extra_vars as $key => $val)
  368. {
  369. if(in_array($key, array('node_name','attrs','body'))) continue;
  370. $obj->extra_vars->{$key} = base64_decode($val->body);
  371. }
  372. }
  373. // Create url for homepage and blog
  374. if($obj->homepage && strncasecmp('http://', $obj->homepage, 7) !== 0 && strncasecmp('https://', $obj->homepage, 8) !== 0) $obj->homepage = 'http://'.$obj->homepage;
  375. // email address column
  376. $obj->email_address = $obj->email;
  377. list($obj->email_id, $obj->email_host) = explode('@', $obj->email);
  378. // Set the mailing option
  379. if($obj->allow_mailing!='Y') $obj->allow_mailing = 'N';
  380. // Set the message option
  381. $obj->allow_message = 'Y';
  382. if(!in_array($obj->allow_message, array('Y','N','F'))) $obj->allow_message= 'Y';
  383. // Get member-join date if the last login time is not found
  384. if(!$obj->last_login) $obj->last_login = $obj->regdate;
  385. // Get a member_srl
  386. $obj->member_srl = getNextSequence();
  387. $obj->list_order = -1 * $obj->member_srl;
  388. // List extra vars
  389. $extra_vars = $obj->extra_vars;
  390. unset($obj->extra_vars);
  391. $obj->extra_vars = serialize($extra_vars);
  392. // Check if the same nickname is existing
  393. $nick_args = new stdClass;
  394. $nick_args->nick_name = $obj->nick_name;
  395. $nick_output = executeQuery('member.getMemberSrl', $nick_args);
  396. if(!$nick_output->toBool()) $obj->nick_name .= '_'.$obj->member_srl;
  397. // Add a member
  398. $output = executeQuery('member.insertMember', $obj);
  399. if($output->toBool() && !($obj->password))
  400. {
  401. // Send a mail telling the user to reset his password.
  402. $oMail = new Mail();
  403. $oMail->setTitle("Password update for your " . getFullSiteUrl() . " account");
  404. $webmaster_name = $member_config->webmaster_name?$member_config->webmaster_name:'Webmaster';
  405. $oMail->setContent("Dear $obj->user_name, <br /><br />
  406. We recently migrated our phpBB forum to XpressEngine. Since you password was encrypted we could not migrate it too, so please reset it by following this link:
  407. <a href='" . getFullSiteUrl() . "/?act=dispMemberFindAccount' >" . getFullSiteUrl() . "?act=dispMemberFindAccount</a>. You need to enter you email address and hit the 'Find account' button. You will then receive an email with a new, generated password that you can change after login. <br /><br />
  408. Thank you for your understanding,<br />
  409. {$webmaster_name}"
  410. );
  411. $oMail->setSender($webmaster_name, $member_config->webmaster_email);
  412. $oMail->setReceiptor( $obj->user_name, $obj->email);
  413. $oMail->send();
  414. }
  415. // add group join/image name-mark-signiture and so on if a new member successfully added
  416. if($output->toBool())
  417. {
  418. // Join to the default group
  419. $obj->group_srl = $default_group_srl;
  420. executeQuery('member.addMemberToGroup',$obj);
  421. // Image name
  422. if($obj->image_nickname)
  423. {
  424. $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($obj->member_srl));
  425. $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl);
  426. FileHandler::writeFile($target_filename, $obj->image_nickname);
  427. }
  428. // Image mark
  429. if($obj->image_mark && file_exists($obj->image_mark))
  430. {
  431. $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($obj->member_srl));
  432. $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl);
  433. FileHandler::writeFile($target_filename, $obj->image_mark);
  434. }
  435. // Profile image
  436. if($obj->profile_image)
  437. {
  438. $target_path = sprintf('files/member_extra_info/profile_image/%s/', getNumberingPath($obj->member_srl));
  439. $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl);
  440. FileHandler::writeFile($target_filename, $obj->profile_image);
  441. }
  442. // Signiture
  443. if($obj->signature)
  444. {
  445. $signature = removeHackTag($obj->signature);
  446. $signature_buff = sprintf('<?php if(!defined("__XE__")) exit();?>%s', $signature);
  447. $target_path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($obj->member_srl));
  448. if(!is_dir($target_path)) FileHandler::makeDir($target_path);
  449. $target_filename = sprintf('%s%d.signature.php', $target_path, $obj->member_srl);
  450. FileHandler::writeFile($target_filename, $signature_buff);
  451. }
  452. }
  453. }
  454. fclose($f);
  455. return $idx-1;
  456. }
  457. /**
  458. * Import message information parsed from a given xml file
  459. * @param int $key
  460. * @param int $cur
  461. * @param string $index_file
  462. * @return int
  463. */
  464. function importMessage($key, $cur, $index_file)
  465. {
  466. if(!$cur) $cur = 0;
  467. // Create the xmlParser object
  468. $oXmlParser = new XmlParser();
  469. // Open an index file
  470. $f = fopen($index_file,"r");
  471. // Pass if already read
  472. for($i=0;$i<$cur;$i++) fgets($f, 1024);
  473. // Read each line until the condition meets
  474. for($idx=$cur;$idx<$cur+$this->unit_count;$idx++)
  475. {
  476. if(feof($f)) break;
  477. // Find a location
  478. $target_file = trim(fgets($f, 1024));
  479. // Load and parse the file
  480. $xmlObj = $oXmlParser->loadXmlFile($target_file);
  481. FileHandler::removeFile($target_file);
  482. if(!$xmlObj) continue;
  483. // List objects
  484. $obj = null;
  485. $obj->receiver = base64_decode($xmlObj->message->receiver->body);
  486. $obj->sender = base64_decode($xmlObj->message->sender->body);
  487. $obj->title = base64_decode($xmlObj->message->title->body);
  488. $obj->content = base64_decode($xmlObj->message->content->body);
  489. $obj->readed = base64_decode($xmlObj->message->readed->body)=='Y'?'Y':'N';
  490. $obj->regdate = base64_decode($xmlObj->message->regdate->body);
  491. $obj->readed_date = base64_decode($xmlObj->message->readed_date->body);
  492. // Get member_srl of sender/recipient (If not exists, pass)
  493. if(!$obj->sender) continue;
  494. $sender_args->user_id = $obj->sender;
  495. $sender_output = executeQuery('member.getMemberInfo',$sender_args);
  496. $sender_srl = $sender_output->data->member_srl;
  497. if(!$sender_srl)
  498. {
  499. unset($sender_args);
  500. $sender_args->email_address = $obj->sender;
  501. $sender_output = executeQuery('member.getMemberInfoByEmailAddress',$sender_args);
  502. $sender_srl = $sender_output->data->member_srl;
  503. }
  504. if(!$sender_srl) continue;
  505. $receiver_args->user_id = $obj->receiver;
  506. if(!$obj->receiver) continue;
  507. $receiver_output = executeQuery('member.getMemberInfo',$receiver_args);
  508. $receiver_srl = $receiver_output->data->member_srl;
  509. if(!$receiver_srl)
  510. {
  511. unset($receiver_args);
  512. $receiver_args->email_address = $obj->receiver;
  513. $receiver_output = executeQuery('member.getMemberInfoByEmailAddress',$receiver_args);
  514. $receiver_srl = $receiver_output->data->member_srl;
  515. }
  516. if(!$receiver_srl) continue;
  517. // Message to save into sender's message box
  518. $sender_args->sender_srl = $sender_srl;
  519. $sender_args->receiver_srl = $receiver_srl;
  520. $sender_args->message_type = 'S';
  521. $sender_args->title = $obj->title;
  522. $sender_args->content = $obj->content;
  523. $sender_args->readed = $obj->readed;
  524. $sender_args->regdate = $obj->regdate;
  525. $sender_args->readed_date = $obj->readed_date;
  526. $sender_args->related_srl = getNextSequence();
  527. $sender_args->message_srl = getNextSequence();
  528. $sender_args->list_order = $sender_args->message_srl * -1;
  529. $output = executeQuery('communication.sendMessage', $sender_args);
  530. if($output->toBool())
  531. {
  532. // Message to save into recipient's massage box
  533. $receiver_args->message_srl = $sender_args->related_srl;
  534. $receiver_args->list_order = $sender_args->related_srl*-1;
  535. $receiver_args->sender_srl = $sender_srl;
  536. if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl;
  537. $receiver_args->receiver_srl = $receiver_srl;
  538. $receiver_args->message_type = 'R';
  539. $receiver_args->title = $obj->title;
  540. $receiver_args->content = $obj->content;
  541. $receiver_args->readed = $obj->readed;
  542. $receiver_args->regdate = $obj->regdate;
  543. $receiver_args->readed_date = $obj->readed_date;
  544. $output = executeQuery('communication.sendMessage', $receiver_args);
  545. }
  546. }
  547. fclose($f);
  548. return $idx-1;
  549. }
  550. /**
  551. * Import data in module.xml format
  552. * @param int $key
  553. * @param int $cur
  554. * @param string $index_file
  555. * @param int $module_srl
  556. * @return int
  557. */
  558. function importModule($key, $cur, $index_file, $module_srl)
  559. {
  560. // Pre-create the objects needed
  561. $this->oXmlParser = new XmlParser();
  562. // Get category information of the target module
  563. $oDocumentController = getController('document');
  564. $oDocumentModel = getModel('document');
  565. $category_list = $category_titles = array();
  566. $category_list = $oDocumentModel->getCategoryList($module_srl);
  567. if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl;
  568. // Extract category information
  569. $category_file = preg_replace('/index$/i', 'category.xml', $index_file);
  570. if(file_exists($category_file))
  571. {
  572. $buff = FileHandler::readFile($category_file);
  573. // Create the xmlParser object
  574. $xmlDoc = $this->oXmlParser->loadXmlFile($category_file);
  575. $categories = $xmlDoc->items->category;
  576. if($categories)
  577. {
  578. if(!is_array($categories)) $categories = array($categories);
  579. $match_sequence = array();
  580. foreach($categories as $k => $v)
  581. {
  582. $category = trim(base64_decode($v->body));
  583. if(!$category || $category_titles[$category]) continue;
  584. $sequence = $v->attrs->sequence;
  585. $parent = $v->attrs->parent;
  586. $obj = null;
  587. $obj->title = $category;
  588. $obj->module_srl = $module_srl;
  589. if($parent) $obj->parent_srl = $match_sequence[$parent];
  590. $output = $oDocumentController->insertCategory($obj);
  591. if($output->toBool()) $match_sequence[$sequence] = $output->get('category_srl');
  592. }
  593. $oDocumentController = getController('document');
  594. $oDocumentController->makeCategoryFile($module_srl);
  595. }
  596. FileHandler::removeFile($category_file);
  597. }
  598. $category_list = $category_titles = array();
  599. $category_list = $oDocumentModel->getCategoryList($module_srl);
  600. if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl;
  601. $ek_args->module_srl = $module_srl;
  602. $output = executeQueryArray('document.getDocumentExtraKeys', $ek_args);
  603. if($output->data)
  604. {
  605. foreach($output->data as $key => $val) $extra_keys[$val->eid] = true;
  606. }
  607. if(!$cur) $cur = 0;
  608. // Open an index file
  609. $f = fopen($index_file,"r");
  610. // Pass if already read
  611. for($i=0;$i<$cur;$i++) fgets($f, 1024);
  612. // Read each line until the condition meets
  613. for($idx=$cur;$idx<$cur+$this->unit_count;$idx++)
  614. {
  615. if(feof($f)) break;
  616. // Find a location
  617. $target_file = trim(fgets($f, 1024));
  618. if(!file_exists($target_file)) continue;
  619. // Importing data from now on
  620. $fp = fopen($target_file,"r");
  621. if(!$fp) continue;
  622. $obj = new stdClass;
  623. $obj->module_srl = $module_srl;
  624. $obj->document_srl = getNextSequence();
  625. $files = array();
  626. $extra_vars = array();
  627. $started = false;
  628. $buff = array();
  629. // Start from the body data
  630. while(!feof($fp))
  631. {
  632. $str = fgets($fp, 1024);
  633. // Prepare an item
  634. if(trim($str) == '<post>')
  635. {
  636. $started = true;
  637. // Trackback inserted
  638. }
  639. else if(substr($str,0,11) == '<trackbacks')
  640. {
  641. $obj->trackback_count = $this->importTrackbacks($fp, $module_srl, $obj->document_srl);
  642. continue;
  643. // Comments inserted
  644. }
  645. else if(substr($str,0,9) == '<comments')
  646. {
  647. $obj->comment_count = $this->importComments($fp, $module_srl, $obj->document_srl);
  648. continue;
  649. // Attachment inserted
  650. }
  651. else if(substr($str,0,9) == '<attaches')
  652. {
  653. $obj->uploaded_count = $this->importAttaches($fp, $module_srl, $obj->document_srl, $files);
  654. continue;
  655. // When starting extra variabls
  656. }
  657. elseif(trim($str) == '<extra_vars>')
  658. {
  659. $extra_vars = $this->importExtraVars($fp);
  660. continue;
  661. }
  662. if($started) $buff[] = $str;
  663. }
  664. $xmlDoc = $this->oXmlParser->parse(implode('', $buff));
  665. $category = base64_decode($xmlDoc->post->category->body);
  666. if($category_titles[$category]) $obj->category_srl = $category_titles[$category];
  667. $obj->member_srl = 0;
  668. $obj->is_notice = base64_decode($xmlDoc->post->is_notice->body)=='Y'?'Y':'N';
  669. $obj->status = base64_decode($xmlDoc->post->is_secret->body)=='Y'?$oDocumentModel->getConfigStatus('secret'):$oDocumentModel->getConfigStatus('public');
  670. $obj->title = base64_decode($xmlDoc->post->title->body);
  671. $obj->content = base64_decode($xmlDoc->post->content->body);
  672. $obj->readed_count = base64_decode($xmlDoc->post->readed_count->body);
  673. $obj->voted_count = base64_decode($xmlDoc->post->voted_count->body);
  674. $obj->blamed_count = base64_decode($xmlDoc->post->blamed_count->body);
  675. $obj->password = base64_decode($xmlDoc->post->password->body);
  676. $obj->user_name = base64_decode($xmlDoc->post->user_name->body);
  677. $obj->nick_name = base64_decode($xmlDoc->post->nick_name->body);
  678. if(!$obj->user_name) $obj->user_name = $obj->nick_name;
  679. $obj->user_id = base64_decode($xmlDoc->post->user_id->body);
  680. $obj->email_address = base64_decode($xmlDoc->post->email->body);
  681. $obj->homepage = base64_decode($xmlDoc->post->homepage->body);
  682. if($obj->homepage && strncasecmp('http://', $obj->homepage, 7) !== 0 && strncasecmp('https://', $obj->homepage, 8) !== 0) $obj->homepage = 'http://'.$obj->homepage;
  683. $obj->tags = base64_decode($xmlDoc->post->tags->body);
  684. $obj->regdate = base64_decode($xmlDoc->post->regdate->body);
  685. $obj->last_update = base64_decode($xmlDoc->post->update->body);
  686. $obj->last_updater = base64_decode($xmlDoc->post->last_updater->body);
  687. if(!$obj->last_update) $obj->last_update = $obj->regdate;
  688. $obj->ipaddress = base64_decode($xmlDoc->post->ipaddress->body);
  689. $obj->list_order = $obj->update_order = $obj->document_srl*-1;
  690. $obj->commentStatus = base64_decode($xmlDoc->post->allow_comment->body)!='N'?'ALLOW':'DENY';
  691. $obj->allow_trackback = base64_decode($xmlDoc->post->allow_trackback->body)!='N'?'Y':'N';
  692. $obj->notify_message = base64_decode($xmlDoc->post->is_notice->body);
  693. // Change content information (attachment)
  694. if(count($files))
  695. {
  696. foreach($files as $key => $val)
  697. {
  698. $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content);
  699. $obj->content = preg_replace('/(["\']?).\/files\/(.+)\/'.preg_quote($key).'([^"\']+)(["\']?)/i','"'.$val.'"',$obj->content);
  700. $obj->content = preg_replace('/(["\']?)files\/(.+)\/'.preg_quote($key).'([^"\']+)(["\']?)/i','"'.$val.'"',$obj->content);
  701. }
  702. }
  703. $output = executeQuery('document.insertDocument', $obj);
  704. if($output->toBool() && $obj->tags)
  705. {
  706. $tag_list = explode(',',$obj->tags);
  707. $tag_count = count($tag_list);
  708. for($i=0;$i<$tag_count;$i++)
  709. {
  710. $args = new stdClass;
  711. $args->tag_srl = getNextSequence();
  712. $args->module_srl = $module_srl;
  713. $args->document_srl = $obj->document_srl;
  714. $args->tag = trim($tag_list[$i]);
  715. $args->regdate = $obj->regdate;
  716. if(!$args->tag) continue;
  717. $output = executeQuery('tag.insertTag', $args);
  718. }
  719. }
  720. // Add extra variables
  721. if(count($extra_vars))
  722. {
  723. foreach($extra_vars as $key => $val)
  724. {
  725. if(!$val->value) continue;
  726. unset($e_args);
  727. $e_args->module_srl = $module_srl;
  728. $e_args->document_srl = $obj->document_srl;
  729. $e_args->var_idx = $val->var_idx;
  730. $e_args->value = $val->value;
  731. $e_args->lang_code = $val->lang_code;
  732. $e_args->eid = $val->eid;
  733. // Create a key for extra vars if not exists (except vars for title and content)
  734. if(!preg_match('/^(title|content)_(.+)$/i',$e_args->eid) && !$extra_keys[$e_args->eid])
  735. {
  736. unset($ek_args);
  737. $ek_args->module_srl = $module_srl;
  738. $ek_args->var_idx = $val->var_idx;
  739. $ek_args->var_name = $val->eid;
  740. $ek_args->var_type = 'text';
  741. $ek_args->var_is_required = 'N';
  742. $ek_args->var_default = '';
  743. $ek_args->eid = $val->eid;
  744. $output = executeQuery('document.insertDocumentExtraKey', $ek_args);
  745. $extra_keys[$ek_args->eid] = true;
  746. }
  747. $output = executeQuery('document.insertDocumentExtraVar', $e_args);
  748. }
  749. }
  750. fclose($fp);
  751. FileHandler::removeFile($target_file);
  752. }
  753. fclose($f);
  754. // Sync category counts
  755. if(count($category_list)) foreach($category_list as $key => $val) $oDocumentController->updateCategoryCount($module_srl, $val->category_srl);
  756. return $idx-1;
  757. }
  758. /**
  759. * Trackbacks
  760. * @param resource $fp
  761. * @param int $module_srl
  762. * @param int $document_srl
  763. * @return int
  764. */
  765. function importTrackbacks($fp, $module_srl, $document_srl)
  766. {
  767. $started = false;
  768. $buff = null;
  769. $cnt = 0;
  770. while(!feof($fp))
  771. {
  772. $str = fgets($fp, 1024);
  773. // If </trackbacks> is, break
  774. if(trim($str) == '</trackbacks>') break;
  775. // If <trackback>, start importing
  776. if(trim($str) == '<trackback>') $started = true;
  777. if($started) $buff .= $str;
  778. // If </trackback>, insert to the DB
  779. if(trim($str) == '</trackback>')
  780. {
  781. $xmlDoc = $this->oXmlParser->parse($buff);
  782. $obj = new stdClass;
  783. $obj->trackback_srl = getNextSequence();
  784. $obj->module_srl = $module_srl;
  785. $obj->document_srl = $document_srl;
  786. $obj->url = base64_decode($xmlDoc->trackback->url->body);
  787. $obj->title = base64_decode($xmlDoc->trackback->title->body);
  788. $obj->blog_name = base64_decode($xmlDoc->trackback->blog_name->body);
  789. $obj->excerpt = base64_decode($xmlDoc->trackback->excerpt->body);
  790. $obj->regdate = base64_decode($xmlDoc->trackback->regdate->body);
  791. $obj->ipaddress = base64_decode($xmlDoc->trackback->ipaddress->body);
  792. $obj->list_order = -1*$obj->trackback_srl;
  793. $output = executeQuery('trackback.insertTrackback', $obj);
  794. if($output->toBool()) $cnt++;
  795. $buff = null;
  796. $started = false;
  797. }
  798. }
  799. return $cnt;
  800. }
  801. /**
  802. * Comments
  803. * @param resource $fp
  804. * @param int $module_srl
  805. * @param int $document_srl
  806. * @return int
  807. */
  808. function importComments($fp, $module_srl, $document_srl)
  809. {
  810. $started = false;
  811. $buff = null;
  812. $cnt = 0;
  813. $sequences = array();
  814. while(!feof($fp))
  815. {
  816. $str = fgets($fp, 1024);
  817. // If </comments> is, break
  818. if(trim($str) == '</comments>') break;
  819. // If <comment> is, start importing
  820. if(trim($str) == '<comment>')
  821. {
  822. $started = true;
  823. $obj = new stdClass;
  824. $obj->comment_srl = getNextSequence();
  825. $files = array();
  826. }
  827. // If <attaches is, start importing attachments
  828. if(substr($str,0,9) == '<attaches')
  829. {
  830. $obj->uploaded_count = $this->importAttaches($fp, $module_srl, $obj->comment_srl, $files);
  831. continue;
  832. }
  833. if($started) $buff .= $str;
  834. // If </comment> is, insert to the DB
  835. if(trim($str) == '</comment>')
  836. {
  837. $xmlDoc = $this->oXmlParser->parse($buff);
  838. $sequence = base64_decode($xmlDoc->comment->sequence->body);
  839. $sequences[$sequence] = $obj->comment_srl;
  840. $parent = base64_decode($xmlDoc->comment->parent->body);
  841. $obj->module_srl = $module_srl;
  842. if($parent) $obj->parent_srl = $sequences[$parent];
  843. else $obj->parent_srl = 0;
  844. $obj->document_srl = $document_srl;
  845. $obj->is_secret = base64_decode($xmlDoc->comment->is_secret->body)=='Y'?'Y':'N';
  846. $obj->notify_message = base64_decode($xmlDoc->comment->notify_message->body)=='Y'?'Y':'N';
  847. $obj->content = base64_decode($xmlDoc->comment->content->body);
  848. $obj->voted_count = base64_decode($xmlDoc->comment->voted_count->body);
  849. $obj->blamed_count = base64_decode($xmlDoc->comment->blamed_count->body);
  850. $obj->password = base64_decode($xmlDoc->comment->password->body);
  851. $obj->user_name =base64_decode($xmlDoc->comment->user_name->body);
  852. $obj->nick_name = base64_decode($xmlDoc->comment->nick_name->body);
  853. if(!$obj->user_name) $obj->user_name = $obj->nick_name;
  854. $obj->user_id = base64_decode($xmlDoc->comment->user_id->body);
  855. $obj->member_srl = 0;
  856. $obj->email_address = base64_decode($xmlDoc->comment->email->body);
  857. $obj->homepage = base64_decode($xmlDoc->comment->homepage->body);
  858. $obj->regdate = base64_decode($xmlDoc->comment->regdate->body);
  859. $obj->last_update = base64_decode($xmlDoc->comment->update->body);
  860. if(!$obj->last_update) $obj->last_update = $obj->regdate;
  861. $obj->ipaddress = base64_decode($xmlDoc->comment->ipaddress->body);
  862. $obj->status = base64_decode($xmlDoc->comment->status->body)==''?'1':base64_decode($xmlDoc->comment->status->body);
  863. $obj->list_order = $obj->comment_srl*-1;
  864. // Change content information (attachment)
  865. if(count($files))
  866. {
  867. foreach($files as $key => $val)
  868. {
  869. $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content);
  870. }
  871. }
  872. // Comment list first
  873. $list_args = new stdClass;
  874. $list_args->comment_srl = $obj->comment_srl;
  875. $list_args->document_srl = $obj->document_srl;
  876. $list_args->module_srl = $obj->module_srl;
  877. $list_args->regdate = $obj->regdate;
  878. // Set data directly if parent comment doesn't exist
  879. if(!$obj->parent_srl)
  880. {
  881. $list_args->head = $list_args->arrange = $obj->comment_srl;
  882. $list_args->depth = 0;
  883. // Get parent_srl if parent comment exists
  884. }
  885. else
  886. {
  887. // Get parent comment infomation
  888. $parent_args->comment_srl = $obj->parent_srl;
  889. $parent_output = executeQuery('comment.getCommentListItem', $parent_args);
  890. // Return if parent comment doesn't exist
  891. if(!$parent_output->toBool() || !$parent_output->data) continue;
  892. $parent = $parent_output->data;
  893. $list_args->head = $parent->head;
  894. $list_args->depth = $parent->depth+1;
  895. if($list_args->depth<2) $list_args->arrange = $obj->comment_srl;
  896. else
  897. {
  898. $list_args->arrange = $parent->arrange;
  899. $output = executeQuery('comment.updateCommentListArrange', $list_args);
  900. if(!$output->toBool()) return $output;
  901. }
  902. }
  903. $output = executeQuery('comment.insertCommentList', $list_args);
  904. if($output->toBool())
  905. {
  906. $output = executeQuery('comment.insertComment', $obj);
  907. if($output->toBool()) $cnt++;
  908. }
  909. $buff = null;
  910. $started = false;
  911. }
  912. }
  913. return $cnt;
  914. }
  915. /**
  916. * Import attachment
  917. * @param resource $fp
  918. * @param int $module_srl
  919. * @param int $upload_target_srl
  920. * @param array $files
  921. * @return int
  922. */
  923. function importAttaches($fp, $module_srl, $upload_target_srl, &$files)
  924. {
  925. $uploaded_count = 0;
  926. $started = false;
  927. $buff = null;
  928. $file_obj = new stdClass;
  929. while(!feof($fp))
  930. {
  931. $str = trim(fgets($fp, 1024));
  932. // If it ends with </attaches>, break
  933. if(trim($str) == '</attaches>') break;
  934. // If it starts with <attach>, collect attachments
  935. if(trim($str) == '<attach>')
  936. {
  937. $file_obj->file_srl = getNextSequence();
  938. $file_obj->upload_target_srl = $upload_target_srl;
  939. $file_obj->module_srl = $module_srl;
  940. $started = true;
  941. $buff = null;
  942. // If it starts with <file>, handle the attachement in xml file
  943. }
  944. else if(trim($str) == '<file>')
  945. {
  946. $file_obj->file = $this->saveTemporaryFile($fp);
  947. continue;
  948. }
  949. if($started) $buff .= $str;
  950. // If it ends with </attach>, handle attachements
  951. if(trim($str) == '</attach>')
  952. {
  953. $xmlDoc = $this->oXmlParser->parse($buff.$str);
  954. $file_obj->source_filename = base64_decode($xmlDoc->attach->filename->body);
  955. $file_obj->download_count = base64_decode($xmlDoc->attach->download_count->body);
  956. if(!$file_obj->file)
  957. {
  958. $url = base64_decode($xmlDoc->attach->url->body);
  959. $path = base64_decode($xmlDoc->attach->path->body);
  960. if($path && file_exists($path)) $file_obj->file = $path;
  961. else
  962. {
  963. $file_obj->file = $this->getTmpFilename();
  964. FileHandler::getRemoteFile($url, $file_obj->file);
  965. }
  966. }
  967. if(file_exists($file_obj->file))
  968. {
  969. // Set upload path by checking if the attachement is an image or other kind of file
  970. if(preg_match("/\.(jpe?g|gif|png|wm[va]|mpe?g|avi|swf|flv|mp[1-4]|as[fx]|wav|midi?|moo?v|qt|r[am]{1,2}|m4v)$/i", $file_obj->source_filename))
  971. {
  972. // Immediately remove the direct file if it has any kind of extensions for hacking
  973. $file_obj->source_filename = preg_replace('/\.(php|phtm|phar|html?|cgi|pl|exe|jsp|asp|inc)/i', '$0-x', $file_obj->source_filename);
  974. $file_obj->source_filename = str_replace(array('<', '>'), array('%3C', '%3E'), $file_obj->source_filename);
  975. $path = sprintf("./files/attach/images/%s/%s", $module_srl, getNumberingPath($upload_target_srl, 3));
  976. $ext = substr(strrchr($file_obj->source_filename,'.'),1);
  977. $_filename = md5(crypt(rand(1000000, 900000), rand(0, 100))).'.'.$ext;
  978. $filename = $path.$_filename;
  979. $idx = 1;
  980. while(file_exists($filename))
  981. {
  982. $filename = $path.preg_replace('/\.([a-z0-9]+)$/i','_'.$idx.'.$1', $_filename);
  983. $idx++;
  984. }
  985. $file_obj->direct_download = 'Y';
  986. }
  987. else
  988. {
  989. $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3));
  990. $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100)));
  991. $file_obj->direct_download = 'N';
  992. }
  993. // Create a directory
  994. if(!FileHandler::makeDir($path)) continue;
  995. if(strncmp('./files/cache/importer/', $file_obj->file, 23) === 0)
  996. {
  997. FileHandler::rename($file_obj->file, $filename);
  998. }
  999. else
  1000. {
  1001. copy($file_obj->file, $filename);
  1002. }
  1003. // Insert the file to the DB
  1004. unset($file_obj->file);
  1005. if(file_exists($filename))
  1006. {
  1007. $file_obj->uploaded_filename = $filename;
  1008. $file_obj->file_size = filesize($filename);
  1009. $file_obj->comment = NULL;
  1010. $file_obj->member_srl = 0;
  1011. $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999)));
  1012. $file_obj->isvalid = 'Y';
  1013. $output = executeQuery('file.insertFile', $file_obj);
  1014. if($output->toBool())
  1015. {
  1016. $uploaded_count++;
  1017. $tmp_obj = null;
  1018. $tmp_obj->source_filename = $file_obj->source_filename;
  1019. if($file_obj->direct_download == 'Y') $files[$file_obj->source_filename] = $file_obj->uploaded_filename;
  1020. else $files[$file_obj->source_filename] = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid);
  1021. }
  1022. }
  1023. }
  1024. }
  1025. }
  1026. return $uploaded_count;
  1027. }
  1028. /**
  1029. * Return a filename to temporarily use
  1030. * @return string
  1031. */
  1032. function getTmpFilename()
  1033. {
  1034. $path = "./files/cache/importer";
  1035. FileHandler::makeDir($path);
  1036. $filename = sprintf("%s/%d", $path, rand(11111111,99999999));
  1037. if(file_exists($filename)) $filename .= rand(111,999);
  1038. return $filename;
  1039. }
  1040. /**
  1041. * Read buff until key value comes out from a specific file point
  1042. * @param resource $fp
  1043. * @return string
  1044. */
  1045. function saveTemporaryFile($fp)
  1046. {
  1047. $temp_filename = $this->getTmpFilename();
  1048. $f = fopen($temp_filename, "w");
  1049. $buff = '';
  1050. while(!feof($fp))
  1051. {
  1052. $str = trim(fgets($fp, 1024));
  1053. if(trim($str) == '</file>') break;
  1054. $buff .= $str;
  1055. if(substr($buff,-7)=='</buff>')
  1056. {
  1057. fwrite($f, base64_decode(substr($buff, 6, -7)));
  1058. $buff = '';
  1059. }
  1060. }
  1061. fclose($f);
  1062. return $temp_filename;
  1063. }
  1064. /**
  1065. * Set extra variables
  1066. * @param resource $fp
  1067. * @return array
  1068. */
  1069. function importExtraVars($fp)
  1070. {
  1071. $buff = null;
  1072. while(!feof($fp))
  1073. {
  1074. $buff .= $str = trim(fgets($fp, 1024));
  1075. if(trim($str) == '</extra_vars>') break;
  1076. }
  1077. if(!$buff) return array();
  1078. $buff = '<extra_vars>'.$buff;
  1079. $oXmlParser = new XmlParser();
  1080. $xmlDoc = $this->oXmlParser->parse($buff);
  1081. if(!count($xmlDoc->extra_vars->key)) return array();
  1082. $index = 1;
  1083. foreach($xmlDoc->extra_vars->key as $k => $v)
  1084. {
  1085. unset($vobj);
  1086. if($v->var_idx)
  1087. {
  1088. $vobj->var_idx = base64_decode($v->var_idx->body);
  1089. $vobj->lang_code = base64_decode($v->lang_code->body);
  1090. $vobj->value = base64_decode($v->value->body);
  1091. $vobj->eid = base64_decode($v->eid->body);
  1092. }
  1093. else if($v->body)
  1094. {
  1095. $vobj->var_idx = $index;
  1096. $vobj->lang_code = Context::getLangType();
  1097. $vobj->value = base64_decode($v->body);
  1098. $vobj->eid = 'extra_vars'.$index;
  1099. }
  1100. $extra_vars["extra_vars".$index] = $vobj;
  1101. $index++;
  1102. }
  1103. return $extra_vars;
  1104. }
  1105. }
  1106. /* End of file importer.admin.controller.php */
  1107. /* Location: ./modules/importer/importer.admin.controller.php */