魔改!讓「禪道」擁有 抄送列表

禪道是第一款國產的開源項目管理軟體,她的核心管理思想基於敏捷方法scrum,內置了產品管理和項目管理。
官方傳送門://www.zentao.net/
禪道有多個版本:專業版、企業版、集團版、開源版。
在使用禪道開源版的過程中,發現了一個問題(不確定是不是使用方式不對),就是禪道的抄送數據並沒有在列表中可以展現。

所以摸索了一下實現了以下功能:

  1. 產品->需求列表加入「抄送給我」的需求列表
  2. 測試->BUG列表加入「抄送給我」的BUG列表

1. 參考文檔

禪道使用自主開發的zentaophp框架開發,內置了完整的擴展機制(非簡單的鉤子),用戶可以非常方便的對禪道進行徹底的二次開發。
zentaophp開發手冊地址://devel.easycorp.cn/book/zentaophphelp/about-10.html
zentaophp二次開發文檔地址://devel.easycorp.cn/book/extension/intro-45.html

2. 流程分析

zentaophp的請求分發是按url地址來劃分的,比如/product-browse-1.html這個請求。
其中:product是一個模組,而browse是這個模組control的一個介面。
以BUG列表為例:
control的browse介面接收到http請求後調用model的getBugs方法拉取bugs數據,然後將數據填充到/view/browse.html.php視圖中顯示出來。

bug

需求的流程大致是一樣的,不過需求的入口是product模組,然後通過調用story拉取數據。

3. 拓展功能

zentaoPHP框架每個模組按照mvc進行劃分,有自己的control(控制層)、 model(模型層)和view(視圖層),並且提供了非常便利的拓展方式。
想要拓展自己的功能只需要將拓展程式碼放在每個模組的ext目錄下即可,可以看一下效果圖:
拓展前:
old
拓展後:
new

a. 對視圖層進行拓展

為了不改變禪道的源碼,對視圖層的拓展鉤子進行擴展,鉤子腳本的命名規則為方法名. 擴展名.html.hook.php。
所以對應的拓展頁面名稱為:browse.mailto.html.hook.php,存放路徑為:module/bug/ext/view。內容如下:

<script>
  <?php
  $mail_to_type = 'mailtome';
  $mail_to_label = "<span class='text'>抄送給我</span>";
  $mail_to_active = $mail_to_type == $browseType ? 'btn-active-text' : '';
  $mail_to_uri = html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$mail_to_type"), $mail_to_label, "", "class='btn btn-link $mail_to_active'");
  $mail_to_uri = str_replace(array("\r", "\n", "\r\n"), "", $mail_to_uri);
  ?>
  $('#bysearchTab')
    .parent()
    .find('a:eq(3)')
    .after("<?php echo $mail_to_uri ?>");
</script>

通過zentaoPHP的js模組生成a標籤,如果將a標籤用jQuery插入到指定的位置。

b. 對模型層進行拓展

上面視圖層拓展中,「抄送給我」調用的還是bug模組的browse介面,所以不需要對control進行拓展,只需要重寫model的getBugs方法,添加對browseType=『mailtome』的數據進行處理即可。

重寫getBugs方法,拓展文件名稱以getBugs方法名稱命名,路徑為module/bug/ext/model/,內容如下:

<?php
public function getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager)
{
  if($browseType == 'mailtome')
  {
    /* Set modules and browse type. */
    $modules    = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
    $browseType = ($browseType == 'bymodule' and $this->session->bugBrowseType and $this->session->bugBrowseType != 'bysearch') ? $this->session->bugBrowseType : $browseType;
    $bugs = array();
    $bugs = $this->getMailToMeBugs($productID, $branch, $modules, $projects, $sort, $pager);
    return $this->checkDelayBugs($bugs);
  } 
  else 
  {
    return parent::getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager);
  }
}
?>

這裡,如果$browseType=’mailtome’的話,就調用getMailToMeBugs這個方法,否則調用父級的getBugs方法。
getMailToMeBug這個方法是自己拓展的,所有需要在module/bug/ext/model/路徑下創建對應的php,內容如下:

<?php
public function getMailToMeBugs($productID, $branch, $modules, $projects, $orderBy, $pager)
{
    return $this->dao->select('*')->from(TABLE_BUG)
      ->where('project')->in(array_keys($projects))
      ->andWhere('product')->eq($productID)
      ->beginIF($branch)->andWhere('branch')->in($branch)->fi()
      ->beginIF($modules)->andWhere('module')->in($modules)->fi()
      ->andWhere('deleted')->eq(0)
      ->andWhere('mailto', true)->like('%,' . $this->app->user->account . ',%')
      ->orWhere('mailto')->like('%,' . $this->app->user->account)
      ->markRight(1)
      ->andWhere('status')->eq('active')
      ->orderBy($orderBy)->page($pager)->fetchAll();
}
?>

根據禪道的抄送入庫規則「,帳號」,只需要查詢「,帳號,」「,帳號」的數據即可,這裡只查詢狀態為激活的BUG。

c. 拓展需求「抄送給我」列表

需求「抄送給我」的拓展方式跟BUG「抄送給我」的拓展方式是一樣的,需要注意的是需求入口是product模組,拉取的數據是story模組。

story拓展的model程式碼:

<?php
public function getByMailTo($productID, $branch, $modules, $orderBy, $pager)
{
  $stories = $this->dao->select('*')->from(TABLE_STORY)
    ->where('product')->in($productID)
    ->andWhere('deleted')->eq(0)
    ->beginIF($branch)->andWhere("branch")->eq($branch)->fi()
    ->beginIF($modules)->andWhere("module")->in($modules)->fi()
    ->andWhere('mailto', true)->like('%,' . $this->app->user->account . ',%')
    ->orWhere('mailto')->like('%,' . $this->app->user->account)
    ->markRight(1)
    ->andWhere('stage')->ne('closed')
    ->orderBy($orderBy)
    ->page($pager)
    ->fetchAll();
  return $this->mergePlanTitle($productID, $stories, $branch);
}
?>

下面是拓展後的效果:

story

至此,就可以在禪道上查看「抄送給我」的需求和BUG了。

我是寫java的,不會php程式碼,這裡的程式碼都是根據開發手冊依葫蘆畫瓢的。

=========================================================
源碼可關注公眾號 「HiIT青年」 發送 「zentao」 獲取。

HiIT青年
關注公眾號,閱讀更多文章。

Tags: