diff --git a/config/config.php b/config/config.php index 6935b8fcec..8820ae3218 100644 --- a/config/config.php +++ b/config/config.php @@ -169,6 +169,7 @@ define('TABLE_EXTENSION', '`' . $config->db->prefix . 'extension`'); define('TABLE_CRON', '`' . $config->db->prefix . 'cron`'); define('TABLE_MAILQUEUE', '`' . $config->db->prefix . 'mailqueue`'); define('TABLE_BLOCK', '`' . $config->db->prefix . 'block`'); +define('TABLE_DOCCONTENT', '`' . $config->db->prefix . 'doccontent`'); if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`'); $config->objectTables['product'] = TABLE_PRODUCT; diff --git a/db/update8.2.6.sql b/db/update8.2.6.sql index ee611ba304..71dc76120d 100644 --- a/db/update8.2.6.sql +++ b/db/update8.2.6.sql @@ -2,3 +2,22 @@ ALTER TABLE `zt_doclib` ADD `product` mediumint(8) unsigned NOT NULL AFTER `id`, ADD `project` mediumint(8) unsigned NOT NULL AFTER `product`, ADD `groups` varchar(255) COLLATE 'utf8_general_ci' NOT NULL AFTER `name`, ADD `users` text COLLATE 'utf8_general_ci' NOT NULL AFTER `groups`; + +CREATE TABLE IF NOT EXISTS `zt_doccontent` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `doc` mediumint(8) unsigned NOT NULL, + `title` varchar(255) NOT NULL, + `digest` varchar(255) NOT NULL, + `content` text NOT NULL, + `files` text NOT NULL, + `type` varchar(10) NOT NULL, + `version` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `doc_version` (`doc`,`version`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +ALTER TABLE `zt_doc` ADD `version` smallint unsigned NOT NULL DEFAULT '1' AFTER `editedDate`; +ALTER TABLE `zt_doc` ADD `groups` varchar(255) NOT NULL AFTER `editedDate`, +ADD `users` text NOT NULL AFTER `groups`; +ALTER TABLE `zt_doc` DROP `type`; +ALTER TABLE `zt_doclib` ADD `acl` varchar(10) COLLATE 'utf8_general_ci' NOT NULL DEFAULT 'public' AFTER `name`; +ALTER TABLE `zt_doc` ADD `acl` varchar(10) NOT NULL DEFAULT 'public' AFTER `editedDate`; diff --git a/module/doc/config.php b/module/doc/config.php index c2f4da974e..e71b77984a 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -13,7 +13,7 @@ $config->doc->create->requiredFields = 'title'; $config->doc->edit->requiredFields = 'title'; $config->doc->editor = new stdclass(); -$config->doc->editor->create = array('id' => 'content', 'tools' => 'fullTools'); +$config->doc->editor->create = array('id' => 'content,digest', 'tools' => 'fullTools'); $config->doc->editor->edit = array('id' => 'content,digest,comment', 'tools' => 'fullTools'); $config->doc->search['module'] = 'doc'; @@ -22,28 +22,22 @@ $config->doc->search['fields']['id'] = $lang->doc->id; $config->doc->search['fields']['keywords'] = $lang->doc->keywords; $config->doc->search['fields']['product'] = $lang->doc->product; $config->doc->search['fields']['project'] = $lang->doc->project; -$config->doc->search['fields']['type'] = $lang->doc->type; $config->doc->search['fields']['module'] = $lang->doc->module; $config->doc->search['fields']['lib'] = $lang->doc->lib; -$config->doc->search['fields']['digest'] = $lang->doc->digest; -$config->doc->search['fields']['content'] = $lang->doc->content; -$config->doc->search['fields']['url'] = $lang->doc->url; $config->doc->search['fields']['addedBy'] = $lang->doc->addedBy; $config->doc->search['fields']['addedDate'] = $lang->doc->addedDate; $config->doc->search['fields']['editedBy'] = $lang->doc->editedBy; $config->doc->search['fields']['editedDate'] = $lang->doc->editedDate; +$config->doc->search['fields']['version'] = $lang->doc->version; $config->doc->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->doc->search['params']['keywords'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->doc->search['params']['product'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->doc->search['params']['module'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->doc->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => ''); -$config->doc->search['params']['type'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->doc->types); $config->doc->search['params']['lib'] = array('operator' => '=', 'control' => 'select', 'values' => '' ); -$config->doc->search['params']['digest'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); -$config->doc->search['params']['content'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); -$config->doc->search['params']['url'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->doc->search['params']['addedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->doc->search['params']['addedDate'] = array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date'); $config->doc->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->doc->search['params']['editedDate'] = array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->doc->search['params']['version'] = array('operator' => '=', 'control' => 'input', 'values' => ''); diff --git a/module/doc/control.php b/module/doc/control.php index d81014ace0..3db90c4e52 100644 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -234,16 +234,13 @@ class doc extends control */ public function create($libID, $moduleID = 0, $productID = 0, $projectID = 0, $from = 'doc') { - $projectID = (int)$projectID; - $lib = $this->doc->getLibByID($libID); - $type = $lib->product ? 'product' : ($lib->project ? 'project' : 'custom'); - $this->libs = $this->doc->getLibs($type); if(!empty($_POST)) { $docResult = $this->doc->create(); if(!$docResult or dao::isError()) die(js::error(dao::getError())); $docID = $docResult['id']; + $lib = $this->doc->getLibByID($this->post->lib); if($docResult['status'] == 'exists') { echo js::alert(sprintf($this->lang->duplicate, $this->lang->doc->common)); @@ -251,34 +248,33 @@ class doc extends control } $this->action->create('doc', $docID, 'Created'); - if($from == 'product') $link = $this->createLink('product', 'doc', "productID={$this->post->product}"); - if($from == 'project') $link = $this->createLink('project', 'doc', "projectID={$this->post->project}"); + if($from == 'product') $link = $this->createLink('product', 'doc', "productID={$lib->product}"); + if($from == 'project') $link = $this->createLink('project', 'doc', "projectID={$lib->project}"); if($from == 'doc') { - $productID = intval($this->post->product); - $projectID = intval($this->post->project); - $vars = "libID=$libID&moduleID={$this->post->module}&productID=$productID&projectID=$projectID"; + $vars = "libID=$libID&browseType=byModule&moduleID={$this->post->module}"; $link = $this->createLink('doc', 'browse', $vars); } die(js::locate($link, 'parent')); } - $this->loadModel('product'); - $this->loadModel('project'); + $lib = $this->doc->getLibByID($libID); + $type = $lib->product ? 'product' : ($lib->project ? 'project' : 'custom'); + $this->libs = $this->doc->getLibs($type); /* According the from, set menus. */ if($from == 'product') { $this->lang->doc->menu = $this->lang->product->menu; $this->lang->doc->menuOrder = $this->lang->product->menuOrder; - $this->product->setMenu($this->product->getPairs(), $productID); + $this->product->setMenu($this->product->getPairs(), $lib->product); $this->lang->set('menugroup.doc', 'product'); } elseif($from == 'project') { $this->lang->doc->menu = $this->lang->project->menu; $this->lang->doc->menuOrder = $this->lang->project->menuOrder; - $this->project->setMenu($this->project->getPairs('nocode'), $projectID); + $this->project->setMenu($this->project->getPairs('nocode'), $lib->project); $this->lang->set('menugroup.doc', 'project'); } else @@ -286,28 +282,14 @@ class doc extends control $this->doc->setMenu($this->libs, $libID); } - /* Get the modules. */ - if($libID == 'product' or $libID == 'project') + $libs = $this->libs; + if($productID) { - $moduleOptionMenu = $this->tree->getOptionMenu(0, $libID . 'doc', $startModuleID = 0); + $libs = $this->doc->getLibsByObject('product', $productID, 'onlylib'); } - else + elseif($projectID) { - $moduleOptionMenu = $this->tree->getOptionMenu($libID, 'customdoc', $startModuleID = 0); - } - - $products = $projectID == 0 ? $this->product->getPairs() : $this->project->getProducts($projectID, false); - if($libID == 'product' and empty($products)) - { - echo js::alert($this->lang->doc->errorEmptyProduct); - die(js::locate('back')); - } - - $projects = $this->project->getPairs('all'); - if($libID == 'project' and empty($projects)) - { - echo js::alert($this->lang->doc->errorEmptyProject); - die(js::locate('back')); + $libs = $this->doc->getLibsByObject('project', $projectID, 'onlylib'); } $this->view->title = $this->libs[$libID] . $this->lang->colon . $this->lang->doc->create; @@ -315,12 +297,12 @@ class doc extends control $this->view->position[] = $this->lang->doc->create; $this->view->libID = $libID; - $this->view->moduleOptionMenu = $moduleOptionMenu; + $this->view->libs = $libs; + $this->view->moduleOptionMenu = $this->tree->getOptionMenu($libID, 'doc', $startModuleID = 0); $this->view->moduleID = $moduleID; - $this->view->productID = $productID; - $this->view->projectID = $projectID; - $this->view->products = $products; - $this->view->projects = $projects; + $this->view->type = $type; + $this->view->groups = $this->loadModel('group')->getPairs(); + $this->view->users = $this->user->getPairs('nocode'); $this->display(); } @@ -336,9 +318,10 @@ class doc extends control { if(!empty($_POST)) { - $changes = $this->doc->update($docID); + $result = $this->doc->update($docID); if(dao::isError()) die(js::error(dao::getError())); - $files = $this->loadModel('file')->saveUpload('doc', $docID); + $changes = $result['changes']; + $files = $result['files']; if($this->post->comment != '' or !empty($changes) or !empty($files)) { $action = !empty($changes) ? 'Edited' : 'Commented'; @@ -353,28 +336,22 @@ class doc extends control /* Get doc and set menu. */ $doc = $this->doc->getById($docID); $libID = $doc->lib; - $this->doc->setMenu($this->libs, $libID); - /* Get modules. */ - if($libID == 'product' or $libID == 'project') - { - $moduleOptionMenu = $this->tree->getOptionMenu(0, $libID . 'doc', $startModuleID = 0); - } - else - { - $moduleOptionMenu = $this->tree->getOptionMenu($libID, 'customdoc', $startModuleID = 0); - } + $lib = $this->doc->getLibByID($libID); + $type = $lib->product ? 'product' : ($lib->project ? 'project' : 'custom'); + $this->libs = $this->doc->getLibs($type); + $this->doc->setMenu($this->libs, $libID); $this->view->title = $this->libs[$libID] . $this->lang->colon . $this->lang->doc->edit; $this->view->position[] = html::a($this->createLink('doc', 'browse', "libID=$libID"), $this->libs[$libID]); $this->view->position[] = $this->lang->doc->edit; $this->view->doc = $doc; - $this->view->libID = $libID; $this->view->libs = $this->libs; - $this->view->moduleOptionMenu = $moduleOptionMenu; - $this->view->products = $doc->project == 0 ? $this->product->getPairs() : $this->project->getProducts($doc->project, false); - $this->view->projects = $this->loadModel('project')->getPairs('all'); + $this->view->moduleOptionMenu = $this->tree->getOptionMenu($libID, 'doc', $startModuleID = 0); + $this->view->type = $type; + $this->view->groups = $this->loadModel('group')->getPairs(); + $this->view->users = $this->user->getPairs('nocode'); $this->display(); } @@ -385,27 +362,19 @@ class doc extends control * @access public * @return void */ - public function view($docID) + public function view($docID, $version = 0) { /* Get doc. */ - $doc = $this->doc->getById($docID, true); + $doc = $this->doc->getById($docID, $version, true); if(!$doc) die(js::error($this->lang->notFound) . js::locate('back')); /* Check priv when lib is product or project. */ - $systemLib = ($doc->lib == 'project' or $doc->lib == 'product') ? $doc->lib : ''; - if($systemLib and $doc->{$systemLib} and !$this->{$systemLib}->checkPriv($this->{$systemLib}->getById($doc->{$systemLib}))) - { - echo(js::alert($this->lang->error->accessDenied)); - die(js::locate('back')); - } - - /* Get library. */ - $lib = $doc->libName; - if($doc->lib == 'product') $lib = $doc->productName; - if($doc->lib == 'project') $lib = $doc->productName . $this->lang->arrow . $doc->projectName; + $lib = $this->doc->getLibByID($doc->lib); + $type = $lib->product ? 'product' : ($lib->project ? 'project' : 'custom'); + $this->libs = $this->doc->getLibs($type); /* Set menu. */ - $this->doc->setMenu($this->libs, $doc->lib); + $this->doc->setMenu($this->libs, $doc->lib, $type); $this->view->title = "DOC #$doc->id $doc->title - " . $this->libs[$doc->lib]; $this->view->position[] = html::a($this->createLink('doc', 'browse', "libID=$doc->lib"), $this->libs[$doc->lib]); @@ -413,6 +382,8 @@ class doc extends control $this->view->doc = $doc; $this->view->lib = $lib; + $this->view->type = $type; + $this->view->version = $version ? $version : $doc->version; $this->view->actions = $this->loadModel('action')->getList('doc', $docID); $this->view->users = $this->user->getPairs('noclosed,noletter'); $this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID); @@ -508,6 +479,19 @@ class doc extends control $this->display(); } + /** + * Ajax get modules by libID. + * + * @param int $libID + * @access public + * @return void + */ + public function ajaxGetModules($libID) + { + $moduleOptionMenu = $this->tree->getOptionMenu($libID, 'doc', $startModuleID = 0); + die(html::select('module', $moduleOptionMenu, 0, "class='form-control'")); + } + /** * Show all libs by type. * diff --git a/module/doc/css/view.css b/module/doc/css/view.css index b880b028b4..4f675fa44a 100644 --- a/module/doc/css/view.css +++ b/module/doc/css/view.css @@ -1,3 +1 @@ -.file-content fieldset .files-list{font-size:16px;} -.file-content fieldset .files-list i.icon-file-text{font-size:16px;} #url-content{v:e­xpressio !important} diff --git a/module/doc/js/common.js b/module/doc/js/common.js index 171519c944..0577677165 100644 --- a/module/doc/js/common.js +++ b/module/doc/js/common.js @@ -1,34 +1,23 @@ -/* Load the products of the roject. */ -function loadProducts(project) +function loadModules(libID) { - link = createLink('project', 'ajaxGetProducts', 'projectID=' + project); - $('#productBox').load(link, function(){$('#productBox').find('select').chosen(defaultChosenOptions)}); + link = createLink('doc', 'ajaxGetModules', 'libID=' + libID); + $('#moduleBox').load(link, function(){$('#moduleBox').find('select').chosen(defaultChosenOptions)}); } -/* Set doc type. */ -function setType(type) +function toggleAcl(acl) { - if(type == 'url') + if(acl == 'custom') { - $('#urlBox').show(); - $('#fileBox').hide(); - $('#contentBox').hide(); - } - else if(type == 'text') - { - $('#urlBox').hide(); - $('#fileBox').hide(); - $('#contentBox').show(); + $('#whiteListBox').removeClass('hidden'); } else { - $('#urlBox').hide(); - $('#fileBox').show(); - $('#contentBox').hide(); + $('#whiteListBox').addClass('hidden'); } } $(document).ready(function() { + $('[data-id="create"] a').modalTrigger({type: 'iframe', width: 800}); if(typeof(type) != 'undefined') $('#modulemenu .nav li[data-id="' + type + '"]').addClass('active'); }); diff --git a/module/doc/js/create.js b/module/doc/js/create.js index af308440d6..424fa8a892 100644 --- a/module/doc/js/create.js +++ b/module/doc/js/create.js @@ -1 +1,4 @@ -loadProducts($('#project').val()); +$(function() +{ + toggleAcl($('#acl').val()); +}) diff --git a/module/doc/js/createlib.js b/module/doc/js/createlib.js index e50c342b91..30445cd5b5 100644 --- a/module/doc/js/createlib.js +++ b/module/doc/js/createlib.js @@ -19,4 +19,5 @@ $(function() $('table tr.project').addClass('hidden'); } }) + toggleAcl($('#acl').val()); }); diff --git a/module/doc/js/edit.js b/module/doc/js/edit.js index 70afdd7caf..424fa8a892 100644 --- a/module/doc/js/edit.js +++ b/module/doc/js/edit.js @@ -1,49 +1,4 @@ -function loadModule(lib) -{ - if(lib == 'product') - { - type = 'productdoc'; - root = 0; - } - else if(lib == 'project') - { - type = 'projectdoc'; - root = 0; - } - else - { - type = 'customdoc'; - root = lib; - } - - $.get(createLink('tree', 'ajaxGetOptionMenu', 'rootID=' + root + '&viewType=' + type), function(data) - { - $('#module').closest('td').html(data); - $("#module").removeAttr('onchange'); - $("#module").chosen(defaultChosenOptions); - }); -} - -function changeByLib(lib) -{ - if(lib == 'product') - { - $('#product').closest('tr').show(); - $('#project').closest('tr').hide(); - } - else if(lib == 'project') - { - $('#product').closest('tr').show(); - $('#project').closest('tr').show(); - } - else - { - $('#product').closest('tr').hide(); - $('#project').closest('tr').hide(); - } -} - $(function() { - changeByLib($('#lib').val()); + toggleAcl($('#acl').val()); }) diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php index 6c39847923..22faacb2bd 100644 --- a/module/doc/lang/zh-cn.php +++ b/module/doc/lang/zh-cn.php @@ -28,9 +28,11 @@ $lang->doc->addedBy = '由谁添加'; $lang->doc->addedDate = '添加时间'; $lang->doc->editedBy = '由谁编辑'; $lang->doc->editedDate = '编辑时间'; +$lang->doc->version = '版本号'; $lang->doc->basicInfo = '基本信息'; $lang->doc->deleted = '已删除'; $lang->doc->fileObject = '所属对象'; +$lang->doc->whiteList = '白名单'; $lang->doc->moduleDoc = '按模块浏览'; $lang->doc->searchDoc = '搜索'; @@ -64,9 +66,9 @@ $lang->doc->libTypeList['custom'] = '自定义文档库'; $lang->doc->systemLibs['product'] = $lang->productCommon . '文档库'; $lang->doc->systemLibs['project'] = $lang->projectCommon . '文档库'; -$lang->doc->types['file'] = '文件'; -$lang->doc->types['url'] = '链接'; -$lang->doc->types['text'] = '网页'; +$lang->doc->aclList['public'] = '公开'; +$lang->doc->aclList['custom'] = '自定义'; +$lang->doc->aclList['private'] = '私有'; $lang->doc->confirmDelete = "您确定删除该文档吗?"; $lang->doc->confirmDeleteLib = "您确定删除该文档库吗?"; @@ -74,13 +76,16 @@ $lang->doc->errorEditSystemDoc = "系统文档库无需修改。"; $lang->doc->errorEmptyProduct = "没有{$lang->productCommon},无法创建文档"; $lang->doc->errorEmptyProject = "没有{$lang->projectCommon},无法创建文档"; $lang->doc->errorEmptySysLib = "系统文档库不能全部删除!"; +$lang->doc->accessDenied = "您没有权限访问该文档库!"; +$lang->doc->noMatched = '找不到包含"%s"的文档库'; $lang->doc->placeholder = new stdclass(); $lang->doc->placeholder->url = '相应的链接地址'; $lang->doclib = new stdclass(); -$lang->doclib->name = '文档库名称'; -$lang->doclib->acl = '文档库权限'; -$lang->doclib->group = '分组'; -$lang->doclib->user = '用户'; +$lang->doclib->name = '文档库名称'; +$lang->doclib->control = '访问控制'; +$lang->doclib->acl = '权限'; +$lang->doclib->group = '分组'; +$lang->doclib->user = '用户'; $lang->doclib->files = '附件库'; diff --git a/module/doc/model.php b/module/doc/model.php index 6f879a8b0f..c2e94b40da 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -26,6 +26,15 @@ class docModel extends model { $currentModule = 'doc'; $currentMethod = 'browse'; + if($libID) + { + $lib = $this->getLibById($libID); + if(!$this->checkPriv($lib)) + { + echo(js::alert($this->lang->doc->accessDenied)); + die(js::locate('back')); + } + } $selectHtml = "{$libs[$libID]}
"; common::setMenuVars($this->lang->doc->menu, 'list', $selectHtml); @@ -83,6 +92,7 @@ class docModel extends model ->join('users', ',') ->remove('libType') ->get(); + if($lib->acl == 'private') $lib->users = $this->app->user->account; $this->dao->insert(TABLE_DOCLIB)->data($lib)->autoCheck() ->batchCheck('name', 'notempty') ->exec(); @@ -101,6 +111,7 @@ class docModel extends model $libID = (int)$libID; $oldLib = $this->getLibById($libID); $lib = fixer::input('post')->join('groups', ',')->join('users', ',')->get(); + if($lib->acl == 'private') $lib->users = $this->app->user->account; $this->dao->update(TABLE_DOCLIB)->data($lib)->autoCheck() ->batchCheck('name', 'notempty') ->where('id')->eq($libID) @@ -149,9 +160,14 @@ class docModel extends model { if($this->session->docQuery == false) $this->session->set('docQuery', ' 1 = 1'); } - $docQuery = str_replace("`product` = 'all'", '1', $this->session->docQuery); // Search all producti. - $docQuery = str_replace("`project` = 'all'", '1', $docQuery); // Search all project. - $docs = $this->dao->select('*')->from(TABLE_DOC)->where($docQuery)->andWhere('deleted')->eq(0)->orderBy($sort)->page($pager)->fetchAll(); + $docQuery = str_replace("`product` = 'all'", '1', $this->session->docQuery); // Search all producti. + $docQuery = str_replace("`project` = 'all'", '1', $docQuery); // Search all project. + $condition = $this->buildConditionSQL(); + $docs = $this->dao->select('*')->from(TABLE_DOC)->where($docQuery) + ->beginIF($condition)->andWhere("($condition)")->fi() + ->andWhere('deleted')->eq(0) + ->orderBy($sort)->page($pager) + ->fetchAll(); } $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'doc'); @@ -174,9 +190,11 @@ class docModel extends model */ public function getDocs($libID, $module, $orderBy, $pager) { + $condition = $this->buildConditionSQL(); return $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere('lib')->in($libID) + ->beginIF($condition)->andWhere("($condition)")->fi() ->beginIF($module)->andWhere('module')->in($module)->fi() ->orderBy($orderBy) ->page($pager) @@ -191,21 +209,42 @@ class docModel extends model * @access public * @return void */ - public function getById($docID, $setImgSize = false) + public function getById($docID, $version = 0, $setImgSize = false) { - $doc = $this->dao->select('*') - ->from(TABLE_DOC) - ->where('id')->eq((int)$docID) - ->fetch(); - if(!$doc) return false; + $doc = $this->dao->select('*')->from(TABLE_DOC)->where('id')->eq((int)$docID)->fetch(); + if(!$doc or !$this->checkPriv($doc)) return false; + $version = $version ? $version : $doc->version; + $docContent = $this->dao->select('*')->from(TABLE_DOCCONTENT)->where('doc')->eq($doc->id)->andWhere('version')->eq($version)->fetch(); + + /* When file change then version add one. */ + $files = $this->loadModel('file')->getByObject('doc', $docID); + $docFiles = array(); + foreach($files as $file) + { + $file->webPath = $this->file->webPath . $file->pathname; + $file->realPath = $this->file->savePath . $file->pathname; + if(strpos(",{$docContent->files},", ",{$file->id},") !== false) $docFiles[$file->id] = $file; + } + + if($version == $doc->version and ((empty($docContent->files) and $docFiles) OR ($docContent->files and count(explode(',', $docContent->files)) != count($docFiles)))) + { + unset($docContent->id); + $doc->version += 1; + $docContent->version = $doc->version; + $docContent->files = join(',', array_keys($docFiles)); + $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec(); + $this->dao->update(TABLE_DOC)->set('version')->eq($doc->version)->where('id')->eq($doc->id)->exec(); + } + + $doc->digest = isset($docContent->digest) ? $docContent->digest : ''; + $doc->content = isset($docContent->content) ? $docContent->content : ''; + $doc->type = isset($docContent->type) ? $docContent->type : ''; if($setImgSize) $doc->content = $this->loadModel('file')->setImgSize($doc->content); - $doc->files = $this->loadModel('file')->getByObject('doc', $docID); + $doc->files = $docFiles; - $doc->libName = ''; $doc->productName = ''; $doc->projectName = ''; $doc->moduleName = ''; - if($doc->lib) $doc->libName = $this->dao->findByID($doc->lib)->from(TABLE_DOCLIB)->fetch('name'); if($doc->product) $doc->productName = $this->dao->findByID($doc->product)->from(TABLE_PRODUCT)->fetch('name'); if($doc->project) $doc->projectName = $this->dao->findByID($doc->project)->from(TABLE_PROJECT)->fetch('name'); if($doc->module) $doc->moduleName = $this->dao->findByID($doc->module)->from(TABLE_MODULE)->fetch('name'); @@ -224,29 +263,46 @@ class docModel extends model $doc = fixer::input('post') ->add('addedBy', $this->app->user->account) ->add('addedDate', $now) - ->setDefault('product, project, module', 0) + ->add('version', 1) + ->setDefault('product,project,module', 0) ->stripTags($this->config->doc->editor->create['id'], $this->config->allowedTags) - ->encodeURL('url') - ->cleanInt('product, project, module') - ->remove('files, labels,uid') + ->cleanInt('product,project,module') + ->join('groups', ',') + ->join('users', ',') + ->remove('files,labels,uid') ->get(); + if($doc->acl == 'private') $doc->users = $this->app->user->account; $condition = "lib = '$doc->lib' AND module = $doc->module"; $result = $this->loadModel('common')->removeDuplicate('doc', $doc, $condition); if($result['stop']) return array('status' => 'exists', 'id' => $result['duplicate']); + $lib = $this->getLibByID($doc->lib); $doc = $this->loadModel('file')->processEditor($doc, $this->config->doc->editor->create['id'], $this->post->uid); - $this->dao->insert(TABLE_DOC) - ->data($doc) - ->autoCheck() + $doc->product = $lib->product; + $doc->project = $lib->project; + + $docContent = new stdclass(); + $docContent->title = $doc->title; + $docContent->digest = $doc->digest; + $docContent->content = $doc->content; + $docContent->version = 1; + $docContent->type = 'html'; + unset($doc->digest); + unset($doc->content); + + $this->dao->insert(TABLE_DOC)->data($doc)->autoCheck() ->batchCheck($this->config->doc->create->requiredFields, 'notempty') - ->check('title', 'unique', $condition) ->exec(); if(!dao::isError()) { $docID = $this->dao->lastInsertID(); $this->file->updateObjectID($this->post->uid, $docID, 'doc'); - $this->file->saveUpload('doc', $docID); + $files = $this->file->saveUpload('doc', $docID); + + $docContent->doc = $docID; + $docContent->files = join(',', array_keys($files)); + $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec(); return array('status' => 'new', 'id' => $docID); } return false; @@ -263,31 +319,58 @@ class docModel extends model { $oldDoc = $this->getById($docID); $now = helper::now(); - $doc = fixer::input('post') - ->cleanInt('module') - ->setDefault('module', 0) - ->setIF($this->post->lib == 'product', 'project', 0) - ->setIF(($this->post->lib != 'product' and $this->post->lib != 'project'), 'project', 0) - ->setIF(($this->post->lib != 'product' and $this->post->lib != 'project'), 'product', 0) + $doc = fixer::input('post')->setDefault('module', 0) ->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags) - ->encodeURL('url') ->add('editedBy', $this->app->user->account) ->add('editedDate', $now) - ->remove('comment,files, labels,uid') + ->cleanInt('module') + ->join('groups', ',') + ->join('users', ',') + ->remove('comment,files,labels,uid') ->get(); + if($doc->acl == 'private') $doc->users = $this->app->user->account; + + $lib = $this->getLibByID($doc->lib); + $doc = $this->loadModel('file')->processEditor($doc, $this->config->doc->editor->edit['id'], $this->post->uid); + $doc->product = $lib->product; + $doc->project = $lib->project; + + $files = $this->file->saveUpload('doc', $docID); + $changes = common::createChanges($oldDoc, $doc); + $changed = false; + if($files) $changed = true; + foreach($changes as $change) + { + if($change['field'] == 'content' or $change['field'] == 'title' or $change['field'] == 'digest') $changed = true; + } + + if($changed) + { + $oldDocContent = $this->dao->select('files,type')->from(TABLE_DOCCONTENT)->where('doc')->eq($docID)->andWhere('version')->eq($oldDoc->version)->fetch(); + $doc->version = $oldDoc->version + 1; + $docContent = new stdclass(); + $docContent->doc = $docID; + $docContent->title = $doc->title; + $docContent->digest = $doc->digest; + $docContent->content = $doc->content; + $docContent->version = $doc->version; + $docContent->type = $oldDocContent->type; + $docContent->files = $oldDocContent->files; + if($files) $docContent->files .= ',' . join(',', array_keys($files)); + $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec(); + } + unset($doc->digest); + unset($doc->content); - $condition = "lib = '$doc->lib' AND module = $doc->module AND id != $docID"; - $doc = $this->loadModel('file')->processEditor($doc, $this->config->doc->editor->edit['id'], $this->post->uid); $this->dao->update(TABLE_DOC)->data($doc) ->autoCheck() ->batchCheck($this->config->doc->edit->requiredFields, 'notempty') - ->check('title', 'unique', $condition) ->where('id')->eq((int)$docID) ->exec(); if(!dao::isError()) { $this->file->updateObjectID($this->post->uid, $docID, 'doc'); - return common::createChanges($oldDoc, $doc); + return array('changes' => $changes, 'files' => $files); } } @@ -308,17 +391,9 @@ class docModel extends model $this->config->doc->search['params']['product']['values'] = array(''=>'') + $this->loadModel('product')->getPairs('nocode') + array('all'=>$this->lang->doc->allProduct); $this->config->doc->search['params']['project']['values'] = array(''=>'') + $this->loadModel('project')->getPairs('nocode') + array('all'=>$this->lang->doc->allProject); $this->config->doc->search['params']['lib']['values'] = array(''=>'') + $libs; - $this->config->doc->search['params']['type']['values'] = array(''=>'') + $this->config->doc->search['params']['type']['values']; /* Get the modules. */ - if($type == 'product' or $type == 'project') - { - $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu(0, $libID . 'doc', $startModuleID = 0); - } - else - { - $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'customdoc', $startModuleID = 0); - } + $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID . 'doc', $startModuleID = 0); $this->config->doc->search['params']['module']['values'] = $moduleOptionMenu; $this->loadModel('search')->setSearchParams($this->config->doc->search); @@ -333,10 +408,11 @@ class docModel extends model */ public function getProductDocs($productID) { - return $this->dao->select('t1.*, t2.name as module') - ->from(TABLE_DOC)->alias('t1') + $condition = $this->buildConditionSQL('t1'); + return $this->dao->select('t1.*, t2.name as module')->from(TABLE_DOC)->alias('t1') ->leftjoin(TABLE_MODULE)->alias('t2')->on('t1.module = t2.id') ->where('t1.product')->eq($productID) + ->beginIF($condition)->andWhere("($condition)")->fi() ->andWhere('t1.deleted')->eq(0) ->orderBy('t1.id_desc') ->fetchAll(); @@ -351,7 +427,13 @@ class docModel extends model */ public function getProjectDocs($projectID) { - return $this->dao->findByProject($projectID)->from(TABLE_DOC)->andWhere('deleted')->eq(0)->orderBy('id_desc')->fetchAll(); + $condition = $this->buildConditionSQL(); + return $this->dao->select('*')->from(TABLE_DOC) + ->where('project')->eq($projectID) + ->beginIF($condition)->andWhere("($condition)")->fi() + ->andWhere('deleted')->eq(0) + ->orderBy('id_desc') + ->fetchAll(); } /** @@ -409,22 +491,26 @@ class docModel extends model /** * Check priv. * - * @param object $docLib + * @param object $object * @access public * @return bool */ - public function checkPriv($docLib) + public function checkPriv($object) { - if(empty($docLib->groups) and empty($docLib->users)) return true; + if($object->acl == 'public') return true; $account = ',' . $this->app->user->account . ','; if(strpos($this->app->company->admins, $account) !== false) return true; - if(strpos(",$docLib->users,", $account) !== false) return true; - - $userGroups = $this->app->user->groups; - foreach($userGroups as $groupID) + if($object->acl == 'private' and $object->users == $this->app->user->account) return true; + if($object->acl == 'custom') { - if(strpos(",$docLib->groups,", ",$groupID,") !== false) return true; + if(strpos(",$object->users,", $account) !== false) return true; + + $userGroups = $this->app->user->groups; + foreach($userGroups as $groupID) + { + if(strpos(",$object->groups,", ",$groupID,") !== false) return true; + } } return false; } @@ -473,14 +559,7 @@ class docModel extends model } if(isset($projects)) $stmt = $stmt->andWhere('project')->in($projects); - $condition = ''; - $account = ',' . $this->app->user->account . ','; - if(strpos($this->app->company->admins, $account) === false) - { - $condition .= "(groups='' and users='')"; - foreach($this->app->user->groups as $groupID) $condition .= " OR (CONCAT(',', groups, ',') like '%,$groupID,%')"; - $condition .= " OR (CONCAT(',', users, ',') like '%$account%')"; - } + $condition = $this->buildConditionSQL(); $idList = $stmt->beginIF($condition)->andWhere("($condition)")->fi()->orderBy("{$key}_desc")->page($pager)->fetchPairs($key, $key); if($type == 'product' or $type == 'project') @@ -583,10 +662,11 @@ class docModel extends model * * @param string $type * @param int $objectID + * @param string $mode * @access public * @return array */ - public function getLibsByObject($type, $objectID) + public function getLibsByObject($type, $objectID, $mode = '') { $objectLibs = $this->dao->select('*')->from(TABLE_DOCLIB)->where('deleted')->eq(0)->andWhere($type)->eq($objectID)->orderBy('id desc')->fetchAll('id'); if($type == 'product') @@ -602,8 +682,12 @@ class docModel extends model { if($this->checkPriv($lib)) $libs[$lib->id] = $lib->name; } - if($type == 'product' and isset($hasProject[$objectID]) and common::hasPriv('doc', 'allLibs')) $libs['project'] = $this->lang->doc->systemLibs['project']; - if(common::hasPriv('doc', 'showFiles')) $libs['files'] = $this->lang->doclib->files; + + if(strpos($mode, 'onlylib') === false) + { + if($type == 'product' and isset($hasProject[$objectID]) and common::hasPriv('doc', 'allLibs')) $libs['project'] = $this->lang->doc->systemLibs['project']; + if(common::hasPriv('doc', 'showFiles')) $libs['files'] = $this->lang->doclib->files; + } return $libs; } @@ -643,4 +727,28 @@ class docModel extends model return $files; } + + /** + * Build condition SQL for priv. + * + * @param string $table + * @access public + * @return string + */ + public function buildConditionSQL($table = '') + { + if($table) $table .= '.'; + $condition = ''; + $account = ',' . $this->app->user->account . ','; + if(strpos($this->app->company->admins, $account) === false) + { + $condition .= "{$table}acl='public'"; + $condition .= " OR ({$table}acl='private' and {$table}users='{$this->app->user->account}')"; + $condition .= " OR ({$table}acl='custom' and ("; + foreach($this->app->user->groups as $groupID) $condition .= "(CONCAT(',', {$table}groups, ',') like '%,$groupID,%') OR "; + $condition .= "(CONCAT(',', {$table}users, ',') like '%$account%')"; + $condition .= "))"; + } + return $condition; + } } diff --git a/module/doc/view/ajaxgetmatcheditems.html.php b/module/doc/view/ajaxgetmatcheditems.html.php index e911d5b422..da914d1f8c 100644 --- a/module/doc/view/ajaxgetmatcheditems.html.php +++ b/module/doc/view/ajaxgetmatcheditems.html.php @@ -1,10 +1,10 @@
diff --git a/module/doc/view/browse.html.php b/module/doc/view/browse.html.php index 3550483b7c..4064fa401b 100644 --- a/module/doc/view/browse.html.php +++ b/module/doc/view/browse.html.php @@ -23,7 +23,7 @@ var type = '';
  •  doc->searchDoc;?>
  • - +
    '>
    @@ -50,7 +50,6 @@ var type = ''; recTotal}&recPerPage={$pager->recPerPage}";?> idAB);?> doc->title);?> - doc->type);?> doc->addedBy);?> doc->addedDate);?> actions;?> @@ -65,7 +64,6 @@ var type = ''; id)); else printf('%03d', $doc->id);?> title);?> - doc->types[$doc->type];?> addedBy]) ? print($users[$doc->addedBy]) : print($doc->addedBy);?> addedDate));?> @@ -81,7 +79,7 @@ var type = ''; - show();?> + show();?> diff --git a/module/doc/view/create.html.php b/module/doc/view/create.html.php index d49f3c6780..63243502de 100644 --- a/module/doc/view/create.html.php +++ b/module/doc/view/create.html.php @@ -12,7 +12,8 @@ ?> -doc->placeholder);?> +doc->placeholder);?> +
    @@ -22,53 +23,56 @@
    - - - + + - - - - - - - - - - - - - - - + - - - - - + + + + + - - - - - + + + + + + + + + diff --git a/module/doc/view/createlib.html.php b/module/doc/view/createlib.html.php index 88dea38509..d32d843fb3 100644 --- a/module/doc/view/createlib.html.php +++ b/module/doc/view/createlib.html.php @@ -38,7 +38,16 @@ - + + + + + - + diff --git a/module/doc/view/edit.html.php b/module/doc/view/edit.html.php index f11074d92e..a93eaf2053 100644 --- a/module/doc/view/edit.html.php +++ b/module/doc/view/edit.html.php @@ -12,13 +12,7 @@ ?> - +
    @@ -31,52 +25,58 @@ $(document).ready(function()
    doc->product;?>doc->lib;?>
    doc->project;?>
    doc->product;?>
    doc->module;?>
    doc->type;?>doc->types, 'file', "onclick=setType(this.value)");?>
    doc->title;?>
    doc->url;?>
    doc->content;?>
    doc->digest;?>
    doc->keywords;?>
    doc->digest;?>
    doc->files;?> fetch('file', 'buildform');?>
    doclib->control;?> +
    + doclib->acl?> + doc->aclList, 'public', "class='form-control' onchange='toggleAcl(this.value)'")?> +
    +
    doclib->acl;?>doclib->control;?> +
    + doclib->acl?> + doc->aclList, 'public', "class='form-control' onchange='toggleAcl(this.value)'")?> +
    +
    - - - - - - - - - + - + - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + - + + + + + - + @@ -57,4 +66,7 @@
    doc->lib;?>lib, "class='form-control chosen' onchange='loadModule(this.value);changeByLib(this.value)'");?>
    doc->project;?>project, "class='form-control chosen' onchange=loadProducts(this.value)");?>
    doc->product;?>product, "class='form-control chosen'");?>lib, "class='form-control chosen' onchange='loadModules(this.value)'");?>
    doc->module;?>module, "class='form-control chosen'");?>module, "class='form-control chosen'");?>
    doc->type;?>doc->types[$doc->type];?>
    doc->title;?> title, "class='form-control'");?>
    doc->content;?>content, "class='form-control' rows='5' style='width:90%; height:200px'");?>
    doc->digest;?>digest, "class='form-control' rows=2");?>
    doc->comment;?>
    doc->keywords;?> keywords, "class='form-control'");?>
    doc->url;?>url), "class='form-control'");?>
    doc->content;?>content), "class='form-control' rows='8' style='width:90%; height:200px'");?>
    doc->digest;?>digest), "class='form-control' rows=3");?>
    doc->comment;?>
    doc->files;?> fetch('file', 'buildform');?>
    doclib->control;?> +
    + doclib->acl?> + doc->aclList, $doc->lib, "class='form-control' onchange='toggleAcl(this.value)'")?> +
    +
    diff --git a/module/doc/view/editlib.html.php b/module/doc/view/editlib.html.php index ccacdb9961..f090ba8cbc 100644 --- a/module/doc/view/editlib.html.php +++ b/module/doc/view/editlib.html.php @@ -38,7 +38,16 @@ name, "class='form-control'")?>
    doclib->acl;?>doclib->control;?> +
    + doclib->acl?> + doc->aclList, $lib->acl, "class='form-control' onchange='toggleAcl(this.value)'")?> +
    +
    + diff --git a/module/doc/view/view.html.php b/module/doc/view/view.html.php index b2bc330c0d..4d0cb7b259 100644 --- a/module/doc/view/view.html.php +++ b/module/doc/view/view.html.php @@ -19,6 +19,20 @@ deleted):?> doc->deleted;?> + version > 1):?> + + + + +
    - type == 'url' and $doc->url):?> -
    - doc->url;?> -
    - url), '', '_blank');?> - - -
    -
    - - type == 'text'):?>
    doc->content;?> -
    content;?>
    +
    + [^<]+<\/a>$/Ui', trim($doc->content), $output); + $href = isset($output[1][0]) ? $output[1][0] : ''; + ?> + content;?> + + + + + + files as $file):?> + extension, $config->file->imageExtensions)):?> + + <?php echo $file->title?> + + files[$file->id]);?> + + + + files):?> +
    fetch('file', 'printFiles', array('files' => $doc->files, 'fieldset' => 'false'));?>
    + +
    - -
    - type == 'file'):?> - fetch('file', 'printFiles', array('files' => $doc->files, 'fieldset' => 'true'));?> - -
    deleted) echo $actionLinks;?>
    @@ -85,22 +105,26 @@
    doc->basicInfo;?> + productName):?> + + + + + + projectName):?> + + + + + - + - - - - - - - - @@ -119,5 +143,6 @@ + diff --git a/module/file/model.php b/module/file/model.php index 165f8f545d..3acfa16612 100644 --- a/module/file/model.php +++ b/module/file/model.php @@ -45,8 +45,10 @@ class fileModel extends model return $this->dao->select('*')->from(TABLE_FILE) ->where('objectType')->eq($objectType) ->andWhere('objectID')->eq((int)$objectID) + ->andWhere('extra')->ne('editor') ->beginIF($extra)->andWhere('extra')->eq($extra) - ->orderBy('id')->fetchAll(); + ->orderBy('id') + ->fetchAll('id'); } /** @@ -643,6 +645,7 @@ class fileModel extends model $data = new stdclass(); $data->objectID = $objectID; $data->objectType = $objectType; + $data->extra = 'editor'; if(isset($_SESSION['album'][$uid]) and $_SESSION['album'][$uid]) { $this->dao->update(TABLE_FILE)->data($data)->where('id')->in($_SESSION['album'][$uid])->exec(); diff --git a/module/upgrade/model.php b/module/upgrade/model.php index f0af4fe535..fa49847e27 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -1256,7 +1256,7 @@ class upgradeModel extends model $files = array(); preg_match_all('/"data\/upload\/.*1\/([0-9]{6}\/[^"]+)"/', $action->comment, $output); foreach($output[1] as $path)$files[$path] = $path; - $this->dao->update(TABLE_FILE)->set('objectType')->eq($action->objectType)->set('objectID')->eq($action->objectID)->where('pathname')->in($files)->exec(); + $this->dao->update(TABLE_FILE)->set('objectType')->eq($action->objectType)->set('objectID')->eq($action->objectID)->set('extra')->eq('editor')->where('pathname')->in($files)->exec(); } $editors['doc'] = array('table' => TABLE_DOC, 'fields' => 'id,`content`,`digest`'); @@ -1290,12 +1290,43 @@ class upgradeModel extends model foreach($output[1] as $path)$files[$path] = $path; } } - if($files) $this->dao->update(TABLE_FILE)->set('objectType')->eq($objectType)->set('objectID')->eq($objectID)->where('pathname')->in($files)->exec(); + if($files) $this->dao->update(TABLE_FILE)->set('objectType')->eq($objectType)->set('objectID')->eq($objectID)->set('extra')->eq('editor')->where('pathname')->in($files)->exec(); } } return true; } + /** + * Move doc content to table zt_doccontent. + * + * @access public + * @return bool + */ + public function moveDocContent() + { + $this->dao->exec('TRUNCATE TABLE ' . TABLE_DOCCONTENT); + $stmt = $this->dao->select('id,title,digest,content,url')->from(TABLE_DOC)->query(); + $fileGroups = $this->dao->select('id,objectID')->from(TABLE_FILE)->where('objectType')->eq('doc')->fetchGroup('objectID', 'id'); + while($doc = $stmt->fetch()) + { + $url = empty($doc->url) ? '' : urldecode($doc->url); + $docContent = new stdclass(); + $docContent->doc = $doc->id; + $docContent->title = $doc->title; + $docContent->digest = $doc->digest; + $docContent->content = $doc->content; + $docContent->content .= empty($url) ? '' : '' . $url . ''; + $docContent->version = 1; + $docContent->type = 'html'; + if(isset($fileGroups[$doc->id])) $docContent->files = join(',', array_keys($fileGroups[$doc->id])); + $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec(); + } + $this->dao->exec('ALTER TABLE ' . TABLE_DOC . ' DROP `digest`'); + $this->dao->exec('ALTER TABLE ' . TABLE_DOC . ' DROP `content`'); + $this->dao->exec('ALTER TABLE ' . TABLE_DOC . ' DROP `url`'); + return true; + } + /** * Judge any error occers. *
    doc->product;?>productName;?>
    doc->project;?>projectName;?>
    doc->lib;?>name;?>
    doc->module;?> moduleName ? $doc->moduleName : '/';?>
    doc->type;?>doc->types[$doc->type];?>
    doc->addedBy;?>addedBy];?>
    doc->addedDate;?> addedDate;?>