| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758 |
- <?php
- /**
- * The control file of doc module of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author Chunsheng Wang <chunsheng@cnezsoft.com>
- * @package doc
- * @version $Id: control.php 933 2010-07-06 06:53:40Z wwccss $
- * @link https://www.zentao.net
- */
- class doc extends control
- {
- /**
- * @var \docModel
- */
- public $doc;
- /**
- * 构造函数,加载通用模块。
- * Construct function, load user, tree, action auto.
- *
- * @access public
- * @return void
- */
- public function __construct($moduleName = '', $methodName = '')
- {
- parent::__construct($moduleName, $methodName);
- $this->loadModel('user');
- $this->loadModel('tree');
- $this->loadModel('action');
- $this->loadModel('product');
- $this->loadModel('project');
- $this->loadModel('execution');
- }
- /**
- * 最近访问的空间首页。
- * Last viewed doc space home.
- *
- * @access public
- * @return void
- */
- public function lastViewedSpaceHome()
- {
- $lastViewedSpaceHome = $this->doc->getLastViewed('lastViewedSpaceHome');
- if($this->config->vision == 'lite' && $lastViewedSpaceHome == 'api') $lastViewedSpaceHome = 'mine';
- if($lastViewedSpaceHome === 'api') return $this->locate($this->createLink('api', 'index'));
- $spaceMap = array(
- 'mine' => 'mySpace',
- 'product' => 'productSpace',
- 'project' => 'projectSpace',
- 'custom' => 'teamSpace'
- );
- $method = $spaceMap[$lastViewedSpaceHome];
- if(empty($method)) return $this->locate($this->createLink('doc', 'mySpace'));
- return $this->locate($this->createLink('doc', $method));
- }
- /**
- * 最近访问的空间。
- * Last viewed doc space.
- *
- * @access public
- * @return void
- */
- public function lastViewedSpace()
- {
- $lastViewedSpaceHome = $this->doc->getLastViewed('lastViewedSpaceHome');
- if($this->config->vision == 'lite' && $lastViewedSpaceHome == 'api') $lastViewedSpaceHome = 'mine';
- if($lastViewedSpaceHome === 'api') return $this->locate($this->createLink('api', 'index'));
- $spaceMap = array(
- 'mine' => 'mySpace',
- 'product' => 'productSpace',
- 'project' => 'projectSpace',
- 'custom' => 'teamSpace'
- );
- $method = $spaceMap[$lastViewedSpaceHome];
- if(empty($method) || !common::hasPriv('doc', $method)) return $this->locate($this->createLink('doc', 'mySpace'));
- $lastViewedSpace = $this->doc->getLastViewed('lastViewedSpace');
- if(!is_numeric($lastViewedSpace)) return $this->locate($this->createLink('doc', 'mySpace'));
- return $this->locate($this->createLink('doc', $method, "objectID={$lastViewedSpace}"));
- }
- /**
- * 最近访问的库。
- * Last viewed doc lib.
- *
- * @access public
- * @return void
- */
- public function lastViewedLib()
- {
- $lastViewedSpaceHome = $this->doc->getLastViewed('lastViewedSpaceHome');
- $lastViewedLib = $this->doc->getLastViewed('lastViewedLib');
- if($lastViewedSpaceHome === 'api')
- {
- if(is_numeric($lastViewedLib)) return $this->locate($this->createLink('api', 'index', "libID={$lastViewedLib}"));
- return $this->locate($this->createLink('api', 'index'));
- }
- $lastViewedSpace = $this->doc->getLastViewed('lastViewedSpace');
- $spaceMap = array(
- 'mine' => 'mySpace',
- 'product' => 'productSpace',
- 'project' => 'projectSpace',
- 'custom' => 'teamSpace'
- );
- $method = $spaceMap[$lastViewedSpaceHome];
- if(empty($method)) return $this->locate($this->createLink('doc', 'mySpace'));
- if(!is_numeric($lastViewedSpace) || !is_numeric($lastViewedLib)) return $this->locate($this->createLink('doc', 'mySpace'));
- return $this->locate($this->createLink('doc', $method, "objectID={$lastViewedSpace}&libID={$lastViewedLib}"));
- }
- /**
- * 设置上次访问的文档对象。
- * Set last viewed doc object.
- *
- * @access public
- * @return void
- */
- public function ajaxSetLastViewed()
- {
- if(empty($_POST)) return $this->send(array('result' => 'fail'));
- $this->doc->setLastViewed($_POST);
- return $this->send(array('result' => 'success'));
- }
- /**
- * 文档仪表盘。
- * Document dashboard.
- *
- * @access public
- * @return void
- */
- public function index()
- {
- $this->session->set('docList', $this->app->getURI(true), 'doc');
- echo $this->fetch('block', 'dashboard', 'dashboard=doc');
- }
- /**
- * 禅道数据列表。
- * Zentao data list.
- *
- * @param string $type
- * @param int|string $blockID
- * @access public
- * @return void
- */
- public function zentaoList($type, $blockID)
- {
- if(is_string($blockID)) $blockID = (int)str_replace('__TML_ZENTAOLIST__', '', $blockID);
- $blockData = $this->doc->getZentaoList($blockID);
- if(!$blockData)
- {
- if(helper::isAjaxRequest('fetch'))
- {
- echo '<div class="text-gray text-sm surface p-1">' . $this->lang->notFound . '</div>';
- return;
- }
- return $this->sendError($this->lang->notFound);
- }
- $doc = $this->doc->getByID($blockData->doc);
- $this->view->isTemplate = !empty($doc->templateType) && !in_array($blockData->extra, array('fromReview', 'fromReport'));
- $this->view->fromReport = $blockData->extra == 'fromReport';
- $noSupport = false;
- if($this->view->fromReport)
- {
- $project = $this->loadModel('project')->fetchByID((int)$doc->project);
- $noSupport = in_array($type, array('HLDS', 'DDS', 'DBDS', 'ADS')) && in_array($project->model, array('scrum', 'agileplus', 'kanban'));
- }
- $this->view->noSupport = $noSupport;
- if($this->view->isTemplate)
- {
- $this->view->title = sprintf($this->lang->doc->insertTitle, $this->lang->docTemplate->zentaoList[$type]);
- $this->view->type = $type;
- $this->view->blockID = $blockID;
- $this->view->settings = $blockData->settings;
- $this->view->searchTab = zget($blockData->content, 'searchTab', '');
- if($type == 'productCase' || $type == 'projectCase') $this->view->caseStage = $blockData->content->caseStage;
- return $this->display();
- }
- $fromTemplate = in_array($blockData->extra, array('fromTemplate', 'fromReview', 'fromReport'));
- if($fromTemplate)
- {
- $this->view->title = sprintf($this->lang->doc->insertTitle, $this->lang->docTemplate->zentaoList[$type]);
- $this->view->searchTab = zget($blockData->content, 'searchTab', '');
- $this->view->isSetted = isset($blockData->content->data) && isset($blockData->content->cols) || isset($blockData->content->ganttOptions);
- if($type == 'productCase' || $type == 'projectCase') $this->view->caseStage = $blockData->content->caseStage;
- }
- else
- {
- $this->view->title = sprintf($this->lang->doc->insertTitle, $this->lang->doc->zentaoList[$type]);
- }
- if($type == 'gantt')
- {
- $this->view->ganttData = (array)zget($blockData->content, 'ganttOptions', array());
- $this->view->ganttFields = (array)zget($blockData->content, 'ganttFields', array());
- $this->view->showFields = zget($blockData->content, 'showFields', '');
- }
- else
- {
- $data = (array)zget($blockData->content, 'data', array());
- if($type == 'task')
- {
- foreach($data as $task) $task->canView = $this->execution->checkPriv($task->execution);
- }
- $this->app->loadClass('pager', true);
- $this->view->idList = (array)zget($blockData->content, 'idList', array());
- $this->view->cols = (array)zget($blockData->content, 'cols', array());
- $this->view->data = $data;
- $this->view->pager = new pager(count($data), 10);
- }
- $this->view->type = $type;
- $this->view->settings = $blockData->settings;
- $this->view->users = $this->loadModel('user')->getPairs('noletter|pofirst');
- $this->view->blockID = $blockID;
- $this->view->fromTemplate = $fromTemplate;
- if(strpos(',productStory,ER,UR,planStory,projectStory', $type) !== false) $this->docZen->assignStoryGradeData($type);
- if($type == 'productRelease')
- {
- $releaseList = array();
- foreach($this->view->data as $release)
- {
- if($release->id == $release->rowID) $releaseList[$release->id] = $release;
- }
- $children = implode(',', array_column($releaseList, 'releases'));
- $childReleases = $this->loadModel('release')->getListByCondition(explode(',', $children), 0, true);
- $this->view->data = $this->release->processReleaseListData($releaseList, $childReleases, false);
- }
- $this->display();
- }
- /**
- * 导出禅道数据列表。
- * Export Zentao data list.
- *
- * @param int|string $blockID
- * @access public
- * @return void
- */
- public function ajaxExportZentaoList($blockID)
- {
- if(is_string($blockID)) $blockID = (int)str_replace('__TML_ZENTAOLIST__', '', $blockID);
- $blockData = $this->doc->getZentaoList($blockID);
- if(!$blockData) return $this->lang->notFound;
- if(!helper::isAjaxRequest('fetch')) return $this->locate(inlink('zentaoList', "type={$blockData->type}&blockID={$blockID}"));
- if(empty($blockData->title))
- {
- $blockType = $blockData->type;
- $blockContent = $blockData->content;
- $templateLang = zget($this->lang, 'docTemplate', array());
- $searchTab = zget($blockContent, 'searchTab', '');
- $blockTitle = '';
- if(!empty($templateLang))
- {
- $blockTitle = empty($templateLang->searchTabList[$blockType][$searchTab]) ? '' : $templateLang->searchTabList[$blockType][$searchTab] . $templateLang->of;
- if($blockType == 'bug' && $searchTab == 'overduebugs') $blockTitle = $templateLang->overdue . $templateLang->of;
- if(!empty($blockContent->caseStage)) $blockTitle .= $this->app->loadLang('testcase')->testcase->stageList[$blockContent->caseStage];
- }
- $blockData->title = $blockTitle . zget($this->lang->doc->zentaoList, $blockType, '') . $this->lang->doc->list;
- }
- $content = $this->docZen->exportZentaoList($blockData);
- echo $content;
- }
- /**
- * 构建禅道数据列表。
- * Build Zentao data list.
- *
- * @param int $docID
- * @param string $type
- * @param int $oldBlockID
- * @access public
- * @return void
- */
- public function buildZentaoList($docID, $type, $oldBlockID = 0)
- {
- $docblock = new stdClass();
- $docblock->doc = $docID;
- $docblock->type = $type;
- $docblock->settings = $this->post->url;
- if($type == 'gantt')
- {
- $docblock->content = json_encode(array('ganttOptions' => json_decode($this->post->ganttOptions), 'showFields' => $this->post->showFields, 'ganttFields' => json_decode($this->post->ganttFields)));
- }
- else
- {
- $docblock->content = json_encode(array('cols' => json_decode($this->post->cols), 'data' => json_decode($this->post->data), 'idList' => $this->post->idList));
- }
- $this->dao->insert(TABLE_DOCBLOCK)->data($docblock)->exec();
- if(dao::isError()) return print(json_encode(array('result' => 'fail', 'message' => dao::getError())));
- $newBlockID = $this->dao->lastInsertId();
- return print(json_encode(array('result' => 'success', 'oldBlockID' => $oldBlockID, 'newBlockID' => $newBlockID)));
- }
- /**
- * 我的空间。
- * My space.
- *
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $browseType all|draft|bysearch
- * @param int $param
- * @param string $orderBy
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- * @param string $mode
- * @param int $docID
- * @param string $search
- */
- public function mySpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = 'order_asc', $recTotal = 0, $recPerPage = 20, $pageID = 1, $mode = '', $docID = 0, $search = '')
- {
- $this->docZen->initLibForMySpace();
- echo $this->fetch('doc', 'app', "type=mine&spaceID=$objectID&libID=$libID&moduleID=$moduleID&docID=$docID&mode=$mode&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&filterType=$browseType&search=$search");
- }
- /**
- * 创建一个空间。
- * Create a space.
- *
- * @param string $type
- * @access public
- * @return void
- */
- public function createSpace($type = '')
- {
- if(!empty($_POST))
- {
- $this->lang->doc->name = $this->lang->doclib->spaceName;
- $space = form::data()->setDefault('addedBy', $this->app->user->account)->get();
- if($type) $space->type = $type;
- $spaceID = $this->doc->doInsertLib($space);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $this->loadModel('action')->create('docspace', $spaceID, 'created');
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->createLink('doc', 'teamSpace', "objectID={$spaceID}"), 'docApp' => array('call' => 'selectSpace', 'args' => array($spaceID, true))));
- }
- $this->display();
- }
- /**
- * 创建一个文档库。
- * Create a library.
- *
- * @param string $type api|project|product|execution|custom|mine
- * @param int $objectID
- * @param int $libID
- * @access public
- * @return void
- */
- public function createLib($type = '', $objectID = 0, $libID = 0)
- {
- $this->app->loadLang('api');
- /* 项目模板下setMenu会修改common语言项,所以执行文档要先执行setAclForCreateLib。 */
- if($type != 'project') $this->docZen->setAclForCreateLib($type);
- $this->doc->setMenuByType($type, (int)$objectID, (int)$libID);
- if($type == 'project') $this->docZen->setAclForCreateLib($type);
- if(!empty($_POST))
- {
- $lib = $this->docZen->buildLibForCreateLib();
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $libID = $this->doc->createLib($lib, (string)$this->post->type, (string)$this->post->libType);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- if($type == 'custom' || $type == 'mine')
- {
- $lib = $this->doc->getLibByID($libID);
- $objectID = $lib->parent;
- }
- return $this->docZen->responseAfterCreateLib($type, $objectID, $libID, $lib->name, $lib->orderBy);
- }
- $objects = array();
- if($type == 'project')
- {
- $this->view->project = $this->project->getById($objectID);
- if($this->app->tab == 'doc') $this->view->executionPairs = $this->execution->getPairs($objectID, 'all', 'multiple,leaf,noprefix');
- }
- if($type == 'execution')
- {
- $objects = $this->execution->getPairs(0, 'all', 'multiple,leaf,noprefix,withobject');
- $execution = $this->execution->getByID($objectID);
- if($execution->type == 'stage') $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution);
- $this->view->execution = $this->doc->fetchByID($objectID, 'execution');
- }
- if($type == 'custom' || $type == 'mine' || $type == 'doctemplate')
- {
- $lib = $this->doc->getLibByID($libID);
- $this->view->spaces = $this->doc->getSubSpacesByType($type);
- $this->view->spaceID = !empty($lib->parent) ? $lib->parent : $objectID;
- }
- $this->view->groups = $this->loadModel('group')->getPairs();
- $this->view->users = $this->user->getPairs('nocode|noclosed');
- $this->view->objects = $objects;
- $this->view->type = $type;
- $this->view->objectID = $objectID;
- $this->display();
- }
- /**
- * 编辑一个文档空间。
- * Edit a doc space.
- *
- * @param int $spaceID
- * @access public
- * @return void
- */
- public function editSpace($spaceID)
- {
- $this->commonEditAction($spaceID);
- $this->display();
- }
- /**
- * 编辑一个文档库。
- * Edit a library.
- *
- * @param int $libID
- * @access public
- * @return void
- */
- public function editLib($libID)
- {
- $this->commonEditAction($libID);
- $this->display();
- }
- /**
- * 编辑空间和编辑库的公用方法。
- * Edit a lib or space.
- *
- * @param int $libID
- * @access public
- * @return void
- */
- public function commonEditAction($libID)
- {
- if(!common::hasPriv('doc', 'editSpace') && !common::hasPriv('doc', 'editLib')) return;
- $lib = $this->doc->getLibByID($libID);
- /* 项目模板下setMenu会修改common语言项,所以执行文档要先执行setAclForCreateLib。 */
- if($lib->type != 'project') $this->docZen->setAclForEditLib($lib);
- $this->doc->setMenuByType($lib->type, (int)zget($lib, $lib->type, 0), (int)$libID);
- if($lib->type == 'project') $this->docZen->setAclForEditLib($lib);
- if(!empty($_POST))
- {
- $this->lang->doc->name = $this->lang->nameAB;
- $libData = form::data($this->config->doc->form->editlib)->get();
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $changes = $this->doc->updateLib($libID, $libData);
- if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
- if($changes)
- {
- $object = ($lib->type == 'custom' && $lib->parent == 0) ? 'docspace' : 'doclib';
- $actionID = $this->action->create($object, $libID, 'edited');
- $this->action->logHistory($actionID, $changes);
- }
- $lib = $this->doc->getLibByID($libID);
- $docAppActions = array();
- $docAppActions[] = array('update', ($lib->parent == 0) ? 'space' : 'lib', $lib);
- $docAppActions[] = array('home:loadHomeLibs');
- $docAppActions[] = array('list:load');
- return $this->send(array('message' => $this->lang->saveSuccess, 'result' => 'success', 'closeModal' => true, 'docApp' => $docAppActions));
- }
- if(!empty($lib->product)) $this->view->object = $this->product->getByID($lib->product);
- if(!empty($lib->project) && empty($lib->execution)) $this->view->object = $this->project->getByID($lib->project);
- if(!empty($lib->execution))
- {
- $execution = $this->execution->getByID($lib->execution);
- if($execution->type == 'stage')
- {
- if($execution->grade > 1)
- {
- $parentExecutions = $this->execution->getPairsByList(explode(',', trim($execution->path, ',')), 'stage,kanban,sprint');
- $execution->name = implode('/', $parentExecutions);
- }
- $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution);
- }
- $this->view->object = $execution;
- }
- $this->view->lib = $lib;
- $this->view->groups = $this->loadModel('group')->getPairs();
- $this->view->users = $this->user->getPairs('noletter|noclosed', $lib->users);
- $this->view->libID = $libID;
- }
- /**
- * 删除一个文档空间。
- * Delete a doc space.
- *
- * @param int $libID
- * @access public
- * @return void
- */
- public function deleteSpace($libID)
- {
- $this->commonDeleteAction($libID);
- }
- /**
- * 删除一个文档库。
- * Delete a library.
- *
- * @param int $libID
- * @access public
- * @return void
- */
- public function deleteLib($libID)
- {
- $this->commonDeleteAction($libID);
- }
- /**
- * 删除空间和删除库的公用方法。
- * Delete a lib or space.
- *
- * @param int $libID
- * @access public
- * @return void
- */
- public function commonDeleteAction($libID)
- {
- if(in_array($libID, array('product', 'execution'))) return;
- $lib = $this->doc->getLibByID($libID);
- if(!empty($lib->main)) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->errorMainSysLib, 'load' => array('alert' => $this->lang->doc->errorMainSysLib)));
- $this->dao->update(TABLE_DOCLIB)->set('deleted')->eq('1')->where('id')->eq($libID)->exec();
- $object = ($lib->type == 'custom' && $lib->parent == 0) ? 'docspace' : 'doclib';
- $this->loadModel('action')->create($object, $libID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED);
- $moduleName = 'doc';
- $objectType = $lib->type;
- $methodName = zget($this->config->doc->spaceMethod, $objectType);
- if($this->app->tab == 'doc') return $this->send(array('result' => 'success', 'load' => $this->createLink($moduleName, $methodName), 'app' => $this->app->tab));
- $objectID = strpos(',product,project,execution,', ",$objectType,") !== false ? $lib->{$objectType} : 0;
- if($this->app->tab == 'execution' && $objectType == 'execution')
- {
- $moduleName = 'execution';
- $methodName = 'doc';
- }
- $browseLink = $this->createLink($moduleName, $methodName, "objectID=$objectID");
- return $this->send(array('result' => 'success', 'load' => $browseLink, 'app' => $this->app->tab));
- }
- /**
- * 文档模板列表。
- * Browse template list.
- *
- * @param int $libID
- * @param string $type
- * @param mixed $docID
- * @param string $orderBy
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- * @param string $mode
- */
- public function browseTemplate($libID = 0, $type = 'all', $docID = 0, $orderBy = 'id_desc', $recPerPage = 20, $pageID = 1, $mode = 'home')
- {
- /* 添加内置的范围、分类、文档模板。*/
- /* Add the built-in scopes and type and doc template. */
- $builtInScopes = $this->dao->select('id')->from(TABLE_DOCLIB)->where('type')->eq('template')->andWhere('main')->eq('1')->fetchAll();
- if(empty($builtInScopes))
- {
- $this->doc->addBuiltInScopes();
- $this->doc->addBuiltInDocTemplateType();
- $this->doc->addBuiltInDocTemplateByType();
- }
- $this->lang->doc->menu->template['alias'] .= ',' . $this->app->rawMethod;
- $libModules = $this->doc->getTemplateModules($libID);
- if($mode == 'create' && empty($libModules)) return $this->send(array('result' => 'success', 'load' => array('alert' => $this->lang->docTemplate->createTypeFirst)));
- $templateList = $this->doc->getDocTemplateList(0, $type, $orderBy);
- $templateList = $this->doc->filterDeletedDocs($templateList);
- $templateList = $this->doc->filterPrivDocs($templateList, 'template');
- $allModules = $this->doc->getTemplateModules();
- $allModules = array_column($allModules, 'fullName', 'id');
- foreach($templateList as $template) $template->moduleName = zget($allModules, $template->module);
- $docVersion = 0;
- if(is_string($docID) && strpos($docID, '_') !== false) list($docID, $docVersion) = explode('_', $docID);
- $this->view->title = $this->lang->doc->template;
- $this->view->libID = $libID;
- $this->view->users = $this->loadModel('user')->getPairs('noclosed,noletter');
- $this->view->templateList = $templateList;
- $this->view->docID = $docID;
- $this->view->docVersion = $docVersion;
- $this->view->orderBy = $orderBy;
- $this->view->recPerPage = $recPerPage;
- $this->view->pageID = $pageID;
- $this->view->mode = $mode;
- $this->view->hasModules = count($libModules) ? true : false;
- $this->view->scopes = $this->doc->getTemplateScopes();
- $this->display();
- }
- /**
- * 创建一个模板类型。
- * Add a template type.
- *
- * @param int $scope
- * @param int|string $parentModule
- * @access public
- * @return void
- */
- public function addTemplateType($scope, $parentModule = '')
- {
- $moduleList = $this->doc->getTemplateModules($scope, '1');
- if(!empty($_POST))
- {
- $this->lang->doc->name = $this->lang->docTemplate->typeName;
- $moduleData = form::data($this->config->doc->form->addTemplateType)
- ->setDefault('type', 'docTemplate')
- ->setDefault('path', '')
- ->get();
- $moduleData->grade = $moduleData->parent === 0 ? 1 : 2;
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $this->doc->addTemplateType($moduleData);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->docZen->responseAfterAddTemplateType($scope);
- }
- $moduleItems = array();
- if($parentModule === 0)
- {
- $moduleItems[] = array('value' => 0, 'text' => '/');
- }
- else
- {
- foreach($moduleList as $module) $moduleItems[] = array('value' => $module->id, 'text' => '/' . $module->name);
- $moduleItems[] = array('value' => 0, 'text' => '/');
- }
- $scopeList = $this->doc->getTemplateScopes();
- $this->view->scope = $scope;
- $this->view->scopes = $this->doc->getScopeItems($scopeList);
- $this->view->moduleItems = $moduleItems;
- $this->view->parentModule = $parentModule === '' ? current($moduleItems) : $parentModule;
- $this->display();
- }
- /**
- * 删除一个模板类型。
- * Delete a template type.
- *
- * @param int $moduleID
- * @access public
- * @return void
- */
- public function deleteTemplateType($moduleID)
- {
- $templates = $this->doc->getTemplatesByType($moduleID);
- if(empty($templates))
- {
- $this->dao->update(TABLE_MODULE)->set('deleted')->eq('1')->where('id')->eq($moduleID)->andWhere('type')->eq('docTemplate')->exec();
- $this->dao->update(TABLE_MODULE)->set('deleted')->eq('1')->where('parent')->eq($moduleID)->andWhere('type')->eq('docTemplate')->exec();
- return $this->sendSuccess(array('load' => true));
- }
- else
- {
- return $this->send(array('result' => 'fail', 'message' => $this->lang->docTemplate->errorDeleteType));
- }
- }
- /**
- * 编辑一个模板类型。
- * Edit a template type.
- *
- * @param int $moduleID
- * @access public
- * @return void
- */
- public function editTemplateType($moduleID)
- {
- echo $this->fetch('tree', 'edit', "moduleID={$moduleID}&type=docTemplate");
- }
- /**
- * 创建一个文档模板。
- * Create a doc template.
- *
- * @param int $moduleID
- * @access public
- * @return void
- */
- public function createTemplate($moduleID = 0)
- {
- if(!empty($_POST))
- {
- $this->lang->doc->title = $_POST['type'] == 'chapter' ? $this->lang->doc->chapterName : $this->lang->docTemplate->title;
- helper::setcookie('lastDocModule', $moduleID);
- $docData = form::data()
- ->setDefault('addedBy', $this->app->user->account)
- ->setDefault('editedBy', $this->app->user->account)
- ->get();
- if(empty($docData->module)) return $this->sendError(sprintf($this->lang->error->notempty, $this->lang->docTemplate->module));
- if(!empty($docData->parent))
- {
- $parentTemplate = $this->doc->fetchByID((int)$docData->parent);
- $docData->module = $parentTemplate->module;
- $docData->lib = (int)$parentTemplate->lib;
- $docData->acl = $parentTemplate->acl;
- $docData->templateType = $parentTemplate->templateType;
- }
- $docResult = $this->doc->create($docData);
- if(!$docResult || dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->docZen->responseAfterCreate($docResult, 'docTemplate');
- }
- }
- /**
- * 编辑一个文档。
- * Edit a doc.
- *
- * @param int $docID
- * @access public
- * @return void
- */
- public function editTemplate($docID)
- {
- $doc = $this->doc->getByID($docID);
- if(!empty($_POST))
- {
- $this->lang->doc->module = $this->lang->docTemplate->module;
- $changes = $files = array();
- $docData = form::data()
- ->setDefault('editedBy', $this->app->user->account)
- ->setIF(!isset($_POST['parent']), 'parent', $doc->parent)
- ->setIF(strpos(",$doc->editedList,", ",{$this->app->user->account},") === false, 'editedList', $doc->editedList . ",{$this->app->user->account}")
- ->setIF($this->post->type == 'chapter', 'content', $doc->content)
- ->setIF($this->post->type == 'chapter', 'rawContent', $doc->rawContent)
- ->remove('fromVersion')
- ->get();
- $result = $this->doc->update($docID, $docData);
- if(dao::isError())
- {
- if(!empty(dao::$errors['lib']) || !empty(dao::$errors['keywords'])) return $this->send(array('result' => 'fail', 'message' => dao::getError(), 'callback' => "zui.Modal.open({id: 'modalBasicInfo'});"));
- return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- }
- $changes = $result['changes'];
- $files = $result['files'];
- return $this->docZen->responseAfterEditTemplate($doc, $changes, $files);
- }
- }
- /**
- * 上传文档。
- * Upload docs.
- *
- * @param int $docID
- * @param string $objectType product|project|execution|custom
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $docType html|word|ppt|excel|attachment
- * @access public
- * @return void
- */
- public function uploadDocs($docID, $objectType, $objectID, $libID, $moduleID = 0, $docType = '')
- {
- if(!empty($_POST))
- {
- /* parent带‘m_’前缀为目录。*/
- if(isset($_POST['parent']) && strpos($_POST['parent'], 'm_') !== false)
- {
- $_POST['module'] = str_replace('m_', '', $_POST['parent']);
- $_POST['parent'] = 0;
- }
- $libID = (int)$this->post->lib;
- if(!$libID) return $this->send(array('result' => 'fail', 'message' => array('lib' => sprintf($this->lang->error->notempty, $this->lang->doc->lib))));
- $doclib = $this->loadModel('doc')->getLibByID($libID);
- $canVisit = $this->docZen->checkPrivForCreate($doclib, $objectType);
- if(!$canVisit) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->accessDenied));
- $moduleID = $this->post->module;
- helper::setcookie('lastDocModule', $moduleID);
- if(!isset($_POST['lib']) && strpos($_POST['module'], '_') !== false) list($_POST['lib'], $_POST['module']) = explode('_', $_POST['module']);
- if($_POST['type'] == 'attachment' && empty($_FILES['files']['name'][0]))
- {
- $this->config->doc->form->create['title']['required'] = false;
- $this->config->doc->form->create['title']['skipRequired'] = true;
- }
- $this->config->doc->create->requiredFields = trim(str_replace(array(',content,', ',keywords,'), ",", ",{$this->config->doc->create->requiredFields},"), ',');
- $docData = form::data(!empty($docID) ? $this->config->doc->form->edit : $this->config->doc->form->create)->remove('fromVersion')->get();
- if(empty($docID)) $docData->addedBy = $this->app->user->account;
- if(!empty($docID)) $docData->editedBy = $this->app->user->account;
- if(!empty($docID))
- {
- $docResult = $this->doc->update($docID, $docData);
- $docData->id = $docID;
- }
- elseif($this->post->uploadFormat == 'combinedDocs')
- {
- $docResult = $this->doc->create($docData);
- }
- else
- {
- $docResult = $this->doc->createSeperateDocs($docData);
- }
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return !empty($docID) ? $this->send($this->docZen->responseAfterEdit($docData, $docResult['changes'], $docResult['files'], $docResult['deletedFiles'])) : $this->docZen->responseAfterUploadDocs($docResult);
- }
- if($objectType == 'execution' && $libID) // 此时传入的objectID是projectID,用lib的信息更改回executionID
- {
- $lib = $this->doc->getLibByID($libID);
- $objectID = $this->doc->getObjectIDByLib($lib);
- }
- $this->docZen->assignVarsForUploadDocs($docID, $objectType, $objectID, $libID, $moduleID, $docType);
- $this->display();
- }
- /**
- * 创建一个文档。
- * Create a doc.
- *
- * @param string $objectType product|project|execution|custom
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $docType html|word|ppt|excel
- * @param int $appendLib
- * @access public
- * @return void
- */
- public function create($objectType, $objectID, $libID, $moduleID = 0, $docType = '', $appendLib = 0)
- {
- if(!empty($_POST))
- {
- /* parent带‘m_’前缀为目录。*/
- if(isset($_POST['parent']) && strpos($_POST['parent'], 'm_') !== false)
- {
- $_POST['module'] = str_replace('m_', '', $_POST['parent']);
- $_POST['parent'] = 0;
- }
- $libID = (int)$this->post->lib;
- $docLib = $this->loadModel('doc')->getLibByID($libID);
- if($docLib)
- {
- $canVisit = $this->docZen->checkPrivForCreate($docLib, $objectType);
- if(!$canVisit) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->accessDenied));
- }
- $moduleID = $this->post->module;
- helper::setcookie('lastDocModule', $moduleID);
- if(!isset($_POST['lib']) && strpos($_POST['module'], '_') !== false) list($_POST['lib'], $_POST['module']) = explode('_', $_POST['module']);
- if($_POST['type'] == 'chapter') $this->lang->doc->title = $this->lang->doc->chapterName;
- $docData = form::data()
- ->setDefault('addedBy', $this->app->user->account)
- ->setDefault('editedBy', $this->app->user->account)
- ->get();
- if($docData->parent && !$docData->module)
- {
- $parentDoc = $this->doc->getByID($docData->parent);
- $docData->module = $parentDoc->module;
- }
- $docResult = $this->doc->create($docData);
- if(!$docResult || dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->docZen->responseAfterCreate($docResult);
- }
- $this->docZen->assignVarsForCreate($objectType, $objectID, $libID, $moduleID, $docType);
- $lib = $this->view->lib;
- if(empty($lib)) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->errorEmptySpaceLib));
- $objectID = $this->view->objectID;
- $libData = $this->doc->setMenuByType($lib->type, (int)$objectID, (int)$lib->id, (int)$appendLib);
- if(is_string($libData)) return $this->locate($libData);
- list($libs, $libID, $object, $objectID, $objectDropdown) = $libData;
- if($this->config->edition != 'open') $this->loadModel('file');
- if($lib->type == 'custom' || $lib->type == 'mine') $this->view->spaces = $this->docZen->getAllSpaces($lib->type == 'mine' ? 'onlymine' : 'nomine');
- $this->view->title = zget($lib, 'name', '', $lib->name . $this->lang->hyphen) . $this->lang->doc->create;
- $this->view->object = $object;
- $this->view->objectDropdown = $objectDropdown;
- $this->view->libTree = $this->doc->getLibTree((int)$libID, $libs, $objectType, (int)$moduleID, (int)$objectID);
- $this->view->linkParams = "objectID={$objectID}&%s&browseType=&orderBy=status,id_desc¶m=0";
- if(!empty($objectType) && $objectType !== 'custom')
- {
- $objectIDVar = $objectType . 'ID';
- $this->view->$objectIDVar = $objectID;
- }
- $this->display();
- }
- /**
- * 编辑一个文档。
- * Edit a doc.
- *
- * @param int $docID
- * @param bool $comment
- * @param int $appendLib
- * @access public
- * @return void
- */
- public function edit($docID, $comment = false, $appendLib = 0)
- {
- $doc = $this->doc->getByID($docID);
- if(!empty($_POST))
- {
- /* parent带‘m_’前缀为目录。*/
- if(isset($_POST['parent']) && strpos($_POST['parent'], 'm_') !== false)
- {
- $_POST['module'] = str_replace('m_', '', $_POST['parent']);
- $_POST['parent'] = 0;
- }
- if(!$doc) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->errorNotFound));
- $isOpen = $doc->acl == 'open';
- $currentAccount = $this->app->user->account;
- $isAuthorOrAdmin = $doc->acl == 'private' && ($doc->addedBy == $currentAccount || $this->app->user->admin);
- $isInEditUsers = strpos(",$doc->users,", ",$currentAccount,") !== false;
- $isInEditGroups = false;
- if(!empty($doc->groups))
- {
- foreach($this->app->user->groups as $groupID)
- {
- if(strpos(",$doc->groups,", ",$groupID,") !== false) $isInEditGroups = true;
- }
- }
- if(!$isOpen && !$isAuthorOrAdmin && !$isInEditUsers && !$isInEditGroups) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->needEditable));
- if($doc->type == 'chapter') $this->lang->doc->title = $this->lang->doc->chapterName;
- $changes = $files = array();
- if($comment == false)
- {
- $docData = form::data()
- ->setDefault('editedBy', $this->app->user->account)
- ->setDefault('acl', $doc->acl)
- ->setIF(strpos(",$doc->editedList,", ",{$this->app->user->account},") === false, 'editedList', $doc->editedList . ",{$this->app->user->account}")
- ->setIF(!isset($_POST['module']), 'module', $doc->module)
- ->setIF(!isset($_POST['mailto']), 'mailto', $doc->mailto)
- ->setIF(!isset($_POST['users']), 'users', $doc->users)
- ->setIF(!isset($_POST['groups']), 'groups', $doc->groups)
- ->setIF(!isset($_POST['readUsers']), 'readUsers', $doc->readUsers)
- ->setIF(!isset($_POST['readGroups']), 'readGroups', $doc->readGroups)
- ->setIF(!isset($_POST['fromVersion']), 'fromVersion', $doc->fromVersion)
- ->removeIF($this->post->project === false, 'project')
- ->removeIF($this->post->product === false, 'product')
- ->removeIF($this->post->execution === false, 'execution')
- ->get();
- $result = $this->doc->update($docID, $docData);
- if(dao::isError())
- {
- if(!empty(dao::$errors['lib']) || !empty(dao::$errors['keywords'])) return $this->send(array('result' => 'fail', 'message' => dao::getError(), 'callback' => "zui.Modal.open({id: 'modalBasicInfo'});"));
- return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- }
- $changes = $result['changes'];
- $files = $result['files'];
- }
- return $this->send($this->docZen->responseAfterEdit($doc, $changes, $files));
- }
- /* Get doc and set menu. */
- $moduleID = (int)$doc->module;
- $libID = (int)$doc->lib;
- $lib = $this->doc->getLibByID($libID);
- $objectType = isset($lib->type) ? $lib->type : 'custom';
- $objectID = zget($lib, $lib->type, 0);
- if($lib->type == 'custom') $objectID = $lib->parent;
- if($doc->type == 'text' || $doc->type == 'article')
- {
- echo $this->fetch('doc', 'app', "type=$objectType&spaceID=$objectID&libID=$libID&moduleID=$doc->module&docID=$docID&mode=edit");
- return;
- }
- $libPairs = $this->doc->getLibs($lib->type, '', $doc->lib, $objectID);
- list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType($objectType, $objectID, (int)$doc->lib, (int)$appendLib);
- if($lib->type == 'custom' || $lib->type == 'mine') $this->view->spaces = $this->docZen->getAllSpaces($lib->type == 'mine' ? 'onlymine' : 'nomine');
- $this->docZen->setObjectsForEdit($lib->type, $objectID);
- $this->view->title = $lib->name . $this->lang->hyphen . $this->lang->doc->edit;
- $this->view->doc = $doc;
- $this->view->optionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- $this->view->type = $lib->type;
- $this->view->libs = $libPairs;
- $this->view->lib = $lib;
- $this->view->libID = $libID;
- $this->view->libTree = $this->doc->getLibTree($libID, $libs, $objectType, $moduleID, (int)$objectID, '', 0, $docID);
- $this->view->groups = $this->loadModel('group')->getPairs();
- $this->view->users = $this->user->getPairs('noletter|noclosed|nodeleted', $doc->users);
- $this->view->files = $this->loadModel('file')->getByObject('doc', $docID);
- $this->view->objectType = $objectType;
- $this->view->object = $object;
- $this->view->objectID = $objectID;
- $this->view->objectDropdown = $objectDropdown;
- $this->view->moduleID = $moduleID;
- $this->view->spaceType = $objectType;
- $this->view->productID = $doc->product;
- $this->view->projectID = $doc->project;
- $this->view->executionID = $doc->execution;
- $this->view->linkParams = "objectID={$objectID}&%s&browseType=&orderBy=status,id_desc¶m=0";
- $this->view->otherEditing = $this->doc->checkOtherEditing($docID);
- $this->display();
- }
- /**
- * 删除一个文档。
- * Delete a doc.
- *
- * @param int $docID
- * @access public
- * @return void
- */
- public function delete($docID)
- {
- $this->doc->delete(TABLE_DOC, $docID);
- /* Delete doc files. */
- $doc = $this->doc->getByID($docID);
- if($doc->files) $this->doc->deleteFiles(array_keys($doc->files));
- if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->sendSuccess(array('load' => $this->session->docList ? $this->session->docList : $this->createLink('doc', 'index')));
- }
- /**
- * 删除一个文档模板。
- * Delete a doctemplate.
- *
- * @param int $templateID
- * @access public
- * @return void
- */
- public function deleteTemplate($templateID)
- {
- $this->doc->deleteTemplate($templateID);
- /* Delete template files. */
- $template = $this->doc->getByID($templateID);
- if($template->files) $this->doc->deleteFiles(array_keys($template->files));
- if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $link = $this->createLink('doc', 'browseTemplate');
- return $this->sendSuccess(array('load' => $link));
- }
- /**
- * 收藏一个文档。
- * Collect a doc.
- *
- * @param int $objectID
- * @access public
- * @return void
- */
- public function collect($objectID)
- {
- $action = $this->doc->getActionByObject($objectID, 'collect');
- if($action)
- {
- $this->doc->deleteAction($action->id);
- $this->action->create('doc', $objectID, 'uncollected');
- }
- else
- {
- $this->doc->createAction($objectID, 'collect');
- $this->action->create('doc', $objectID, 'collected');
- }
- if($this->viewType == 'json') $this->send(array('status' => $action ? 'no' : 'yes'));
- return $this->send(array('result' => 'success', 'message' => $action ? $this->lang->doc->cancelCollection : $this->lang->doc->collectSuccess, 'load' => true, 'status' => $action ? 'no' : 'yes'));
- }
- /**
- *
- * AJAX: 获取对象的目录。
- * Ajax get modules by object.
- *
- * @param string $objectType project|product|custom|mine
- * @param int $objectID
- * @param string $docType doc|api
- * @param int $docID
- * @param int $libID
- * @access public
- * @return void
- */
- public function ajaxGetModules($objectType, $objectID, $docType = 'doc', $docID = 0, $libID = 0)
- {
- if($objectType != 'mine' && empty($objectID)) return print(json_encode(array()));
- if($docType == 'doc')
- {
- $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '';
- $libPairs = $this->doc->getLibs($objectType, $unclosed, '', (int)$objectID);
- }
- elseif($docType == 'api')
- {
- $libs = $this->doc->getApiLibs(0, $objectType, $objectID);
- $libPairs = array();
- foreach($libs as $lib) $libPairs[$lib->id] = $lib->name;
- }
- $libItems = array();
- foreach($libPairs as $id => $name) $libItems[] = array('text' => $name, 'value' => $id, 'keys' => $name);
- $moduleItems = array();
- $libID = $libID ? $libID : key($libPairs);
- if($libID)
- {
- $chapterAndDocs = $this->doc->getDocsOfLibs(array($libID), $objectType, $docID);
- $modulePairs = empty($libID) ? array() : $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- $nestedDocs = $this->doc->buildNestedDocs($chapterAndDocs, $modulePairs);
- $moduleItems = array_merge(array(array('text' => '/', 'value' => 'm_0')), array_values($nestedDocs));
- }
- return print(json_encode(array('libs' => $libItems, 'modules' => $moduleItems)));
- }
- /**
- *
- * AJAX: 获取范围下的类型。
- * Ajax get types of scope.
- *
- * @param int $libID
- * @access public
- * @return json
- */
- public function ajaxGetScopeTypes($libID = 0)
- {
- $optionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'docTemplate', 0, 'all', 'nodeleted', 'all');
- $types = array();
- foreach($optionMenu as $menuID => $menu)
- {
- if(empty($menuID)) continue;
- $types[] = array('text' => $menu, 'value' => $menuID, 'keys' => $menu);
- }
- return print(json_encode($types));
- }
- /**
- * AJAX: 通过空间类型获取文档库。
- * AJAX: Get libs by type.
- *
- * @param string $type mine|product|project|nolink|custom
- * @param string $docType doc|api
- * @access public
- * @return void
- * @param string $extra
- */
- public function ajaxGetLibsByType($type, $docType = 'doc', $extra = '')
- {
- $libPairs = array();
- if($docType == 'doc')
- {
- $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '';
- if($extra) $unclosed .= ",$extra";
- $libPairs = $this->doc->getLibs($type, $unclosed);
- }
- elseif($docType == 'api')
- {
- $libs = $this->doc->getApiLibs(0, 'nolink');
- $libPairs = array();
- foreach($libs as $libID => $lib) $libPairs[$libID] = $lib->name;
- }
- $libItems = array();
- foreach($libPairs as $id => $name) $libItems[] = array('text' => $name, 'value' => $id, 'keys' => $name);
- $moduleItems = array();
- $libID = key($libPairs);
- if($libID)
- {
- $optionMenu = $this->loadModel('tree')->getOptionMenu($libID, $docType, 0);
- foreach($optionMenu as $id => $name) $moduleItems[] = array('text' => $name, 'value' => $id, 'keys' => $name);
- }
- return print(json_encode(array('libs' => $libItems, 'modules' => $moduleItems)));
- }
- /**
- * Ajax: 获取白名单。
- * Ajax: Get whitelist.
- *
- * @param int $doclibID
- * @param string $acl open|custom|private
- * @param string $control user|group
- * @param int $docID
- * @access public
- * @return string
- */
- public function ajaxGetWhitelist($doclibID, $acl = '', $control = '', $docID = 0)
- {
- $doclib = $this->doc->getLibByID($doclibID);
- $users = $this->user->getPairs('noletter|noempty|noclosed');
- if($control == 'group')
- {
- if($doclib->acl == 'private') return print('private');
- $groupItems = array();
- $groups = $this->loadModel('group')->getPairs();
- foreach($groups as $groupID => $groupName) $groupItems[] = array('text' => $groupName, 'value' => $groupID, 'keys' => $groupName);
- return print(json_encode($groupItems));
- }
- if($doclib->acl == 'private') return print('private');
- $userItems = array();
- foreach($users as $account => $realname)
- {
- if($doclib->acl == 'private' && strpos($doclib->users, (string)$account) === false ) unset($users[$account]);
- $userItems[] = array('text' => $realname, 'value' => $account, 'keys' => $realname);
- }
- return print(json_encode($userItems));
- }
- /**
- * 附件库。
- * Show files.
- *
- * @param string $type
- * @param int $objectID
- * @param string $viewType
- * @param string $browseType
- * @param int $param
- * @param string $orderBy
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @param string $searchTitle
- * @access public
- * @return void
- */
- public function showFiles($type, $objectID, $viewType = '', $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1, $searchTitle = '')
- {
- $this->loadModel('file');
- if(empty($viewType)) $viewType = !empty($_COOKIE['docFilesViewType']) ? $this->cookie->docFilesViewType : 'list';
- helper::setcookie('docFilesViewType', $viewType, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
- $objects = $this->doc->getOrderedObjects($type, 'nomerge', $objectID);
- list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType($type, $objectID, 0);
- $object = $this->doc->getObjectByID($type, $objectID);
- if(empty($_POST) && !empty($searchTitle)) $this->post->title = $searchTitle;
- $this->session->set('storyList', $this->app->getURI(true), 'doc');
- $this->session->set('bugList', $this->app->getURI(true), 'doc');
- /* Load pager. */
- $rawMethod = $this->app->rawMethod;
- $this->app->rawMethod = 'showFiles';
- $this->app->loadClass('pager', $static = true);
- $pager = new pager($recTotal, $recPerPage, $pageID);
- $this->app->rawMethod = $rawMethod;
- $files = $this->doc->getLibFiles($type, $objectID, $browseType, (int)$param, $orderBy, $pager);
- $fileIcon = $this->doc->getFileIcon($files);
- $sourcePairs = $this->doc->getFileSourcePairs($files);
- if($this->app->tab != 'doc')
- {
- $objectVar = $this->app->tab . 'ID';
- $this->view->{$objectVar} = $objectID;
- }
- $this->docZen->buildSearchFormForShowFiles($type, $objectID, $viewType, $param);
- $this->view->title = $object->name;
- $this->view->type = $type;
- $this->view->object = $object;
- $this->view->files = $this->docZen->processFiles($files, $fileIcon, $sourcePairs);
- $this->view->fileIcon = $fileIcon;
- $this->view->sourcePairs = $sourcePairs;
- $this->view->users = $this->loadModel('user')->getPairs('noletter');
- $this->view->pager = $pager;
- $this->view->viewType = $viewType;
- $this->view->orderBy = $orderBy;
- $this->view->objectID = $objectID;
- $this->view->canBeChanged = common::canModify($type, $object); // Determines whether an object is editable.
- $this->view->summary = $this->doc->summary($files);
- $this->view->libTree = $this->doc->getLibTree(0, $libs, $type, 0, $objectID);
- $this->view->objectDropdown = $objectDropdown;
- $this->view->searchTitle = $searchTitle;
- $this->view->linkParams = "objectID=$objectID&%s&browseType=&orderBy=status,id_desc¶m=0";
- $this->view->spaceType = $type;
- $this->view->objectType = $type;
- $this->view->browseType = $browseType;
- $this->view->param = $param;
- $this->view->libID = 0;
- $this->view->moduleID = 0;
- $this->display();
- }
- /**
- * 文档详情页面。
- * Document details page.
- *
- * @param string|int $docID
- * @param int $version
- * @access public
- * @return void
- */
- public function view($docID = 0, $version = 0)
- {
- $isApi = is_string($docID) && strpos($docID, 'api.') === 0;
- $docID = $isApi ? (int)str_replace('api.', '', $docID) : (int)$docID;
- $doc = $isApi ? $this->loadModel('api')->getByID($docID, $version) : $this->doc->getByID($docID, $version, true);
- $docParam = $version ? ($docID . '_' . $version) : $docID;
- if($isApi) $docParam = 'api.' . $docParam;
- if(!$doc || !isset($doc->id))
- {
- if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found'));
- return $this->sendError($this->lang->notFound, $this->inlink('index'));
- }
- $_SESSION["doc_{$doc->id}_nopriv"] = '';
- if(!$isApi && !$this->doc->checkPrivDoc($doc))
- {
- $user = $this->loadModel('user')->getByID($doc->addedBy);
- $realname = $user->deleted ? $user->account : $user->realname;
- $errorMessage = empty($_SESSION["doc_{$doc->id}_nopriv"]) ? sprintf($this->lang->doc->cannotView, $realname) : $_SESSION["doc_{$doc->id}_nopriv"];
- unset($_SESSION["doc_{$doc->id}_nopriv"]);
- return $this->sendError($errorMessage, inlink('index'));
- }
- unset($_SESSION["doc_{$doc->id}_nopriv"]);
- if(!empty($doc->templateType))
- {
- echo $this->fetch('doc', 'browseTemplate', "libID=$doc->lib&type=all&docID=$docParam&orderBy=id_desc&recPerPage=20&pageID=1&mode=view");
- return;
- }
- $lib = $this->doc->getLibByID((int)$doc->lib);
- $objectType = isset($lib->type) ? $lib->type : 'custom';
- if($objectType == 'api')
- {
- if(isset($lib->product) && $lib->product) list($objectType, $objectID) = array('product', $lib->product);
- if(isset($lib->project) && $lib->project) list($objectType, $objectID) = array('project', $lib->project);
- }
- else
- {
- if($this->app->tab === 'project' && $objectType === 'execution') $objectType = 'project';
- $objectID = $this->doc->getObjectIDByLib($lib, $objectType);
- }
- /* Get doc. */
- if($docID) $this->doc->createAction($docID, 'view');
- $this->view->title = $doc->title;
- $libID = isset($lib->id) ? $lib->id : 0;
- echo $this->fetch('doc', 'app', "type=$objectType&spaceID=$objectID&libID=$libID&moduleID=$doc->module&docID=$docParam&mode=view");
- }
- /**
- * 产品/项目/执行/团队空间。
- * ProductSpace/ProjectSpace/ExecutionSpace/TeamSpace.
- *
- * @param string $type custom|product|project|execution|doctemplate
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $browseType all|draft|bysearch
- * @param string $orderBy
- * @param int $param
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- */
- public function tableContents($type = 'custom', $objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = 'order_asc', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
- {
- $this->docZen->setSpacePageStorage($type, $browseType, $objectID, $libID, $moduleID, $param);
- if($moduleID) $libID = $this->tree->getById($moduleID)->root;
- $isFirstLoad = $libID == 0 ? true : false;
- if(empty($browseType)) $browseType = 'all';
- $libData = $this->doc->setMenuByType($type, $objectID, $libID);
- if(is_string($libData)) return $this->locate($libData);
- list($libs, $libID, $object, $objectID, $objectDropdown) = $libData;
- $libID = (int)$libID;
- $lib = $this->doc->getLibByID($libID);
- $libType = isset($lib->type) && $lib->type == 'api' ? 'api' : 'lib';
- /* Build the search form. */
- $queryID = $browseType == 'bySearch' ? $param : 0;
- $queryID = $queryID == 'myQueryID' ? 0 : $queryID;
- $params = "objectID={$objectID}&libID={$libID}&moduleID=0&browseType=bySearch&orderBy={$orderBy}¶m=myQueryID";
- if($this->app->rawMethod == 'tablecontents') $params = "type={$type}&" . $params;
- $actionURL = $this->createLink($this->app->rawModule, $this->app->rawMethod, $params);
- if($libType == 'api') $this->loadModel('api')->buildSearchForm($lib, $queryID, $actionURL, $libs, $type);
- if($libType != 'api') $this->doc->buildSearchForm($libID, $libs, $queryID, $actionURL, $type);
- $this->docZen->assignApiVarForSpace($type, $browseType, $libType, $libID, $libs, $objectID, $moduleID, $queryID, $orderBy, $param, $recTotal, $recPerPage, $pageID);
- /* For product drop menu. */
- if(in_array($type, array('product', 'project', 'execution')))
- {
- $objectKey = $type . 'ID';
- $this->view->$objectKey = $objectID;
- }
- $isOrderByOrder = $orderBy == 'order_asc';
- $isNotCustomLib = $lib && !($lib->type == 'custom' && $lib->parent == 0);
- $canUpdateOrder = $isOrderByOrder && $isNotCustomLib && common::hasPriv('doc', 'sortDoc');
- $this->view->title = $type == 'custom' ? $this->lang->doc->tableContents : $object->name . $this->lang->hyphen . $this->lang->doc->tableContents;
- $this->view->type = $type;
- $this->view->objectType = $type;
- $this->view->spaceType = $type;
- $this->view->browseType = $browseType;
- $this->view->isFirstLoad = $isFirstLoad;
- $this->view->param = $queryID;
- $this->view->users = $this->user->getPairs('noletter');
- $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $moduleID, $objectID, $browseType, (int)$param);
- $this->view->libID = $libID;
- $this->view->moduleID = $moduleID;
- $this->view->objectDropdown = $objectDropdown;
- $this->view->lib = $lib;
- $this->view->libType = $libType;
- $this->view->objectID = $objectID;
- $this->view->orderBy = $orderBy;
- $this->view->release = $browseType == 'byrelease' ? $param : 0;
- $this->view->exportMethod = $libType == 'api' ? 'export' : $type . '2export';
- $this->view->linkParams = "objectID={$objectID}&%s&browseType=&orderBy={$orderBy}¶m=0";
- $this->view->canUpdateOrder = $canUpdateOrder;
- $this->display();
- }
- /**
- * 产品空间。
- * Product space.
- *
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $browseType all|draft|bysearch
- * @param string $orderBy
- * @param int $param
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- * @param string $mode
- * @param int $docID
- * @param string $search
- */
- public function productSpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = '', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1, $mode = '', $docID = 0, $search = '')
- {
- $noSpace = $this->app->tab != 'doc';
- $mode = empty($mode) && $noSpace ? 'list' : $mode;
- echo $this->fetch('doc', 'app', "type=product&spaceID=$objectID&libID=$libID&moduleID=$moduleID&docID=$docID&mode=$mode&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&filterType=$browseType&search=$search&noSpace=$noSpace");
- }
- /**
- * 项目空间。
- * Project space.
- *
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $browseType all|draft|bysearch
- * @param string $orderBy
- * @param int $param
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- * @param string $mode
- * @param int $docID
- * @param string $search
- */
- public function projectSpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = '', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1, $mode = '', $docID = 0, $search = '')
- {
- $noSpace = $this->app->tab != 'doc';
- $mode = empty($mode) && $noSpace ? 'list' : $mode;
- echo $this->fetch('doc', 'app', "type=project&spaceID=$objectID&libID=$libID&moduleID=$moduleID&docID=$docID&mode=$mode&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&filterType=$browseType&search=$search&noSpace=$noSpace");
- }
- /**
- * 团队空间。
- * Team space.
- *
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param string $browseType all|draft|bysearch
- * @param string $orderBy
- * @param int $param
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- * @param string $mode
- * @param int $docID
- * @param string $search
- */
- public function teamSpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = '', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1, $mode = '', $docID = 0, $search = '')
- {
- $this->docZen->initLibForTeamSpace();
- echo $this->fetch('doc', 'app', "type=custom&spaceID=$objectID&libID=$libID&moduleID=$moduleID&docID=$docID&mode=$mode&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&filterType=$browseType&search=$search");
- }
- /**
- * 设置选择文档库类型的范围。
- * Set the scope of the document library type to be selected.
- *
- * @param string $objectType
- * @param string $params
- * @param string $from
- * @access public
- * @return void
- */
- public function selectLibType($objectType = 'mine', $params = '', $from = '')
- {
- if($_POST)
- {
- $response = array();
- $libID = $_POST['lib'];
- $moduleID = $_POST['module'];
- $rootSpace = $_POST['rootSpace'];
- $docType = isset($_POST['type']) ? $_POST['type'] : 'doc';
- if(empty($libID)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->error->notempty, $this->lang->doc->lib)));
- $spaceID = 0;
- if(in_array($rootSpace, array('mine', 'custom', 'product', 'project')))
- {
- $methodList = array('mine' => 'mySpace', 'custom' => 'teamSpace', 'product' => 'productSpace', 'project' => 'projectSpace');
- $spaceID = $_POST[$rootSpace];
- $method = $methodList[$rootSpace];
- if($docType == 'doc') $url = $this->createLink('doc', $method, "objectID=$spaceID&libID=$libID&moduleID=$moduleID&browseType=all¶ms=0&orderBy=&recTotal=0&recPerPage=20&pageID=1&mode=create");
- else $url = helper::createLink('api', 'create', "libID=$libID&moduleID=$moduleID&space=$rootSpace");
- }
- elseif($rootSpace == 'api')
- {
- $url = helper::createLink('api', 'create', "libID=$libID&moduleID=$moduleID&space=$rootSpace");
- }
- $response['result'] = 'success';
- $response['closeModal'] = true;
- $response['callback'] = "redirectParentWindow(\"{$url}\", \"{$from}\", \"{$spaceID}\", \"{$libID}\", \"{$moduleID}\")";
- return $this->send($response);
- }
- $spaceList = $this->lang->doc->spaceList;
- $typeList = $this->lang->doc->types;
- if(!common::hasPriv('doc', 'create')) unset($spaceList['mine'], $spaceList['custom'], $typeList['doc']);
- if(!common::hasPriv('doc', 'mySpace')) unset($spaceList['mine']);
- if(!common::hasPriv('doc', 'productSpace')) unset($spaceList['product']);
- if(!common::hasPriv('doc', 'projectSpace')) unset($spaceList['project']);
- if(!common::hasPriv('doc', 'teamSpace')) unset($spaceList['custom']);
- if(!common::hasPriv('api', 'index')) unset($spaceList['api']);
- if(!common::hasPriv('api', 'create')) unset($spaceList['api'], $typeList['api']);
- if($this->config->vision == 'lite') unset($spaceList['api'], $spaceList['product'], $typeList['api']);
- $params = helper::safe64Decode($params);
- parse_str($params, $params);
- $this->view->params = $params;
- $this->view->objectType = $objectType;
- $this->view->spaceList = $spaceList;
- $this->view->typeList = $typeList;
- $this->view->from = $from;
- $this->display();
- }
- /**
- * Ajax: 根据对象类型设置下拉菜单。
- * Ajax: Set the drop-down menu according to the object type.
- *
- * @param string $objectType product|project
- * @param int $objectID
- * @param string $module
- * @param string $method
- * @access public
- * @return void
- */
- public function ajaxGetDropMenu($objectType, $objectID, $module, $method)
- {
- list($myObjects, $normalObjects, $closedObjects) = $this->doc->getOrderedObjects($objectType, 'nomerge', $objectID);
- $libData = $this->doc->setMenuByType($objectType, $objectID, 0);
- $this->view->objectType = $objectType;
- $this->view->objectID = $objectID;
- $this->view->libID = !empty($libData[1]) ? $libData[1] : 0;
- $this->view->module = $module;
- $this->view->method = $method == 'view' ? $objectType.'space' : $method;
- $this->view->normalObjects = $myObjects + $normalObjects;
- $this->view->closedObjects = $closedObjects;
- $this->view->objectsPinYin = common::convert2Pinyin($myObjects + $normalObjects + $closedObjects);
- $this->display();
- }
- /**
- * Ajax: 获取空间的下拉数据。
- * Ajax: Get the space drop down.
- *
- * @param int $libID
- * @param string $module
- * @param string $method
- * @access public
- * @return void
- * @param string $extra
- */
- public function ajaxGetSpaceMenu($libID, $module, $method, $extra = 'nomine')
- {
- $this->view->libID = $libID;
- $this->view->module = $module;
- $this->view->method = $method;
- $this->view->extra = $extra;
- $this->view->spaces = $this->docZen->getAllSpaces($extra);
- $this->display();
- }
- /**
- * Ajax: 获取执行下拉数据。
- * Ajax: Get the execution drop down by the projectID.
- *
- * @param int $projectID
- * @access public
- * @return string
- */
- public function ajaxGetExecution($projectID)
- {
- $json = array();
- $items = array();
- $executionPairs = $this->execution->getPairs($projectID, 'all', 'multiple,leaf,noprefix');
- foreach($executionPairs as $id => $name) $items[] = array('text' => $name, 'value' => $id, 'keys' => $name);
- $json['items'] = $items;
- $json['project'] = $this->project->getByID($projectID);
- return print(json_encode($json));
- }
- /**
- * 编辑一个目录。
- * Edit a catalog.
- *
- * @param int $moduleID
- * @param string $type doc|api
- * @access public
- * @return void
- */
- public function editCatalog($moduleID, $type)
- {
- echo $this->fetch('tree', 'edit', "moduleID={$moduleID}&type={$type}");
- }
- /**
- * 删除一个目录。
- * Delete a catalog.
- *
- * @param int $moduleID
- * @access public
- * @return void
- */
- public function deleteCatalog($moduleID)
- {
- echo $this->fetch('tree', 'delete', "moduleID={$moduleID}&confirm=yes");
- }
- /**
- * 设置左侧树中是否显示文档。
- * Set documents are show or hidden in the left tree.
- *
- * @access public
- * @return void
- */
- public function displaySetting()
- {
- $this->loadModel('setting');
- if($_POST)
- {
- $this->setting->setItem($this->app->user->account . '.doc.showDoc', $this->post->showDoc);
- return $this->sendSuccess(array('load' => true, 'closeModal' => true));
- }
- $showDoc = $this->setting->getItem('owner=' . $this->app->user->account . '&module=doc&key=showDoc');
- $this->view->showDoc = $showDoc === '0' ? '0' : '1';
- $this->display();
- }
- /**
- * 文档库排序
- * Doclib sorting.
- *
- * @access public
- * @return void
- */
- public function sortDoclib()
- {
- if($_POST)
- {
- $orders = $_POST['orders'];
- if(is_string($orders)) $orders = json_decode($orders, true);
- foreach($orders as $id => $order) $this->doc->updateDoclibOrder($id, (int)$order);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->send(array('result' => 'success', 'orders' => $orders));
- }
- }
- /**
- * 文档排序
- * Doc sorting.
- *
- * @access public
- * @return void
- */
- public function sortDoc()
- {
- if($_POST)
- {
- $orders = json_decode($this->post->orders, true);
- asort($orders);
- $orders = array_flip($orders);
- /* Sort by sorted id list. */
- $this->doc->updateDocOrder($orders);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->send(array('result' => 'success'));
- }
- }
- /**
- * 目录排序
- * Catalog sorting.
- *
- * @access public
- * @return void
- */
- public function sortCatalog()
- {
- if($_POST)
- {
- $orders = $_POST['orders'];
- $type = isset($_POST['type']) ? $_POST['type'] : 'doc';
- if(is_string($orders)) $orders = json_decode($orders, true);
- foreach($orders as $id => $order) $this->doc->updateOrder($id, (int)$order, $type);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->send(array('result' => 'success'));
- }
- }
- /**
- * 删除文档附件。
- * Delete file for doc.
- *
- * @param int $docID
- * @param int $fileID
- * @param string $confirm
- * @access public
- * @return void
- */
- public function deleteFile($docID, $fileID, $confirm = 'no')
- {
- $this->loadModel('file');
- if($confirm == 'no')
- {
- $formUrl = inlink('deleteFile', "docID={$docID}&fileID={$fileID}&confirm=yes");
- return $this->send(array('result' => 'fail', 'callback' => "zui.Modal.confirm('{$this->lang->file->confirmDelete}').then((res) => {if(res) $.ajaxSubmit({url: '$formUrl'});});"));
- }
- else
- {
- $this->doc->updateDocFile($docID, $fileID);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $file = $this->file->getById($fileID);
- $this->action->create($file->objectType, $file->objectID, 'deletedFile', '', $file->title);
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
- }
- }
- /**
- * 移动文档库
- * Move Lib.
- *
- * @param int $libID
- * @param string $targetSpace [int]
- * @access public
- * @return void
- */
- public function moveLib($libID, $targetSpace = '')
- {
- $lib = $this->doc->getLibByID($libID);
- if(empty($targetSpace)) $targetSpace = $this->doc->getLibTargetSpace($lib);
- $spaceType = $this->doc->getParamFromTargetSpace($targetSpace, 'type');
- if(!empty($lib->main)) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->errorEditSystemDoc));
- if(!empty($_POST))
- {
- $data = form::data()
- ->setIF($this->post->acl == 'open', 'groups', '')
- ->setIF($this->post->acl == 'open', 'users', '')
- ->get();
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $this->doc->moveLib($libID, $data);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $spaceTypeChanged = $spaceType != $lib->type;
- return $this->docZen->responseAfterMove($this->post->space, $libID, 0, $spaceTypeChanged);
- }
- $this->docZen->setAclForCreateLib($spaceType);
- $this->view->title = $this->lang->doc->moveLibAction;
- $this->view->spaces = $this->doc->getAllSubSpaces('all');
- $this->view->lib = $lib;
- $this->view->targetSpace = $targetSpace;
- $this->view->libType = $spaceType;
- $this->view->hasOthersDoc = $this->doc->hasOthersDoc($lib);
- $this->view->groups = $this->loadModel('group')->getPairs();
- $this->view->users = $this->loadModel('user')->getPairs('nocode|noclosed');
- $this->display();
- }
- /**
- * 移动文档
- * Move Document.
- *
- * @param int $docID
- * @param int $libID
- * @param string $spaceType
- * @param string $space
- * @access public
- * @return void
- */
- public function moveDoc($docID, $libID = 0, $spaceType = '', $space = '')
- {
- if($spaceType == 'quick')
- {
- $libID = 0;
- $space = $spaceType = '';
- }
- $doc = $this->doc->getByID($docID);
- if(empty($libID)) $libID = (int)$doc->lib;
- $lib = $this->doc->getLibByID($libID);
- if(empty($space))
- {
- if($lib->parent)
- {
- $space = $lib->parent;
- }
- else
- {
- if($lib->product) $space = $lib->product;
- if($lib->project) $space = $lib->project;
- }
- }
- if(empty($spaceType))
- {
- if($lib->parent)
- {
- $spaceType = $this->doc->getSpaceType($space);
- }
- else
- {
- if($lib->product && $lib->type == 'product') $spaceType = 'product';
- if($lib->project && $lib->type == 'project') $spaceType = 'project';
- }
- }
- if(!empty($_POST))
- {
- /* parent带‘m_’前缀为目录。*/
- if(isset($_POST['parent']) && strpos($_POST['parent'], 'm_') !== false)
- {
- $_POST['module'] = str_replace('m_', '', $_POST['parent']);
- $_POST['parent'] = 0;
- }
- $data = form::data()
- ->setIF($this->post->acl == 'open', 'groups', '')
- ->setIF($this->post->acl == 'open', 'users', '')
- ->setIF($this->post->acl == 'open', 'readGroups', '')
- ->setIF($this->post->acl == 'open', 'readUsers', '')
- ->setIF(in_array($spaceType, array('project', 'product')), $spaceType, $space)
- ->setIF($spaceType != 'project', 'project', 0)
- ->setIF($spaceType != 'product', 'product', 0)
- ->get();
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $changes = common::createChanges($doc, $data);
- if($changes)
- {
- $this->doc->doUpdateDoc($docID, $data);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $actionID = $this->loadModel('action')->create('doc', $docID, 'Moved', '', json_encode(array('from' => $doc->lib, 'to' => $data->lib)));
- $this->action->logHistory($actionID, $changes);
- }
- $spaceTypeChanged = $spaceType != $lib->type;
- return $this->docZen->responseAfterMove($this->post->space, $data->lib, $docID, $spaceTypeChanged);
- }
- $projects = $this->loadModel('project')->getPairsByProgram(0, 'all', false, 'order_asc');
- $products = $this->loadModel('product')->getPairs();
- $executions = $this->loadModel('execution')->getPairs(0, 'all', 'multiple,leaf');
- $libPairs = $this->doc->getLibPairs($spaceType, 'withObject', (int)$space, '', $products, $projects, $executions);
- if($spaceType == 'project') $libPairs += $this->doc->getExecutionLibPairsByProject((int)$space, 'withObject', $executions);
- if(!isset($libPairs[$libID])) $libID = (int)key($libPairs);
- $chapterAndDocs = $this->doc->getDocsOfLibs(array($libID), $spaceType, $docID);
- $modulePairs = empty($libID) ? array() : $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- if(isset($doc) && !empty($doc->parent) && !isset($chapterAndDocs[$doc->parent])) $chapterAndDocs[$doc->parent] = $this->doc->fetchByID($doc->parent);
- $chapterAndDocs = $this->doc->buildNestedDocs($chapterAndDocs, $modulePairs);
- $this->view->docID = $docID;
- $this->view->libID = $libID;
- $this->view->spaceType = $spaceType;
- $this->view->space = $space;
- $this->view->doc = $doc;
- $this->view->spaces = $this->doc->getAllSubSpaces($this->app->tab != 'doc' ? $this->app->tab : 'all');
- $this->view->libPairs = $libPairs;
- $this->view->optionMenu = $chapterAndDocs;
- $this->view->groups = $this->loadModel('group')->getPairs();
- $this->view->users = $this->loadModel('user')->getPairs('nocode|noclosed');
- $this->display();
- }
- /**
- * 移动文档模板
- * Move document template.
- *
- * @param int $docID
- * @access public
- * @return void
- */
- public function moveTemplate($docID)
- {
- $doc = $this->doc->getByID($docID);
- if(!empty($_POST))
- {
- $this->lang->doc->module = $this->lang->docTemplate->module;
- $data = form::data()
- ->setIF(!isset($_POST['lib']), 'lib', $doc->lib)
- ->setIF(!isset($_POST['module']), 'module', $doc->module)
- ->setIF(!isset($_POST['parent']), 'parent', $doc->parent)
- ->setIF(!isset($_POST['acl']), 'acl', $doc->acl)
- ->get();
- $changes = common::createChanges($doc, $data);
- if($changes)
- {
- $basicInfoChanged = false;
- foreach($changes as $change)
- {
- if(in_array($change['field'], array('module', 'lib', 'acl'))) $basicInfoChanged = true;
- }
- $this->doc->doUpdateDoc($docID, $data, $basicInfoChanged);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $actionID = $this->loadModel('action')->create('docTemplate', $docID, 'Moved', '', json_encode(array('from' => $doc->lib, 'to' => $data->lib)));
- $this->action->logHistory($actionID, $changes);
- }
- $newDoc = $this->doc->getByID($docID);
- if(!$this->doc->checkPrivDoc($newDoc))
- {
- $link = $this->createLink('doc', 'browseTemplate', "libID={$doc->lib}&type=all&docID=0&orderBy=id_desc&recPerPage=20&pageID=1&mode=list");
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => $link, 'doc' => $newDoc));
- }
- $docAppAction = array('executeCommand', 'handleMovedDoc', array($docID, '1', $data->lib));
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'docApp' => $docAppAction));
- }
- if(!empty($doc->parent))
- {
- $parentDoc = $this->doc->fetchByID($doc->parent);
- $chapterAndDocs = $this->doc->getDocsOfLibs(array($doc->lib), 'template', $docID, true);
- if(!isset($chapterAndDocs[$doc->parent])) $chapterAndDocs[$doc->parent] = $parentDoc;
- $parentPath = trim($parentDoc->path, ',') . ",";
- $topTemplate = substr($parentPath, 0, strpos($parentPath, ',')) ?: $doc->parent;
- foreach($chapterAndDocs as $key => $template)
- {
- if(strpos(",{$template->path},", ",{$topTemplate},") === false) unset($chapterAndDocs[$key]);
- }
- $this->view->chapterAndDocs = $this->doc->buildNestedDocs($chapterAndDocs);
- }
- $scopeList = $this->doc->getTemplateScopes();
- $this->view->scopeItems = $this->doc->getScopeItems($scopeList);
- $this->view->doc = $doc;
- $this->view->docID = $docID;
- $this->view->modules = $this->loadModel('tree')->getOptionMenu((int)$doc->lib, 'docTemplate', 0, 'all', 'nodeleted', 'all');
- $this->display();
- }
- /**
- * Batch move document.
- *
- * @param string $type
- * @param string $encodeDocIdList
- * @param int $spaceID
- * @param int $libID
- * @param int $moduleID
- * @access public
- * @return void
- */
- public function batchMoveDoc($type, $encodeDocIdList, $spaceID, $libID = 0, $moduleID = 0)
- {
- $docIdList = json_decode(base64_decode($encodeDocIdList), true);
- if(!$docIdList) $this->locate($this->createLink('doc', 'app', "type={$type}&spaceID={$spaceID}&libID={$libID}&moduleID={$moduleID}"));
- $spaces = $this->doc->getAllSubSpaces();
- if($type == 'quick')
- {
- list($type, $spaceID) = explode('.', key($spaces));
- $spaceID = (int) $spaceID;
- }
- if($_POST)
- {
- $oldDocList = $this->doc->getDocsByIdList($docIdList);
- $data = form::data()
- ->setIF($type == 'mine' || $this->post->acl == 'open', 'groups', '')
- ->setIF($type == 'mine' || $this->post->acl == 'open', 'users', '')
- ->setIF(in_array($type, array('project', 'product')), $type, $spaceID)
- ->get();
- $this->doc->batchMoveDoc($data, $docIdList);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $this->docZen->recordBatchMoveActions($oldDocList, $data);
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'docApp' => array('load', null, null, null, array('noLoading' => true, 'picks' => 'doc'))));
- }
- $projects = $this->loadModel('project')->getPairsByProgram(0, 'all', false, 'order_asc');
- $products = $this->loadModel('product')->getPairs();
- $executions = $this->loadModel('execution')->getPairs(0, 'all', 'multiple,leaf');
- $libPairs = $this->doc->getLibPairs($type, 'withObject', $spaceID, '', $products, $projects, $executions);
- if($type == 'project') $libPairs += $this->doc->getExecutionLibPairsByProject($spaceID, 'withObject', $executions);
- if(!isset($libPairs[$libID])) $libID = (int)key($libPairs);
- $docList = $this->doc->getByIdList($docIdList);
- $docAclList = array_column($docList, 'acl');
- $this->view->title = $this->lang->doc->batchMove;
- $this->view->encodeDocIdList = $encodeDocIdList;
- $this->view->type = $type;
- $this->view->spaceID = $spaceID;
- $this->view->libID = $libID;
- $this->view->moduleID = $moduleID;
- $this->view->spaces = $spaces;
- $this->view->libPairs = $libPairs;
- $this->view->optionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- $this->view->groups = $this->loadModel('group')->getPairs();
- $this->view->users = $this->loadModel('user')->getPairs('nocode|noclosed');
- $this->view->hasOpenDoc = in_array('open', $docAclList);
- $this->display();
- }
- /**
- * Ajax: 检查对象权限。
- * Ajax check object priv.
- *
- * @param string $objectType
- * @param int $objectID
- * @access public
- * @return void
- */
- public function ajaxCheckObjectPriv($objectType, $objectID)
- {
- $accounts = $this->post->users;
- $object = $this->doc->getObjectByID($objectType, $objectID);
- if(empty($object)) return print('');
- if($object->acl == 'open') return print('');
- $this->loadModel('user');
- $userViews = $this->dao->select('*')->from(TABLE_USERVIEW)->where('account')->in($accounts)->fetchAll('account');
- $userPairs = $this->dao->select('account,realname')->from(TABLE_USER)->where('account')->in($accounts)->fetchPairs('account', 'realname');
- $denyUsers = array();
- foreach($accounts as $account)
- {
- if(strpos(",{$this->app->company->admins}", ",{$account},") !== false) continue;
- $userView = zget($userViews, $account, '');
- if(empty($userView)) $userView = $this->user->computeUserView($account, true);
- if($objectType == 'product' && isset($userView->products) && strpos(",{$userView->products},", ",{$objectID},") === false) $denyUsers[$account] = zget($userPairs, $account);
- if($objectType == 'project' && isset($userView->projects) && strpos(",{$userView->projects},", ",{$objectID},") === false) $denyUsers[$account] = zget($userPairs, $account);
- if($objectType == 'execution' && isset($userView->sprints) && strpos(",{$userView->sprints},", ",{$objectID},") === false) $denyUsers[$account] = zget($userPairs, $account);
- }
- if(empty($denyUsers)) return print('');
- if(isset($this->lang->doc->whitelistDeny[$objectType])) return printf($this->lang->doc->whitelistDeny[$objectType], implode('、', $denyUsers));
- }
- /**
- * Ajax: 检查库权限。
- * Ajax check lib priv.
- *
- * @param int $libID
- * @access public
- * @return void
- */
- public function ajaxCheckLibPriv($libID)
- {
- $accounts = $this->post->users;
- $lib = $this->doc->getLibByID($libID);
- if(empty($lib)) return print('');
- if($lib->acl == 'open') return print('');
- if($lib->acl == 'default' && strpos("product,project,execution", $lib->type) !== false) return $this->ajaxCheckObjectPriv($lib->type, zget($lib, $lib->type, 0));
- $authAccounts[$lib->addedBy] = $lib->addedBy;
- if($lib->groups) $authAccounts += $this->loadModel('group')->getGroupAccounts(explode(',', $lib->groups));
- if($lib->users)
- {
- foreach(array_filter(explode(',', $lib->users)) as $account) $authAccounts[$account] = $account;
- }
- $userPairs = $this->dao->select('account,realname')->from(TABLE_USER)->where('account')->in($accounts)->fetchPairs('account', 'realname');
- $denyUsers = array();
- foreach($accounts as $account)
- {
- if(strpos(",{$this->app->company->admins}", ",{$account},") !== false) continue;
- if(!isset($authAccounts[$account])) $denyUsers[$account] = zget($userPairs, $account);
- }
- if(empty($denyUsers)) return print('');
- if(isset($this->lang->doc->whitelistDeny['doc'])) return printf($this->lang->doc->whitelistDeny['doc'], implode('、', $denyUsers));
- }
- /**
- * Doc app view.
- * 文档应用视图。
- *
- * @param string $type
- * @param int $spaceID
- * @param int $libID
- * @param int $moduleID
- * @param mixed $docID
- * @param string $mode
- * @param string $orderBy
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @param string $filterType
- * @param string $search
- * @param string $param
- * @access public
- * @access public
- * @return void
- * @param bool $noSpace
- */
- public function app($type = 'mine', $spaceID = 0, $libID = 0, $moduleID = 0, $docID = 0, $mode = '', $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1, $filterType = '', $search = '', $noSpace = false)
- {
- $isNotDocTab = $this->app->tab != 'doc';
- if(empty($mode))
- {
- $showList = $noSpace || !empty($spaceID);
- $mode = ($isNotDocTab || $type == 'execution' || $showList) ? 'list' : 'home';
- }
- $this->app->loadLang('file');
- /* For product drop menu. */
- if(!$isNotDocTab && $type == 'execution')
- {
- $execution = $this->loadModel('execution')->getByID($spaceID);
- $type = 'project';
- $spaceID = $execution->project;
- }
- if($isNotDocTab && in_array($type, array('product', 'project', 'execution')))
- {
- if($type == 'product' && $spaceID == 0) $spaceID = (int)$this->cookie->preProductID;
- $this->doc->setMenuByType($type, $spaceID, $libID);
- $objectKey = $type . 'ID';
- $this->view->$objectKey = $spaceID;
- $this->view->$type = $this->doc->fetchByID($spaceID, $type);
- }
- if($type == 'mine') $menuType = 'my';
- else $menuType = $type == 'custom' ? 'team' : $type;
- if(isset($this->lang->doc->menu->{$menuType})) $this->lang->doc->menu->{$menuType}['alias'] .= ',' . $this->app->rawMethod;
- $docVersion = 0;
- $isApi = is_string($docID) && strpos($docID, 'api.') === 0;
- if($isApi) $docID = str_replace('api.', '', $docID);
- if(is_string($docID) && strpos($docID, '_') !== false) list($docID, $docVersion) = explode('_', $docID);
- $this->view->type = $type;
- $this->view->spaceID = $spaceID;
- $this->view->libID = $libID;
- $this->view->moduleID = $moduleID;
- $this->view->docID = $isApi ? "api.$docID" : (int)$docID;
- $this->view->docVersion = (int)$docVersion;
- $this->view->mode = $mode;
- $this->view->filterType = $filterType;
- $this->view->search = $search;
- $this->view->recTotal = $recTotal;
- $this->view->recPerPage = $recPerPage;
- $this->view->pageID = $pageID;
- $this->view->orderBy = $orderBy;
- $this->view->objectType = $type;
- $this->view->noSpace = $noSpace;
- $this->view->objectID = $spaceID;
- $this->view->users = $this->dao->select('account,realname,avatar')->from(TABLE_USER)->where('deleted')->eq('0')->fetchAll('account');
- $this->view->title = isset($this->lang->doc->spaceList[$type]) ? $this->lang->doc->spaceList[$type] : $this->lang->doc->common;
- $this->display();
- }
- /**
- * Doc quick access page.
- * 快捷访问页面。
- *
- * @param string $type 'view'|'collect'|'createdby'|'editedby'
- * @param int $docID
- * @param string $orderBy
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- */
- public function quick($type = 'view', $docID = 0, $orderBy = '', $recPerPage = 20, $pageID = 1)
- {
- if(empty($orderBy)) $orderBy = 'id_desc';
- if(!isset($this->config->doc->quickMenu[$type])) $type = 'view';
- $menu = $this->config->doc->quickMenu[$type];
- $currentUser = $this->app->user->account;
- $docs = $this->doc->getMineList($type, 'all', 0, $orderBy);
- $order = 0;
- foreach($docs as $doc)
- {
- $order++;
- unset($doc->draft);
- $doc->originLIb = $doc->lib;
- $doc->lib = $menu['id'];
- $doc->order = $order;
- $doc->isCollector = strpos($doc->collector, ',' . $currentUser . ',') !== false;
- }
- $this->view->docs = $docs;
- $this->view->menu = $menu;
- $this->view->type = $type;
- $this->view->docID = $docID;
- $this->view->orderBy = $orderBy;
- $this->view->recPerPage = $recPerPage;
- $this->view->pageID = $pageID;
- $this->view->users = $this->dao->select('account,realname,avatar')->from(TABLE_USER)->where('deleted')->eq('0')->fetchAll('account');
- $this->view->title = $this->lang->doc->quick;
- $this->display();
- }
- /**
- * Ajax: Get doc space data.
- * Ajax: 获取文档空间数据。
- *
- * @param string $type
- * @param int $space
- * @access public
- * @return void
- * @param int $spaceID
- * @param string $picks
- * @param int $libID
- */
- public function ajaxGetSpaceData($type = 'custom', $spaceID = 0, $picks = '', $libID = 0)
- {
- $this->doc->setMenuByType($type, (int)$spaceID, 0);
- if($type === 'template')
- {
- $modules = $this->doc->getTemplateModules();
- $moduleNames = array_column($modules, 'fullName', 'id');
- $templateList = $this->doc->getDocTemplateList(0, 'all');
- $templateList = $this->doc->filterDeletedDocs($templateList);
- $templateList = $this->doc->filterPrivDocs($templateList, 'template');
- foreach($templateList as $template)
- {
- $template->moduleName = zget($moduleNames, $template->module);
- }
- $data = array('spaceID' => $spaceID, 'docs' => array_values($templateList));
- $data['spaces'][] = array('name' => $this->lang->doc->template, 'id' => $spaceID);
- $data['modules'] = $modules;
- $scopeList = $this->doc->getTemplateScopes();
- foreach($scopeList as $scope) $data['libs'][] = array('id' => $scope->id, 'name' => $scope->name, 'space' => $spaceID);
- }
- else
- {
- $noPicks = empty($picks);
- $picks = $noPicks ? '' : ",$picks,";
- list($spaces, $spaceID) = $this->doc->getSpaces($type, $spaceID);
- $data = array('spaceID' => (int)$spaceID);
- $libs = $this->doc->getLibsOfSpace($type, $spaceID);
- $libIds = array_keys($libs);
- foreach($libs as $lib) $lib->order = (int)$lib->order;
- if($noPicks || strpos($picks, ',space,') !== false) $data['spaces'] = $spaces;
- if($noPicks || strpos($picks, ',lib,') !== false) $data['libs'] = array_values($libs);
- if($noPicks || strpos($picks, ',module,') !== false) $data['modules'] = array_values($this->doc->getModulesOfLibs($libIds));
- if($noPicks || strpos($picks, ',doc,') !== false) $data['docs'] = array_values($this->doc->getDocsOfLibs($libIds + array($spaceID), $type));
- }
- $this->send($data);
- }
- /**
- * Ajax: Get doc data.
- * Ajax: 获取文档数据。
- *
- * @param string|int $docID
- * @param int $version
- * @access public
- * @return void
- */
- public function ajaxGetDoc($docID, $version = 0, $details = 'no')
- {
- if(is_string($docID) && strpos($docID, 'api.') === 0)
- {
- $apiID = (int)str_replace('api.', '', $docID);
- echo $this->fetch('api', 'ajaxGetApi', "apiID=$apiID&version=$version");
- return;
- }
- $docID = (int)$docID;
- $doc = $this->doc->getByID($docID, $version);
- $doc->lib = (int)$doc->lib;
- $doc->module = (int)$doc->module;
- $doc->privs = array('edit' => common::hasPriv('doc', 'edit', $doc) && $doc->acl == 'open');
- $doc->editors = $this->doc->getEditors($docID);
- $doc->draft = $doc->status == 'draft' ? $this->doc->getContent($docID, 0) : null;
- $lib = $this->doc->getLibByID((int)$doc->lib);
- $objectType = $lib->type;
- if(empty($objectType))
- {
- if($lib->execution) $objectType = 'execution';
- elseif($lib->project) $objectType = 'project';
- elseif($lib->product) $objectType = 'product';
- }
- $this->doc->setDocPriv($doc, $objectType);
- if($details == 'yes')
- {
- $objectID = $this->doc->getObjectIDByLib($lib, $objectType);
- $object = in_array($objectType, array('product', 'project', 'execution')) ? $this->doc->getObjectByID($objectType, $objectID) : $this->doc->getLibByID((int)$objectID);
- $doc->libInfo = $lib;
- $doc->objectType = $objectType;
- $doc->object = $object;
- }
- if(!empty($doc->rawContent))
- {
- $doc->html = $doc->content;
- $doc->content = $doc->rawContent;
- unset($doc->rawContent);
- if(empty($doc->templateType) && $doc->contentType == 'doc' && preg_match('/ src="{([0-9]+)(\.(\w+))?}" /', $doc->html))
- {
- $doc->contentType = 'html';
- $doc->content = preg_replace('/ src="{([0-9]+)(\.(\w+))?}" /', ' src="' . helper::createLink('file', 'read', "fileID=$1", "$3") . '" ', $doc->html);
- }
- }
- if($docID) $this->doc->createAction($docID, 'view');
- $this->send($doc);
- }
- /**
- * Get files by type and objectID.
- * 根据类型和对象ID获取文件列表。
- *
- * @param string $type
- * @param int $objectID
- * @param string $browseType
- * @param string $orderBy
- * @param int $recTotal
- * @param int $recPerPage
- * @param int $pageID
- * @access public
- * @return void
- */
- public function ajaxGetFiles($type, $objectID, $browseType = '', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 9999, $pageID = 1)
- {
- if(common::hasPriv('doc', 'showFiles'))
- {
- /* Load pager. */
- $rawMethod = $this->app->rawMethod;
- $this->app->rawMethod = 'showFiles';
- $this->app->loadClass('pager', true);
- $pager = new pager($recTotal, $recPerPage, $pageID);
- $this->app->rawMethod = $rawMethod;
- $files = $this->doc->getLibFiles($type, $objectID, $browseType, 0, $orderBy, $pager);
- $sourcePairs = $this->doc->getFileSourcePairs($files);
- $files = $this->docZen->processFiles($files, array(), $sourcePairs, true);
- echo json_encode(array_values($files)); // $this->send($files); not work.
- }
- else
- {
- echo '[]';
- }
- }
- /**
- * Get lib summaries by space type and space list.
- *
- * @param string $spaceType
- * @param string $spaceList
- * @access public
- * @return void
- */
- public function ajaxGetLibSummaries($spaceType, $spaceList)
- {
- $libsMap = $this->doc->getLibsOfSpaces($spaceType, $spaceList, 0);
- echo json_encode($libsMap);
- }
- /**
- * Ajax modal for setting doc basic info.
- * 设置文档基本信息的模态框。
- *
- * @param string $objectType
- * @param int $objectID
- * @param int $libID
- * @param int $moduleID
- * @param int $docID
- * @param string $isDraft
- * @access public
- * @param int $parentID
- * @param string $modalType
- */
- public function setDocBasic($objectType, $objectID, $libID = 0, $moduleID = 0, $parentID = 0, $docID = 0, $isDraft = 'no', $modalType = 'doc')
- {
- $this->doc->setMenuByType($objectType, (int)$objectID, (int)$libID);
- $lib = $libID ? $this->doc->getLibByID($libID) : '';
- $isCreate = empty($docID);
- if($docID) $doc = $this->doc->getByID($docID);
- $title = $this->lang->settings;
- if($modalType == 'doc')
- {
- $title = $parentID ? $this->lang->doc->addSubDoc : $this->lang->doc->create;
- if($objectType == 'template') $title = $parentID ? $this->lang->docTemplate->addSubDocTemplate : $this->lang->docTemplate->create;
- if($isDraft == 'no') $title = $this->lang->settings;
- }
- if($modalType == 'chapter') $title = $isCreate ? $this->lang->doc->addChapter : $this->lang->doc->editChapter;
- if($isCreate)
- {
- if(!$moduleID && $docID)
- {
- $parentDoc = $this->doc->getByID($parentID);
- $moduleID = $parentDoc->module;
- }
- if(empty($objectID) && $lib) $objectID = $this->doc->getObjectIDByLib($lib);
- if($lib && $objectType != 'template') $objectType = $lib->type;
- $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '';
- $libPairs = $this->doc->getLibs($objectType, "{$unclosed}", $libID, $objectID);
- $moduleID = $moduleID ? (int)$moduleID : (int)$this->cookie->lastDocModule;
- if(!$libID && !empty($libPairs)) $libID = key($libPairs);
- if(empty($lib) && $libID) $lib = $this->doc->getLibByID($libID);
- if($objectType == 'custom' || $objectType == 'mine') $this->view->spaces = $this->doc->getSubSpacesByType($objectType, true);
- $this->docZen->setObjectsForCreate($objectType, empty($lib) ? null : $lib, $unclosed, $objectID);
- $this->view->optionMenu = empty($libID) ? array() : $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- }
- else
- {
- $parentID = (int)$doc->parent;
- $moduleID = (int)$doc->module;
- $libID = (int)$doc->lib;
- $lib = $this->doc->getLibByID($libID);
- if($lib && $objectType != 'template') $objectType = $lib->type;
- $objectID = $this->doc->getObjectIDByLib($lib);
- $libPairs = $this->doc->getLibs($objectType, '', $libID, $objectID);
- if($objectType == 'custom' || $objectType == 'mine') $this->view->spaces = $this->doc->getSubSpacesByType($objectType, true);
- $this->docZen->setObjectsForEdit($objectType, $objectID);
- $this->view->doc = $doc;
- $this->view->optionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- }
- $chapterAndDocs = $this->doc->getDocsOfLibs(array($libID), $objectType, $docID, $objectType == 'template' ? true : false);
- if($objectType == 'template' && !empty($moduleID)) $chapterAndDocs = array_filter($chapterAndDocs, function ($docInfo) use ($moduleID) {
- return $docInfo->module == $moduleID;
- });
- if(isset($doc) && !empty($doc->parent) && !isset($chapterAndDocs[$doc->parent])) $chapterAndDocs[$doc->parent] = $this->doc->fetchByID($doc->parent);
- $modulePairs = empty($libID) || $modalType == 'chapter' || $objectType == 'template' ? array() : $this->loadModel('tree')->getOptionMenu($libID, 'doc', 0);
- if($objectType == 'template' && !empty($parentID))
- {
- $parentDoc = $this->doc->fetchByID($parentID);
- $parentPath = trim($parentDoc->path, ',') . ",";
- $topTemplate = substr($parentPath, 0, strpos($parentPath, ',')) ?: $parentID;
- foreach($chapterAndDocs as $key => $template)
- {
- if(strpos(",{$template->path},", ",{$topTemplate},") === false) unset($chapterAndDocs[$key]);
- }
- }
- $this->view->chapterAndDocs = $this->doc->buildNestedDocs($chapterAndDocs, $modulePairs);
- if($objectType == 'template')
- {
- $scopeList = $this->doc->getTemplateScopes();
- $this->view->scopeItems = $this->doc->getScopeItems($scopeList);
- }
- else
- {
- $this->view->users = $this->user->getPairs('nocode|noclosed|nodeleted');
- $this->view->groups = $this->loadModel('group')->getPairs();
- }
- $docTitle = '';
- if(!empty($doc))
- {
- $docTitle = $doc->title;
- }
- elseif($this->post->title)
- {
- $docTitle = $this->post->title;
- }
- $this->view->docID = $docID;
- $this->view->docTitle = $docTitle;
- $this->view->mode = empty($docID) ? 'create' : 'edit';
- $this->view->libID = $libID;
- $this->view->moduleID = $moduleID;
- $this->view->objectID = $objectID;
- $this->view->objectType = $objectType;
- $this->view->lib = $lib;
- $this->view->libs = $libPairs;
- $this->view->parentID = $parentID;
- $this->view->isDraft = $isDraft == 'yes';
- $this->view->title = $title;
- $this->view->modalType = $modalType;
- $this->view->isCreate = $isCreate;
- $this->display();
- }
- /**
- * AJAX: 通过文档ID获取Confluence子文档。
- * AJAX: Get confluence subdocuments by doc ID.
- *
- * @param int $originPageID 当前Confluence文档ID
- * @param string $title 选择的父页面标题
- * @param int $level 展示层级
- * @access public
- * @return void
- */
- public function ajaxGetConfluenceChildren($originPageID, $title, $level = PHP_INT_MAX)
- {
- $parentID = $this->doc->getDocIdByTitle($originPageID, $title);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $docs = $this->docZen->getDocChildrenByRecursion((int)$parentID, $level);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->send(array('result' => 'success', 'data' => $docs));
- }
- /**
- * Ajax: Retrieve corresponding user information in the Zen path through Confluence user ID.
- * Ajax: 通过Confluence用户ID获取在禅道中的对应用户信息。
- *
- * @param string $username
- * @access public
- * @return void
- */
- public function ajaxGetConfluenceUser($username)
- {
- $user = $this->doc->getUserByConfluenceUserID($username);
- return $this->send(array('result' => 'success', 'data'=> $user));
- }
- /**
- * Manage scope.
- * 维护范围。
- *
- * @access public
- * @return void
- */
- public function manageScope()
- {
- $scopeList = $this->doc->getTemplateScopes();
- if(!empty($_POST))
- {
- $scopes = $this->post->scopes;
- $oldScopes = $newScopes = array();
- foreach($scopes as $index => $name)
- {
- if(empty(trim($name))) continue;
- $scopeID = $_POST['id'][$index];
- if($scopeID)
- {
- $oldScopes[$scopeID] = $name;
- }
- else
- {
- $newScopes[$index] = $name;
- }
- }
- $deletedScopes = array_diff(array_keys($scopeList), array_keys($oldScopes));
- if(!empty($deletedScopes)) $this->doc->deleteTemplateScopes($deletedScopes);
- if(dao::isError()) return $this->sendError(array('message' => dao::getError()));
- if(!empty($oldScopes)) $this->doc->updateTemplateScopes($oldScopes);
- if(dao::isError()) return $this->sendError(array('message' => dao::getError()));
- if(!empty($newScopes)) $this->doc->insertTemplateScopes($newScopes);
- if(dao::isError()) return $this->sendError(array('message' => dao::getError()));
- return $this->sendSuccess(array('closeModal' => true, 'load' => true));
- }
- $this->view->scopeList = $scopeList;
- $this->display();
- }
- /**
- * AJAX: Judge can be deleted scope.
- * AJAX: 判断范围是否可以被删除。
- *
- * @param int $scopeID
- * @access public
- * @return array
- */
- public function ajaxJudgeCanBeDeleted($scopeID = 0)
- {
- if(empty($scopeID)) return $this->sendSuccess(array('message' => 'success'));
- $templates = $this->doc->getScopeTemplates(array($scopeID));
- if(!empty($templates[$scopeID])) return $this->sendError($this->lang->docTemplate->scopeHasTemplateTips);
- $modules = $this->doc->getTemplateModules($scopeID);
- if(!empty($modules)) return $this->sendError($this->lang->docTemplate->scopeHasModuleTips);
- return $this->sendSuccess(array('message' => 'success'));
- }
- }
|