zentaobiz.php 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  1. <?php
  2. /**
  3. * 创建自定义关联关系。
  4. * Create relation.
  5. *
  6. * @param array $relations
  7. * @access public
  8. * @return array
  9. */
  10. public function createRelation($relations)
  11. {
  12. if(empty($relations['zentaoLinkType'])) return $relations;
  13. $this->loadModel('custom');
  14. $issueLink = $this->getJiraData($this->session->jiraMethod, 'issuelinktype');
  15. $maxKey = $this->dao->select('max(cast(`key` as SIGNED)) as maxKey')->from(TABLE_LANG)->where('section')->eq('relationList')->andWhere('module')->eq('custom')->fetch('maxKey');
  16. $maxKey = $maxKey ? $maxKey : 1;
  17. foreach($relations['zentaoLinkType'] as $jiraCode => $zentaoCode)
  18. {
  19. if($zentaoCode != 'add_relation') continue;
  20. $maxKey += 1;
  21. $relation = new stdclass();
  22. $relation->relation = $issueLink[$jiraCode]->inward;
  23. $relation->relativeRelation = $issueLink[$jiraCode]->outward;
  24. $this->custom->setItem("all.custom.relationList.{$maxKey}.0", json_encode($relation));
  25. $relations['zentaoLinkType'][$jiraCode] = $maxKey;
  26. }
  27. return $relations;
  28. }
  29. /**
  30. * 更新对象关联关系。
  31. * Update object relation.
  32. *
  33. * @param array $issueLinkTypeList
  34. * @param array $dataList
  35. * @param array $issueList
  36. * @access public
  37. * @return bool
  38. */
  39. public function updateObjectRelation($issueLinkTypeList = array(), $dataList = array(), $issueList = array())
  40. {
  41. if(empty($issueLinkTypeList) || empty($dataList) || empty($issueList)) return false;
  42. $linkRelation = $this->dao->dbh($this->dbh)->select('*')->from(JIRA_TMPRELATION)->where('AType')->eq('jissuelink')->fetchAll('AID');
  43. foreach($dataList as $data)
  44. {
  45. if(!empty($linkRelation[$data->id])) continue;
  46. $issueRelation = zget($issueLinkTypeList, $data->linktype, '');
  47. if(in_array($issueRelation, array('subTaskLink', 'subStoryLink'))) $issueRelation = 'subdivideinto';
  48. if(in_array($issueRelation, array('duplicate', 'relates'))) $issueRelation = '1';
  49. $relation = new stdClass();
  50. $relation->relation = $issueRelation;
  51. $relation->AID = zget(zget($issueList, $data->source, array()), 'BID', 0);
  52. $relation->AType = preg_replace('/^z/', '', zget(zget($issueList, $data->source, array()), 'BType', 'z'), 1);
  53. $relation->BID = zget(zget($issueList, $data->destination, array()), 'BID', 0);
  54. $relation->BType = preg_replace('/^z/', '', zget(zget($issueList, $data->destination, array()), 'BType', 'z'), 1);
  55. $relation->product = 0;
  56. if(!in_array($relation->AType, array_keys($this->lang->convert->jira->zentaoObjectList))) $relation->AType = 'workflow_' . $relation->AType;
  57. if(!in_array($relation->BType, array_keys($this->lang->convert->jira->zentaoObjectList))) $relation->BType = 'workflow_' . $relation->BType;
  58. if(empty($relation->relation) || empty($relation->AID) || empty($relation->AType) || empty($relation->BID) || empty($relation->BType)) continue;
  59. $this->dao->replace(TABLE_RELATION)->data($relation)->exec();
  60. $relationID = $this->dao->dbh($this->dbh)->lastInsertID();
  61. $relation = array();
  62. $relation['AType'] = 'jissuelink';
  63. $relation['BType'] = 'zrelation';
  64. $relation['AID'] = $data->id;
  65. $relation['BID'] = $relationID;
  66. $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($relation)->exec();
  67. }
  68. return true;
  69. }
  70. /**
  71. * 创建自定义工作流数据。
  72. * Create flow data.
  73. *
  74. * @param int $productID
  75. * @param int $projectID
  76. * @param string $issueType
  77. * @param object $data
  78. * @param array $relations
  79. * @param array $customFields
  80. * @param array $workflows
  81. * @access public
  82. * @return bool
  83. */
  84. public function createFlowData($productID, $projectID, $issueType, $data, $relations, $customFields, $workflows)
  85. {
  86. if(empty($workflows[$issueType])) return false;
  87. $flow = new stdclass();
  88. $flow = $this->processBuildinFieldData($issueType, $data, $flow, $relations, $customFields, true);
  89. $flow->product = $productID;
  90. $flow->project = $projectID;
  91. $flow->status = $this->convertStatus('flow', $data->issuestatus, $data->issuetype, $relations);
  92. $flow->createdBy = $this->getJiraAccount(isset($data->creator) ? $data->creator : '');
  93. $flow->createdDate = isset($data->created) ? $this->formatDatetime(substr($data->created, 0, 19)) : null;
  94. $flow->assignedTo = $flow->status == 'closed' ? 'closed' : $this->getJiraAccount(isset($data->assignee) ? $data->assignee : '');
  95. $this->dao->dbh($this->dbh)->insert($workflows[$issueType])->data($flow)->exec();
  96. $flowID = $this->dao->dbh($this->dbh)->lastInsertID();
  97. /* Create opened action from openedDate. */
  98. $action = new stdclass();
  99. $action->objectType = $issueType;
  100. $action->objectID = $flowID;
  101. $action->actor = $flow->createdBy;
  102. $action->action = 'create';
  103. $action->date = $flow->createdDate;
  104. $this->dao->dbh($this->dbh)->insert(TABLE_ACTION)->data($action)->exec();
  105. $flowRelation['AType'] = 'jissue';
  106. $flowRelation['BType'] = 'z' . $issueType;
  107. $flowRelation['AID'] = $data->id;
  108. $flowRelation['BID'] = $flowID;
  109. $flowRelation['extra'] = 'issue';
  110. $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($flowRelation)->exec();
  111. $issueRelation['AType'] = 'jissueid';
  112. $issueRelation['BType'] = 'zissuetype';
  113. $issueRelation['AID'] = $data->id;
  114. $issueRelation['extra'] = $issueType;
  115. $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec();
  116. return true;
  117. }
  118. /**
  119. * 获取confluence用户。
  120. * Get confluence account.
  121. *
  122. * @param string $userKey
  123. * @access public
  124. * @return string
  125. */
  126. public function getConfluenceAccount($userKey)
  127. {
  128. if(empty($userKey) || empty($_SESSION['confluenceUsers'])) return '';
  129. $confluenceUsers = json_decode($this->session->confluenceUsers, true);
  130. return zget($confluenceUsers, $userKey);
  131. }
  132. /**
  133. * 处理Confluence用户名为禅道格式。
  134. * Process confluence user.
  135. *
  136. * @param string $confluenceAccount
  137. * @param string $confluenceEmail
  138. * @param int $i
  139. * @access public
  140. * @return string
  141. */
  142. public function processConfluenceUser($confluenceAccount, $confluenceEmail, $i)
  143. {
  144. $userConfig = $this->session->confluenceUser;
  145. $account = substr($confluenceAccount, 0, 30);
  146. if($userConfig['mode'] == 'email')
  147. {
  148. if(strpos($confluenceEmail, '@') !== false)
  149. {
  150. $account = substr(substr($confluenceEmail, 0, strpos($confluenceEmail, '@')), 0, 30);
  151. }
  152. else
  153. {
  154. $account = 'zentao' . $i;
  155. }
  156. }
  157. return $account;
  158. }
  159. /**
  160. * 导入user数据。
  161. * Import confluence user.
  162. *
  163. * @param array $dataList
  164. * @access public
  165. * @return bool
  166. */
  167. public function importConfluenceUser($dataList)
  168. {
  169. $localUsers = $this->dao->dbh($this->dbh)->select('account')->from(TABLE_USER)->where('deleted')->eq('0')->fetchPairs();
  170. $userEmail = $this->dao->dbh($this->dbh)->select('email,account')->from(TABLE_USER)->where('deleted')->eq('0')->andWhere('email')->ne('')->fetchPairs();
  171. $userRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cuser')->fetchPairs();
  172. $userConfig = $this->session->confluenceUser;
  173. $i = 1;
  174. foreach($dataList as $data)
  175. {
  176. $accountKey = !empty($data->accountId) ? $data->accountId : zget($data, 'userKey', '');
  177. $accountID = !empty($data->accountId) ? $data->accountId : zget($data, 'username', '');
  178. if(!empty($userRelation[$accountKey])) continue;
  179. if(!isset($data->email)) $data->email = '';
  180. $user = new stdclass();
  181. $user->account = $this->processConfluenceUser($accountID, $data->email, $i);
  182. if(!isset($localUsers[$user->account]))
  183. {
  184. $user->realname = isset($data->publicName) ? $data->publicName : zget($data, 'displayName', '');
  185. $user->password = $userConfig['password'];
  186. $user->email = isset($data->email) ? $data->email : '';
  187. $user->gender = 'm';
  188. $user->type = 'inside';
  189. $user->join = helper::now();
  190. $this->dao->dbh($this->dbh)->replace(TABLE_USER)->data($user, 'group')->exec();
  191. if(!dao::isError() && !empty($userConfig['group']))
  192. {
  193. $group = new stdclass();
  194. $group->account = $user->account;
  195. $group->group = $userConfig['group'];
  196. $group->project = '';
  197. $this->dao->dbh($this->dbh)->replace(TABLE_USERGROUP)->data($group)->exec();
  198. }
  199. }
  200. $relation['AType'] = 'cuser';
  201. $relation['BType'] = 'zuser';
  202. $relation['AID'] = $accountKey;
  203. $relation['BID'] = $user->account;
  204. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($relation)->exec();
  205. $userRelation[$accountKey] = $user->account;
  206. $i ++;
  207. }
  208. $this->session->set('confluenceUsers', json_encode($userRelation));
  209. return true;
  210. }
  211. /**
  212. * 创建导入所需的我的默认空间。
  213. * Create default my space.
  214. *
  215. * @param object $space
  216. * @param array $spaceRelation
  217. * @access public
  218. * @return array
  219. */
  220. public function createDefaultMineSpace($space, $spaceRelation)
  221. {
  222. $addedBy = $this->app->user->account;
  223. if(!empty($space->history->createdBy->accountId)) $addedBy = $this->getConfluenceAccount($space->history->createdBy->accountId);
  224. if(!empty($space->creator->userKey)) $addedBy = $this->getConfluenceAccount($space->creator->userKey);
  225. /* 我的空间下创建默认空间。 */
  226. $docSpace = new stdclass();
  227. $docSpace->name = $this->lang->convert->confluence->defaultSpace;
  228. $docSpace->parent = '0';
  229. $docSpace->type = 'mine';
  230. $docSpace->acl = 'open';
  231. $docSpace->vision = $this->config->vision;
  232. $docSpace->addedDate = helper::now();
  233. $docSpace->addedBy = $addedBy;
  234. if(!empty($spaceRelation[$docSpace->addedBy])) return $spaceRelation;
  235. $mineSpaceID = $this->loadModel('doc')->doInsertLib($docSpace);
  236. $this->loadModel('action')->create('docspace', $mineSpaceID, 'created');
  237. $relation['AType'] = 'cspace';
  238. $relation['BType'] = 'zspace';
  239. $relation['AID'] = $space->id;
  240. $relation['BID'] = $mineSpaceID;
  241. $relation['extra'] = $docSpace->addedBy;
  242. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($relation)->exec();
  243. $spaceRelation[$docSpace->addedBy] = $mineSpaceID;
  244. return $spaceRelation;
  245. }
  246. /**
  247. * 创建导入所需的默认团队空间。
  248. * Create default custom space.
  249. *
  250. * @access public
  251. * @return int
  252. */
  253. public function createDefaultCustomSpace()
  254. {
  255. $spaceID = $this->dao->dbh($this->dbh)->select('BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cspace')->andWhere('BType')->eq('zspace')->andWhere('extra')->eq('custom')->andWhere('AID') ->eq('0')->fetch('BID');
  256. if($spaceID) return $spaceID;
  257. /* 团队空间下创建默认空间。 */
  258. $space = new stdclass();
  259. $space->name = $this->lang->convert->confluence->defaultSpace;
  260. $space->parent = '0';
  261. $space->type = 'custom';
  262. $space->acl = 'open';
  263. $space->vision = $this->config->vision;
  264. $space->addedDate = helper::now();
  265. $space->addedBy = $this->app->user->account;
  266. $customSpaceID = $this->doc->doInsertLib($space);
  267. $this->loadModel('action')->create('docspace', $customSpaceID, 'created');
  268. $relation['AType'] = 'cspace';
  269. $relation['BType'] = 'zspace';
  270. $relation['AID'] = '0';
  271. $relation['BID'] = $customSpaceID;
  272. $relation['extra'] = 'custom';
  273. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($relation)->exec();
  274. return $customSpaceID;
  275. }
  276. /**
  277. * 导入Confluence空间。
  278. * Import confluence space.
  279. *
  280. * @param array $dataList
  281. * @access public
  282. * @return bool
  283. */
  284. public function importConfluenceSpace($dataList)
  285. {
  286. $this->loadModel('doc');
  287. $this->loadModel('action');
  288. $customSpaceID = $this->createDefaultCustomSpace();
  289. $confluenceRelation = $this->session->confluenceRelation;
  290. $confluenceRelation = $confluenceRelation ? json_decode($confluenceRelation, true) : array();
  291. $spaceRelation = $this->dao->dbh($this->dbh)->select('extra,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cspace')->andWhere('BType')->eq('zspace')->andWhere('AID')->ne('0')->fetchPairs();
  292. $libRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cspace')->andWhere('Btype')->eq('zlib')->fetchPairs();
  293. foreach($dataList as $space)
  294. {
  295. if(!empty($libRelation[$space->id])) continue;
  296. $spaceType = $this->checkConfluenceSpacePriv($space);
  297. $spaceType = !empty($confluenceRelation['zentaoSpace'][$space->id]) ? $confluenceRelation['zentaoSpace'][$space->id] : $spaceType;
  298. if($spaceType == 'mine') $spaceRelation = $this->createDefaultMineSpace($space, $spaceRelation);
  299. $lib = new stdclass();
  300. $lib->name = mb_substr($space->name, 0, 50) . ($space->status == 'archived' ? "({$this->lang->convert->confluence->archived})" : '');
  301. $lib->spaceName = '';
  302. $lib->parent = '0';
  303. $lib->baseUrl = '';
  304. $lib->acl = 'private';
  305. $lib->type = $spaceType;
  306. $lib->product = $lib->type == 'product' && !empty($confluenceRelation['zentaoDocLib'][$space->id]) ? $confluenceRelation['zentaoDocLib'][$space->id] : '0';
  307. $lib->project = $lib->type == 'project' && !empty($confluenceRelation['zentaoDocLib'][$space->id]) ? $confluenceRelation['zentaoDocLib'][$space->id] : '0';
  308. $lib->execution = '0';
  309. $lib->groups = '';
  310. $lib->users = '';
  311. $lib->archived = $space->status == 'archived' ? '1' : '0';
  312. $lib->vision = $this->config->vision;
  313. $lib->orderBy = 'id_asc';
  314. $lib->addedBy = $this->app->user->account;
  315. $lib->addedDate = helper::now();
  316. if(!empty($space->history->createdBy->accountId)) $lib->addedBy = $this->getConfluenceAccount($space->history->createdBy->accountId);
  317. if(!empty($space->creator->userKey)) $lib->addedBy = $this->getConfluenceAccount($space->creator->userKey);
  318. if(!empty($space->history->createdDate)) $lib->addedDate = date('Y-m-d H:i:s', strtotime($space->history->createdDate));
  319. if(!empty($space->creationDate)) $lib->addedDate = date('Y-m-d H:i:s', strtotime($space->creationDate));
  320. if($lib->type == 'mine') $lib->parent = $spaceRelation[$lib->addedBy];
  321. if($lib->type == 'custom') $lib->parent = $customSpaceID;
  322. if($lib->type != 'mine') $lib->users = $this->getConfluenceSpaceUsers($space);
  323. $libID = $this->doc->createLib($lib);
  324. $this->action->create('docLib', $libID, 'Created');
  325. $tmpRelation['AType'] = 'cspace';
  326. $tmpRelation['BType'] = 'zlib';
  327. $tmpRelation['AID'] = $space->id;
  328. $tmpRelation['BID'] = $libID;
  329. $tmpRelation['extra'] = !empty($space->homepage->id) ? $space->homepage->id : '';
  330. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  331. }
  332. return true;
  333. }
  334. /**
  335. * 创建Confluence文档内容,便于存储到 zt_doc 表 rawContent 字段。
  336. * Create confluence doc content, for store to zt_doc rawContent field.
  337. *
  338. * @param string $content
  339. * @access public
  340. * @return string
  341. */
  342. public function createConfluenceDocContent($content)
  343. {
  344. return json_encode(array('$migrate' => 'confluence', '$data' => $content));
  345. }
  346. /**
  347. * 导入Confluence文件夹。
  348. * Import confluence folder.
  349. *
  350. * @param array $dataList
  351. * @access public
  352. * @return bool
  353. */
  354. public function importConfluenceFolder($dataList)
  355. {
  356. $libList = $this->dao->dbh($this->dbh)->select('id,parent,type,project,product,execution,archived,name')->from(TABLE_DOCLIB)->fetchAll('id');
  357. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  358. foreach($dataList as $libID => $folderList)
  359. {
  360. $this->loadModel('action');
  361. $archived = zget($libList[$libID], 'archived', 0);
  362. $space = $libList[$libList[$libID]->parent];
  363. foreach($folderList as $folder)
  364. {
  365. if(!empty($docRelation[$folder->id]))
  366. {
  367. $this->importConfluenceChild($libID, 0, (int)$folder->id, $docRelation[$folder->id], 2, $libList, $docRelation);
  368. continue;
  369. }
  370. $doc = new stdclass();
  371. $doc->title = mb_substr($folder->title, 0, 50) . ($archived ? "({$this->lang->convert->confluence->archived})" : '');
  372. $doc->version = '1';
  373. $doc->lib = $libID;
  374. $doc->product = $doc->lib ? zget($libList[$doc->lib], 'product', '0') : '0';
  375. $doc->project = $doc->lib ? zget($libList[$doc->lib], 'project', '0') : '0';
  376. $doc->execution = $doc->lib ? zget($libList[$doc->lib], 'execution', '0') : '0';
  377. $doc->status = 'normal';
  378. $doc->type = 'chapter';
  379. $doc->path = '';
  380. $doc->grade = '1';
  381. $doc->order = 0;
  382. $doc->editedBy = !empty($folder->version->by->accountId) ? $this->getConfluenceAccount($folder->version->by->accountId) : $this->app->user->account;
  383. $doc->editedDate = !empty($folder->version->when) ? date('Y-m-d H:i:s', strtotime($folder->version->when)) : helper::now();
  384. $doc->addedBy = !empty($folder->history->createdBy->accountId) ? $this->getConfluenceAccount($folder->history->createdBy->accountId) : $doc->editedBy;
  385. $doc->addedDate = !empty($folder->history->createdDate) ? date('Y-m-d H:i:s', strtotime($folder->history->createdDate)) : $doc->editedDate;
  386. $doc->acl = $space->type == 'mine' ? 'private' : '';
  387. if($space->type != 'mine') $doc = $this->setDocPrivUsers($folder, $doc);
  388. $this->dao->insert(TABLE_DOC)->data($doc)->exec();
  389. $docID = $this->dao->lastInsertID();
  390. $this->action->create('doc', $docID, 'Created');
  391. $tmpRelation['AType'] = "cfolder";
  392. $tmpRelation['BType'] = 'zdoc';
  393. $tmpRelation['AID'] = $folder->id;
  394. $tmpRelation['BID'] = $docID;
  395. $tmpRelation['extra'] = $doc->grade;
  396. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  397. $docContent = new stdclass();
  398. $docContent->title = $doc->title;
  399. $docContent->content = !empty($folder->body->view->value) ? $folder->body->view->value : '';
  400. $docContent->type = 'doc';
  401. $docContent->rawContent = $this->createConfluenceDocContent(!empty($folder->body->storage->value) ? $folder->body->storage->value : '');
  402. $docContent->digest = !empty($folder->version->message) ? $folder->version->message : '';
  403. $docContent->version = $doc->version;
  404. $docContent->doc = $docID;
  405. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  406. $this->importConfluenceChild($libID, 0, (int)$folder->id, $docID, 2, $libList, $docRelation);
  407. }
  408. }
  409. return true;
  410. }
  411. /**
  412. * 导入Confluence页面。
  413. * Import confluence page.
  414. *
  415. * @param array $dataList
  416. * @access public
  417. * @return bool
  418. * @param string $module
  419. */
  420. public function importConfluencePage($dataList, $module)
  421. {
  422. $this->loadModel('action');
  423. $libList = $this->dao->dbh($this->dbh)->select('id,parent,type,project,product,execution,archived,name')->from(TABLE_DOCLIB)->fetchAll('id');
  424. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  425. foreach($dataList as $libID => $pageList)
  426. {
  427. $order = 0;
  428. $archived = zget($libList[$libID], 'archived', 0);
  429. $space = $libList[$libList[$libID]->parent];
  430. foreach($pageList as $page)
  431. {
  432. if(!empty($docRelation[$page->id]))
  433. {
  434. $this->importConfluenceChild($libID, 0, (int)$page->id, $docRelation[$page->id], 2, $libList, $docRelation);
  435. continue;
  436. }
  437. $order = $order + 10;
  438. $doc = new stdclass();
  439. $doc->title = $page->title . ($archived ? "({$this->lang->convert->confluence->archived})" : '');
  440. $doc->version = !empty($page->version->number) ? $page->version->number : '1';
  441. $doc->module = '0';
  442. $doc->lib = $libID;
  443. $doc->product = $doc->lib ? zget($libList[$doc->lib], 'product', '0') : '0';
  444. $doc->project = $doc->lib ? zget($libList[$doc->lib], 'project', '0') : '0';
  445. $doc->execution = $doc->lib ? zget($libList[$doc->lib], 'execution', '0') : '0';
  446. $doc->status = 'normal';
  447. $doc->type = 'text';
  448. $doc->parent = '0';
  449. $doc->path = '';
  450. $doc->grade = '0';
  451. $doc->order = $order;
  452. $doc->acl = $space->type == 'mine' ? 'private' : '';
  453. $doc->addedBy = $this->app->user->account;
  454. $doc->addedDate = !empty($page->history->createdDate) ? date('Y-m-d H:i:s', strtotime($page->history->createdDate)) : helper::now();
  455. $doc->editedBy = $this->app->user->account;
  456. $doc->editedDate = !empty($page->version->when) ? date('Y-m-d H:i:s', strtotime($page->version->when)) : helper::now();
  457. if(!empty($page->history->createdBy->accountId)) $doc->addedBy = $this->getConfluenceAccount($page->history->createdBy->accountId);
  458. if(!empty($page->history->createdBy->userKey)) $doc->addedBy = $this->getConfluenceAccount($page->history->createdBy->userKey);
  459. if(!empty($page->version->by->accountId)) $doc->editedBy = $this->getConfluenceAccount($page->version->by->accountId);
  460. if(!empty($page->version->by->userKey)) $doc->editedBy = $this->getConfluenceAccount($page->version->by->userKey);
  461. if($space->type != 'mine') $doc = $this->setDocPrivUsers($page, $doc);
  462. if(!$doc->title) $doc->title = $this->lang->convert->confluence->undefined;
  463. $this->dao->insert(TABLE_DOC)->data($doc)->exec();
  464. $docID = $this->dao->lastInsertID();
  465. $this->action->create('doc', $docID, 'Created');
  466. $tmpRelation['AType'] = "c$module";
  467. $tmpRelation['BType'] = 'zdoc';
  468. $tmpRelation['AID'] = $page->id;
  469. $tmpRelation['BID'] = $docID;
  470. $tmpRelation['extra'] = $doc->grade;
  471. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  472. $docContent = new stdclass();
  473. $docContent->title = $doc->title ? $doc->title : $this->lang->convert->confluence->undefined;
  474. $docContent->content = !empty($page->body->view->value) ? $page->body->view->value : '';
  475. $docContent->type = 'doc';
  476. $docContent->rawContent = $this->createConfluenceDocContent(!empty($page->body->storage->value) ? $page->body->storage->value : '');
  477. $docContent->digest = !empty($page->version->message) ? $page->version->message : '';
  478. $docContent->version = $doc->version;
  479. $docContent->doc = $docID;
  480. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  481. $docContentID = $this->dao->lastInsertID();
  482. $tmpRelation['AType'] = "c$module";
  483. $tmpRelation['BType'] = 'zdoccontent';
  484. $tmpRelation['AID'] = $page->id;
  485. $tmpRelation['BID'] = $docContentID;
  486. $tmpRelation['extra'] = $docContent->version;
  487. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  488. $this->importConfluenceChild($libID, 0, (int)$page->id, $docID, $doc->grade + 1, $libList, $docRelation);
  489. }
  490. }
  491. return true;
  492. }
  493. /**
  494. * 导入Confluence子元素。
  495. * Import confluence child.
  496. *
  497. * @param int $libID
  498. * @param int $moduleID
  499. * @param int $objectID
  500. * @param int $parent
  501. * @param int $grade
  502. * @param array $libList
  503. * @param int $start
  504. * @access public
  505. * @return bool
  506. * @param mixed[] $docRelation
  507. */
  508. public function importConfluenceChild($libID, $moduleID, $objectID, $parent = 0, $grade = 0, $libList = array(), $docRelation = array(), $start = 0)
  509. {
  510. $this->loadModel('action');
  511. if(empty($_SESSION['confluenceApi'])) return false;
  512. $confluenceApi = json_decode($this->session->confluenceApi, true);
  513. if(empty($confluenceApi['domain'])) return false;
  514. $archived = zget($libList[$libID], 'archived', 0);
  515. $space = $libList[$libList[$libID]->parent];
  516. foreach(array('folder', 'page', 'embed', 'database', 'whiteboard') as $objectType)
  517. {
  518. $token = base64_encode("{$confluenceApi['admin']}:{$confluenceApi['token']}");
  519. $url = $confluenceApi['domain'] . "/rest/api/content/{$objectID}/child/{$objectType}?start={$start}&limit=500&expand=body.storage,body.view,version,history,restrictions.read.restrictions.user,restrictions.update.restrictions.user,restrictions.read.restrictions.group,restrictions.update.restrictions.group";
  520. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  521. if(!empty($result->results))
  522. {
  523. $order = 0;
  524. foreach($result->results as $object)
  525. {
  526. if(!empty($docRelation[$object->id]))
  527. {
  528. $this->importConfluenceChild($libID, $moduleID, (int)$object->id, $docRelation[$object->id], $grade + 1, $libList, $docRelation);
  529. continue;
  530. }
  531. $order = $order + 10;
  532. $doc = new stdclass();
  533. $doc->title = $object->title . ($archived ? "({$this->lang->convert->confluence->archived})" : '');
  534. $doc->version = !empty($object->version->number) ? $object->version->number : '1';
  535. $doc->module = $moduleID;
  536. $doc->lib = $libID;
  537. $doc->product = $doc->lib ? zget($libList[$doc->lib], 'product', '0') : '0';
  538. $doc->project = $doc->lib ? zget($libList[$doc->lib], 'project', '0') : '0';
  539. $doc->execution = $doc->lib ? zget($libList[$doc->lib], 'execution', '0') : '0';
  540. $doc->status = 'normal';
  541. $doc->type = $objectType == 'folder' ? 'chapter' : 'text';
  542. $doc->parent = $parent;
  543. $doc->path = '';
  544. $doc->grade = $grade;
  545. $doc->order = $order;
  546. $doc->acl = $space->type == 'mine' ? 'private' : '';
  547. $doc->addedBy = $this->app->user->account;
  548. $doc->addedDate = !empty($object->history->createdDate) ? date('Y-m-d H:i:s', strtotime($object->history->createdDate)) : helper::now();
  549. $doc->editedBy = $this->app->user->account;
  550. $doc->editedDate = !empty($object->version->when) ? date('Y-m-d H:i:s', strtotime($object->version->when)) : helper::now();
  551. if(!empty($object->history->createdBy->accountId)) $doc->addedBy = $this->getConfluenceAccount($object->history->createdBy->accountId);
  552. if(!empty($object->history->createdBy->userKey)) $doc->addedBy = $this->getConfluenceAccount($object->history->createdBy->userKey);
  553. if(!empty($object->version->by->accountId)) $doc->editedBy = $this->getConfluenceAccount($object->version->by->accountId);
  554. if(!empty($object->version->by->userKey)) $doc->editedBy = $this->getConfluenceAccount($object->version->by->userKey);
  555. if($space->type != 'mine') $doc = $this->setDocPrivUsers($object, $doc);
  556. if(!$doc->title) $doc->title = $this->lang->convert->confluence->undefined;
  557. $this->dao->insert(TABLE_DOC)->data($doc)->exec();
  558. $docID = $this->dao->lastInsertID();
  559. $this->action->create('doc', $docID, 'Created');
  560. $tmpRelation['AType'] = "c$objectType";
  561. $tmpRelation['BType'] = "zdoc";
  562. $tmpRelation['AID'] = $object->id;
  563. $tmpRelation['BID'] = $docID;
  564. $tmpRelation['extra'] = $doc->grade;
  565. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  566. if($doc->type == 'text')
  567. {
  568. $docContent = new stdclass();
  569. $docContent->title = $doc->title ? $doc->title : $this->lang->convert->confluence->undefined;
  570. $docContent->content = !empty($object->body->view->value) ? $object->body->view->value : '';
  571. $docContent->type = 'doc';
  572. $docContent->rawContent = json_encode(array('$migrate' => 'confluence', '$data' => !empty($object->body->storage->value) ? $object->body->storage->value : ''));
  573. $docContent->digest = !empty($object->version->message) ? $object->version->message : '';
  574. $docContent->version = $doc->version;
  575. $docContent->doc = $docID;
  576. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  577. $docContentID = $this->dao->lastInsertID();
  578. $tmpRelation['AType'] = "c$objectType";
  579. $tmpRelation['BType'] = 'zdoccontent';
  580. $tmpRelation['AID'] = $object->id;
  581. $tmpRelation['BID'] = $docContentID;
  582. $tmpRelation['extra'] = $docContent->version;
  583. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  584. }
  585. $this->importConfluenceChild($libID, $moduleID, (int)$object->id, $docID, $doc->grade + 1, $libList, $docRelation);
  586. }
  587. if($result->size == $result->limit) $this->importConfluenceChild($libID, $moduleID, $objectID, $parent, $grade, $libList, $docRelation, $result->start + $result->limit);
  588. }
  589. }
  590. return true;
  591. }
  592. /**
  593. * 创建Confluence博文所需的年份目录。
  594. * Create confluence blog dir
  595. *
  596. * @param object $blogPost
  597. * @param array $blogDirList
  598. * @param array $spaceRelation
  599. * @param bool $archived
  600. * @access public
  601. * @return array
  602. */
  603. public function createConfluenceBlogDir($blogPost, $blogDirList, $spaceRelation, $archived = false)
  604. {
  605. if(empty($blogDirList[$blogPost->space->id]['module']))
  606. {
  607. $module = new stdclass();
  608. $module->root = $spaceRelation[$blogPost->space->id];
  609. $module->type = 'doc';
  610. $module->parent = '0';
  611. $module->name = $this->lang->convert->confluence->objectList['blogpost'] . ($archived ? "({$this->lang->convert->confluence->archived})" : '');
  612. $module->branch = '0';
  613. $module->short = '';
  614. $module->order = '999';
  615. $module->grade = '1';
  616. $this->dao->insert(TABLE_MODULE)->data($module)->exec();
  617. $moduleID = $this->dao->lastInsertID();
  618. $tmpRelation['AType'] = 'cblogpost';
  619. $tmpRelation['BType'] = 'zmodule';
  620. $tmpRelation['AID'] = $blogPost->id;
  621. $tmpRelation['BID'] = $moduleID;
  622. $tmpRelation['extra'] = $module->grade;
  623. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  624. $blogDirList[$blogPost->space->id]['module'] = $moduleID;
  625. }
  626. $year = !empty($blogPost->history->createdDate) ? date('Y', strtotime($blogPost->history->createdDate)) : date('Y');
  627. if(empty($blogDirList[$blogPost->space->id][$year]))
  628. {
  629. $module = new stdclass();
  630. $module->root = $spaceRelation[$blogPost->space->id];
  631. $module->type = 'doc';
  632. $module->parent = $blogDirList[$blogPost->space->id]['module'];
  633. $module->name = $year . ($archived ? "({$this->lang->convert->confluence->archived})" : '');
  634. $module->branch = '0';
  635. $module->short = '';
  636. $module->order = $year;
  637. $module->grade = '2';
  638. $this->dao->insert(TABLE_MODULE)->data($module)->exec();
  639. $moduleID = $this->dao->lastInsertID();
  640. $tmpRelation['AType'] = 'cblogpost';
  641. $tmpRelation['BType'] = 'zmodule';
  642. $tmpRelation['AID'] = $blogPost->id;
  643. $tmpRelation['BID'] = $moduleID;
  644. $tmpRelation['extra'] = $module->grade;
  645. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  646. $blogDirList[$blogPost->space->id][$year] = $moduleID;
  647. }
  648. return $blogDirList;
  649. }
  650. /**
  651. * 导入Confluence博文。
  652. * Import confluence blog post.
  653. *
  654. * @param array $dataList
  655. * @access public
  656. * @return bool
  657. */
  658. public function importConfluenceBlogPost($dataList)
  659. {
  660. $this->loadModel('action');
  661. $libList = $this->dao->dbh($this->dbh)->select('id,parent,type,project,product,execution,archived,name')->from(TABLE_DOCLIB)->fetchAll('id');
  662. $spaceRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cspace')->andWhere('BType')->eq('zlib')->fetchPairs();
  663. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  664. $order = 0;
  665. $blogDirList = array();
  666. foreach($dataList as $blogPost)
  667. {
  668. if(!empty($docRelation[$blogPost->id])) continue;
  669. $order = $order + 10;
  670. $libID = $spaceRelation[$blogPost->space->id];
  671. $lib = $libList[$libID];
  672. $archived = !empty($lib->archived) ? $lib->archived : 0;
  673. $blogDirList = $this->createConfluenceBlogDir($blogPost, $blogDirList, $spaceRelation, $archived ? true : false);
  674. $space = $libList[$libList[$libID]->parent];
  675. $doc = new stdclass();
  676. $doc->title = (!empty($blogPost->title) ? $blogPost->title : $this->lang->convert->confluence->undefined) . ($archived ? "({$this->lang->convert->confluence->archived})" : '');
  677. $doc->version = !empty($blogPost->version->number) ? $blogPost->version->number : '1';
  678. $doc->module = $blogDirList[$blogPost->space->id][!empty($blogPost->history->createdDate) ? date('Y', strtotime($blogPost->history->createdDate)) : date('Y')];
  679. $doc->lib = $libID;
  680. $doc->product = $doc->lib ? zget($libList[$doc->lib], 'product', '0') : '0';
  681. $doc->project = $doc->lib ? zget($libList[$doc->lib], 'project', '0') : '0';
  682. $doc->execution = $doc->lib ? zget($libList[$doc->lib], 'execution', '0') : '0';
  683. $doc->status = $blogPost->status == 'draft' ? 'draft' : 'normal';
  684. $doc->type = 'text';
  685. $doc->parent = '0';
  686. $doc->path = '';
  687. $doc->grade = '0';
  688. $doc->order = $order;
  689. $doc->acl = $space->type == 'mine' ? 'private' : '';
  690. $doc->addedBy = $this->app->user->account;
  691. $doc->addedDate = !empty($blogPost->history->createdDate) ? date('Y-m-d H:i:s', strtotime($blogPost->history->createdDate)) : helper::now();
  692. $doc->editedBy = $this->app->user->account;
  693. $doc->editedDate = !empty($blogPost->version->when) ? date('Y-m-d H:i:s', strtotime($blogPost->version->when)) : helper::now();
  694. if(!empty($blogPost->history->createdBy->accountId)) $doc->addedBy = $this->getConfluenceAccount($blogPost->history->createdBy->accountId);
  695. if(!empty($blogPost->history->createdBy->userKey)) $doc->addedBy = $this->getConfluenceAccount($blogPost->history->createdBy->userKey);
  696. if(!empty($blogPost->version->by->accountId)) $doc->editedBy = $this->getConfluenceAccount($blogPost->version->by->accountId);
  697. if(!empty($blogPost->version->by->userKey)) $doc->editedBy = $this->getConfluenceAccount($blogPost->version->by->userKey);
  698. if($blogPost->status == 'draft') $doc->addedBy = $doc->editedBy;
  699. if($space->type != 'mine') $doc = $this->setDocPrivUsers($blogPost, $doc);
  700. $this->dao->insert(TABLE_DOC)->data($doc)->exec();
  701. $docID = $this->dao->lastInsertID();
  702. $this->action->create('doc', $docID, 'Created');
  703. $tmpRelation['AType'] = 'cblogpost';
  704. $tmpRelation['BType'] = 'zdoc';
  705. $tmpRelation['AID'] = $blogPost->id;
  706. $tmpRelation['BID'] = $docID;
  707. $tmpRelation['extra'] = $doc->grade;
  708. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  709. $docContent = new stdclass();
  710. $docContent->title = $doc->title ? $doc->title : $this->lang->convert->confluence->undefined;
  711. $docContent->content = !empty($blogPost->body->view->value) ? $blogPost->body->view->value : '';
  712. $docContent->type = 'doc';
  713. $docContent->rawContent = $this->createConfluenceDocContent(!empty($blogPost->body->storage->value) ? $blogPost->body->storage->value : '');
  714. $docContent->digest = !empty($blogPost->version->message) ? $blogPost->version->message : '';
  715. $docContent->version = $doc->version;
  716. $docContent->doc = $docID;
  717. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  718. $docContentID = $this->dao->lastInsertID();
  719. $tmpRelation['AType'] = 'cblogpost';
  720. $tmpRelation['BType'] = 'zdoccontent';
  721. $tmpRelation['AID'] = $blogPost->id;
  722. $tmpRelation['BID'] = $docContentID;
  723. $tmpRelation['extra'] = $docContent->version;
  724. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  725. }
  726. return true;
  727. }
  728. /**
  729. * 导入Confluence草稿页面。
  730. * Import confluence draft page.
  731. *
  732. * @param array $dataList
  733. * @access public
  734. * @return bool
  735. */
  736. public function importConfluenceDraftPage($dataList)
  737. {
  738. $this->loadModel('action');
  739. $docList = $this->dao->dbh($this->dbh)->select('id,lib,module')->from(TABLE_DOC)->fetchAll('id');
  740. $libList = $this->dao->dbh($this->dbh)->select('id,parent,type,project,product,execution,archived,name')->from(TABLE_DOCLIB)->fetchAll('id');
  741. $relations = $this->dao->dbh($this->dbh)->select('*')->from(CONFLUENCE_TMPRELATION)->where('BType')->in('zmodule,zlib,zdoc')->fetchAll();
  742. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  743. $parentList = array();
  744. foreach($relations as $relation)
  745. {
  746. $parentList[$relation->AID] = $relation;
  747. $parentList[$relation->extra] = $relation;
  748. }
  749. foreach($dataList as $page)
  750. {
  751. if(!empty($docRelation[$page->id])) continue;
  752. if(empty($page->ancestors)) continue;
  753. $parent = end($page->ancestors);
  754. if(!isset($parentList[$parent->id])) continue;
  755. $parent = $parentList[$parent->id];
  756. $docModule = '0';
  757. $docLib = '0';
  758. if($parent->BType == 'zlib') $docLib = $parent->BID;
  759. if($parent->BType == 'zmodule') $docModule = $parent->BID;
  760. if($parent->BType == 'zdoc')
  761. {
  762. $parentDoc = $docList[$parent->BID];
  763. $docLib = $parentDoc->lib;
  764. $docModule = $parentDoc->module;
  765. }
  766. $doc = new stdclass();
  767. $doc->title = !empty($page->title) ? $page->title : $this->lang->convert->confluence->undefined;
  768. $doc->version = '0';
  769. $doc->module = $docModule;
  770. $doc->lib = $docLib;
  771. $doc->product = $doc->lib ? zget($libList[$doc->lib], 'product', '0') : '0';
  772. $doc->project = $doc->lib ? zget($libList[$doc->lib], 'project', '0') : '0';
  773. $doc->execution = $doc->lib ? zget($libList[$doc->lib], 'execution', '0') : '0';
  774. $doc->status = 'draft';
  775. $doc->type = 'text';
  776. $doc->parent = $parent->BType == 'zdoc' ? $parent->BID : '0';
  777. $doc->path = '';
  778. $doc->grade = $parent->BType == 'zdoc' ? ((int)$parent->extra + 1) : '0';
  779. $doc->order = '0';
  780. $doc->addedBy = $this->app->user->account;
  781. $doc->addedDate = !empty($page->history->createdDate) ? date('Y-m-d H:i:s', strtotime($page->history->createdDate)) : helper::now();
  782. $doc->editedBy = $this->app->user->account;
  783. $doc->editedDate = !empty($page->version->when) ? date('Y-m-d H:i:s', strtotime($page->version->when)) : helper::now();
  784. if(!empty($page->history->createdBy->accountId)) $doc->addedBy = $this->getConfluenceAccount($page->history->createdBy->accountId);
  785. if(!empty($page->history->createdBy->userKey)) $doc->addedBy = $this->getConfluenceAccount($page->history->createdBy->userKey);
  786. if(!empty($page->version->by->accountId)) $doc->editedBy = $this->getConfluenceAccount($page->version->by->accountId);
  787. if(!empty($page->version->by->userKey)) $doc->editedBy = $this->getConfluenceAccount($page->version->by->userKey);
  788. $this->dao->insert(TABLE_DOC)->data($doc)->exec();
  789. $docID = $this->dao->lastInsertID();
  790. $this->action->create('doc', $docID, 'Created');
  791. $tmpRelation['AType'] = 'cpage';
  792. $tmpRelation['BType'] = 'zdoc';
  793. $tmpRelation['AID'] = $page->id;
  794. $tmpRelation['BID'] = $docID;
  795. $tmpRelation['extra'] = $doc->grade;
  796. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  797. $docContent = new stdclass();
  798. $docContent->title = $doc->title ? $doc->title : $this->lang->convert->confluence->undefined;
  799. $docContent->content = !empty($page->body->view->value) ? $page->body->view->value : '';
  800. $docContent->type = 'doc';
  801. $docContent->rawContent = $this->createConfluenceDocContent(!empty($page->body->storage->value) ? $page->body->storage->value : '');
  802. $docContent->digest = !empty($page->version->message) ? $page->version->message : '';
  803. $docContent->version = '0';
  804. $docContent->doc = $docID;
  805. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  806. $docContentID = $this->dao->lastInsertID();
  807. $tmpRelation['AType'] = 'cpage';
  808. $tmpRelation['BType'] = 'zdoccontent';
  809. $tmpRelation['AID'] = $page->id;
  810. $tmpRelation['BID'] = $docContentID;
  811. $tmpRelation['extra'] = $docContent->version;
  812. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  813. }
  814. return true;
  815. }
  816. /**
  817. * 导入Confluence归档页面。
  818. * Import confluence archived page.
  819. *
  820. * @param array dataList
  821. * @access public
  822. * @return bool
  823. */
  824. public function importConfluenceArchivedPage($dataList)
  825. {
  826. $this->loadModel('action');
  827. $libList = $this->dao->dbh($this->dbh)->select('id,parent,type,project,product,execution,archived,name')->from(TABLE_DOCLIB)->fetchAll('id');
  828. $spaceRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cspace')->andWhere('BType')->eq('zlib')->fetchPairs();
  829. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  830. foreach($dataList as $page)
  831. {
  832. if(!empty($docRelation[$page->id])) continue;
  833. if(empty($page->space->id)) continue;
  834. if(empty($spaceRelation[$page->space->id])) continue;
  835. $space = $libList[$libList[$spaceRelation[$page->space->id]]->parent];
  836. $doc = new stdclass();
  837. $doc->title = $page->title . "({$this->lang->convert->confluence->archived})";
  838. $doc->version = !empty($page->version->number) ? $page->version->number : '1';
  839. $doc->module = '0';
  840. $doc->lib = $spaceRelation[$page->space->id];
  841. $doc->product = $doc->lib ? zget($libList[$doc->lib], 'product', '0') : '0';
  842. $doc->project = $doc->lib ? zget($libList[$doc->lib], 'project', '0') : '0';
  843. $doc->execution = $doc->lib ? zget($libList[$doc->lib], 'execution', '0') : '0';
  844. $doc->status = $page->status == 'draft' ? 'draft' : 'normal';
  845. $doc->type = 'text';
  846. $doc->parent = '0';
  847. $doc->path = '';
  848. $doc->grade = '1';
  849. $doc->order = '999';
  850. $doc->acl = $space->type == 'mine' ? 'private' : '';
  851. $doc->addedBy = $this->app->user->account;
  852. $doc->addedDate = !empty($page->history->createdDate) ? date('Y-m-d H:i:s', strtotime($page->history->createdDate)) : helper::now();
  853. $doc->editedBy = $this->app->user->account;
  854. $doc->editedDate = !empty($page->version->when) ? date('Y-m-d H:i:s', strtotime($page->version->when)) : helper::now();
  855. if(!empty($page->history->createdBy->accountId)) $doc->addedBy = $this->getConfluenceAccount($page->history->createdBy->accountId);
  856. if(!empty($page->history->createdBy->userKey)) $doc->addedBy = $this->getConfluenceAccount($page->history->createdBy->userKey);
  857. if(!empty($page->version->by->accountId)) $doc->editedBy = $this->getConfluenceAccount($page->version->by->accountId);
  858. if(!empty($page->version->by->userKey)) $doc->editedBy = $this->getConfluenceAccount($page->version->by->userKey);
  859. if($space->type != 'mine') $doc = $this->setDocPrivUsers($page, $doc);
  860. if(!$doc->title) $doc->title = $this->lang->convert->confluence->undefined;
  861. $this->dao->insert(TABLE_DOC)->data($doc)->exec();
  862. $docID = $this->dao->lastInsertID();
  863. $this->action->create('doc', $docID, 'Created');
  864. $tmpRelation['AType'] = 'cpage';
  865. $tmpRelation['BType'] = 'zdoc';
  866. $tmpRelation['AID'] = $page->id;
  867. $tmpRelation['BID'] = $docID;
  868. $tmpRelation['extra'] = $doc->grade;
  869. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  870. $docContent = new stdclass();
  871. $docContent->title = $doc->title;
  872. $docContent->content = !empty($page->body->view->value) ? $page->body->view->value : '';
  873. $docContent->type = 'doc';
  874. $docContent->rawContent = $this->createConfluenceDocContent(!empty($page->body->storage->value) ? $page->body->storage->value : '');
  875. $docContent->digest = !empty($page->version->message) ? $page->version->message : '';
  876. $docContent->version = $doc->version;
  877. $docContent->doc = $docID;
  878. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  879. $docContentID = $this->dao->lastInsertID();
  880. $tmpRelation['AType'] = 'cpage';
  881. $tmpRelation['BType'] = 'zdoccontent';
  882. $tmpRelation['AID'] = $page->id;
  883. $tmpRelation['BID'] = $docContentID;
  884. $tmpRelation['extra'] = $docContent->version;
  885. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  886. }
  887. return true;
  888. }
  889. /**
  890. * 导入Confluence文档的历史版本。
  891. * Import confluence history version.
  892. *
  893. * @param array $dataList
  894. * @access public
  895. * @return bool
  896. */
  897. public function importConfluenceVersion($dataList)
  898. {
  899. $contentRelation = $this->dao->dbh($this->dbh)->select('*')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->andWhere('AType')->ne('cfolder')->fetchAll('AID');
  900. foreach($dataList as $contentID => $versions)
  901. {
  902. $currentContent = $contentRelation[$contentID];
  903. foreach($versions as $version => $content)
  904. {
  905. if(empty($content)) continue;
  906. $docContent = new stdclass();
  907. $docContent->title = $content->title;
  908. $docContent->content = !empty($content->body->view->value) ? $content->body->view->value : '';
  909. $docContent->type = 'doc';
  910. $docContent->rawContent = $this->createConfluenceDocContent(!empty($content->body->storage->value) ? $content->body->storage->value : '');
  911. $docContent->digest = !empty($content->version->message) ? $content->version->message : '';
  912. $docContent->version = $version;
  913. $docContent->doc = $currentContent->BID;
  914. $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
  915. $docContentID = $this->dao->lastInsertID();
  916. $tmpRelation['AType'] = $currentContent->AType;
  917. $tmpRelation['BType'] = 'zdoccontent';
  918. $tmpRelation['AID'] = $contentID;
  919. $tmpRelation['BID'] = $docContentID;
  920. $tmpRelation['extra'] = $docContent->version;
  921. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($tmpRelation)->exec();
  922. }
  923. }
  924. return true;
  925. }
  926. /**
  927. * 导入Confluence文档的附件。
  928. * Import confluence attachment.
  929. *
  930. * @param array $dataList
  931. * @access public
  932. * @return bool
  933. */
  934. public function importConfluenceAttachment($dataList)
  935. {
  936. $this->loadModel('file');
  937. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  938. $fileRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cfile')->andWhere('BType')->eq('zfile')->fetchPairs();
  939. foreach($dataList as $attachment)
  940. {
  941. if(!empty($fileRelation[$attachment->id])) continue;
  942. if(empty($attachment->container->id)) continue;
  943. if(empty($docRelation[$attachment->container->id])) continue;
  944. $fileID = $attachment->id;
  945. $fileName = $attachment->title;
  946. $parts = explode('.', $fileName);
  947. $extension = array_pop($parts);
  948. $confluenceFile = $this->app->getTmpRoot() . 'attachments/' . $attachment->container->id . '/' . str_replace('att', '', $attachment->id) . '/1';
  949. if(!is_file($confluenceFile)) continue;
  950. $file = new stdclass();
  951. $file->pathname = $this->file->setPathName((int)$fileID, $extension);
  952. $file->title = $fileName;
  953. $file->extension = substr($extension, 0, 30); // 防止超长报错
  954. $file->size = $attachment->extensions->fileSize;
  955. $file->objectType = 'doc';
  956. $file->objectID = $docRelation[$attachment->container->id];
  957. $file->addedBy = $this->app->user->account;
  958. $file->addedDate = !empty($attachment->history->createdDate) ? date('Y-m-d H:i:s', strtotime($attachment->history->createdDate)) : helper::now();
  959. if(!empty($attachment->history->createdBy->accountId)) $file->addedBy = $this->getConfluenceAccount($attachment->history->createdBy->accountId);
  960. if(!empty($attachment->history->createdBy->userKey)) $file->addedBy = $this->getConfluenceAccount($attachment->history->createdBy->userKey);
  961. $this->dao->insert(TABLE_FILE)->data($file)->exec();
  962. $fileID = $this->dao->lastInsertID();
  963. $this->dao->update(TABLE_DOCCONTENT)->set("`files`=IF(`files` IS NOT NULL, CONCAT(`files`,',{$fileID},'), '{$fileID}')")->where('doc')->eq($file->objectID)->exec();
  964. copy($confluenceFile, $this->file->savePath . $file->pathname);
  965. $relation['AType'] = 'cfile';
  966. $relation['BType'] = 'zfile';
  967. $relation['AID'] = $attachment->id;
  968. $relation['BID'] = $fileID;
  969. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($relation)->exec();
  970. }
  971. return true;
  972. }
  973. /**
  974. * 导入Confluence的文档批注。
  975. * Import confluence comment.
  976. *
  977. * @param array $dataList
  978. * @access public
  979. * @return bool
  980. */
  981. public function importConfluenceComment($dataList)
  982. {
  983. $docRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoc')->fetchPairs();
  984. $commentRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('ccomment')->andWhere('BType')->eq('zaction')->fetchPairs();
  985. foreach($dataList as $comment)
  986. {
  987. if(!empty($commentRelation[$comment->id])) continue;
  988. if(empty($comment->container->id)) continue;
  989. if(empty($docRelation[$comment->container->id])) continue;
  990. if(empty($comment->body->storage->value)) continue;
  991. $action = new stdclass();
  992. $action->objectID = $docRelation[$comment->container->id];
  993. $action->objectType = 'doc';
  994. $action->actor = !empty($comment->history->createdBy->accountId) ? $this->getConfluenceAccount($comment->history->createdBy->accountId) : $this->app->user->account;
  995. $action->action = 'commented';
  996. $action->date = !empty($comment->history->createdDate) ? date('Y-m-d H:i:s', strtotime($comment->history->createdDate)) : helper::now();
  997. $action->comment = $comment->body->storage->value;
  998. $action->comment = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $action->comment);
  999. $this->dao->dbh($this->dbh)->insert(TABLE_ACTION)->data($action)->exec();
  1000. $actionID = $this->dao->lastInsertID();
  1001. $relation['AType'] = 'ccomment';
  1002. $relation['BType'] = 'zaction';
  1003. $relation['AID'] = $comment->id;
  1004. $relation['BID'] = $actionID;
  1005. $this->dao->dbh($this->dbh)->insert(CONFLUENCE_TMPRELATION)->data($relation)->exec();
  1006. }
  1007. return true;
  1008. }
  1009. /**
  1010. * 获取Confluence接口数据。
  1011. * Get confluence data.
  1012. *
  1013. * @param string $module
  1014. * @param object $group
  1015. * @param int $start
  1016. * @access public
  1017. * @return array
  1018. */
  1019. public function getConfluenceData($module, $group = null, $start = 0)
  1020. {
  1021. if(empty($_SESSION['confluenceApi'])) return array();
  1022. $confluenceApi = json_decode($this->session->confluenceApi, true);
  1023. if(empty($confluenceApi['domain'])) return array();
  1024. $token = base64_encode("{$confluenceApi['admin']}:{$confluenceApi['token']}");
  1025. $isSaas = strpos($confluenceApi['domain'], 'atlassian.net') !== false ? true : false;
  1026. if($module == 'user')
  1027. {
  1028. if($isSaas)
  1029. {
  1030. $users = array();
  1031. $userGroups = $this->getConfluenceData('userGroup', $group, 0);
  1032. foreach($userGroups as $userGroup) $users = array_merge($users, $this->getConfluenceData('group', $userGroup, 0));
  1033. }
  1034. else
  1035. {
  1036. $url = $confluenceApi['domain'] . "/rest/api/user/list?start={$start}";
  1037. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1038. $users = array();
  1039. if(!empty($result->results))
  1040. {
  1041. $users = $result->results;
  1042. if($result->size == $result->limit) $users = array_merge($users, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1043. }
  1044. }
  1045. return $users;
  1046. }
  1047. elseif($module == 'group')
  1048. {
  1049. $url = $confluenceApi['domain'] . ($isSaas ? "/rest/api/group/{$group->id}/membersByGroupId?start={$start}" : "/rest/api/group/{$group->name}/member?start={$start}");
  1050. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1051. $groups = array();
  1052. if(!empty($result->results))
  1053. {
  1054. $groups = $result->results;
  1055. if($result->size == $result->limit) $groups = array_merge($groups, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1056. }
  1057. return $groups;
  1058. }
  1059. elseif($module == 'userGroup')
  1060. {
  1061. $url = $confluenceApi['domain'] . "/rest/api/group?start={$start}";
  1062. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1063. $userGroups = array();
  1064. if(!empty($result->results))
  1065. {
  1066. $userGroups = $result->results;
  1067. if($result->size == $result->limit) $userGroups = array_merge($userGroups, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1068. }
  1069. return $userGroups;
  1070. }
  1071. elseif(in_array($module, array('folder', 'page', 'embed', 'database', 'whiteboard')))
  1072. {
  1073. $spaceRelation = $this->dao->dbh($this->dbh)->select('*')->from(CONFLUENCE_TMPRELATION)->where('AType')->eq('cspace')->andWhere('BType')->eq('zlib')->fetchAll();
  1074. $dataList = array();
  1075. foreach($spaceRelation as $space)
  1076. {
  1077. $url = $confluenceApi['domain'] . "/rest/api/content/{$space->extra}/child/{$module}?start={$start}&limit=500&expand=body.storage,body.view,version,history,restrictions.read.restrictions.user,restrictions.update.restrictions.user,restrictions.read.restrictions.group,restrictions.update.restrictions.group";
  1078. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1079. if(!empty($result->results))
  1080. {
  1081. $dataList[$space->BID] = $result->results;
  1082. if($result->size == $result->limit) $dataList[$space->BID] = array_merge($dataList[$space->BID], $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1083. }
  1084. }
  1085. return $dataList;
  1086. }
  1087. elseif($module == 'blogpost')
  1088. {
  1089. $url = $confluenceApi['domain'] . "/rest/api/content?start={$start}&limit=1000&type=blogpost&status=any&expand=body.storage,body.view,version,history,space,restrictions.read.restrictions.user,restrictions.update.restrictions.user,restrictions.read.restrictions.group,restrictions.update.restrictions.group";
  1090. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1091. $blogPost = array();
  1092. if(!empty($result->results))
  1093. {
  1094. $blogPost = $result->results;
  1095. if($result->size == $result->limit) $blogPost = array_merge($blogPost, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1096. }
  1097. return $blogPost;
  1098. }
  1099. elseif($module == 'draft')
  1100. {
  1101. $url = $confluenceApi['domain'] . "/rest/api/content?start={$start}&limit=1000&type=page&status=draft&expand=body.storage,body.view,version,history,space,ancestors";
  1102. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1103. $draftPage = array();
  1104. if(!empty($result->results))
  1105. {
  1106. $draftPage = $result->results;
  1107. if($result->size == $result->limit) $draftPage = array_merge($draftPage, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1108. }
  1109. return $draftPage;
  1110. }
  1111. elseif($module == 'archived')
  1112. {
  1113. $url = $confluenceApi['domain'] . "/rest/api/content?start={$start}&limit=1000&type=page&status=archived&expand=body.storage,body.view,version,history,space,ancestors,restrictions.read.restrictions.user,restrictions.update.restrictions.user,restrictions.read.restrictions.group,restrictions.update.restrictions.group";
  1114. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1115. $archivedPage = array();
  1116. if(!empty($result->results))
  1117. {
  1118. $archivedPage = $result->results;
  1119. if($result->size == $result->limit) $archivedPage = array_merge($archivedPage, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1120. }
  1121. return $archivedPage;
  1122. }
  1123. elseif($module == 'version')
  1124. {
  1125. $contentRelation = $this->dao->dbh($this->dbh)->select('*')->from(CONFLUENCE_TMPRELATION)->where('BType')->eq('zdoccontent')->orderBy('extra_desc')->fetchAll('AID');
  1126. $versionList = array();
  1127. foreach($contentRelation as $content)
  1128. {
  1129. for($version = $content->extra - 1; $version >= 1; $version --)
  1130. {
  1131. $url = $confluenceApi['domain'] . "/rest/api/content/{$content->AID}?version={$version}&expand=body.storage,body.view,version,history";
  1132. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1133. $versionList[$content->AID][$version] = !empty($result->id) ? $result : array();
  1134. }
  1135. }
  1136. return $versionList;
  1137. }
  1138. elseif($module == 'space')
  1139. {
  1140. $url = $confluenceApi['domain'] . "/rest/api/space?start={$start}&limit=1000&expand=homepage,history,permissions";
  1141. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1142. $spaces = array();
  1143. if(!empty($result->results))
  1144. {
  1145. $spaces = $result->results;
  1146. if($result->size == $result->limit) $spaces = array_merge($spaces, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1147. }
  1148. return $spaces;
  1149. }
  1150. elseif($module == 'comment')
  1151. {
  1152. $url = $confluenceApi['domain'] . "/rest/api/content/search?cql=type=comment&start={$start}&limit=1000&expand=body.storage,history,container";
  1153. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1154. $comments = array();
  1155. if(!empty($result->results))
  1156. {
  1157. $comments = $result->results;
  1158. if($result->size == $result->limit) $comments = array_merge($comments, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1159. }
  1160. return $comments;
  1161. }
  1162. elseif($module == 'attachment')
  1163. {
  1164. $url = $confluenceApi['domain'] . "/rest/api/content/search?cql=type=attachment&start={$start}&limit=1000&expand=container,history";
  1165. $result = json_decode(commonModel::http($url, array(), array(), array("Authorization: Basic $token"), 'json', 'GET', 10));
  1166. $attachments = array();
  1167. if(!empty($result->results))
  1168. {
  1169. $attachments = $result->results;
  1170. if($result->size == $result->limit) $attachments = array_merge($attachments, $this->getConfluenceData($module, $group, $result->start + $result->limit));
  1171. }
  1172. return $attachments;
  1173. }
  1174. return array();
  1175. }
  1176. /**
  1177. * 检查Conffluence空间权限类型。
  1178. * Check Confluence space priv.
  1179. *
  1180. * @param object $space
  1181. * @access public
  1182. * @return string
  1183. */
  1184. public function checkConfluenceSpacePriv($space)
  1185. {
  1186. $userList = array();
  1187. $spaceType = 'mine';
  1188. $permissions = !empty($space->permissions) ? $space->permissions : array();
  1189. if(!empty($permissions->data))
  1190. {
  1191. foreach($permissions->data as $permission)
  1192. {
  1193. if($permission->operation->operationKey != 'read' || $permission->operation->targetType != 'space') continue;
  1194. if($permission->subject->type == 'group')
  1195. {
  1196. $spaceType = 'custom';
  1197. break;
  1198. }
  1199. if($permission->subject->type == 'user')
  1200. {
  1201. $userKey = $permission->subject->userKey;
  1202. $userList[$userKey] = $userKey;
  1203. }
  1204. }
  1205. }
  1206. else
  1207. {
  1208. foreach($permissions as $permission)
  1209. {
  1210. if($permission->operation->operation != 'read' || $permission->operation->targetType != 'space') continue;
  1211. if(!empty($permission->subjects->group))
  1212. {
  1213. $groupList = $permission->subjects->group->results;
  1214. foreach($groupList as $group)
  1215. {
  1216. if($group->name != 'atlassian-addons-admin')
  1217. {
  1218. $spaceType = 'custom';
  1219. break;
  1220. }
  1221. }
  1222. }
  1223. if(!empty($permission->subjects->user))
  1224. {
  1225. $userGroup = $permission->subjects->user->results;
  1226. foreach($userGroup as $user)
  1227. {
  1228. if($user->accountType == 'atlassian') $userList[$user->accountId] = $user->accountId;
  1229. }
  1230. }
  1231. }
  1232. }
  1233. if(count($userList) > 1 || empty($permissions)) $spaceType = 'custom';
  1234. return $spaceType;
  1235. }
  1236. /**
  1237. * 获取有权限访问空间的用户列表。
  1238. * Get Confluence space users.
  1239. *
  1240. * @param object $space
  1241. * @access public
  1242. * @return string
  1243. */
  1244. public function getConfluenceSpaceUsers($space)
  1245. {
  1246. $userGroup = !empty($_SESSION['confluenceUserGroup']) ? json_decode($this->session->confluenceUserGroup, true) : array();
  1247. $userList = array();
  1248. $permissions = !empty($space->permissions) ? $space->permissions : array();
  1249. if(!empty($permissions->data))
  1250. {
  1251. foreach($permissions->data as $permission)
  1252. {
  1253. if($permission->operation->operationKey != 'read' || $permission->operation->targetType != 'space') continue;
  1254. if($permission->subject->type == 'group')
  1255. {
  1256. $group = new stdclass();
  1257. $group->name = $permission->subject->name;
  1258. if(empty($userGroup[$group->name]))
  1259. {
  1260. $userGroup[$group->name] = $this->getConfluenceData('group', $group);
  1261. }
  1262. foreach($userGroup[$group->name] as $user)
  1263. {
  1264. $accountID = zget($user, 'userKey');
  1265. $userList[$accountID] = $this->getConfluenceAccount($accountID);
  1266. }
  1267. }
  1268. if($permission->subject->type == 'user')
  1269. {
  1270. $userKey = $permission->subject->userKey;
  1271. $userList[$userKey] = $this->getConfluenceAccount($userKey);
  1272. }
  1273. }
  1274. }
  1275. else
  1276. {
  1277. foreach($permissions as $permission)
  1278. {
  1279. if($permission->operation->operation != 'read' || $permission->operation->targetType != 'space') continue;
  1280. if(!empty($permission->subjects->group))
  1281. {
  1282. $groupList = $permission->subjects->group->results;
  1283. foreach($groupList as $group)
  1284. {
  1285. if($group->name == 'atlassian-addons-admin') continue;
  1286. if(empty($userGroup[$group->name]))
  1287. {
  1288. $userGroup[$group->name] = $this->getConfluenceData('group', $group);
  1289. }
  1290. foreach($userGroup[$group->name] as $user)
  1291. {
  1292. $accountID = zget($user, 'accountId');
  1293. $userList[$accountID] = $this->getConfluenceAccount($accountID);
  1294. }
  1295. }
  1296. }
  1297. if(!empty($permission->subjects->user))
  1298. {
  1299. $users = $permission->subjects->user->results;
  1300. foreach($users as $user) $userList[$user->accountId] = $this->getConfluenceAccount($user->accountId);
  1301. }
  1302. }
  1303. }
  1304. $this->session->set('confluenceUserGroup', json_encode($userGroup));
  1305. return implode(',', $userList);
  1306. }
  1307. /**
  1308. * 设置Confluence导入文档的权限。
  1309. * Get doc priv users.
  1310. *
  1311. * @param object $content
  1312. * @param object $doc
  1313. * @access public
  1314. * @return object
  1315. */
  1316. public function setDocPrivUsers($content, $doc)
  1317. {
  1318. $userGroup = !empty($_SESSION['confluenceUserGroup']) ? json_decode($this->session->confluenceUserGroup, true) : array();
  1319. $users = !empty($_SESSION['confluenceUsers']) ? json_decode($this->session->confluenceUsers, true) : array();
  1320. $readUsers = $content->restrictions->read->restrictions->user->results;
  1321. $readGroups = $content->restrictions->read->restrictions->group->results;
  1322. $updateUsers = $content->restrictions->update->restrictions->user->results;
  1323. $updateGroups = $content->restrictions->update->restrictions->group->results;
  1324. $readUserList = array();
  1325. foreach($readUsers as $user)
  1326. {
  1327. $accountID = !empty($user->accountId) ? $user->accountId : $user->userKey;
  1328. $readUserList[$accountID] = $this->getConfluenceAccount($accountID);
  1329. }
  1330. foreach($readGroups as $group)
  1331. {
  1332. if(empty($userGroup[$group->name]))
  1333. {
  1334. $userGroup[$group->name] = $this->getConfluenceData('group', $group);
  1335. }
  1336. foreach($userGroup[$group->name] as $user)
  1337. {
  1338. $accountID = !empty($user->accountId) ? $user->accountId : $user->userKey;
  1339. $readUserList[$accountID] = $this->getConfluenceAccount($accountID);
  1340. }
  1341. }
  1342. $editUsers = array();
  1343. foreach($updateUsers as $user)
  1344. {
  1345. $accountID = !empty($user->accountId) ? $user->accountId : $user->userKey;
  1346. $editUsers[$accountID] = $this->getConfluenceAccount($accountID);
  1347. }
  1348. foreach($updateGroups as $group)
  1349. {
  1350. if(empty($userGroup[$group->name]))
  1351. {
  1352. $userGroup[$group->name] = $this->getConfluenceData('group', $group);
  1353. }
  1354. foreach($userGroup[$group->name] as $user)
  1355. {
  1356. $accountID = !empty($user->accountId) ? $user->accountId : $user->userKey;
  1357. $editUsers[$accountID] = $this->getConfluenceAccount($accountID);
  1358. }
  1359. }
  1360. if($doc->type == 'chapter')
  1361. {
  1362. $doc->acl = $readUserList && $editUsers ? 'private' : 'open';
  1363. if($doc->acl == 'private')
  1364. {
  1365. /* 章节的白名单用的是editUsers。 */
  1366. $editUsers = array_unique(array_merge($readUserList, $editUsers));
  1367. $readUserList = array();
  1368. }
  1369. }
  1370. else
  1371. {
  1372. $doc->acl = $readUserList || $editUsers ? 'private' : 'open';
  1373. if($doc->acl == 'private' && empty($readUserList)) $readUserList = $users;
  1374. }
  1375. $doc->readUsers = implode(',', $readUserList);
  1376. $doc->users = implode(',', $editUsers);
  1377. $this->session->set('confluenceUserGroup', json_encode($userGroup));
  1378. return $doc;
  1379. }